@dombaras/agent-harness 0.1.6 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -34,10 +34,11 @@ npx @dombaras/agent-harness init --target . --dry-run
34
34
  | Path | Content | Ownership |
35
35
  |---|---|---|
36
36
  | `AGENTS.md` | root dispatcher (points to the rulebook) | harness (overwrite) |
37
- | `.opencode/agents/*.md` | 13 persona subagent defs (with `model:` pins + `permission`/`steps`/`temperature`/`hidden`) | harness (overwrite) |
37
+ | `.opencode/agents/*.md` | 14 persona subagent defs (with `model:` pins + `permission`/`steps`/`temperature`/`hidden`) | harness (overwrite) |
38
38
  | `.agents/AGENTS.md` | full canonical operating rulebook | harness (overwrite) |
39
39
  | `.agents/rules/00-operating.md` | always-loaded rules summary (wired into `opencode.json` `instructions`) | harness (overwrite) |
40
40
  | `.agents/skills/*/SKILL.md` | persona instruction skills | harness (overwrite) |
41
+ | `.agents/features/INDEX.md` | feature backlog + status board (durable feature doc tree root) | **project** (create-if-missing) |
41
42
  | `opencode.json` | main/small model routing + `instructions` | harness (**merged**, see below) |
42
43
  | `scripts/qa/*` | `test:dispatch` / `test:governance` / `test:qa-plan` gates + QA-script wiring check | harness (overwrite) |
43
44
  | `.agents/memory/*` | project data (domain-map, stack-versions, handoff, locations, model-routing, history, flow-map, qa-plan) | **project** (create-if-missing) |
@@ -59,6 +60,17 @@ tiers, trust tiers) live in `.agents/memory/domain-map.md`, which `init`
59
60
  scaffolds for you to fill in — the skills and rules reference memory instead of
60
61
  hardcoding domain assumptions.
61
62
 
63
+ **Features (`.agents/features/`)** — the durable, feature-centric plan of record. A
64
+ found item is captured as one light row in `.agents/features/INDEX.md` (backlog: what's
65
+ known, priority, context, status). When a feature is picked up, the `features` persona
66
+ authors the per-feature doc chain (`.agents/features/<slug>/`), each layer routed to its
67
+ author persona — `intent.md` (product-manager) → `scope.md` (system-architect, HIGH-risk
68
+ only) → `plan.md` (planner) → `tests.md` (qa-architect, points to `qa-plan.md`). Ceremony
69
+ is right-sized to blast radius: trivial → none, low → single `intent.md`, high (auth/DB/
70
+ public API/flow-siblings) → full chain. Docs live beside the code, are written-back before
71
+ continuing when implementation invalidates them, and are archived on ship. See
72
+ `.agents/skills/features/SKILL.md`.
73
+
62
74
  **Flow map (`.agents/memory/flow-map.md`)** — the project-owned registry powering the
63
75
  flow-closure half of `test:qa-plan`. Each user-facing flow lists the code surfaces that
64
76
  implement the same behavior across codebases/layers (e.g. web component, `mobile/` sheet,
@@ -123,6 +135,10 @@ npx @dombaras/agent-harness update --target /path/to/project
123
135
  modified harness files. Your unrelated uncommitted work is never staged.
124
136
  - `--no-commit` to skip commit+push, `--no-push` to commit but not push.
125
137
  - `init` never commits.
138
+ - Harness-owned paths are **force-added**, so a project that gitignores deployment
139
+ artifacts (an inherited `.agents/` `.opencode/` `AGENTS.md` pattern) still gets the
140
+ harness commit instead of a raw `git add` failure that silently skips it — force-added
141
+ files are called out in the summary.
126
142
  - **`[Nothing-to-Update]` confirmation**: if the target is already at this CLI's version and no
127
143
  harness-owned file changed, `update` says so explicitly, writes nothing, and makes no commit —
128
144
  a no-op is never mistaken for a sync and never churns `.harness.json`.
@@ -15,7 +15,7 @@
15
15
  * PROJECT_NAME }} / {{ PROJECT_DOMAIN }}.
16
16
  *
17
17
  * Ownership model:
18
- * - `.agents/memory/*` is project data -> create-if-missing (never overwrite).
18
+ * - `.agents/memory/*` + `.agents/features/*` is project data -> create-if-missing (never overwrite).
19
19
  * - `opencode.json` is MERGED: harness manages $schema/model/small_model/
20
20
  * instructions; every other key the project adds is preserved.
