@event4u/agent-config 14.2.0 → 14.5.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 (117) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +33 -252
  3. package/agents/templates/.ai-council.yml.example +35 -0
  4. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +83 -12
  5. package/dist/agent-src/rules/roadmap-progress-sync.md +48 -4
  6. package/dist/agent-src/scripts/resume_probe.ts +154 -9
  7. package/dist/agent-src/scripts/roadmap_gates.ts +210 -6
  8. package/dist/agent-src/skills/roadmap-management/SKILL.md +9 -4
  9. package/dist/agent-src/templates/agent-settings.md +70 -0
  10. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  11. package/dist/agent-src/templates/scripts/telemetry/remote.ts +571 -0
  12. package/dist/agent-src/templates/scripts/telemetry/settings.ts +222 -44
  13. package/dist/cli/python/workspace_drive.js +8 -3
  14. package/dist/cli/python/workspace_drive.js.map +1 -1
  15. package/dist/cli/python/workspace_hosts.js +16 -12
  16. package/dist/cli/python/workspace_hosts.js.map +1 -1
  17. package/dist/cli/registry.js +2 -0
  18. package/dist/cli/registry.js.map +1 -1
  19. package/dist/cli-delegate/{chunk-F3YUF7SA.js → chunk-3UCJWMMP.js} +1 -1
  20. package/dist/cli-delegate/chunk-F7DQWYR5.js +69 -0
  21. package/dist/cli-delegate/{chunk-7PZ4FSZB.js → chunk-FBKL6JWT.js} +61 -2
  22. package/dist/cli-delegate/{chunk-MNWRDMR5.js → chunk-PKOBQADP.js} +1 -1
  23. package/dist/cli-delegate/cmd_conformance.js +26 -11
  24. package/dist/cli-delegate/cmd_doctor.js +2 -2
  25. package/dist/cli-delegate/cmd_handoff.js +3 -3
  26. package/dist/cli-delegate/cmd_route_audit.js +2 -2
  27. package/dist/cli-delegate/cmd_settings_set.js +17 -3
  28. package/dist/discovery/deprecation-report.md +1 -1
  29. package/dist/discovery/discovery-manifest.json +4 -4
  30. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  31. package/dist/discovery/discovery-manifest.summary.md +1 -1
  32. package/dist/discovery/dormancy-report.md +1 -1
  33. package/dist/discovery/orphan-report.md +1 -1
  34. package/dist/discovery/packs.json +2 -2
  35. package/dist/discovery/trust-report.md +1 -1
  36. package/dist/discovery/workspaces.json +2 -2
  37. package/dist/hooks/dispatch.js +3754 -1721
  38. package/dist/mcp/registry-manifest.json +2 -2
  39. package/dist/mcp/server.json +2 -2
  40. package/dist/mcp/server.mjs +1070 -408
  41. package/dist/scripts/_lib/host_launch.js +66 -0
  42. package/dist/scripts/_lib/host_launch.js.map +1 -0
  43. package/dist/server/io/yamlIO.js +175 -3
  44. package/dist/server/io/yamlIO.js.map +1 -1
  45. package/dist/server/routes/wizard.js +20 -1
  46. package/dist/server/routes/wizard.js.map +1 -1
  47. package/dist/shared/settingsConsent.js +25 -0
  48. package/dist/shared/settingsConsent.js.map +1 -1
  49. package/docs/contracts/settings-classes.md +11 -0
  50. package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +2 -1
  51. package/package.json +1 -1
  52. package/src/agent-src/scripts/resume_probe.ts +154 -9
  53. package/src/agent-src/scripts/roadmap_gates.ts +210 -6
  54. package/src/agent-src/templates/scripts/telemetry/remote.ts +571 -0
  55. package/src/agent-src/templates/scripts/telemetry/settings.ts +222 -44
  56. package/src/config/estate-count-budget.json +127 -0
  57. package/src/config/evaluator-budgets.json +4 -4
  58. package/src/config/gate-coverage.yml +32 -4
  59. package/src/config/gate-violation-baselines.json +63 -63
  60. package/src/config/gitignore-block.txt +5 -0
  61. package/src/config/hook-latency-budget.json +40 -1
  62. package/src/config/hook-token-budget.json +16 -0
  63. package/src/config/rule-stub-ceilings.json +11 -3
  64. package/src/scripts/_dispatch.bash +42 -1
  65. package/src/scripts/_lib/council_fallback_posture.ts +81 -0
  66. package/src/scripts/_lib/council_fallback_wiring.ts +126 -0
  67. package/src/scripts/_lib/council_settings_block.ts +152 -0
  68. package/src/scripts/_lib/headless_invocation.ts +285 -0
  69. package/src/scripts/_lib/host_launch.ts +72 -0
  70. package/src/scripts/_lib/map_to_object.ts +16 -0
  71. package/src/scripts/_lib/roadmap_checkboxes.ts +88 -0
  72. package/src/scripts/_lib/run_checkpoint.ts +409 -0
  73. package/src/scripts/_lib/session_register.ts +32 -1
  74. package/src/scripts/_lib/stdin.ts +35 -1
  75. package/src/scripts/_lib/turn_end_refusals.ts +12 -4
  76. package/src/scripts/_lib/unattended_guard.ts +371 -0
  77. package/src/scripts/ai_council/config.ts +27 -1
  78. package/src/scripts/ai_council/events_log.ts +12 -1
  79. package/src/scripts/ai_council/fallback_config.ts +114 -0
  80. package/src/scripts/ai_council/mid_flight_fallback.ts +295 -0
  81. package/src/scripts/ai_council/orchestrator.ts +251 -292
  82. package/src/scripts/ai_council/py_parity.ts +139 -0
  83. package/src/scripts/ai_council/response_render.ts +99 -0
  84. package/src/scripts/ai_council/spend_gate.ts +123 -0
  85. package/src/scripts/ai_council/transport_resolver.ts +81 -13
  86. package/src/scripts/bench_hook_injection.ts +118 -7
  87. package/src/scripts/bench_hook_latency.ts +442 -16
  88. package/src/scripts/check_estate_count.ts +924 -0
  89. package/src/scripts/compile_hook_manifest.ts +67 -0
  90. package/src/scripts/council_cli.ts +100 -125
  91. package/src/scripts/decision_memo.ts +325 -0
  92. package/src/scripts/hook_manifest.json +1 -0
  93. package/src/scripts/hook_manifest.yaml +172 -25
  94. package/src/scripts/hooks/concern_registry.ts +6 -0
  95. package/src/scripts/hooks/dispatch_hook.ts +183 -10
  96. package/src/scripts/hooks/dispatch_issues.ts +26 -0
  97. package/src/scripts/hooks/end_review_nudge_hook.ts +97 -24
  98. package/src/scripts/hooks/hook_stdin.ts +111 -5
  99. package/src/scripts/hooks/host_semantics.ts +28 -0
  100. package/src/scripts/hooks/injection_budget.ts +731 -0
  101. package/src/scripts/hooks/payload_stub.ts +446 -0
  102. package/src/scripts/hooks/run_continuation_hook.ts +683 -0
  103. package/src/scripts/hooks/session_eol_hook.ts +52 -0
  104. package/src/scripts/hooks/telemetry_usage_hook.ts +339 -0
  105. package/src/scripts/hooks/tool_result_bytes_hook.ts +27 -0
  106. package/src/scripts/hooks/turn_end_gate_hook.ts +45 -7
  107. package/src/scripts/hooks_doctor.ts +16 -2
  108. package/src/scripts/interruption_report.ts +330 -13
  109. package/src/scripts/lint_hook_manifest.ts +167 -0
  110. package/src/scripts/roadmap_progress_hook.ts +254 -46
  111. package/src/scripts/run_supervise.ts +623 -0
  112. package/src/scripts/session_register_hook.ts +146 -12
  113. package/src/scripts/sessions_cli.ts +18 -6
  114. package/src/scripts/telemetry_disclosure_hook.ts +244 -0
  115. package/src/server/io/yamlIO.ts +167 -3
  116. package/src/shared/settingsConsent.ts +49 -2
  117. package/dist/cli-delegate/chunk-MMJL4TIX.js +0 -18
