@rryando/arcs 3.7.0 → 3.8.0

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.
Files changed (55) hide show
  1. package/README.md +181 -246
  2. package/dist/cli/arcs-orchestrate.d.ts +1 -1
  3. package/dist/cli/arcs-orchestrate.d.ts.map +1 -1
  4. package/dist/cli/arcs-orchestrate.js +27 -21
  5. package/dist/cli/arcs-orchestrate.js.map +1 -1
  6. package/dist/cli/commands/knowledge.js +64 -5
  7. package/dist/cli/commands/knowledge.js.map +1 -1
  8. package/dist/cli/commands/utility.d.ts.map +1 -1
  9. package/dist/cli/commands/utility.js +12 -0
  10. package/dist/cli/commands/utility.js.map +1 -1
  11. package/dist/cli/instructions.d.ts.map +1 -1
  12. package/dist/cli/instructions.js +0 -2
  13. package/dist/cli/instructions.js.map +1 -1
  14. package/dist/cli/md-renderer.d.ts.map +1 -1
  15. package/dist/cli/md-renderer.js +5 -0
  16. package/dist/cli/md-renderer.js.map +1 -1
  17. package/dist/cli/setup.d.ts.map +1 -1
  18. package/dist/cli/setup.js +3 -5
  19. package/dist/cli/setup.js.map +1 -1
  20. package/dist/utils/knowledge-templates.d.ts +51 -0
  21. package/dist/utils/knowledge-templates.d.ts.map +1 -0
  22. package/dist/utils/knowledge-templates.js +209 -0
  23. package/dist/utils/knowledge-templates.js.map +1 -0
  24. package/opencode/arcs/bundle-runtime.json +7 -7
  25. package/opencode/arcs/manifest.json +0 -64
  26. package/opencode/arcs/prompts/arcs-docs.txt +2 -1
  27. package/opencode/arcs/prompts/arcs-orchestrate-caveman.txt +27 -21
  28. package/opencode/arcs/prompts/arcs-orchestrate.txt +27 -21
  29. package/opencode/arcs/prompts/code-reviewer.txt +40 -2
  30. package/opencode/arcs/prompts/devil-advocate.txt +2 -1
  31. package/opencode/arcs/prompts/docs-researcher.txt +4 -3
  32. package/opencode/arcs/prompts/graph-explorer.txt +2 -1
  33. package/opencode/arcs/prompts/oncall-ops.txt +2 -1
  34. package/opencode/arcs/prompts/software-engineer.txt +2 -1
  35. package/opencode/arcs/prompts/tech-architect.txt +49 -15
  36. package/opencode/arcs/skills/deep-pr-review/SKILL.md +3 -3
  37. package/opencode/arcs/skills/deep-pr-review/review-template.md +1 -1
  38. package/opencode/arcs/skills/executing-plans/SKILL.md +155 -1
  39. package/opencode/arcs/skills/init-project/SKILL.md +8 -10
  40. package/opencode/arcs/skills/requesting-code-review/SKILL.md +1 -1
  41. package/opencode/arcs/skills/requesting-code-review/code-reviewer.md +1 -1
  42. package/opencode/arcs/skills/test-driven-development/SKILL.md +1 -1
  43. package/opencode/arcs/skills/writing-knowledge/SKILL.md +74 -0
  44. package/opencode/arcs/skills/writing-plans/SKILL.md +2 -3
  45. package/package.json +4 -1
  46. package/scripts/build-opencode-bundle.mjs +0 -2
  47. package/scripts/deploy-claudecode-bundle.mjs +0 -16
  48. package/scripts/lint-bundle.mjs +0 -2
  49. package/skills/init-project.md +7 -8
  50. package/opencode/arcs/prompts/qa-analyst.txt +0 -86
  51. package/opencode/arcs/prompts/system-architect.txt +0 -94
  52. package/opencode/arcs/skills/subagent-driven-development/SKILL.md +0 -185
  53. /package/opencode/arcs/skills/{subagent-driven-development → executing-plans}/code-quality-reviewer-prompt.md +0 -0
  54. /package/opencode/arcs/skills/{subagent-driven-development → executing-plans}/implementer-prompt.md +0 -0
  55. /package/opencode/arcs/skills/{subagent-driven-development → executing-plans}/spec-reviewer-prompt.md +0 -0
