@event4u/agent-config 9.29.0 → 9.30.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 (122) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +108 -7
  3. package/README.md +1 -0
  4. package/dist/agent-src/commands/analyze/inbox.md +22 -1
  5. package/dist/agent-src/commands/explain-run.md +31 -1
  6. package/dist/agent-src/commands/team/delegate.md +1 -0
  7. package/dist/agent-src/contexts/execution/orchestration-telemetry.md +4 -1
  8. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +17 -0
  9. package/dist/agent-src/contexts/execution/subagent-response-contract.md +11 -1
  10. package/dist/agent-src/rules/preservation-guard.md +9 -0
  11. package/dist/agent-src/scripts/roadmap_gates.ts +312 -0
  12. package/dist/agent-src/scripts/update_roadmap_progress.ts +72 -4
  13. package/dist/agent-src/skills/subagent-orchestration/SKILL.md +10 -0
  14. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  15. package/dist/cli/registry.js +2 -0
  16. package/dist/cli/registry.js.map +1 -1
  17. package/dist/cli-delegate/{chunk-OJM3MBJM.js → chunk-BTJNRUX3.js} +21 -34
  18. package/dist/cli-delegate/{chunk-MMXA5GY7.js → chunk-DDUNNFYX.js} +14 -0
  19. package/dist/cli-delegate/{chunk-NZ5N2XQL.js → chunk-EQY4FLJB.js} +1 -1
  20. package/dist/cli-delegate/{chunk-RCIA67XN.js → chunk-IYTGIG2Y.js} +44 -1
  21. package/dist/cli-delegate/chunk-MMJL4TIX.js +18 -0
  22. package/dist/cli-delegate/chunk-O3CO5BFB.js +161 -0
  23. package/dist/cli-delegate/{chunk-REKCMYOU.js → chunk-PFBV6XRT.js} +36 -20
  24. package/dist/cli-delegate/chunk-RVGBH4XK.js +142 -0
  25. package/dist/cli-delegate/cmd_conformance.js +2798 -95
  26. package/dist/cli-delegate/cmd_doctor.js +2 -1
  27. package/dist/cli-delegate/cmd_export.js +2 -2
  28. package/dist/cli-delegate/cmd_handoff.js +86 -6
  29. package/dist/cli-delegate/cmd_prune.js +2 -2
  30. package/dist/cli-delegate/cmd_route_audit.js +2 -1
  31. package/dist/cli-delegate/cmd_session_recycle.js +177 -0
  32. package/dist/cli-delegate/cmd_settings_get.js +1 -1
  33. package/dist/cli-delegate/cmd_settings_migrate.js +2 -2
  34. package/dist/cli-delegate/cmd_settings_set.js +2 -2
  35. package/dist/cli-delegate/cmd_sync.js +2 -2
  36. package/dist/cli-delegate/cmd_uninstall.js +2 -2
  37. package/dist/cli-delegate/cmd_validate.js +2 -2
  38. package/dist/discovery/deprecation-report.md +1 -1
  39. package/dist/discovery/discovery-manifest.json +7 -7
  40. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  41. package/dist/discovery/discovery-manifest.summary.md +1 -1
  42. package/dist/discovery/orphan-report.md +1 -1
  43. package/dist/discovery/packs.json +2 -2
  44. package/dist/discovery/trust-report.md +1 -1
  45. package/dist/discovery/workspaces.json +2 -2
  46. package/dist/hooks/dispatch.js +1904 -575
  47. package/dist/install/install.mjs +14 -0
  48. package/dist/mcp/registry-manifest.json +2 -2
  49. package/dist/mcp/server.json +2 -2
  50. package/dist/mcp/server.mjs +3760 -726
  51. package/dist/server/schemas/settings.js +6 -0
  52. package/dist/server/schemas/settings.js.map +1 -1
  53. package/dist/ui/assets/index-B5qGYOJo.js +26 -0
  54. package/dist/ui/assets/index-B5qGYOJo.js.map +1 -0
  55. package/dist/ui/index.html +1 -1
  56. package/docs/contracts/settings-classes.md +21 -5
  57. package/package.json +1 -1
  58. package/src/agent-src/scripts/roadmap_gates.ts +312 -0
  59. package/src/agent-src/scripts/update_roadmap_progress.ts +72 -4
  60. package/src/config/agent-settings.template.yml +36 -0
  61. package/src/config/dispatch-economy-metrics.json +61 -0
  62. package/src/config/evaluator-budgets.json +4 -4
  63. package/src/config/hook-token-budget.json +91 -0
  64. package/src/config/recycle-threshold-budget.json +12 -0
  65. package/src/config/rule-enforcement-baseline.json +86 -0
  66. package/src/scripts/_cli/cmd_conformance.ts +17 -2
  67. package/src/scripts/_cli/cmd_session_recycle.ts +226 -0
  68. package/src/scripts/_dispatch.bash +23 -0
  69. package/src/scripts/_lib/judgment_ladder.ts +254 -2
  70. package/src/scripts/_lib/orchestration_record.ts +41 -10
  71. package/src/scripts/_lib/recycle_envelope_paths.ts +35 -0
  72. package/src/scripts/_lib/self_repair.ts +194 -0
  73. package/src/scripts/_lib/session_eol.ts +230 -0
  74. package/src/scripts/_lib/session_role.ts +42 -0
  75. package/src/scripts/_lib/subagent_capsule.ts +159 -0
  76. package/src/scripts/_lib/subagent_response.ts +75 -0
  77. package/src/scripts/ai_council/clients.ts +50 -1
  78. package/src/scripts/ask_transport.ts +221 -0
  79. package/src/scripts/bench_hook_injection.ts +234 -0
  80. package/src/scripts/check_adr_frontmatter.ts +84 -40
  81. package/src/scripts/check_branch_freshness.ts +1 -0
  82. package/src/scripts/check_corpus_staleness.ts +18 -4
  83. package/src/scripts/check_detector_corpus.ts +17 -0
  84. package/src/scripts/check_gitignore_freshness.ts +42 -8
  85. package/src/scripts/check_hook_bundle_freshness.ts +20 -0
  86. package/src/scripts/check_kernel_prefix_stability.ts +1 -0
  87. package/src/scripts/check_standing_rule_delivery.ts +73 -32
  88. package/src/scripts/check_static_layer_stability.ts +154 -0
  89. package/src/scripts/check_suppression_hygiene.ts +48 -0
  90. package/src/scripts/dispatch_economy_report.ts +448 -0
  91. package/src/scripts/dispatch_r2_reviewer.ts +15 -2
  92. package/src/scripts/explain_run.ts +206 -4
  93. package/src/scripts/generate_settings_reference.ts +1 -0
  94. package/src/scripts/handoff_context_hook.ts +112 -4
  95. package/src/scripts/hook_manifest.yaml +117 -10
  96. package/src/scripts/hooks/concern_registry.ts +8 -0
  97. package/src/scripts/hooks/delegation_nudge_hook.ts +40 -3
  98. package/src/scripts/hooks/dispatch_hook.ts +39 -2
  99. package/src/scripts/hooks/edit_shape_hook.ts +303 -0
  100. package/src/scripts/hooks/orchestration_record_hook.ts +19 -1
  101. package/src/scripts/hooks/reread_guard_hook.ts +314 -0
  102. package/src/scripts/hooks/rtk_wrap_hook.ts +133 -14
  103. package/src/scripts/hooks/session_eol_hook.ts +268 -0
  104. package/src/scripts/hooks/turn_end_gate_hook.ts +507 -0
  105. package/src/scripts/install-hooks.sh +1 -1
  106. package/src/scripts/language_mirror_hook.ts +89 -0
  107. package/src/scripts/lint_decision_impact.ts +14 -1
  108. package/src/scripts/lint_hook_manifest.ts +82 -0
  109. package/src/scripts/lint_readme_serial_comma.ts +1 -0
  110. package/src/scripts/lint_rule_enforcement_declaration.ts +347 -0
  111. package/src/scripts/measure_turn_end_gate.ts +194 -0
  112. package/src/scripts/orchestration_record.ts +4 -1
  113. package/src/scripts/rebuild_hook_bundle.ts +1 -0
  114. package/src/scripts/report_conformance_funnel.ts +284 -0
  115. package/src/scripts/report_imperative_density.ts +1 -0
  116. package/src/scripts/routing_doctor.ts +97 -0
  117. package/src/scripts/self_repair_cli.ts +51 -3
  118. package/src/scripts/session_eol_report.ts +261 -0
  119. package/src/server/schemas/settings.ts +14 -0
  120. package/src/templates/compact-instructions.md +40 -0
  121. package/dist/ui/assets/index-JDAF00bC.js +0 -26
  122. package/dist/ui/assets/index-JDAF00bC.js.map +0 -1
