@event4u/agent-config 17.0.0 → 17.1.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/.augment-plugin/marketplace.json +3 -3
- package/.augment-plugin/plugin.json +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +104 -485
- package/README.md +2 -1
- package/dist/agent-src/contexts/execution/host-capability-manifest.md +5 -3
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/roadmaps.md +5 -1
- package/dist/cli-delegate/{chunk-IROAQ77A.js → chunk-3PK3VZHB.js} +107 -9
- package/dist/cli-delegate/{chunk-2SFOOFJJ.js → chunk-BZJ4Y3CI.js} +1 -1
- package/dist/cli-delegate/{chunk-CAL76ADI.js → chunk-CMZEKSNN.js} +52 -10
- package/dist/cli-delegate/{chunk-ESUNQ5XR.js → chunk-E3CFULNX.js} +22 -4
- package/dist/cli-delegate/{chunk-GOMILC3O.js → chunk-QBHEI5N4.js} +4 -3
- package/dist/cli-delegate/{chunk-SIOMDAKL.js → chunk-VYZGJLCA.js} +29 -39
- package/dist/cli-delegate/chunk-W5JXMF2T.js +77 -0
- package/dist/cli-delegate/{chunk-4SHNERBL.js → chunk-XIAPY44N.js} +1 -1
- package/dist/cli-delegate/{chunk-JHMMWNJ2.js → chunk-YHAPONWV.js} +1 -1
- package/dist/cli-delegate/cmd_conformance.js +9 -8
- package/dist/cli-delegate/cmd_doctor.js +4 -4
- package/dist/cli-delegate/cmd_doctor_neighbours.js +2 -2
- package/dist/cli-delegate/cmd_explain.js +1 -1
- package/dist/cli-delegate/cmd_export.js +6 -6
- package/dist/cli-delegate/cmd_fleet.js +3 -3
- package/dist/cli-delegate/cmd_preflight.js +3 -3
- package/dist/cli-delegate/cmd_prune.js +6 -6
- package/dist/cli-delegate/cmd_settings_migrate.js +6 -6
- package/dist/cli-delegate/cmd_settings_set.js +1 -1
- package/dist/cli-delegate/cmd_sync.js +6 -6
- package/dist/cli-delegate/cmd_uninstall.js +6 -6
- package/dist/cli-delegate/cmd_update.js +9 -13
- package/dist/cli-delegate/cmd_validate.js +6 -6
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +4 -4
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +1 -1
- package/dist/discovery/dormancy-report.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 +98 -74
- package/dist/hooks/dispatch.sha256 +1 -1
- package/dist/install/claudeRuleRewrite.js +10 -3
- package/dist/install/conflict.js +24 -2
- package/dist/install/conflictTracker.js +14 -3
- package/dist/install/install.mjs +222 -117
- package/dist/install/installThinLayer.js +1 -0
- package/dist/install/loggedWrites.js +142 -0
- package/dist/install/paths.js +12 -2
- package/dist/install/preserve.js +25 -4
- package/dist/install/txlog.js +10 -6
- package/dist/mcp/registry-manifest.json +2 -2
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +845 -294
- package/dist/scripts/_lib/egress_rules.js +4 -1
- package/dist/scripts/_lib/identifier_redaction.js +35 -2
- package/dist/scripts/ai_council/seat_policy.js +7 -1
- package/dist/server/schemas/settings.js +1 -1
- package/package.json +1 -1
- package/src/config/ci-local-parity.yml +1 -1
- package/src/config/gate-coverage.yml +27 -7
- package/src/config/gate-violation-baselines.json +8 -2
- package/src/config/hook-bundle-budget.json +2 -2
- package/src/config/production-entries.json +18 -0
- package/src/config/release-gate-locality.yml +0 -7
- package/src/install/claudeRuleRewrite.ts +10 -1
- package/src/install/conflict.ts +24 -1
- package/src/install/conflictTracker.ts +18 -2
- package/src/install/installThinLayer.ts +6 -0
- package/src/install/loggedWrites.ts +148 -0
- package/src/install/paths.ts +11 -2
- package/src/install/preserve.ts +40 -4
- package/src/install/txlog.ts +10 -6
- package/src/scripts/_cli/cmd_conformance.ts +3 -2
- package/src/scripts/_cli/cmd_update.ts +15 -17
- package/src/scripts/_lib/council_settings_block.ts +9 -2
- package/src/scripts/_lib/egress_rules.ts +4 -1
- package/src/scripts/_lib/host_capability.ts +10 -5
- package/src/scripts/_lib/identifier_redaction.ts +38 -2
- package/src/scripts/_lib/price_freshness.ts +112 -0
- package/src/scripts/_lib/production_reach.ts +194 -0
- package/src/scripts/_lib/quota_parked.ts +17 -28
- package/src/scripts/_lib/release_findings_ingest.ts +13 -335
- package/src/scripts/_lib/tier_downshift_verdict.ts +81 -35
- package/src/scripts/ai_council/chairman.ts +5 -2
- package/src/scripts/ai_council/clients.ts +4 -3
- package/src/scripts/ai_council/free_hand_shadow.ts +24 -12
- package/src/scripts/ai_council/free_route_catalog.ts +142 -5
- package/src/scripts/ai_council/free_route_client.ts +4 -0
- package/src/scripts/ai_council/hand_payload.ts +115 -7
- package/src/scripts/ai_council/orchestrator.ts +7 -10
- package/src/scripts/ai_council/route_chooser.ts +1 -1
- package/src/scripts/ai_council/route_member.ts +66 -4
- package/src/scripts/ai_council/seat_policy.ts +8 -1
- package/src/scripts/ai_council/self_hosted_probe.ts +327 -0
- package/src/scripts/ai_council/status_surface.ts +2 -0
- package/src/scripts/ask_transport.ts +137 -15
- package/src/scripts/check_finding_dispositions.ts +25 -71
- package/src/scripts/check_release_pr_shape.ts +3 -3
- package/src/scripts/check_step_production_reach.ts +257 -0
- package/src/scripts/council_cli.ts +10 -8
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +3 -0
- package/src/scripts/hooks/dispatch_hook.ts +2 -2
- package/src/scripts/hooks/payload_stub.ts +27 -0
- package/src/scripts/hooks/spawn_guard_shadow_hook.ts +29 -70
- package/src/scripts/hooks/subagent_ledger_hook.ts +80 -0
- package/src/scripts/install.ts +2 -2
- package/src/scripts/lint_decision_classes.ts +34 -0
- package/src/scripts/lint_hook_manifest.ts +24 -0
- package/src/scripts/lint_roadmap_blockers.ts +52 -3
- package/src/scripts/release.ts +5 -9
- package/src/scripts/release_drill.ts +11 -165
- package/src/scripts/release_publication.ts +0 -9
- package/src/scripts/report_production_reach.ts +35 -0
- package/src/scripts/worker_reuse_shadow_report.ts +399 -1
- package/src/server/schemas/settings.ts +1 -1
- package/dist/cli-delegate/chunk-A4QJ6ENT.js +0 -50
- /package/dist/cli-delegate/{chunk-E6XNBVE4.js → chunk-KR5ZIFPO.js} +0 -0
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* mutable and unaudited; it is transport, not a record). Every blocking
|
|
12
12
|
* finding in the ledger (see `isBlocking`) must carry a complete disposition
|
|
13
13
|
* `{status: fixed|false_positive|accepted_risk, commit (when fixed),
|
|
14
|
-
* rationale, verified_by}
|
|
14
|
+
* rationale, verified_by}` when the gate is run.
|
|
15
15
|
*
|
|
16
16
|
* Modes:
|
|
17
17
|
* --release X.Y.Z [--dir <ledger dir>] validate the committed ledger
|
|
@@ -24,50 +24,28 @@
|
|
|
24
24
|
* self_review_gate --findings-out) into the ledger with an empty
|
|
25
25
|
* disposition, so validation is red until a human fills it.
|
|
26
26
|
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
27
|
+
* AN ABSENT LEDGER IS NOT A FAILURE (owner, 2026-10-22). A release waits for
|
|
28
|
+
* no review ledger, because every commit on main is already reviewed and
|
|
29
|
+
* merged; the 17.0.0 cut stopped for a day on a ledger whose self-review never
|
|
30
|
+
* finished. No release workflow waits for this check, and an absent ledger
|
|
31
|
+
* passes, shipped or not. The consistency coverage guard still executes it,
|
|
32
|
+
* so any committed ledger must remain valid.
|
|
31
33
|
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* unreleased the local tag list is COMPLETE and lacks it, or the remote
|
|
35
|
-
* says so -> normal in-flight state, absent ledger is fine
|
|
36
|
-
* undeterminable the tag list cannot settle it and no remote answered ->
|
|
37
|
-
* exit 2. Refusing beats passing: a silent green here is the
|
|
38
|
-
* very inversion this split exists to remove
|
|
39
|
-
*
|
|
40
|
-
* THE SOURCE IS THE TAG / RELEASE, AND DELIBERATELY NOT `CHANGELOG.md`. The
|
|
41
|
-
* changelog heading is written by the release PR itself — gh pr diff 1836 shows
|
|
42
|
-
* "+## [14.16.0](...)" inside the release commit — so on branch release/X the
|
|
43
|
-
* changelog claims X is released before X exists. Reading it would redden every
|
|
44
|
-
* in-flight release branch over a file nobody could yet have written, which is
|
|
45
|
-
* the exact behaviour this split is here to preserve. The tag is created at
|
|
46
|
-
* publish, after merge, so it cannot make that mistake.
|
|
47
|
-
*
|
|
48
|
-
* A local tag MISS is not authoritative on its own: actions/checkout fetches
|
|
49
|
-
* depth 1 and no tags by default, and the one workflow that runs this gate does
|
|
50
|
-
* not override either, so in CI the local tag list is EMPTY. See releaseStatus
|
|
51
|
-
* for the asymmetry and the remote fallback.
|
|
52
|
-
*
|
|
53
|
-
* AN EMPTY LEDGER MUST SAY WHY IT IS EMPTY. The released/unreleased split above
|
|
54
|
-
* closed the missing-file half; it left the other half open, because
|
|
55
|
-
* `findings: []` still passed while asserting nothing. A writer could satisfy
|
|
34
|
+
* AN EMPTY LEDGER MUST SAY WHY IT IS EMPTY. A ledger that exists is a record,
|
|
35
|
+
* and `findings: []` used to pass while asserting nothing. A writer could satisfy
|
|
56
36
|
* the gate by creating an empty file, which is the same silence wearing the
|
|
57
37
|
* shape of a record. `no_findings_reason` is now required whenever the file
|
|
58
38
|
* exists and the array is empty — see empty_ledger_problem for what the reason
|
|
59
39
|
* has to distinguish.
|
|
60
40
|
*
|
|
61
41
|
* A future reader changing allowEmpty below is the person this is addressed to:
|
|
62
|
-
* the EMPTY_VALID waiver
|
|
63
|
-
*
|
|
64
|
-
* empty ledger with no reason.
|
|
42
|
+
* the EMPTY_VALID waiver covers an absent ledger and an EXPLAINED empty one. It
|
|
43
|
+
* does not cover an empty ledger with no reason.
|
|
65
44
|
*
|
|
66
|
-
* Exit codes: 0 complete · 1 missing/incomplete dispositions (an
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
* a broken ledger file is a hard error, not a neutral skip.
|
|
45
|
+
* Exit codes: 0 complete or no ledger · 1 missing/incomplete dispositions (an
|
|
46
|
+
* unexplained empty ledger among them) · 2 usage error or schema error.
|
|
47
|
+
* Deliberately NOT fail-open: this script never calls a model; a broken ledger
|
|
48
|
+
* file is a hard error, not a neutral skip.
|
|
71
49
|
*/
|
|
72
50
|
import { spawnSync } from 'node:child_process';
|
|
73
51
|
import * as fs from 'node:fs';
|
|
@@ -861,7 +839,7 @@ function main(argv: readonly string[]): number {
|
|
|
861
839
|
fs.writeFileSync(ledgerPath, JSON.stringify(ledger, null, 2) + '\n');
|
|
862
840
|
process.stdout.write(
|
|
863
841
|
`📥 ingested ${added} new finding(s) into ${path.relative(REPO_ROOT, ledgerPath)} — ` +
|
|
864
|
-
'fill dispositions
|
|
842
|
+
'fill dispositions by hand; no release waits for them\n',
|
|
865
843
|
);
|
|
866
844
|
if (carried.length > 0) {
|
|
867
845
|
process.stdout.write(` carried integrity fields: ${carried.join(', ')}\n`);
|
|
@@ -883,30 +861,9 @@ function main(argv: readonly string[]): number {
|
|
|
883
861
|
return 0;
|
|
884
862
|
}
|
|
885
863
|
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
process.stderr.write(
|
|
890
|
-
`❌ ${release} has shipped and carries no findings ledger at `
|
|
891
|
-
+ `${path.relative(REPO_ROOT, ledgerPath)}.\n`
|
|
892
|
-
+ ' Absence is not evidence of zero — the release PR\'s self-review may have\n'
|
|
893
|
-
+ ' reported findings that were never ingested. Recover the machine block and:\n'
|
|
894
|
-
+ ` ./scripts-run src/scripts/check_finding_dispositions --ingest <findings.json> --release ${release}\n`,
|
|
895
|
-
);
|
|
896
|
-
return 1;
|
|
897
|
-
}
|
|
898
|
-
if (status === 'undeterminable') {
|
|
899
|
-
process.stderr.write(
|
|
900
|
-
`❌ cannot determine whether ${release} has shipped: this checkout tag list is`
|
|
901
|
-
+ ' incomplete (shallow or tagless) and no remote answered.\n'
|
|
902
|
-
+ ' Refusing to pass on an absent ledger without knowing — that silent green is\n'
|
|
903
|
-
+ ' the defect this check replaces. Fetch tags (actions/checkout fetch-tags: true)\n'
|
|
904
|
-
+ ' or make the gh CLI available.\n',
|
|
905
|
-
);
|
|
906
|
-
return 2;
|
|
907
|
-
}
|
|
908
|
-
}
|
|
909
|
-
|
|
864
|
+
// An absent ledger is not a failure, shipped or not: a release waits for no
|
|
865
|
+
// review ledger, because everything on main is already reviewed and merged
|
|
866
|
+
// (owner, 2026-10-22). It reads as an empty ledger below.
|
|
910
867
|
let ledger: Ledger = { schema_version: 1, release, findings: [] };
|
|
911
868
|
if (fs.existsSync(ledgerPath)) {
|
|
912
869
|
try {
|
|
@@ -965,15 +922,12 @@ function main(argv: readonly string[]): number {
|
|
|
965
922
|
units: 'recorded finding(s)',
|
|
966
923
|
roots: [path.relative(REPO_ROOT, ledgerPath)],
|
|
967
924
|
allowEmpty:
|
|
968
|
-
'EMPTY_VALID: zero recorded findings
|
|
969
|
-
+ '
|
|
970
|
-
+ '
|
|
971
|
-
+ '
|
|
972
|
-
+ '
|
|
973
|
-
+ '
|
|
974
|
-
+ 'remains is an EXPLAINED empty ledger and an unreleased version. Un-ingested '
|
|
975
|
-
+ 'findings on an in-flight release are caught by --pr (unrecorded_findings), '
|
|
976
|
-
+ 'never by this count.',
|
|
925
|
+
'EMPTY_VALID: zero recorded findings is a pass. A version with no ledger reads '
|
|
926
|
+
+ 'as empty, shipped or not, because a release waits for no review ledger '
|
|
927
|
+
+ '(owner, 2026-10-22). It does not cover an existing empty ledger that does not '
|
|
928
|
+
+ 'say why it is empty, which returns 1 above via empty_ledger_problem. '
|
|
929
|
+
+ 'Un-ingested findings are caught by --pr (unrecorded_findings), never by this '
|
|
930
|
+
+ 'count.',
|
|
977
931
|
});
|
|
978
932
|
} catch (exc) {
|
|
979
933
|
if (exc instanceof DeadScopeError) {
|
|
@@ -41,9 +41,9 @@ const ALLOWLIST_GLOBS = [
|
|
|
41
41
|
'src/domains/*/pack.yaml',
|
|
42
42
|
'src/domains/*/README.md',
|
|
43
43
|
'docs/archive/CHANGELOG-pre-*.md',
|
|
44
|
-
// Finding-disposition ledger
|
|
45
|
-
//
|
|
46
|
-
//
|
|
44
|
+
// Finding-disposition ledger — optional, committed by hand; a release PR
|
|
45
|
+
// may carry one. No release workflow waits for it (2026-10-22); the
|
|
46
|
+
// consistency coverage guard still requires any committed ledger to be valid.
|
|
47
47
|
'agents/evidence/release-findings/*.json',
|
|
48
48
|
// Evidence-temperature census — `taskfiles/content.yml` § release-prepare
|
|
49
49
|
// writes one per release, so without this entry the pipeline generates a
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
/**
|
|
3
|
+
* A step a pull request ticks reaches production (road-to-a-tick-the-shipped-path-earns 3.2).
|
|
4
|
+
*
|
|
5
|
+
* Reads only the PR's own new ticks, the `check_step_receipts` diff walk. For each,
|
|
6
|
+
* the step's SUBJECT modules are the `src/` paths its block names (its receipt's
|
|
7
|
+
* `production code touched:` bound included), and its tests are the test files it
|
|
8
|
+
* names plus each subject's conventional test. Every public symbol such a test
|
|
9
|
+
* takes from a subject must be imported by name somewhere in the production
|
|
10
|
+
* closure (`_lib/production_reach.ts`), or the subject is itself an entry. A
|
|
11
|
+
* `_`-prefixed name is a testing seam and is not counted.
|
|
12
|
+
*
|
|
13
|
+
* A step whose code is built but not wired stays `[ ]` with `built, not wired`; a
|
|
14
|
+
* ticked step carrying that phrase is refused outright. `production entry: <path>`
|
|
15
|
+
* in the block adds an entry for that step. Report mode exits 0 (3.3: one release
|
|
16
|
+
* of shadow first); `--enforce` exits 1 on a finding.
|
|
17
|
+
*
|
|
18
|
+
* Usage:
|
|
19
|
+
* ./scripts-run src/scripts/check_step_production_reach [--base <ref>] [--head <ref>] [--enforce] [--json]
|
|
20
|
+
* ./scripts-run src/scripts/check_step_production_reach --self-test
|
|
21
|
+
*
|
|
22
|
+
* Exit 0 clean or report-only · 1 a finding while enforcing · 2 usage or git error.
|
|
23
|
+
*/
|
|
24
|
+
import { spawnSync } from 'node:child_process';
|
|
25
|
+
import * as path from 'node:path';
|
|
26
|
+
import { fileURLToPath } from 'node:url';
|
|
27
|
+
|
|
28
|
+
import {
|
|
29
|
+
commitTreeOf,
|
|
30
|
+
ENTRIES_CONFIG_REL,
|
|
31
|
+
moduleImports,
|
|
32
|
+
productionReach,
|
|
33
|
+
type Reach,
|
|
34
|
+
type ReachTree,
|
|
35
|
+
worktreeOf,
|
|
36
|
+
} from './_lib/production_reach.js';
|
|
37
|
+
import { GateLedger } from './_lib/gate_ledger.js';
|
|
38
|
+
import { reportScanned } from './_lib/scan_scope.js';
|
|
39
|
+
|
|
40
|
+
const _HERE = fileURLToPath(import.meta.url);
|
|
41
|
+
const REPO_ROOT = path.resolve(path.dirname(_HERE), '..', '..');
|
|
42
|
+
const ROADMAP_ROOT = 'agents/roadmaps';
|
|
43
|
+
const TICK = /^- \[x\] \*\*([^\s*]+)/;
|
|
44
|
+
|
|
45
|
+
export interface NewTick {
|
|
46
|
+
readonly file: string;
|
|
47
|
+
readonly step: string;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Steps an added line ticks that no removed line of the same file ticked. */
|
|
51
|
+
export function newTicks(diff: string): NewTick[] {
|
|
52
|
+
const perFile = new Map<string, { added: string[]; removed: Set<string> }>();
|
|
53
|
+
let cur: { added: string[]; removed: Set<string> } | null = null;
|
|
54
|
+
for (const line of diff.split('\n')) {
|
|
55
|
+
if (line.startsWith('+++ ')) {
|
|
56
|
+
const target = line.slice(4).replace(/^b\//, '');
|
|
57
|
+
cur = target === '/dev/null' ? null : { added: [], removed: new Set() };
|
|
58
|
+
if (cur !== null) perFile.set(target, cur);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (cur === null || line.startsWith('--- ')) continue;
|
|
62
|
+
const id = TICK.exec(line.slice(1))?.[1];
|
|
63
|
+
if (id === undefined) continue;
|
|
64
|
+
if (line.startsWith('+')) cur.added.push(id);
|
|
65
|
+
else if (line.startsWith('-')) cur.removed.add(id);
|
|
66
|
+
}
|
|
67
|
+
const out: NewTick[] = [];
|
|
68
|
+
for (const [file, { added, removed }] of perFile) {
|
|
69
|
+
for (const step of added) if (!removed.has(step)) out.push({ file, step });
|
|
70
|
+
}
|
|
71
|
+
return out;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** The step's block: its tick line through the line before the next checkbox or heading. */
|
|
75
|
+
export function stepBlock(text: string, step: string): string | null {
|
|
76
|
+
const lines = text.split('\n');
|
|
77
|
+
const start = lines.findIndex((l) => TICK.exec(l)?.[1] === step);
|
|
78
|
+
if (start < 0) return null;
|
|
79
|
+
let end = start + 1;
|
|
80
|
+
while (end < lines.length && !/^\s*- \[[ x~-]\]/.test(lines[end] as string) && !/^#{1,6}\s/.test(lines[end] as string)) end += 1;
|
|
81
|
+
return lines.slice(start, end).join('\n');
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const PATH_RE = /(?:^|[\s`(:,])((?:src\/|tests\/|_lib\/)[A-Za-z0-9_/.-]+\.ts)\b/g;
|
|
85
|
+
|
|
86
|
+
/** `src/` subjects and test files a block names; `_lib/x.ts` means `src/scripts/_lib/x.ts`. */
|
|
87
|
+
export function namedPaths(tree: ReachTree, block: string): { subjects: string[]; tests: string[]; entries: string[] } {
|
|
88
|
+
const subjects = new Set<string>();
|
|
89
|
+
const tests = new Set<string>();
|
|
90
|
+
for (const m of block.matchAll(PATH_RE)) {
|
|
91
|
+
let p = m[1] as string;
|
|
92
|
+
if (p.startsWith('_lib/')) p = `src/scripts/${p}`;
|
|
93
|
+
if (tree.read(p) === null) continue;
|
|
94
|
+
if (/\.test\.ts$/.test(p)) tests.add(p);
|
|
95
|
+
else if (p.startsWith('src/')) subjects.add(p);
|
|
96
|
+
}
|
|
97
|
+
const entries = [...block.matchAll(/production entry:\s*`?([A-Za-z0-9_/.-]+\.ts)`?/g)].map((m) => m[1] as string);
|
|
98
|
+
// A named test's own module is a subject too: `tests/scripts/_lib_x.test.ts` → `src/scripts/_lib/x.ts`.
|
|
99
|
+
for (const t of tests) {
|
|
100
|
+
const stem = path.posix.basename(t, '.test.ts');
|
|
101
|
+
const own = t.startsWith('src/')
|
|
102
|
+
? t.replace(/\.test\.ts$/, '.ts')
|
|
103
|
+
: `src/scripts/${stem.startsWith('_lib_') ? `_lib/${stem.slice(5)}` : stem}.ts`;
|
|
104
|
+
if (tree.read(own) !== null) subjects.add(own);
|
|
105
|
+
}
|
|
106
|
+
for (const s of [...subjects]) {
|
|
107
|
+
const dir = path.posix.dirname(s);
|
|
108
|
+
const base = path.posix.basename(s, '.ts');
|
|
109
|
+
const rel = s.replace(/^src\/scripts\//, '').replace(/\.ts$/, '').replace(/\//g, '_');
|
|
110
|
+
for (const c of [`${dir}/${base}.test.ts`, `tests/scripts/${base}.test.ts`, `tests/scripts/${rel}.test.ts`]) {
|
|
111
|
+
if (tree.read(c) !== null) tests.add(c);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return { subjects: [...subjects].sort(), tests: [...tests].sort(), entries };
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export interface Finding {
|
|
118
|
+
readonly file: string;
|
|
119
|
+
readonly step: string;
|
|
120
|
+
readonly reason: string;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** The unreached public symbols this block's tests take from its subjects. */
|
|
124
|
+
export function checkStep(tree: ReachTree, reach: Reach, file: string, step: string, block: string): Finding | null {
|
|
125
|
+
// Quoted, the phrase is talk about the rule; bare, it is the step's own status.
|
|
126
|
+
if (/built, not wired/i.test(block.replace(/`[^`]*`/g, ''))) {
|
|
127
|
+
return { file, step, reason: 'ticked while it says `built, not wired` — such a step stays `[ ]`' };
|
|
128
|
+
}
|
|
129
|
+
const { subjects, tests, entries } = namedPaths(tree, block);
|
|
130
|
+
const r = entries.length ? productionReach(tree, entries) : reach;
|
|
131
|
+
const reached = (key: string, mod: string): boolean =>
|
|
132
|
+
r.entries.has(mod) || r.symbols.has(key) || r.symbols.has(`${mod}#*`);
|
|
133
|
+
const missing: string[] = [];
|
|
134
|
+
for (const t of tests) {
|
|
135
|
+
for (const imp of moduleImports(tree, t)) {
|
|
136
|
+
if (!subjects.includes(imp.target)) continue;
|
|
137
|
+
for (const n of imp.names) {
|
|
138
|
+
if (n === '*' || n.startsWith('_')) continue;
|
|
139
|
+
if (!reached(`${imp.target}#${n}`, imp.target)) missing.push(`${imp.target}#${n}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (missing.length === 0) return null;
|
|
144
|
+
return {
|
|
145
|
+
file,
|
|
146
|
+
step,
|
|
147
|
+
reason: `tested but unreached from any production entry: ${[...new Set(missing)].join(', ')}`,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function git(root: string, args: string[]): string | null {
|
|
152
|
+
const res = spawnSync('git', args, { cwd: root, encoding: 'utf-8', maxBuffer: 256 * 1024 * 1024 });
|
|
153
|
+
return res.status === 0 ? res.stdout : null;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export function run(
|
|
157
|
+
root: string,
|
|
158
|
+
base: string,
|
|
159
|
+
head: string | null,
|
|
160
|
+
ledger: GateLedger = new GateLedger('check_step_production_reach'),
|
|
161
|
+
): { scanned: number; findings: Finding[] } | null {
|
|
162
|
+
const range = head === null ? `${base}...HEAD` : `${base}...${head}`;
|
|
163
|
+
const diff = git(root, ['diff', '-U0', '--find-renames', '--no-color', range, '--', `${ROADMAP_ROOT}/`]);
|
|
164
|
+
if (diff === null) return null;
|
|
165
|
+
const ticks = newTicks(diff);
|
|
166
|
+
// A replayed commit predates the entries config, so the checkout's copy is read over it.
|
|
167
|
+
const config = worktreeOf(root).read(ENTRIES_CONFIG_REL);
|
|
168
|
+
const at = head === null ? worktreeOf(root) : commitTreeOf(root, head);
|
|
169
|
+
const tree: ReachTree = { list: at.list, read: (rel) => (rel === ENTRIES_CONFIG_REL ? config : at.read(rel)) };
|
|
170
|
+
const reach = productionReach(tree);
|
|
171
|
+
const findings: Finding[] = [];
|
|
172
|
+
for (const { file, step } of ticks) {
|
|
173
|
+
const target = `${file}#${step}`;
|
|
174
|
+
ledger.plan(target);
|
|
175
|
+
const block = stepBlock(tree.read(file) ?? '', step);
|
|
176
|
+
if (block === null) {
|
|
177
|
+
ledger.skip(target, 'precondition_unmet');
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
const f = checkStep(tree, reach, file, step, block);
|
|
181
|
+
if (f === null) ledger.complete(target);
|
|
182
|
+
else {
|
|
183
|
+
ledger.fail(target, f.reason);
|
|
184
|
+
findings.push(f);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return { scanned: ticks.length, findings };
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function selfTest(): number {
|
|
191
|
+
// Assembled at run time, so prepack's import scan does not read fixture text as a shipped import.
|
|
192
|
+
const from = (spec: string): string => `from '${spec}';`;
|
|
193
|
+
const files: Record<string, string> = {
|
|
194
|
+
'src/config/production-entries.json': JSON.stringify({ entries: ['src/main.ts'], entry_sources: [] }),
|
|
195
|
+
'src/main.ts': `import { wired } ${from('./lib.js')}\nwired();\n`,
|
|
196
|
+
'src/lib.ts': 'export function wired() {}\nexport function unwired() {}\n',
|
|
197
|
+
'src/cli.ts': `import { unwired } ${from('./lib.js')}\nunwired();\n`,
|
|
198
|
+
'tests/lib.test.ts': `import { wired, unwired } ${from('../src/lib.js')}\n`,
|
|
199
|
+
'tests/wired.test.ts': `import { wired } ${from('../src/lib.js')}\n`,
|
|
200
|
+
};
|
|
201
|
+
const tree: ReachTree = { list: () => Object.keys(files), read: (rel) => files[rel] ?? null };
|
|
202
|
+
const reach = productionReach(tree);
|
|
203
|
+
const failures: string[] = [];
|
|
204
|
+
const unwired = checkStep(tree, reach, 'r.md', '1.1', '- [x] **1.1 x** `src/lib.ts`\n verify: `tests/lib.test.ts`');
|
|
205
|
+
if (unwired === null || !unwired.reason.includes('src/lib.ts#unwired')) failures.push('an unwired symbol did not red');
|
|
206
|
+
if (checkStep(tree, reach, 'r.md', '1.2', '- [x] **1.2 x** `src/lib.ts`\n verify: `tests/wired.test.ts`') !== null) {
|
|
207
|
+
failures.push('a wired symbol red');
|
|
208
|
+
}
|
|
209
|
+
const declared = '- [x] **1.4 x** `src/lib.ts`, production entry: `src/cli.ts`\n verify: `tests/lib.test.ts`';
|
|
210
|
+
if (checkStep(tree, reach, 'r.md', '1.4', declared) !== null) failures.push('a declared production entry was not honoured');
|
|
211
|
+
if (checkStep(tree, reach, 'r.md', '1.3', '- [x] **1.3 x** built, not wired') === null) {
|
|
212
|
+
failures.push('a ticked built-not-wired step did not red');
|
|
213
|
+
}
|
|
214
|
+
if (newTicks('+++ b/r.md\n-- [ ] **1.1 x**\n+- [x] **1.1 x**\n').length !== 1) failures.push('a new tick was not read');
|
|
215
|
+
if (newTicks('+++ b/r.md\n-- [x] **1.1 x**\n+- [x] **1.1 y**\n').length !== 0) failures.push('a reworded tick read as new');
|
|
216
|
+
for (const f of failures) process.stderr.write(`❌ check_step_production_reach --self-test: ${f}\n`);
|
|
217
|
+
if (failures.length === 0) process.stdout.write('✅ check_step_production_reach --self-test: both directions hold\n');
|
|
218
|
+
return failures.length ? 1 : 0;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export function main(argv: readonly string[]): number {
|
|
222
|
+
if (argv.includes('--self-test')) return selfTest();
|
|
223
|
+
const value = (flag: string): string | undefined => {
|
|
224
|
+
const i = argv.indexOf(flag);
|
|
225
|
+
return i >= 0 ? argv[i + 1] : undefined;
|
|
226
|
+
};
|
|
227
|
+
const ledger = new GateLedger('check_step_production_reach');
|
|
228
|
+
const result = run(REPO_ROOT, value('--base') ?? 'origin/main', value('--head') ?? null, ledger);
|
|
229
|
+
if (result === null) {
|
|
230
|
+
process.stderr.write('check_step_production_reach: cannot diff the range\n');
|
|
231
|
+
return 2;
|
|
232
|
+
}
|
|
233
|
+
reportScanned({
|
|
234
|
+
gate: 'check_step_production_reach',
|
|
235
|
+
scanned: result.scanned,
|
|
236
|
+
units: 'newly ticked step(s)',
|
|
237
|
+
roots: [`git diff ${value('--base') ?? 'origin/main'}... -- ${ROADMAP_ROOT}/`],
|
|
238
|
+
allowEmpty: 'EMPTY_VALID: the scan root is a DIFF, and most pull requests tick no roadmap step.',
|
|
239
|
+
});
|
|
240
|
+
if (!argv.includes('--json')) ledger.report();
|
|
241
|
+
else ledger.finalize();
|
|
242
|
+
if (argv.includes('--json')) {
|
|
243
|
+
process.stdout.write(JSON.stringify(result, null, 2) + '\n');
|
|
244
|
+
} else if (result.findings.length === 0) {
|
|
245
|
+
process.stdout.write('✅ check_step_production_reach: every newly ticked step reaches a production entry\n');
|
|
246
|
+
}
|
|
247
|
+
const enforce = argv.includes('--enforce');
|
|
248
|
+
if (!argv.includes('--json')) {
|
|
249
|
+
for (const f of result.findings) process.stdout.write(`${enforce ? '❌' : '⚠️ '} ${f.file}: step ${f.step} — ${f.reason}\n`);
|
|
250
|
+
if (result.findings.length && !enforce) process.stdout.write(' Report only (shadow, step 3.3): nothing is refused yet.\n');
|
|
251
|
+
}
|
|
252
|
+
return enforce && result.findings.length ? 1 : 0;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if (process.argv[1] !== undefined && path.resolve(process.argv[1]) === path.resolve(_HERE)) {
|
|
256
|
+
process.exit(main(process.argv.slice(2)));
|
|
257
|
+
}
|
|
@@ -86,7 +86,7 @@ import {
|
|
|
86
86
|
resolvedTransportFor as _resolvedTransportFor,
|
|
87
87
|
routeStatusLines as _routeStatusLines,
|
|
88
88
|
} from './ai_council/status_surface.js';
|
|
89
|
-
import { routeMemberFor } from './ai_council/route_member.js';
|
|
89
|
+
import { routeMemberFor, stampSeatCeilings } from './ai_council/route_member.js';
|
|
90
90
|
import { evaluateQuorum, type QuorumResult } from './ai_council/quorum.js';
|
|
91
91
|
import {
|
|
92
92
|
_emitQuorumEvent,
|
|
@@ -886,6 +886,7 @@ function build_members(settings: Dict, opts: BuildMembersOptions = {}): External
|
|
|
886
886
|
'prints the resolved path.',
|
|
887
887
|
);
|
|
888
888
|
}
|
|
889
|
+
stampSeatCeilings(members, members_cfg);
|
|
889
890
|
wireCouncilFallback(fallback_out, ai, {
|
|
890
891
|
repoRoot: REPO_ROOT, isDict: _isDict, membersCfg: members_cfg, overrides,
|
|
891
892
|
hasApiRung: (p) => _API_PROVIDERS.has(p),
|
|
@@ -1350,7 +1351,7 @@ export function chairman_candidates(membersRaw: Dict): ChairmanCandidate[] {
|
|
|
1350
1351
|
candidates.push({
|
|
1351
1352
|
name,
|
|
1352
1353
|
tier: typeof md['tier'] === 'number' ? (md['tier'] as number) : null,
|
|
1353
|
-
...(billing !== null ? { billing } : {}),
|
|
1354
|
+
...(billing !== null ? { billing, route: true } : {}),
|
|
1354
1355
|
});
|
|
1355
1356
|
}
|
|
1356
1357
|
return candidates;
|
|
@@ -1439,12 +1440,13 @@ function _maybe_run_chairman(
|
|
|
1439
1440
|
// `model_unservable` being eligible and by the retry's spend gate, and the
|
|
1440
1441
|
// annotation below still reports FAILED rather than degrading silently.
|
|
1441
1442
|
// `consult` builds its own ledger: this is a separate invocation.
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
original_ask: args.original_ask,
|
|
1446
|
-
|
|
1447
|
-
|
|
1443
|
+
if (client instanceof CliClient) client.blind = blind;
|
|
1444
|
+
let out: CouncilResponse[];
|
|
1445
|
+
try {
|
|
1446
|
+
out = consult([client], synthQ, budget, { table, project: project as never, original_ask: args.original_ask, cli_fallback });
|
|
1447
|
+
} finally {
|
|
1448
|
+
if (client instanceof CliClient) client.blind = false;
|
|
1449
|
+
}
|
|
1448
1450
|
const r = out[0] ?? null;
|
|
1449
1451
|
if (r === null || r.error !== null || r.text.trim() === '') {
|
|
1450
1452
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"fingerprint":"08b7193fdf2e5c821c287e4869cca75073cba044364aeb1e632c86478d6ca877:109044","body_fingerprint":"4d292b77bb366df6440741112db86aad404dc85ff237387c132f49137009feef:20776","manifest":{"schema_version":1,"concerns":{"chat-history":{"script":"src/scripts/chat_history.ts","args":["hook-dispatch"],"fail_closed":false,"severity":"advisory","effect":"telemetry","needs_payload_bodies":["result"]},"hot-context":{"script":"src/scripts/hot_context_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"memory"},"handoff-context":{"script":"src/scripts/handoff_context_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"context"},"roadmap-progress":{"script":"src/scripts/roadmap_progress_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"formatting","needs_payload_bodies":["input"]},"onboarding-gate":{"script":"src/scripts/onboarding_gate_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification"},"context-hygiene":{"script":"src/scripts/context_hygiene_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"verify-before-complete":{"script":"src/scripts/before_complete_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","needs_payload_bodies":["input","result"]},"ship-diff-volume":{"script":"src/scripts/hooks/ship_diff_volume_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","needs_payload_bodies":["input"]},"minimal-safe-diff":{"script":"src/scripts/minimal_safe_diff_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","needs_payload_bodies":["input"]},"injection-scan":{"script":"src/scripts/injection_scan_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","needs_payload_bodies":["input","result"]},"block-no-verify":{"script":"src/scripts/hooks/block_no_verify.ts","args":[],"fail_closed":true,"severity":"blocking","effect":"permission","needs_payload_bodies":["input"]},"block-kernel-rule-writes":{"script":"src/scripts/hooks/block_kernel_rule_writes.ts","args":[],"fail_closed":true,"severity":"blocking","effect":"permission","needs_payload_bodies":["input"]},"block-plumbing-writes":{"script":"src/scripts/hooks/block_plumbing_writes.ts","args":[],"fail_closed":true,"severity":"blocking","effect":"permission","needs_payload_bodies":["input"]},"one-question-per-ask":{"script":"src/scripts/hooks/one_question_per_ask_hook.ts","args":[],"fail_closed":false,"severity":"blocking","effect":"permission","tools":["AskUserQuestion","AskQuestion","UserQuestion","ask_user_question","ask_question","user_question"],"needs_payload_bodies":["input"]},"block-speaking-inbox-dir":{"script":"src/scripts/hooks/block_speaking_inbox_dir.ts","args":[],"fail_closed":false,"severity":"blocking","effect":"permission","needs_payload_bodies":["input"]},"block-credential-reads":{"script":"src/scripts/hooks/block_credential_reads.ts","args":[],"fail_closed":false,"severity":"blocking","effect":"permission","needs_payload_bodies":["input"]},"block-config-weakening":{"script":"src/scripts/hooks/block_config_weakening.ts","args":[],"fail_closed":false,"severity":"blocking","effect":"permission","needs_payload_bodies":["input"]},"rtk-wrap":{"script":"src/scripts/hooks/rtk_wrap_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"formatting","needs_payload_bodies":["input"]},"design-slop":{"script":"src/scripts/hooks/design_slop_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","needs_payload_bodies":["input"]},"design-pass":{"script":"src/scripts/hooks/design_pass_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification","needs_payload_bodies":["input"]},"design-pass-stop":{"script":"src/scripts/hooks/design_pass_hook.ts","args":["--slot","stop"],"fail_closed":false,"severity":"advisory","effect":"notification"},"ui-route-nudge":{"script":"src/scripts/hooks/ui_route_nudge_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification","needs_payload_bodies":["input"]},"suggestion-capture":{"script":"src/scripts/hooks/suggestion_capture_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"chain-nudge":{"script":"src/scripts/hooks/chain_nudge_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification","needs_payload_bodies":["input"]},"code-graph-context":{"script":"src/scripts/hooks/code_graph_context_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"context","tools":["Grep","Glob","Read","Bash"],"needs_payload_bodies":["input"]},"memory-learn":{"script":"src/scripts/memory_learn_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"memory"},"first-run-gate":{"script":"src/scripts/first_run_gate_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification"},"profile-staleness":{"script":"src/scripts/profile_staleness_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification"},"wrapper-freshness":{"script":"src/scripts/wrapper_freshness_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification"},"surface-probe":{"script":"src/scripts/surface_probe_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"team-review-gate":{"script":"src/scripts/team_review_gate_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification"},"pr-url-reminder":{"script":"src/scripts/pr_url_reminder_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification","needs_payload_bodies":["input","result"]},"push-settle":{"script":"src/scripts/hooks/push_settle_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","needs_payload_bodies":["input","result"]},"language-mirror":{"script":"src/scripts/language_mirror_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"context"},"git-authorization":{"script":"src/scripts/git_authorization_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification"},"evidence-independence":{"script":"src/scripts/hooks/evidence_independence.ts","args":[],"fail_closed":false,"severity":"blocking","effect":"permission","needs_payload_bodies":["input"]},"session-canary":{"script":"src/scripts/session_canary_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"context"},"council-availability":{"script":"src/scripts/council_availability_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification"},"telemetry-disclosure":{"script":"src/scripts/telemetry_disclosure_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification"},"telemetry-flush":{"script":"src/scripts/hooks/telemetry_flush_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"self-repair":{"script":"src/scripts/self_repair_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"session-register":{"script":"src/scripts/session_register_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"orchestration-record":{"script":"src/scripts/hooks/orchestration_record_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry","tools":["Agent","Task"],"needs_payload_bodies":["input","result"]},"telemetry-usage":{"script":"src/scripts/hooks/telemetry_usage_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry","tools":["Skill"],"needs_payload_bodies":["input"]},"mcp-usage-observation":{"script":"src/scripts/hooks/mcp_usage_observation_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"delegation-nudge":{"script":"src/scripts/hooks/delegation_nudge_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification","nudge_rank":1},"skill-route":{"script":"src/scripts/hooks/skill_route_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"context","nudge_rank":2},"rule-inject":{"script":"src/scripts/hooks/rule_inject_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"context","needs_payload_bodies":["input"]},"obligation-settle":{"script":"src/scripts/hooks/obligation_settle_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification"},"end-review-nudge":{"script":"src/scripts/hooks/end_review_nudge_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification","skip_on_refusal_retry":true},"review-baseline":{"script":"src/scripts/hooks/review_baseline_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"turn-end-gate":{"script":"src/scripts/hooks/turn_end_gate_hook.ts","args":[],"fail_closed":false,"severity":"blocking","effect":"permission"},"comment-discipline":{"script":"src/scripts/hooks/comment_discipline_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","tools":["Write","Edit"],"needs_payload_bodies":["input"]},"edit-shape":{"script":"src/scripts/hooks/edit_shape_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","tools":["Write"],"needs_payload_bodies":["input"]},"reread-guard":{"script":"src/scripts/hooks/reread_guard_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","tools":["Read","Edit","Write"],"needs_payload_bodies":["input"]},"memory-recall":{"script":"src/scripts/hooks/memory_recall_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"memory","tools":["Bash","Edit","Write","MultiEdit","str-replace-editor","save-file","launch-process"],"needs_payload_bodies":["input"]},"session-eol":{"script":"src/scripts/hooks/session_eol_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification"},"interruption-ledger":{"script":"src/scripts/hooks/interruption_ledger_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry","skip_on_refusal_retry":true},"subagent-ledger":{"script":"src/scripts/hooks/subagent_ledger_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"tool-result-bytes":{"script":"src/scripts/hooks/tool_result_bytes_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"spawn-guard-shadow":{"script":"src/scripts/hooks/spawn_guard_shadow_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry","tools":["Agent","Task","SendMessage"],"needs_payload_bodies":["input","result"]},"host-rate-marker":{"script":"src/scripts/hooks/host_rate_marker_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"source-first-gate":{"script":"src/scripts/hooks/source_first_gate_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry","needs_payload_bodies":["input"]},"journal-record":{"script":"src/scripts/hooks/journal_record_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"}},"roles":{"worker":{"drop":["delegation-nudge","skill-route","end-review-nudge","review-baseline","council-availability","team-review-gate","self-repair","session-eol","interruption-ledger"]}},"platforms":{"augment":{"ask":"text","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","telemetry-flush"],"stop":["chat-history","verify-before-complete","self-repair","session-register","roadmap-progress","design-pass-stop"],"pre_tool_use":["block-no-verify","evidence-independence","block-kernel-rule-writes","block-plumbing-writes","block-config-weakening","block-speaking-inbox-dir","block-credential-reads","rtk-wrap","design-slop","ui-route-nudge","code-graph-context","chain-nudge","ship-diff-volume","reread-guard","memory-recall"],"post_tool_use":["chat-history","roadmap-progress","context-hygiene","verify-before-complete","minimal-safe-diff","injection-scan","pr-url-reminder","push-settle","orchestration-record","telemetry-usage","mcp-usage-observation","tool-result-bytes","edit-shape","comment-discipline","design-pass"]},"claude":{"ask":"native","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","review-baseline","journal-record","rule-inject"],"session_end":["chat-history","memory-learn","session-register","roadmap-progress","telemetry-flush","journal-record"],"stop":["chat-history","verify-before-complete","team-review-gate","end-review-nudge","obligation-settle","turn-end-gate","self-repair","session-register","session-eol","interruption-ledger","roadmap-progress","design-pass-stop","suggestion-capture","journal-record"],"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","rule-inject","suggestion-capture","journal-record"],"pre_tool_use":["block-no-verify","evidence-independence","block-kernel-rule-writes","block-plumbing-writes","block-config-weakening","block-speaking-inbox-dir","block-credential-reads","one-question-per-ask","rtk-wrap","design-slop","ui-route-nudge","code-graph-context","chain-nudge","ship-diff-volume","reread-guard","spawn-guard-shadow","source-first-gate","memory-recall"],"post_tool_use":["chat-history","roadmap-progress","context-hygiene","verify-before-complete","minimal-safe-diff","injection-scan","pr-url-reminder","push-settle","orchestration-record","telemetry-usage","mcp-usage-observation","tool-result-bytes","edit-shape","comment-discipline","language-mirror","design-pass","journal-record","spawn-guard-shadow"],"pre_compact":["language-mirror","rule-inject","journal-record"],"subagent_start":["subagent-ledger","journal-record"],"subagent_stop":["subagent-ledger","journal-record"],"agent_error":["host-rate-marker"]},"cowork":{"ask":"text","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","telemetry-flush"],"stop":["chat-history","verify-before-complete","self-repair","session-register","roadmap-progress","design-pass-stop"],"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","evidence-independence","block-kernel-rule-writes","block-plumbing-writes","block-config-weakening","block-speaking-inbox-dir","block-credential-reads","rtk-wrap","design-slop","ui-route-nudge","code-graph-context","chain-nudge","ship-diff-volume","reread-guard","spawn-guard-shadow","source-first-gate","memory-recall"],"post_tool_use":["chat-history","roadmap-progress","context-hygiene","verify-before-complete","minimal-safe-diff","injection-scan","pr-url-reminder","push-settle","orchestration-record","telemetry-usage","mcp-usage-observation","tool-result-bytes","edit-shape","comment-discipline","design-pass","spawn-guard-shadow"],"subagent_start":["subagent-ledger"],"subagent_stop":["subagent-ledger"]},"cursor":{"ask":"text","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","telemetry-flush"],"stop":["chat-history","verify-before-complete","self-repair","session-register","roadmap-progress","design-pass-stop"],"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","push-settle","orchestration-record","telemetry-usage","mcp-usage-observation","tool-result-bytes","edit-shape","comment-discipline","design-pass"]},"cline":{"ask":"text","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","telemetry-flush"],"stop":["chat-history","verify-before-complete","self-repair","session-register","roadmap-progress","design-pass-stop"],"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","push-settle","orchestration-record","telemetry-usage","mcp-usage-observation","tool-result-bytes","edit-shape","comment-discipline","design-pass"]},"windsurf":{"ask":"text","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","verify-before-complete","self-repair","session-register","design-pass-stop"],"user_prompt_submit":["chat-history","verify-before-complete","language-mirror","git-authorization","session-canary","self-repair","session-register"]},"gemini":{"ask":"text","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","telemetry-flush"],"stop":["chat-history","verify-before-complete","self-repair","session-register","roadmap-progress","design-pass-stop"],"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","push-settle","orchestration-record","telemetry-usage","mcp-usage-observation","tool-result-bytes","edit-shape","comment-discipline","design-pass"]},"copilot":{"ask":"text","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","PostToolUseFailure":"post_tool_use","PreToolUse":"pre_tool_use","PreCompact":"pre_compact","SubagentStart":"subagent_start","SubagentStop":"subagent_stop","StopFailure":"agent_error"},"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"}}}}
|
|
1
|
+
{"fingerprint":"30b82f3ba5aa4c971915094f5f9e31647e476211304ac9657075cac72f19a391:109264","body_fingerprint":"1b21abf258fdb3d2684c9562058adf0c33b4b945b36da054f03bc794d63fa430:20850","manifest":{"schema_version":1,"concerns":{"chat-history":{"script":"src/scripts/chat_history.ts","args":["hook-dispatch"],"fail_closed":false,"severity":"advisory","effect":"telemetry","needs_payload_bodies":["result"]},"hot-context":{"script":"src/scripts/hot_context_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"memory"},"handoff-context":{"script":"src/scripts/handoff_context_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"context"},"roadmap-progress":{"script":"src/scripts/roadmap_progress_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"formatting","needs_payload_bodies":["input"]},"onboarding-gate":{"script":"src/scripts/onboarding_gate_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification"},"context-hygiene":{"script":"src/scripts/context_hygiene_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"verify-before-complete":{"script":"src/scripts/before_complete_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","needs_payload_bodies":["input","result"]},"ship-diff-volume":{"script":"src/scripts/hooks/ship_diff_volume_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","needs_payload_bodies":["input"]},"minimal-safe-diff":{"script":"src/scripts/minimal_safe_diff_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","needs_payload_bodies":["input"]},"injection-scan":{"script":"src/scripts/injection_scan_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","needs_payload_bodies":["input","result"]},"block-no-verify":{"script":"src/scripts/hooks/block_no_verify.ts","args":[],"fail_closed":true,"severity":"blocking","effect":"permission","needs_payload_bodies":["input"]},"block-kernel-rule-writes":{"script":"src/scripts/hooks/block_kernel_rule_writes.ts","args":[],"fail_closed":true,"severity":"blocking","effect":"permission","needs_payload_bodies":["input"]},"block-plumbing-writes":{"script":"src/scripts/hooks/block_plumbing_writes.ts","args":[],"fail_closed":true,"severity":"blocking","effect":"permission","needs_payload_bodies":["input"]},"one-question-per-ask":{"script":"src/scripts/hooks/one_question_per_ask_hook.ts","args":[],"fail_closed":false,"severity":"blocking","effect":"permission","tools":["AskUserQuestion","AskQuestion","UserQuestion","ask_user_question","ask_question","user_question"],"needs_payload_bodies":["input"]},"block-speaking-inbox-dir":{"script":"src/scripts/hooks/block_speaking_inbox_dir.ts","args":[],"fail_closed":false,"severity":"blocking","effect":"permission","needs_payload_bodies":["input"]},"block-credential-reads":{"script":"src/scripts/hooks/block_credential_reads.ts","args":[],"fail_closed":false,"severity":"blocking","effect":"permission","needs_payload_bodies":["input"]},"block-config-weakening":{"script":"src/scripts/hooks/block_config_weakening.ts","args":[],"fail_closed":false,"severity":"blocking","effect":"permission","needs_payload_bodies":["input"]},"rtk-wrap":{"script":"src/scripts/hooks/rtk_wrap_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"formatting","needs_payload_bodies":["input"]},"design-slop":{"script":"src/scripts/hooks/design_slop_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","needs_payload_bodies":["input"]},"design-pass":{"script":"src/scripts/hooks/design_pass_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification","needs_payload_bodies":["input"]},"design-pass-stop":{"script":"src/scripts/hooks/design_pass_hook.ts","args":["--slot","stop"],"fail_closed":false,"severity":"advisory","effect":"notification"},"ui-route-nudge":{"script":"src/scripts/hooks/ui_route_nudge_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification","needs_payload_bodies":["input"]},"suggestion-capture":{"script":"src/scripts/hooks/suggestion_capture_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"chain-nudge":{"script":"src/scripts/hooks/chain_nudge_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification","needs_payload_bodies":["input"]},"code-graph-context":{"script":"src/scripts/hooks/code_graph_context_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"context","tools":["Grep","Glob","Read","Bash"],"needs_payload_bodies":["input"]},"memory-learn":{"script":"src/scripts/memory_learn_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"memory"},"first-run-gate":{"script":"src/scripts/first_run_gate_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification"},"profile-staleness":{"script":"src/scripts/profile_staleness_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification"},"wrapper-freshness":{"script":"src/scripts/wrapper_freshness_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification"},"surface-probe":{"script":"src/scripts/surface_probe_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"team-review-gate":{"script":"src/scripts/team_review_gate_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification"},"pr-url-reminder":{"script":"src/scripts/pr_url_reminder_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification","needs_payload_bodies":["input","result"]},"push-settle":{"script":"src/scripts/hooks/push_settle_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","needs_payload_bodies":["input","result"]},"language-mirror":{"script":"src/scripts/language_mirror_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"context"},"git-authorization":{"script":"src/scripts/git_authorization_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification"},"evidence-independence":{"script":"src/scripts/hooks/evidence_independence.ts","args":[],"fail_closed":false,"severity":"blocking","effect":"permission","needs_payload_bodies":["input"]},"session-canary":{"script":"src/scripts/session_canary_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"context"},"council-availability":{"script":"src/scripts/council_availability_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification"},"telemetry-disclosure":{"script":"src/scripts/telemetry_disclosure_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification"},"telemetry-flush":{"script":"src/scripts/hooks/telemetry_flush_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"self-repair":{"script":"src/scripts/self_repair_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"session-register":{"script":"src/scripts/session_register_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"orchestration-record":{"script":"src/scripts/hooks/orchestration_record_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry","tools":["Agent","Task"],"needs_payload_bodies":["input","result"]},"telemetry-usage":{"script":"src/scripts/hooks/telemetry_usage_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry","tools":["Skill"],"needs_payload_bodies":["input"]},"mcp-usage-observation":{"script":"src/scripts/hooks/mcp_usage_observation_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"delegation-nudge":{"script":"src/scripts/hooks/delegation_nudge_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification","nudge_rank":1},"skill-route":{"script":"src/scripts/hooks/skill_route_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"context","nudge_rank":2},"rule-inject":{"script":"src/scripts/hooks/rule_inject_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"context","needs_payload_bodies":["input"]},"obligation-settle":{"script":"src/scripts/hooks/obligation_settle_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification"},"end-review-nudge":{"script":"src/scripts/hooks/end_review_nudge_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification","skip_on_refusal_retry":true},"review-baseline":{"script":"src/scripts/hooks/review_baseline_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"turn-end-gate":{"script":"src/scripts/hooks/turn_end_gate_hook.ts","args":[],"fail_closed":false,"severity":"blocking","effect":"permission"},"comment-discipline":{"script":"src/scripts/hooks/comment_discipline_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","tools":["Write","Edit"],"needs_payload_bodies":["input"]},"edit-shape":{"script":"src/scripts/hooks/edit_shape_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","tools":["Write"],"needs_payload_bodies":["input"]},"reread-guard":{"script":"src/scripts/hooks/reread_guard_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"verification","tools":["Read","Edit","Write"],"needs_payload_bodies":["input"]},"memory-recall":{"script":"src/scripts/hooks/memory_recall_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"memory","tools":["Bash","Edit","Write","MultiEdit","str-replace-editor","save-file","launch-process"],"needs_payload_bodies":["input"]},"session-eol":{"script":"src/scripts/hooks/session_eol_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"notification"},"interruption-ledger":{"script":"src/scripts/hooks/interruption_ledger_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry","skip_on_refusal_retry":true},"subagent-ledger":{"script":"src/scripts/hooks/subagent_ledger_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"tool-result-bytes":{"script":"src/scripts/hooks/tool_result_bytes_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"spawn-guard-shadow":{"script":"src/scripts/hooks/spawn_guard_shadow_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry","tools":["Agent","Task","SendMessage"],"needs_payload_bodies":["input","result"],"payload_fields":["name","subagent_type","to","recipient_kind","agentId"]},"host-rate-marker":{"script":"src/scripts/hooks/host_rate_marker_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"source-first-gate":{"script":"src/scripts/hooks/source_first_gate_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry","needs_payload_bodies":["input"]},"journal-record":{"script":"src/scripts/hooks/journal_record_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"}},"roles":{"worker":{"drop":["delegation-nudge","skill-route","end-review-nudge","review-baseline","council-availability","team-review-gate","self-repair","session-eol","interruption-ledger"]}},"platforms":{"augment":{"ask":"text","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","telemetry-flush"],"stop":["chat-history","verify-before-complete","self-repair","session-register","roadmap-progress","design-pass-stop"],"pre_tool_use":["block-no-verify","evidence-independence","block-kernel-rule-writes","block-plumbing-writes","block-config-weakening","block-speaking-inbox-dir","block-credential-reads","rtk-wrap","design-slop","ui-route-nudge","code-graph-context","chain-nudge","ship-diff-volume","reread-guard","memory-recall"],"post_tool_use":["chat-history","roadmap-progress","context-hygiene","verify-before-complete","minimal-safe-diff","injection-scan","pr-url-reminder","push-settle","orchestration-record","telemetry-usage","mcp-usage-observation","tool-result-bytes","edit-shape","comment-discipline","design-pass"]},"claude":{"ask":"native","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","review-baseline","journal-record","rule-inject"],"session_end":["chat-history","memory-learn","session-register","roadmap-progress","telemetry-flush","journal-record"],"stop":["chat-history","verify-before-complete","team-review-gate","end-review-nudge","obligation-settle","turn-end-gate","self-repair","session-register","session-eol","interruption-ledger","roadmap-progress","design-pass-stop","suggestion-capture","journal-record"],"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","rule-inject","suggestion-capture","journal-record"],"pre_tool_use":["block-no-verify","evidence-independence","block-kernel-rule-writes","block-plumbing-writes","block-config-weakening","block-speaking-inbox-dir","block-credential-reads","one-question-per-ask","rtk-wrap","design-slop","ui-route-nudge","code-graph-context","chain-nudge","ship-diff-volume","reread-guard","spawn-guard-shadow","source-first-gate","memory-recall"],"post_tool_use":["chat-history","roadmap-progress","context-hygiene","verify-before-complete","minimal-safe-diff","injection-scan","pr-url-reminder","push-settle","orchestration-record","telemetry-usage","mcp-usage-observation","tool-result-bytes","edit-shape","comment-discipline","language-mirror","design-pass","journal-record","spawn-guard-shadow"],"pre_compact":["language-mirror","rule-inject","journal-record"],"subagent_start":["subagent-ledger","journal-record"],"subagent_stop":["subagent-ledger","journal-record"],"agent_error":["host-rate-marker"]},"cowork":{"ask":"text","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","telemetry-flush"],"stop":["chat-history","verify-before-complete","self-repair","session-register","roadmap-progress","design-pass-stop"],"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","evidence-independence","block-kernel-rule-writes","block-plumbing-writes","block-config-weakening","block-speaking-inbox-dir","block-credential-reads","rtk-wrap","design-slop","ui-route-nudge","code-graph-context","chain-nudge","ship-diff-volume","reread-guard","spawn-guard-shadow","source-first-gate","memory-recall"],"post_tool_use":["chat-history","roadmap-progress","context-hygiene","verify-before-complete","minimal-safe-diff","injection-scan","pr-url-reminder","push-settle","orchestration-record","telemetry-usage","mcp-usage-observation","tool-result-bytes","edit-shape","comment-discipline","design-pass","spawn-guard-shadow"],"subagent_start":["subagent-ledger"],"subagent_stop":["subagent-ledger"]},"cursor":{"ask":"text","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","telemetry-flush"],"stop":["chat-history","verify-before-complete","self-repair","session-register","roadmap-progress","design-pass-stop"],"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","push-settle","orchestration-record","telemetry-usage","mcp-usage-observation","tool-result-bytes","edit-shape","comment-discipline","design-pass"]},"cline":{"ask":"text","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","telemetry-flush"],"stop":["chat-history","verify-before-complete","self-repair","session-register","roadmap-progress","design-pass-stop"],"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","push-settle","orchestration-record","telemetry-usage","mcp-usage-observation","tool-result-bytes","edit-shape","comment-discipline","design-pass"]},"windsurf":{"ask":"text","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","verify-before-complete","self-repair","session-register","design-pass-stop"],"user_prompt_submit":["chat-history","verify-before-complete","language-mirror","git-authorization","session-canary","self-repair","session-register"]},"gemini":{"ask":"text","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","telemetry-flush"],"stop":["chat-history","verify-before-complete","self-repair","session-register","roadmap-progress","design-pass-stop"],"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","push-settle","orchestration-record","telemetry-usage","mcp-usage-observation","tool-result-bytes","edit-shape","comment-discipline","design-pass"]},"copilot":{"ask":"text","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","PostToolUseFailure":"post_tool_use","PreToolUse":"pre_tool_use","PreCompact":"pre_compact","SubagentStart":"subagent_start","SubagentStop":"subagent_stop","StopFailure":"agent_error"},"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"}}}}
|
|
@@ -1422,6 +1422,9 @@ concerns:
|
|
|
1422
1422
|
# addresses, because a send names the worker and the ledger keys its id.
|
|
1423
1423
|
tools: [Agent, Task, SendMessage]
|
|
1424
1424
|
needs_payload_bodies: [input, result]
|
|
1425
|
+
# Each body narrowed to the addressing fields it reads: never a prompt,
|
|
1426
|
+
# a message or a result body (ratification 2026-10-22, condition 4).
|
|
1427
|
+
payload_fields: [name, subagent_type, to, recipient_kind, agentId]
|
|
1425
1428
|
# The host's StopFailure with error class rate_limit writes the quota_parked
|
|
1426
1429
|
# marker tagged host-sourced; record-only, and every other class writes
|
|
1427
1430
|
# nothing (road-to-a-cold-start-paid-once 4.3).
|