21
21
  * - all other harness-owned files are overwritten. If a harness-owned file was
@@ -89,9 +89,19 @@ function relKey(rel) {
89
89
  return rel.split(path.sep).join("/");
90
90
  }
91
91
 
92
- function isMemoryFile(rel) {
92
+ /* `.agents/memory/*` (session memory) and `.agents/features/*` (feature doc
93
+ * tree) are project data — scaffolded create-if-missing, never overwritten,
94
+ * and never tracked in the manifest, exactly like the memory files. */
95
+ function isProjectScaffold(rel) {
93
96
  const parts = rel.split(path.sep);
94
- return parts.includes(".agents") && parts.includes("memory");
97
+ return (
98
+ parts.includes(".agents") &&
99
+ (parts.includes("memory") || parts.includes("features"))
100
+ );
101
+ }
102
+ /* Back-compat alias (kept for any external caller referencing the old name). */
103
+ function isMemoryFile(rel) {
104
+ return isProjectScaffold(rel);
95
105
  }
96
106
 
97
107
  function isOpencodeJson(rel) {
@@ -210,9 +220,12 @@ function isGitRepo(target) {
210
220
  // project's next session never sees "unexplained" modified harness files. Scoped
211
221
  // to this run's changed harness files (never `git add -A`) so unrelated uncommitted
212
222
  // work is NEVER swept in. Memory/backup files are excluded (project data / rollback).
213
- // Returns { committed:boolean, staged:string[], skipped:string[], pushed:boolean|null }.
223
+ // Harness-owned paths are force-added (`-f`): target projects often gitignore
224
+ // .agents/ .opencode/ AGENTS.md (inherited from the harness's own .gitignore), and
225
+ // a plain `git add` would fail on the first ignored path and commit NOTHING.
226
+ // Returns { committed:boolean, staged:string[], skipped:string[], pushed:boolean|null, forceAdded:string[] }.
214
227
  function commitHarnessChanges(target, changedRels, opts) {
215
- const out = { committed: false, staged: [], skipped: [], pushed: null };
228
+ const out = { committed: false, staged: [], skipped: [], pushed: null, forceAdded: [] };
216
229
  if (!opts.commit) return out;
217
230
  if (!isGitRepo(target)) {
218
231
  out.skipped.push("not a git repo");
@@ -222,9 +235,13 @@ function commitHarnessChanges(target, changedRels, opts) {
222
235
  out.skipped.push("no harness files changed");
223
236
  return out;
224
237
  }
225
- const addR = runGit(target, ["add", "--", ...changedRels]);
238
+ const ignored = runGit(target, ["check-ignore", ...changedRels]);
239
+ if (ignored.ok && ignored.out) {
240
+ out.forceAdded = ignored.out.split(/\r?\n/).filter(Boolean).map(relKey);
241
+ }
242
+ const addR = runGit(target, ["add", "-f", "--", ...changedRels]);
226
243
  if (!addR.ok) {
227
- out.skipped.push("git add failed: " + addR.err);
244
+ out.skipped.push("git add failed: " + firstGitErrorLine(addR.err));
228
245
  return out;
229
246
  }
230
247
  const diffCached = runGit(target, ["diff", "--cached", "--name-only"]);
@@ -238,7 +255,7 @@ function commitHarnessChanges(target, changedRels, opts) {
238
255
  const message = `chore(harness): @dombaras/agent-harness ${prior}${PKG.version}`;
239
256
  const commitR = runGit(target, ["commit", "-m", message]);
240
257
  if (!commitR.ok) {
241
- out.skipped.push("commit failed: " + commitR.err);
258
+ out.skipped.push("commit failed: " + firstGitErrorLine(commitR.err));
242
259
  return out;
243
260
  }
244
261
  out.committed = true;
@@ -247,7 +264,7 @@ function commitHarnessChanges(target, changedRels, opts) {
247
264
  if (hasRemote) {
248
265
  const pushR = runGit(target, ["push", "origin", "HEAD"]);
249
266
  out.pushed = pushR.ok;
250
- if (!pushR.ok) out.skipped.push("push failed: " + pushR.err);
267
+ if (!pushR.ok) out.skipped.push("push failed: " + firstGitErrorLine(pushR.err));
251
268
  } else {
252
269
  out.skipped.push("no git remote to push");
253
270
  }
@@ -255,6 +272,16 @@ function commitHarnessChanges(target, changedRels, opts) {
255
272
  return out;
256
273
  }
257
274
 
275
+ /* Pull the first real error line out of git's stderr, dropping the LF/CRLF
276
+ * warnings and `hint:` noise that bury the actual message. */
277
+ function firstGitErrorLine(err) {
278
+ const line = String(err || "")
279
+ .split(/\r?\n/)
280
+ .map((l) => l.trim())
281
+ .find((l) => l && !/^warning:/i.test(l) && !/^hint:/i.test(l));
282
+ return line || "git command failed";
283
+ }
284
+
258
285
  // ---------------------------------------------------------------- deploy
259
286
 
260
287
  function backup(target, rel, content) {
@@ -323,7 +350,7 @@ async function deploy(target, opts) {
323
350
  continue;
324
351
  }
325
352
 
326
- if (isMemoryFile(rel)) {
353
+ if (isProjectScaffold(rel)) {
327
354
  if (fs.existsSync(targetAbs)) {
328
355
  actions.push({ rel: key, kind: "preserve" });
329
356
  } else {
@@ -386,7 +413,10 @@ async function deploy(target, opts) {
386
413
  let commitResult = null;
387
414
  if (isUpdate && !dryRun && !nothingToUpdate) {
388
415
  const changedRels = changedRelsAll.filter(
389
- (r) => !r.startsWith(".agents/memory/") && !r.startsWith(".harness-backup/")
416
+ (r) =>
417
+ !r.startsWith(".agents/memory/") &&
418
+ !r.startsWith(".agents/features/") &&
419
+ !r.startsWith(".harness-backup/")
390
420
  );
391
421
  changedRels.push(CONFIG_FILE); // .harness.json reflects the new deployed version
392
422
  commitResult = commitHarnessChanges(target, changedRels, {
@@ -464,7 +494,9 @@ function printNextSteps() {
464
494
  console.log(" test:qa-plan enforces their sibling-surface/variant closure).");
465
495
  console.log(" 2. Harness gate scripts (`test:dispatch`, `test:governance`, `test:qa-plan`) were");
466
496
  console.log(' auto-wired into package.json "scripts".');
467
- console.log(" 3. Restart your agent CLI (config is read once at startup).\n");
497
+ console.log(" 3. Capture found items as rows in `.agents/features/INDEX.md`; dispatch the `features`");
498
+ console.log(" persona to author the per-feature doc chain when one is picked up.");
499
+ console.log(" 4. Restart your agent CLI (config is read once at startup).\n");
468
500
  }
469
501
 
470
502
  function printUsage() {
@@ -537,6 +569,12 @@ function printCommitResult(result) {
537
569
  console.log("");
538
570
  if (c.committed) {
539
571
  console.log(" committed harness files: " + c.staged.join(", "));
572
+ if (c.forceAdded.length) {
573
+ console.log(
574
+ " force-added (gitignored in this project, but harness-owned): " +
575
+ c.forceAdded.join(", ")
576
+ );
577
+ }
540
578
  console.log(
541
579
  c.pushed === true
542
580
  ? " pushed to origin."
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dombaras/agent-harness",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "Reusable multi-agent harness for AI-assisted development: personas, skills, operating rules, model routing, and QA gates. Deploy into any project with `npx @dombaras/agent-harness init`.",
5
5
  "bin": {
6
6
  "agent-harness": "bin/agent-harness.js"
@@ -55,6 +55,16 @@ The canonical rulebook. The always-loaded summary is `.agents/rules/00-operating
55
55
  | Data ingestion / entity resolution | `data-engineer` |
56
56
  | Deployment / cron / secrets / build+release | `devops-engineer` |
57
57
  | Session wrap-up / handoff | `handoff` |
58
+ | Feature backlog + per-feature doc tree (intent/scope/plan/tests) | `features` |
59
+ - **Feature docs, not ceremony**: capture a found item as one light row in
60
+ `.agents/features/INDEX.md` (backlog). When a feature is picked up, dispatch
61
+ `features` to author the doc chain — `intent` (product-manager) → `scope`
62
+ (system-architect, HIGH-risk only) → `plan` (planner) → `tests` (qa-architect) —
63
+ each by its author persona. Match ceremony to blast radius: trivial → none,
64
+ low → single `intent.md`, high (auth/DB/API/flow-siblings) → full chain. Write
65
+ back first (update the doc before continuing when implementation invalidates it),
66
+ archive on ship. Feature docs are durable and complementary to the per-session
67
+ `qa-plan.md`/`handoff.md`; the `tests` doc points to `qa-plan.md`, never duplicates it.
58
68
  - **QA planning is never optional (no silent skip)**: every change that touches
59
69
  code paths MUST get a QA plan before it is verified. The plan is authored by
60
70
  `qa-architect` (thinker). If `qa-architect` is not dispatched — for ANY reason,
@@ -0,0 +1,22 @@
1
+ # Features — backlog & status board
2
+
3
+ Project-owned (like all `.agents/features/*`). This is the **collection box**, not a
4
+ spec and not a status board. Every found item gets one terse row here; the per-feature
5
+ doc chain (`.agents/features/<slug>/` intent · scope · plan · tests) is written only
6
+ when the main agent focuses on the feature. Keep rows ultra-light — a note, not a promise.
7
+
8
+ Maintained by the `features` persona (`.agents/skills/features/SKILL.md`).
9
+
10
+ ## Backlog
11
+
12
+ One row per found item. `Status`: `backlog → ready → in-progress → testing → shipped → archived`.
13
+
14
+ | ID | Item (what's known so far) | Priority | Context | Status |
15
+ |----|----------------------------|----------|---------|--------|
16
+ | F-001 | _replace: short, only-what-is-known description; open questions with `?`_ | P3 | _pointer to evidence (file/log/ticket/words), not a re-derivation_ | backlog |
17
+
18
+ <!-- Add rows as items surface. Never invent status or priority — leave blank/`?` if unknown. -->
19
+
20
+ ## Active / next
21
+
22
+ - _when a feature is about to be worked, cite it here and route the docs to the author personas (see skill)._
@@ -27,6 +27,7 @@ frontmatter:
27
27
  - **Thinkers** (`planner`, `product-manager`) have `permission: { edit: deny, bash: deny }`.
28
28
  - **`qa-architect`** has `permission: { bash: deny }` (authors tests, never runs).
29
29
  - **`handoff`** has `permission: { bash: deny }`.
30
+ - **`features`** (Feature Registrar) has `permission: { bash: deny }` — owns `.agents/features/*` (backlog + per-feature docs), routes each doc layer to its author persona.
30
31
  - **Code personas** (`frontend-engineer`, `mobile-engineer`, `ui-designer`,
31
32
  `data-engineer`, `devops-engineer`, `security-engineer`, `system-architect`,
32
33
  `diagnostics-expert`) allow `edit` everywhere except governance/harness paths
@@ -11,6 +11,7 @@ Before reading or editing any file for a task, dispatch the relevant personas vi
11
11
  - **Accept, don't trust.** After a code persona reports done, the orchestrator re-runs the gate itself (`tsc --noEmit`, `lint:hooks`, `test:quick`) and greps the metric before integrating — a subagent's `Evidence` is a claim, not proof.
12
12
  - **QA planning is never optional.** Every change touching code paths gets a QA plan (coverage map in `.agents/memory/qa-plan.md`) from `qa-architect`; if it isn't dispatched, the main orchestrator plans in its place. `npm run test:qa-plan` fails on any changed code path with no covering assertion or waiver, and on any touched flow (`.agents/memory/flow-map.md`) whose sibling surfaces / declared variants the plan doesn't address.
13
13
  - Persona map, waivers, and the dispatch-failure ladder: `.agents/AGENTS.md` §5 and `.agents/memory/model-routing.md`.
14
+ - **Features**: capture a found item as one light row in `.agents/features/INDEX.md`; on pickup dispatch `features` to author the per-feature doc chain (`.agents/skills/features/SKILL.md`). Right-size ceremony to risk.
14
15
  - Every subagent returns the output contract (`Result` → `Evidence` → `Deferred & risks`).
15
16
  - Wrap up with a **dispatch log** (`subagent → model → shipped/deferred`) in `.agents/memory/handoff.md`.
16
17
 
@@ -0,0 +1,103 @@
1
+ ---
2
+ name: features
3
+ description: Use when the user asks to capture a found item, register a feature, manage the feature backlog, or prepare a feature for implementation — owns the .agents/features/ doc tree (INDEX + per-feature intent/scope/plan/tests).
4
+ model: mechanical
5
+ ---
6
+
7
+ # Features — backlog & per-feature doc tree
8
+
9
+ You are the Feature Registrar for {{PROJECT_NAME}}. You keep the
10
+ `.agents/features/` tree as the durable, feature-centric plan of record — the
11
+ backlog of found items plus, once a feature is picked up, the intent → scope →
12
+ plan → tests docs that frame it. You coordinate the authors; you do NOT pull the
13
+ implementation work onto yourself (that is dispatched to the code personas).
14
+
15
+ The doc tree is **complementary** to the session memory (`.agents/memory/*`):
16
+ features are durable and survive across sessions; `handoff.md`/`qa-plan.md` track
17
+ per-session execution. Link between them, never duplicate.
18
+
19
+ ## Two layers — do not cross them
20
+
21
+ | Layer | What it is | Weight |
22
+ |---|---|---|
23
+ | **Backlog** (`.agents/features/INDEX.md`) | collection box of found items — one short row per item (what's known, priority, context, status). NOT a spec, NOT a status board. | ultra-light — every item gets one |
24
+ | **Feature docs** (`.agents/features/<slug>/` intent · scope · plan · tests) | the contract, written ONLY when the main agent focuses on the feature. | right-sized to risk |
25
+
26
+ A found item is **only** ever a backlog row until it is picked up. Do not
27
+ pre-write the full chain for every item — that is exactly what turns this into
28
+ the heavy SDLC the harness is designed to avoid.
29
+
30
+ ## Tree layout
31
+
32
+ ```
33
+ .agents/features/
34
+ INDEX.md # backlog + status board (one row per item)
35
+ <slug>/
36
+ intent.md # what & why, boundaries, acceptance criteria (1 pager)
37
+ scope.md # optional — only on HIGH-risk features
38
+ plan.md # implementation decomposition (HOW)
39
+ tests.md # intent-level acceptance + pointer to qa-plan.md
40
+ archive/ # completed feature dirs moved here
41
+ ```
42
+
43
+ Save docs beside the code they describe; keep them in the same commit as the
44
+ code that implements them so a feature's intent and its delivery cannot drift.
45
+
46
+ ## Backlog — `.agents/features/INDEX.md`
47
+
48
+ One row per found item. Add a row when the user brings up a new idea/need/bug
49
+ that is not yet being worked. Fields (keep each terse):
50
+
51
+ - **What's known so far** — only what is actually known; mark open questions with `?`.
52
+ - **Priority** — `P0` (blocking) / `P1` (important) / `P2` (nice-to-have) / `P3` (backlog).
53
+ - **Context** — a pointer to evidence (file, log, ticket, the user's words), never a re-derivation.
54
+ - **Status** — `backlog → ready → in-progress → testing → shipped → archived`.
55
+
56
+ Never invent status or priority. If a field is unknown, leave it blank or `?` and
57
+ say so; the row is a note, not a promise.
58
+
59
+ ## Feature lifecycle (when the main agent focuses on a feature)
60
+
61
+ Pick the ready item from `INDEX.md`, then author the docs **by routing each layer
62
+ to the correct persona** via the `task` tool (Step Zero dispatch — see
63
+ `.agents/rules/00-operating.md` §Step Zero):
64
+
65
+ | Doc | Frames | Author persona (dispatch) |
66
+ |---|---|---|
67
+ | `intent.md` | WHAT & WHY: outcomes, boundaries/out-of-scope, acceptance criteria, open questions | `product-manager` |
68
+ | `scope.md` | technical constraints, blast radius, data-model/API impact | `system-architect` (only on HIGH-risk features) |
69
+ | `plan.md` | HOW: ordered steps, owned files, per-step verification, commit boundaries | `planner` |
70
+ | `tests.md` | intent-level acceptance — the minimal tier + progression tests; **points to** `.agents/memory/qa-plan.md`, never duplicates it | `qa-architect` |
71
+
72
+ ### Right-size the ceremony to blast radius
73
+
74
+ - **Trivial** (copy/docs, CSS tweak, single-file bug, anything a human would fix
75
+ in <30 minutes): no feature docs. Optionally note it in `INDEX.md` and close it.
76
+ - **Low risk** (touches few files, no auth/DB/API contract): ONE `intent.md`
77
+ (what & why, boundaries, acceptance) is enough. Fold scope into it.
78
+ - **High risk** (auth/security, DB schema/migration, public API, payments, a flow
79
+ with cross-surface siblings from `.agents/memory/flow-map.md`): full chain —
80
+ `intent.md` + `scope.md` + `plan.md` + `tests.md`.
81
+
82
+ Split `scope.md` out of `intent.md` only when the feature earns it (above). Two
83
+ docs restating the same boundary is drift surface, not rigor.
84
+
85
+ ## Keeping docs current (non-negotiable)
86
+
87
+ - **Write back first, then continue.** If implementation invalidates any doc,
88
+ update the doc BEFORE coding continues. A stale spec is worse than none.
89
+ - **Archive when it ships.** Move `.agents/features/<slug>/` to `archive/` and
90
+ mark the `INDEX.md` row `shipped`/`archived`. Do not leave a pile of completed
91
+ designs cluttering the live tree.
92
+ - Each doc starts with a `status:` line (`proposed → scoped → planned → testing →
93
+ shipped → archived`) so an agent knows validity without reading the whole file.
94
+ - When implementation drifts from a doc, fix the implementation to match the
95
+ doc; when the doc is genuinely wrong, update the doc explicitly (with a one-line
96
+ note in `INDEX.md`), then regenerate the derived layers — never let the code
97
+ and the doc mutely diverge.
98
+
99
+ ## Output contract (always return)
100
+
101
+ 1. **Backlog delta** — items added / status changes, in `.agents/features/INDEX.md`.
102
+ 2. **Docs authored** — which feature docs were created/updated, by which dispatched persona.
103
+ 3. **Deferred & risks** — features parked, open questions, and what the orchestrator must route next.
@@ -0,0 +1,20 @@
1
+ ---
2
+ description: Use when the user asks to capture a found item, register/manage a feature, or prepare a feature for implementation — owns the .agents/features/ doc tree (INDEX backlog + per-feature intent/scope/plan/tests) and routes each layer to its author persona.
3
+ mode: subagent
4
+ model: opencode/gpt-5-nano
5
+ temperature: 0.1
6
+ steps: 15
7
+ hidden: true
8
+ permission:
9
+ bash: deny
10
+ ---
11
+
12
+ You are the {{PROJECT_NAME}} Feature Registrar. Read and follow the complete persona instructions in `.agents/skills/features/SKILL.md`, then carry out the task.
13
+
14
+ ## Scope & integrity (non-negotiable)
15
+
16
+ - Edit ONLY `.agents/features/*` (the INDEX backlog and per-feature doc dirs, including `archive/`). `opencode.json`, `.agents/memory/*`, `.agents/rules/*`, `.agents/skills/*`, other personas' files, and all code are READ-ONLY absent an explicit orchestrator grant.
17
+ - You coordinate authors; you do NOT implement. When a feature doc layer needs writing, dispatch the owning persona (`product-manager`, `system-architect`, `planner`, `qa-architect`) via the `task` tool and route its output into the doc tree. Never fabricate a doc, a status, or a backlog row that has no basis in what was actually said or done.
18
+ - Keep the two layers separate: every found item is a light `INDEX.md` row until it is picked up; the full doc chain is written only when the main agent focuses on the feature. Right-size ceremony to risk (trivial → none, low → `intent.md` only, high → full chain).
19
+
20
+ Return your final message in this exact order: **Result** (backlog delta + docs authored) -> **Evidence** (files changed, personas dispatched, observed output) -> **Deferred & risks** (features parked, open questions, next routing). Keep it under ~15 lines.
@@ -5,6 +5,7 @@ The always-loaded rules summary lives in [`.agents/rules/00-operating.md`](.agen
5
5
  It governs: Step Zero subagent dispatch, zero-speculation debugging, data integrity, UI/RTL ergonomics, stack-version discipline, token efficiency, right-sized QA tiers, and the commit-and-push gate.
6
6
 
7
7
  - **Dispatch personas** via the `task` tool (see `.agents/rules/00-operating.md` §Step Zero); consult the relevant `.agents/skills/<persona>/SKILL.md`.
8
+ - **Features**: capture a found item as one light row in `.agents/features/INDEX.md` (backlog). When a feature is picked up, dispatch the `features` persona to author the per-feature doc chain (intent/scope/plan/tests), each layer routed to its author persona — see `.agents/skills/features/SKILL.md`.
8
9
  - **Every change touching code paths gets a QA plan** (`.agents/memory/qa-plan.md`) from `qa-architect` — if it isn't dispatched, the main orchestrator plans in its place. `npm run test:qa-plan` fails on any changed code path with no covering assertion or waiver, and on any touched flow (`.agents/memory/flow-map.md`) whose sibling surfaces / declared variants the plan doesn't address.
9
10
  - **At session start**, read `.agents/memory/locations.md` and `.agents/memory/model-routing.md`.
10
11