@event4u/agent-config 14.12.0 → 14.14.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 (521) 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/CHANGELOG.md +118 -155
  5. package/CONTRIBUTING.md +38 -0
  6. package/CREDITS.md +135 -0
  7. package/NOTICE +13 -0
  8. package/README.md +8 -6
  9. package/dist/agent-src/commands/analyze/inbox.md +145 -2
  10. package/dist/agent-src/commands/feature/dev.md +7 -2
  11. package/dist/agent-src/commands/ghostwriter/write.md +5 -1
  12. package/dist/agent-src/commands/implement-ticket.md +1 -1
  13. package/dist/agent-src/commands/mission/upgrade.md +1 -1
  14. package/dist/agent-src/commands/orchestrate.md +2 -2
  15. package/dist/agent-src/commands/post-as/me.md +5 -1
  16. package/dist/agent-src/commands/pr/merge.md +19 -6
  17. package/dist/agent-src/commands/roadmap/process-full.md +19 -5
  18. package/dist/agent-src/commands/tdd/red.md +12 -2
  19. package/dist/agent-src/commands/work.md +1 -1
  20. package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +40 -0
  21. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +5 -2
  22. package/dist/agent-src/contexts/execution/autonomy-mechanics.md +21 -0
  23. package/dist/agent-src/contexts/execution/orchestration-telemetry.md +1 -0
  24. package/dist/agent-src/contexts/execution/subagent-response-contract.md +40 -0
  25. package/dist/agent-src/contexts/execution/subagent-steering.md +13 -1
  26. package/dist/agent-src/contexts/execution/terminal-states.md +96 -0
  27. package/dist/agent-src/rules/artifact-drafting-protocol.md +1 -1
  28. package/dist/agent-src/rules/broken-access-control.md +4 -0
  29. package/dist/agent-src/rules/code-comment-discipline.md +6 -0
  30. package/dist/agent-src/rules/code-provenance.md +4 -0
  31. package/dist/agent-src/rules/design-fidelity.md +1 -1
  32. package/dist/agent-src/rules/domain-safety-pii.md +4 -0
  33. package/dist/agent-src/rules/domain-safety-retention.md +4 -0
  34. package/dist/agent-src/rules/engineering-safety-floor.md +2 -0
  35. package/dist/agent-src/rules/external-code-graph-interop.md +14 -12
  36. package/dist/agent-src/rules/improve-before-implement.md +6 -8
  37. package/dist/agent-src/rules/laravel-routing.md +1 -1
  38. package/dist/agent-src/rules/lethal-trifecta-guard.md +4 -0
  39. package/dist/agent-src/rules/secret-vcs-guard.md +2 -0
  40. package/dist/agent-src/rules/security-sensitive-stop.md +2 -0
  41. package/dist/agent-src/rules/source-confidentiality.md +12 -34
  42. package/dist/agent-src/rules/symfony-routing.md +1 -1
  43. package/dist/agent-src/rules/token-efficiency.md +14 -0
  44. package/dist/agent-src/rules/tool-safety.md +4 -0
  45. package/dist/agent-src/rules/untrusted-input-defense.md +4 -0
  46. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +252 -8
  47. package/dist/agent-src/scripts/guarded_baseline.ts +343 -0
  48. package/dist/agent-src/scripts/roadmap_set_step.ts +253 -0
  49. package/dist/agent-src/scripts/stub_queue.ts +82 -0
  50. package/dist/agent-src/scripts/stubs_due.ts +516 -0
  51. package/dist/agent-src/scripts/ticket_bundles.ts +84 -0
  52. package/dist/agent-src/scripts/update_roadmap_progress.ts +16 -12
  53. package/dist/agent-src/skills/brand-asset-generation/SKILL.md +17 -4
  54. package/dist/agent-src/skills/brand-audit/SKILL.md +33 -0
  55. package/dist/agent-src/skills/code-intelligence/SKILL.md +57 -0
  56. package/dist/agent-src/skills/database/SKILL.md +8 -0
  57. package/dist/agent-src/skills/dependency-upgrade/SKILL.md +27 -0
  58. package/dist/agent-src/skills/design-review/SKILL.md +1 -1
  59. package/dist/agent-src/skills/doc-coauthoring/SKILL.md +1 -1
  60. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +17 -1
  61. package/dist/agent-src/skills/feature-planning/SKILL.md +9 -2
  62. package/dist/agent-src/skills/frontend-render-security/SKILL.md +44 -0
  63. package/dist/agent-src/skills/git-workflow/SKILL.md +1 -1
  64. package/dist/agent-src/skills/js-library-packaging/scripts/check_package_surface.ts +38 -4
  65. package/dist/agent-src/skills/judge-artifact-completeness/rubrics/ticket-quality-score.json +2 -2
  66. package/dist/agent-src/skills/laravel/SKILL.md +35 -0
  67. package/dist/agent-src/skills/laravel-migration/SKILL.md +57 -3
  68. package/dist/agent-src/skills/monorepo-workspace/SKILL.md +26 -0
  69. package/dist/agent-src/skills/playbook-authoring/SKILL.md +28 -1
  70. package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +1 -1
  71. package/dist/agent-src/skills/skill-writing/references/procedure.md +5 -5
  72. package/dist/agent-src/skills/sql-writing/SKILL.md +7 -1
  73. package/dist/agent-src/skills/standards-from-config/SKILL.md +27 -4
  74. package/dist/agent-src/skills/supply-chain-intake/SKILL.md +11 -4
  75. package/dist/agent-src/skills/symfony-workflow/SKILL.md +35 -0
  76. package/dist/agent-src/skills/test-case-discovery/SKILL.md +85 -0
  77. package/dist/agent-src/skills/test-driven-development/SKILL.md +33 -9
  78. package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
  79. package/dist/agent-src/skills/testing-anti-patterns/process-anti-patterns.md +37 -0
  80. package/dist/agent-src/skills/ui-component-architect/SKILL.md +45 -2
  81. package/dist/agent-src/skills/upstream-contribute/SKILL.md +38 -1
  82. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +9 -4
  83. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  84. package/dist/agent-src/templates/roadmaps.md +97 -3
  85. package/dist/agent-src/templates/scripts/check_memory.ts +258 -17
  86. package/dist/agent-src/templates/scripts/check_memory_proposal.ts +9 -3
  87. package/dist/agent-src/templates/scripts/memory_lookup.ts +86 -0
  88. package/dist/agent-src/templates/scripts/memory_signal.ts +44 -0
  89. package/dist/agent-src/templates/scripts/work_engine/directives/backend/implement.ts +90 -0
  90. package/dist/agent-src/templates/scripts/work_engine/directives/backend/index.ts +11 -0
  91. package/dist/agent-src/templates/scripts/work_engine/directives/backend/test.ts +23 -1
  92. package/dist/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +10 -1
  93. package/dist/agent-src/templates/scripts/work_engine/directives/mixed/stitch.ts +5 -1
  94. package/dist/agent-src/templates/scripts/work_engine/stack/runner.ts +102 -14
  95. package/dist/cli/commands/uiAudit.js +124 -5
  96. package/dist/cli/registry.js +2 -0
  97. package/dist/cli-delegate/{chunk-HYWSRNUX.js → chunk-2DK2VJWG.js} +3 -3
  98. package/dist/cli-delegate/{chunk-JCW7ZLHK.js → chunk-4FS4WRXP.js} +5 -0
  99. package/dist/cli-delegate/{chunk-OMIVVCG2.js → chunk-A4QJ6ENT.js} +24 -0
  100. package/dist/cli-delegate/{chunk-JJA2QEWA.js → chunk-AKJGUQNO.js} +466 -285
  101. package/dist/cli-delegate/{chunk-E46KPN6K.js → chunk-BTWUYDGN.js} +424 -363
  102. package/dist/cli-delegate/{chunk-K4FFODTS.js → chunk-ILMUPLGW.js} +1227 -316
  103. package/dist/cli-delegate/{chunk-FF7WAFMR.js → chunk-KPBWFOPZ.js} +5 -1
  104. package/dist/cli-delegate/cmd_adr_effective.js +102 -0
  105. package/dist/cli-delegate/cmd_conformance.js +80 -11
  106. package/dist/cli-delegate/cmd_doctor.js +3 -3
  107. package/dist/cli-delegate/cmd_export.js +3 -2
  108. package/dist/cli-delegate/cmd_fleet.js +2 -2
  109. package/dist/cli-delegate/cmd_handoff.js +1 -1
  110. package/dist/cli-delegate/cmd_preflight.js +2 -2
  111. package/dist/cli-delegate/cmd_prune.js +3 -2
  112. package/dist/cli-delegate/cmd_settings_get.js +1 -1
  113. package/dist/cli-delegate/cmd_settings_migrate.js +3 -2
  114. package/dist/cli-delegate/cmd_settings_set.js +2 -2
  115. package/dist/cli-delegate/cmd_sync.js +3 -2
  116. package/dist/cli-delegate/cmd_uninstall.js +3 -2
  117. package/dist/cli-delegate/cmd_validate.js +3 -2
  118. package/dist/discovery/deprecation-report.md +1 -1
  119. package/dist/discovery/discovery-manifest.json +58 -58
  120. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  121. package/dist/discovery/discovery-manifest.summary.md +1 -1
  122. package/dist/discovery/dormancy-report.md +1 -1
  123. package/dist/discovery/orphan-report.md +1 -1
  124. package/dist/discovery/packs.json +2 -2
  125. package/dist/discovery/trust-report.md +1 -1
  126. package/dist/discovery/workspaces.json +2 -2
  127. package/dist/hooks/dispatch.js +2900 -1049
  128. package/dist/install/claudeRuleRewrite.js +254 -0
  129. package/dist/install/detect.js +29 -16
  130. package/dist/install/detect_php_shape.js +159 -0
  131. package/dist/install/install.mjs +634 -428
  132. package/dist/mcp/awesome-mcp-servers.row.md +1 -1
  133. package/dist/mcp/mcp-cloudflare-catalogue.json +1 -1
  134. package/dist/mcp/registry-manifest.json +3 -3
  135. package/dist/mcp/server.json +3 -3
  136. package/dist/mcp/server.mjs +4895 -2627
  137. package/dist/server/schemas/settings.js +3 -0
  138. package/dist/ui/assets/index-D0jaCRPM.js +29 -0
  139. package/dist/ui/index.html +1 -1
  140. package/docs/MIGRATION.md +1 -1
  141. package/docs/THIRD-PARTY-NOTICES.md +25 -0
  142. package/docs/contracts/provider-lifecycle.md +1 -1
  143. package/docs/contracts/settings-classes.md +10 -4
  144. package/docs/guidelines/agent-infra/5w2h-analysis.md +3 -3
  145. package/docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md +1 -0
  146. package/docs/guidelines/agent-infra/artifact-drafting-protocol-mechanics.md +58 -3
  147. package/docs/guidelines/agent-infra/ask-when-uncertain-demos.md +2 -2
  148. package/docs/guidelines/agent-infra/asking-and-brevity-examples.md +3 -3
  149. package/docs/guidelines/agent-infra/break-glass-usage.md +7 -7
  150. package/docs/guidelines/agent-infra/carve-out-predicates.md +3 -3
  151. package/docs/guidelines/agent-infra/comparison-matrix.md +1 -1
  152. package/docs/guidelines/agent-infra/critical-thinking.md +4 -4
  153. package/docs/guidelines/agent-infra/direct-answers-demos.md +2 -2
  154. package/docs/guidelines/agent-infra/domain-eval-anti-pattern.md +1 -1
  155. package/docs/guidelines/agent-infra/engineering-memory-data-format.md +3 -3
  156. package/docs/guidelines/agent-infra/existence-question-verdicts.md +80 -0
  157. package/docs/guidelines/agent-infra/first-principles.md +2 -2
  158. package/docs/guidelines/agent-infra/framework-neutrality-patterns.md +2 -2
  159. package/docs/guidelines/agent-infra/guarded-baseline.md +39 -0
  160. package/docs/guidelines/agent-infra/inversion-thinking.md +5 -5
  161. package/docs/guidelines/agent-infra/language-and-tone-examples.md +1 -1
  162. package/docs/guidelines/agent-infra/layered-settings.md +10 -10
  163. package/docs/guidelines/agent-infra/memory-access.md +1 -1
  164. package/docs/guidelines/agent-infra/mental-models.md +3 -3
  165. package/docs/guidelines/agent-infra/reuse-verdict-mechanics.md +71 -0
  166. package/docs/guidelines/agent-infra/review-routing-data-format.md +7 -7
  167. package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +13 -7
  168. package/docs/guidelines/agent-infra/role-contracts.md +2 -2
  169. package/docs/guidelines/agent-infra/role-mode-router.md +3 -3
  170. package/docs/guidelines/agent-infra/rule-type-governance.md +2 -2
  171. package/docs/guidelines/agent-infra/scqa-framework.md +5 -5
  172. package/docs/guidelines/agent-infra/self-improvement-pipeline.md +6 -6
  173. package/docs/guidelines/agent-infra/simplicity-and-goal-demos.md +2 -2
  174. package/docs/guidelines/agent-infra/six-hats.md +3 -3
  175. package/docs/guidelines/agent-infra/skill-quality-checklist.md +6 -6
  176. package/docs/guidelines/agent-infra/source-confidentiality-mechanics.md +109 -0
  177. package/docs/guidelines/agent-infra/systems-thinking.md +1 -1
  178. package/docs/guidelines/agent-infra/verify-before-complete-demos.md +2 -2
  179. package/docs/guidelines/augment-portability-patterns.md +6 -4
  180. package/docs/guidelines/code-clarity.md +18 -0
  181. package/docs/guidelines/component-oriented-and-oop-development.md +3 -2
  182. package/docs/guidelines/cross-role-handoff.md +2 -2
  183. package/docs/guidelines/design-fidelity-mechanics.md +1 -1
  184. package/docs/guidelines/docs/readme-size-and-splitting.md +3 -3
  185. package/docs/guidelines/php/database.md +90 -7
  186. package/docs/guidelines/prompt-templates.md +7 -7
  187. package/llms.txt +2 -2
  188. package/package.json +5 -2
  189. package/src/agent-src/scripts/archive_completed_roadmaps.ts +252 -8
  190. package/src/agent-src/scripts/guarded_baseline.ts +343 -0
  191. package/src/agent-src/scripts/roadmap_set_step.ts +253 -0
  192. package/src/agent-src/scripts/stub_queue.ts +82 -0
  193. package/src/agent-src/scripts/stubs_due.ts +516 -0
  194. package/src/agent-src/scripts/ticket_bundles.ts +84 -0
  195. package/src/agent-src/scripts/update_roadmap_progress.ts +16 -12
  196. package/src/agent-src/templates/scripts/check_memory.ts +258 -17
  197. package/src/agent-src/templates/scripts/check_memory_proposal.ts +9 -3
  198. package/src/agent-src/templates/scripts/memory_lookup.ts +86 -0
  199. package/src/agent-src/templates/scripts/memory_signal.ts +44 -0
  200. package/src/agent-src/templates/scripts/work_engine/directives/backend/implement.ts +90 -0
  201. package/src/agent-src/templates/scripts/work_engine/directives/backend/index.ts +11 -0
  202. package/src/agent-src/templates/scripts/work_engine/directives/backend/test.ts +23 -1
  203. package/src/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +10 -1
  204. package/src/agent-src/templates/scripts/work_engine/directives/mixed/stitch.ts +5 -1
  205. package/src/agent-src/templates/scripts/work_engine/stack/runner.ts +102 -14
  206. package/src/config/agent-settings.template.yml +32 -3
  207. package/src/config/assurance-capability-registry.json +21 -9
  208. package/src/config/canonical-terms.yml +119 -0
  209. package/src/config/capability-native-outcome-bars.json +81 -0
  210. package/src/config/ci-local-parity.yml +80 -0
  211. package/src/config/drafting-channels.yml +43 -0
  212. package/src/config/estate-count-budget.json +57 -36
  213. package/src/config/evaluator-budgets.json +14 -14
  214. package/src/config/gate-coverage.yml +729 -63
  215. package/src/config/gate-reachability-exemptions.json +21 -0
  216. package/src/config/gate-violation-baselines.json +42 -19
  217. package/src/config/harness-evolution-budget.json +25 -0
  218. package/src/config/lapsed-beta-baseline.json +96 -0
  219. package/src/config/memory-twin-verdicts.yml +129 -0
  220. package/src/config/metric-registry.yml +124 -0
  221. package/src/config/pack-size-budget.json +16 -15
  222. package/src/config/preamble-payload-budget.json +12 -4
  223. package/src/config/profiles/balanced.ini +27 -0
  224. package/src/config/profiles/full.ini +27 -0
  225. package/src/config/profiles/minimal.ini +27 -0
  226. package/src/config/publish-surface.json +9 -2
  227. package/src/config/routing-coverage-seed.json +16 -2
  228. package/src/config/rule-stub-ceilings.json +133 -112
  229. package/src/config/turnaround-budget.json +66 -0
  230. package/src/install/claudeRuleRewrite.ts +288 -0
  231. package/src/install/detect.ts +60 -17
  232. package/src/install/detect_php_shape.ts +191 -0
  233. package/src/scripts/_cli/cmd_doctor.ts +27 -112
  234. package/src/scripts/_dispatch.bash +23 -0
  235. package/src/scripts/_lib/activation_ladder.ts +255 -0
  236. package/src/scripts/_lib/activation_receipt_producer.ts +341 -0
  237. package/src/scripts/_lib/activation_states.ts +88 -0
  238. package/src/scripts/_lib/adherence_detectors.ts +143 -0
  239. package/src/scripts/_lib/adr_frontmatter.ts +26 -0
  240. package/src/scripts/_lib/arith_claims.ts +181 -0
  241. package/src/scripts/_lib/arm_ranking.ts +62 -0
  242. package/src/scripts/_lib/asset_delivery_ledger.ts +303 -0
  243. package/src/scripts/_lib/audit_field_provenance.ts +54 -0
  244. package/src/scripts/_lib/auto_dispatch.ts +32 -3
  245. package/src/scripts/_lib/bench_ab_size_claim.ts +98 -4
  246. package/src/scripts/_lib/benchmark_cache_fields.ts +158 -0
  247. package/src/scripts/_lib/candidate_pair_delta.ts +349 -0
  248. package/src/scripts/_lib/candidate_proposer.ts +402 -0
  249. package/src/scripts/_lib/candidate_record.ts +601 -0
  250. package/src/scripts/_lib/capture_rate.ts +319 -0
  251. package/src/scripts/_lib/carrier_status.ts +118 -0
  252. package/src/scripts/_lib/cascade_stage_enumeration.ts +92 -0
  253. package/src/scripts/_lib/collector_denominator.ts +771 -0
  254. package/src/scripts/_lib/collector_record.ts +340 -0
  255. package/src/scripts/_lib/collector_store.ts +664 -0
  256. package/src/scripts/_lib/collector_supervision.ts +827 -0
  257. package/src/scripts/_lib/concern_estate.ts +77 -0
  258. package/src/scripts/_lib/config_chain.ts +477 -0
  259. package/src/scripts/_lib/config_cost.ts +209 -0
  260. package/src/scripts/_lib/corpus_manifest.ts +726 -0
  261. package/src/scripts/_lib/council_settings_block.ts +6 -0
  262. package/src/scripts/_lib/curator_ops.ts +172 -0
  263. package/src/scripts/_lib/delivery_arm_experiment.ts +282 -0
  264. package/src/scripts/_lib/delivery_criticality.ts +126 -0
  265. package/src/scripts/_lib/doctor_runtime_checks.ts +70 -0
  266. package/src/scripts/_lib/empty_cycles.ts +88 -0
  267. package/src/scripts/_lib/estate_carrier_cases.ts +72 -0
  268. package/src/scripts/_lib/eval_publication.ts +354 -0
  269. package/src/scripts/_lib/evaluation_cascade.ts +452 -0
  270. package/src/scripts/_lib/evaluation_vector.ts +283 -0
  271. package/src/scripts/_lib/evaluator_promotion.ts +225 -0
  272. package/src/scripts/_lib/evidence_basis.ts +118 -0
  273. package/src/scripts/_lib/evolution_roi.ts +562 -0
  274. package/src/scripts/_lib/exec_evidence.ts +8 -0
  275. package/src/scripts/_lib/experience_card.ts +272 -0
  276. package/src/scripts/_lib/experience_report.ts +151 -0
  277. package/src/scripts/_lib/experiment_freeze.ts +112 -0
  278. package/src/scripts/_lib/generated_by.ts +66 -0
  279. package/src/scripts/_lib/harness_evolution_guards.ts +239 -0
  280. package/src/scripts/_lib/hook_effect_probe.ts +141 -0
  281. package/src/scripts/_lib/host_denominator.ts +687 -0
  282. package/src/scripts/_lib/host_projection_reach.ts +157 -0
  283. package/src/scripts/_lib/ignored_blocker.ts +148 -0
  284. package/src/scripts/_lib/install_reach_checks.ts +495 -0
  285. package/src/scripts/_lib/json_duplicate_keys.ts +150 -0
  286. package/src/scripts/_lib/judge_hygiene.ts +228 -0
  287. package/src/scripts/_lib/legacy_boundary_map.ts +228 -0
  288. package/src/scripts/_lib/lexical_shortlist.ts +215 -0
  289. package/src/scripts/_lib/llm_candidate_proposer.ts +461 -0
  290. package/src/scripts/_lib/llm_proposer_transport.ts +153 -0
  291. package/src/scripts/_lib/loop_guards.ts +299 -0
  292. package/src/scripts/_lib/loss_class.ts +129 -0
  293. package/src/scripts/_lib/machine_wake.ts +51 -0
  294. package/src/scripts/_lib/md_prose_lines.ts +177 -0
  295. package/src/scripts/_lib/minimality_tiebreak.ts +168 -0
  296. package/src/scripts/_lib/one_resolver_invariant.ts +449 -0
  297. package/src/scripts/_lib/orchestration_record.ts +253 -5
  298. package/src/scripts/_lib/outcome_envelope.ts +227 -0
  299. package/src/scripts/_lib/outcome_vocabularies.ts +125 -0
  300. package/src/scripts/_lib/paired_stats.ts +245 -0
  301. package/src/scripts/_lib/paired_verdict.ts +226 -0
  302. package/src/scripts/_lib/pathology_archive.ts +393 -0
  303. package/src/scripts/_lib/prefix_stable_surfaces.ts +123 -0
  304. package/src/scripts/_lib/privacy_class.ts +47 -0
  305. package/src/scripts/_lib/promotion_capability.ts +315 -0
  306. package/src/scripts/_lib/promotion_evidence.ts +414 -0
  307. package/src/scripts/_lib/promotion_review.ts +294 -0
  308. package/src/scripts/_lib/prompt_shape.ts +92 -0
  309. package/src/scripts/_lib/regression_neighbourhood.ts +259 -0
  310. package/src/scripts/_lib/release_highlights.ts +70 -1
  311. package/src/scripts/_lib/release_material.ts +125 -2
  312. package/src/scripts/_lib/repeated_failure.ts +105 -0
  313. package/src/scripts/_lib/repo_root.ts +111 -0
  314. package/src/scripts/_lib/review_skipped_record.ts +37 -0
  315. package/src/scripts/_lib/role_split.ts +338 -0
  316. package/src/scripts/_lib/routing_corpus.ts +307 -0
  317. package/src/scripts/_lib/routing_index_input.ts +104 -0
  318. package/src/scripts/_lib/rule_injection.ts +22 -1
  319. package/src/scripts/_lib/runtime_journal.ts +1499 -0
  320. package/src/scripts/_lib/runtime_wiring_checks.ts +430 -0
  321. package/src/scripts/_lib/semantic_noop.ts +167 -0
  322. package/src/scripts/_lib/skill_catalogue.ts +11 -1
  323. package/src/scripts/_lib/source_digest.ts +200 -0
  324. package/src/scripts/_lib/source_redact.ts +260 -0
  325. package/src/scripts/_lib/source_shape.ts +502 -0
  326. package/src/scripts/_lib/source_snapshot_dedup.ts +199 -0
  327. package/src/scripts/_lib/strip_comments.d.mts +8 -0
  328. package/src/scripts/_lib/strip_comments.mjs +65 -0
  329. package/src/scripts/_lib/test_red_state.ts +154 -0
  330. package/src/scripts/_lib/trigger_shift.ts +144 -0
  331. package/src/scripts/_lib/untrusted_content.ts +82 -7
  332. package/src/scripts/activation_receipt.ts +258 -0
  333. package/src/scripts/adoption_report.ts +1 -1
  334. package/src/scripts/adr/evidence_census.ts +1 -1
  335. package/src/scripts/adr/regenerate_index.ts +26 -2
  336. package/src/scripts/adr_cite_check.ts +164 -1
  337. package/src/scripts/ai_council/blind_review.ts +11 -1
  338. package/src/scripts/ai_council/clients.ts +4 -0
  339. package/src/scripts/ai_council/config.ts +3 -0
  340. package/src/scripts/ai_council/consensus.ts +28 -8
  341. package/src/scripts/ai_council/consensus_round.ts +226 -0
  342. package/src/scripts/ai_council/cross_exam.ts +128 -0
  343. package/src/scripts/ai_council/disagreement_signal.ts +338 -0
  344. package/src/scripts/ai_council/explain_route.ts +157 -0
  345. package/src/scripts/ai_council/information_gain.ts +293 -0
  346. package/src/scripts/ai_council/inline_findings.ts +340 -0
  347. package/src/scripts/ai_council/judge_position_bias.ts +197 -0
  348. package/src/scripts/ai_council/leakage_corpus.ts +385 -0
  349. package/src/scripts/ai_council/leakage_patterns.ts +453 -0
  350. package/src/scripts/ai_council/minority_retention.ts +171 -0
  351. package/src/scripts/ai_council/orchestrator.ts +16 -203
  352. package/src/scripts/ai_council/orchestrator_results.ts +23 -3
  353. package/src/scripts/ai_council/pricing.ts +106 -0
  354. package/src/scripts/ai_council/prompts.ts +74 -7
  355. package/src/scripts/ai_council/provider_leakage_bench.ts +327 -0
  356. package/src/scripts/ai_council/py_format.ts +14 -3
  357. package/src/scripts/ai_council/recouncil_guard.ts +293 -0
  358. package/src/scripts/ai_council/recouncil_savings.ts +299 -0
  359. package/src/scripts/ai_council/replay_route.ts +223 -0
  360. package/src/scripts/ai_council/response_record.ts +50 -0
  361. package/src/scripts/ai_council/reviewer_assignment.ts +279 -0
  362. package/src/scripts/ai_council/routing_training_row.ts +197 -0
  363. package/src/scripts/ai_council/synthesis_strategy.ts +159 -0
  364. package/src/scripts/ai_council/topology_bench_manifest.ts +860 -0
  365. package/src/scripts/ai_council/topology_vocabulary.ts +175 -0
  366. package/src/scripts/asset_delivery_ledger.ts +157 -0
  367. package/src/scripts/attest_artifact.ts +193 -0
  368. package/src/scripts/audit_auto_rules.ts +2 -1
  369. package/src/scripts/audit_command_surface.ts +1 -1
  370. package/src/scripts/audit_mcp_tools.ts +2 -2
  371. package/src/scripts/audit_skill_overlap_allowlist.json +6 -1
  372. package/src/scripts/audit_user_type_axis.ts +2 -1
  373. package/src/scripts/bench_ab_clone.ts +215 -10
  374. package/src/scripts/bench_ab_integrity.ts +119 -5
  375. package/src/scripts/bench_ab_v2_stats.ts +40 -213
  376. package/src/scripts/build_archive_index.ts +1 -1
  377. package/src/scripts/build_linear_digest.ts +1 -1
  378. package/src/scripts/build_proof.ts +11 -4
  379. package/src/scripts/build_rule_trigger_matrix.ts +1 -1
  380. package/src/scripts/build_source_digests.ts +157 -0
  381. package/src/scripts/cache_realization_report.ts +103 -0
  382. package/src/scripts/check_adr_frontmatter.ts +131 -10
  383. package/src/scripts/check_benchmark_report_fields.ts +207 -0
  384. package/src/scripts/check_beta_review_markers.ts +235 -6
  385. package/src/scripts/check_bundle_path_leakage.ts +34 -1
  386. package/src/scripts/check_claims.ts +576 -6
  387. package/src/scripts/check_composite_arming.ts +35 -0
  388. package/src/scripts/check_concern_admissions.ts +365 -0
  389. package/src/scripts/check_enforcement_coverage.ts +28 -0
  390. package/src/scripts/check_estate_count.ts +347 -25
  391. package/src/scripts/check_gate_reachability.ts +383 -0
  392. package/src/scripts/check_host_loadability.ts +104 -0
  393. package/src/scripts/check_loss_class_declared.ts +308 -0
  394. package/src/scripts/check_md_language.ts +15 -98
  395. package/src/scripts/check_memory_proposal.ts +18 -11
  396. package/src/scripts/check_no_currency_in_cost_surfaces.ts +225 -0
  397. package/src/scripts/check_no_external_sources.ts +281 -6
  398. package/src/scripts/check_pack_conformance_fixture.ts +11 -1
  399. package/src/scripts/check_pack_size.ts +59 -2
  400. package/src/scripts/check_preamble_payload_budget.ts +114 -3
  401. package/src/scripts/check_prefix_stable_mutation.ts +372 -0
  402. package/src/scripts/check_publish_surface.ts +10 -1
  403. package/src/scripts/check_references.ts +24 -1
  404. package/src/scripts/check_release_highlights.ts +96 -13
  405. package/src/scripts/check_roadmap_trackable.ts +17 -2
  406. package/src/scripts/check_rule_evidence_declaration.ts +316 -0
  407. package/src/scripts/check_rule_projection_integrity.ts +14 -4
  408. package/src/scripts/check_score_contract.ts +26 -3
  409. package/src/scripts/check_static_parity.ts +285 -0
  410. package/src/scripts/check_supervision_claim_atomicity.ts +498 -0
  411. package/src/scripts/check_suppression_hygiene.ts +15 -0
  412. package/src/scripts/ci_settle.ts +39 -2
  413. package/src/scripts/code_graph/build.ts +60 -3
  414. package/src/scripts/code_graph/extract.ts +44 -0
  415. package/src/scripts/code_graph/types.ts +24 -0
  416. package/src/scripts/collector_daemon.ts +714 -0
  417. package/src/scripts/config_cost_report.ts +302 -0
  418. package/src/scripts/consumer_matrix.ts +74 -1
  419. package/src/scripts/corpus_manifest.ts +235 -0
  420. package/src/scripts/cost/budget.mjs +10 -3
  421. package/src/scripts/cost/track.mjs +10 -3
  422. package/src/scripts/council_cli.ts +37 -54
  423. package/src/scripts/dispatch_r2_reviewer.ts +46 -5
  424. package/src/scripts/evolution_lab.ts +1153 -0
  425. package/src/scripts/external_sources_denylist.json +5 -18
  426. package/src/scripts/extract_audit_patterns.ts +21 -0
  427. package/src/scripts/fold_intake.ts +12 -1
  428. package/src/scripts/gen_discovery_baseline.ts +1 -1
  429. package/src/scripts/generate_capabilities_index.ts +12 -5
  430. package/src/scripts/generate_capability_matrix.ts +3 -3
  431. package/src/scripts/generate_command_flows.ts +2 -2
  432. package/src/scripts/generate_cookbook.ts +2 -2
  433. package/src/scripts/generate_index.ts +8 -1
  434. package/src/scripts/generate_knowledge_index.ts +2 -1
  435. package/src/scripts/generate_ownership_matrix.ts +2 -1
  436. package/src/scripts/generate_pack_manifests.ts +10 -2
  437. package/src/scripts/generate_role_experiences_catalog.ts +2 -2
  438. package/src/scripts/generate_settings_reference.ts +1 -1
  439. package/src/scripts/git_authorization_hook.ts +22 -1
  440. package/src/scripts/grade_target_readiness.ts +48 -5
  441. package/src/scripts/hook_effect_doctor.ts +261 -0
  442. package/src/scripts/hook_manifest.json +1 -1
  443. package/src/scripts/hook_manifest.yaml +125 -16
  444. package/src/scripts/hooks/block_speaking_inbox_dir.ts +271 -0
  445. package/src/scripts/hooks/block_unauthorized_git.ts +18 -0
  446. package/src/scripts/hooks/comment_discipline_hook.ts +146 -0
  447. package/src/scripts/hooks/concern_registry.ts +6 -0
  448. package/src/scripts/hooks/dispatch_hook.ts +32 -0
  449. package/src/scripts/hooks/journal_record_hook.ts +345 -0
  450. package/src/scripts/hooks/prepush_metadata_sources.sh +110 -0
  451. package/src/scripts/hooks/run_continuation_hook.ts +44 -9
  452. package/src/scripts/hooks/shims/install.sh +61 -0
  453. package/src/scripts/hooks/shims/php +101 -0
  454. package/src/scripts/hooks/suggestion_capture_hook.ts +10 -0
  455. package/src/scripts/hooks/turn_end_gate_hook.ts +9 -1
  456. package/src/scripts/hot_context_hook.ts +16 -0
  457. package/src/scripts/install-hooks.sh +20 -5
  458. package/src/scripts/install.ts +17 -35
  459. package/src/scripts/inventory_frontmatter.ts +2 -1
  460. package/src/scripts/language_mirror_hook.ts +14 -2
  461. package/src/scripts/lint_adr_sweep_routing.ts +12 -0
  462. package/src/scripts/lint_canonical_terms.ts +604 -0
  463. package/src/scripts/lint_carrier_integrity.ts +820 -0
  464. package/src/scripts/lint_code_comments.ts +643 -0
  465. package/src/scripts/lint_composition_review.ts +619 -0
  466. package/src/scripts/lint_consolidation_lineage.ts +666 -0
  467. package/src/scripts/lint_eval_specs.ts +593 -0
  468. package/src/scripts/lint_hook_manifest.ts +19 -0
  469. package/src/scripts/lint_host_portability.ts +373 -0
  470. package/src/scripts/lint_judge_prompt_expectation.ts +27 -1
  471. package/src/scripts/lint_memory_twin_parity.ts +335 -0
  472. package/src/scripts/lint_metric_consumers.ts +355 -0
  473. package/src/scripts/lint_plan_risk_register.ts +39 -19
  474. package/src/scripts/lint_promotion_paths.ts +779 -0
  475. package/src/scripts/lint_skill_descriptions.ts +18 -1
  476. package/src/scripts/lint_skill_frontmatter_safety.ts +58 -0
  477. package/src/scripts/lint_skill_link_reach.ts +252 -0
  478. package/src/scripts/lint_skill_trigger_corpus.ts +426 -23
  479. package/src/scripts/lint_ticket_buildable.ts +17 -1
  480. package/src/scripts/llm_propose.ts +256 -0
  481. package/src/scripts/mcp_server/consumer_tool_catalog.json +1 -1
  482. package/src/scripts/mcp_server/tool_catalog_source.ts +1 -1
  483. package/src/scripts/measure_delivery_sets.ts +361 -0
  484. package/src/scripts/measure_docs_dead_links.ts +348 -0
  485. package/src/scripts/measure_host_capture.ts +461 -0
  486. package/src/scripts/measure_routing_signal.ts +307 -0
  487. package/src/scripts/migration_status.ts +3 -3
  488. package/src/scripts/model_rule_injection.ts +76 -0
  489. package/src/scripts/orchestration_record.ts +14 -0
  490. package/src/scripts/preamble_byte_census.ts +139 -10
  491. package/src/scripts/prepack-check.mjs +4 -1
  492. package/src/scripts/probe_council_retention.ts +495 -0
  493. package/src/scripts/probe_turnaround.ts +384 -0
  494. package/src/scripts/probe_unblocked_ask.ts +279 -0
  495. package/src/scripts/release.ts +21 -37
  496. package/src/scripts/release_drill.ts +143 -0
  497. package/src/scripts/release_env.ts +35 -0
  498. package/src/scripts/release_publication.ts +84 -0
  499. package/src/scripts/render_benchmark_md.ts +1 -1
  500. package/src/scripts/rule_activation_census.ts +70 -9
  501. package/src/scripts/rule_backlinks.ts +1 -1
  502. package/src/scripts/run_lifecycle_suite.ts +208 -0
  503. package/src/scripts/run_skill_evals.ts +40 -0
  504. package/src/scripts/schemas/delivery-manifest.schema.json +43 -0
  505. package/src/scripts/schemas/drafting-channels.schema.json +43 -0
  506. package/src/scripts/schemas/evals.schema.json +24 -1
  507. package/src/scripts/schemas/rule.schema.json +52 -1
  508. package/src/scripts/schemas/skill.schema.json +17 -2
  509. package/src/scripts/skill_overlap.ts +7 -1
  510. package/src/scripts/skill_tools/run_block_d_eval.ts +8 -1
  511. package/src/scripts/skill_tools/score_skill_relevance.ts +84 -3
  512. package/src/scripts/skill_tools/suggest_skill_for_task.ts +8 -1
  513. package/src/scripts/skill_usage_report.ts +2 -1
  514. package/src/scripts/stubs_due.ts +211 -0
  515. package/src/scripts/sweep_source_surfaces.ts +678 -0
  516. package/src/scripts/sync_pr_branch.ts +3 -3
  517. package/src/scripts/trigger_eval_grandfather.json +202 -222
  518. package/src/scripts/utilization_report.ts +22 -2
  519. package/src/server/schemas/settings.ts +5 -0
  520. package/src/templates/marketing-copy.yml +1 -1
  521. package/dist/ui/assets/index-Cxgy63kz.js +0 -26
