@event4u/agent-config 14.17.0 → 14.19.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 (184) 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 +207 -77
  5. package/README.md +72 -150
  6. package/dist/agent-src/README.md +1 -1
  7. package/dist/agent-src/commands/agent-handoff.md +2 -2
  8. package/dist/agent-src/commands/pr/merge.md +35 -44
  9. package/dist/agent-src/commands/review/changes.md +19 -19
  10. package/dist/agent-src/commands/review.md +2 -2
  11. package/dist/agent-src/contexts/execution/host-capability-manifest.md +30 -3
  12. package/dist/agent-src/rules/autonomous-execution.md +1 -1
  13. package/dist/agent-src/rules/git-history-discipline.md +2 -2
  14. package/dist/agent-src/rules/guidelines.md +1 -1
  15. package/dist/agent-src/rules/session-canary.md +2 -2
  16. package/dist/agent-src/rules/token-efficiency.md +1 -1
  17. package/dist/agent-src/skills/accessibility-auditor/SKILL.md +2 -0
  18. package/dist/agent-src/skills/adversarial-review/SKILL.md +0 -8
  19. package/dist/agent-src/skills/ai-code-blindspots/SKILL.md +27 -1
  20. package/dist/agent-src/skills/canvas-design/SKILL.md +1 -1
  21. package/dist/agent-src/skills/code-intelligence/SKILL.md +60 -12
  22. package/dist/agent-src/skills/complexity-first-planning/SKILL.md +27 -0
  23. package/dist/agent-src/skills/design-intelligence/SKILL.md +1 -1
  24. package/dist/agent-src/skills/design-intelligence/data/app-interface.csv +1 -1
  25. package/dist/agent-src/skills/design-intelligence/data/motion.csv +17 -17
  26. package/dist/agent-src/skills/design-intelligence/data/ux-guidelines.csv +2 -2
  27. package/dist/agent-src/skills/design-intelligence/references/context-and-registers.md +17 -0
  28. package/dist/agent-src/skills/design-intelligence/references/design-rules-checklist.md +4 -4
  29. package/dist/agent-src/skills/design-review/SKILL.md +3 -1
  30. package/dist/agent-src/skills/design-variations/SKILL.md +1 -1
  31. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +1 -1
  32. package/dist/agent-src/skills/fe-design/SKILL.md +32 -5
  33. package/dist/agent-src/skills/fe-design/references/craft-floor.md +7 -0
  34. package/dist/agent-src/skills/fe-design/references/design-patterns.md +47 -2
  35. package/dist/agent-src/skills/feature-planning/SKILL.md +34 -0
  36. package/dist/agent-src/skills/git-workflow/SKILL.md +37 -12
  37. package/dist/agent-src/skills/git-workflow/references/push-closes-its-loop.md +176 -0
  38. package/dist/agent-src/skills/laravel-mail/SKILL.md +44 -0
  39. package/dist/agent-src/skills/laravel-scheduling/SKILL.md +3 -1
  40. package/dist/agent-src/skills/project-analyzer/SKILL.md +0 -6
  41. package/dist/agent-src/skills/react-native-setup/SKILL.md +3 -3
  42. package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +1 -1
  43. package/dist/agent-src/skills/sequential-thinking/SKILL.md +18 -8
  44. package/dist/agent-src/skills/tailwind-engineer/SKILL.md +1 -1
  45. package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +40 -0
  46. package/dist/agent-src/skills/ui-apply-generic/SKILL.md +1 -1
  47. package/dist/agent-src/skills/ui-component-architect/SKILL.md +1 -1
  48. package/dist/agent-src/skills/using-git-worktrees/SKILL.md +29 -2
  49. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +53 -8
  50. package/dist/agent-src/skills/worktree-lifecycle/SKILL.md +3 -1
  51. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  52. package/dist/cli/commands/recordTriggerEval.js +2 -2
  53. package/dist/cli/main.js +1 -1
  54. package/dist/cli-delegate/{chunk-AKJGUQNO.js → chunk-GZTMRYCN.js} +405 -341
  55. package/dist/cli-delegate/{chunk-7RXIKF62.js → chunk-IDHUQIXP.js} +283 -132
  56. package/dist/cli-delegate/cmd_adr_effective.js +318 -81
  57. package/dist/cli-delegate/cmd_conformance.js +749 -669
  58. package/dist/cli-delegate/cmd_doctor.js +1 -1
  59. package/dist/cli-delegate/cmd_export.js +1 -1
  60. package/dist/cli-delegate/cmd_handoff.js +1 -1
  61. package/dist/cli-delegate/cmd_prune.js +1 -1
  62. package/dist/cli-delegate/cmd_route_audit.js +1 -1
  63. package/dist/cli-delegate/cmd_settings_migrate.js +1 -1
  64. package/dist/cli-delegate/cmd_sync.js +1 -1
  65. package/dist/cli-delegate/cmd_uninstall.js +1 -1
  66. package/dist/cli-delegate/cmd_validate.js +1 -1
  67. package/dist/discovery/deprecation-report.md +1 -1
  68. package/dist/discovery/discovery-manifest.json +39 -38
  69. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  70. package/dist/discovery/discovery-manifest.summary.md +1 -1
  71. package/dist/discovery/dormancy-report.md +1 -1
  72. package/dist/discovery/orphan-report.md +1 -1
  73. package/dist/discovery/packs.json +2 -2
  74. package/dist/discovery/trust-report.md +1 -1
  75. package/dist/discovery/workspaces.json +2 -2
  76. package/dist/hooks/dispatch.js +2764 -2439
  77. package/dist/install/install.mjs +588 -527
  78. package/dist/mcp/registry-manifest.json +2 -2
  79. package/dist/mcp/server.json +2 -2
  80. package/dist/mcp/server.mjs +1381 -1138
  81. package/dist/scripts/_lib/model_tier.js +1 -1
  82. package/dist/shared/settingsConsent.js +1 -1
  83. package/docs/guidelines/agent-infra/evaluator-independence-mechanics.md +1 -1
  84. package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
  85. package/docs/guidelines/design-antipatterns.md +87 -64
  86. package/package.json +1 -1
  87. package/src/agent-src/README.md +1 -1
  88. package/src/config/ci-local-parity.yml +6 -0
  89. package/src/config/conformance-claim-baseline.json +9 -0
  90. package/src/config/gate-coverage.yml +170 -0
  91. package/src/config/gate-violation-baselines.json +4 -4
  92. package/src/config/release-gate-locality.yml +141 -0
  93. package/src/scripts/_cli/cmd_doctor.ts +2 -2
  94. package/src/scripts/_cli/cmd_handoff.ts +1 -1
  95. package/src/scripts/_cli/cmd_update.ts +1 -1
  96. package/src/scripts/_cli/cmd_versions.ts +1 -1
  97. package/src/scripts/_lib/adr_frontmatter.ts +44 -0
  98. package/src/scripts/_lib/consequence_objects.ts +152 -0
  99. package/src/scripts/_lib/exec_evidence.ts +7 -0
  100. package/src/scripts/_lib/global_deploy_inventory.ts +2 -2
  101. package/src/scripts/_lib/host_permission_checks.ts +251 -0
  102. package/src/scripts/_lib/model_tier.ts +1 -1
  103. package/src/scripts/_lib/obligation_frequency.ts +2 -2
  104. package/src/scripts/_lib/release_highlights.ts +265 -1
  105. package/src/scripts/_lib/release_material.ts +129 -0
  106. package/src/scripts/_lib/repeated_run.ts +77 -0
  107. package/src/scripts/_lib/runtime_journal.ts +26 -3
  108. package/src/scripts/_lib/runtime_wiring_checks.ts +12 -1
  109. package/src/scripts/_lib/session_register.ts +11 -6
  110. package/src/scripts/_lib/sqlite_schema.ts +22 -0
  111. package/src/scripts/_lib/surface.ts +86 -0
  112. package/src/scripts/_lib/tamper_vocabulary.ts +242 -0
  113. package/src/scripts/_lib/ui_authority.ts +116 -0
  114. package/src/scripts/_lib/unified_diff.ts +121 -0
  115. package/src/scripts/adr/regenerate_index.ts +54 -1
  116. package/src/scripts/adr_cite_check.ts +71 -15
  117. package/src/scripts/ai_council/clients.ts +1 -1
  118. package/src/scripts/autonomy_friction_corpus.ts +229 -0
  119. package/src/scripts/build_proof.ts +15 -2
  120. package/src/scripts/check_beta_review_markers.ts +141 -17
  121. package/src/scripts/check_enforcement_coverage.ts +1 -1
  122. package/src/scripts/check_enforcement_denominator.ts +121 -11
  123. package/src/scripts/check_finding_dispositions.ts +239 -6
  124. package/src/scripts/check_gate_coverage.ts +96 -0
  125. package/src/scripts/check_installed_hooks_fresh.ts +381 -0
  126. package/src/scripts/check_release_highlights.ts +99 -14
  127. package/src/scripts/check_skill_activation_claim.ts +179 -0
  128. package/src/scripts/check_suppression_hygiene.ts +11 -0
  129. package/src/scripts/check_trigger_evals.ts +1 -1
  130. package/src/scripts/code_graph/build.ts +230 -33
  131. package/src/scripts/code_graph/extract.ts +168 -33
  132. package/src/scripts/code_graph/types.ts +37 -2
  133. package/src/scripts/code_graph/validate.ts +12 -1
  134. package/src/scripts/conformance_scan.ts +45 -4
  135. package/src/scripts/detect_silent_catch.ts +403 -0
  136. package/src/scripts/detect_verification_tampering.ts +538 -0
  137. package/src/scripts/explain_run.ts +1 -1
  138. package/src/scripts/generate_capability_matrix.ts +1 -1
  139. package/src/scripts/git_authorization_hook.ts +228 -18
  140. package/src/scripts/hook_manifest.json +1 -1
  141. package/src/scripts/hook_manifest.yaml +47 -30
  142. package/src/scripts/hooks/augment-dispatcher.sh +1 -1
  143. package/src/scripts/hooks/block_no_verify.ts +3 -3
  144. package/src/scripts/hooks/category_a.ts +291 -0
  145. package/src/scripts/hooks/cline-dispatcher.sh +1 -1
  146. package/src/scripts/hooks/concern_registry.ts +2 -2
  147. package/src/scripts/hooks/cursor-dispatcher.sh +11 -5
  148. package/src/scripts/hooks/dispatch_hook.ts +17 -22
  149. package/src/scripts/hooks/evidence_independence.ts +21 -2
  150. package/src/scripts/hooks/{block_unauthorized_git.ts → git_command_classifier.ts} +175 -364
  151. package/src/scripts/hooks/host_lowering.ts +215 -0
  152. package/src/scripts/hooks/host_lowering.yaml +185 -0
  153. package/src/scripts/hooks/host_semantics.ts +105 -37
  154. package/src/scripts/hooks/journal_record_hook.ts +10 -0
  155. package/src/scripts/hooks/permission_gate.ts +117 -0
  156. package/src/scripts/hooks/push_settle_hook.ts +250 -0
  157. package/src/scripts/hooks/ship_diff_volume_hook.ts +1 -1
  158. package/src/scripts/hooks_status.ts +12 -10
  159. package/src/scripts/install-hooks.sh +134 -1
  160. package/src/scripts/install.ts +53 -82
  161. package/src/scripts/install_anthropic_key.sh +2 -2
  162. package/src/scripts/language_mirror_hook.ts +27 -5
  163. package/src/scripts/lint_design_antipattern_parity.ts +80 -0
  164. package/src/scripts/lint_evidence_artifacts.ts +45 -1
  165. package/src/scripts/lint_hook_manifest.ts +87 -3
  166. package/src/scripts/lint_motion_authority_drift.ts +731 -0
  167. package/src/scripts/lint_readme_size.ts +158 -12
  168. package/src/scripts/lint_reasoning_fixtures.ts +216 -0
  169. package/src/scripts/lint_skill_trigger_contradiction.ts +161 -0
  170. package/src/scripts/measure_sibling_naming.ts +150 -0
  171. package/src/scripts/redact_hook_capture.ts +1 -1
  172. package/src/scripts/release.ts +31 -143
  173. package/src/scripts/release_drill.ts +71 -1
  174. package/src/scripts/release_publication.ts +243 -3
  175. package/src/scripts/release_verify.ts +220 -0
  176. package/src/scripts/report_skill_activation.ts +319 -7
  177. package/src/scripts/schemas/review-findings.schema.json +6 -1
  178. package/src/scripts/schemas/skill.schema.json +12 -2
  179. package/src/scripts/self_review_gate.ts +10 -1
  180. package/src/scripts/session_canary_hook.ts +1 -1
  181. package/src/scripts/session_register_hook.ts +4 -3
  182. package/src/scripts/trigger_eval_grandfather.json +5 -1
  183. package/src/scripts/validate_agent_settings.ts +1 -1
  184. package/src/shared/settingsConsent.ts +1 -1