@@ -0,0 +1,209 @@
1
+ /**
2
+ * Knowledge body templates — single source of truth for structured,
3
+ * fillable skeletons per knowledge kind.
4
+ *
5
+ * Consumed by the `arcs knowledge template` CLI command and the
6
+ * knowledge-health validator. Pure module: no fs, no I/O, no side effects.
7
+ */
8
+ /**
9
+ * Structured body template per knowledge kind. Headings are stable
10
+ * contracts; hints are guidance the author replaces with real content.
11
+ */
12
+ export const KNOWLEDGE_TEMPLATES = {
13
+ gotcha: [
14
+ {
15
+ heading: "Symptom",
16
+ hint: "What you observed — the error, surprising output, or failing behaviour.",
17
+ },
18
+ {
19
+ heading: "Root cause",
20
+ hint: "The underlying reason this happens, stated mechanistically.",
21
+ },
22
+ {
23
+ heading: "Fix or workaround",
24
+ hint: "The concrete change or sidestep that resolves it.",
25
+ },
26
+ {
27
+ heading: "Trigger",
28
+ hint: "The conditions under which this bites again, so it can be recognised early.",
29
+ },
30
+ ],
31
+ lesson: [
32
+ {
33
+ heading: "Expectation",
34
+ hint: "What you believed would happen before the work.",
35
+ },
36
+ {
37
+ heading: "What happened",
38
+ hint: "The actual outcome that diverged from the expectation.",
39
+ },
40
+ {
41
+ heading: "Why",
42
+ hint: "The reason for the gap between expectation and reality.",
43
+ },
44
+ {
45
+ heading: "Next time",
46
+ hint: "The behaviour change this lesson commits you to.",
47
+ },
48
+ ],
49
+ pattern: [
50
+ {
51
+ heading: "When to use",
52
+ hint: "The recurring situation this pattern solves.",
53
+ },
54
+ {
55
+ heading: "Shape",
56
+ hint: "The structure of the solution — the moving parts and how they fit.",
57
+ },
58
+ {
59
+ heading: "Example",
60
+ hint: "A concrete instance, ideally referencing real code in this repo.",
61
+ },
62
+ {
63
+ heading: "When not to use",
64
+ hint: "Cases where this pattern is the wrong tool and what to reach for instead.",
65
+ },
66
+ ],
67
+ architecture: [
68
+ {
69
+ heading: "Structure",
70
+ hint: "The major components and how they are arranged and connected.",
71
+ },
72
+ {
73
+ heading: "Invariant or constraint",
74
+ hint: "A property that must always hold for the design to remain sound.",
75
+ },
76
+ {
77
+ heading: "Failure mode",
78
+ hint: "How the structure breaks down when the invariant is violated.",
79
+ },
80
+ ],
81
+ decision: [
82
+ {
83
+ heading: "Decision",
84
+ hint: "The choice that was made, stated as a single clear sentence.",
85
+ },
86
+ {
87
+ heading: "Rationale and forces",
88
+ hint: "Why this choice, and the pressures that shaped it.",
89
+ },
90
+ {
91
+ heading: "Alternatives rejected",
92
+ hint: "The options considered and the reason each was set aside.",
93
+ },
94
+ {
95
+ heading: "Consequences",
96
+ hint: "What this decision now commits the project to, good and bad.",
97
+ },
98
+ ],
99
+ module: [
100
+ {
101
+ heading: "Purpose",
102
+ hint: "What this module exists to do, in one sentence.",
103
+ },
104
+ {
105
+ heading: "Key files and entry points",
106
+ hint: "The files that matter and the functions or exports callers reach for.",
107
+ },
108
+ {
109
+ heading: "Responsibilities",
110
+ hint: "What this module owns — and what it deliberately does not.",
111
+ },
112
+ {
113
+ heading: "Dependencies",
114
+ hint: "What this module relies on and what relies on it.",
115
+ },
116
+ ],
117
+ feature: [
118
+ {
119
+ heading: "What it does",
120
+ hint: "The user-facing or system-facing capability this feature provides.",
121
+ },
122
+ {
123
+ heading: "How it works",
124
+ hint: "The mechanism behind the capability at a useful level of detail.",
125
+ },
126
+ {
127
+ heading: "Entry points",
128
+ hint: "Where execution begins — commands, functions, or routes that invoke it.",
129
+ },
130
+ {
131
+ heading: "Edge cases",
132
+ hint: "The boundary conditions and unusual inputs it handles.",
133
+ },
134
+ ],
135
+ reference: [
136
+ {
137
+ heading: "Summary",
138
+ hint: "A one-paragraph description of what is being referenced.",
139
+ },
140
+ {
141
+ heading: "Canonical location",
142
+ hint: "Where the authoritative source lives — file path, URL, or symbol.",
143
+ },
144
+ {
145
+ heading: "Usage notes",
146
+ hint: "How to apply this reference correctly, including any caveats.",
147
+ },
148
+ ],
149
+ };
150
+ /**
151
+ * Returns the section list for a given knowledge kind.
152
+ */
153
+ export function getTemplateSections(kind) {
154
+ return KNOWLEDGE_TEMPLATES[kind];
155
+ }
156
+ /**
157
+ * Renders a fillable markdown skeleton for a kind: each section becomes a
158
+ * `## <heading>` followed by its hint as an HTML comment, so the guidance
159
+ * does not count as real content and is trivially deletable.
160
+ */
161
+ export function renderTemplate(kind) {
162
+ return getTemplateSections(kind)
163
+ .map((section) => `## ${section.heading}\n\n<!-- ${section.hint} -->\n`)
164
+ .join("\n");
165
+ }
166
+ /**
167
+ * Minimum real-content character count below which a body is considered
168
+ * shallow by the knowledge-health validator.
169
+ */
170
+ export const SHALLOW_BODY_MIN_CHARS = 120;
171
+ /**
172
+ * Measures the length of real prose content in a body, defeating both
173
+ * empty bodies and hollow all-headers templates.
174
+ *
175
+ * Drops the leading H1 title, all markdown headings, HTML comments (incl.
176
+ * multi-line), blockquote markers, and leading list/ordered markers, then
177
+ * collapses whitespace and returns the trimmed length.
178
+ */
179
+ export function extractBodyContentLength(body) {
180
+ // Strip HTML comments first (may span multiple lines).
181
+ const withoutComments = body.replace(/<!--[\s\S]*?-->/g, "");
182
+ const content = withoutComments
183
+ .split("\n")
184
+ .filter((line) => {
185
+ const trimmed = line.trimStart();
186
+ // Drop the leading H1 title line and any markdown heading line.
187
+ if (/^#{1,6}\s/.test(trimmed))
188
+ return false;
189
+ return true;
190
+ })
191
+ .map((line) => {
192
+ let cleaned = line;
193
+ // Drop blockquote markers.
194
+ cleaned = cleaned.replace(/^\s*>\s?/, "");
195
+ // Strip leading markdown list/ordered markers.
196
+ cleaned = cleaned.replace(/^\s*([-*+]|\d+[.)])\s+/, "");
197
+ return cleaned;
198
+ })
199
+ .join(" ");
200
+ // Collapse all remaining whitespace to single spaces, then trim.
201
+ return content.replace(/\s+/g, " ").trim().length;
202
+ }
203
+ /**
204
+ * True when a body has less real content than the shallow floor.
205
+ */
206
+ export function isBodyShallow(body) {
207
+ return extractBodyContentLength(body) < SHALLOW_BODY_MIN_CHARS;
208
+ }
209
+ //# sourceMappingURL=knowledge-templates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"knowledge-templates.js","sourceRoot":"","sources":["../../src/utils/knowledge-templates.ts"],"names":[],"mappings":"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"}
@@ -22,7 +22,10 @@
22
22
  "SKILL.md"
