@event4u/agent-config 17.2.1 → 17.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (225) hide show
  1. package/.augment-plugin/marketplace.json +3 -3
  2. package/.augment-plugin/plugin.json +1 -1
  3. package/.claude-plugin/marketplace.json +1 -1
  4. package/.claude-plugin/skills/install-agent-config/SKILL.md +9 -9
  5. package/CHANGELOG.md +167 -193
  6. package/CREDITS.md +2 -2
  7. package/README.md +1 -1
  8. package/dist/agent-src/skills/code-intelligence/SKILL.md +16 -12
  9. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  10. package/dist/agent-src/templates/scripts/check_memory.ts +1 -1
  11. package/dist/cli/commands/recordTriggerEval.js +1 -1
  12. package/dist/cli/registry.js +2 -2
  13. package/dist/cli-delegate/{chunk-KR5ZIFPO.js → chunk-5AYJGUA3.js} +1 -3
  14. package/dist/cli-delegate/chunk-DIFZBP4G.js +1336 -0
  15. package/dist/cli-delegate/chunk-E7ACTJTJ.js +6792 -0
  16. package/dist/cli-delegate/{chunk-VYZGJLCA.js → chunk-RKNT4LIK.js} +22 -1286
  17. package/dist/cli-delegate/{chunk-BZJ4Y3CI.js → chunk-WY5ZZPGL.js} +2 -2
  18. package/dist/cli-delegate/{chunk-CMZEKSNN.js → chunk-X6LZ7W5A.js} +73 -10
  19. package/dist/cli-delegate/cmd_conformance.js +190 -192
  20. package/dist/cli-delegate/cmd_doctor.js +5 -5
  21. package/dist/cli-delegate/cmd_doctor_neighbours.js +3 -3
  22. package/dist/cli-delegate/cmd_explain.js +1 -1
  23. package/dist/cli-delegate/cmd_export.js +2 -2
  24. package/dist/cli-delegate/cmd_handoff.js +2 -2
  25. package/dist/cli-delegate/cmd_memory_get.js +1 -1
  26. package/dist/cli-delegate/cmd_prune.js +2 -2
  27. package/dist/cli-delegate/cmd_route_audit.js +1 -1
  28. package/dist/cli-delegate/cmd_session_recycle.js +2 -2
  29. package/dist/cli-delegate/cmd_settings_migrate.js +2 -2
  30. package/dist/cli-delegate/cmd_settings_set.js +8 -4
  31. package/dist/cli-delegate/cmd_sync.js +2 -2
  32. package/dist/cli-delegate/cmd_uninstall.js +2 -2
  33. package/dist/cli-delegate/cmd_update.js +24 -13
  34. package/dist/cli-delegate/cmd_upgrade.js +2 -2
  35. package/dist/cli-delegate/cmd_validate.js +2 -2
  36. package/dist/cli-delegate/dist-25AZAHOP.js +3240 -0
  37. package/dist/cli-delegate/dist-P7MFPMF3.js +411 -0
  38. package/dist/cli-delegate/dist-XAS5ZLQB.js +6 -0
  39. package/dist/cli-delegate/{upgrade_unattended-VVL6JLSX.js → upgrade_unattended-QCWOKTUN.js} +178 -163
  40. package/dist/discovery/deprecation-report.md +1 -1
  41. package/dist/discovery/discovery-manifest.json +3 -3
  42. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  43. package/dist/discovery/discovery-manifest.summary.md +1 -1
  44. package/dist/discovery/dormancy-report.md +1 -1
  45. package/dist/discovery/orphan-report.md +1 -1
  46. package/dist/discovery/packs.json +2 -2
  47. package/dist/discovery/trust-report.md +1 -1
  48. package/dist/discovery/workspaces.json +2 -2
  49. package/dist/hooks/code_graph_refresh.chunk.cjs +443 -0
  50. package/dist/hooks/code_graph_refresh.chunk.cjs.sha256 +1 -0
  51. package/dist/hooks/dispatch.js +1001 -938
  52. package/dist/hooks/dispatch.sha256 +1 -1
  53. package/dist/hooks/egress_engine.chunk.cjs +57 -7
  54. package/dist/hooks/egress_engine.chunk.cjs.sha256 +1 -1
  55. package/dist/hooks/update_notice.chunk.cjs +914 -0
  56. package/dist/hooks/update_notice.chunk.cjs.sha256 +1 -0
  57. package/dist/install/install.mjs +6974 -6037
  58. package/dist/mcp/mcp-cloudflare-catalogue.json +1 -0
  59. package/dist/mcp/registry-manifest.json +3 -2
  60. package/dist/mcp/server.json +13 -4
  61. package/dist/mcp/server.mjs +71202 -63282
  62. package/dist/scripts/_lib/egress_rules.js +8 -2
  63. package/dist/scripts/condense.js +18 -15
  64. package/dist/server/routes/discovery.js +1 -1
  65. package/dist/server/routes/install.js +1 -1
  66. package/dist/server/routes/ping.js +1 -1
  67. package/dist/server/routes/schema.js +4 -4
  68. package/dist/server/routes/settings.js +2 -6
  69. package/dist/server/routes/wizard.js +6 -6
  70. package/dist/server/schemas/settings.js +42 -42
  71. package/dist/shared/settingsSurface.js +1 -1
  72. package/dist/shared/userMd/schema.js +1 -1
  73. package/dist/shared/zodJsonSchema.js +47 -0
  74. package/dist/ui/assets/index-B0bcIgi0.js +77 -0
  75. package/dist/ui/index.html +1 -1
  76. package/package.json +6 -3
  77. package/src/agent-src/templates/scripts/check_memory.ts +1 -1
  78. package/src/config/ci-local-parity.yml +11 -0
  79. package/src/config/continuity-surface.json +9 -2
  80. package/src/config/evaluator-budgets.json +9 -8
  81. package/src/config/gate-violation-baselines.json +3 -3
  82. package/src/config/gitignore-block.txt +6 -5
  83. package/src/config/hook-bundle-budget.json +46 -6
  84. package/src/config/pack-size-budget.json +12 -1
  85. package/src/config/packed-binary-manifest.json +18 -0
  86. package/src/config/sigstore/npm_keys.json +50 -0
  87. package/src/config/sigstore/trust-material.json +9 -0
  88. package/src/config/sigstore/trusted_root.json +126 -0
  89. package/src/config/skill-body-budget.json +7 -1
  90. package/src/scripts/_cli/cmd_settings_set.ts +3 -2
  91. package/src/scripts/_cli/cmd_update.ts +48 -20
  92. package/src/scripts/_cli/cmd_upgrade.ts +7 -1
  93. package/src/scripts/_cli/upgrade_unattended.ts +90 -76
  94. package/src/scripts/_dispatch.bash +4 -3
  95. package/src/scripts/_lib/confusables.ts +0 -19
  96. package/src/scripts/_lib/egress_normalize.ts +53 -23
  97. package/src/scripts/_lib/egress_rules.ts +8 -2
  98. package/src/scripts/_lib/egress_text.ts +5 -3
  99. package/src/scripts/_lib/egress_token.ts +7 -5
  100. package/src/scripts/_lib/gate_collector_experimental.ts +633 -0
  101. package/src/scripts/_lib/git_common_dir.ts +10 -0
  102. package/src/scripts/_lib/graph_feeder_record.ts +3 -2
  103. package/src/scripts/_lib/install_reach_checks.ts +32 -2
  104. package/src/scripts/_lib/lineage_backfill.ts +136 -0
  105. package/src/scripts/_lib/lineage_ledger.ts +211 -0
  106. package/src/scripts/_lib/lineage_map.ts +55 -0
  107. package/src/scripts/_lib/lineage_query.ts +140 -0
  108. package/src/scripts/_lib/lineage_seed.ts +116 -0
  109. package/src/scripts/_lib/lineage_watch.ts +249 -0
  110. package/src/scripts/_lib/link_crypto.ts +8 -4
  111. package/src/scripts/_lib/listing_manifests.ts +85 -0
  112. package/src/scripts/_lib/neighbour_census.ts +1 -0
  113. package/src/scripts/_lib/production_reach.ts +3 -3
  114. package/src/scripts/_lib/project_registry.ts +227 -0
  115. package/src/scripts/_lib/provenance_verify.ts +14 -242
  116. package/src/scripts/_lib/release_settings_surface.ts +2 -6
  117. package/src/scripts/_lib/sigstore_provenance.ts +177 -0
  118. package/src/scripts/_lib/source_id.ts +48 -0
  119. package/src/scripts/_lib/source_shape.ts +4 -0
  120. package/src/scripts/_lib/unattended_gates.ts +6 -1
  121. package/src/scripts/adoption_status.ts +231 -27
  122. package/src/scripts/advisories.ts +26 -10
  123. package/src/scripts/ai_council/council_egress.ts +5 -6
  124. package/src/scripts/bench_graph_feeder_latency.ts +10 -3
  125. package/src/scripts/build_mcp_registry_manifest.ts +23 -12
  126. package/src/scripts/check_dependency_floors.ts +14 -0
  127. package/src/scripts/check_egress_mutations.ts +1 -0
  128. package/src/scripts/check_release_manifest_content.ts +17 -2
  129. package/src/scripts/check_release_pr_shape.ts +5 -0
  130. package/src/scripts/code_graph/build.ts +145 -45
  131. package/src/scripts/code_graph/cli.ts +382 -35
  132. package/src/scripts/code_graph/conventions_default.ts +247 -0
  133. package/src/scripts/code_graph/detect.ts +5 -5
  134. package/src/scripts/code_graph/estate_cli.ts +135 -0
  135. package/src/scripts/code_graph/estate_index.ts +394 -0
  136. package/src/scripts/code_graph/estate_manifests.ts +223 -0
  137. package/src/scripts/code_graph/estate_map.ts +141 -0
  138. package/src/scripts/code_graph/extract.ts +8 -2
  139. package/src/scripts/code_graph/extract_more.ts +241 -2
  140. package/src/scripts/code_graph/graph_budget.ts +158 -0
  141. package/src/scripts/code_graph/graph_home.ts +80 -0
  142. package/src/scripts/code_graph/lineage_cli.ts +315 -0
  143. package/src/scripts/code_graph/loader.ts +10 -2
  144. package/src/scripts/code_graph/map.ts +195 -53
  145. package/src/scripts/code_graph/map_model.ts +113 -20
  146. package/src/scripts/code_graph/map_verify.ts +80 -5
  147. package/src/scripts/code_graph/map_viewer/viewer.css +18 -0
  148. package/src/scripts/code_graph/map_viewer/viewer.js +146 -15
  149. package/src/scripts/code_graph/passes.ts +173 -0
  150. package/src/scripts/code_graph/project_ref.ts +25 -0
  151. package/src/scripts/code_graph/projects_cli.ts +254 -0
  152. package/src/scripts/code_graph/providers/angular.ts +55 -0
  153. package/src/scripts/code_graph/providers/aspnetcore.ts +182 -0
  154. package/src/scripts/code_graph/providers/catalog.ts +299 -0
  155. package/src/scripts/code_graph/providers/django.ts +206 -0
  156. package/src/scripts/code_graph/providers/express.ts +25 -0
  157. package/src/scripts/code_graph/providers/fastapi.ts +49 -0
  158. package/src/scripts/code_graph/providers/flask.ts +99 -0
  159. package/src/scripts/code_graph/providers/go_http.ts +121 -0
  160. package/src/scripts/code_graph/providers/index.ts +103 -0
  161. package/src/scripts/code_graph/{laravel_overlay.ts → providers/laravel.ts} +113 -7
  162. package/src/scripts/code_graph/providers/nestjs.ts +34 -0
  163. package/src/scripts/code_graph/providers/nextjs.ts +91 -0
  164. package/src/scripts/code_graph/providers/nuxt.ts +55 -0
  165. package/src/scripts/code_graph/providers/rails.ts +204 -0
  166. package/src/scripts/code_graph/providers/react-router.ts +58 -0
  167. package/src/scripts/code_graph/providers/shared/detect.ts +78 -0
  168. package/src/scripts/code_graph/providers/shared/extractors.ts +249 -0
  169. package/src/scripts/code_graph/providers/shared/js.ts +252 -0
  170. package/src/scripts/code_graph/providers/shared/kit.ts +210 -0
  171. package/src/scripts/code_graph/providers/shared/php.ts +64 -0
  172. package/src/scripts/code_graph/providers/shared/python.ts +223 -0
  173. package/src/scripts/code_graph/providers/spring.ts +175 -0
  174. package/src/scripts/code_graph/providers/sqlalchemy.ts +62 -0
  175. package/src/scripts/code_graph/providers/sveltekit.ts +59 -0
  176. package/src/scripts/code_graph/providers/symfony.ts +142 -0
  177. package/src/scripts/code_graph/providers/typeorm.ts +58 -0
  178. package/src/scripts/code_graph/providers/types.ts +56 -0
  179. package/src/scripts/code_graph/providers/vue-router.ts +21 -0
  180. package/src/scripts/code_graph/providers/wordpress.ts +128 -0
  181. package/src/scripts/code_graph/query.ts +9 -9
  182. package/src/scripts/code_graph/refresh_cli.ts +81 -0
  183. package/src/scripts/code_graph/refresh_lock.ts +197 -0
  184. package/src/scripts/code_graph/repo_identity.ts +169 -0
  185. package/src/scripts/code_graph/resolution_tiers.ts +19 -7
  186. package/src/scripts/code_graph/scip_reader.ts +2 -2
  187. package/src/scripts/code_graph/sqlite_store.ts +31 -28
  188. package/src/scripts/code_graph/types.ts +79 -41
  189. package/src/scripts/code_graph/validate.ts +6 -8
  190. package/src/scripts/condense.ts +15 -15
  191. package/src/scripts/generate_settings_reference.ts +2 -6
  192. package/src/scripts/hook_chunks.mjs +11 -0
  193. package/src/scripts/hook_manifest.json +1 -1
  194. package/src/scripts/hook_manifest.yaml +43 -23
  195. package/src/scripts/hooks/code_graph_refresh_hook.ts +163 -0
  196. package/src/scripts/hooks/dispatch_hook.ts +6 -7
  197. package/src/scripts/hooks/host_semantics.ts +72 -0
  198. package/src/scripts/hooks/lazy_concern.ts +8 -0
  199. package/src/scripts/hooks/user_notice.ts +105 -0
  200. package/src/scripts/install-hooks.sh +54 -33
  201. package/src/scripts/install.ts +2 -6
  202. package/src/scripts/lint_harvest_provenance.ts +137 -11
  203. package/src/scripts/lint_hook_manifest.ts +2 -0
  204. package/src/scripts/lint_marketplace.ts +33 -0
  205. package/src/scripts/lint_mcp_registry_manifest.ts +36 -0
  206. package/src/scripts/mcp_server/consumer_tool_catalog.json +70 -15
  207. package/src/scripts/mcp_server/graph_tools.ts +165 -41
  208. package/src/scripts/network_sources.ts +24 -6
  209. package/src/scripts/release.ts +2 -5
  210. package/src/scripts/release_drill.ts +4 -1
  211. package/src/scripts/release_env.ts +17 -0
  212. package/src/scripts/release_mix_taxonomy.json +3 -0
  213. package/src/scripts/schemas/provenance-mechanism.schema.json +46 -0
  214. package/src/scripts/update_notice_hook.ts +75 -7
  215. package/src/server/schemas/settings.ts +42 -42
  216. package/src/shared/settingsSurface.ts +1 -1
  217. package/src/shared/userMd/schema.ts +1 -1
  218. package/src/shared/zodJsonSchema.ts +41 -0
  219. package/src/vendor/grammars/README.md +8 -6
  220. package/src/vendor/grammars/tree-sitter-c_sharp.wasm +0 -0
  221. package/src/vendor/grammars/tree-sitter-ruby.wasm +0 -0
  222. package/dist/cli-delegate/chunk-XIAPY44N.js +0 -4587
  223. package/dist/ui/assets/index-w70Ado09.js +0 -23
  224. /package/dist/cli-delegate/{chunk-FKYZOWVD.js → chunk-QBAFP67O.js} +0 -0
  225. /package/dist/cli-delegate/{chunk-BMGUGSY6.js → chunk-TQG6UMPC.js} +0 -0
