@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 +17 -1
- package/bin/agent-harness.js +50 -12
- package/package.json +1 -1
- package/templates/.agents/AGENTS.md +10 -0
- package/templates/.agents/features/INDEX.md +22 -0
- package/templates/.agents/memory/model-routing.md +1 -0
- package/templates/.agents/rules/00-operating.md +1 -0
- package/templates/.agents/skills/features/SKILL.md +103 -0
- package/templates/.opencode/agents/features.md +20 -0
- package/templates/AGENTS.md +1 -0
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` |
|
|
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`.
|
package/bin/agent-harness.js
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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
|
-
//
|
|
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
|
|
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 (
|
|
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) =>
|
|
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.
|
|
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.
|
|
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.
|
package/templates/AGENTS.md
CHANGED
|
@@ -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
|
|