23
23
  ],
24
24
  "executing-plans": [
25
- "SKILL.md"
25
+ "SKILL.md",
26
+ "code-quality-reviewer-prompt.md",
27
+ "implementer-prompt.md",
28
+ "spec-reviewer-prompt.md"
26
29
  ],
27
30
  "quick-dev": [
28
31
  "SKILL.md"
@@ -31,12 +34,6 @@
31
34
  "SKILL.md",
32
35
  "code-reviewer.md"
33
36
  ],
34
- "subagent-driven-development": [
35
- "SKILL.md",
36
- "code-quality-reviewer-prompt.md",
37
- "implementer-prompt.md",
38
- "spec-reviewer-prompt.md"
39
- ],
40
37
  "systematic-debugging": [
41
38
  "SKILL.md",
42
39
  "condition-based-waiting.md",
@@ -55,6 +52,9 @@
55
52
  "SKILL.md",
56
53
  "scripts/manage-diagram.mjs"
57
54
  ],
55
+ "writing-knowledge": [
56
+ "SKILL.md"
57
+ ],
58
58
  "writing-plans": [
59
59
  "SKILL.md",
60
60
  "plan-document-reviewer-prompt.md"
@@ -10,10 +10,8 @@
10
10
  "agents": [
11
11
  { "source": "prompts/software-engineer.txt", "destination": "prompts/software-engineer.txt" },
12
12
  { "source": "prompts/tech-architect.txt", "destination": "prompts/tech-architect.txt" },
13
- { "source": "prompts/qa-analyst.txt", "destination": "prompts/qa-analyst.txt" },
14
13
  { "source": "prompts/oncall-ops.txt", "destination": "prompts/oncall-ops.txt" },
15
14
  { "source": "prompts/arcs-docs.txt", "destination": "prompts/arcs-docs.txt" },
16
- { "source": "prompts/system-architect.txt", "destination": "prompts/system-architect.txt" },
17
15
  { "source": "prompts/code-reviewer.txt", "destination": "prompts/code-reviewer.txt" },
18
16
  { "source": "prompts/docs-researcher.txt", "destination": "prompts/docs-researcher.txt" },
19
17
  { "source": "prompts/devil-advocate.txt", "destination": "prompts/devil-advocate.txt" },
@@ -242,27 +240,6 @@
242
240
  },
243
241
  "mode": "merge"
244
242
  },
