|
| 1 | +# Research-first project bootstrap |
| 2 | + |
| 3 | +Agent instructions for this project. Read this before planning, designing, or building |
| 4 | +anything here. |
| 5 | + |
| 6 | +## This is a DECISION PROJECT, and the project root is this directory |
| 7 | + |
| 8 | +`docs/decisions/2026-09-21-delivery-architecture/` is a self-contained research project |
| 9 | +nested inside a larger repository. Two rules follow, and both have been broken already: |
| 10 | + |
| 11 | +1. **Every kit command runs with THIS directory as the current working directory.** The kit |
| 12 | + takes no project argument. Run from the repository root, `preflight` judges the |
| 13 | + repository's corpus - a different contract, a different set of unknowns - and reports a |
| 14 | + verdict that says nothing about this project. Quoting the parent's PASS beside this |
| 15 | + project's claims is the error that produced |
| 16 | + `../../preliminary-2026-09-21-delivery-architecture.md`. |
| 17 | +2. **This project's corpus is committed, ledger included.** Research supporting a |
| 18 | + repository-level architectural decision lives at `docs/decisions/<date>-<name>/`. |
| 19 | + Temporary scratch projects may be used for experiments, but their findings cannot |
| 20 | + support a committed decision unless the complete evidence corpus and ledger are |
| 21 | + preserved. The first attempt at this research was collected into a temporary directory |
| 22 | + and deleted as cleanup, taking nine captures, the hash chain and the provenance for |
| 23 | + every claim with it. |
| 24 | + |
| 25 | +Do not collect this project's topic into the repository's own `research/`, and do not |
| 26 | +collect the repository's topic into this one. One project, one contract, one corpus. |
| 27 | + |
| 28 | +## How this project works: two phases, two roles |
| 29 | + |
| 30 | +**Phase 1 - research (this kit).** Close every blocking unknown with fetched primary |
| 31 | +sources, then pass the gate. The output is a briefing, not code: `research/DISCOVERY.md` |
| 32 | +(the contract), `research/EVIDENCE.md` (claims with cached pages behind them), and |
| 33 | +`research/BRIEF.md` (the handoff). Phase 1 never writes product code. |
| 34 | + |
| 35 | +**Phase 2 - build (someone else's job).** A builder - another agent, a different model, or |
| 36 | +a human - takes `research/BRIEF.md` plus `research/` and implements. They should not need |
| 37 | +to re-research anything: if they do, phase 1 was incomplete, and the fix is to collect the |
| 38 | +missing fact rather than to let the builder guess it. |
| 39 | + |
| 40 | +The gate is the handoff point. Before it passes, phase 2 does not start. |
| 41 | + |
| 42 | +## Two machines, two roles |
| 43 | + |
| 44 | +The role is machine config - `role: "collector" | "builder"` in |
| 45 | +`~/.agents/research-kit.config.json`, default `collector`; declare it with |
| 46 | +`node ../../../research-kit/bin/install-hooks.mjs --role builder`. |
| 47 | + |
| 48 | +| | **collector** (the operator's PC) | **builder** (a sandbox, a CI box, a laptop) | |
| 49 | +|---|---|---| |
| 50 | +| holds | the Firecrawl key | no key, no Firecrawl egress | |
| 51 | +| runs | `decompose.mjs`, `research.mjs` | `handoff.mjs`, `preflight.mjs`, the build | |
| 52 | +| a missing key is | a **FAIL** | **informational** | |
| 53 | +| must | push `research/raw/` including its dotfiles | **not collect** - the collection CLIs refuse (exit 2) | |
| 54 | + |
| 55 | +**If you are on a builder machine and there is no brief: you do not collect.** A page |
| 56 | +fetched by hand is not evidence in this kit, and a builder that "re-collects" a missing |
| 57 | +page forges a corpus instead of reporting a gap. Name the missing fact instead. |
| 58 | + |
| 59 | +A builder's first command is: |
| 60 | + |
| 61 | +``` |
| 62 | +node ../../../research-kit/bin/handoff.mjs |
| 63 | +``` |
| 64 | + |
| 65 | +The remedy depends on the cause, and the command says which: something that did not |
| 66 | +travel is the collector's to push (`git add -f research/raw/`, dotfiles included); |
| 67 | +a corpus that travelled whole and was rewritten on checkout here is fixed **here**, with |
| 68 | +`.gitattributes`, and costs no credits. |
| 69 | + |
| 70 | +## Starting in the wrong place: ask which project, do not hunt for it |
| 71 | + |
| 72 | +The project is the **current working directory**. The kit takes no project argument and |
| 73 | +never will. If the cwd is not the project the operator means - the kit's own repo, a |
| 74 | +parent folder, an unrelated checkout - **ask which project**, and wait. Do not search the |
| 75 | +filesystem, do not infer it from a name, do not look it up on a remote. Searching a |
| 76 | +person's disk to guess his intent reads directories nobody authorised, and the question |
| 77 | +it replaces takes one line. |
| 78 | + |
| 79 | +Signals: no `AGENTS.md`, no `research/` directory, or a `research/` corpus plainly about |
| 80 | +something else. An existing corpus about another topic is the signal doing its job. |
| 81 | + |
| 82 | +## Resuming after an interruption: resume, do not restart |
| 83 | + |
| 84 | +The gate is a pure function of repository state, so orient from disk before touching |
| 85 | +anything. `doctor.mjs` and preflight answer *where this project is*; the last commit |
| 86 | +report and `docs/ARCHITECTURE.md` say *what was happening and why*; `git status` answers |
| 87 | +what is unfinished, and its uncommitted changes are the interrupted task - partial and |
| 88 | +unverified, work in progress, never state to trust. The corpus is already collected and |
| 89 | +spent credits are not spent again. |
| 90 | + |
| 91 | +## Rule 1 - research first, then build |
| 92 | + |
| 93 | +The sequence is decompose -> contract -> collect -> gate -> brief. |
| 94 | + |
| 95 | +0. **Decompose** (collector machine): `node ../../../research-kit/bin/decompose.mjs --topic "<topic>"` |
| 96 | + drafts `research/MAP.md` seeded with the universal checklist. The tool contains no |
| 97 | + judgment. Mark every row COVERED (citing U-## rows), DISMISSED (reason required), or |
| 98 | + GAP. |
| 99 | +1. **Write the intent** in `research/DISCOVERY.md` under `## Build intent`, and enumerate |
| 100 | + the blocking unknowns FROM the map. |
| 101 | +2. **Collect**: `node ../../../research-kit/bin/research.mjs --plan research/plan.json`. Prefer the page |
| 102 | + that *owns* the fact over any write-up about it. |
| 103 | +3. **Rewrite** each auto-extracted `Finding` cell into a real claim, keeping the `Raw` |
| 104 | + cell pointing at the cached page. |
| 105 | +4. **Gate**: `node ../../../research-kit/bin/preflight.mjs`. **Do not start building until it prints |
| 106 | + PASS.** Evidence must be *fetched*, not typed, and by a named transport. |
| 107 | +5. **Hand off**: write `research/BRIEF.md`. |
| 108 | + |
| 109 | +There are exactly three overrides - `git commit --no-verify`, a deliberate |
| 110 | +`research/GATE_OFF`, and a repository-local `core.hooksPath` - and all three are recorded |
| 111 | +in `research/overrides.log`. If you take one, say so in your reply. |
| 112 | + |
| 113 | +## Rule 2 - questions are for intent, never for facts |
| 114 | + |
| 115 | +At most **3** questions, once, up front, and only about things no document can answer. If |
| 116 | +a question's answer is in public documentation, it is a research task. **Never answer |
| 117 | +"insufficient info" and stop.** |
| 118 | + |
| 119 | +## Rule 3 - known unknowns are allowed, silence is not |
| 120 | + |
| 121 | +Mark a genuinely unreachable fact `KNOWN-UNKNOWN` and write the day-one verification step |
| 122 | +in the `Evidence` cell. An unlabeled gap is the failure mode this project exists to |
| 123 | +prevent. |
| 124 | + |
| 125 | +## Rule 4 - source quality |
| 126 | + |
| 127 | +`P` primary/official carries the design. `S` secondary is context. `L` lead-only is a |
| 128 | +hint, never proof. Never invent a citation. Flag contradictions instead of averaging them. |
| 129 | + |
| 130 | +## Rule 5 - cost discipline |
| 131 | + |
| 132 | +Every scrape spends credits. Plan the queries in `research/plan.json` first, reuse the |
| 133 | +cache (`--refresh-days`), and check the budget with `node ../../../research-kit/bin/research.mjs --status`. |
| 134 | + |
| 135 | +## Rule 6 - secrets |
| 136 | + |
| 137 | +The key lives in the CLI config or the environment. Never write it into this repository. |
| 138 | + |
| 139 | +## The standing protocol |
| 140 | + |
| 141 | +Five rules for how work here is committed and recorded. Documentation, not enforcement: |
| 142 | +no check judges prose, because a gate that judges prose is a gate that will be wrong. |
| 143 | + |
| 144 | +1. **Architecture map current in the same commit.** A commit touching a declared code |
| 145 | + path (`research/kit.json`) stages `docs/ARCHITECTURE.md` with it. Enforced - and a |
| 146 | + prompt, not a proof: the gate checks the map was *staged*, not that it is *current*. |
| 147 | +2. **Commit report: five named parts** - what changed / why / what it touched / what you |
| 148 | + verified / what you got wrong and fixed. The got-wrong line is not optional; if |
| 149 | + nothing was gotten wrong it is written as "nothing to report". |
| 150 | +3. **An ADR for any choice with a rejected alternative**, dated, with the reason a future |
| 151 | + explorer would need to avoid re-suggesting it. |
| 152 | +4. **One commit per task - the revert test.** `git revert <sha>` undoes it alone. |
| 153 | +5. **A red suite stops work**, reported immediately and alone, **with the cwd recorded**. |
0 commit comments