@@ -0,0 +1,271 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * PreToolUse guard: refuse the CREATION of a speaking inbox directory under
4
+ * `agents/tmp/` — `road-to-source-silence` Phase 4.2.
5
+ *
6
+ * ## Why a write-time guard, when the directory is gitignored anyway
7
+ *
8
+ * `agents/tmp/` is gitignored, so a speaking round directory looks free. It is
9
+ * the root of the whole leak chain and the chain is measured, not theorised:
10
+ * the name gets quoted into a tracked roadmap `> **Source:**` header, into an
11
+ * evidence artefact, into a review-snapshot FILENAME and into a PR body — and
12
+ * every one of those quotes republishes it in a public repository. Phase 0's
13
+ * census counted **190 block-tier occurrences** of quoted non-opaque
14
+ * `agents/tmp(.old)/<name>/` paths across the tracked tree, plus one tracked
15
+ * findings file named after a round.
16
+ *
17
+ * Every downstream gate in this programme catches the QUOTE. This one catches
18
+ * the name, at the only moment removing it is free: before anything can cite
19
+ * it. Renaming after the first quote lands means chasing the quotes.
20
+ *
21
+ * ## What it refuses, and the four things it does not
22
+ *
23
+ * Refuses: a Write/Edit/NotebookEdit (or cross-platform equivalent) whose
24
+ * target path introduces a **new** first-level directory under `agents/tmp/`
25
+ * or `agents/tmp.old/` whose name is not an opaque round identifier.
26
+ *
27
+ * Allowed, deliberately:
28
+ *
29
+ * 1. **A file directly under `agents/tmp/`** with no subdirectory. Scratch
30
+ * files are not rounds and have no name to leak.
31
+ * 2. **A directory that already exists.** Blocking every later write into an
32
+ * already-created speaking directory would wedge a session mid-round without
33
+ * removing the name — the fix there is a rename, which the deny message of
34
+ * the creating call already asked for. This is the one filesystem read the
35
+ * guard performs.
36
+ * 3. **An opaque round identifier** — `isOpaqueRoundId` in
37
+ * `_lib/source_shape.ts` is the single authority, shared with the gate, so
38
+ * the guard and the CI check can never disagree about what "opaque" means.
39
+ * 4. **A named working set** — `NON_HARVEST_TMP_DIRS`, same shared module. A
40
+ * directory named after the WORK leaks nothing; the precedent
41
+ * (`bench-local`) was added on a measured false positive.
42
+ *
43
+ * ## Severity, stated honestly
44
+ *
45
+ * `severity: blocking` with `fail_closed: false`. A DETECTED violation refuses;
46
+ * a malformed envelope, an unreadable path or any crash ALLOWS. That pairing is
47
+ * deliberate and copied from `block_config_weakening`: the guarantee is about
48
+ * the case the guard actually decided, and a scratch-directory guard must never
49
+ * be the reason an unrelated edit fails. Kill switch for a maintainer who needs
50
+ * it out of the way: `AGENT_CONFIG_ALLOW_SPEAKING_INBOX=1`.
51
+ *
52
+ * Only `claude` both binds `pre_tool_use` and honours a deny. Elsewhere this
53
+ * runs and is ignored, or does not bind at all — `agent-config hooks:status`
54
+ * answers it for the host you are on, and this docstring does not claim
55
+ * otherwise.
56
+ *
57
+ * Exit codes (docs/contracts/hook-architecture-v1.md): 0 allow · 1 block.
58
+ */
59
+
60
+ import * as fs from 'node:fs';
61
+ import * as path from 'node:path';
62
+ import { fileURLToPath, pathToFileURL } from 'node:url';
63
+
64
+ import { isNonHarvestTmpDir, isOpaqueRoundId } from '../_lib/source_shape.js';
65
+ import { readHookStdin } from './hook_stdin.js';
66
+
67
+ const _HERE = fileURLToPath(import.meta.url);
68
+
69
+ type JsonValue = string | number | boolean | null | JsonValue[] | { [k: string]: JsonValue };
70
+ type JsonObject = { [k: string]: JsonValue };
71
+
72
+ const KILL_SWITCH = 'AGENT_CONFIG_ALLOW_SPEAKING_INBOX';
73
+
74
+ /** Keys across platforms that carry a tool call's target file path. */
75
+ const _PATH_KEYS: readonly string[] = [
76
+ 'file_path', 'path', 'target_file', 'filename', 'filePath', 'notebook_path',
77
+ ];
78
+
79
+ function _isObject(v: JsonValue | undefined): v is JsonObject {
80
+ return v !== null && v !== undefined && typeof v === 'object' && !Array.isArray(v);
81
+ }
82
+
83
+ /** `agents/tmp/<name>/…` or `agents/tmp.old/<name>/…`, after normalisation. */
84
+ const INBOX_RE = /(?:^|\/)agents\/tmp(?:\.old)?\/([^/]+)\/./;
85
+
86
+ /**
87
+ * A DIRECTORY-TERMINAL inbox path — `agents/tmp/<name>` with nothing after it.
88
+ *
89
+ * `mkdir -p agents/tmp/<name>` names the directory with no trailing slash and no
90
+ * file after it, so `INBOX_RE` cannot see it. That is the exact bypass the R2
91
+ * review of this branch found, and the test that pins it caught this second
92
+ * form on the first run.
93
+ *
94
+ * The last segment is read as a DIRECTORY only when it carries no `.` — so
95
+ * `cat agents/tmp/scratch.ts` stays a file reference and is not judged as a
96
+ * round name. That is a heuristic and its limit is real: a directory whose name
97
+ * genuinely contains a dot is missed by this form. It is still caught the moment
98
+ * anything is written INSIDE it, which is the path `INBOX_RE` covers.
99
+ */
100
+ const INBOX_DIR_TERMINAL_RE = /(?:^|\/)agents\/tmp(?:\.old)?\/([^/.]+)\/?$/;
101
+
102
+ /**
103
+ * The first-level directory name this path would place a file under, or `null`
104
+ * when the path is not inside an inbox subdirectory at all.
105
+ *
106
+ * Pure, and separated from the filesystem check so the decision is testable
107
+ * without a tree — the shape half of the guard is what a harness can pin.
108
+ */
109
+ export function inboxDirName(filePath: string): string | null {
110
+ if (!filePath) {
111
+ return null;
112
+ }
113
+ const normalized = filePath.replace(/\\/g, '/').replace(/^(\.\/)+/, '');
114
+ const m = INBOX_RE.exec(normalized);
115
+ if (m) {
116
+ return m[1] as string;
117
+ }
118
+ const d = INBOX_DIR_TERMINAL_RE.exec(normalized);
119
+ return d ? (d[1] as string) : null;
120
+ }
121
+
122
+ /**
123
+ * Is this directory name one the confidentiality contract accepts?
124
+ *
125
+ * Delegates entirely to the shared shape module, so "opaque" means exactly what
126
+ * `check_no_external_sources` means by it.
127
+ */
128
+ export function isAcceptableInboxDir(name: string): boolean {
129
+ return isOpaqueRoundId(name) || isNonHarvestTmpDir(name);
130
+ }
131
+
132
+ /**
133
+ * The guard's verdict for one target path. `existsSync` is injected so the
134
+ * harness can pin the already-exists branch without touching a real tree.
135
+ */
136
+ export function verdictFor(
137
+ filePath: string,
138
+ exists: (p: string) => boolean,
139
+ repoRoot = '',
140
+ ): { block: boolean; dir: string | null; reason: string } {
141
+ const dir = inboxDirName(filePath);
142
+ if (dir === null) {
143
+ return { block: false, dir: null, reason: 'not inside an inbox subdirectory' };
144
+ }
145
+ if (isAcceptableInboxDir(dir)) {
146
+ return { block: false, dir, reason: 'opaque round identifier or named working set' };
147
+ }
148
+ // Already created — a rename is the fix, and refusing every later write
149
+ // would wedge the round without removing the name.
150
+ //
151
+ // The probe path is derived from the SAME anchored match that found the
152
+ // directory, not from `indexOf('agents/tmp')`. That prefix also matches
153
+ // `agents/tmp-notes/` and `agents/tmpfiles/`, and taking the FIRST
154
+ // occurrence meant a path carrying a decoy earlier segment probed the wrong
155
+ // directory — in either direction. Found by the R2 review of this branch.
156
+ const normalized = filePath.replace(/\\/g, '/').replace(/^(\.\/)+/, '');
157
+ const m =
158
+ /(?:^|\/)(agents\/tmp(?:\.old)?\/[^/]+)\//.exec(normalized) ??
159
+ /(?:^|\/)(agents\/tmp(?:\.old)?\/[^/.]+)\/?$/.exec(normalized);
160
+ if (m === null) {
161
+ // `inboxDirName` matched but this did not — treat as unattributable and
162
+ // BLOCK, since the name is speaking and we cannot prove it pre-exists.
163
+ return { block: true, dir, reason: 'new inbox directory with a speaking name (path not re-anchorable)' };
164
+ }
165
+ const upto = m[1] as string;
166
+ const probe = repoRoot === '' ? upto : path.join(repoRoot, upto);
167
+ if (exists(probe)) {
168
+ return { block: false, dir, reason: 'directory already exists — rename, do not re-refuse' };
169
+ }
170
+ return { block: true, dir, reason: 'new inbox directory with a speaking name' };
171
+ }
172
+
173
+ /** The deny message — names the rule, the fix and the accepted forms. */
174
+ export function denyMessage(dir: string): string {
175
+ return (
176
+ `block-speaking-inbox-dir: BLOCKED — creating \`agents/tmp/${dir}/\` would name an\n` +
177
+ 'inbox round after its source. That name is the root of the leak chain: it gets\n' +
178
+ 'quoted into tracked roadmap `Source:` headers, evidence artefacts, review-snapshot\n' +
179
+ 'filenames and PR bodies, and every quote republishes it in a public repository.\n' +
180
+ '\n' +
181
+ 'Use an opaque round identifier instead:\n' +
182
+ ' inbox-2026-08-h round-dated, optional 1-3 char disambiguator\n' +
183
+ ' round-a91f3c content-free hex (also set-, src-set-, source-set-)\n' +
184
+ ' S17 a set number\n' +
185
+ '\n' +
186
+ 'Record the true source ONCE, encrypted, in the round\'s intake note:\n' +
187
+ " printf '%s' '<the real source>' | ./scripts-run src/scripts/_lib/link_crypto encrypt\n" +
188
+ '\n' +
189
+ 'Naming rule: /analyze:inbox Phase 1. Rule: src/rules/source-confidentiality.md.\n' +
190
+ `Maintainer kill switch: ${KILL_SWITCH}=1.\n`
191
+ );
192
+ }
193
+
194
+ export function main(): number {
195
+ if ((process.env[KILL_SWITCH] ?? '') !== '') {
196
+ return 0;
197
+ }
198
+ let envelope: JsonObject;
199
+ try {
200
+ const raw = readHookStdin();
201
+ if (!raw) {
202
+ return 0;
203
+ }
204
+ envelope = JSON.parse(raw) as JsonObject;
205
+ } catch {
206
+ return 0; // fail_closed: false — a malformed envelope never blocks.
207
+ }
208
+ try {
209
+ const payload = _isObject(envelope['payload']) ? envelope['payload'] : envelope;
210
+ const ti = _isObject(payload['tool_input'])
211
+ ? payload['tool_input']
212
+ : _isObject(envelope['tool_input'])
213
+ ? envelope['tool_input']
214
+ : null;
215
+ if (ti === null) {
216
+ return 0;
217
+ }
218
+ const repoRoot = typeof envelope['project_dir'] === 'string' ? envelope['project_dir'] : '';
219
+ const candidates: string[] = [];
220
+ for (const key of _PATH_KEYS) {
221
+ const v = ti[key];
222
+ if (typeof v === 'string' && v) {
223
+ candidates.push(v);
224
+ }
225
+ }
226
+ // A shell command creates the directory just as effectively as a Write,
227
+ // and this guard read only the path keys — so `mkdir -p
228
+ // agents/tmp/<speaking-name>`, a `git mv` into one, or a redirect
229
+ // bypassed it entirely. Both siblings on this slot (`block_no_verify`,
230
+ // `block_kernel_rule_writes`) parse the command string; this one did
231
+ // not, and the R2 review of this branch caught it. Every whitespace
232
+ // token of the command is offered to the same pure verdict, so the
233
+ // decision logic is shared rather than duplicated.
234
+ const cmd = ti['command'] ?? (_isObject(envelope['payload']) ? (envelope['payload'] as JsonObject)['command'] : undefined);
235
+ if (typeof cmd === 'string' && cmd) {
236
+ for (const tok of cmd.split(/[\s"'`(){};|&<>]+/)) {
237
+ if (tok) {
238
+ candidates.push(tok);
239
+ }
240
+ }
241
+ }
242
+ for (const v of candidates) {
243
+ const verdict = verdictFor(v, (p) => fs.existsSync(p), repoRoot);
244
+ if (verdict.block && verdict.dir !== null) {
245
+ process.stderr.write(denyMessage(verdict.dir));
246
+ return 1;
247
+ }
248
+ }
249
+ } catch {
250
+ return 0;
251
+ }
252
+ return 0;
253
+ }
254
+
255
+ function _isCliEntry(): boolean {
256
+ if (process.argv[1] === undefined) {
257
+ return false;
258
+ }
259
+ if (import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href) {
260
+ return true;
261
+ }
262
+ try {
263
+ return fs.realpathSync(fileURLToPath(import.meta.url)) === fs.realpathSync(path.resolve(process.argv[1]));
264
+ } catch {
265
+ return false;
266
+ }
267
+ }
268
+
269
+ if (_isCliEntry()) {
270
+ process.exit(main());
271
+ }
@@ -523,6 +523,24 @@ export function commandOp(command: string): GitOp | null {
523
523
  * window grows. The agent never edits this constant, this file, or the built
524
524
  * bundle; `dist/hooks/dispatch.js` is what actually executes, and a source
525
525
  * edit without a rebuild is silently inert.
526
+ *
527
+ * **ADR-251 (2026-08-30) decided this question and KEPT the value.** An AI
528
+ * council converged 2/2 on a different authorization SHAPE rather than a wider
529
+ * window, against the measured pressure that 7 of the 10 most recent sessions
530
+ * of this package outlive a 30-minute window (median span 3.1 h) and that the
531
+ * constant has been hand-widened twice. `LEDGER_MAX_AGE_MS` is unchanged at 30
532
+ * minutes and raising it remains forbidden — that transition is owner-reserved,
533
+ * and this record did not take it.
534
+ *
535
+ * What the record DID change is the behaviour at expiry: the run PAUSES,
536
+ * reports the remaining work, and ASKS for re-authorization, instead of ending.
537
+ * The user's reply renews this ledger through the path that already exists —
538
+ * `git_authorization_hook.ts` rewrites the session's ledger with a fresh
539
+ * `detected_at` on every human-typed prompt (`:512-537`), so a mid-run reply
540
+ * carrying an authorization phrase resets the age this constant is compared
541
+ * against. No new machinery, and the signal stays agent-unforgeable.
542
+ *
543
+ * See `docs/decisions/ADR-251-authorization-window-shape-not-width.md`.
526
544
  */
527
545
  export const LEDGER_MAX_AGE_MS = 30 * 60 * 1000;
528
546
 
@@ -0,0 +1,146 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Comment-discipline advisory — `post_tool_use` concern.
4
+ *
5
+ * The write-time half of `lint_code_comments`. The gate answers "may this
6
+ * land"; this answers "was it written that way in the first place", which is
7
+ * the question the maintainer actually asked after a run produced 509 German
8
+ * comment lines across 41 of 45 changed source files without anything
9
+ * objecting once.
10
+ *
11
+ * `code-comment-discipline` is `type: auto` with PROMPT keywords (`comment`,
12
+ * `refactor`, `implement`, …). A run that writes forty-five files while the
13
+ * user says "build the todo module" matches none of them, so the rule never
14
+ * loads — the activation gap `fix-what-you-see` names for itself, in the one
15
+ * place where the agent is producing the artefact the rule governs. A
16
+ * post-write concern fires on the TOOL EVENT and therefore does not depend on
17
+ * what the prompt happened to say.
18
+ *
19
+ * `Write` carries the new content in `tool_input.content`; `Edit` carries the
20
+ * replacement in `tool_input.new_string`. Scanning that text rather than the
21
+ * file on disk makes the concern forward-only by construction: a pre-existing
22
+ * comment the edit did not touch cannot fire it, so there is no baseline to
23
+ * maintain and no legacy tree to clean before turning it on.
24
+ *
25
+ * Same shape as `edit_shape_hook.ts` and `delegation_nudge_hook.ts`:
26
+ * `host_semantics.emitFor`'s `severity === "warn"` branch returns exit 0 with
27
+ * the text in `hookSpecificOutput.additionalContext`, unconditionally, so the
28
+ * byte handed to the host is always 0. Advisory is the right severity here
29
+ * and not a hedge — the classifier is a line heuristic, and a heuristic that
30
+ * can refuse a write would turn one false positive into a blocked session.
31
+ * The deterministic refusal lives in the gate, where a human can read the
32
+ * whole file before answering.
33
+ *
34
+ * `edit-shape` fires once per session because its advice is a habit
35
+ * correction that lands the first time. This one is per-write on purpose: the
36
+ * measured failure is forty-one files each carrying the defect, and a nudge
37
+ * that speaks once and then watches forty more land is the shape that
38
+ * produced the incident. The cost is bounded by naming at most
39
+ * `MAX_REPORTED` findings and no more than one line per write.
40
+ *
41
+ * ROBUSTNESS: malformed payload → exit 0 silently. This concern never blocks.
42
+ */
43
+ import * as fs from 'node:fs';
44
+ import * as path from 'node:path';
45
+ import { fileURLToPath, pathToFileURL } from 'node:url';
46
+
47
+ import { isScannable, scanText, type CommentFinding } from '../lint_code_comments.js';
48
+ import { unwrap, type JsonObject, type JsonValue } from './envelope.js';
49
+ import { readHookStdin } from './hook_stdin.js';
50
+
51
+ const EXIT_ALLOW = 0;
52
+ const EXIT_WARN = 2;
53
+
54
+ /** Findings named in the advisory line. The rest are counted, never listed. */
55
+ export const MAX_REPORTED = 3;
56
+
57
+ function str(v: JsonValue | undefined): string {
58
+ return typeof v === 'string' ? v : '';
59
+ }
60
+ function isObject(v: unknown): v is JsonObject {
61
+ return typeof v === 'object' && v !== null && !Array.isArray(v);
62
+ }
63
+
64
+ /** The written text, per tool. Empty string when the payload carries none. */
65
+ export function writtenText(toolName: string, toolInput: JsonObject): string {
66
+ if (toolName === 'Write') return str(toolInput['content'] as JsonValue | undefined);
67
+ if (toolName === 'Edit') {
68
+ return str(toolInput['new_string'] as JsonValue | undefined)
69
+ || str(toolInput['newString'] as JsonValue | undefined);
70
+ }
71
+ return '';
72
+ }
73
+
74
+ /** One advisory line, naming what fired and where. */
75
+ export function buildAdvisoryLine(file: string, findings: readonly CommentFinding[]): string {
76
+ const counts = new Map<string, number>();
77
+ for (const f of findings) counts.set(f.cls, (counts.get(f.cls) ?? 0) + 1);
78
+ const summary = [...counts].map(([c, n]) => `${c} ×${n}`).join(' · ');
79
+ const named = findings.slice(0, MAX_REPORTED)
80
+ .map((f) => `line ${f.line} (${f.signal})`)
81
+ .join(', ');
82
+ const more = findings.length > MAX_REPORTED ? `, +${findings.length - MAX_REPORTED} more` : '';
83
+ return (
84
+ `comment-discipline: the text just written to ${file} carries ${summary} — ${named}${more}. `
85
+ + 'A comment states a WHY or a constraint the code cannot show, in English; evidence for a '
86
+ + 'roadmap step belongs in that roadmap, not in a second copy in the source. Rewrite or '
87
+ + 'delete those lines now, before the next write — `lint_code_comments` refuses them at the gate.'
88
+ );
89
+ }
90
+
91
+ export function main(): number {
92
+ try {
93
+ const [envelope, payload] = unwrap(readHookStdin(), 'claude');
94
+
95
+ const event = str(envelope['event'] as JsonValue | undefined);
96
+ if (event !== '' && event !== 'post_tool_use') return EXIT_ALLOW;
97
+
98
+ const toolName = str(
99
+ (payload['tool_name'] ?? payload['toolName'] ?? payload['tool']) as JsonValue | undefined,
100
+ );
101
+ if (toolName !== 'Write' && toolName !== 'Edit') return EXIT_ALLOW;
102
+
103
+ const ti = payload['tool_input'] ?? payload['toolInput'] ?? payload['input'];
104
+ if (!isObject(ti)) return EXIT_ALLOW;
105
+
106
+ const filePath = str((ti['file_path'] ?? ti['path'] ?? ti['filePath']) as JsonValue | undefined);
107
+ if (!filePath || !isScannable(filePath)) return EXIT_ALLOW;
108
+
109
+ const text = writtenText(toolName, ti);
110
+ if (!text) return EXIT_ALLOW;
111
+
112
+ const workspaceRoot = str(envelope['workspace_root'] as JsonValue | undefined).trim() || process.cwd();
113
+ const abs = path.isAbsolute(filePath) ? filePath : path.resolve(workspaceRoot, filePath);
114
+ const rel = path.relative(workspaceRoot, abs);
115
+ const shown = rel.startsWith('..') ? path.basename(abs) : rel;
116
+
117
+ const findings = scanText(shown, text);
118
+ if (findings.length === 0) return EXIT_ALLOW;
119
+
120
+ process.stdout.write(
121
+ `${JSON.stringify({
122
+ decision: 'warn',
123
+ reason: `comment-discipline: ${findings.length} comment finding(s) in the text written to ${shown}`,
124
+ additional_context: buildAdvisoryLine(shown, findings),
125
+ })}\n`,
126
+ );
127
+ return EXIT_WARN;
128
+ } catch {
129
+ return EXIT_ALLOW;
130
+ }
131
+ }
132
+
133
+ declare const __AGENT_CONFIG_BUNDLE__: boolean | undefined;
134
+ function _isCliEntry(): boolean {
135
+ if (typeof __AGENT_CONFIG_BUNDLE__ !== 'undefined' && __AGENT_CONFIG_BUNDLE__) return false;
136
+ if (process.argv[1] === undefined) return false;
137
+ const argvUrl = pathToFileURL(path.resolve(process.argv[1])).href;
138
+ if (import.meta.url === argvUrl) return true;
139
+ try {
140
+ return fs.realpathSync(fileURLToPath(import.meta.url)) === fs.realpathSync(path.resolve(process.argv[1]));
141
+ } catch {
142
+ return false;
143
+ }
144
+ }
145
+
146
+ if (_isCliEntry()) process.exit(main());
@@ -53,6 +53,7 @@ import { main as evidenceIndependenceMain } from './evidence_independence.js';
53
53
  import { main as blockNoVerifyMain } from './block_no_verify.js';
54
54
  import { main as blockKernelRuleWritesMain } from './block_kernel_rule_writes.js';
55
55
  import { main as blockConfigWeakeningMain } from './block_config_weakening.js';
56
+ import { main as blockSpeakingInboxDirMain } from './block_speaking_inbox_dir.js';
56
57
  import { main as rtkWrapMain } from './rtk_wrap_hook.js';
57
58
  import { _main as designPassMain } from './design_pass_hook.js';
58
59
  import { main as designSlopMain } from './design_slop_hook.js';
@@ -68,6 +69,7 @@ import { main as ruleInjectMain } from './rule_inject_hook.js';
68
69
  import { main as endReviewNudgeMain } from './end_review_nudge_hook.js';
69
70
  import { main as turnEndGateMain } from './turn_end_gate_hook.js';
70
71
  import { main as editShapeMain } from './edit_shape_hook.js';
72
+ import { main as commentDisciplineMain } from './comment_discipline_hook.js';
71
73
  import { main as rereadGuardMain } from './reread_guard_hook.js';
72
74
  import { main as sessionEolMain } from './session_eol_hook.js';
73
75
  import { main as subagentLedgerMain } from './subagent_ledger_hook.js';
@@ -76,6 +78,7 @@ import { main as spawnGuardShadowMain } from './spawn_guard_shadow_hook.js';
76
78
  import { main as sourceFirstGateMain } from './source_first_gate_hook.js';
77
79
  import { main as interruptionLedgerMain } from './interruption_ledger_hook.js';
78
80
  import { main as runContinuationMain } from './run_continuation_hook.js';
81
+ import { main as journalRecordMain } from './journal_record_hook.js';
79
82
 
80
83
  /** A concern `main` — argv-taking or not; both shapes exist. */
81
84
  export type ConcernMain = (argv?: string[]) => number | undefined | void;
@@ -111,6 +114,7 @@ export const CONCERN_REGISTRY: Readonly<Record<string, ConcernMain>> = {
111
114
  'src/scripts/hooks/block_no_verify.ts': blockNoVerifyMain as ConcernMain,
112
115
  'src/scripts/hooks/block_kernel_rule_writes.ts': blockKernelRuleWritesMain as ConcernMain,
113
116
  'src/scripts/hooks/block_config_weakening.ts': blockConfigWeakeningMain as ConcernMain,
117
+ 'src/scripts/hooks/block_speaking_inbox_dir.ts': blockSpeakingInboxDirMain as ConcernMain,
114
118
  'src/scripts/hooks/rtk_wrap_hook.ts': rtkWrapMain as ConcernMain,
115
119
  'src/scripts/hooks/design_pass_hook.ts': designPassMain as ConcernMain,
116
120
  'src/scripts/hooks/design_slop_hook.ts': designSlopMain as ConcernMain,
@@ -126,6 +130,7 @@ export const CONCERN_REGISTRY: Readonly<Record<string, ConcernMain>> = {
126
130
  'src/scripts/hooks/end_review_nudge_hook.ts': endReviewNudgeMain as ConcernMain,
127
131
  'src/scripts/hooks/turn_end_gate_hook.ts': turnEndGateMain as ConcernMain,
128
132
  'src/scripts/hooks/edit_shape_hook.ts': editShapeMain as ConcernMain,
133
+ 'src/scripts/hooks/comment_discipline_hook.ts': commentDisciplineMain as ConcernMain,
129
134
  'src/scripts/hooks/reread_guard_hook.ts': rereadGuardMain as ConcernMain,
130
135
  'src/scripts/hooks/session_eol_hook.ts': sessionEolMain as ConcernMain,
131
136
  'src/scripts/hooks/subagent_ledger_hook.ts': subagentLedgerMain as ConcernMain,
@@ -134,4 +139,5 @@ export const CONCERN_REGISTRY: Readonly<Record<string, ConcernMain>> = {
134
139
  'src/scripts/hooks/source_first_gate_hook.ts': sourceFirstGateMain as ConcernMain,
135
140
  'src/scripts/hooks/interruption_ledger_hook.ts': interruptionLedgerMain as ConcernMain,
136
141
  'src/scripts/hooks/run_continuation_hook.ts': runContinuationMain as ConcernMain,
142
+ 'src/scripts/hooks/journal_record_hook.ts': journalRecordMain as ConcernMain,
137
143
  };
@@ -57,6 +57,7 @@ import { stdinReadFailure, denyOnStdinFailure } from './stdin_failure_policy.js'
57
57
  export { stdinReadFailure, denyOnStdinFailure, _is_fail_closed_blocking } from './stdin_failure_policy.js';
58
58
  import { _py_json_dumps } from './py_json_dumps.js';
59
59
  import { _fallback_yaml } from './fallback_yaml.js';
60
+ import { recordCapture, recordOpportunity } from "../_lib/collector_denominator.js";
60
61
  export { _fallback_yaml } from './fallback_yaml.js';
61
62
 
62
63
  // Free-form JSON values flow through every helper here; a documented
@@ -1144,6 +1145,37 @@ export function main(argv?: string[]): number {
1144
1145
  return EXIT_ALLOW; // fail-open per contract for unknown events
1145
1146
  }
1146
1147
 
1148
+ // ── The capture rate: both halves, written here ─────────────────────────────
1149
+ //
1150
+ // Two calls rather than one, because they must be able to FAIL DIFFERENTLY.
1151
+ // `recordOpportunity` is the denominator's independent writer — in-process,
1152
+ // no daemon — so a dead collector yields a climbing denominator against a
1153
+ // flat numerator and the rate falls instead of reading 0/0. `recordCapture`
1154
+ // is the numerator, and its absence was a real defect three review rounds
1155
+ // took to find. Both are gated on the opt-in marker, both refuse a
1156
+ // self-observed dispatch, and neither throws; the rationale, the ordering and
1157
+ // the exclusion all live in `collector_denominator.ts`.
1158
+ //
1159
+ // UNGUARDED HERE, and that is finding 3 of round 4. The guard used to be
1160
+ // `if (!isSelfObservation())` around these two lines — and vitest always sets
1161
+ // `VITEST`, so under the parity comparison NEITHER run ever reached them.
1162
+ // `check_static_parity` could observe a module-load difference and nothing
1163
+ // else, which made the AC-7 comparison vacuous with respect to the thing it
1164
+ // claims to compare. The exclusion is a property of the METRIC, so it belongs
1165
+ // inside the metric functions where the opt-in check already is; putting it
1166
+ // in the caller's control flow is what made the calls disappear.
1167
+ //
1168
+ // Cost on a default-off install: FOUR `existsSync` calls, not two — each
1169
+ // function calls `isCollectorEnabled`, which probes the opt-out marker and
1170
+ // then the ENABLED one. The number is stated correctly here at the third
1171
+ // attempt (R2 finding 14 corrected one to two, round 4 finding 9 caught that
1172
+ // a second caller had since doubled it).
1173
+ //
1174
+ // Placed after the vocabulary check so an unknown event is not an
1175
+ // opportunity, and before the manifest load so a missing manifest still is.
1176
+ recordOpportunity(args.event, args.platform);
1177
+ recordCapture(args.event, args.platform);
1178
+
1147
1179
  const manifest_path = args.manifest;
1148
1180
  if (!fs.existsSync(manifest_path)) {
1149
1181
  process.stderr.write(`dispatch_hook: manifest missing at ${manifest_path}\n`);