peaks-loop 4.0.34 → 4.0.36

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 (72) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/dist/cli/commands/code-runtime-commands.d.ts +5 -2
  3. package/dist/cli/commands/code-runtime-commands.js +57 -2
  4. package/dist/cli/commands/core/doctor-command.d.ts +8 -0
  5. package/dist/cli/commands/core/doctor-command.js +44 -2
  6. package/dist/cli/commands/core/memory-command.js +65 -3
  7. package/dist/cli/commands/dispatch-commands.js +19 -5
  8. package/dist/cli/commands/dispatch-from-dag.js +17 -0
  9. package/dist/cli/commands/memory-commands.d.ts +59 -0
  10. package/dist/cli/commands/memory-commands.js +195 -19
  11. package/dist/cli/commands/request-commands.d.ts +8 -0
  12. package/dist/cli/commands/request-commands.js +23 -2
  13. package/dist/cli/commands/sub-agent-commands.js +2 -0
  14. package/dist/cli/commands/wave-plan-commands.d.ts +24 -0
  15. package/dist/cli/commands/wave-plan-commands.js +93 -0
  16. package/dist/services/context/build-dispatch-system-prompt.d.ts +66 -9
  17. package/dist/services/context/build-dispatch-system-prompt.js +132 -17
  18. package/dist/services/context/context-audit.d.ts +100 -0
  19. package/dist/services/context/context-audit.js +322 -0
  20. package/dist/services/context/context-schema.d.ts +1 -1
  21. package/dist/services/context/memory-index-reader.d.ts +26 -0
  22. package/dist/services/context/memory-index-reader.js +62 -30
  23. package/dist/services/context/memory-preflight-config.d.ts +33 -0
  24. package/dist/services/context/memory-preflight-config.js +32 -2
  25. package/dist/services/context/memory-preflight-service.d.ts +20 -1
  26. package/dist/services/context/memory-preflight-service.js +198 -31
  27. package/dist/services/context/summary-view.d.ts +54 -0
  28. package/dist/services/context/summary-view.js +114 -0
  29. package/dist/services/dispatch/file-overlap-wave-planner.d.ts +70 -0
  30. package/dist/services/dispatch/file-overlap-wave-planner.js +119 -0
  31. package/dist/services/dispatch/session-capsule.d.ts +23 -0
  32. package/dist/services/dispatch/session-capsule.js +56 -0
  33. package/dist/services/dispatch/slice-dag.d.ts +9 -0
  34. package/dist/services/dispatch/slice-dag.js +9 -1
  35. package/dist/services/dispatch/test-tool-detection.d.ts +12 -1
  36. package/dist/services/dispatch/test-tool-detection.js +14 -13
  37. package/dist/services/doctor/doctor-service/checks/l3-memory-health.d.ts +19 -2
  38. package/dist/services/doctor/doctor-service/checks/l3-memory-health.js +143 -19
  39. package/dist/services/ide/adapters/claude-code-adapter.d.ts +10 -0
  40. package/dist/services/ide/adapters/claude-code-adapter.js +20 -1
  41. package/dist/services/ide/ide-types.d.ts +15 -0
  42. package/dist/services/job/job-types.d.ts +3 -3
  43. package/dist/services/memory/memory-ingest-service.d.ts +79 -0
  44. package/dist/services/memory/memory-ingest-service.js +225 -0
  45. package/dist/services/memory/memory-rotate-service.d.ts +88 -0
  46. package/dist/services/memory/memory-rotate-service.js +373 -0
  47. package/dist/services/memory/project-memory-service/index/ranking.d.ts +9 -1
  48. package/dist/services/memory/project-memory-service/index/ranking.js +25 -13
  49. package/dist/services/memory/project-memory-service/index/reindex.d.ts +75 -0
  50. package/dist/services/memory/project-memory-service/index/reindex.js +207 -0
  51. package/dist/services/memory/project-memory-service/index/search.js +14 -24
  52. package/dist/services/memory/project-memory-service/index.d.ts +7 -3
  53. package/dist/services/memory/project-memory-service/index.js +6 -2
  54. package/dist/services/memory/project-memory-service/parsers/frontmatter.d.ts +80 -3
  55. package/dist/services/memory/project-memory-service/parsers/frontmatter.js +167 -28
  56. package/dist/services/memory/project-memory-service/types.d.ts +31 -1
  57. package/dist/services/memory/project-memory-service/types.js +76 -1
  58. package/dist/services/preferences/preferences-types.d.ts +14 -0
  59. package/dist/services/preferences/preferences-types.js +8 -0
  60. package/dist/services/share/run-state-contract.d.ts +1 -1
  61. package/package.json +5 -5
  62. package/skills/bee/peaks-qa/SKILL.md +2 -0
  63. package/skills/bee/peaks-qa/references/qa-sub-agent-dispatch.md +12 -0
  64. package/skills/bee/peaks-rd/SKILL.md +2 -0
  65. package/skills/bee/peaks-rd/references/rd-sub-agent-dispatch.md +14 -0
  66. package/skills/bee/peaks-txt/SKILL.md +2 -0
  67. package/skills/bee/peaks-ui/SKILL.md +2 -0
  68. package/skills/peaks-code/SKILL.md +9 -1
  69. package/skills/peaks-code/references/context-governance.md +29 -0
  70. package/skills/peaks-code/references/runbook.md +6 -0
  71. package/skills/peaks-code/references/step-11-memory-sediment.md +35 -0
  72. package/skills/peaks-doctor/SKILL.md +2 -0