@@ -2150,19 +2150,19 @@ export const PLUGIN_POINTER_SLUG = 'install-agent-config';
2150
2150
  export const PLUGIN_POINTER_SKILL_BODY = `---
2151
2151
  name: install-agent-config
2152
2152
  description: >-
2153
- Install or upgrade the event4u agent-config suite. This marketplace plugin
2154
- is a bootstrap shim — it ships hooks plus this pointer only; ALL skills,
2155
- rules, and commands are installed via \`npx -y @event4u/agent-config init\`.
2156
- Use when the user asks to install, set up, or upgrade agent-config, or
2153
+ Governance rules, skills and commands for AI coding agents in Claude Code, Cursor, GitHub Copilot and Gemini CLI —
2154
+ install or upgrade the full event4u agent-config suite. No plugin that ships this pointer is the full suite (the Claude
2155
+ Code one adds hooks, the Copilot one a read-only MCP server); ALL content installs via \`npx -y @event4u/agent-config init\`.
2156
+ Use when the user asks to install, set up, or upgrade agent-config, wants coding-agent rules or skills, or
2157
2157
  wonders why this plugin contains no other skills.
2158
2158
  ---
2159
2159
 
2160
2160
  # Install agent-config
2161
2161
 
2162
- This plugin is a **bootstrap shim** kept so the marketplace listing stays
2163
- discoverable. Its hooks run only alongside a global npm install of the package (never a project-local one) —
2164
- on a plugin-only install no hook runs, so the \`fail_closed\` guards (\`block-no-verify\`, \`block-kernel-rule-writes\`,
2165
- \`block-plumbing-writes\`) are **off**; the session start says so once. Content ships as a file projection.
2162
+ The plugin that delivered this skill is a **discovery entry**, not the suite. The Claude Code plugin adds hooks that
2163
+ run only alongside a global npm install of the package (never a project-local one) — on a plugin-only install no hook
2164
+ runs, so the \`fail_closed\` guards (\`block-no-verify\`, \`block-kernel-rule-writes\`, \`block-plumbing-writes\`) are
2165
+ **off**; the session start says so once. The Copilot plugin adds a read-only MCP server and no hooks.
2166
2166
 
2167
2167
  ## Install (canonical, one command)
2168
2168
 
@@ -2172,7 +2172,7 @@ npx -y @event4u/agent-config init
2172
2172
 
2173
2173
  The installer writes the full content projection, registers the dispatcher
2174
2174
  hooks as a managed block in \`~/.claude/settings.json\` (byte-identical to
2175
- this plugin's hooks, so nothing double-fires), and keeps everything
2175
+ the Claude Code plugin's hooks, so nothing double-fires), and keeps everything
2176
2176
  upgradeable via \`agent-config upgrade\`.
2177
2177
 
2178
2178
  ## Already installed both?
@@ -2191,11 +2191,11 @@ export function generate_plugin_command_skills(): number {
2191
2191
  const pointer_dir = path.join(MODULE_STATE.PLUGIN_SKILLS_DIR, PLUGIN_POINTER_SLUG);
2192
2192
  _mkdirp(pointer_dir);
2193
2193
  const pointer_file = path.join(pointer_dir, 'SKILL.md');
2194
- if (_isSymlink(pointer_file)) {
2195
- fs.unlinkSync(pointer_file);
2196
- }
2197
- if (!_isFile(pointer_file) || fs.readFileSync(pointer_file, 'utf-8') !== PLUGIN_POINTER_SKILL_BODY) {
2198
- fs.writeFileSync(pointer_file, PLUGIN_POINTER_SKILL_BODY);
2194
+ for (const file of [pointer_file, path.join(MODULE_STATE.PROJECT_ROOT, '.github', 'plugin', 'skills', PLUGIN_POINTER_SLUG, 'SKILL.md')]) {
2195
+ if (_isSymlink(file)) {
2196
+ fs.unlinkSync(file);
2197
+ }
2198
+ if (!_isFile(file) || fs.readFileSync(file, 'utf-8') !== PLUGIN_POINTER_SKILL_BODY) { fs.mkdirSync(path.dirname(file), { recursive: true }); fs.writeFileSync(file, PLUGIN_POINTER_SKILL_BODY); }
2199
2199
  }
2200
2200
 
2201
2201
  // 2. Prune every other skill dir so the tree converges to shim shape
@@ -2226,7 +2226,7 @@ export function generate_plugin_command_skills(): number {
2226
2226
  }
2227
2227
  }
2228
2228
 
2229
- let msg = ' ✅ Plugin skills: bootstrap shim (1 pointer skill) in .claude-plugin/skills/';
2229
+ let msg = ' ✅ Plugin skills: bootstrap shim (1 pointer skill) in .claude-plugin/skills/ and .github/plugin/skills/';
2230
2230
  if (removed_dirs) {
2231
2231
  msg += ` (${removed_dirs} content entries pruned)`;
2232
2232
  }
@@ -33,7 +33,7 @@ import * as fs from 'node:fs';
33
33
  import * as path from 'node:path';
34
34
  import { fileURLToPath, pathToFileURL } from 'node:url';
35
35
 
36
- import { zodToJsonSchema } from 'zod-to-json-schema';
36
+ import { toJsonSchema7 } from '../shared/zodJsonSchema.js';
37
37
 
38
38
  import { settingsSchema } from '../server/schemas/settings.js';
39
39
  import {
@@ -97,11 +97,7 @@ export function renderProse(value: string | undefined): string {
97
97
  }
98
98
 
99
99
  export function buildRows(contractMarkdown: string): ReferenceRow[] {
100
- const jsonSchema = zodToJsonSchema(settingsSchema, {
101
- name: 'AgentSettings',
102
- $refStrategy: 'none',
103
- target: 'jsonSchema7',
104
- }) as Parameters<typeof flattenSurface>[0];
100
+ const jsonSchema = toJsonSchema7(settingsSchema, 'AgentSettings') as Parameters<typeof flattenSurface>[0];
105
101
  // The version is a required parameter of the shared flattener and is
106
102
  // discarded here on purpose — see the module header.
107
103
  const surface = flattenSurface(jsonSchema, 'unversioned');
@@ -45,6 +45,17 @@ export const HOOK_CHUNKS = Object.freeze([
45
45
  entry: 'src/scripts/hooks/instructions_observer_hook.ts',
46
46
  outfile: 'dist/hooks/instructions_observer.chunk.cjs',
47
47
  }),
48
+ Object.freeze({
49
+ entry: 'src/scripts/hooks/code_graph_refresh_hook.ts',
50
+ outfile: 'dist/hooks/code_graph_refresh.chunk.cjs',
51
+ }),
52
+ // `yaml` external for the reason given at `chat_history`: the concern
53
+ // reads one user-global settings file with it.
54
+ Object.freeze({
55
+ entry: 'src/scripts/update_notice_hook.ts',
56
+ outfile: 'dist/hooks/update_notice.chunk.cjs',
57
+ external: Object.freeze(['yaml']),
58
+ }),
48
59
  ]);
49
60
 
50
61
  /**
@@ -1 +1 @@
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"}}}}
1
+ {"fingerprint":"a1ea34a86eaabc4536ff7758681c8a89249dec6925148e96721b677b4d9de34b:111522","body_fingerprint":"6729962557eee79c6c7cda21ee5d245da8d52a4c22fbce12bdba960996db322e:21553","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"},"update-notice":{"script":"src/scripts/update_notice_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"},"code-graph-refresh":{"script":"src/scripts/hooks/code_graph_refresh_hook.ts","args":[],"fail_closed":false,"severity":"advisory","effect":"execution"},"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","code-graph-refresh"],"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","update-notice","surface-probe","session-register","review-baseline","journal-record","rule-inject","code-graph-refresh"],"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","code-graph-refresh"],"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","code-graph-refresh"],"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","code-graph-refresh"],"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","code-graph-refresh"],"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","code-graph-refresh"],"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"}}}}
@@ -630,22 +630,25 @@ concerns:
630
630
  fail_closed: false
631
631
  severity: advisory
632
632
  effect: notification
633
- # `update-notice` and `update-auto-invite` were registered here on
634
- # 2026-10-20 and REMOVED the same day on a council verdict: both seats
635
- # refused the change 2/2, convergent, no split
636
- # (agents/evidence/council/lazy-concern-authority-expansion-20261020.md).
637
- # The finding is not about the concerns' quality. `fail_closed: false` and
638
- # `severity: advisory` describe failure and classification, not side
639
- # effects, and `effect: notification` means the concern tells a human
640
- # something and changes nothing else — so a session_start concern that may
641
- # initiate `upgrade --unattended`, and a stop concern that may open a
642
- # question with the user, are each an expansion of what lifecycle hooks are
643
- # permitted to DECIDE. That the invoked command keeps all its own gates is
644
- # true and beside the point: the gates constrain HOW an install happens,
645
- # never WHO may start one. The ring-0 record is a rollout switch, not
646
- # consent, so it postpones the expansion rather than bounding it.
647
- # They return in their own change, declared as authority expansions and
648
- # ratified on their own merits.
633
+ # Tells the user, at session start, that their global install is behind or
634
+ # has just moved. It installs nothing and starts nothing: a 2026-10-20
635
+ # council refused it 2/2 while it could spawn `upgrade --unattended`
636
+ # (agents/evidence/council/lazy-concern-authority-expansion-20261020.md),
637
+ # and that capability was removed rather than the effect widened (D13).
638
+ # Its writes are its own bookkeeping — a day stamp and the last version it
639
+ # reported, user-global, read by no other module (a CI assertion).
640
+ # Bound on `claude` alone: its text goes out through the user channel
641
+ # (`hooks/user_notice.ts`, `systemMessage`), which is UI-only, and claude is
642
+ # the one host with a verified field of that kind. Every other host keeps
643
+ # the CLI banner. Day-throttled, file reads only, loaded from its own chunk.
644
+ # Kill switches: `AGENT_CONFIG_NO_UPDATE_CHECK=1`, `update.mode: off`.
645
+ # `update-auto-invite` (step 4.3) is not registered.
646
+ update-notice:
647
+ script: src/scripts/update_notice_hook.ts
648
+ args: []
649
+ fail_closed: false
650
+ severity: advisory
651
+ effect: notification
649
652
  # road-to-install-path-convergence Phase 4 — duplicate-surface probe.
650
653
  # Reads src/config/surface-matrix.yml, existence-checks declared duplicate
651
654
  # classes, nudges ONCE per day (state: agents/runtime/state/
@@ -1377,6 +1380,23 @@ concerns:
1377
1380
  fail_closed: false
1378
1381
  severity: advisory
1379
1382
  effect: telemetry
1383
+ # Consumer-side code-graph freshness. The git-hook refresh in install-hooks.sh
1384
+ # reaches this package's own checkout only; a consumer project's graph and
1385
+ # agents/map/ never refreshed. On session_start this spawns a detached
1386
+ # `agent-config code-graph refresh --single-flight --map` and returns — only
1387
+ # for a project that ran `code-graph auto-refresh on`, whose opt-in marker
1388
+ # and cache git does not track, with an `agent-config` on PATH that resolves
1389
+ # outside the repository. session_start alone: `stop` is per turn and
1390
+ # `session_end` refreshes for a session that is gone (council, 2026-10-23,
1391
+ # two of two seats). Silent, exit 0, POSIX only, no hook-token-budget row —
1392
+ # it emits nothing. Loaded from its own chunk.
1393
+ # Kill switch: `AGENT_CONFIG_CODE_GRAPH_REFRESH=off`.
1394
+ code-graph-refresh:
1395
+ script: src/scripts/hooks/code_graph_refresh_hook.ts
1396
+ args: []
1397
+ fail_closed: false
1398
+ severity: advisory
1399
+ effect: execution
1380
1400
  subagent-ledger:
1381
1401
  script: src/scripts/hooks/subagent_ledger_hook.ts
1382
1402
  args: []
@@ -1591,7 +1611,7 @@ platforms:
1591
1611
  # assumption a contract makes on every host's behalf.
1592
1612
  augment:
1593
1613
  ask: text
1594
- 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]
1614
+ 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, code-graph-refresh]
1595
1615
  session_end: [chat-history, memory-learn, session-register, roadmap-progress, telemetry-flush]
1596
1616
  stop: [chat-history, verify-before-complete, self-repair, session-register, roadmap-progress, design-pass-stop]
1597
1617
  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]
@@ -1599,7 +1619,7 @@ platforms:
1599
1619
 
1600
1620
  claude:
1601
1621
  ask: native
1602
- 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]
1622
+ 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, update-notice, surface-probe, session-register, review-baseline, journal-record, rule-inject, code-graph-refresh]
1603
1623
  # `rule-inject` is bound here for ONE source: `compact`
1604
1624
  # (road-to-a-rule-carrier-that-works-outside-the-repo step 1.6). The concern
1605
1625
  # returns before reading anything on `startup`, `resume`, `clear` and
@@ -1674,7 +1694,7 @@ platforms:
1674
1694
  # agents/settings/contexts/chat-history-platform-hooks.md § Cowork.
1675
1695
  cowork:
1676
1696
  ask: text
1677
- 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]
1697
+ 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, code-graph-refresh]
1678
1698
  session_end: [chat-history, memory-learn, session-register, roadmap-progress, telemetry-flush]
1679
1699
  # end-review-nudge and delegation-nudge are DELIBERATELY NOT bound on
1680
1700
  # this platform (F10, review) — cowork-dispatcher.sh's own header states
@@ -1710,7 +1730,7 @@ platforms:
1710
1730
  # agents/settings/contexts/chat-history-platform-hooks.md § Cursor.
1711
1731
  cursor:
1712
1732
  ask: text
1713
- 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]
1733
+ 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, code-graph-refresh]
1714
1734
  session_end: [chat-history, memory-learn, session-register, roadmap-progress, telemetry-flush]
1715
1735
  stop: [chat-history, verify-before-complete, self-repair, session-register, roadmap-progress, design-pass-stop]
1716
1736
  user_prompt_submit: [chat-history, verify-before-complete, minimal-safe-diff, language-mirror, git-authorization, session-canary, self-repair, session-register]
@@ -1726,7 +1746,7 @@ platforms:
1726
1746
  # session is interrupted with partial state (mirrors Augment Stop).
1727
1747
  cline:
1728
1748
  ask: text
1729
- 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]
1749
+ 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, code-graph-refresh]
1730
1750
  session_end: [chat-history, memory-learn, session-register, roadmap-progress, telemetry-flush]
1731
1751
  stop: [chat-history, verify-before-complete, self-repair, session-register, roadmap-progress, design-pass-stop]
1732
1752
  user_prompt_submit: [chat-history, verify-before-complete, minimal-safe-diff, language-mirror, git-authorization, session-canary, self-repair, session-register]
@@ -1746,7 +1766,7 @@ platforms:
1746
1766
  # minimal-safe-diff is omitted entirely on Windsurf for the same reason.
1747
1767
  windsurf:
1748
1768
  ask: text
1749
- 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]
1769
+ 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, code-graph-refresh]
1750
1770
  stop: [chat-history, verify-before-complete, self-repair, session-register, design-pass-stop]
1751
1771
  # language-mirror IS bound here: unlike minimal-safe-diff it needs only the
1752
1772
  # user_prompt_submit slot, which Windsurf has.
@@ -1764,7 +1784,7 @@ platforms:
1764
1784
  # — this is our `stop` slot.
1765
1785
  gemini:
1766
1786
  ask: text
1767
- 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]
1787
+ 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, code-graph-refresh]
1768
1788
  session_end: [chat-history, memory-learn, session-register, roadmap-progress, telemetry-flush]
1769
1789
  stop: [chat-history, verify-before-complete, self-repair, session-register, roadmap-progress, design-pass-stop]
1770
1790
  user_prompt_submit: [chat-history, verify-before-complete, minimal-safe-diff, language-mirror, git-authorization, session-canary, self-repair, session-register]
@@ -0,0 +1,163 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * Session-start code-graph refresh — the consumer-side freshness carrier.
4
+ *
5
+ * WHY THIS EXISTS. The git-hook refresh block lives in `install-hooks.sh`,
6
+ * which only this package's own `prepare` script runs. A consumer project gets
7
+ * no git hook, so its graph and `agents/map/` stayed at whatever commit the
8
+ * developer last built them on, and `code-graph-context` could only report
9
+ * `behind:N`. This concern closes that at the one moment every agent session
10
+ * shares: its start. It does not write into the consumer's `.git/hooks` — that
11
+ * would collide with husky, lefthook and `core.hooksPath` (council, 2026-10-23,
12
+ * two of two seats).
13
+ *
14
+ * WHAT IT DOES. It spawns a detached
15
+ * `agent-config code-graph refresh --single-flight --map` and returns. The
16
+ * child rebuilds only when the cache is not fresh, discards a result built
17
+ * while HEAD moved, and redraws the map only for a project that has one.
18
+ * Freshness is eventual: the session's first graph read may still see the old
19
+ * cache, and `code-graph-context` keeps saying so.
20
+ *
21
+ * WHEN IT DOES NOTHING — the conditions a ratification round of 2026-10-23
22
+ * (two of two seats, refused the first cut) made load-bearing:
23
+ * · the project never ran `code-graph auto-refresh on`. An existing cache is
24
+ * not consent: a repository can commit one.
25
+ * · the opt-in marker or the cache is TRACKED by git. Both live under the
26
+ * gitignored runtime dir; a tracked copy came from the repository, not
27
+ * from this developer.
28
+ * · no `agent-config` on PATH that resolves OUTSIDE the repository, or one
29
+ * too old to know `refresh --single-flight` (`refresh_cli.ts`).
30
+ * · a live refresh holds the lock, the host is Windows (the CLI shim is a
31
+ * `.cmd` that needs a shell), replay mode, or the kill switch
32
+ * `AGENT_CONFIG_CODE_GRAPH_REFRESH=off`.
33
+ *
34
+ * Silent and exit 0 on every path — but never invisible: every outcome from the
35
+ * opt-in check onward is recorded in `code-graph-refresh.last.json`, which
36
+ * `code-graph auto-refresh status` prints.
37
+ */
38
+ import { execFileSync, spawn } from 'node:child_process';
39
+ import * as fs from 'node:fs';
40
+ import * as path from 'node:path';
41
+ import { fileURLToPath, pathToFileURL } from 'node:url';
42
+
43
+ import { hardenedSpawnEnv } from '../_lib/spawn_env.js';
44
+ import { usableCli } from '../code_graph/refresh_cli.js';
45
+ import { hasProjectHome, projectHome } from '../code_graph/graph_home.js';
46
+ import { isStale, recordRefreshIn } from '../code_graph/refresh_lock.js';
47
+ import { EXIT_ALLOW } from './exit_codes.js';
48
+ import { readHookStdin } from './hook_stdin.js';
49
+ import { is_replay_mode } from './state_io.js';
50
+
51
+ export const REFRESH_ARGS = ['code-graph', 'refresh', '--single-flight', '--map', '--budget-seconds', '60'];
52
+
53
+ export type RefreshOutcome =
54
+ | 'disabled'
55
+ | 'unsupported'
56
+ | 'replay'
57
+ | 'not-opted-in'
58
+ | 'no-cache'
59
+ | 'tracked'
60
+ | 'locked'
61
+ | 'no-cli'
62
+ | 'cli-too-old'
63
+ | 'spawned';
64
+
65
+ export { resolveCli } from '../code_graph/refresh_cli.js';
66
+
67
+ /**
68
+ * The nearest ancestor of `start`'s realpath holding `.git` (a dir, or a
69
+ * worktree's file). Only ENOENT walks upward: a `.git` that cannot be
70
+ * inspected ends the search, so an unreadable inner repository is never
71
+ * skipped in favour of an outer one.
72
+ */
73
+ export function repoRoot(start: string): string | null {
74
+ let dir: string;
75
+ try {
76
+ dir = fs.realpathSync(start);
77
+ } catch {
78
+ return null;
79
+ }
80
+ for (;;) {
81
+ try {
82
+ fs.lstatSync(path.join(dir, '.git'));
83
+ return dir;
84
+ } catch (e) {
85
+ if ((e as NodeJS.ErrnoException).code !== 'ENOENT') return null;
86
+ }
87
+ const up = path.dirname(dir);
88
+ if (up === dir) return null;
89
+ dir = up;
90
+ }
91
+ }
92
+
93
+ /** True when git tracks any of `rels` under `root` (or git cannot answer). */
94
+ function anyTracked(root: string, rels: readonly string[]): boolean {
95
+ try {
96
+ const out = execFileSync('git', ['-C', root, 'ls-files', '--', ...rels], {
97
+ encoding: 'utf-8',
98
+ stdio: ['ignore', 'pipe', 'ignore'],
99
+ env: hardenedSpawnEnv(),
100
+ });
101
+ return out.trim() !== '';
102
+ } catch {
103
+ return true;
104
+ }
105
+ }
106
+
107
+ export function refreshFor(cwd: string, spawnFn: typeof spawn = spawn): RefreshOutcome {
108
+ if (process.env['AGENT_CONFIG_CODE_GRAPH_REFRESH'] === 'off') return 'disabled';
109
+ if (process.platform === 'win32') return 'unsupported';
110
+ if (is_replay_mode()) return 'replay';
111
+ const root = repoRoot(cwd);
112
+ // `auto-refresh on` refuses a root without a project home (ADR-299).
113
+ if (root === null || !hasProjectHome(root)) return 'not-opted-in';
114
+ const home = projectHome(root);
115
+ if (!fs.existsSync(home.autoRefreshPath)) return 'not-opted-in';
116
+ // A repository-committed opt-in is refused before anything is written into the tree.
117
+ if (anyTracked(root, [home.autoRefreshPath, home.cachePath].map((p) => path.relative(root, p)))) return 'tracked';
118
+ const done = (outcome: RefreshOutcome, detail?: string): RefreshOutcome => {
119
+ recordRefreshIn(home.stateDir, { by: 'session-start', outcome, detail });
120
+ return outcome;
121
+ };
122
+ if (!fs.existsSync(home.cachePath)) return done('no-cache');
123
+ const lock = home.lockPath;
124
+ if (fs.existsSync(lock) && !isStale(lock)) return done('locked');
125
+ const verdict = usableCli(root);
126
+ if ('reason' in verdict) return done(verdict.reason, (verdict as { cli?: string }).cli);
127
+ const child = spawnFn(verdict.cli, [...REFRESH_ARGS, '--root', root], {
128
+ cwd: root,
129
+ detached: true,
130
+ stdio: 'ignore',
131
+ env: hardenedSpawnEnv(),
132
+ });
133
+ child.on('error', () => {});
134
+ child.unref();
135
+ return done('spawned', verdict.cli);
136
+ }
137
+
138
+ export function main(): number {
139
+ try {
140
+ const raw = readHookStdin();
141
+ const envelope = raw.trim() ? (JSON.parse(raw) as Record<string, unknown>) : {};
142
+ const cwd = typeof envelope['cwd'] === 'string' && envelope['cwd'] ? envelope['cwd'] : process.cwd();
143
+ refreshFor(cwd);
144
+ } catch {
145
+ /* a freshness side job never breaks a session start */
146
+ }
147
+ return EXIT_ALLOW;
148
+ }
149
+
150
+ // Bundle-safety: never auto-run when inlined into an esbuild bundle, where
151
+ // every module shares the bundle's `import.meta.url` (see cmd_migrate.ts).
152
+ declare const __AGENT_CONFIG_BUNDLE__: boolean | undefined;
153
+ function isCliEntry(): boolean {
154
+ if (typeof __AGENT_CONFIG_BUNDLE__ !== 'undefined' && __AGENT_CONFIG_BUNDLE__) return false;
155
+ if (process.argv[1] === undefined) return false;
156
+ if (import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href) return true;
157
+ try {
158
+ return fs.realpathSync(fileURLToPath(import.meta.url)) === fs.realpathSync(path.resolve(process.argv[1]));
159
+ } catch {
160
+ return false;
161
+ }
162
+ }
163
+ if (isCliEntry()) process.exit(main());
@@ -52,7 +52,8 @@ import {
52
52
  setHookStdinOverride,
53
53
  clearHookStdinOverride,
54
54
  } from "./hook_stdin.js";
55
- import { emitFor, type PermissionDecision, type Severity } from "./host_semantics.js";
55
+ import { emitFor, writeStdout, type PermissionDecision, type Severity } from "./host_semantics.js";
56
+ import { collectUserNotice, type NoticeBatch } from "./user_notice.js";
56
57
  import { _concern_permission_verdict, _payload_tool_name, _permission_for } from "./permission_gate.js";
57
58
  export { _concern_permission_verdict, _payload_tool_input, _payload_tool_name, _permission_for, _working_tree_root } from "./permission_gate.js";
58
59
  import { _concern_body_classes, applyPayloadFields, planPayloadShapes } from "./payload_stub.js";
@@ -1264,6 +1265,7 @@ export function main(argv?: string[]): number {
1264
1265
  // stdout-injection; harmless surfacing elsewhere). All other events keep
1265
1266
  // the swallow-stdout contract unchanged.
1266
1267
  const context_blocks: string[] = [];
1268
+ const notices: NoticeBatch = []; // `hooks/user_notice.ts`, never model context
1267
1269
  // Per-concern message for the host emission (P0.1). Kept OUT of
1268
1270
  // feedback_entries on purpose: that record is written to disk with a
1269
1271
  // fixed-field schema (PII-exclusion-by-construction), and a concern's raw
@@ -1376,6 +1378,7 @@ export function main(argv?: string[]): number {
1376
1378
  ) {
1377
1379
  context_blocks.push(injected((reply["context"] as string).trim()));
1378
1380
  }
1381
+ collectUserNotice(notices, concern, reply, injected);
1379
1382
  feedback_entries.push({
1380
1383
  concern: String(concern["name"]),
1381
1384
  exit_code: rc,
@@ -1402,9 +1405,6 @@ export function main(argv?: string[]): number {
1402
1405
  writeConcernTimings(String(envelope["event"] ?? ""), String(envelope["platform"] ?? ""), timing_samples);
1403
1406
  _write_feedback(envelope, session_id, feedback_entries, final_rc, started_at);
1404
1407
  _record_rule_trips(envelope, feedback_entries);
1405
- if (context_blocks.length > 0 && final_rc === EXIT_ALLOW) {
1406
- process.stdout.write(context_blocks.join("\n\n") + "\n");
1407
- }
1408
1408
 
1409
1409
  // P0.1 host-semantics translation. The internal ladder (0/1/2) is written to
1410
1410
  // the feedback dir verbatim above — that record is unchanged. What leaves the
@@ -1427,9 +1427,8 @@ export function main(argv?: string[]): number {
1427
1427
  final_rc,
1428
1428
  _permission_for(args.event, envelope, final_rc, permission_verdicts),
1429
1429
  );
1430
- if (emission.stdout) {
1431
- process.stdout.write(emission.stdout);
1432
- }
1430
+ const context_out = context_blocks.length > 0 && final_rc === EXIT_ALLOW ? context_blocks.join("\n\n") + "\n" : "";
1431
+ writeStdout(args.platform, args.event, context_out, emission, notices, session_id, (s) => process.stdout.write(s));
1433
1432
  if (emission.stderr) {
1434
1433
  process.stderr.write(emission.stderr);
1435
1434
  }