Skip to content

The Four Phase Workflow

Mikhail Deynekin edited this page Oct 14, 2026 · 1 revision

The Four Phase Workflow

The kit's operating doctrine: four ordered phases — research, wiki architecture, writing, QA and delivery — with one tool per job and files as the only hand-off between phases. This page walks the whole pipeline the way an agent run executes it, with the effort budget, the phase-boundary discipline, and the reasons the order is not negotiable. Sources: SKILL.md, AGENTS.md, PROMPT.md at commit 7e17a11; measured behaviour from this wiki run (test IDs T0–T18).

Contents


Why phases at all

Each phase makes the next cheap, and skipping one makes the rest expensive:

If you skip… What happens Documented cost
Phase 1 research Phase 3 transcribes the README; plausible falsehoods ship The reference case: "syntax highlighting" and "nested lists" claims, both false, both two minutes from disproving
Phase 2 architecture Structure gets retrofitted; sidebar grouping is a guess; ban/terms discipline arrives after the prose is written "Structure is free when you scaffold it and expensive when you retrofit it"
Phase 3 scaffolding Every page reinvents H1/lead/Contents/See-also; QA drowns in structural errors instead of content errors The scaffold is QA-clean by construction — verified across three page lists (T8)
Phase 4 QA Dead anchors, broken mermaid, fence-swallowing bugs and banned claims ship A real shipping bug: a markdown example containing a bash fence silently closed the outer block and would have rendered the rest of a page as garbage

The effort budget from the reference run (22 files, 73,013 words, 0 QA errors): research ~40%, architecture ~3%, writing ~45%, QA + delivery ~12%.

Phase 1 — research (~40%)

Goal: know the subject better than its README does, with evidence.

# 1. environment + capability report (idempotent)
bash setup/bootstrap.sh --subject repo/SUBJECT

# 2. clone and record HEAD
mkdir -p workspace/repo && cd workspace/repo
git clone https://github.com/OWNER/REPO SUBJECT
cd SUBJECT && git log --oneline -1 && cd ../..

# 3. inventory — replaces an hour of manual grepping
python3 scan/repo_scan.py repo/SUBJECT --brief -o research/scan.json

# 4. RUN the subject and probe it (PHP web app shown; see below for others)
python3 probe/webapp_probe.py --repo repo/SUBJECT \
    --copy 'md.php,updater.php,css,js' --entry /md.php \
    --suite php-mdviewer -o research/probe.json --md research/probe.md

Then read source in ranges (sed -n '661,760p' file), never cat a 200 KB file; start with header docblocks — they often hold a prose changelog with the reasoning behind decisions. Do targeted web research only for context the repo cannot give (specs, OWASP, competitor docs); every statement about the subject comes from the subject.

Phase 1 is not done until five files exist:

File Contents
research/summary.md what it is, the problem, architecture in one paragraph, security posture, measured feature support, competitive position
research/architecture.md component map, request lifecycle, module breakdown, config resolution, function index with line numbers
research/domain-notes.md standards/spec context, security domain, deployment context, and the canonical glossary
research/facts.json machine-readable facts; every value carries a source (code:file:line, readme, git, test:name, web:url)
research/sources.md §A source-line citations · §B named empirical tests · §C external sources · §D claims deliberately NOT made, with reasons

Important

Section D is the most valuable thing you will write in Phase 1. It becomes ban.json in Phase 2, and it is what stops a future pass from "helpfully" re-adding a plausible falsehood. This wiki's own §D grew to 18 entries — including three that came from drift this run's probes found between the kit's recorded expectations and current subject behaviour.

Before writing any probe code, read setup/PITFALLS.md. Its first three entries produce silently wrong results: a port collision makes tests hit a stale server (A1); a file named http.py breaks every urllib call with a misleading error (A2); anything in /tmp does not persist (A3).

Phase 2 — wiki architecture (~3%)

Cheap, and the phase most often skipped — which is exactly why it has its own step.

  1. Design the page tree before writing prose. Record it in PROGRESS.json (from templates/PROGRESS.json.tmpl): page list, groupings, style contract, do_not_claim.
  2. Fill ban.json from sources.md §D — affirmative forms of claims that must never appear, each with its reason.
  3. Fill terms.json from the domain-notes glossary — canonical terms plus the near-synonyms to reject. The synonym list is the valuable half: the real failure mode is not wrong terminology, it is five terms for one concept.

The recommended 20-page composition for a tool-shaped project (adapt to the subject):

Overview    Home · Getting Started · Features and Live Demo · Comparison with Alternatives
Install     Installation and Deployment · Configuration Reference · Settings Panel
Authoring   Markdown Extensions Matrix · Authoring Guide · File Browser and Routing
Operating   Security Hardening Guide · Self-Updater Guide · Machine API ·
            File Upload and Clipboard · Performance and Caching