@@ -1,4 +1,34 @@
1
- export type ProjectMemoryKind = 'project' | 'rule' | 'decision' | 'reference' | 'feedback' | 'convention' | 'module' | 'lesson';
1
+ /**
2
+ * Canonical memory-kind vocabulary — the single source of truth.
3
+ *
4
+ * The union type, the accepted-kind set in the frontmatter parser, the
5
+ * hot/warm tier map below, `KIND_ORDER` in the reindex view, and the CLI
6
+ * `--kind` help text all derive from this tuple. Adding a kind here is the
7
+ * only edit required; TypeScript then forces `MEMORY_KIND_TIER` to cover it.
8
+ *
9
+ * Slice 2026-09-10-memory-vocab-and-rotate (E): the original 8 kinds are
10
+ * unchanged. The 13 appended kinds were observed on disk with real values
11
+ * that the index schema rejected (`peaks memory reindex` reported them as
12
+ * `unrecognized kind value`). Accepting them moves those files into the
13
+ * index; files with no kind field at all stay reported as unclassified.
14
+ */
15
+ export declare const PROJECT_MEMORY_KINDS: readonly ["project", "rule", "decision", "reference", "feedback", "convention", "module", "lesson", "bug", "investigation", "technical-pattern", "project-rule", "design", "handoff", "session-handoff", "project-todo", "publish-closure", "project-closure", "slice-closure", "slice-pilot-findings", "sediment"];
16
+ export type ProjectMemoryKind = (typeof PROJECT_MEMORY_KINDS)[number];
17
+ /** Hot kinds keep their body in the always-available index; warm kinds are
18
+ * indexed with the same entry shape but read on demand. */
19
+ export type MemoryKindTier = 'hot' | 'warm';
20
+ /**
21
+ * Hot/warm tier per kind. Insertion order IS the deterministic section order
22
+ * used by the generated `MEMORY.md` (`KIND_ORDER` in `index/reindex.ts`),
23
+ * so this object's key order is load-bearing — append new kinds at the end
24
+ * of their tier block rather than reshuffling existing entries.
25
+ *
26
+ * The `Record<ProjectMemoryKind, MemoryKindTier>` annotation makes a missing
27
+ * tier a compile error whenever `PROJECT_MEMORY_KINDS` grows.
28
+ */
29
+ export declare const MEMORY_KIND_TIER: Record<ProjectMemoryKind, MemoryKindTier>;
30
+ export declare const HOT_MEMORY_KINDS: readonly ProjectMemoryKind[];
31
+ export declare const WARM_MEMORY_KINDS: readonly ProjectMemoryKind[];
2
32
  export type ExtractedProjectMemory = {
3
33
  title: string;
4
34
  kind: ProjectMemoryKind;
@@ -6,4 +6,79 @@
6
6
  // from here, and the top-level `index.ts` re-exports them for back-compat
7
7
  // with downstream callers (CLI commands, audit writers, presence service).
8
8
  // ---------------------------------------------------------------------------
9
- export {};
9
+ /**
10
+ * Canonical memory-kind vocabulary — the single source of truth.
11
+ *
12
+ * The union type, the accepted-kind set in the frontmatter parser, the
13
+ * hot/warm tier map below, `KIND_ORDER` in the reindex view, and the CLI
14
+ * `--kind` help text all derive from this tuple. Adding a kind here is the
15
+ * only edit required; TypeScript then forces `MEMORY_KIND_TIER` to cover it.
16
+ *
17
+ * Slice 2026-09-10-memory-vocab-and-rotate (E): the original 8 kinds are
18
+ * unchanged. The 13 appended kinds were observed on disk with real values
19
+ * that the index schema rejected (`peaks memory reindex` reported them as
20
+ * `unrecognized kind value`). Accepting them moves those files into the
21
+ * index; files with no kind field at all stay reported as unclassified.
22
+ */
23
+ export const PROJECT_MEMORY_KINDS = [
24
+ // Original 8 (pre-2026-09-10).
25
+ 'project',
26
+ 'rule',
27
+ 'decision',
28
+ 'reference',
29
+ 'feedback',
30
+ 'convention',
31
+ 'module',
32
+ 'lesson',
33
+ // Slice E expansion — observed on-disk values, hot tier.
34
+ 'bug',
35
+ 'investigation',
36
+ 'technical-pattern',
37
+ 'project-rule',
38
+ // Slice E expansion — observed on-disk values, warm tier.
39
+ 'design',
40
+ 'handoff',
41
+ 'session-handoff',
42
+ 'project-todo',
43
+ 'publish-closure',
44
+ 'project-closure',
45
+ 'slice-closure',
46
+ 'slice-pilot-findings',
47
+ 'sediment'
48
+ ];
49
+ /**
50
+ * Hot/warm tier per kind. Insertion order IS the deterministic section order
51
+ * used by the generated `MEMORY.md` (`KIND_ORDER` in `index/reindex.ts`),
52
+ * so this object's key order is load-bearing — append new kinds at the end
53
+ * of their tier block rather than reshuffling existing entries.
54
+ *
55
+ * The `Record<ProjectMemoryKind, MemoryKindTier>` annotation makes a missing
56
+ * tier a compile error whenever `PROJECT_MEMORY_KINDS` grows.
57
+ */
58
+ export const MEMORY_KIND_TIER = {
59
+ // hot — full body kept in the index
60
+ feedback: 'hot',
61
+ decision: 'hot',
62
+ rule: 'hot',
63
+ convention: 'hot',
64
+ module: 'hot',
65
+ lesson: 'hot',
66
+ bug: 'hot',
67
+ investigation: 'hot',
68
+ 'technical-pattern': 'hot',
69
+ 'project-rule': 'hot',
70
+ // warm — same entry shape, read on demand
71
+ project: 'warm',
72
+ reference: 'warm',
73
+ design: 'warm',
74
+ handoff: 'warm',
75
+ 'session-handoff': 'warm',
76
+ 'project-todo': 'warm',
77
+ 'publish-closure': 'warm',
78
+ 'project-closure': 'warm',
79
+ 'slice-closure': 'warm',
80
+ 'slice-pilot-findings': 'warm',
81
+ sediment: 'warm'
82
+ };
83
+ export const HOT_MEMORY_KINDS = PROJECT_MEMORY_KINDS.filter((kind) => MEMORY_KIND_TIER[kind] === 'hot');
84
+ export const WARM_MEMORY_KINDS = PROJECT_MEMORY_KINDS.filter((kind) => MEMORY_KIND_TIER[kind] === 'warm');
@@ -127,9 +127,23 @@ export interface ProjectPreferences {
127
127
  */
128
128
  readonly memoryPreflight?: {
129
129
  readonly enabled?: boolean;
130
+ /** Back-compat token cap; converted to bytes as `maxTokens * 4`. */
130
131
  readonly maxTokens?: number;
132
+ /** Back-compat hot item cap; `hotItemCap` overrides it when set. */
131
133
  readonly listCap?: number;
132
134
  readonly contentCacheBytes?: number;
135
+ /** Slice 2026-09-09-memory-retrieval: hard byte cap on the block. */
136
+ readonly maxBytes?: number;
137
+ /** Slice 2026-09-09-memory-retrieval: max hot items (default 10). */
138
+ readonly hotItemCap?: number;
139
+ /** Slice 2026-09-09-memory-retrieval: max warm items (default 4; 0 disables). */
140
+ readonly warmItemCap?: number;
141
+ /** Slice 2026-09-09-memory-retrieval: min task-token hits for warm eligibility. */
142
+ readonly warmMinTokenHits?: number;
143
+ /** Slice 2026-09-09-memory-retrieval: soft selection wall-clock budget (ms). */
144
+ readonly selectionTimeBudgetMs?: number;
145
+ /** Slice 2026-09-09-memory-retrieval: inline memo bodies (default false). */
146
+ readonly includeBodies?: boolean;
133
147
  };
134
148
  }
135
149
  export type FanoutMode = 'fan-out';
@@ -48,5 +48,13 @@ export const DEFAULT_PREFERENCES = {
48
48
  maxTokens: 1200,
49
49
  listCap: 12,
50
50
  contentCacheBytes: 6000,
51
+ // Slice 2026-09-09-memory-retrieval tiered budget (see
52
+ // memory-preflight-config.ts::DEFAULTS).
53
+ maxBytes: 4800,
54
+ hotItemCap: 10,
55
+ warmItemCap: 4,
56
+ warmMinTokenHits: 1,
57
+ selectionTimeBudgetMs: 200,
58
+ includeBodies: false,
51
59
  },
52
60
  };