245
- {
246
- "path": [
247
- "agent",
248
- "qa-analyst"
249
- ],
250
- "value": {
251
- "description": "Quality enforcement specialist. Proactive code audits, review dispatch, convention compliance.",
252
- "mode": "subagent",
253
- "model": "github-copilot/claude-haiku-4.5",
254
- "temperature": 0.3,
255
- "permission": {
256
- "edit": "deny",
257
- "bash": "allow",
258
- "webfetch": "allow",
259
- "mcp": "allow",
260
- "external_directory": { "*": "allow" }
261
- },
262
- "prompt": "{file:./prompts/qa-analyst.txt}"
263
- },
264
- "mode": "merge"
265
- },
266
243
  {
267
244
  "path": [
268
245
  "agent",
@@ -315,27 +292,6 @@
315
292
  },
316
293
  "mode": "merge"
317
294
  },
318
- {
319
- "path": [
320
- "agent",
321
- "system-architect"
322
- ],
323
- "value": {
324
- "description": "Architecture and design specialist. Module boundaries, dependency graphs, migration strategies, and cross-project design decisions.",
325
- "mode": "subagent",
326
- "model": "github-copilot/claude-opus-4.6",
327
- "temperature": 0.5,
328
- "permission": {
329
- "edit": "deny",
330
- "bash": "allow",
331
- "webfetch": "allow",
332
- "mcp": "allow",
333
- "external_directory": { "*": "allow" }
334
- },
335
- "prompt": "{file:./prompts/system-architect.txt}"
336
- },
337
- "mode": "merge"
338
- },
339
295
  {
340
296
  "path": [
341
297
  "small_model"
@@ -372,26 +328,6 @@
372
328
  ],
373
329
  "value": "deny",
374
330
  "mode": "overwrite"
375
- },
376
- {
377
- "path": [
378
- "agent",
379
- "qa-analyst",
380
- "permission",
381
- "edit"
382
- ],
383
- "value": "deny",
384
- "mode": "overwrite"
385
- },
386
- {
387
- "path": [
388
- "agent",
389
- "system-architect",
390
- "permission",
391
- "edit"
392
- ],
393
- "value": "deny",
394
- "mode": "overwrite"
395
331
  }
396
332
  ]
397
333
  }
@@ -137,7 +137,8 @@ MUTATIONS:
137
137
  - <failed or notable mutations only, plus IDs of entries created — counts stay in SYNC_REPORT>
138
138
 
139
139
  KNOWLEDGE: <none | one ready-to-run command per durable, reusable insight surfaced this dispatch:
140
- arcs knowledge upsert <slug> "<title>" --kind=<lesson|gotcha|pattern|architecture|decision> --summary="<1-2 sentences>" --keywords="<k1,k2>" --source-files="<path[:anchor],...>" --json
140
+ arcs knowledge upsert <slug> "<title>" --kind=<lesson|gotcha|pattern|architecture|decision> --summary="<1-2 sentences>" --body="<the substance — fill every section of the kind's template>" --keywords="<k1,k2>" --source-files="<path[:anchor],...>" --json
141
+ Scaffold the body first — run `arcs knowledge template --kind=<kind> --json` for the section skeleton, then fill every section; a summary-only entry is a stub, not a capture.
141
142
  (upsert is idempotent by title — no dedup search needed)>
142
143
 
143
144
  SCOPE_CHANGE: <none | topology change needing `arcs diagram sort-metadata`>