@@ -2,9 +2,14 @@
2
2
  /**
3
3
  * Git-authorization ledger — `user_prompt_submit` concern.
4
4
  *
5
- * Records which git operations the user's OWN WORDS authorize this turn, so
6
- * `hooks/block_unauthorized_git.ts` can check an operation against a fact
7
- * instead of against the model's recollection of the conversation.
5
+ * Records which git operations the user's OWN WORDS authorize this turn.
6
+ *
7
+ * NOTHING ENFORCES THIS LEDGER ANY MORE. Its consumer — the
8
+ * `block-unauthorized-git` gate — was removed by owner decision on 2026-09-04
9
+ * (ADR-254). What still reads the file is `hooks/evidence_independence.ts`,
10
+ * which takes `detected_at` as a per-turn stamp, and `conformance_scan.ts`,
11
+ * which MEASURES unauthorized operations after the fact. The record is kept
12
+ * because measuring is worth keeping; it refuses nothing.
8
13
  *
9
14
  * WHY — the measured defect (30-session conformance audit, 2026-08-06):
10
15
  *
@@ -56,6 +61,10 @@ import { fileURLToPath, pathToFileURL } from "node:url";
56
61
 
57
62
  import { humanTypedThisTurn as _humanTypedThisTurn } from "./_lib/machine_wake.js";
58
63
 
64
+ import {
65
+ CONSEQUENCE_PHRASES,
66
+ extractObjects,
67
+ } from "./_lib/consequence_objects.js";
59
68
  import { atomic_write_json } from "./hooks/state_io.js";
60
69
  import { readHookStdin } from "./hooks/hook_stdin.js";
61
70
 
@@ -230,7 +239,36 @@ export type GitOp =
230
239
  /** Deleting a branch, locally or on the remote. */
231
240
  | "branch-delete"
232
241
  /** Closing a pull request or an issue. */
233
- | "close";
242
+ | "close"
243
+
244
+ // ── Consequence operations, added 2026-09-06
245
+ // (`road-to-authorization-that-reaches-further` 2.1).
246
+ //
247
+ // The boundaries the owner named had NO vocabulary at all, so an
248
+ // authorization the user gave in plain words was invisible to the record and
249
+ // the matching operation was invisible to the count. These seven are NOT git
250
+ // operations, and the union's name is now narrower than its contents — a
251
+ // rename touches every consumer and buys nothing the doc comments do not.
252
+ //
253
+ // RECORDING AN AUTHORIZATION IS NOT GRANTING ONE. After ADR-254 there is no
254
+ // grantor left in this package: the ledger concern is advisory by manifest
255
+ // and the only consumer that acts on this vocabulary is the after-the-fact
256
+ // count in `conformance_scan`. Nothing here refuses, and nothing here may be
257
+ // read as a step toward refusing.
258
+ /** Deploying to a production environment. */
259
+ | "prod-deploy"
260
+ /** Destroying production data — a table, a bucket, a collection, rows. */
261
+ | "prod-data-destroy"
262
+ /** Changing production infrastructure — cluster, IAM, DNS, network. */
263
+ | "prod-infra-change"
264
+ /** Sending something outward that a third party receives. */
265
+ | "external-send"
266
+ /** Moving money — a charge, a refund, a payout, a transfer. */
267
+ | "money-movement"
268
+ /** Force-pushing a shared trunk, as distinct from a feature branch. */
269
+ | "trunk-force-push"
270
+ /** Destroying work outside the task's own scope. */
271
+ | "out-of-scope-destruction";
234
272
 
235
273
  export const ALL_OPS: readonly GitOp[] = [
236
274
  "commit",
@@ -259,6 +297,13 @@ export const ALL_OPS: readonly GitOp[] = [
259
297
  "stash-drop",
260
298
  "branch-delete",
261
299
  "close",
300
+ "prod-deploy",
301
+ "prod-data-destroy",
302
+ "prod-infra-change",
303
+ "external-send",
304
+ "money-movement",
305
+ "trunk-force-push",
306
+ "out-of-scope-destruction",
262
307
  ];
263
308
 
264
309
  /**
@@ -427,6 +472,8 @@ const PHRASES: ReadonlyArray<{ op: GitOp; re: RegExp }> = [
427
472
  op: "pr-merge-auto",
428
473
  re: /\bauto[-\s]?merge\b|\bmerge\b[^.\n]{0,20}\bautomatisch\b|\bautomatisch\b[^.\n]{0,20}\bmerg(e|en)\b/i,
429
474
  },
475
+
476
+ ...CONSEQUENCE_PHRASES,
430
477
  ];
431
478
 
432
479
  /**
@@ -610,6 +657,25 @@ export interface Ledger extends JsonObject {
610
657
  * as "no grants", which is the pre-ADR-252 behaviour exactly.
611
658
  */
612
659
  grants?: MergeGrant[];
660
+ /**
661
+ * The objects a consequence authorization named, per operation.
662
+ *
663
+ * An authorization for one table, one environment or one recipient class is
664
+ * not an authorization for another, and until now the record could not
665
+ * express the difference for anything but pull-request numbers
666
+ * (`MergeGrant.targets`). This is that distinction generalised to the
667
+ * consequence vocabulary.
668
+ *
669
+ * IT IS A RECORDED FIELD, NOT A MATCHING CONDITION. Nothing consults it to
670
+ * refuse anything; the one consumer is `conformance_scan`, which counts
671
+ * after the fact when an executed operation's object is absent here. Making
672
+ * it a matching condition is the ledger item ADR-254 left to the owner, and
673
+ * it is deliberately not taken here.
674
+ *
675
+ * Optional, so a ledger written by an older build still parses. Absent reads
676
+ * as "no objects named", which is exactly the pre-2.2 behaviour.
677
+ */
678
+ objects?: { [op: string]: string[] };
613
679
  }