@@ -0,0 +1,261 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * session_eol_report — session end-of-life baseline over the local
4
+ * Claude Code transcript store (road-to-token-economy-recycling Phases
5
+ * 1.1–1.3). Read-only; prints aggregate numbers, never content.
6
+ *
7
+ * Per session file (main chain only): final context size in parsed tokens
8
+ * (`cc_transcript.billableInputTokens` of the last assistant record), turn
9
+ * count, and every observed compaction event (`_lib/session_eol.ts`
10
+ * detector, pinned to the observed `compact_boundary` marker). The
11
+ * aggregate is the baseline the recycle threshold cites
12
+ * (`src/config/recycle-threshold-budget.json`), and the reproduce command
13
+ * for `agents/evidence/analysis/token-economy-recycling-phase1.md`:
14
+ *
15
+ * ./scripts-run src/scripts/session_eol_report # text
16
+ * ./scripts-run src/scripts/session_eol_report -- --json # machine
17
+ *
18
+ * Fallback honesty (Phase 1.2): sessions whose transcript yields NO
19
+ * parseable assistant usage are counted as `sessions_without_usage`, and
20
+ * the bytes↔tokens Pearson r over the READABLE set is printed so the
21
+ * byte-proxy's (un)fitness is a published number, not a vibe.
22
+ *
23
+ * Marker-drift alarm (blocker `compaction-marker-shape`): the scanner
24
+ * counts BOTH observed markers independently; a store-wide divergence
25
+ * between `compact_boundary` events and `isCompactSummary` records is
26
+ * reported as drift instead of silently zeroing the metric.
27
+ */
28
+
29
+ import * as fs from 'node:fs';
30
+ import process from 'node:process';
31
+ import { fileURLToPath, pathToFileURL } from 'node:url';
32
+ import * as path from 'node:path';
33
+
34
+ import { DEFAULT_PROJECTS_ROOT, listTranscriptFiles } from './_lib/cc_transcript.js';
35
+ import { emptyCounters, scanEolSlice, type EolCounters } from './_lib/session_eol.js';
36
+
37
+ export interface SessionSummary {
38
+ file: string;
39
+ bytes: number;
40
+ counters: EolCounters;
41
+ last_ts: string | null;
42
+ }
43
+
44
+ export interface EolReport {
45
+ schema_version: 1;
46
+ generated_at: string;
47
+ root: string;
48
+ files_scanned: number;
49
+ sessions: number;
50
+ sessions_with_usage: number;
51
+ sessions_without_usage: number;
52
+ final_context_tokens: Percentiles | null;
53
+ turns: Percentiles | null;
54
+ compaction: {
55
+ sessions_with_compaction: number;
56
+ events_total: number;
57
+ events_by_trigger: Record<string, number>;
58
+ pre_tokens: Percentiles | null;
59
+ post_tokens: Percentiles | null;
60
+ /** `isCompactSummary` records store-wide — drift alarm vs `events_total`. */
61
+ compact_summary_records: number;
62
+ marker_drift: boolean;
63
+ };
64
+ /** Pearson r of file bytes vs final context tokens over the readable set. */
65
+ bytes_tokens_pearson_r: number | null;
66
+ threshold_crossings: Record<string, number>;
67
+ }
68
+
69
+ export interface Percentiles {
70
+ n: number;
71
+ min: number;
72
+ median: number;
73
+ p90: number;
74
+ p95: number;
75
+ max: number;
76
+ }
77
+
78
+ function percentile(sorted: number[], p: number): number {
79
+ if (sorted.length === 0) return NaN;
80
+ const k = (sorted.length - 1) * p;
81
+ const f = Math.floor(k);
82
+ const c = Math.min(f + 1, sorted.length - 1);
83
+ return (sorted[f] as number) + ((sorted[c] as number) - (sorted[f] as number)) * (k - f);
84
+ }
85
+
86
+ export function percentiles(values: number[]): Percentiles | null {
87
+ if (values.length === 0) return null;
88
+ const sorted = [...values].sort((a, b) => a - b);
89
+ return {
90
+ n: sorted.length,
91
+ min: sorted[0] as number,
92
+ median: percentile(sorted, 0.5),
93
+ p90: percentile(sorted, 0.9),
94
+ p95: percentile(sorted, 0.95),
95
+ max: sorted[sorted.length - 1] as number,
96
+ };
97
+ }
98
+
99
+ function pearson(pairs: Array<[number, number]>): number | null {
100
+ if (pairs.length < 3) return null;
101
+ const n = pairs.length;
102
+ const mx = pairs.reduce((s, [x]) => s + x, 0) / n;
103
+ const my = pairs.reduce((s, [, y]) => s + y, 0) / n;
104
+ let cov = 0;
105
+ let sx = 0;
106
+ let sy = 0;
107
+ for (const [x, y] of pairs) {
108
+ cov += (x - mx) * (y - my);
109
+ sx += (x - mx) ** 2;
110
+ sy += (y - my) ** 2;
111
+ }
112
+ if (sx === 0 || sy === 0) return null;
113
+ return cov / (Math.sqrt(sx) * Math.sqrt(sy));
114
+ }
115
+
116
+ /** Scan one transcript file into a session summary. Unreadable file → null. */
117
+ export function scanSessionFile(file: string): SessionSummary | null {
118
+ let text: string;
119
+ let bytes: number;
120
+ try {
121
+ text = fs.readFileSync(file, 'utf-8');
122
+ bytes = fs.statSync(file).size;
123
+ } catch {
124
+ return null;
125
+ }
126
+ const counters = scanEolSlice(text, emptyCounters());
127
+ let last_ts: string | null = null;
128
+ // cheap: reuse the final assistant stamp; fall back to null.
129
+ last_ts = counters.final_context_at;
130
+ return { file, bytes, counters, last_ts };
131
+ }
132
+
133
+ export function buildReport(root: string, now: Date = new Date()): EolReport {
134
+ const files = listTranscriptFiles({ root });
135
+ const sessions: SessionSummary[] = [];
136
+ for (const file of files) {
137
+ const summary = scanSessionFile(file);
138
+ if (!summary) continue;
139
+ const c = summary.counters;
140
+ if (c.assistant_records === 0 && c.turns === 0 && c.compactions.length === 0) continue;
141
+ sessions.push(summary);
142
+ }
143
+
144
+ const withUsage = sessions.filter((s) => s.counters.final_context_tokens !== null);
145
+ const finals = withUsage.map((s) => s.counters.final_context_tokens as number);
146
+ const turns = withUsage.map((s) => s.counters.turns);
147
+
148
+ const allEvents = sessions.flatMap((s) => s.counters.compactions);
149
+ const byTrigger: Record<string, number> = {};
150
+ for (const e of allEvents) byTrigger[e.trigger] = (byTrigger[e.trigger] ?? 0) + 1;
151
+ const pre = allEvents.map((e) => e.pre_tokens).filter((v): v is number => v !== null);
152
+ const post = allEvents.map((e) => e.post_tokens).filter((v): v is number => v !== null);
153
+ const summaryRecords = sessions.reduce((s, x) => s + x.counters.compact_summaries, 0);
154
+
155
+ const crossings: Record<string, number> = {};
156
+ for (const thr of [200_000, 400_000, 600_000, 800_000]) {
157
+ crossings[`>=${thr / 1000}k`] = finals.filter((c) => c >= thr).length;
158
+ }
159
+
160
+ return {
161
+ schema_version: 1,
162
+ generated_at: now.toISOString(),
163
+ root,
164
+ files_scanned: files.length,
165
+ sessions: sessions.length,
166
+ sessions_with_usage: withUsage.length,
167
+ sessions_without_usage: sessions.length - withUsage.length,
168
+ final_context_tokens: percentiles(finals),
169
+ turns: percentiles(turns),
170
+ compaction: {
171
+ sessions_with_compaction: sessions.filter((s) => s.counters.compactions.length > 0).length,
172
+ events_total: allEvents.length,
173
+ events_by_trigger: byTrigger,
174
+ pre_tokens: percentiles(pre),
175
+ post_tokens: percentiles(post),
176
+ compact_summary_records: summaryRecords,
177
+ marker_drift: summaryRecords !== allEvents.length,
178
+ },
179
+ bytes_tokens_pearson_r: pearson(
180
+ withUsage
181
+ .filter((s) => (s.counters.final_context_tokens as number) > 1_000)
182
+ .map((s) => [s.bytes, s.counters.final_context_tokens as number]),
183
+ ),
184
+ threshold_crossings: crossings,
185
+ };
186
+ }
187
+
188
+ function fmt(n: number): string {
189
+ return Math.round(n).toLocaleString('en-US');
190
+ }
191
+
192
+ export function renderText(r: EolReport): string {
193
+ const lines: string[] = [];
194
+ lines.push(`session end-of-life baseline — ${r.root}`);
195
+ lines.push(`files scanned: ${r.files_scanned} · sessions: ${r.sessions}`);
196
+ lines.push(
197
+ ` with parseable final usage: ${r.sessions_with_usage} · without (fallback set, 1.2): ${r.sessions_without_usage}`,
198
+ );
199
+ if (r.final_context_tokens) {
200
+ const f = r.final_context_tokens;
201
+ lines.push(
202
+ `final context tokens: median=${fmt(f.median)} p90=${fmt(f.p90)} p95=${fmt(f.p95)} max=${fmt(f.max)}`,
203
+ );
204
+ }
205
+ if (r.turns) {
206
+ lines.push(`turns per session: median=${fmt(r.turns.median)} p90=${fmt(r.turns.p90)} max=${fmt(r.turns.max)}`);
207
+ }
208
+ const c = r.compaction;
209
+ lines.push(
210
+ `compaction: ${c.sessions_with_compaction} sessions, ${c.events_total} events (${Object.entries(c.events_by_trigger)
211
+ .map(([k, v]) => `${k}:${v}`)
212
+ .join(', ') || 'none'})`,
213
+ );
214
+ if (c.pre_tokens) {
215
+ lines.push(
216
+ ` trigger pre-tokens: min=${fmt(c.pre_tokens.min)} median=${fmt(c.pre_tokens.median)} max=${fmt(c.pre_tokens.max)}`,
217
+ );
218
+ }
219
+ if (c.post_tokens) {
220
+ lines.push(` post-tokens median=${fmt(c.post_tokens.median)}`);
221
+ }
222
+ lines.push(
223
+ ` marker drift (${c.events_total} boundary vs ${c.compact_summary_records} summary records): ${c.marker_drift ? 'YES — detector shapes diverge, re-pin the fixture' : 'no'}`,
224
+ );
225
+ lines.push(
226
+ `bytes↔tokens Pearson r (readable set): ${r.bytes_tokens_pearson_r === null ? 'n/a' : r.bytes_tokens_pearson_r.toFixed(3)}`,
227
+ );
228
+ for (const [k, v] of Object.entries(r.threshold_crossings)) {
229
+ lines.push(`sessions ending ${k} tokens: ${v}`);
230
+ }
231
+ return lines.join('\n');
232
+ }
233
+
234
+ export function main(argv: string[] = process.argv.slice(2)): number {
235
+ const json = argv.includes('--json');
236
+ const rootFlag = argv.indexOf('--root');
237
+ const root =
238
+ rootFlag !== -1 && argv[rootFlag + 1] ? path.resolve(argv[rootFlag + 1] as string) : DEFAULT_PROJECTS_ROOT;
239
+ const report = buildReport(root);
240
+ process.stdout.write(json ? `${JSON.stringify(report, null, 2)}\n` : `${renderText(report)}\n`);
241
+ return 0;
242
+ }
243
+
244
+ // Bundle-safety: never auto-run when inlined into an esbuild bundle.
245
+ declare const __AGENT_CONFIG_BUNDLE__: boolean | undefined;
246
+ function _isCliEntry(): boolean {
247
+ if (typeof __AGENT_CONFIG_BUNDLE__ !== 'undefined' && __AGENT_CONFIG_BUNDLE__) return false;
248
+ if (process.argv[1] === undefined) return false;
249
+ if (import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href) return true;
250
+ try {
251
+ return (
252
+ fs.realpathSync(fileURLToPath(import.meta.url)) === fs.realpathSync(path.resolve(process.argv[1]))
253
+ );
254
+ } catch {
255
+ return false;
256
+ }
257
+ }
258
+
259
+ if (_isCliEntry()) {
260
+ process.exit(main());
261
+ }
@@ -350,6 +350,9 @@ export const settingsSchema = z.object({
350
350
  judge_model: z.string().default('').describe(
351
351
  'Override the model used for review / judge subagents that critique implementer output. Empty (default) = one tier above the implementer model — picks up nuance the implementer missed.',
352
352
  ),
353
+ model_ceiling: z.string().default('').describe(
354
+ 'Session-wide model CEILING for subagents (spend cap). Empty (default) = no ceiling. When set, suite-owned CLI spawn wrappers export CLAUDE_CODE_SUBAGENT_MODEL to the sessions they launch. Class C: a human sets it; the agent never writes or infers one.',
355
+ ),
353
356
  max_parallel: z.number().int().min(1).default(3).describe(
354
357
  'Hard cap on subagents running in parallel during /do-in-parallel, /do-competitively, and /judge runs. Raise for faster fan-out, lower if you hit rate limits or want lower token spend.',
355
358
  ),
@@ -517,6 +520,17 @@ export const settingsSchema = z.object({
517
520
  'PreToolUse code-graph nudge (ADR-124 Phase 4). Default off. When on AND a native code-graph cache or a consumer-shipped graph.json/SCIP index is present, warns once per session (never blocks) as the agent is about to Grep/Glob or Read a source file — query the graph first for who-calls/where-used/impact questions (or rebuild if stale, build if absent). Source G’s strict block-first-read mode is deliberately un-ported.',
518
521
  ),
519
522
  }).default({}),
523
+ turn_end_gate: z.object({
524
+ enabled: z.boolean().default(false).describe(
525
+ 'Stop-slot turn-end gate (road-to-conformance-round5 Phase 3). Default off, and it is the only concern that can REFUSE a turn-end rather than a tool call — so it soaks behind an explicit opt-in before it binds. Round 5 measured the reason: both blocking carriers reached zero violations, neither advisory carrier did, and 19 wrong-language replies survived a pin that had fired 26-35 seconds earlier. A refused turn continues in the SAME turn and is never refused twice.',
526
+ ),
527
+ promissory: z.boolean().default(true).describe(
528
+ 'Detector A of the turn-end gate: refuse a turn whose closing paragraph promises work not yet performed while asking the user nothing (20 measured occurrences). Inert while hooks.turn_end_gate.enabled is false.',
529
+ ),
530
+ language: z.boolean().default(true).describe(
531
+ 'Detector B of the turn-end gate: refuse a turn whose user-visible prose is not in the pinned language, with fenced code, inline code, quoted tool output, tables, URLs, paths and identifiers excluded first (19 measured occurrences). Fires 18.0% of turns on the measured corpus, which is why the master switch is off by default. Inert while hooks.turn_end_gate.enabled is false.',
532
+ ),
533
+ }).default({}),
520
534
  }),