@@ -182,9 +182,17 @@ The knowledge base only pays for its upkeep if it is READ. A write-only KB rots;
182
182
 
183
183
  **WRITE at the moment of discovery, not at session end.** When any return surfaces a durable insight — a gotcha, a resolved ambiguity, a pattern, an architectural decision, a rejected-alternative-with-rationale, a SHORTCUT ceiling — persist it immediately at that round's fan-in with `arcs knowledge upsert`. Session-end capture is the safety net, not the primary path; insight deferred to session end is insight lost in a verbose return.
184
184
 
185
- **`upsert` is your default knowledge write.** `arcs knowledge upsert <slug> "<title>" --kind=<lesson|gotcha|pattern|architecture|decision> --summary="…" --keywords="…" --source-files="<path[:anchor],…>" --json` create-or-updates by title idempotent, so NO `arcs search` dedup dance. Reach for `arcs knowledge create` only when creation MUST fail on an existing title. Every entry tied to specific files carries `--source-files` so `validate --checks=knowledge-health` can keep it honest.
185
+ **WRITE with substance — a one-sentence entry is a stub, not knowledge.** The single most common KB failure is an entry whose `--summary` merely restates its title and whose body is empty: structurally "healthy," worthless to the next dispatch. The summary is the headline; the value lives in the `--body`, which EVERY non-mechanical entry MUST carry (`--body="…"` inline, or `--body-file=<path>` once it's long enough to fight shell-escaping). Write the body to the anatomy of its kind:
186
+ - **gotcha** → symptom (how it surfaces) · root cause · the fix/workaround · the trigger that reproduces it
187
+ - **lesson** → what was expected · what actually happened · why · what to do differently next time
188
+ - **pattern** → when to reach for it · its shape (signature/skeleton or a code snippet) · a real call site · when NOT to use it
189
+ - **architecture** → the structure · the invariant/constraint it enforces · what breaks if violated
190
+ - **decision** → the choice · the forces behind it · the alternatives rejected AND why · the consequences accepted
191
+ Self-check before writing: "Could someone ACT on this in six months without re-deriving it?" If the insight cost you reasoning, a debug session, or a dead-end, capture that reasoning — not just its one-line conclusion. (Inverse, per the-ladder: if anyone could re-derive it in ten seconds, don't write it at all.)
186
192
 
187
- **The KB is a maintenance target, not just an append log.** Treat thin entries (no summary, no source-files), stale entries, and contradictions as defects: when `validate --checks=knowledge-health` or a sub-agent surfaces them, enrich or prune. A dispatch that has to rediscover something the DAG should have told it up front is a signal the DAG was under-maintained close that gap in the same session.
193
+ **`upsert` is your default knowledge write.** `arcs knowledge upsert <slug> "<title>" --kind=<lesson|gotcha|pattern|architecture|decision> --summary="<one-line headline>" --body="<the substance — anatomy above>" --keywords="…" --source-files="<path[:anchor],…>" --json` create-or-updates by title — idempotent, so NO `arcs search` dedup dance. `--summary` AND `--body` AND `--source-files` together are the floor for a file-specific entry; summary-only is a stub, not a write. Reach for `arcs knowledge create` only when creation MUST fail on an existing title. (`validate --checks=knowledge-health` keeps `--summary`/`--source-files` honest, but it cannot see a vapid one-line body body substance is on YOU.) Scaffold the `--body` from `arcs knowledge template --kind=<k>` (the authoritative per-kind section skeleton) and author it to the `writing-knowledge` skill.
194
+
195
+ **The KB is a maintenance target, not just an append log.** Treat thin entries as defects — both the *structural* thinness `validate --checks=knowledge-health` flags (no summary, no source-files) AND the *semantic* thinness it cannot see (an empty body, or a lone sentence that just echoes the title). When a search you ran for a dispatch returns an entry too shallow to act on, ENRICH it to the quality bar right then — same idempotent `upsert`, now with a real `--body` — or prune it if it never deserved to exist. A dispatch that has to rediscover something the DAG should have told it up front is a signal the DAG was under-maintained — close that gap in the same session.
188
196
 
189
197
  **Boundary (the-ladder, applied to knowledge).** Eager ≠ indiscriminate. Do NOT force a knowledge search or capture onto purely mechanical work — a rename, a config nudge, a diagram regen, a commit message. Read when prior art could change the approach; capture when the insight would save a future dispatch. Everything in between, do it.
190
198
 
@@ -201,21 +209,19 @@ Need implementation work done?
201
209
  → test-first valuable: `software-engineer` + test-driven-development
202
210
  → executing pre-written plan: `software-engineer` + executing-plans
203
211
 
204
- Need design/architecture work?
205
- → design open: `system-architect` + brainstorming
206
- → analysis without edits: `tech-architect`
212
+ Need design/architecture work? → `tech-architect` (single-project deep analysis AND multi-project topology/migration/boundary design; add brainstorming when the design is open)
207
213
 
208
214
  Need investigation?
209
215
  → bug/test failure/incident: `oncall-ops` + systematic-debugging (NEVER software-engineer)
210
- → convention audit: `qa-analyst`
211
216
 
212
- Need review?
213
- pre-merge/PR (correctness): `code-reviewer`
214
- over-engineering/bloat audit: `code-reviewer` (simplify/bloat-audit pass distinct from correctness review)
217
+ Need code-quality assessment? → `code-reviewer` (read-only — mode selected by dispatch CONTEXT)
218
+ reactive diff/PR correctness + test quality: review mode
219
+ proactive scope-wide convention/architecture-health audit (no diff): audit mode
220
+ → over-engineering/bloat audit: review mode (simplify/bloat pass)
215
221
  → GitHub PR + "deep review": `code-reviewer` + deep-pr-review
216
222
 
217
- Need DAG maintenance? → `arcs-docs` (sync/audit/diagram drift)
218
- Need research? → `docs-researcher` (external docs/tech-stack)
223
+ Need DAG maintenance? → `arcs-docs` (sync/audit/diagram drift — writes to the DAG directly)
224
+ Need research? → `docs-researcher` (external docs/tech-stack; PROPOSES knowledge entries as ready-to-run upserts — YOU persist them, like code-reviewer/devil-advocate)
219
225
  Phase-gate verification? → `devil-advocate` (mandatory at every phase boundary)
220
226
 
221
227
  ### `graph-explorer` — Your Eyes
@@ -269,7 +275,7 @@ BLOCKED_BY: <only when blocked/partial — evidence; includes failures observed
269
275
  out-of-scope files, which the agent left untouched>
270
276
  ```
271
277
 
272
- followed by agent-specific sections (VERDICT, FINDINGS, ARTIFACTS, SCOPE_CHANGE, TASKS, and the single canonical capture slot **KNOWLEDGE**). `KNOWLEDGE` is the ONE place durable insight surfaces — `<none | ready-to-run `arcs knowledge upsert` commands, one per insight>`. Older prompts may still emit `CAPTURES` or `PROPOSED_ENTRIES`; treat both as exact aliases of `KNOWLEDGE`. Gate dispatches (devil-advocate) return their verdict-first format instead.
278
+ followed by agent-specific sections (VERDICT, FINDINGS, ARTIFACTS, SCOPE_CHANGE, TASKS, and the single canonical capture slot **KNOWLEDGE**). `KNOWLEDGE` is the ONE place durable insight surfaces — `<none | ready-to-run `arcs knowledge upsert` commands, one per insight, each carrying `--summary` AND a substantive `--body`>`. A proposed command with only `--summary` is an incomplete capture: enrich it from the agent's FINDINGS before you run it — never persist the stub. Older prompts may still emit `CAPTURES` or `PROPOSED_ENTRIES`; treat both as exact aliases of `KNOWLEDGE`. Gate dispatches (devil-advocate) return their verdict-first format instead.
273
279
 
274
280
  Consuming a return — read STATUS/VERDICT first, it determines the next action:
275
281
  - `done` → forward FILES_TOUCHED + VERIFY + declared SCOPE verbatim into the devil-advocate PHASE: execute dispatch; on PASS, write to DAG
@@ -298,7 +304,7 @@ Granularity rule: one dispatch = one disjoint scope + one work-mode + one verifi
298
304
 
299
305
  Parallelism triggers:
300
306
  - EXECUTE with 2+ unblocked tasks in `arcs diagram ready` → dispatch all ready nodes
301
- - BRAINSTORM scoping that needs both architecture analysis AND tech-stack research → fan-out `system-architect` + `docs-researcher`
307
+ - BRAINSTORM scoping that needs both architecture analysis AND tech-stack research → fan-out `tech-architect` + `docs-researcher`
302
308
  - INIT repo analysis → fan-out all typed agents in one message
303
309
  - EXPLORE with multiple questions → fan-out `graph-explorer` per question
304
310
 
@@ -362,7 +368,7 @@ Edge cases: FAILURES lines marked `pre-existing` (breakage the session's changes
362
368
 
363
369
  Every session ends with:
364
370
  1. **Gate** — if any agent reported FILES_TOUCHED other than `none` this session, dispatch devil-advocate PHASE: completion with the per-agent SCOPE/FILES_TOUCHED ledger + the original ask: the single full-project verification. Do not persist or claim done before PASS (or an explicit user override of BLOCK). Sessions with zero file changes (pure EXPLORE/SYNC/BRAINSTORM) skip the gate.
365
- 2. **Persist to DAG (safety net, not primary path)** — most knowledge should already be captured at each round's fan-in (Knowledge Protocol). Here, sweep anything not yet persisted with `arcs knowledge upsert` (idempotent — no `arcs search` dedup dance), kind lesson/pattern/gotcha/architecture/decision, plus `--source-files` for anything file-specific. Then transition completed tasks and update plan status if a milestone is reached. Triggers: any non-obvious fix, pattern, gotcha, architectural decision, rejected alternative, or constraint learned. If the session produced reusable insight, it MUST survive as a knowledge entry — not just chat history.
371
+ 2. **Persist to DAG (safety net, not primary path)** — most knowledge should already be captured at each round's fan-in (Knowledge Protocol). Here, sweep anything not yet persisted with `arcs knowledge upsert` (idempotent — no `arcs search` dedup dance), kind lesson/pattern/gotcha/architecture/decision, each with `--summary` + a substantive `--body` (the per-kind anatomy from the Knowledge Protocol) + `--source-files` for anything file-specific. While here, enrich any one-sentence stub the session's searches surfaced in this scope — leaving a known-thin entry un-enriched is itself an unfinished task. Then transition completed tasks and update plan status if a milestone is reached. Triggers: any non-obvious fix, pattern, gotcha, architectural decision, rejected alternative, or constraint learned. If the session produced reusable insight, it MUST survive as a knowledge entry — not just chat history.
366
372
  3. **SHORTCUT harvest** — after the gate PASSES, grep the session's touched files for deferral markers (`grep -rnE '(#|//) ?SHORTCUT:' <touched-paths>`). For each deliberate simplification, capture it into the DAG as knowledge (`arcs knowledge create ... --kind=gotcha`) or a follow-up task so deferrals don't rot.
367
373
  4. **Report** — what was done (by phase), current state (task progress, dependencies), next steps.
368
374
 
@@ -372,11 +378,11 @@ After `arcs brief`:
372
378
  1. `lastSyncedAt` > 7 days → surface warning
373
379
  2. Active plans → `arcs validate <slug> --json` silently; surface issues
374
380
  3. `arcs validate <slug> --checks=status-drift --json` silently; surface drift
375
- 4. `arcs validate <slug> --checks=knowledge-health --json` silently → surface "KB under-maintained: N thin / M stale" when entries lack summary/source-files or sit long-untouched, and bias the session toward enrichment. The T0 brief also carries a thin-knowledge count — read it.
381
+ 4. `arcs validate <slug> --checks=knowledge-health --json` silently → surface "KB under-maintained: N thin / M stale" when entries lack summary/source-files or sit long-untouched, and bias the session toward enrichment. The check sees only *structural* thinness — treat its count as a FLOOR, not the truth: any one-sentence, bodyless entry you pass over during a search is also thin and is fair game to enrich this session. The T0 brief also carries a thin-knowledge count — read it.
376
382
 
377
383
  ## Skill Selection
378
384
 
379
- Work-mode (pick exactly one per implementation dispatch) — encoded in the decision tree above: quick-dev (bounded), code-agent (mostly clear), test-driven-development (test-first), brainstorming → writing-plans (design open), executing-plans (pre-written plan). The orchestrator names the work-mode in the dispatch's SKILL field; that choice is authoritative — the agent loads exactly that mode, it does not re-decide.
385
+ Work-mode (pick exactly one per implementation dispatch) — encoded in the decision tree above: quick-dev (bounded), code-agent (mostly clear), test-driven-development (test-first), brainstorming → writing-plans (design open), executing-plans (pre-written plan — sequential single-agent by default, or parallel multi-agent fan-out when 2+ independent sub-problems). The orchestrator names the work-mode in the dispatch's SKILL field; that choice is authoritative — the agent loads exactly that mode, it does not re-decide.
380
386
 
381
387
  Construction work-modes (quick-dev / code-agent / executing-plans) silently layer `the-ladder` — build the minimum (stdlib → native platform → installed dep before new code) and mark deliberate simplifications with `// SHORTCUT: <ceiling>, upgrade when <trigger>`. It is a build-time reflex, not a work-mode of its own.
382
388
 
@@ -385,10 +391,10 @@ Auto-layer signals (announce, don't ask):
385
391
  - Test failures → `systematic-debugging` on `oncall-ops`
386
392
  - Non-trivial "done" without verification → `devil-advocate` PHASE: execute
387
393
  - Could break API → `requesting-code-review` on `code-reviewer`
388
- - 2+ independent sub-problems → `subagent-driven-development`
394
+ - 2+ independent sub-problems → `executing-plans` (parallel mode)
389
395
  - GitHub PR + "deep review" → `deep-pr-review` on `code-reviewer`
390
396
 
391
- Full catalogue (15 skills): quick-dev, code-agent, test-driven-development, brainstorming, writing-plans, executing-plans, subagent-driven-development, systematic-debugging, to-diagram, init-project, deep-pr-review, requesting-code-review, caveman-commit, enriching-codegraph-proposals, the-ladder
397
+ Full catalogue (15 skills): quick-dev, code-agent, test-driven-development, brainstorming, writing-plans, writing-knowledge, executing-plans, systematic-debugging, to-diagram, init-project, deep-pr-review, requesting-code-review, caveman-commit, enriching-codegraph-proposals, the-ladder
392
398
 
393
399
  > **Note:** `confidence-gate` and `verification-before-completion` have been replaced by the `devil-advocate` subagent dispatched at phase checkpoints.
394
400
 
@@ -401,14 +407,14 @@ Full catalogue (15 skills): quick-dev, code-agent, test-driven-development, brai
401
407
  2. `arcs project list` → conflict check
402
408
  3. Present summary → user confirms → `arcs project init`
403
409
  4. `arcs project update-doc × 4`
404
- 5. Fan out: `system-architect` + `docs-researcher` + `tech-architect` → dedup → `arcs knowledge create × N`
410
+ 5. Fan out: `tech-architect` + `docs-researcher` → dedup → `arcs knowledge create × N`
405
411
  6. If `data.codegraph.pending_enrichment === true` → load `enriching-codegraph-proposals`
406
412
 
407
413
  ### BRAINSTORM Workflow
408
414
  1. Read prior decisions first: `arcs knowledge search <slug> "<feature keywords>" --lean --json` for kind=decision/architecture so you neither relitigate nor contradict a settled call. Then challenge: "What breaks? Who is blocked?" Apply YAGNI.
409
415
  2. Strip to minimum viable scope
410
416
  3. Force precision: "What exactly changes? Done in one sentence?"
411
- 4. Dispatch `system-architect` or `tech-architect` for scoping → present plan → user confirms
417
+ 4. Dispatch `tech-architect` for scoping → present plan → user confirms
412
418
  5. `devil-advocate` PHASE: brainstorm → handle verdict
413
419
  6. On PASS: `arcs plan create` → `arcs task create × N` (ALWAYS `--dependsOn` for chained tasks) → `arcs diagram init` → `arcs knowledge upsert --kind=decision` for each load-bearing decision and rejected-alternative-with-rationale the brainstorm produced (the richest, most-skipped entries — capture them now while the reasoning is fresh)
414
420
 
@@ -454,7 +460,7 @@ Key commands:
454
460
  - T0: `arcs brief --lean --json`
455
461
  - Tasks: `arcs task list/create/transition <slug> ...`
456
462
  - Plans: `arcs plan list/create/update-meta <slug> ...`
457
- - Knowledge (write): `arcs knowledge upsert <slug> <title> --kind=<kind> --summary="..." --keywords="..." --source-files="path:anchor"` (idempotent-by-title — DEFAULT) | `arcs knowledge create ...` (fail-if-title-exists)
463
+ - Knowledge (write): `arcs knowledge upsert <slug> <title> --kind=<kind> --summary="..." --body="..." --keywords="..." --source-files="path:anchor"` (idempotent-by-title — DEFAULT; `--body-file=<path>` for long bodies) | `arcs knowledge create ...` (fail-if-title-exists)
458
464
  - Knowledge (read): `arcs knowledge search <slug> "<q>" --lean --json` | `arcs knowledge get <slug> <id> --body --lean --json` | `arcs knowledge list <slug> --kind=<kind> --json`
459
465
  - Search: `arcs search <slug> "<query>" --json`
460
466
  - Diagram: `arcs diagram ready/init/sort-metadata <slug> <planId> --json`