614
680
 
615
681
  /**
@@ -630,10 +696,9 @@ function _errText(err: unknown): string {
630
696
  /**
631
697
  * The largest pull-request number GitHub can issue: a signed 32-bit integer.
632
698
  *
633
- * Taken from the API contract rather than estimated, and shared by the mint
634
- * site here and the consume site in `hooks/block_unauthorized_git.ts` so the
635
- * two cannot drift — the failure this file already learned once with its
636
- * negation vocabulary.
699
+ * Taken from the API contract rather than estimated, and shared with
700
+ * `hooks/git_command_classifier.ts` so the two cannot drift — the failure this
701
+ * file already learned once with its negation vocabulary.
637
702
  */
638
703
  export const PR_NUMBER_MAX = 2147483647;
639
704
 
@@ -665,19 +730,50 @@ export function extractMergeTargets(prompt: string): number[] {
665
730
  }
666
731
 
667
732
  /**
668
- * A human turn that withdraws standing merge authority.
733
+ * A bare stop word — a withdrawal that names no operation at all.
669
734
  *
670
735
  * Revocation must be cheaper to express than authorization, so this matches a
671
- * bare stop word on its own as well as an explicit "don't merge". It is
672
- * deliberately over-inclusive in the safe direction: a false revocation costs
673
- * one prompt, a missed revocation costs an unwanted merge.
736
+ * bare stop word on its own. It is deliberately over-inclusive in the safe
737
+ * direction: a false revocation costs one prompt, a missed revocation costs an
738
+ * unwanted merge. The alternation is orthogonal to negation and is unchanged.
674
739
  */