@@ -0,0 +1,325 @@
1
+ /**
2
+ * decision_memo — the decision-memo channel (UOTL Phase 4.3, sequenced by
3
+ * road-to-long-horizon-execution Phase 2.2).
4
+ *
5
+ * ## What this is for
6
+ *
7
+ * A question the agent resolves without contacting the user is only
8
+ * legitimate if the resolution is REVIEWABLE afterwards. Before this, a
9
+ * medium-impact resolution left no trace at all: the run either halted (a
10
+ * contact) or decided silently (no record). Neither is what the ladder wants
11
+ * between those two — the memo is.
12
+ *
13
+ * One file per resolution under
14
+ * `agents/runtime/state/decisions/<run>/NNN.md`, monotonic index per run.
15
+ * Local-only: the whole `agents/runtime/` tree is gitignored, so a memo never
16
+ * reaches a commit unless a human copies it out.
17
+ *
18
+ * ## Why a writer script rather than "the agent writes a markdown file"
19
+ *
20
+ * Two properties a prose instruction cannot give:
21
+ *
22
+ * - **The shape cannot drift.** Every memo carries the same five fields the
23
+ * roadmap names — question, chosen option, reasoning, resolver, confidence —
24
+ * because the writer refuses a memo missing any of them. A directory of
25
+ * free-form notes is not a channel, it is a folder.
26
+ * - **The index is monotonic and gap-free per run**, so "003 exists but 002
27
+ * does not" is impossible and a reader can tell a pruned memo from an
28
+ * unwritten one.
29
+ *
30
+ * ## What it deliberately does NOT do
31
+ *
32
+ * It does not decide anything, and it does not gate. A memo is a record of a
33
+ * resolution that already happened; making the writer refuse a resolution
34
+ * would put a decision gate in an observability surface, which is the shape
35
+ * `roadmap-progress` and the interruption ledger both stay clear of.
36
+ *
37
+ * It also carries no locked-class check, and that is not an omission to fix
38
+ * here: `high_impact` and `user_required` are refused at the SCHEMA
39
+ * (`config.ts::_build_decision_resolution`), before any model sees a route.
40
+ * A second check in the writer would read as the enforcement point and put
41
+ * the real one out of mind — the schema is the gate, this is the ledger.
42
+ */
43
+
44
+ import * as fs from 'node:fs';
45
+ import * as path from 'node:path';
46
+ import { fileURLToPath, pathToFileURL } from 'node:url';
47
+
48
+ export const DECISIONS_DIR_REL = path.join('agents', 'runtime', 'state', 'decisions');
49
+
50
+ /** The five fields the roadmap names, and nothing optional among them. */
51
+ export interface DecisionMemo {
52
+ /** The question as it was actually open — not a summary of the answer. */
53
+ question: string;
54
+ /** The option taken, stated so a reader can see what was NOT taken. */
55
+ chosen: string;
56
+ /** Why. The load-bearing field: without it the memo is a log line. */
57
+ reasoning: string;
58
+ /** Which rung resolved it — `agent`, `second-model:<provider>`, `council`. */
59
+ resolver: string;
60
+ /** Self-assessed, `high` | `medium` | `low`. Never a number. */
61
+ confidence: 'high' | 'medium' | 'low';
62
+ }
63
+
64
+ const CONFIDENCE: ReadonlySet<string> = new Set(['high', 'medium', 'low']);
65
+
66
+ /**
67
+ * A run id has to be a filename component. `safe` here is deliberately
68
+ * narrow rather than a sanitiser: a run id that needs escaping is a caller
69
+ * bug, and silently rewriting it would put two runs in one directory.
70
+ */
71
+ export function isSafeRunId(runId: string): boolean {
72
+ return /^[A-Za-z0-9_-]{1,64}$/.test(runId);
73
+ }
74
+
75
+ export function runDir(repoRoot: string, runId: string): string {
76
+ return path.join(repoRoot, DECISIONS_DIR_REL, runId);
77
+ }
78
+
79
+ /**
80
+ * The next index for this run — one past the highest `NNN.md` present.
81
+ *
82
+ * Reads the directory rather than a counter file: a counter that drifts from
83
+ * the directory is a second source of truth, and the directory is the one a
84
+ * human reads.
85
+ */
86
+ export function nextIndex(dir: string): number {
87
+ let entries: string[];
88
+ try {
89
+ entries = fs.readdirSync(dir);
90
+ } catch {
91
+ return 1;
92
+ }
93
+ let max = 0;
94
+ for (const name of entries) {
95
+ const m = /^(\d{3})\.md$/.exec(name);
96
+ if (m === null) continue;
97
+ const n = Number.parseInt(m[1] as string, 10);
98
+ if (Number.isFinite(n) && n > max) max = n;
99
+ }
100
+ return max + 1;
101
+ }
102
+
103
+ /** Refusal reasons, as a list so a caller can report all of them at once. */
104
+ export function validate(memo: Partial<DecisionMemo>): string[] {
105
+ const problems: string[] = [];
106
+ for (const field of ['question', 'chosen', 'reasoning', 'resolver'] as const) {
107
+ const v = memo[field];
108
+ if (typeof v !== 'string' || v.trim() === '') {
109
+ problems.push(`${field} is required and must be non-empty`);
110
+ }
111
+ }
112
+ const c = memo.confidence;
113
+ if (typeof c !== 'string' || !CONFIDENCE.has(c)) {
114
+ problems.push(`confidence must be one of high | medium | low (got ${String(c)})`);
115
+ }
116
+ return problems;
117
+ }
118
+
119
+ export function render(memo: DecisionMemo, index: number, stampedAt: string): string {
120
+ return [
121
+ `# Decision ${String(index).padStart(3, '0')}`,
122
+ '',
123
+ `- **Resolver:** ${memo.resolver}`,
124
+ `- **Confidence:** ${memo.confidence}`,
125
+ `- **Recorded:** ${stampedAt}`,
126
+ '',
127
+ '## Question',
128
+ '',
129
+ memo.question.trim(),
130
+ '',
131
+ '## Chosen',
132
+ '',
133
+ memo.chosen.trim(),
134
+ '',
135
+ '## Reasoning',
136
+ '',
137
+ memo.reasoning.trim(),
138
+ '',
139
+ ].join('\n');
140
+ }
141
+
142
+ export interface WriteResult {
143
+ path: string;
144
+ index: number;
145
+ }
146
+
147
+ /**
148
+ * Write one memo. Throws on a validation failure — a memo that cannot be
149
+ * written is a caller bug and must not degrade into a partial record.
150
+ */
151
+ export function writeMemo(
152
+ repoRoot: string,
153
+ runId: string,
154
+ memo: DecisionMemo,
155
+ opts: { now?: () => Date } = {},
156
+ ): WriteResult {
157
+ if (!isSafeRunId(runId)) {
158
+ throw new Error(
159
+ `decision_memo: run id ${JSON.stringify(runId)} is not a safe filename ` +
160
+ `component (letters, digits, _ and - only, 1..64 chars)`,
161
+ );
162
+ }
163
+ const problems = validate(memo);
164
+ if (problems.length > 0) {
165
+ throw new Error(`decision_memo: refusing an incomplete memo — ${problems.join('; ')}`);
166
+ }
167
+ const dir = runDir(repoRoot, runId);
168
+ fs.mkdirSync(dir, { recursive: true });
169
+ const stamp = (opts.now ?? ((): Date => new Date()))().toISOString();
170
+ // Claim the slot with `wx` and retry on collision, rather than
171
+ // read-then-write.
172
+ //
173
+ // R2 review, finding 10. `nextIndex` followed by a plain `writeFileSync`
174
+ // is a read-then-write with no lock: two memos written for the same run
175
+ // concurrently — the unattended or parallel lane this module exists for,
176
+ // or simply two shell calls — compute the same index and the second
177
+ // silently overwrites the first. That breaks the exact property the header
178
+ // sells as this module's reason to exist ("monotonic and gap-free per run,
179
+ // so a reader can tell a pruned memo from an unwritten one"), because a
180
+ // LOST memo leaves no gap at all.
181
+ //
182
+ // The bound is generous and finite: a loop that cannot fail would hide a
183
+ // permission error as a hang.
184
+ const MAX_ATTEMPTS = 64;
185
+ for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt++) {
186
+ const index = nextIndex(dir);
187
+ const file = path.join(dir, `${String(index).padStart(3, '0')}.md`);
188
+ try {
189
+ fs.writeFileSync(file, render(memo, index, stamp), { encoding: 'utf-8', flag: 'wx' });
190
+ return { path: file, index };
191
+ } catch (err) {
192
+ // EEXIST means another writer took this index between the read and
193
+ // the write — re-read and take the next one. Anything else (EACCES,
194
+ // ENOSPC) is a real failure and must not be retried into a hang.
195
+ if ((err as NodeJS.ErrnoException).code !== 'EEXIST') throw err;
196
+ }
197
+ }
198
+ throw new Error(
199
+ `decision_memo: could not claim an index for run ${JSON.stringify(runId)} ` +
200
+ `after ${MAX_ATTEMPTS} attempts — another writer is taking every slot`,
201
+ );
202
+ }
203
+
204
+ /** Every memo of one run, in index order. */
205
+ export function listMemos(repoRoot: string, runId: string): string[] {
206
+ const dir = runDir(repoRoot, runId);
207
+ let entries: string[];
208
+ try {
209
+ entries = fs.readdirSync(dir);
210
+ } catch {
211
+ return [];
212
+ }
213
+ return entries
214
+ .filter((n) => /^\d{3}\.md$/.test(n))
215
+ .sort()
216
+ .map((n) => path.join(dir, n));
217
+ }
218
+
219
+ const USAGE = `usage: decision_memo write --run <id> --question <q> --chosen <c> \\
220
+ --reasoning <r> --resolver <who> --confidence <high|medium|low>
221
+ decision_memo list --run <id>
222
+
223
+ Records one autonomously-resolved question so it is reviewable after the run.
224
+ Writes agents/runtime/state/decisions/<run>/NNN.md — local-only (gitignored).
225
+
226
+ --run takes ANY slug, and that freedom has a cost worth stating (R2 round 4,
227
+ finding 3): interruption_report attributes memos to a run by joining on the
228
+ session-derived run id, so a memo written under a hand-picked slug is counted
229
+ by 'run:supervise --digest' (which counts directories) and NOT by the report's
230
+ median_memos_per_run (which joins). The two disagree about the same files, and
231
+ the report's zero reads as "no memos" rather than "no join".
232
+
233
+ To be attributable, pass the id the ledger uses:
234
+ agent-config run:supervise --digest # lists the session ids in play
235
+ A free-form slug is still valid and still recorded — it is simply a memo about
236
+ a run the report cannot name.
237
+
238
+ Locked classes (high_impact, user_required) are refused at the CONFIG SCHEMA,
239
+ never here: this is the ledger, not the gate.
240
+ `;
241
+
242
+ function argValue(argv: string[], flag: string): string | null {
243
+ const i = argv.indexOf(flag);
244
+ if (i === -1 || i + 1 >= argv.length) return null;
245
+ return argv[i + 1] ?? null;
246
+ }
247
+
248
+ export function main(argv: string[] = process.argv.slice(2)): number {
249
+ const sub = argv[0] ?? '';
250
+ if (sub === '' || sub === '--help' || sub === '-h') {
251
+ process.stdout.write(USAGE);
252
+ return sub === '' ? 2 : 0;
253
+ }
254
+ const repoRoot = argValue(argv, '--root') ?? process.cwd();
255
+ const runId = argValue(argv, '--run');
256
+ if (runId === null) {
257
+ process.stderr.write('decision_memo: --run <id> is required\n');
258
+ return 2;
259
+ }
260
+
261
+ if (sub === 'list') {
262
+ const memos = listMemos(repoRoot, runId);
263
+ if (memos.length === 0) {
264
+ process.stdout.write(`decision_memo: no memos for run ${runId}\n`);
265
+ return 0;
266
+ }
267
+ for (const m of memos) {
268
+ process.stdout.write(`${path.relative(repoRoot, m)}\n`);
269
+ }
270
+ return 0;
271
+ }
272
+
273
+ if (sub !== 'write') {
274
+ process.stderr.write(`decision_memo: unknown subcommand '${sub}'\n${USAGE}`);
275
+ return 2;
276
+ }
277
+
278
+ const memo: Partial<DecisionMemo> = {
279
+ question: argValue(argv, '--question') ?? '',
280
+ chosen: argValue(argv, '--chosen') ?? '',
281
+ reasoning: argValue(argv, '--reasoning') ?? '',
282
+ resolver: argValue(argv, '--resolver') ?? '',
283
+ confidence: (argValue(argv, '--confidence') ?? '') as DecisionMemo['confidence'],
284
+ };
285
+ const problems = validate(memo);
286
+ if (problems.length > 0) {
287
+ process.stderr.write(`decision_memo: ${problems.join('; ')}\n`);
288
+ return 2;
289
+ }
290
+ try {
291
+ const res = writeMemo(repoRoot, runId, memo as DecisionMemo);
292
+ process.stdout.write(`${path.relative(repoRoot, res.path)}\n`);
293
+ return 0;
294
+ } catch (exc) {
295
+ process.stderr.write(`${exc instanceof Error ? exc.message : String(exc)}\n`);
296
+ return 2;
297
+ }
298
+ }
299
+
300
+ /**
301
+ * The realpath-comparing form, not a `basename` test: an installed projection
302
+ * and macOS `/var` → `/private/var` both make `argv[1]` a symlink whose URL
303
+ * differs from `import.meta.url`, and a naive comparison silently no-ops the
304
+ * CLI. Same shape as `interruption_report.ts::_isCliEntry`.
305
+ */
306
+ function _isCliEntry(): boolean {
307
+ if (process.argv[1] === undefined) {
308
+ return false;
309
+ }
310
+ const argvUrl = pathToFileURL(path.resolve(process.argv[1])).href;
311
+ if (import.meta.url === argvUrl) {
312
+ return true;
313
+ }
314
+ try {
315
+ const here = fs.realpathSync(fileURLToPath(import.meta.url));
316
+ const argv = fs.realpathSync(path.resolve(process.argv[1]));
317
+ return here === argv;
318
+ } catch {
319
+ return false;
320
+ }
321
+ }
322
+
323
+ if (_isCliEntry()) {
324
+ process.exit(main());
325
+ }
@@ -0,0 +1 @@
1
+ {"fingerprint":"4834904a:65187","manifest":{"schema_version":1,"concerns":{"chat-history":{"script":"src/scripts/chat_history.ts","args":["hook-dispatch"],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["result"]},"hot-context":{"script":"src/scripts/hot_context_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"handoff-context":{"script":"src/scripts/handoff_context_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"roadmap-progress":{"script":"src/scripts/roadmap_progress_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input"]},"onboarding-gate":{"script":"src/scripts/onboarding_gate_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"context-hygiene":{"script":"src/scripts/context_hygiene_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"verify-before-complete":{"script":"src/scripts/before_complete_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input","result"]},"ship-diff-volume":{"script":"src/scripts/hooks/ship_diff_volume_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input"]},"minimal-safe-diff":{"script":"src/scripts/minimal_safe_diff_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input"]},"injection-scan":{"script":"src/scripts/injection_scan_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input","result"]},"block-no-verify":{"script":"src/scripts/hooks/block_no_verify.ts","args":[],"fail_closed":true,"severity":"blocking","needs_payload_bodies":["input"]},"block-kernel-rule-writes":{"script":"src/scripts/hooks/block_kernel_rule_writes.ts","args":[],"fail_closed":true,"severity":"blocking","needs_payload_bodies":["input"]},"block-config-weakening":{"script":"src/scripts/hooks/block_config_weakening.ts","args":[],"fail_closed":false,"severity":"blocking","needs_payload_bodies":["input"]},"rtk-wrap":{"script":"src/scripts/hooks/rtk_wrap_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input"]},"design-slop":{"script":"src/scripts/hooks/design_slop_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input"]},"ui-route-nudge":{"script":"src/scripts/hooks/ui_route_nudge_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input"]},"code-graph-nudge":{"script":"src/scripts/hooks/code_graph_nudge_hook.ts","args":[],"fail_closed":false,"severity":"advisory","tools":["Grep","Glob","Read"],"needs_payload_bodies":["input"]},"memory-learn":{"script":"src/scripts/memory_learn_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"first-run-gate":{"script":"src/scripts/first_run_gate_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"profile-staleness":{"script":"src/scripts/profile_staleness_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"wrapper-freshness":{"script":"src/scripts/wrapper_freshness_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"surface-probe":{"script":"src/scripts/surface_probe_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"team-review-gate":{"script":"src/scripts/team_review_gate_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"pr-url-reminder":{"script":"src/scripts/pr_url_reminder_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input","result"]},"language-mirror":{"script":"src/scripts/language_mirror_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"git-authorization":{"script":"src/scripts/git_authorization_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"block-unauthorized-git":{"script":"src/scripts/hooks/block_unauthorized_git.ts","args":[],"fail_closed":true,"severity":"blocking","needs_payload_bodies":["input"]},"evidence-independence":{"script":"src/scripts/hooks/evidence_independence.ts","args":[],"fail_closed":false,"severity":"blocking","needs_payload_bodies":["input"]},"session-canary":{"script":"src/scripts/session_canary_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"council-availability":{"script":"src/scripts/council_availability_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"telemetry-disclosure":{"script":"src/scripts/telemetry_disclosure_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"self-repair":{"script":"src/scripts/self_repair_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"session-register":{"script":"src/scripts/session_register_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"orchestration-record":{"script":"src/scripts/hooks/orchestration_record_hook.ts","args":[],"fail_closed":false,"severity":"advisory","tools":["Agent","Task"],"needs_payload_bodies":["input","result"]},"telemetry-usage":{"script":"src/scripts/hooks/telemetry_usage_hook.ts","args":[],"fail_closed":false,"severity":"advisory","tools":["Skill"],"needs_payload_bodies":["input"]},"delegation-nudge":{"script":"src/scripts/hooks/delegation_nudge_hook.ts","args":[],"fail_closed":false,"severity":"advisory","nudge_rank":1},"skill-route":{"script":"src/scripts/hooks/skill_route_hook.ts","args":[],"fail_closed":false,"severity":"advisory","nudge_rank":2},"end-review-nudge":{"script":"src/scripts/hooks/end_review_nudge_hook.ts","args":[],"fail_closed":false,"severity":"advisory","skip_on_refusal_retry":true},"turn-end-gate":{"script":"src/scripts/hooks/turn_end_gate_hook.ts","args":[],"fail_closed":false,"severity":"blocking"},"edit-shape":{"script":"src/scripts/hooks/edit_shape_hook.ts","args":[],"fail_closed":false,"severity":"advisory","tools":["Write"],"needs_payload_bodies":["input"]},"reread-guard":{"script":"src/scripts/hooks/reread_guard_hook.ts","args":[],"fail_closed":false,"severity":"advisory","tools":["Read","Edit","Write"],"needs_payload_bodies":["input"]},"session-eol":{"script":"src/scripts/hooks/session_eol_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"run-continuation":{"script":"src/scripts/hooks/run_continuation_hook.ts","args":[],"fail_closed":false,"severity":"blocking"},"interruption-ledger":{"script":"src/scripts/hooks/interruption_ledger_hook.ts","args":[],"fail_closed":false,"severity":"advisory","skip_on_refusal_retry":true},"subagent-ledger":{"script":"src/scripts/hooks/subagent_ledger_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"tool-result-bytes":{"script":"src/scripts/hooks/tool_result_bytes_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"spawn-guard-shadow":{"script":"src/scripts/hooks/spawn_guard_shadow_hook.ts","args":[],"fail_closed":false,"severity":"advisory","tools":["Agent","Task"]}},"roles":{"worker":{"drop":["delegation-nudge","skill-route","end-review-nudge","council-availability","team-review-gate","self-repair","session-eol","interruption-ledger"]}},"platforms":{"augment":{"session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","minimal-safe-diff","profile-staleness","wrapper-freshness","surface-probe","session-register"],"session_end":["chat-history","memory-learn","session-register","roadmap-progress"],"stop":["chat-history","hot-context","verify-before-complete","self-repair","session-register","roadmap-progress"],"pre_tool_use":["block-no-verify","block-unauthorized-git","evidence-independence","block-kernel-rule-writes","block-config-weakening","rtk-wrap","design-slop","ui-route-nudge","code-graph-nudge","ship-diff-volume","reread-guard"],"post_tool_use":["chat-history","roadmap-progress","context-hygiene","verify-before-complete","minimal-safe-diff","injection-scan","pr-url-reminder","orchestration-record","telemetry-usage","tool-result-bytes","edit-shape"]},"claude":{"session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","minimal-safe-diff","profile-staleness","wrapper-freshness","surface-probe","session-register"],"session_end":["chat-history","memory-learn","session-register","roadmap-progress"],"stop":["chat-history","hot-context","verify-before-complete","team-review-gate","end-review-nudge","turn-end-gate","self-repair","session-register","session-eol","interruption-ledger","roadmap-progress","run-continuation"],"user_prompt_submit":["chat-history","verify-before-complete","minimal-safe-diff","language-mirror","delegation-nudge","skill-route","git-authorization","session-canary","self-repair","session-register"],"pre_tool_use":["block-no-verify","block-unauthorized-git","evidence-independence","block-kernel-rule-writes","block-config-weakening","rtk-wrap","design-slop","ui-route-nudge","code-graph-nudge","ship-diff-volume","reread-guard","spawn-guard-shadow"],"post_tool_use":["chat-history","roadmap-progress","context-hygiene","verify-before-complete","minimal-safe-diff","injection-scan","pr-url-reminder","orchestration-record","telemetry-usage","tool-result-bytes","edit-shape","language-mirror"],"pre_compact":["language-mirror","hot-context"],"subagent_start":["subagent-ledger"],"subagent_stop":["subagent-ledger"]},"cowork":{"session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","minimal-safe-diff","profile-staleness","wrapper-freshness","surface-probe","session-register"],"session_end":["chat-history","memory-learn","session-register","roadmap-progress"],"stop":["chat-history","hot-context","verify-before-complete","self-repair","session-register","roadmap-progress"],"user_prompt_submit":["chat-history","verify-before-complete","minimal-safe-diff","language-mirror","git-authorization","session-canary","self-repair","session-register"],"pre_tool_use":["block-no-verify","block-unauthorized-git","evidence-independence","block-kernel-rule-writes","block-config-weakening","rtk-wrap","design-slop","ui-route-nudge","code-graph-nudge","ship-diff-volume","reread-guard","spawn-guard-shadow"],"post_tool_use":["chat-history","roadmap-progress","context-hygiene","verify-before-complete","minimal-safe-diff","injection-scan","pr-url-reminder","orchestration-record","telemetry-usage","tool-result-bytes","edit-shape"],"subagent_start":["subagent-ledger"],"subagent_stop":["subagent-ledger"]},"cursor":{"session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","minimal-safe-diff","profile-staleness","wrapper-freshness","surface-probe","session-register"],"session_end":["chat-history","memory-learn","session-register","roadmap-progress"],"stop":["chat-history","hot-context","verify-before-complete","self-repair","session-register","roadmap-progress"],"user_prompt_submit":["chat-history","verify-before-complete","minimal-safe-diff","language-mirror","git-authorization","session-canary","self-repair","session-register"],"post_tool_use":["chat-history","roadmap-progress","context-hygiene","verify-before-complete","minimal-safe-diff","injection-scan","pr-url-reminder","orchestration-record","telemetry-usage","tool-result-bytes","edit-shape"]},"cline":{"session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","minimal-safe-diff","profile-staleness","wrapper-freshness","surface-probe","session-register"],"session_end":["chat-history","memory-learn","session-register","roadmap-progress"],"stop":["chat-history","hot-context","verify-before-complete","self-repair","session-register","roadmap-progress"],"user_prompt_submit":["chat-history","verify-before-complete","minimal-safe-diff","language-mirror","git-authorization","session-canary","self-repair","session-register"],"post_tool_use":["chat-history","roadmap-progress","context-hygiene","verify-before-complete","minimal-safe-diff","injection-scan","pr-url-reminder","orchestration-record","telemetry-usage","tool-result-bytes","edit-shape"]},"windsurf":{"session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","profile-staleness","wrapper-freshness","surface-probe","session-register"],"stop":["chat-history","hot-context","verify-before-complete","self-repair","session-register"],"user_prompt_submit":["chat-history","verify-before-complete","language-mirror","git-authorization","session-canary","self-repair","session-register"]},"gemini":{"session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","minimal-safe-diff","profile-staleness","wrapper-freshness","surface-probe","session-register"],"session_end":["chat-history","memory-learn","session-register","roadmap-progress"],"stop":["chat-history","hot-context","verify-before-complete","self-repair","session-register","roadmap-progress"],"user_prompt_submit":["chat-history","verify-before-complete","minimal-safe-diff","language-mirror","git-authorization","session-canary","self-repair","session-register"],"post_tool_use":["chat-history","roadmap-progress","context-hygiene","verify-before-complete","minimal-safe-diff","injection-scan","pr-url-reminder","orchestration-record","telemetry-usage","tool-result-bytes","edit-shape"]},"copilot":{"fallback_only":true}},"native_event_aliases":{"augment":{"SessionStart":"session_start","SessionEnd":"session_end","Stop":"stop","PostToolUse":"post_tool_use","PreToolUse":"pre_tool_use"},"claude":{"SessionStart":"session_start","SessionEnd":"session_end","Stop":"stop","UserPromptSubmit":"user_prompt_submit","PostToolUse":"post_tool_use","PreToolUse":"pre_tool_use","PreCompact":"pre_compact","SubagentStart":"subagent_start","SubagentStop":"subagent_stop"},"cowork":{"SessionStart":"session_start","SessionEnd":"session_end","Stop":"stop","UserPromptSubmit":"user_prompt_submit","PostToolUse":"post_tool_use","PreToolUse":"pre_tool_use","PreCompact":"pre_compact","SubagentStart":"subagent_start","SubagentStop":"subagent_stop"},"cursor":{"sessionStart":"session_start","sessionEnd":"session_end","stop":"stop","beforeSubmitPrompt":"user_prompt_submit","postToolUse":"post_tool_use","preToolUse":"pre_tool_use","preCompact":"pre_compact"},"cline":{"TaskStart":"session_start","TaskResume":"session_start","TaskComplete":"session_end","TaskCancel":"stop","UserPromptSubmit":"user_prompt_submit","PostToolUse":"post_tool_use","PreToolUse":"pre_tool_use","PreCompact":"pre_compact"},"windsurf":{"pre_user_prompt":"user_prompt_submit","post_cascade_response":"stop","post_setup_worktree":"session_start"},"gemini":{"SessionStart":"session_start","SessionEnd":"session_end","BeforeAgent":"user_prompt_submit","AfterAgent":"stop","BeforeTool":"pre_tool_use","AfterTool":"post_tool_use"}}}}