Reference   Architecture · Troubleshooting · FAQ · Changelog and Versioning · Glossary

Two pages are non-negotiable for anything that runs a server: a Security page and a Troubleshooting page. Troubleshooting usually ends up the longest (6,200 words in the reference run) because it absorbs every HTTP status code and every exact error string — collect those strings in Phase 1.

Composition requirements: _Sidebar.md (grouped by meaning), _Footer.md (version, license, links, source commit), Home.md (badges, summary, features, five-minute quick start, navigation).

Phase 3 — writing (~45%)

python3 scaffold/new_page.py workspace/wiki/OWNER.REPO.wiki --init \
    --project "SUBJECT" --repo-url https://github.com/OWNER/REPO \
    --version X.Y.Z --commit abc1234 \
    --progress workspace/PROGRESS.json

The scaffold emits Home.md, _Sidebar.md, _Footer.md and one stub per page — each already carrying an H1, a lead-paragraph slot, a ## Contents block and a ## See also section. Then fill pages, hardest first while the research is fresh (usually Security and the reference matrix). After filling or rewriting a page, run qa/fix_toc.py on the directory — never hand-write anchor slugs.

The filename rule decides whether your links live or die: GitHub maps spaces in a wiki filename to hyphens in the URL and resolves [[Page Name]] against that.

File URL [[Security Hardening Guide]]
Security Hardening Guide.md /wiki/Security-Hardening-Guide resolves
Security-Hardening-Guide.md /wiki/Security-Hardening-Guide dead

Name files with spaces; link with the same spaces; _Sidebar.md/_Footer.md keep their underscores (GitHub renders them on every page and does not list them). Every page: one H1, a lead paragraph, ## Contents, logical H2/H3, ## See also with cross-links. Devices: GitHub Alerts for stakes, mermaid for structure and process, tables for parameters/errors/matrices, fenced code with a language tag for every command — copy-pasteable, with sample output where useful. No marketing filler, no decorative emoji; emoji are acceptable only as data.

Phase 4 — QA and delivery (~12%)

# 1. prove the checker can fail — once per session
python3 qa/qa_wiki.py --self-test

# 2. the real audit; iterate to zero errors
python3 qa/qa_wiki.py workspace/wiki/OWNER.REPO.wiki \
    --terms workspace/terms.json --ban workspace/ban.json --strict

# 3. re-run the commands your wiki documents, in a clean sandbox
python3 qa/verify_commands.py    # adapted from the worked template

# 4. deliver
bash publish/publish.sh workspace/wiki/OWNER.REPO.wiki OWNER/REPO

Step 3 is the one agents skip and the one that catches factual drift: in the reference run it found two errors — a 403 page's <title> versus its <h1>, and a README claim about a force-flag propagating between update phases that the code did not implement. This wiki run's equivalent step reproduced a recorded figure exactly (19 of 26 injection payloads reflected verbatim by the reference subject) and flagged two expectation drifts in the current subject build — evidence that the loop works in both directions.

Finally, write REPORT.md: page inventory with word counts, what was verified and how, the findings where the subject's own docs are wrong, sources, and an honest "what remains to be improved" section including the limits of the analysis — which runtime version you actually used, what you could not execute, what you reasoned from source rather than observed.

Phase-boundary discipline

At every boundary, not at the end:

  • update STATE.md (phase, done, next single action, facts a fresh agent must not lose)
  • update PROGRESS.json (per-page status/words, QA numbers, delivery fields)
  • append a row to REWORK-STATE.md's log (what was done + where the evidence is)
  • bash setup/snapshot.sh workspace "phase N done" — or mirror the workspace to a backup location

The payoff, from the reference run: a hard session interruption in the middle of Phase 4 cost zero work, because REWORK-STATE.md and research/ were current. Resuming took one ls and one head.

Adapting the workflow to non-PHP and non-server subjects

Subject shape Adaptation
Node/Python/any server ServedApp(..., serve_cmd='node {root}/server.js') or 'python3 -m http.server {port} -d {root}'; the batteries are transport-level (verified T10: static app served through a non-PHP command)
Static site same http.server template; probe reachability + headers
CLI tool skip serve.py; write a suite that shells out and captures stdout/stderr/exit codes — the reusable part is the shape: declarative cases → evidence JSON → Markdown tables
Library examples-as-subject: run the documented recipes as the probe; compile()/execution of every snippet becomes the battery
This kit itself the self-referential run: every tool's self-test, CI replication and a probe battery against the reference subject become Phase 1 evidence (this wiki)

See also

Clone this wiki locally