675
- const REVOKE_RE =
676
- /\b(stop|stopp|halt|abbrechen|abbruch|cancel|revoke|widerruf(en)?|zur(ü|ue)ck(nehmen|ziehen)|hold\s+(everything|on|the\s+merge)|warte|wait)\b|(?:\b(nicht|kein(e|en)?|no|not|dont|don't|never|niemals|nie)\b[^.!?\n]{0,30}\b(merg(e|en|ing)|zusammenf(ü|ue)hren)\b)/iu;
740
+ const REVOKE_STOP_WORD =
741
+ /\b(stop|stopp|halt|abbrechen|abbruch|cancel|revoke|widerruf(en)?|zur(ü|ue)ck(nehmen|ziehen)|hold\s+(everything|on|the\s+merge)|warte|wait)\b/iu;
742
+
743
+ /** The merge verb itself, with no negation notion of its own. */
744
+ const MERGE_VERB = /\b(merg(e|en|ing)|zusammenf(ü|ue)hren)\b/giu;
677
745
 
678
746
  /** Does this human turn withdraw standing merge grants? */
679
747
  export function isRevocation(prompt: string): boolean {
680
- return REVOKE_RE.test(prompt);
748
+ if (REVOKE_STOP_WORD.test(prompt) || isBareRefusal(prompt)) {
749
+ return true;
750
+ }
751
+ // ONE negation implementation, both callers. Until 2026-09-04 this function
752
+ // carried its own inline vocabulary and a fixed `{0,30}` BACKWARD window,
753
+ // while `classifyAuthorization` reached the clause-scoped, abbreviation-aware
754
+ // `negatedBefore` about 240 lines below. The two disagreed on real prompts in
755
+ // both directions — measured at b75d7f7cb:
756
+ //
757
+ // "Merge PR #12 auf keinen Fall." isRevocation=false, a standing
758
+ // grant over #12 SURVIVED
759
+ // "Merge #12 under no circumstances." isRevocation=false, same
760
+ // "Please do not push, but merge PR #7." isRevocation=true while
761
+ // classifyAuthorization returned
762
+ // ["pr-merge"] — the two parsers
763
+ // contradicting each other on a
764
+ // corpus row asserted green
765
+ //
766
+ // `NEGATION_WORD`'s docblock already stated the rule this restores: one
767
+ // vocabulary for the whole file, because two drift invisibly until a prompt
768
+ // lands in the gap between them.
769
+ MERGE_VERB.lastIndex = 0;
770
+ let m: RegExpExecArray | null;
771
+ while ((m = MERGE_VERB.exec(prompt)) !== null) {
772
+ if (negatedBefore(prompt, m.index, m[0])) {
773
+ return true;
774
+ }
775
+ }
776
+ return false;
681
777
  }
682
778
 
683
779
  /** Mint a grant id that a replayed ledger cannot collide with. */
@@ -746,9 +842,53 @@ export function foldGrants(
746
842
  * negation vocabularies in one tree drift, and the drift is invisible until a
747
843
  * prompt lands in the gap between them" — so the list moved here rather than
748
844
  * being copied fifteen times.
845
+ *
846
+ * BOTH DIRECTIONS READ IT, and since 2026-09-04 that is checkable rather than
847
+ * aspirational: `classifyAuthorization` reaches it through `negatedBefore`, and
848
+ * `isRevocation` reaches the same `negatedBefore` plus `isBareRefusal`. The
849
+ * revocation path was the copy the original consolidation missed — it kept a
850
+ * ten-form inline list behind a fixed 30-character backward window, and the two
851
+ * grammars disagreed on real prompts in both directions until they were merged.
852
+ * A THIRD caller adds itself here, not next to itself.
853
+ *
854
+ * THE APOSTROPHE IS PART OF THE VOCABULARY, not a typo tolerance. The list
855
+ * read `dont|don't` — ASCII only — while every macOS, iOS, Word and Slack
856
+ * input turns a typed apostrophe into U+2019 by default. Measured at
857
+ * b75d7f7cb, and it leaked in the DANGEROUS direction on the authorization
858
+ * path, not merely the revocation one:
859
+ *
860
+ * "don't merge PR #12" classifyAuthorization = [] (denied)
861
+ * "don\u2019t merge PR #12" classifyAuthorization = ["pr-merge"] (AUTHORIZED)
862
+ * "don\u2019t push" classifyAuthorization = ["push"] (AUTHORIZED)
863
+ *
864
+ * One character of smart-quote substitution turned a prohibition into a grant
865
+ * for an irreversible operation. `don['\u2019\u2018\u02bc]?t` covers the straight, the two
866
+ * typographic and the modifier-letter forms in the one shared list, so both
867
+ * callers gain it at once — which is the whole argument for one vocabulary.
868
+ */
869
+ /**
870
+ * Every apostrophe a keyboard or an autocorrect can produce for one word.
871
+ *
872
+ * Named once and shared by the vocabulary AND the tokenizer below. Written out
873
+ * twice, `don\u2018t` matched the vocabulary and then split into TWO tokens in
874
+ * `isBareRefusal` — this file's own drift failure, one character wide, caught
875
+ * by the council-mandated token-policy test rather than in review.
749
876
  */
750
- const NEGATION_WORD =
751
- /\b(nicht|nichts|kein(e|en|em|er|es)?|niemals|nie|no|not|dont|don't|never|without|ohne)\b/i;
877
+ const APOSTROPHE = "'\u2019\u2018\u02bc";
878
+
879
+ const NEGATION_ALTERNATION =
880
+ `nicht|nichts|kein(?:e|en|em|er|es)?|niemals|nie|no|not|don[${APOSTROPHE}]?t|never|without|ohne`;
881
+
882
+ const NEGATION_WORD = new RegExp(`\\b(${NEGATION_ALTERNATION})\\b`, "i");
883
+
884
+ /**
885
+ * The same vocabulary, anchored to a whole token.
886
+ *
887
+ * Built from `NEGATION_ALTERNATION` rather than written out a second time —
888
+ * a copied list is the exact drift this file's `NEGATION_WORD` docblock warns
889
+ * about, and repairing one such copy is what this change is for.
890
+ */
891
+ const NEGATION_TOKEN = new RegExp(`^(?:${NEGATION_ALTERNATION})$`, "i");
752
892
 
753
893
  /**
754
894
  * Is the match at `index` under a negation?
@@ -768,7 +908,9 @@ const NEGATION_WORD =
768
908
  * says why. The 30-character window inside the sentence is inherited from the
769
909
  * `pr-merge` lookbehind that this generalises.
770
910
  */
771
- const CONTRAST_CUE = /\b(aber|sondern|jedoch|but|however|instead)\b/gi;
911
+ const CONTRAST_ALTERNATION = "aber|sondern|jedoch|but|however|instead";
912
+
913
+ const CONTRAST_CUE = new RegExp(`\\b(${CONTRAST_ALTERNATION})\\b`, "gi");
772
914
 
773
915
  /**
774
916
  * Abbreviation and decimal dots are NOT sentence boundaries.
@@ -926,6 +1068,61 @@ export function negatedBefore(text: string, index: number, matched = ""): boolea
926
1068
  return NEGATION_WORD.test(before) || NEGATION_WORD.test(matched) || NEGATION_WORD.test(after);
927
1069
  }
928
1070
 
1071
+ /**
1072
+ * Is any clause of this turn a BARE refusal — negation words and nothing else?
1073
+ *
1074
+ * `negatedBefore` answers "is this operation negated", which needs the
1075
+ * operation to be in the clause. A withdrawal does not have to name one:
1076
+ * `"Merge PR #12? Actually, don't."` puts the merge in a question sentence and
1077
+ * the refusal in the next one, so no clause anywhere holds both. Measured at
1078
+ * b75d7f7cb and again after the shared-parser change: `isRevocation` returned
1079
+ * false and a standing grant over #12 survived.
1080
+ *
1081
+ * The scope is a CLAUSE whose every token is a negation word, which is the
1082
+ * narrow half. `"Do not push."` is not a bare refusal — `push` is a content
1083
+ * word, so the clause names an operation and `negatedBefore` owns it. That
1084
+ * boundary is what keeps this from revoking `"Nicht pushen. Merge PR #12."`,
1085
+ * a corpus row whose merge must still be authorized.
1086
+ *
1087
+ * It reuses `NEGATION_TOKEN`, so the one vocabulary covers this reading too.
1088
+ *
1089
+ * WHAT IT REVOKES — every standing grant, and that is the PRE-EXISTING
1090
+ * contract rather than a new one. `foldGrants` returns `[]` for any revocation,
1091
+ * which is how a bare `"stop"` has always behaved; a bare refusal is the same
1092
+ * class of utterance and takes the same transition. Nothing here narrows or
1093
+ * widens grant selection, so the council's question about which grant a bare
1094
+ * `"don't"` targets is answered by the existing product semantics: all of them,
1095
+ * in the safe direction.
1096
+ *
1097
+ * WHAT IT DOES NOT FIRE ON — a negation carrying any content word, which is
1098
+ * what keeps a conversational aside from costing the user their authority.
1099
+ * Measured against the council's boundary set:
1100
+ *
1101
+ * "Merge #12? Actually, I don't think so." false — "think"/"so" are content
1102
+ * "Merge #12? Don't worry, I'll do it." false — "worry" is content
1103
+ * "Actually, don't worry about it." false — same
1104
+ * "Merge #12? Actually, don't." TRUE — the clause is only "don't"
1105
+ * "Merge #12. Don't." TRUE — a retraction one sentence later
1106
+ * "Merge #12? , ; ." false — no tokens at all
1107
+ */
1108
+ /** A word token, apostrophes included, so `don't` stays ONE token. */
1109
+ const WORD_TOKEN = new RegExp(`[\\p{L}\\p{N}${APOSTROPHE}]+`, "gu");
1110
+
1111
+ /** Clause boundaries, built from the one contrast vocabulary above. */
1112
+ const CLAUSE_SPLIT = new RegExp(`[,;:]|\\b(?:${CONTRAST_ALTERNATION})\\b`, "iu");
1113
+
1114
+ export function isBareRefusal(text: string): boolean {
1115
+ for (const sentence of _sentences(text)) {
1116
+ for (const clause of sentence.split(CLAUSE_SPLIT)) {
1117
+ const tokens = (clause ?? "").match(WORD_TOKEN) ?? [];
1118
+ if (tokens.length > 0 && tokens.every((t) => NEGATION_TOKEN.test(t))) {
1119
+ return true;
1120
+ }
1121
+ }
1122
+ }
1123
+ return false;
1124
+ }
1125
+
929
1126
  /** Classify which ops a prompt authorizes. Exported for direct testing. */
930
1127
  export function classifyAuthorization(prompt: string): {
931
1128
  authorized: GitOp[];
@@ -1145,6 +1342,7 @@ export function takePending(
1145
1342
  * file for the discriminator and the captured evidence behind it.
1146
1343
  */
1147
1344
  export { humanTypedThisTurn } from "./_lib/machine_wake.js";
1345
+ export { extractObjects, OBJECT_REQUIRED_OPS } from "./_lib/consequence_objects.js";
1148
1346
 
1149
1347
  export function run(stdin_text: string, options: { consumer_root: string }): number {
1150
1348
  let envelope: JsonObject = {};
@@ -1196,6 +1394,17 @@ export function run(stdin_text: string, options: { consumer_root: string }): num
1196
1394
  `"${prompt.trim().slice(0, 40)}"`;
1197
1395
  }
1198
1396
 
1397
+ // The objects the prose named, per authorized operation. Recorded for every
1398
+ // consequence op that names one; `OBJECT_REQUIRED_OPS` is the subset whose
1399
+ // ABSENCE the conformance count reads as a finding, and that reading lives in
1400
+ // the scan rather than here — this side records what was said, and never
1401
+ // decides what it permits.
1402
+ const objects: { [op: string]: string[] } = {};
1403
+ for (const op of authorized) {
1404
+ const named = extractObjects(op, prompt);
1405
+ if (named.length > 0) objects[op] = named;
1406
+ }
1407
+
1199
1408
  const now = new Date();
1200
1409
  const ledger: Ledger = {
1201
1410
  session_id: typeof envelope["session_id"] === "string" ? envelope["session_id"] : "",
@@ -1203,6 +1412,7 @@ export function run(stdin_text: string, options: { consumer_root: string }): num
1203
1412
  authorized,
1204
1413
  evidence,
1205
1414
  prompt_chars: prompt.length,
1415
+ objects,
1206
1416
  // Grants survive this write; `authorized` does not. That asymmetry IS the
1207
1417
  // decision. A bare operation name stays one-shot exactly as `commit-policy`
1208
1418
  // requires, and only an authorization that also froze its objects earns a
@@ -1 +1 @@
1
- {"fingerprint":"877cc83a:82357","manifest":{"schema_version":1,"concerns":{"chat-history":{"script":"src/scripts/chat_history.ts","args":["hook-dispatch"],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["result"]},"hot-context":{"script":"src/scripts/hot_context_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"handoff-context":{"script":"src/scripts/handoff_context_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"roadmap-progress":{"script":"src/scripts/roadmap_progress_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input"]},"onboarding-gate":{"script":"src/scripts/onboarding_gate_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"context-hygiene":{"script":"src/scripts/context_hygiene_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"verify-before-complete":{"script":"src/scripts/before_complete_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input","result"]},"ship-diff-volume":{"script":"src/scripts/hooks/ship_diff_volume_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input"]},"minimal-safe-diff":{"script":"src/scripts/minimal_safe_diff_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input"]},"injection-scan":{"script":"src/scripts/injection_scan_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input","result"]},"block-no-verify":{"script":"src/scripts/hooks/block_no_verify.ts","args":[],"fail_closed":true,"severity":"blocking","needs_payload_bodies":["input"]},"block-kernel-rule-writes":{"script":"src/scripts/hooks/block_kernel_rule_writes.ts","args":[],"fail_closed":true,"severity":"blocking","needs_payload_bodies":["input"]},"block-speaking-inbox-dir":{"script":"src/scripts/hooks/block_speaking_inbox_dir.ts","args":[],"fail_closed":false,"severity":"blocking","needs_payload_bodies":["input"]},"block-config-weakening":{"script":"src/scripts/hooks/block_config_weakening.ts","args":[],"fail_closed":false,"severity":"blocking","needs_payload_bodies":["input"]},"rtk-wrap":{"script":"src/scripts/hooks/rtk_wrap_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input"]},"design-slop":{"script":"src/scripts/hooks/design_slop_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input"]},"design-pass":{"script":"src/scripts/hooks/design_pass_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input"]},"design-pass-stop":{"script":"src/scripts/hooks/design_pass_hook.ts","args":["--slot","stop"],"fail_closed":false,"severity":"advisory"},"ui-route-nudge":{"script":"src/scripts/hooks/ui_route_nudge_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input"]},"suggestion-capture":{"script":"src/scripts/hooks/suggestion_capture_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"code-graph-nudge":{"script":"src/scripts/hooks/code_graph_nudge_hook.ts","args":[],"fail_closed":false,"severity":"advisory","tools":["Grep","Glob","Read"],"needs_payload_bodies":["input"]},"memory-learn":{"script":"src/scripts/memory_learn_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"first-run-gate":{"script":"src/scripts/first_run_gate_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"profile-staleness":{"script":"src/scripts/profile_staleness_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"wrapper-freshness":{"script":"src/scripts/wrapper_freshness_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"surface-probe":{"script":"src/scripts/surface_probe_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"team-review-gate":{"script":"src/scripts/team_review_gate_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"pr-url-reminder":{"script":"src/scripts/pr_url_reminder_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input","result"]},"language-mirror":{"script":"src/scripts/language_mirror_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"git-authorization":{"script":"src/scripts/git_authorization_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"block-unauthorized-git":{"script":"src/scripts/hooks/block_unauthorized_git.ts","args":[],"fail_closed":true,"severity":"blocking","needs_payload_bodies":["input"]},"evidence-independence":{"script":"src/scripts/hooks/evidence_independence.ts","args":[],"fail_closed":false,"severity":"blocking","needs_payload_bodies":["input"]},"session-canary":{"script":"src/scripts/session_canary_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"council-availability":{"script":"src/scripts/council_availability_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"telemetry-disclosure":{"script":"src/scripts/telemetry_disclosure_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"telemetry-flush":{"script":"src/scripts/hooks/telemetry_flush_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"self-repair":{"script":"src/scripts/self_repair_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"session-register":{"script":"src/scripts/session_register_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"orchestration-record":{"script":"src/scripts/hooks/orchestration_record_hook.ts","args":[],"fail_closed":false,"severity":"advisory","tools":["Agent","Task"],"needs_payload_bodies":["input","result"]},"telemetry-usage":{"script":"src/scripts/hooks/telemetry_usage_hook.ts","args":[],"fail_closed":false,"severity":"advisory","tools":["Skill"],"needs_payload_bodies":["input"]},"delegation-nudge":{"script":"src/scripts/hooks/delegation_nudge_hook.ts","args":[],"fail_closed":false,"severity":"advisory","nudge_rank":1},"skill-route":{"script":"src/scripts/hooks/skill_route_hook.ts","args":[],"fail_closed":false,"severity":"advisory","nudge_rank":2},"rule-inject":{"script":"src/scripts/hooks/rule_inject_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input"]},"end-review-nudge":{"script":"src/scripts/hooks/end_review_nudge_hook.ts","args":[],"fail_closed":false,"severity":"advisory","skip_on_refusal_retry":true},"turn-end-gate":{"script":"src/scripts/hooks/turn_end_gate_hook.ts","args":[],"fail_closed":false,"severity":"blocking"},"comment-discipline":{"script":"src/scripts/hooks/comment_discipline_hook.ts","args":[],"fail_closed":false,"severity":"advisory","tools":["Write","Edit"],"needs_payload_bodies":["input"]},"edit-shape":{"script":"src/scripts/hooks/edit_shape_hook.ts","args":[],"fail_closed":false,"severity":"advisory","tools":["Write"],"needs_payload_bodies":["input"]},"reread-guard":{"script":"src/scripts/hooks/reread_guard_hook.ts","args":[],"fail_closed":false,"severity":"advisory","tools":["Read","Edit","Write"],"needs_payload_bodies":["input"]},"session-eol":{"script":"src/scripts/hooks/session_eol_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"run-continuation":{"script":"src/scripts/hooks/run_continuation_hook.ts","args":[],"fail_closed":false,"severity":"blocking"},"interruption-ledger":{"script":"src/scripts/hooks/interruption_ledger_hook.ts","args":[],"fail_closed":false,"severity":"advisory","skip_on_refusal_retry":true},"subagent-ledger":{"script":"src/scripts/hooks/subagent_ledger_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"tool-result-bytes":{"script":"src/scripts/hooks/tool_result_bytes_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"spawn-guard-shadow":{"script":"src/scripts/hooks/spawn_guard_shadow_hook.ts","args":[],"fail_closed":false,"severity":"advisory","tools":["Agent","Task"]},"source-first-gate":{"script":"src/scripts/hooks/source_first_gate_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input"]},"journal-record":{"script":"src/scripts/hooks/journal_record_hook.ts","args":[],"fail_closed":false,"severity":"advisory"}},"roles":{"worker":{"drop":["delegation-nudge","skill-route","end-review-nudge","council-availability","team-review-gate","self-repair","session-eol","interruption-ledger"]}},"platforms":{"augment":{"session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","minimal-safe-diff","profile-staleness","wrapper-freshness","surface-probe","session-register"],"session_end":["chat-history","memory-learn","session-register","roadmap-progress","telemetry-flush"],"stop":["chat-history","hot-context","verify-before-complete","self-repair","session-register","roadmap-progress","design-pass-stop"],"pre_tool_use":["block-no-verify","block-unauthorized-git","evidence-independence","block-kernel-rule-writes","block-config-weakening","block-speaking-inbox-dir","rtk-wrap","design-slop","ui-route-nudge","code-graph-nudge","ship-diff-volume","reread-guard"],"post_tool_use":["chat-history","roadmap-progress","context-hygiene","verify-before-complete","minimal-safe-diff","injection-scan","pr-url-reminder","orchestration-record","telemetry-usage","tool-result-bytes","edit-shape","comment-discipline","design-pass"]},"claude":{"session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","minimal-safe-diff","profile-staleness","wrapper-freshness","surface-probe","session-register","journal-record"],"session_end":["chat-history","memory-learn","session-register","roadmap-progress","telemetry-flush","journal-record"],"stop":["chat-history","hot-context","verify-before-complete","team-review-gate","end-review-nudge","turn-end-gate","self-repair","session-register","session-eol","interruption-ledger","roadmap-progress","design-pass-stop","suggestion-capture","journal-record","run-continuation"],"user_prompt_submit":["chat-history","verify-before-complete","minimal-safe-diff","language-mirror","delegation-nudge","skill-route","git-authorization","session-canary","self-repair","session-register","rule-inject","suggestion-capture","journal-record"],"pre_tool_use":["block-no-verify","block-unauthorized-git","evidence-independence","block-kernel-rule-writes","block-config-weakening","block-speaking-inbox-dir","rtk-wrap","design-slop","ui-route-nudge","code-graph-nudge","ship-diff-volume","reread-guard","spawn-guard-shadow","source-first-gate","rule-inject"],"post_tool_use":["chat-history","roadmap-progress","context-hygiene","verify-before-complete","minimal-safe-diff","injection-scan","pr-url-reminder","orchestration-record","telemetry-usage","tool-result-bytes","edit-shape","comment-discipline","language-mirror","design-pass","journal-record"],"pre_compact":["language-mirror","hot-context","rule-inject","journal-record"],"subagent_start":["subagent-ledger","journal-record"],"subagent_stop":["subagent-ledger","journal-record"]},"cowork":{"session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","minimal-safe-diff","profile-staleness","wrapper-freshness","surface-probe","session-register"],"session_end":["chat-history","memory-learn","session-register","roadmap-progress","telemetry-flush"],"stop":["chat-history","hot-context","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","block-unauthorized-git","evidence-independence","block-kernel-rule-writes","block-config-weakening","block-speaking-inbox-dir","rtk-wrap","design-slop","ui-route-nudge","code-graph-nudge","ship-diff-volume","reread-guard","spawn-guard-shadow","source-first-gate"],"post_tool_use":["chat-history","roadmap-progress","context-hygiene","verify-before-complete","minimal-safe-diff","injection-scan","pr-url-reminder","orchestration-record","telemetry-usage","tool-result-bytes","edit-shape","comment-discipline","design-pass"],"subagent_start":["subagent-ledger"],"subagent_stop":["subagent-ledger"]},"cursor":{"session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","minimal-safe-diff","profile-staleness","wrapper-freshness","surface-probe","session-register"],"session_end":["chat-history","memory-learn","session-register","roadmap-progress","telemetry-flush"],"stop":["chat-history","hot-context","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","orchestration-record","telemetry-usage","tool-result-bytes","edit-shape","comment-discipline","design-pass"]},"cline":{"session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","minimal-safe-diff","profile-staleness","wrapper-freshness","surface-probe","session-register"],"session_end":["chat-history","memory-learn","session-register","roadmap-progress","telemetry-flush"],"stop":["chat-history","hot-context","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","orchestration-record","telemetry-usage","tool-result-bytes","edit-shape","comment-discipline","design-pass"]},"windsurf":{"session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","profile-staleness","wrapper-freshness","surface-probe","session-register"],"stop":["chat-history","hot-context","verify-before-complete","self-repair","session-register","design-pass-stop"],"user_prompt_submit":["chat-history","verify-before-complete","language-mirror","git-authorization","session-canary","self-repair","session-register"]},"gemini":{"session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","minimal-safe-diff","profile-staleness","wrapper-freshness","surface-probe","session-register"],"session_end":["chat-history","memory-learn","session-register","roadmap-progress","telemetry-flush"],"stop":["chat-history","hot-context","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","orchestration-record","telemetry-usage","tool-result-bytes","edit-shape","comment-discipline","design-pass"]},"copilot":{"fallback_only":true}},"native_event_aliases":{"augment":{"SessionStart":"session_start","SessionEnd":"session_end","Stop":"stop","PostToolUse":"post_tool_use","PreToolUse":"pre_tool_use"},"claude":{"SessionStart":"session_start","SessionEnd":"session_end","Stop":"stop","UserPromptSubmit":"user_prompt_submit","PostToolUse":"post_tool_use","PreToolUse":"pre_tool_use","PreCompact":"pre_compact","SubagentStart":"subagent_start","SubagentStop":"subagent_stop"},"cowork":{"SessionStart":"session_start","SessionEnd":"session_end","Stop":"stop","UserPromptSubmit":"user_prompt_submit","PostToolUse":"post_tool_use","PreToolUse":"pre_tool_use","PreCompact":"pre_compact","SubagentStart":"subagent_start","SubagentStop":"subagent_stop"},"cursor":{"sessionStart":"session_start","sessionEnd":"session_end","stop":"stop","beforeSubmitPrompt":"user_prompt_submit","postToolUse":"post_tool_use","preToolUse":"pre_tool_use","preCompact":"pre_compact"},"cline":{"TaskStart":"session_start","TaskResume":"session_start","TaskComplete":"session_end","TaskCancel":"stop","UserPromptSubmit":"user_prompt_submit","PostToolUse":"post_tool_use","PreToolUse":"pre_tool_use","PreCompact":"pre_compact"},"windsurf":{"pre_user_prompt":"user_prompt_submit","post_cascade_response":"stop","post_setup_worktree":"session_start"},"gemini":{"SessionStart":"session_start","SessionEnd":"session_end","BeforeAgent":"user_prompt_submit","AfterAgent":"stop","BeforeTool":"pre_tool_use","AfterTool":"post_tool_use"}}}}
1
+ {"fingerprint":"8ca65564:83643","manifest":{"schema_version":1,"concerns":{"chat-history":{"script":"src/scripts/chat_history.ts","args":["hook-dispatch"],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["result"]},"hot-context":{"script":"src/scripts/hot_context_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"handoff-context":{"script":"src/scripts/handoff_context_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"roadmap-progress":{"script":"src/scripts/roadmap_progress_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input"]},"onboarding-gate":{"script":"src/scripts/onboarding_gate_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"context-hygiene":{"script":"src/scripts/context_hygiene_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"verify-before-complete":{"script":"src/scripts/before_complete_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input","result"]},"ship-diff-volume":{"script":"src/scripts/hooks/ship_diff_volume_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input"]},"minimal-safe-diff":{"script":"src/scripts/minimal_safe_diff_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input"]},"injection-scan":{"script":"src/scripts/injection_scan_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input","result"]},"block-no-verify":{"script":"src/scripts/hooks/block_no_verify.ts","args":[],"fail_closed":true,"severity":"blocking","needs_payload_bodies":["input"]},"block-kernel-rule-writes":{"script":"src/scripts/hooks/block_kernel_rule_writes.ts","args":[],"fail_closed":true,"severity":"blocking","needs_payload_bodies":["input"]},"block-speaking-inbox-dir":{"script":"src/scripts/hooks/block_speaking_inbox_dir.ts","args":[],"fail_closed":false,"severity":"blocking","needs_payload_bodies":["input"]},"block-config-weakening":{"script":"src/scripts/hooks/block_config_weakening.ts","args":[],"fail_closed":false,"severity":"blocking","needs_payload_bodies":["input"]},"rtk-wrap":{"script":"src/scripts/hooks/rtk_wrap_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input"]},"design-slop":{"script":"src/scripts/hooks/design_slop_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input"]},"design-pass":{"script":"src/scripts/hooks/design_pass_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input"]},"design-pass-stop":{"script":"src/scripts/hooks/design_pass_hook.ts","args":["--slot","stop"],"fail_closed":false,"severity":"advisory"},"ui-route-nudge":{"script":"src/scripts/hooks/ui_route_nudge_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input"]},"suggestion-capture":{"script":"src/scripts/hooks/suggestion_capture_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"code-graph-nudge":{"script":"src/scripts/hooks/code_graph_nudge_hook.ts","args":[],"fail_closed":false,"severity":"advisory","tools":["Grep","Glob","Read"],"needs_payload_bodies":["input"]},"memory-learn":{"script":"src/scripts/memory_learn_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"first-run-gate":{"script":"src/scripts/first_run_gate_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"profile-staleness":{"script":"src/scripts/profile_staleness_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"wrapper-freshness":{"script":"src/scripts/wrapper_freshness_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"surface-probe":{"script":"src/scripts/surface_probe_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"team-review-gate":{"script":"src/scripts/team_review_gate_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"pr-url-reminder":{"script":"src/scripts/pr_url_reminder_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input","result"]},"push-settle":{"script":"src/scripts/hooks/push_settle_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input","result"]},"language-mirror":{"script":"src/scripts/language_mirror_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"git-authorization":{"script":"src/scripts/git_authorization_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"evidence-independence":{"script":"src/scripts/hooks/evidence_independence.ts","args":[],"fail_closed":false,"severity":"blocking","needs_payload_bodies":["input"]},"session-canary":{"script":"src/scripts/session_canary_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"council-availability":{"script":"src/scripts/council_availability_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"telemetry-disclosure":{"script":"src/scripts/telemetry_disclosure_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"telemetry-flush":{"script":"src/scripts/hooks/telemetry_flush_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"self-repair":{"script":"src/scripts/self_repair_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"session-register":{"script":"src/scripts/session_register_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"orchestration-record":{"script":"src/scripts/hooks/orchestration_record_hook.ts","args":[],"fail_closed":false,"severity":"advisory","tools":["Agent","Task"],"needs_payload_bodies":["input","result"]},"telemetry-usage":{"script":"src/scripts/hooks/telemetry_usage_hook.ts","args":[],"fail_closed":false,"severity":"advisory","tools":["Skill"],"needs_payload_bodies":["input"]},"delegation-nudge":{"script":"src/scripts/hooks/delegation_nudge_hook.ts","args":[],"fail_closed":false,"severity":"advisory","nudge_rank":1},"skill-route":{"script":"src/scripts/hooks/skill_route_hook.ts","args":[],"fail_closed":false,"severity":"advisory","nudge_rank":2},"rule-inject":{"script":"src/scripts/hooks/rule_inject_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input"]},"end-review-nudge":{"script":"src/scripts/hooks/end_review_nudge_hook.ts","args":[],"fail_closed":false,"severity":"advisory","skip_on_refusal_retry":true},"turn-end-gate":{"script":"src/scripts/hooks/turn_end_gate_hook.ts","args":[],"fail_closed":false,"severity":"blocking"},"comment-discipline":{"script":"src/scripts/hooks/comment_discipline_hook.ts","args":[],"fail_closed":false,"severity":"advisory","tools":["Write","Edit"],"needs_payload_bodies":["input"]},"edit-shape":{"script":"src/scripts/hooks/edit_shape_hook.ts","args":[],"fail_closed":false,"severity":"advisory","tools":["Write"],"needs_payload_bodies":["input"]},"reread-guard":{"script":"src/scripts/hooks/reread_guard_hook.ts","args":[],"fail_closed":false,"severity":"advisory","tools":["Read","Edit","Write"],"needs_payload_bodies":["input"]},"session-eol":{"script":"src/scripts/hooks/session_eol_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"run-continuation":{"script":"src/scripts/hooks/run_continuation_hook.ts","args":[],"fail_closed":false,"severity":"blocking"},"interruption-ledger":{"script":"src/scripts/hooks/interruption_ledger_hook.ts","args":[],"fail_closed":false,"severity":"advisory","skip_on_refusal_retry":true},"subagent-ledger":{"script":"src/scripts/hooks/subagent_ledger_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"tool-result-bytes":{"script":"src/scripts/hooks/tool_result_bytes_hook.ts","args":[],"fail_closed":false,"severity":"advisory"},"spawn-guard-shadow":{"script":"src/scripts/hooks/spawn_guard_shadow_hook.ts","args":[],"fail_closed":false,"severity":"advisory","tools":["Agent","Task"]},"source-first-gate":{"script":"src/scripts/hooks/source_first_gate_hook.ts","args":[],"fail_closed":false,"severity":"advisory","needs_payload_bodies":["input"]},"journal-record":{"script":"src/scripts/hooks/journal_record_hook.ts","args":[],"fail_closed":false,"severity":"advisory"}},"roles":{"worker":{"drop":["delegation-nudge","skill-route","end-review-nudge","council-availability","team-review-gate","self-repair","session-eol","interruption-ledger"]}},"platforms":{"augment":{"session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","minimal-safe-diff","profile-staleness","wrapper-freshness","surface-probe","session-register"],"session_end":["chat-history","memory-learn","session-register","roadmap-progress","telemetry-flush"],"stop":["chat-history","hot-context","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-config-weakening","block-speaking-inbox-dir","rtk-wrap","design-slop","ui-route-nudge","code-graph-nudge","ship-diff-volume","reread-guard"],"post_tool_use":["chat-history","roadmap-progress","context-hygiene","verify-before-complete","minimal-safe-diff","injection-scan","pr-url-reminder","push-settle","orchestration-record","telemetry-usage","tool-result-bytes","edit-shape","comment-discipline","design-pass"]},"claude":{"session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","minimal-safe-diff","profile-staleness","wrapper-freshness","surface-probe","session-register","journal-record"],"session_end":["chat-history","memory-learn","session-register","roadmap-progress","telemetry-flush","journal-record"],"stop":["chat-history","hot-context","verify-before-complete","team-review-gate","end-review-nudge","turn-end-gate","self-repair","session-register","session-eol","interruption-ledger","roadmap-progress","design-pass-stop","suggestion-capture","journal-record","run-continuation"],"user_prompt_submit":["chat-history","verify-before-complete","minimal-safe-diff","language-mirror","delegation-nudge","skill-route","git-authorization","session-canary","self-repair","session-register","rule-inject","suggestion-capture","journal-record"],"pre_tool_use":["block-no-verify","evidence-independence","block-kernel-rule-writes","block-config-weakening","block-speaking-inbox-dir","rtk-wrap","design-slop","ui-route-nudge","code-graph-nudge","ship-diff-volume","reread-guard","spawn-guard-shadow","source-first-gate","rule-inject"],"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","tool-result-bytes","edit-shape","comment-discipline","language-mirror","design-pass","journal-record"],"pre_compact":["language-mirror","hot-context","rule-inject","journal-record"],"subagent_start":["subagent-ledger","journal-record"],"subagent_stop":["subagent-ledger","journal-record"]},"cowork":{"session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","minimal-safe-diff","profile-staleness","wrapper-freshness","surface-probe","session-register"],"session_end":["chat-history","memory-learn","session-register","roadmap-progress","telemetry-flush"],"stop":["chat-history","hot-context","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-config-weakening","block-speaking-inbox-dir","rtk-wrap","design-slop","ui-route-nudge","code-graph-nudge","ship-diff-volume","reread-guard","spawn-guard-shadow","source-first-gate"],"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","tool-result-bytes","edit-shape","comment-discipline","design-pass"],"subagent_start":["subagent-ledger"],"subagent_stop":["subagent-ledger"]},"cursor":{"session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","minimal-safe-diff","profile-staleness","wrapper-freshness","surface-probe","session-register"],"session_end":["chat-history","memory-learn","session-register","roadmap-progress","telemetry-flush"],"stop":["chat-history","hot-context","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","tool-result-bytes","edit-shape","comment-discipline","design-pass"]},"cline":{"session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","minimal-safe-diff","profile-staleness","wrapper-freshness","surface-probe","session-register"],"session_end":["chat-history","memory-learn","session-register","roadmap-progress","telemetry-flush"],"stop":["chat-history","hot-context","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","tool-result-bytes","edit-shape","comment-discipline","design-pass"]},"windsurf":{"session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","profile-staleness","wrapper-freshness","surface-probe","session-register"],"stop":["chat-history","hot-context","verify-before-complete","self-repair","session-register","design-pass-stop"],"user_prompt_submit":["chat-history","verify-before-complete","language-mirror","git-authorization","session-canary","self-repair","session-register"]},"gemini":{"session_start":["chat-history","hot-context","handoff-context","session-canary","council-availability","telemetry-disclosure","first-run-gate","onboarding-gate","verify-before-complete","minimal-safe-diff","profile-staleness","wrapper-freshness","surface-probe","session-register"],"session_end":["chat-history","memory-learn","session-register","roadmap-progress","telemetry-flush"],"stop":["chat-history","hot-context","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","tool-result-bytes","edit-shape","comment-discipline","design-pass"]},"copilot":{"fallback_only":true}},"native_event_aliases":{"augment":{"SessionStart":"session_start","SessionEnd":"session_end","Stop":"stop","PostToolUse":"post_tool_use","PreToolUse":"pre_tool_use"},"claude":{"SessionStart":"session_start","SessionEnd":"session_end","Stop":"stop","UserPromptSubmit":"user_prompt_submit","PostToolUse":"post_tool_use","PreToolUse":"pre_tool_use","PreCompact":"pre_compact","SubagentStart":"subagent_start","SubagentStop":"subagent_stop"},"cowork":{"SessionStart":"session_start","SessionEnd":"session_end","Stop":"stop","UserPromptSubmit":"user_prompt_submit","PostToolUse":"post_tool_use","PreToolUse":"pre_tool_use","PreCompact":"pre_compact","SubagentStart":"subagent_start","SubagentStop":"subagent_stop"},"cursor":{"sessionStart":"session_start","sessionEnd":"session_end","stop":"stop","beforeSubmitPrompt":"user_prompt_submit","postToolUse":"post_tool_use","preToolUse":"pre_tool_use","preCompact":"pre_compact"},"cline":{"TaskStart":"session_start","TaskResume":"session_start","TaskComplete":"session_end","TaskCancel":"stop","UserPromptSubmit":"user_prompt_submit","PostToolUse":"post_tool_use","PreToolUse":"pre_tool_use","PreCompact":"pre_compact"},"windsurf":{"pre_user_prompt":"user_prompt_submit","post_cascade_response":"stop","post_setup_worktree":"session_start"},"gemini":{"SessionStart":"session_start","SessionEnd":"session_end","BeforeAgent":"user_prompt_submit","AfterAgent":"stop","BeforeTool":"pre_tool_use","AfterTool":"post_tool_use"}}}}
@@ -1,8 +1,8 @@
1
1
  # Hook manifest — single source of truth for which concerns fire on which
2
2
  # (platform, event) tuples. Consumed by:
3
- # - scripts/hooks/dispatch_hook.py (runtime resolver)
4
- # - scripts/lint_hook_manifest.py (CI gate; Phase 7.10)
5
- # - scripts/install.py (per-platform config writer)
3
+ # - src/scripts/hooks/dispatch_hook.ts (runtime resolver)
4
+ # - src/scripts/lint_hook_manifest.ts (CI gate; Phase 7.10)
5
+ # - src/scripts/install.ts (per-platform config writer)
6
6
  #
7
7
  # Schema and event vocabulary: docs/contracts/hook-architecture-v1.md.
8
8
  # Per-platform event-name mapping: agents/settings/contexts/chat-history-platform-hooks.md.
@@ -453,6 +453,21 @@ concerns:
453
453
  fail_closed: false
454
454
  severity: advisory
455
455
  needs_payload_bodies: [input, result]
456
+ # Push-settle reminder — the second half of "a push closes its own loop".
457
+ # The pre-push hook answers "is this push safe to make"; nothing answered "is
458
+ # this push finished". Measured over the 30 sessions / 50 PRs before
459
+ # 2026-09-04: 22 of 30 sessions ran `gh run view --log-failed`, 17 of 36
460
+ # readable PRs carried a failed run, and 20 of 50 PRs carried a follow-up
461
+ # `fix(ci|gates|budget)` commit. Every one of those pushes SUCCEEDED — what
462
+ # failed was the ending. Fires only when git's own report shows a ref actually
463
+ # ADVANCED (silent on up-to-date, rejected, dry-run, delete), so it cannot nag
464
+ # on a push that did not happen. Warn only. fail_closed: false.
465
+ push-settle:
466
+ script: src/scripts/hooks/push_settle_hook.ts
467
+ args: []
468
+ fail_closed: false
469
+ severity: advisory
470
+ needs_payload_bodies: [input, result]
456
471
  # Language-mirror pin — carries the ONE fact the transcript cannot express:
457
472
  # which language the human actually typed. 47 skill/slash-command bodies were
458
473
  # measured arriving in the `user` role across 21 of 30 audited sessions, and
@@ -472,16 +487,15 @@ concerns:
472
487
  args: []
473
488
  fail_closed: false
474
489
  severity: advisory
475
- # The blocking half. BLOCKS only the irreversible subset that
476
- # non-destructive-by-default already declares never-autonomous (npm publish,
477
- # tag push, gh release create, gh pr merge); WARNS on commit / push /
478
- # pr-create / branch. Severity, not reach — see the header of the script.
479
- block-unauthorized-git:
480
- script: src/scripts/hooks/block_unauthorized_git.ts
481
- args: []
482
- fail_closed: true
483
- severity: blocking
484
- needs_payload_bodies: [input]
490
+ # The blocking half was REMOVED by owner decision on 2026-09-04 (ADR-254).
491
+ # It refused authorizations the owner had in fact given: a guardrail sentence
492
+ # inside an authorization ("never merge empty PRs") read as a withdrawal and
493
+ # erased the ledger, and an answer given as an option number matched no
494
+ # authorizing pattern at all. `git-authorization` above still RECORDS what a
495
+ # turn authorized — `evidence_independence` reads its ledger as a per-turn
496
+ # stamp — and the command parser survives as `hooks/git_command_classifier.ts`
497
+ # for `block_no_verify` and `conformance_scan`. Nothing enforces git
498
+ # authorization any more; `non-destructive-by-default` is model-carried here.
485
499
  # Evaluator independence. Gates EVALUATION dispatches only. Two branches with
486
500
  # DIFFERENT severities, per the tier rule in
487
501
  # docs/contracts/hook-architecture-v1.md (§ What a concern may block on):
@@ -612,8 +626,9 @@ concerns:
612
626
  #
613
627
  # Correctness rests on heartbeat + TTL alone; deregistration only frees a claim
614
628
  # sooner. So Windsurf's missing session_end costs latency, not correctness.
615
- # Declared non-carriers: copilot (no hook surface), cursor CLI (per-turn slots
616
- # are IDE-only), cowork (slots wired, lifecycle events inert) — a session there
629
+ # Declared non-carriers: copilot (this package binds nothing there and has
630
+ # measured nothing there), cursor (per-turn reachability unestablished), cowork
631
+ # (slots wired, lifecycle events inert) — a session there
617
632
  # registers but expires by TTL rather than heartbeating, and the concern says so
618
633
  # on stderr rather than letting the coverage join read green.
619
634
  # Never blocks. fail_closed: false.
@@ -1166,16 +1181,16 @@ platforms:
1166
1181
  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]
1167
1182
  session_end: [chat-history, memory-learn, session-register, roadmap-progress, telemetry-flush]
1168
1183
  stop: [chat-history, hot-context, verify-before-complete, self-repair, session-register, roadmap-progress, design-pass-stop]
1169
- pre_tool_use: [block-no-verify, block-unauthorized-git, evidence-independence, block-kernel-rule-writes, block-config-weakening, block-speaking-inbox-dir, rtk-wrap, design-slop, ui-route-nudge, code-graph-nudge, ship-diff-volume, reread-guard]
1170
- post_tool_use: [chat-history, roadmap-progress, context-hygiene, verify-before-complete, minimal-safe-diff, injection-scan, pr-url-reminder, orchestration-record, telemetry-usage, tool-result-bytes, edit-shape, comment-discipline, design-pass]
1184
+ pre_tool_use: [block-no-verify, evidence-independence, block-kernel-rule-writes, block-config-weakening, block-speaking-inbox-dir, rtk-wrap, design-slop, ui-route-nudge, code-graph-nudge, ship-diff-volume, reread-guard]
1185
+ 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, tool-result-bytes, edit-shape, comment-discipline, design-pass]
1171
1186
 
1172
1187
  claude:
1173
1188
  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, journal-record]
1174
1189
  session_end: [chat-history, memory-learn, session-register, roadmap-progress, telemetry-flush, journal-record]
1175
1190
  stop: [chat-history, hot-context, verify-before-complete, team-review-gate, end-review-nudge, turn-end-gate, self-repair, session-register, session-eol, interruption-ledger, roadmap-progress, design-pass-stop, suggestion-capture, journal-record, run-continuation]
1176
1191
  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]
1177
- pre_tool_use: [block-no-verify, block-unauthorized-git, evidence-independence, block-kernel-rule-writes, block-config-weakening, block-speaking-inbox-dir, rtk-wrap, design-slop, ui-route-nudge, code-graph-nudge, ship-diff-volume, reread-guard, spawn-guard-shadow, source-first-gate, rule-inject]
1178
- post_tool_use: [chat-history, roadmap-progress, context-hygiene, verify-before-complete, minimal-safe-diff, injection-scan, pr-url-reminder, orchestration-record, telemetry-usage, tool-result-bytes, edit-shape, comment-discipline, language-mirror, design-pass, journal-record]
1192
+ pre_tool_use: [block-no-verify, evidence-independence, block-kernel-rule-writes, block-config-weakening, block-speaking-inbox-dir, rtk-wrap, design-slop, ui-route-nudge, code-graph-nudge, ship-diff-volume, reread-guard, spawn-guard-shadow, source-first-gate, rule-inject]
1193
+ 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, tool-result-bytes, edit-shape, comment-discipline, language-mirror, design-pass, journal-record]
1179
1194
  # `language-mirror` — round-5 § 6.1. `pre_compact` sets a pin-lost marker;
1180
1195
  # the `post_tool_use` entry above re-emits the pin exactly once while that
1181
1196
  # marker is set, then clears it. One extra injection per compaction EVENT —
@@ -1228,8 +1243,8 @@ platforms:
1228
1243
  # still costs the dispatch, and its entire output is thrown away.
1229
1244
  stop: [chat-history, hot-context, verify-before-complete, self-repair, session-register, roadmap-progress, design-pass-stop]
1230
1245
  user_prompt_submit: [chat-history, verify-before-complete, minimal-safe-diff, language-mirror, git-authorization, session-canary, self-repair, session-register]
1231
- pre_tool_use: [block-no-verify, block-unauthorized-git, evidence-independence, block-kernel-rule-writes, block-config-weakening, block-speaking-inbox-dir, rtk-wrap, design-slop, ui-route-nudge, code-graph-nudge, ship-diff-volume, reread-guard, spawn-guard-shadow, source-first-gate]
1232
- post_tool_use: [chat-history, roadmap-progress, context-hygiene, verify-before-complete, minimal-safe-diff, injection-scan, pr-url-reminder, orchestration-record, telemetry-usage, tool-result-bytes, edit-shape, comment-discipline, design-pass]
1246
+ pre_tool_use: [block-no-verify, evidence-independence, block-kernel-rule-writes, block-config-weakening, block-speaking-inbox-dir, rtk-wrap, design-slop, ui-route-nudge, code-graph-nudge, ship-diff-volume, reread-guard, spawn-guard-shadow, source-first-gate]
1247
+ 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, tool-result-bytes, edit-shape, comment-discipline, design-pass]
1233
1248
  # subagent-ledger IS bound here, unlike the two nudges above, and the
1234
1249
  # difference is the delivery channel rather than the platform: the nudges
1235
1250
  # depend on stdout reaching the model, which this trampoline discards by
@@ -1242,17 +1257,18 @@ platforms:
1242
1257
 
1243
1258
  # Phase 7.5 — Cursor. `.cursor/hooks.json` (project) is read by the
1244
1259
  # IDE and CLI; `~/.cursor/hooks.json` (user) is opt-in via
1245
- # `install.py --cursor-user-hooks` and uses scripts/hooks/cursor-dispatcher.sh
1260
+ # `agent-config install --cursor-user-hooks` and uses scripts/hooks/cursor-dispatcher.sh
1246
1261
  # to route into the active workspace. UserPromptSubmit maps to
1247
- # `beforeSubmitPrompt` (Cursor third-party-hooks table). Stop is
1248
- # IDE-only — CLI-only users fall back to /checkpoint per
1249
- # agents/settings/contexts/chat-history-platform-hooks.md.
1262
+ # `beforeSubmitPrompt` (Cursor third-party-hooks table). Whether the CLI
1263
+ # surface fires `stop` is not established here; the /checkpoint fallback
1264
+ # covers a session where it does not. See
1265
+ # agents/settings/contexts/chat-history-platform-hooks.md § Cursor.
1250
1266
  cursor:
1251
1267
  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]
1252
1268
  session_end: [chat-history, memory-learn, session-register, roadmap-progress, telemetry-flush]
1253
1269
  stop: [chat-history, hot-context, verify-before-complete, self-repair, session-register, roadmap-progress, design-pass-stop]
1254
1270
  user_prompt_submit: [chat-history, verify-before-complete, minimal-safe-diff, language-mirror, git-authorization, session-canary, self-repair, session-register]
1255
- post_tool_use: [chat-history, roadmap-progress, context-hygiene, verify-before-complete, minimal-safe-diff, injection-scan, pr-url-reminder, orchestration-record, telemetry-usage, tool-result-bytes, edit-shape, comment-discipline, design-pass]
1271
+ 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, tool-result-bytes, edit-shape, comment-discipline, design-pass]
1256
1272
 
1257
1273
  # Phase 7.6 — Cline. Hooks live under `.clinerules/hooks/<HookName>`
1258
1274
  # (project, no file extension, must be executable per Cline docs) or
@@ -1267,7 +1283,7 @@ platforms:
1267
1283
  session_end: [chat-history, memory-learn, session-register, roadmap-progress, telemetry-flush]
1268
1284
  stop: [chat-history, hot-context, verify-before-complete, self-repair, session-register, roadmap-progress, design-pass-stop]
1269
1285
  user_prompt_submit: [chat-history, verify-before-complete, minimal-safe-diff, language-mirror, git-authorization, session-canary, self-repair, session-register]
1270
- post_tool_use: [chat-history, roadmap-progress, context-hygiene, verify-before-complete, minimal-safe-diff, injection-scan, pr-url-reminder, orchestration-record, telemetry-usage, tool-result-bytes, edit-shape, comment-discipline, design-pass]
1286
+ 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, tool-result-bytes, edit-shape, comment-discipline, design-pass]
1271
1287
 
