@event4u/agent-config 17.0.0 → 17.2.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 +157 -468
- package/README.md +4 -3
- package/dist/agent-src/commands/project/analyze.md +9 -6
- package/dist/agent-src/commands/project/map.md +58 -0
- package/dist/agent-src/commands/project.md +5 -3
- package/dist/agent-src/contexts/execution/host-capability-manifest.md +5 -3
- package/dist/agent-src/skills/code-intelligence/SKILL.md +6 -0
- 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/registry.js +1 -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 +32 -47
- 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 +41 -15
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +3 -3
- package/dist/discovery/dormancy-report.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +6 -5
- package/dist/discovery/trust-report.md +2 -2
- package/dist/discovery/workspaces.json +5 -4
- package/dist/hooks/dispatch.js +163 -148
- package/dist/hooks/dispatch.sha256 +1 -1
- package/dist/hooks/instructions_observer.chunk.cjs +301 -0
- package/dist/hooks/instructions_observer.chunk.cjs.sha256 +1 -0
- 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 +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +33595 -22916
- 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 +4 -1
- package/src/config/ci-local-parity.yml +1 -1
- package/src/config/continuity-surface.json +7 -0
- package/src/config/evaluator-budgets.json +4 -4
- package/src/config/gate-coverage.yml +27 -7
- package/src/config/gate-violation-baselines.json +9 -3
- package/src/config/gitignore-block.txt +6 -0
- package/src/config/hook-bundle-budget.json +19 -4
- package/src/config/hook-token-budget.json +1 -1
- package/src/config/packed-binary-manifest.json +27 -0
- package/src/config/production-entries.json +18 -0
- package/src/config/release-gate-locality.yml +0 -7
- package/src/config/skill-body-budget.json +7 -1
- 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/bench_ab_complexity.ts +14 -2
- package/src/scripts/_lib/collector_record.ts +1 -0
- 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/runtime_journal.ts +7 -7
- 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/code_graph/build.ts +210 -10
- package/src/scripts/code_graph/cli.ts +168 -46
- package/src/scripts/code_graph/detect.ts +5 -4
- package/src/scripts/code_graph/docs_layer.ts +57 -0
- package/src/scripts/code_graph/extract.ts +58 -13
- package/src/scripts/code_graph/extract_more.ts +314 -0
- package/src/scripts/code_graph/laravel_overlay.ts +454 -0
- package/src/scripts/code_graph/map.ts +846 -0
- package/src/scripts/code_graph/map_model.ts +977 -0
- package/src/scripts/code_graph/map_verify.ts +140 -0
- package/src/scripts/code_graph/map_viewer/viewer.css +278 -0
- package/src/scripts/code_graph/map_viewer/viewer.js +756 -0
- package/src/scripts/code_graph/scip_reader.ts +201 -0
- package/src/scripts/code_graph/sqlite_store.ts +8 -1
- package/src/scripts/code_graph/types.ts +81 -15
- package/src/scripts/code_graph/validate.ts +16 -26
- package/src/scripts/code_graph/verbs.ts +7 -0
- package/src/scripts/council_cli.ts +10 -8
- package/src/scripts/hook_chunks.mjs +7 -0
- package/src/scripts/hook_manifest.json +1 -1
- package/src/scripts/hook_manifest.yaml +23 -0
- package/src/scripts/hooks/dispatch_hook.ts +4 -4
- package/src/scripts/hooks/instructions_observer_hook.ts +25 -6
- package/src/scripts/hooks/lazy_concern.ts +4 -0
- 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-hooks.sh +5 -0
- package/src/scripts/install.ts +2 -2
- package/src/scripts/lint_agents_layout.ts +2 -0
- package/src/scripts/lint_decision_classes.ts +34 -0
- package/src/scripts/lint_hook_manifest.ts +25 -0
- package/src/scripts/lint_roadmap_blockers.ts +52 -3
- package/src/scripts/mcp_server/consumer_tool_catalog.json +53 -6
- package/src/scripts/mcp_server/graph_tools.ts +73 -1
- package/src/scripts/mcp_server/tools.ts +19 -36
- 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/src/vendor/grammars/README.md +10 -5
- package/src/vendor/grammars/tree-sitter-go.wasm +0 -0
- package/src/vendor/grammars/tree-sitter-java.wasm +0 -0
- package/src/vendor/grammars/tree-sitter-python.wasm +0 -0
- package/dist/cli-delegate/chunk-A4QJ6ENT.js +0 -50
- /package/dist/cli-delegate/{chunk-E6XNBVE4.js → chunk-KR5ZIFPO.js} +0 -0
|
@@ -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":"42e661504c14c219092fe030a1e89d6b94e28568dc5f6fc3b81ed69d2c653938:110425","body_fingerprint":"3f626590e35e1ad6ebc66c61a96fe5008ace6ff2df53fb4f645d023b69e2945b:21099","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},"instructions-observer":{"script":"src/scripts/hooks/instructions_observer_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"telemetry"},"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"],"instructions_loaded":["instructions-observer"]},"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","InstructionsLoaded":"instructions_loaded","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"}}}}
|
|
@@ -1364,6 +1364,19 @@ concerns:
|
|
|
1364
1364
|
#
|
|
1365
1365
|
# Never blocks, never warns: exit 0 on every path including a malformed
|
|
1366
1366
|
# payload or an unwritable disk. fail_closed: false.
|
|
1367
|
+
# road-to-a-setup-that-decides-itself step 1.1 — the instructions-loaded
|
|
1368
|
+
# observer. CAPTURE ONLY: one classified line per loaded file into
|
|
1369
|
+
# `<machine root>/runtime/arrivals/<session>.jsonl`, the input of the arrival
|
|
1370
|
+
# record the computed layer form reads. Emits nothing to the model; exit 0 on
|
|
1371
|
+
# every path. Loaded from its own conditional chunk, never inlined.
|
|
1372
|
+
# Kill switch: `AGENT_CONFIG_INSTRUCTIONS_OBSERVER=off`, or remove the
|
|
1373
|
+
# `instructions_loaded` row under `platforms.claude` and reinstall.
|
|
1374
|
+
instructions-observer:
|
|
1375
|
+
script: src/scripts/hooks/instructions_observer_hook.ts
|
|
1376
|
+
args: []
|
|
1377
|
+
fail_closed: false
|
|
1378
|
+
severity: advisory
|
|
1379
|
+
effect: telemetry
|
|
1367
1380
|
subagent-ledger:
|
|
1368
1381
|
script: src/scripts/hooks/subagent_ledger_hook.ts
|
|
1369
1382
|
args: []
|
|
@@ -1422,6 +1435,9 @@ concerns:
|
|
|
1422
1435
|
# addresses, because a send names the worker and the ledger keys its id.
|
|
1423
1436
|
tools: [Agent, Task, SendMessage]
|
|
1424
1437
|
needs_payload_bodies: [input, result]
|
|
1438
|
+
# Each body narrowed to the addressing fields it reads: never a prompt,
|
|
1439
|
+
# a message or a result body (ratification 2026-10-22, condition 4).
|
|
1440
|
+
payload_fields: [name, subagent_type, to, recipient_kind, agentId]
|
|
1425
1441
|
# The host's StopFailure with error class rate_limit writes the quota_parked
|
|
1426
1442
|
# marker tagged host-sourced; record-only, and every other class writes
|
|
1427
1443
|
# nothing (road-to-a-cold-start-paid-once 4.3).
|
|
@@ -1637,6 +1653,10 @@ platforms:
|
|
|
1637
1653
|
subagent_start: [subagent-ledger, journal-record]
|
|
1638
1654
|
subagent_stop: [subagent-ledger, journal-record]
|
|
1639
1655
|
agent_error: [host-rate-marker]
|
|
1656
|
+
# Observe-only; the host runs this event asynchronously, once per loaded file.
|
|
1657
|
+
# `journal-record` is deliberately not bound here: the event is recordable
|
|
1658
|
+
# (RECORDED_EVENTS), but its capture lives under runtime/arrivals/.
|
|
1659
|
+
instructions_loaded: [instructions-observer]
|
|
1640
1660
|
|
|
1641
1661
|
# Cowork — the Claude desktop app's local-agent-mode runtime, built
|
|
1642
1662
|
# on top of the Claude Code CLI. Same lifecycle vocabulary, same
|
|
@@ -1793,6 +1813,9 @@ native_event_aliases:
|
|
|
1793
1813
|
# agents/evidence/investigations/subagent-lifecycle-phase0-host-pin.md.
|
|
1794
1814
|
SubagentStart: subagent_start
|
|
1795
1815
|
SubagentStop: subagent_stop
|
|
1816
|
+
# Present on the installed binary (exact-token count 9):
|
|
1817
|
+
# agents/evidence/investigations/standing-context-40k-host-and-machine-probes.md § 1.
|
|
1818
|
+
InstructionsLoaded: instructions_loaded
|
|
1796
1819
|
# StopFailure fires on an API failure and carries its class in `error`
|
|
1797
1820
|
# (observed on 2.1.308 with `server_error`; `rate_limit` is the host's
|
|
1798
1821
|
# documented value for the plan limit and has not been observed live, so a
|
|
@@ -55,7 +55,7 @@ import {
|
|
|
55
55
|
import { emitFor, type PermissionDecision, type Severity } from "./host_semantics.js";
|
|
56
56
|
import { _concern_permission_verdict, _payload_tool_name, _permission_for } from "./permission_gate.js";
|
|
57
57
|
export { _concern_permission_verdict, _payload_tool_input, _payload_tool_name, _permission_for, _working_tree_root } from "./permission_gate.js";
|
|
58
|
-
import { _concern_body_classes, planPayloadShapes } from "./payload_stub.js";
|
|
58
|
+
import { _concern_body_classes, applyPayloadFields, planPayloadShapes } from "./payload_stub.js";
|
|
59
59
|
import { attributeRefusal, egressInjection, egressViewFor, runEgressStage } from "./egress_stage.js";
|
|
60
60
|
import { resolveSessionRole, type SessionRole } from "../_lib/session_role.js";
|
|
61
61
|
import { stdinReadFailure, denyOnStdinFailure } from './stdin_failure_policy.js';
|
|
@@ -118,8 +118,8 @@ export const EVENT_VOCABULARY: ReadonlySet<string> = new Set([
|
|
|
118
118
|
"stop",
|
|
119
119
|
"pre_compact",
|
|
120
120
|
"agent_error",
|
|
121
|
-
"subagent_start",
|
|
122
|
-
"
|
|
121
|
+
"subagent_start", "subagent_stop",
|
|
122
|
+
"instructions_loaded",
|
|
123
123
|
]);
|
|
124
124
|
|
|
125
125
|
const _SEVERITY_BY_EXIT: Record<number, string> = {
|
|
@@ -1299,7 +1299,7 @@ export function main(argv?: string[]): number {
|
|
|
1299
1299
|
if (!_concern_matches_tool(concern, tool_name)) {
|
|
1300
1300
|
continue;
|
|
1301
1301
|
}
|
|
1302
|
-
const concern_envelope = shapes.shapeFor(keep_classes, egressViewFor(concern));
|
|
1302
|
+
const concern_envelope = applyPayloadFields(concern, shapes.shapeFor(keep_classes, egressViewFor(concern)));
|
|
1303
1303
|
const stubs_served = shapes.stubsFor(keep_classes);
|
|
1304
1304
|
// What was actually SERVED, not what was declared. Recording the
|
|
1305
1305
|
// declaration made the record wrong in both directions on a body-less
|
|
@@ -46,19 +46,20 @@
|
|
|
46
46
|
* the observer has written since. A failure that also prevents writing the mark
|
|
47
47
|
* — the machine root itself unwritable — leaves none.
|
|
48
48
|
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
*
|
|
49
|
+
* BOUND ON `claude` ALONE, FROM ITS OWN CHUNK. The manifest runs it on
|
|
50
|
+
* `instructions_loaded`; the dispatcher loads it through `LAZY_CONCERNS`, so its
|
|
51
|
+
* body is not inlined into the dispatch bundle. The binding itself is: one
|
|
52
|
+
* registry row and the event name, 237 bytes (`hook-bundle-budget.json`).
|
|
52
53
|
*
|
|
53
54
|
* KILL SWITCH. `AGENT_CONFIG_INSTRUCTIONS_OBSERVER=off` makes it a no-op without
|
|
54
|
-
* a reinstall;
|
|
55
|
-
* `
|
|
56
|
-
* it entirely. Either is the
|
|
55
|
+
* a reinstall; removing the one `instructions_loaded` row from
|
|
56
|
+
* `hook_manifest.yaml` and reinstalling removes it entirely. Either is the
|
|
57
57
|
* response to hook failures, duplicate events, a session-start regression or an
|
|
58
58
|
* unexplained test break.
|
|
59
59
|
*/
|
|
60
60
|
import * as fs from 'node:fs';
|
|
61
61
|
import * as path from 'node:path';
|
|
62
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
62
63
|
|
|
63
64
|
import { event4u_root } from '../_lib/user_global_paths.js';
|
|
64
65
|
import { captureInstructionsLoaded, isSessionFile } from '../_lib/instructions_loaded_event.js';
|
|
@@ -168,3 +169,21 @@ export function main(): number {
|
|
|
168
169
|
return EXIT_ALLOW;
|
|
169
170
|
}
|
|
170
171
|
}
|
|
172
|
+
|
|
173
|
+
// The spawn fallback runs this file as a script, so it needs an entry; inside a
|
|
174
|
+
// bundle or chunk every module shares one `import.meta.url`, so it must never fire there.
|
|
175
|
+
declare const __AGENT_CONFIG_BUNDLE__: boolean | undefined;
|
|
176
|
+
function _isCliEntry(): boolean {
|
|
177
|
+
if (typeof __AGENT_CONFIG_BUNDLE__ !== 'undefined' && __AGENT_CONFIG_BUNDLE__) {
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
if (process.argv[1] === undefined) return false;
|
|
181
|
+
const argvUrl = pathToFileURL(path.resolve(process.argv[1])).href;
|
|
182
|
+
if (import.meta.url === argvUrl) return true;
|
|
183
|
+
try {
|
|
184
|
+
return fs.realpathSync(fileURLToPath(import.meta.url)) === fs.realpathSync(path.resolve(process.argv[1]));
|
|
185
|
+
} catch {
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
if (_isCliEntry()) process.exit(main());
|
|
@@ -68,6 +68,10 @@ export const LAZY_CONCERNS: Readonly<Record<string, { readonly chunk: string; re
|
|
|
68
68
|
chunk: 'chat_history.chunk.cjs',
|
|
69
69
|
source: path.join('..', 'chat_history'),
|
|
70
70
|
}),
|
|
71
|
+
'src/scripts/hooks/instructions_observer_hook.ts': Object.freeze({
|
|
72
|
+
chunk: 'instructions_observer.chunk.cjs',
|
|
73
|
+
source: 'instructions_observer_hook',
|
|
74
|
+
}),
|
|
71
75
|
});
|
|
72
76
|
|
|
73
77
|
declare const __AGENT_CONFIG_BUNDLE__: boolean | undefined;
|
|
@@ -387,6 +387,33 @@ export function _concern_body_classes(concern: JsonObject): Set<BodyClass> {
|
|
|
387
387
|
return parseBodyClasses(concern["needs_payload_bodies"]);
|
|
388
388
|
}
|
|
389
389
|
|
|
390
|
+
/**
|
|
391
|
+
* Field-level projection: a concern declaring `payload_fields: [k, …]` gets
|
|
392
|
+
* each tool body reduced to those top-level keys, and a body that is not an
|
|
393
|
+
* object as a stub. It reads only what it was handed, so its privacy does not
|
|
394
|
+
* rest on what it chooses to keep. The same guard floor as the body classes:
|
|
395
|
+
* a blocking or fail-closed concern is never narrowed.
|
|
396
|
+
*/
|
|
397
|
+
export function applyPayloadFields(concern: JsonObject, env: JsonObject): JsonObject {
|
|
398
|
+
const fields = concern["payload_fields"];
|
|
399
|
+
const payload = env["payload"];
|
|
400
|
+
if (!Array.isArray(fields) || !isObject(payload) || concern["fail_closed"] === true || concern["severity"] === "blocking") {
|
|
401
|
+
return env;
|
|
402
|
+
}
|
|
403
|
+
const keep = new Set(fields);
|
|
404
|
+
const out: JsonObject = { ...payload };
|
|
405
|
+
for (const cls of BODY_CLASSES) {
|
|
406
|
+
for (const key of BODY_KEYS[cls]) {
|
|
407
|
+
const v = payload[key];
|
|
408
|
+
if (v === undefined || v === null || isPayloadStub(v)) continue;
|
|
409
|
+
out[key] = isObject(v)
|
|
410
|
+
? Object.fromEntries(Object.entries(v).filter(([k]) => keep.has(k)))
|
|
411
|
+
: makePayloadStub(key, cls, v, new Map([[key, bodyBytes(v)]]));
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
return { ...env, payload: out };
|
|
415
|
+
}
|
|
416
|
+
|
|
390
417
|
/** The per-dispatch shaping plan. Built once, read per concern. */
|
|
391
418
|
export interface PayloadShapePlan {
|
|
392
419
|
/**
|
|
@@ -61,12 +61,15 @@ import { probeHostCapabilities } from '../_lib/host_capability.js';
|
|
|
61
61
|
import { recentHostMarker } from '../_lib/quota_parked.js';
|
|
62
62
|
import { shadowReuseVerdict, type ReuseContext, type WorkerState } from '../_lib/worker_reuse.js';
|
|
63
63
|
import {
|
|
64
|
-
LEDGER_DIR,
|
|
65
64
|
appendLedgerLine,
|
|
66
65
|
openRecordStats,
|
|
66
|
+
readIndexEntry,
|
|
67
67
|
readOpenRecords,
|
|
68
68
|
refFor,
|
|
69
69
|
resolveConsumerRoot,
|
|
70
|
+
stateStamp,
|
|
71
|
+
stopIndexKey,
|
|
72
|
+
writeIndexEntry,
|
|
70
73
|
} from './subagent_ledger_hook.js';
|
|
71
74
|
import { readHookStdin } from './hook_stdin.js';
|
|
72
75
|
import { EXIT_ALLOW } from './exit_codes.js';
|
|
@@ -104,49 +107,6 @@ export const RESUME_TOOL_NAMES: ReadonlySet<string> = new Set(['SendMessage']);
|
|
|
104
107
|
*/
|
|
105
108
|
export type SendKind = 'resume' | 'message_running' | 'message_or_resume';
|
|
106
109
|
|
|
107
|
-
/** Bytes read from the end of each monthly ledger file when looking for a stop. */
|
|
108
|
-
export const STOP_SCAN_BYTES = 1024 * 1024;
|
|
109
|
-
|
|
110
|
-
function tailOf(file: string): string {
|
|
111
|
-
let fd: number;
|
|
112
|
-
try {
|
|
113
|
-
fd = fs.openSync(file, 'r');
|
|
114
|
-
} catch {
|
|
115
|
-
return '';
|
|
116
|
-
}
|
|
117
|
-
try {
|
|
118
|
-
const size = fs.fstatSync(fd).size;
|
|
119
|
-
const length = Math.min(size, STOP_SCAN_BYTES);
|
|
120
|
-
const buf = Buffer.alloc(length);
|
|
121
|
-
fs.readSync(fd, buf, 0, length, size - length);
|
|
122
|
-
return buf.toString('utf8');
|
|
123
|
-
} finally {
|
|
124
|
-
fs.closeSync(fd);
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
function stoppedInSession(root: string, ref: string, sessionId: string, now: Date): boolean {
|
|
129
|
-
const prev = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth() - 1, 1));
|
|
130
|
-
for (const month of [now.toISOString().slice(0, 7), prev.toISOString().slice(0, 7)]) {
|
|
131
|
-
for (const line of tailOf(path.join(root, LEDGER_DIR, `${month}.jsonl`)).split('\n')) {
|
|
132
|
-
if (!line.includes(ref)) continue;
|
|
133
|
-
try {
|
|
134
|
-
const rec = JSON.parse(line) as Record<string, unknown>;
|
|
135
|
-
if (rec['event'] === 'subagent_stop' && rec['ref'] === ref && rec['session_id'] === sessionId) {
|
|
136
|
-
return true;
|
|
137
|
-
}
|
|
138
|
-
} catch {
|
|
139
|
-
// The first line of a tail is usually cut; a torn line is no evidence.
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
return false;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* The ref a named spawn of this session left in the register, read from the
|
|
148
|
-
* same bounded tails as a stop; null when this session named no such worker.
|
|
149
|
-
*/
|
|
150
110
|
/** Longer names are neither recorded nor resolved: a name is an address, not a payload. */
|
|
151
111
|
export const NAME_MAX = 128;
|
|
152
112
|
|
|
@@ -155,27 +115,6 @@ function nameKey(sessionId: string, name: string): string {
|
|
|
155
115
|
return refFor(`subagent-name\0${sessionId}\0${name}`);
|
|
156
116
|
}
|
|
157
117
|
|
|
158
|
-
function refForName(root: string, name: string, sessionId: string, now: Date): string | null {
|
|
159
|
-
if (name.length > NAME_MAX) return null;
|
|
160
|
-
const key = nameKey(sessionId, name);
|
|
161
|
-
let found: string | null = null;
|
|
162
|
-
const prev = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth() - 1, 1));
|
|
163
|
-
for (const month of [prev.toISOString().slice(0, 7), now.toISOString().slice(0, 7)]) {
|
|
164
|
-
for (const line of tailOf(path.join(root, LEDGER_DIR, `${month}.jsonl`)).split('\n')) {
|
|
165
|
-
if (!line.includes('subagent_named')) continue;
|
|
166
|
-
try {
|
|
167
|
-
const rec = JSON.parse(line) as Record<string, unknown>;
|
|
168
|
-
if (rec['event'] === 'subagent_named' && rec['name_key'] === key && typeof rec['ref'] === 'string') {
|
|
169
|
-
found = rec['ref'];
|
|
170
|
-
}
|
|
171
|
-
} catch {
|
|
172
|
-
// A torn line is no evidence.
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
return found;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
118
|
/**
|
|
180
119
|
* Classify one send. `recipient_kind: name` is resolved through the register a
|
|
181
120
|
* named spawn of this session left; any other recipient is taken as an agent id
|
|
@@ -192,10 +131,15 @@ export function classifySend(
|
|
|
192
131
|
const recipient = input['to'];
|
|
193
132
|
if (typeof recipient !== 'string' || recipient === '') return 'message_or_resume';
|
|
194
133
|
if (sessionId === null || sessionId === '') return 'message_or_resume';
|
|
195
|
-
const ref =
|
|
196
|
-
|
|
134
|
+
const ref =
|
|
135
|
+
input['recipient_kind'] !== 'name'
|
|
136
|
+
? refFor(recipient)
|
|
137
|
+
: recipient.length > NAME_MAX
|
|
138
|
+
? null
|
|
139
|
+
: readIndexEntry(root, nameKey(sessionId, recipient), now);
|
|
140
|
+
if (!ref) return 'message_or_resume';
|
|
197
141
|
if (readOpenRecords(root).has(ref)) return 'message_running';
|
|
198
|
-
return
|
|
142
|
+
return readIndexEntry(root, stopIndexKey(sessionId, ref), now) === null ? 'message_or_resume' : 'resume';
|
|
199
143
|
}
|
|
200
144
|
|
|
201
145
|
/**
|
|
@@ -208,8 +152,10 @@ export function recordNamedSpawn(root: string, payload: JsonObject, sessionId: s
|
|
|
208
152
|
const name = input['name'];
|
|
209
153
|
const agentId = result['agentId'];
|
|
210
154
|
if (typeof name !== 'string' || name === '' || name.length > NAME_MAX || typeof agentId !== 'string' || agentId === '') return;
|
|
211
|
-
if (sessionId
|
|
212
|
-
|
|
155
|
+
if (!sessionId) return;
|
|
156
|
+
const key = nameKey(sessionId, name);
|
|
157
|
+
appendLedgerLine(root, nowIso, { event: 'subagent_named', ts: nowIso, ref: refFor(agentId), name_key: key, session_id: sessionId });
|
|
158
|
+
writeIndexEntry(root, nowIso, key, refFor(agentId));
|
|
213
159
|
}
|
|
214
160
|
|
|
215
161
|
/**
|
|
@@ -318,6 +264,18 @@ export function processEnvelope(envelope: JsonValue, consumerRoot: string, deps:
|
|
|
318
264
|
const sessionRaw = payload['session_id'] ?? envelope['session_id'];
|
|
319
265
|
const sessionId = typeof sessionRaw === 'string' ? sessionRaw : null;
|
|
320
266
|
const sendKind: SendKind | null = isResume ? classifySend(consumerRoot, toolInput, sessionId) : null;
|
|
267
|
+
// A spawn's definition and requested name (as its session digest), so a
|
|
268
|
+
// report can join the request to the named worker a reuse would address.
|
|
269
|
+
const reqName = toolInput['name'];
|
|
270
|
+
const spawnFacts = isResume
|
|
271
|
+
? {}
|
|
272
|
+
: {
|
|
273
|
+
...stateStamp(payload['cwd']),
|
|
274
|
+
agent_type: typeof toolInput['subagent_type'] === 'string' ? toolInput['subagent_type'] : null,
|
|
275
|
+
...(typeof reqName === 'string' && reqName && reqName.length <= NAME_MAX && sessionId
|
|
276
|
+
? { name_key: nameKey(sessionId, reqName) }
|
|
277
|
+
: {}),
|
|
278
|
+
};
|
|
321
279
|
// Only the verdict's label and reason codes reach disk — never the tool input.
|
|
322
280
|
const reuse = isResume
|
|
323
281
|
? null
|
|
@@ -357,6 +315,7 @@ export function processEnvelope(envelope: JsonValue, consumerRoot: string, deps:
|
|
|
357
315
|
? {}
|
|
358
316
|
: { candidates: verdicts.map((v) => ({ label: v.label, would_deny: v.would_deny, on: v.on })) }),
|
|
359
317
|
dispatch_kind: sendKind ?? 'spawn',
|
|
318
|
+
...spawnFacts,
|
|
360
319
|
resume_admission: platform !== null && RESUME_ADMISSION_OBSERVED.has(platform) ? 'counted' : 'unobserved',
|
|
361
320
|
...(reuse === null ? {} : { reuse }),
|
|
362
321
|
// A recent host-sourced rate marker: a new spawn would have waited.
|
|
@@ -107,6 +107,7 @@
|
|
|
107
107
|
* undercount landed precisely in parallel fan-out, the mode this instrument
|
|
108
108
|
* exists to measure.
|
|
109
109
|
*/
|
|
110
|
+
import { execFileSync } from 'node:child_process';
|
|
110
111
|
import * as crypto from 'node:crypto';
|
|
111
112
|
import * as fs from 'node:fs';
|
|
112
113
|
import * as path from 'node:path';
|
|
@@ -500,6 +501,78 @@ export function appendLedgerLine(root: string, ts: string, line: Record<string,
|
|
|
500
501
|
fs.appendFileSync(file, `${JSON.stringify(line)}\n`, 'utf8');
|
|
501
502
|
}
|
|
502
503
|
|
|
504
|
+
/**
|
|
505
|
+
* The register's index: one file per key under `index/<YYYY-MM>/`, so a reader
|
|
506
|
+
* answers "did this session stop that leg" or "which ref does this name
|
|
507
|
+
* address" with one stat or read instead of scanning a ledger tail that heavy
|
|
508
|
+
* traffic can push the answer out of. Keys are digests only (`refFor` over a
|
|
509
|
+
* domain-separated string), so no session id, agent id or name is a file name.
|
|
510
|
+
*/
|
|
511
|
+
const INDEX_SUBDIR = 'index';
|
|
512
|
+
|
|
513
|
+
export function writeIndexEntry(root: string, ts: string, key: string, value: string): void {
|
|
514
|
+
if (is_replay_mode()) return;
|
|
515
|
+
const dir = path.join(root, LEDGER_DIR, INDEX_SUBDIR, ts.slice(0, 7));
|
|
516
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
517
|
+
const tmp = path.join(dir, `.${key}.${process.pid}.tmp`);
|
|
518
|
+
try {
|
|
519
|
+
fs.writeFileSync(tmp, value, 'utf8');
|
|
520
|
+
fs.renameSync(tmp, path.join(dir, key));
|
|
521
|
+
} finally {
|
|
522
|
+
fs.rmSync(tmp, { force: true });
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/** The entry for `key` in this month or the previous one; null when neither holds it. */
|
|
527
|
+
export function readIndexEntry(root: string, key: string, now: Date): string | null {
|
|
528
|
+
const prev = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth() - 1, 1));
|
|
529
|
+
for (const month of [now.toISOString().slice(0, 7), prev.toISOString().slice(0, 7)]) {
|
|
530
|
+
try {
|
|
531
|
+
return fs.readFileSync(path.join(root, LEDGER_DIR, INDEX_SUBDIR, month, key), 'utf8');
|
|
532
|
+
} catch {
|
|
533
|
+
// Not in this month.
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
return null;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
/** The commit the checkout containing `dir` is on; null outside a repository or on any failure. */
|
|
540
|
+
export function headOf(dir: string): string | null {
|
|
541
|
+
try {
|
|
542
|
+
// An inherited GIT_DIR / GIT_WORK_TREE would override `-C`.
|
|
543
|
+
const env = Object.fromEntries(Object.entries(process.env).filter(([k]) => !k.startsWith('GIT_')));
|
|
544
|
+
return execFileSync('git', ['-C', dir, 'rev-parse', 'HEAD'], { encoding: 'utf8', timeout: 2000, stdio: ['ignore', 'pipe', 'ignore'], env }).trim() || null;
|
|
545
|
+
} catch {
|
|
546
|
+
return null;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* What a reuse decision compares between a worker's stop and a later spawn,
|
|
552
|
+
* stamped at both so a report can reconstruct it after the fact: the commit,
|
|
553
|
+
* a digest of the directory, and the install epoch (the running bundle's
|
|
554
|
+
* mtime, which changes whenever the package is rebuilt or reinstalled).
|
|
555
|
+
*/
|
|
556
|
+
export function stateStamp(cwd: unknown): { head: string | null; cwd_key: string | null; epoch: number | null } {
|
|
557
|
+
let epoch: number | null = null;
|
|
558
|
+
try {
|
|
559
|
+
epoch = fs.statSync(fileURLToPath(import.meta.url)).mtimeMs;
|
|
560
|
+
} catch {
|
|
561
|
+
// No file behind the module; the epoch stays unknown.
|
|
562
|
+
}
|
|
563
|
+
return typeof cwd === 'string' && cwd
|
|
564
|
+
? { head: headOf(cwd), cwd_key: refFor(cwd), epoch }
|
|
565
|
+
: { head: null, cwd_key: null, epoch };
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
export function stopIndexKey(sessionId: string, ref: string): string {
|
|
569
|
+
return refFor(`subagent-stop\0${sessionId}\0${ref}`);
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
export function recordStopIndex(root: string, ts: string, sessionId: string, ref: string): void {
|
|
573
|
+
writeIndexEntry(root, ts, stopIndexKey(sessionId, ref), '');
|
|
574
|
+
}
|
|
575
|
+
|
|
503
576
|
/**
|
|
504
577
|
* Candidate wall-clock stop-loss arms — Phase 3 Step 3, shadow only.
|
|
505
578
|
*
|
|
@@ -750,7 +823,14 @@ function handleStop(root: string, payload: JsonObject, nowIso: string, sessionId
|
|
|
750
823
|
// candidate was, this says whether it was aimed at the envelope.
|
|
751
824
|
envelope_field_hits: parse.field_hits,
|
|
752
825
|
concurrent_open: countOpen(root),
|
|
826
|
+
...stateStamp(payload['cwd']),
|
|
753
827
|
});
|
|
828
|
+
// After the line, and on its own: a failed index write must not cost the stop record.
|
|
829
|
+
try {
|
|
830
|
+
if (sessionId !== null) recordStopIndex(root, nowIso, sessionId, ref);
|
|
831
|
+
} catch {
|
|
832
|
+
// The guard then reads this stop as unplaced, the safe reading.
|
|
833
|
+
}
|
|
754
834
|
}
|
|
755
835
|
|
|
756
836
|
/** Process an ALREADY-PARSED dispatcher envelope. Always returns EXIT_ALLOW. */
|
|
@@ -674,6 +674,11 @@ if [ -f "$cg_cache" ] && [ -x ./agent-config ]; then
|
|
|
674
674
|
(
|
|
675
675
|
trap 'rmdir "$cg_lock" 2>/dev/null || true' EXIT
|
|
676
676
|
./agent-config code-graph refresh --budget-seconds 60 >/dev/null 2>&1 || true
|
|
677
|
+
# The map follows the index it is drawn from, but only for a
|
|
678
|
+
# project that asked for one: no agents/map/, no map (ADR-297).
|
|
679
|
+
if [ -d agents/map ]; then
|
|
680
|
+
./agent-config code-graph map --no-verify --no-build >/dev/null 2>&1 || true
|
|
681
|
+
fi
|
|
677
682
|
) >/dev/null 2>&1 &
|
|
678
683
|
fi
|
|
679
684
|
fi
|
package/src/scripts/install.ts
CHANGED
|
@@ -3010,14 +3010,14 @@ function _deploy_global_content(
|
|
|
3010
3010
|
info,
|
|
3011
3011
|
warn,
|
|
3012
3012
|
res,
|
|
3013
|
-
preserved_now,
|
|
3013
|
+
preserved_now, claude_rule_rewrite.onlyDeployed(anchor, current_files, (p) => _log_tx_entry('write', p)),
|
|
3014
3014
|
);
|
|
3015
3015
|
// Steps 1.1 and 1.4 of road-to-an-installed-layer-that-is-thinned;
|
|
3016
3016
|
// both modules' headers carry the reasoning.
|
|
3017
3017
|
deployClaudeCarrier({
|
|
3018
3018
|
packageRoot: package_root, rulesDir: path.join(anchor, 'rules'), quiet: state.QUIET, info, warn, userPin: state.FULL_PIN,
|
|
3019
3019
|
wantsThin: installerThinsHost(tool_id, { packageRoot: package_root }),
|
|
3020
|
-
thin: (bodyLinkRoot) => describeThinInstalledLayer(thinInstalledRuleLayer({ rulesDir: path.join(anchor, 'rules'), packageRoot: package_root, preserved: preserved_now, bodyLinkRoot })),
|
|
3020
|
+
thin: (bodyLinkRoot) => describeThinInstalledLayer(thinInstalledRuleLayer({ rulesDir: path.join(anchor, 'rules'), packageRoot: package_root, preserved: preserved_now, bodyLinkRoot, onWrite: claude_rule_rewrite.onlyDeployed(anchor, current_files, (p) => _log_tx_entry('write', p)) })),
|
|
3021
3021
|
});
|
|
3022
3022
|
if (!state.QUIET) for (const l of installReceiptBudgetLines(package_root, undefined, { thisDeploy: new Map([[anchor, current_files]]) })) info(l);
|
|
3023
3023
|
}
|
|
@@ -62,6 +62,7 @@ const ALLOWED_SOURCE_DIRS: ReadonlySet<string> = new Set([
|
|
|
62
62
|
'evidence',
|
|
63
63
|
'features',
|
|
64
64
|
'knowledge', // * consumer
|
|
65
|
+
'map', // * consumer — code-graph map, local-only, gitignored (ADR-297)
|
|
65
66
|
'memory', // * consumer
|
|
66
67
|
'notes', // legacy; new files go to evidence/notes/
|
|
67
68
|
'reports', // legacy; new files go to evidence/reports/ (see agents-layout.md)
|
|
@@ -91,6 +92,7 @@ const CONSUMER_EXPECTED_ENTRIES: ReadonlySet<string> = new Set([
|
|
|
91
92
|
'.gitkeep',
|
|
92
93
|
// Optional but legitimate consumer entries (will not trigger warnings)
|
|
93
94
|
'knowledge',
|
|
95
|
+
'map',
|
|
94
96
|
'memory',
|
|
95
97
|
'proposals',
|
|
96
98
|
'roadmaps',
|