@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.
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +108 -7
- package/README.md +1 -0
- package/dist/agent-src/commands/analyze/inbox.md +22 -1
- package/dist/agent-src/commands/explain-run.md +31 -1
- package/dist/agent-src/commands/team/delegate.md +1 -0
- package/dist/agent-src/contexts/execution/orchestration-telemetry.md +4 -1
- package/dist/agent-src/contexts/execution/roadmap-process-loop.md +17 -0
- package/dist/agent-src/contexts/execution/subagent-response-contract.md +11 -1
- package/dist/agent-src/rules/preservation-guard.md +9 -0
- package/dist/agent-src/scripts/roadmap_gates.ts +312 -0
- package/dist/agent-src/scripts/update_roadmap_progress.ts +72 -4
- package/dist/agent-src/skills/subagent-orchestration/SKILL.md +10 -0
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/cli/registry.js +2 -0
- package/dist/cli/registry.js.map +1 -1
- package/dist/cli-delegate/{chunk-OJM3MBJM.js → chunk-BTJNRUX3.js} +21 -34
- package/dist/cli-delegate/{chunk-MMXA5GY7.js → chunk-DDUNNFYX.js} +14 -0
- package/dist/cli-delegate/{chunk-NZ5N2XQL.js → chunk-EQY4FLJB.js} +1 -1
- package/dist/cli-delegate/{chunk-RCIA67XN.js → chunk-IYTGIG2Y.js} +44 -1
- package/dist/cli-delegate/chunk-MMJL4TIX.js +18 -0
- package/dist/cli-delegate/chunk-O3CO5BFB.js +161 -0
- package/dist/cli-delegate/{chunk-REKCMYOU.js → chunk-PFBV6XRT.js} +36 -20
- package/dist/cli-delegate/chunk-RVGBH4XK.js +142 -0
- package/dist/cli-delegate/cmd_conformance.js +2798 -95
- package/dist/cli-delegate/cmd_doctor.js +2 -1
- package/dist/cli-delegate/cmd_export.js +2 -2
- package/dist/cli-delegate/cmd_handoff.js +86 -6
- package/dist/cli-delegate/cmd_prune.js +2 -2
- package/dist/cli-delegate/cmd_route_audit.js +2 -1
- package/dist/cli-delegate/cmd_session_recycle.js +177 -0
- package/dist/cli-delegate/cmd_settings_get.js +1 -1
- package/dist/cli-delegate/cmd_settings_migrate.js +2 -2
- package/dist/cli-delegate/cmd_settings_set.js +2 -2
- package/dist/cli-delegate/cmd_sync.js +2 -2
- package/dist/cli-delegate/cmd_uninstall.js +2 -2
- package/dist/cli-delegate/cmd_validate.js +2 -2
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +7 -7
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +2 -2
- package/dist/discovery/trust-report.md +1 -1
- package/dist/discovery/workspaces.json +2 -2
- package/dist/hooks/dispatch.js +1904 -575
- package/dist/install/install.mjs +14 -0
- package/dist/mcp/registry-manifest.json +2 -2
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +3760 -726
- package/dist/server/schemas/settings.js +6 -0
- package/dist/server/schemas/settings.js.map +1 -1
- package/dist/ui/assets/index-B5qGYOJo.js +26 -0
- package/dist/ui/assets/index-B5qGYOJo.js.map +1 -0
- package/dist/ui/index.html +1 -1
- package/docs/contracts/settings-classes.md +21 -5
- package/package.json +1 -1
- package/src/agent-src/scripts/roadmap_gates.ts +312 -0
- package/src/agent-src/scripts/update_roadmap_progress.ts +72 -4
- package/src/config/agent-settings.template.yml +36 -0
- package/src/config/dispatch-economy-metrics.json +61 -0
- package/src/config/evaluator-budgets.json +4 -4
- package/src/config/hook-token-budget.json +91 -0
- package/src/config/recycle-threshold-budget.json +12 -0
- package/src/config/rule-enforcement-baseline.json +86 -0
- package/src/scripts/_cli/cmd_conformance.ts +17 -2
- package/src/scripts/_cli/cmd_session_recycle.ts +226 -0
- package/src/scripts/_dispatch.bash +23 -0
- package/src/scripts/_lib/judgment_ladder.ts +254 -2
- package/src/scripts/_lib/orchestration_record.ts +41 -10
- package/src/scripts/_lib/recycle_envelope_paths.ts +35 -0
- package/src/scripts/_lib/self_repair.ts +194 -0
- package/src/scripts/_lib/session_eol.ts +230 -0
- package/src/scripts/_lib/session_role.ts +42 -0
- package/src/scripts/_lib/subagent_capsule.ts +159 -0
- package/src/scripts/_lib/subagent_response.ts +75 -0
- package/src/scripts/ai_council/clients.ts +50 -1
- package/src/scripts/ask_transport.ts +221 -0
- package/src/scripts/bench_hook_injection.ts +234 -0
- package/src/scripts/check_adr_frontmatter.ts +84 -40
- package/src/scripts/check_branch_freshness.ts +1 -0
- package/src/scripts/check_corpus_staleness.ts +18 -4
- package/src/scripts/check_detector_corpus.ts +17 -0
- package/src/scripts/check_gitignore_freshness.ts +42 -8
- package/src/scripts/check_hook_bundle_freshness.ts +20 -0
- package/src/scripts/check_kernel_prefix_stability.ts +1 -0
- package/src/scripts/check_standing_rule_delivery.ts +73 -32
- package/src/scripts/check_static_layer_stability.ts +154 -0
- package/src/scripts/check_suppression_hygiene.ts +48 -0
- package/src/scripts/dispatch_economy_report.ts +448 -0
- package/src/scripts/dispatch_r2_reviewer.ts +15 -2
- package/src/scripts/explain_run.ts +206 -4
- package/src/scripts/generate_settings_reference.ts +1 -0
- package/src/scripts/handoff_context_hook.ts +112 -4
- package/src/scripts/hook_manifest.yaml +117 -10
- package/src/scripts/hooks/concern_registry.ts +8 -0
- package/src/scripts/hooks/delegation_nudge_hook.ts +40 -3
- package/src/scripts/hooks/dispatch_hook.ts +39 -2
- package/src/scripts/hooks/edit_shape_hook.ts +303 -0
- package/src/scripts/hooks/orchestration_record_hook.ts +19 -1
- package/src/scripts/hooks/reread_guard_hook.ts +314 -0
- package/src/scripts/hooks/rtk_wrap_hook.ts +133 -14
- package/src/scripts/hooks/session_eol_hook.ts +268 -0
- package/src/scripts/hooks/turn_end_gate_hook.ts +507 -0
- package/src/scripts/install-hooks.sh +1 -1
- package/src/scripts/language_mirror_hook.ts +89 -0
- package/src/scripts/lint_decision_impact.ts +14 -1
- package/src/scripts/lint_hook_manifest.ts +82 -0
- package/src/scripts/lint_readme_serial_comma.ts +1 -0
- package/src/scripts/lint_rule_enforcement_declaration.ts +347 -0
- package/src/scripts/measure_turn_end_gate.ts +194 -0
- package/src/scripts/orchestration_record.ts +4 -1
- package/src/scripts/rebuild_hook_bundle.ts +1 -0
- package/src/scripts/report_conformance_funnel.ts +284 -0
- package/src/scripts/report_imperative_density.ts +1 -0
- package/src/scripts/routing_doctor.ts +97 -0
- package/src/scripts/self_repair_cli.ts +51 -3
- package/src/scripts/session_eol_report.ts +261 -0
- package/src/server/schemas/settings.ts +14 -0
- package/src/templates/compact-instructions.md +40 -0
- package/dist/ui/assets/index-JDAF00bC.js +0 -26
- 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
|
+
```
|