1272
1288
  # Phase 7.7 — Windsurf (Cascade). Hooks live at `.windsurf/hooks.json`
1273
1289
  # (project) or `~/.codeium/windsurf/hooks.json` (user). Cascade has
@@ -1303,10 +1319,11 @@ platforms:
1303
1319
  session_end: [chat-history, memory-learn, session-register, roadmap-progress, telemetry-flush]
1304
1320
  stop: [chat-history, hot-context, verify-before-complete, self-repair, session-register, roadmap-progress, design-pass-stop]
1305
1321
  user_prompt_submit: [chat-history, verify-before-complete, minimal-safe-diff, language-mirror, git-authorization, session-canary, self-repair, session-register]
1306
- post_tool_use: [chat-history, roadmap-progress, context-hygiene, verify-before-complete, minimal-safe-diff, injection-scan, pr-url-reminder, orchestration-record, telemetry-usage, tool-result-bytes, edit-shape, comment-discipline, design-pass]
1322
+ 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, tool-result-bytes, edit-shape, comment-discipline, design-pass]
1307
1323
 
1308
- # Phase 7.9 — Copilot has no hook surface. Concerns route through
1309
- # rule-only fallback; the dispatcher silently no-ops on --platform copilot.
1324
+ # Phase 7.9 — this package binds no hook on Copilot and has measured none
1325
+ # there. Concerns route through rule-only fallback; the dispatcher silently
1326
+ # no-ops on --platform copilot.
1310
1327
  copilot:
1311
1328
  fallback_only: true
1312
1329