@@ -64,8 +64,8 @@ export declare const RunStateContractSchema: z.ZodObject<{
64
64
  status: z.ZodEnum<{
65
65
  blocked: "blocked";
66
66
  failed: "failed";
67
- running: "running";
68
67
  done: "done";
68
+ running: "running";
69
69
  paused: "paused";
70
70
  }>;
71
71
  current_step: z.ZodString;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "peaks-loop",
3
- "version": "4.0.34",
3
+ "version": "4.0.36",
4
4
  "description": "Loop Engineering CLI — workflow primitive / loop guards / evaluators / slice orchestration",
5
5
  "author": "SquabbyZ",
6
6
  "keywords": [
@@ -101,10 +101,10 @@
101
101
  "fzf": "^0.5.2",
102
102
  "yaml": "^2.9.0",
103
103
  "zod": "^4.4.3",
104
- "peaks-loop-internal-runtime": "0.0.19",
105
- "peaks-loop-shared": "0.0.68",
106
- "peaks-loop-shared-channel": "0.0.36",
107
- "peaks-loop-mut": "0.1.32"
104
+ "peaks-loop-internal-runtime": "0.0.21",
105
+ "peaks-loop-shared-channel": "0.0.38",
106
+ "peaks-loop-shared": "0.0.70",
107
+ "peaks-loop-mut": "0.1.34"
108
108
  },
109
109
  "devDependencies": {
110
110
  "@changesets/cli": "2.31.1",
@@ -210,6 +210,8 @@ Do not own product scope or implementation. Do not modify runtime configuration.
210
210
 
211
211
  QA sub-agents (qa / qa-business / qa-perf / qa-security) follow the same G7 metadata-only + G8.6 share protocol as RD. Detailed: `skills/peaks-code/references/context-governance.md`.
212
212
 
213
+ **Large tool output (> 2 KB) MUST NOT be dumped into the orchestrator's context** — use `--summary` (`peaks doctor --summary`, `peaks memory list --summary`, `peaks request list --summary`) or write to a file and `Read` selectively. Rationale (measured, session 2026-09-07-session-245530): full-envelope dumps cost ≈ 40K tokens of a 68%-full 1M window. `--summary` is an additive view — no information is removed. → `skills/peaks-code/references/context-governance.md` §G0.
214
+
213
215
  → see `references/qa-context-governance.md` for the full G7 / G8.6 / G9 protocol + QA sub-agent prompt template.
214
216
 
215
217
  ## References
@@ -59,6 +59,18 @@ What the sub-agent **MUST** still do:
59
59
 
60
60
  If `--type` is `docs` or `chore`, return `{"status":"skipped","reason":"type=<type>"}` and exit — there is no acceptance surface to plan tests for.
61
61
 
62
+ ## Final report cap (mandatory, slice 2026-09-10-context-audit-and-discipline)
63
+
64
+ Your FINAL report to the parent MUST be **≤ 40 lines and ≤ 2 KB**. Write any longer detail into the artifact file you already own; the parent can `Read` that file for the full detail, so nothing is lost. The report itself MUST still carry:
65
+
66
+ - changed files (one line each)
67
+ - the exact commands you ran
68
+ - pass/fail counts
69
+ - tsc status
70
+ - any blocker
71
+
72
+ Do NOT paste file contents, full tool output, or logs into the report. **Rationale (measured, session 2026-09-07-session-245530):** 20 sub-agent final reports ≈ 60 KB ≈ 15K tokens of the orchestrator's window — the report is an index into the artifact, not a copy of it. This rule is also machine-injected into every dispatch prompt (`REPORT_CAP_BLOCK` in `src/services/context/build-dispatch-system-prompt.ts`); this doc and that constant MUST stay in lockstep.
73
+
62
74
  ## Test Tool Detection (mandatory)
63
75
 
64
76
  The dispatch CLI (`peaks sub-agent dispatch`) automatically prepends a Test Tool Detection block to every sub-agent prompt — telling the sub-agent to read `package.json#scripts.test` first and use the project-local runner (`./node_modules/.bin/<runner>` or `pnpm test -- <file>`). NEVER use `npx <runner>`. This rule is machine-injected, not a prompt ritual — every sub-agent gets it including rd/qa/ui/txt/sc.
@@ -239,6 +239,8 @@ The main RD loop MUST call `peaks job karpathy-cost-check` after every `peaks re
239
239
 
240
240
  RD sub-agent prompt template MUST include the G7 path convention + G8.6 share protocol. Detailed protocol: `skills/peaks-code/references/context-governance.md`.
241
241
 
242
+ **Large tool output (> 2 KB) MUST NOT be dumped into the orchestrator's context** — use `--summary` (`peaks memory reindex --summary`, `peaks memory list --summary`, `peaks doctor --summary`, `peaks request list --summary`) or write to a file and `Read` selectively. Rationale (measured, session 2026-09-07-session-245530): 4 full `reindex --json` dumps ≈ 40K tokens of a 68%-full 1M window. `--summary` is an additive view — no information is removed. → `skills/peaks-code/references/context-governance.md` §G0.
243
+
242
244
  → see `references/rd-context-governance.md` for the full G7 / G8.6 / G9 protocol + RD sub-agent prompt template.
243
245
 
244
246
  ## Sub-stages (Plan 3 — strategic + tactical split)
@@ -113,6 +113,20 @@ Any RD/QA/SC sub-agent dispatched by `peaks sub-agent dispatch --from-dag` (or b
113
113
 
114
114
  ---
115
115
 
116
+ ## Final report cap (mandatory, slice 2026-09-10-context-audit-and-discipline)
117
+
118
+ Your FINAL report to the parent MUST be **≤ 40 lines and ≤ 2 KB**. Write any longer detail into the artifact file you already own (registered via `--write-artifact`); the parent can `Read` that file for the full detail, so nothing is lost. The report itself MUST still carry:
119
+
120
+ - changed files (one line each)
121
+ - the exact commands you ran
122
+ - pass/fail counts
123
+ - tsc status
124
+ - any blocker
125
+
126
+ Do NOT paste file contents, full tool output, or logs into the report. **Rationale (measured, session 2026-09-07-session-245530):** 20 sub-agent final reports ≈ 60 KB ≈ 15K tokens of the orchestrator's window — the report is an index into the artifact, not a copy of it. This rule is also machine-injected into every dispatch prompt (`REPORT_CAP_BLOCK` in `src/services/context/build-dispatch-system-prompt.ts`); this doc and that constant MUST stay in lockstep.
127
+
128
+ ---
129
+
116
130
  ## Test Tool Detection (mandatory)
117
131
 
118
132
  The dispatch CLI (`peaks sub-agent dispatch`) automatically prepends a Test Tool Detection block to every sub-agent prompt — telling the sub-agent to read `package.json#scripts.test` first and use the project-local runner (`./node_modules/.bin/<runner>` or `pnpm test -- <file>`). NEVER use `npx <runner>`. This rule is machine-injected, not a prompt ritual — every sub-agent gets it including rd/qa/ui/txt/sc.
@@ -283,6 +283,8 @@ Reference: `references/context-capsule.md`.
283
283
 
284
284
  > peaks-txt is the TXT reducer; it sees the metadata-only view from G7 + the share entries from G8. The TXT handoff summarizes the slice at the slice-close gate. Detailed: `skills/peaks-code/references/context-governance.md`.
285
285
 
286
+ **Large tool output (> 2 KB) MUST NOT be dumped into the orchestrator's context** — use `--summary` (`peaks request list --summary`, `peaks memory list --summary`, `peaks memory reindex --summary`) or write to a file and `Read` selectively. Rationale (measured, session 2026-09-07-session-245530): full-envelope dumps cost ≈ 40K tokens of a 68%-full 1M window. `--summary` is an additive view — no information is removed. → `skills/peaks-code/references/context-governance.md` §G0.
287
+
286
288
  ### G8 — TXT reducer sees share entries on completion
287
289
 
288
290
  When TXT reduces a batch, it consumes:
@@ -333,6 +333,8 @@ Do not own backend architecture, non-UI implementation, runtime hook installatio
333
333
 
334
334
  UI sub-agents follow the same G7 metadata-only + G8.6 share protocol. UI artifacts are large binary-ish; the 1MB artifact size limit (G7.3) applies. Detailed: `skills/peaks-code/references/context-governance.md`.
335
335
 
336
+ **Large tool output (> 2 KB) MUST NOT be dumped into the orchestrator's context** — use `--summary` (`peaks request list --summary`, `peaks memory list --summary`) or write to a file and `Read` selectively. Rationale (measured, session 2026-09-07-session-245530): full-envelope dumps cost ≈ 40K tokens of a 68%-full 1M window. `--summary` is an additive view — no information is removed. → `skills/peaks-code/references/context-governance.md` §G0.
337
+
336
338
  ### G7 — UI sub-agent protocol
337
339
 
338
340
  1. Write design draft / component scaffold to `.peaks/_sub_agents/<sid>/artifacts/<rid>-ui-001.md` (size ≤ 1MB).
@@ -296,7 +296,7 @@ After final validation, refresh project-local standards via `peaks standards ini
296
296
 
297
297
  ## Peaks-Loop Step 11: Memory sediment (BLOCKING on workflow complete)
298
298
 
299
- > **Hard rule.** Code MUST NOT declare a workflow complete until Step 11 has produced ≥ 1 file in `.peaks/memory/` OR the user has explicitly approved a no-sediment outcome via AskUserQuestion. Canonical CLI: `peaks memory extract --project <repo> --artifact .peaks/_runtime/<sessionId>/txt/handoff.md --apply --json` (the artifact-scoped extract; the batch-scoped sibling `peaks project memories:extract` is for non-handoff flows only). Substeps 11a/11b/11c/11d (Gate A/B/C), D-010 fix root cause check → `references/step-11-memory-sediment.md` + `references/runbook.md` §Step 11.
299
+ > **Hard rule.** Code MUST NOT declare a workflow complete until Step 11 has produced ≥ 1 file in `.peaks/memory/` OR the user has explicitly approved a no-sediment outcome via AskUserQuestion. Canonical CLI: `peaks memory extract --project <repo> --artifact .peaks/_runtime/<sessionId>/txt/handoff.md --apply --json` (the artifact-scoped extract; the batch-scoped sibling `peaks project memories:extract` is for non-handoff flows only). **Single authority:** inside a peaks-code workflow, sedimenting memory writes to `.peaks/memory/`; the IDE-side memory dir (`~/.claude/projects/<hash>/memory/`) is a session note, not the authority and is read-only for peaks — pull any session note in with `peaks memory ingest --apply`, and keep the index in sync with `peaks memory reindex --apply`. Substeps 11a/11b/11c/11d (Gate A/B/C), 11e (index hygiene), 11f (IDE-side ingest), D-010 fix root cause check → `references/step-11-memory-sediment.md` + `references/runbook.md` §Step 11.
300
300
 
301
301
  ## Peaks-Loop External references and lifecycle
302
302
 
@@ -310,6 +310,14 @@ After final validation, refresh project-local standards via `peaks standards ini
310
310
 
311
311
  Main LLM reducer sees metadata-only view (~200 chars/sub-agent); on-demand `Read` for full content. Threshold table: 50% soft warn, 75% `CONTEXT_NEAR_LIMIT`, 80% hard reject (CLI + hook double-guard). → `references/context-governance.md`.
312
312
 
313
+ ## Large tool output discipline (BLOCKING — slice 2026-09-10-context-audit-and-discipline)
314
+
315
+ > **Hard rule.** Any tool output larger than **2 KB** MUST NOT be dumped into the orchestrator's own context. Use `--summary` (bounded counts + names-of-first-N, ≤ 2 KB) when the command offers it — `peaks memory reindex --summary`, `peaks memory list --summary`, `peaks doctor --summary`, `peaks request list --summary` — otherwise write the output to a file and `Read` only the slice you need. The default envelopes are unchanged; `--summary` is strictly opt-in.
316
+ >
317
+ > **Why (measured, not cargo-cult).** In session `2026-09-07-session-245530` the orchestrator spent ~68% of a 1M window on its OWN context. Two offenders dominated: 4 × dumping a full `peaks memory reindex --json` unclassified array ≈ 160 KB ≈ 40K tokens, and 20 × sub-agent final reports ≈ 60 KB ≈ 15K tokens. Neither was dispatch boilerplate — both were the orchestrator reading things it did not need in full. `peaks code context-audit` now measures this per group (`{tool, key, bytes, pctOfTotal, count}`); run it when the window feels heavy.
318
+ >
319
+ > **Quality guard.** `--summary` removes no information — it is an additive view. Every path, name and count stays on disk and is re-readable by re-running the command without the flag. Never silently drop data; shrink the in-context copy instead.
320
+
313
321
  ## Sub-agent cross-batch signal — G8.4 share / shared-read / await
314
322
 
315
323
  Three CLI primitives: `peaks sub-agent share / shared-read / await` (last-write-wins, ≤ 1KB warn / ≥ 64KB reject). Channel gitignored under `.peaks/_sub_agents/<sessionId>/shared/`.
@@ -3,6 +3,35 @@
3
3
  > Slice #010 (G7 + G8 + G9 context-governance push).
4
4
  > See: `.peaks/memory/sub-agent-context-minimal-occupation.md` + `sub-agent-shared-channel-cross-completion.md` for the red lines.
5
5
 
6
+ ## G0 — orchestrator large-tool-output discipline (slice 2026-09-10-context-audit-and-discipline)
7
+
8
+ ### The measurement (session `2026-09-07-session-245530`, ~68% of a 1M window)
9
+
10
+ The real token cost is the ORCHESTRATOR's own context — not dispatch boilerplate:
11
+
12
+ | Offender | Volume | Cost |
13
+ |---|---|---|
14
+ | 4 × full `peaks memory reindex --json` unclassified array | ≈ 160 KB | ≈ 40K tokens |
15
+ | 20 × sub-agent final reports | ≈ 60 KB | ≈ 15K tokens |
16
+ | several `cat` of large docs | ≈ 15 KB | ≈ 4K tokens |
17
+
18
+ `peaks code context-now` reports a RATIO only. `peaks code context-audit --project <root> --json` reports WHAT fills the window — top-N groups of `{tool, key, bytes, pctOfTotal, count}` — so the next session can name the offender instead of guessing. Read-only, fail-soft (`available: false` + reason; never blocks, never exits non-zero).
19
+
20
+ ### The rule (BLOCKING)
21
+
22
+ - Tool output **> 2 KB** MUST NOT be dumped into the orchestrator's context.
23
+ - Prefer the opt-in `--summary` flag, which emits counts + names-of-first-N (≤ 2 KB) instead of the full array:
24
+ - `peaks memory reindex --summary`
25
+ - `peaks memory list --summary`
26
+ - `peaks doctor --summary` (JSON envelope)
27
+ - `peaks request list --summary`
28
+ - When a command has no `--summary`, write the output to a file and `Read` only the needed slice (offset/limit), or pipe through a filter before it reaches the orchestrator.
29
+ - Default (no flag) envelopes are byte-identical to before — `--summary` is strictly opt-in, so back-compat is preserved.
30
+
31
+ ### Quality guard (binding)
32
+
33
+ `--summary` is an ADDITIVE view. It removes no information: every path, name and count remains on disk and is re-readable by re-running the same command without the flag. Silently dropping data is forbidden; shrinking the in-context copy is the goal. The sub-agent FINAL report cap (≤ 40 lines / 2 KB, detail in the artifact the parent can `Read`) follows the same principle — see the dispatch prompt's `## Final report cap (mandatory)` block.
34
+
6
35
  ## G7 — sub-agent context minimal-occupation (metadata-only + 按需 Read)
7
36
 
8
37
  ### Path convention
@@ -215,6 +215,12 @@ peaks memory extract --project <repo> --artifact .peaks/_runtime/<id>/txt/handof
215
215
  # --apply is REQUIRED to write .peaks/memory/; without it the command only
216
216
  # previews. The extract regenerates index.json in the same call.
217
217
 
218
+ # 10d. Index hygiene (single authority: .peaks/memory/ is peaks-owned):
219
+ peaks memory reindex --project <repo> --json # drift report (unclassified / orphans both ways)
220
+ peaks memory reindex --project <repo> --apply --json # rebuild index.json + regenerate MEMORY.md
221
+ peaks memory ingest --project <repo> --json # preview IDE-side session notes
222
+ peaks memory ingest --project <repo> --apply --json # import them into .peaks/memory (IDE side stays read-only)
223
+
218
224
  # 11. Peaks-Loop Final snapshot
219
225
  peaks project dashboard --project <repo> --json
220
226
  peaks skill doctor --json
@@ -6,6 +6,15 @@ Companion to `SKILL.md` §"Peaks-Loop Step 11". This file holds the substep-by-s
6
6
 
7
7
  Code MUST NOT declare a workflow complete until Step 11 has produced ≥ 1 file in `.peaks/memory/` OR the user has explicitly approved a no-sediment outcome via AskUserQuestion. Applies to **all modes** including `assisted` and `strict`.
8
8
 
9
+ ## Single authority (2026-09-09)
10
+
11
+ **Inside a peaks-code workflow, sedimenting memory writes to `.peaks/memory/`. The IDE-side memory dir is a session note, not the authority.**
12
+
13
+ - `.peaks/memory/` is peaks-owned and authoritative. Every sediment action ends there.
14
+ - Claude Code's per-project memory dir (`~/.claude/projects/<project-hash>/memory/*.md`) is the IDE's own scratch memory. It is **read-only** for peaks — never write there (same rule as `~/.claude/agents/`).
15
+ - If a session note was written to the IDE-side dir instead of `.peaks/memory/`, pull it in with `peaks memory ingest --apply` (LLM-run; read-only on the IDE side, normalizes frontmatter to `metadata.type`, idempotent by filename stem). Conflicts leave both copies in place — resolve by hand.
16
+ - Never let a memory exist only in the IDE-side dir when the workflow claims the memory was sedimented.
17
+
9
18
  ## Substeps
10
19
 
11
20
  ### 11a — Gate A (txt/ inventory)
@@ -42,6 +51,32 @@ If `extractedCount === 0` after 11c, fire AskUserQuestion:
42
51
 
43
52
  > **D-010 fix root cause check:** When firing 11d, first inspect whether the block has the YAML frontmatter (`title:` + `kind:` + `---`). If the `<!-- peaks-memory:start -->` exists but no `title:` line follows, fix the block format and re-run 11c — don't ask the user yet. Default option = (a). Code MUST NOT silently accept (b) without user pick.
44
53
 
54
+ ### 11e — Index hygiene (run after any sediment)
55
+
56
+ ```bash
57
+ peaks memory reindex --project <repo> --json # drift report (dry run)
58
+ peaks memory reindex --project <repo> --apply --json # rebuild index.json + MEMORY.md
59
+ ```
60
+
61
+ `reindex` re-scans **every** `.peaks/memory/*.md` (including `archived/`), resolves each file's kind as `metadata.type` → top-level `kind:` → top-level `type:`, rebuilds `index.json` deterministically, and regenerates `MEMORY.md` (generated banner; do not hand-edit). It reports, never silently drops:
62
+
63
+ - `unclassified[]` — files with no resolvable kind (add `metadata.type` to fix);
64
+ - `orphanIndex[]` — index entries whose `sourcePath` no longer exists;
65
+ - `orphanDisk[]` — files on disk the rebuilt index does not contain.
66
+
67
+ Run it whenever Step 11 wrote or imported memories, so the machine index and `MEMORY.md` never drift apart again.
68
+
69
+ ### 11f — Pull in IDE-side session notes (only when needed)
70
+
71
+ If a memory was written to Claude Code's own memory dir during the session instead of `.peaks/memory/`:
72
+
73
+ ```bash
74
+ peaks memory ingest --project <repo> --json # preview
75
+ peaks memory ingest --project <repo> --apply --json # write into .peaks/memory
76
+ ```
77
+
78
+ Source defaults to `~/.claude/projects/<project-hash>/memory/` (read-only). Import is idempotent by filename stem; differing destinations are reported as conflicts and both copies are left in place. Files whose kind cannot be resolved are reported as needing classification — never invented.
79
+
45
80
  ## Why Step 11 exists
46
81
 
47
82
  Audit 2026-07-03 confirmed 2 consecutive sessions produced zero `.peaks/memory/` files despite completing RD + QA + handoff artifacts; `assisted` mode silently skipped runbook Step 10 (no STOP condition).
@@ -47,6 +47,8 @@ If a doctor finding requires a code change, the workflow hands off to `peaks-rd`
47
47
  - `peaks openspec from-doctor` — L3.3 proposal generator
48
48
  - `peaks openspec validate` — gate a draft proposal
49
49
 
50
+ **Large tool output (> 2 KB) MUST NOT be dumped into the orchestrator's context.** `peaks doctor` returns ~69 checks — use `peaks doctor --summary` (counts + names-of-first-N, ≤ 2 KB) and re-run without the flag only for the specific check you need to read. Rationale (measured, session 2026-09-07-session-245530): full-envelope dumps cost ≈ 40K tokens of a 68%-full 1M window; `--summary` is an additive view, so no information is removed.
51
+
50
52
  ## Boundaries
51
53
 
52
54
  - The doctor is read-only. It does NOT modify code, fix bugs, or clean up sessions.