521
535
  decision_engine: z.object({
522
536
  surface_traces: z.boolean().default(false).describe(
@@ -0,0 +1,40 @@
1
+ # Compact-instructions template — lose less when you compact anyway
2
+
3
+ Fallback lane of `road-to-token-economy-recycling` Phase 3.3. The recycle
4
+ envelope (`agent-config session:recycle` + `/clear`) is the primary path —
5
+ validated state, no summarizer. This template is for the user who compacts
6
+ instead: Claude Code honours a `# Compact instructions` section in the
7
+ project's `CLAUDE.md` when it summarizes (see the "Manage context
8
+ proactively" section of the host's cost docs), and `/compact <instructions>`
9
+ accepts the same guidance ad hoc.
10
+
11
+ **Adopt:** paste the section below into your project's `CLAUDE.md` (root),
12
+ or pass the body to `/compact` directly. One committed file, no hook —
13
+ verified against the host docs 2026-08-10.
14
+
15
+ ---
16
+
17
+ ```markdown
18
+ # Compact instructions
19
+
20
+ When compacting this conversation, preserve in full:
21
+
22
+ - every DECISION made, each with its one-line rationale
23
+ - binding CONSTRAINTS (things I was told not to do, scope fences,
24
+ permission grants and their exact wording)
25
+ - the current task, its acceptance criteria, and the precise list of
26
+ remaining steps
27
+ - VERIFY state: which checks/tests ran, their exact outcomes, and which
28
+ claims are still unverified
29
+ - file paths and `file:line` references that later steps depend on
30
+
31
+ Drop aggressively:
32
+
33
+ - raw tool output (test logs, diffs, file bodies) — keep only the one-line
34
+ conclusion each produced and the path to re-read
35
+ - exploratory dead ends, superseded plans, and repeated content
36
+ - pleasantries and process narration
37
+
38
+ Never convert an unverified claim into a fact while summarizing — keep its
39
+ epistemic state (verified / assumed / gap) attached.
40
+ ```