@event4u/agent-config 14.16.0 → 14.18.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 (93) 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 +177 -213
  5. package/README.md +2 -2
  6. package/dist/agent-src/commands/analyze/inbox.md +172 -6
  7. package/dist/agent-src/commands/fix/commit-messages.md +336 -0
  8. package/dist/agent-src/commands/fix.md +5 -3
  9. package/dist/agent-src/commands/pr/merge.md +35 -44
  10. package/dist/agent-src/rules/commit-conventions.md +1 -1
  11. package/dist/agent-src/skills/accessibility-auditor/SKILL.md +2 -0
  12. package/dist/agent-src/skills/ai-code-blindspots/SKILL.md +27 -1
  13. package/dist/agent-src/skills/aws-infrastructure/SKILL.md +41 -0
  14. package/dist/agent-src/skills/code-intelligence/SKILL.md +60 -12
  15. package/dist/agent-src/skills/complexity-first-planning/SKILL.md +27 -0
  16. package/dist/agent-src/skills/conventional-commits-writing/SKILL.md +234 -4
  17. package/dist/agent-src/skills/design-review/SKILL.md +2 -0
  18. package/dist/agent-src/skills/feature-planning/SKILL.md +34 -0
  19. package/dist/agent-src/skills/git-workflow/SKILL.md +37 -12
  20. package/dist/agent-src/skills/git-workflow/references/push-closes-its-loop.md +176 -0
  21. package/dist/agent-src/skills/laravel-mail/SKILL.md +44 -0
  22. package/dist/agent-src/skills/terraform/SKILL.md +29 -0
  23. package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +40 -0
  24. package/dist/agent-src/skills/threat-modeling/data/reasoning.csv +1 -0
  25. package/dist/agent-src/skills/threat-modeling/data/surfaces.csv +1 -0
  26. package/dist/agent-src/skills/threat-modeling/data/threats.csv +5 -0
  27. package/dist/agent-src/skills/using-git-worktrees/SKILL.md +12 -0
  28. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +53 -8
  29. package/dist/agent-src/skills/worktree-lifecycle/SKILL.md +3 -1
  30. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  31. package/dist/cli-delegate/cmd_conformance.js +335 -659
  32. package/dist/cli-delegate/cmd_explain.js +24 -112
  33. package/dist/discovery/deprecation-report.md +1 -1
  34. package/dist/discovery/discovery-manifest.json +55 -29
  35. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  36. package/dist/discovery/discovery-manifest.summary.md +3 -3
  37. package/dist/discovery/dormancy-report.md +1 -1
  38. package/dist/discovery/orphan-report.md +1 -1
  39. package/dist/discovery/packs.json +6 -5
  40. package/dist/discovery/trust-report.md +2 -2
  41. package/dist/discovery/workspaces.json +5 -4
  42. package/dist/hooks/dispatch.js +959 -1304
  43. package/dist/mcp/registry-manifest.json +3 -3
  44. package/dist/mcp/server.json +2 -2
  45. package/dist/mcp/server.mjs +671 -1002
  46. package/dist/shared/settingsConsent.js +1 -1
  47. package/package.json +1 -1
  48. package/src/config/conformance-claim-baseline.json +9 -0
  49. package/src/config/gate-violation-baselines.json +3 -3
  50. package/src/config/release-gate-locality.yml +129 -0
  51. package/src/config/web-launch-readiness.json +1 -1
  52. package/src/scripts/_cli/explain_last/index.ts +1 -1
  53. package/src/scripts/_cli/explain_last/memory.ts +8 -104
  54. package/src/scripts/_lib/release_highlights.ts +172 -1
  55. package/src/scripts/_lib/release_material.ts +66 -0
  56. package/src/scripts/_lib/repeated_run.ts +77 -0
  57. package/src/scripts/_lib/tamper_vocabulary.ts +242 -0
  58. package/src/scripts/_lib/unified_diff.ts +121 -0
  59. package/src/scripts/check_artefact_count_messaging.ts +9 -0
  60. package/src/scripts/check_finding_dispositions.ts +179 -3
  61. package/src/scripts/check_installed_hooks_fresh.ts +381 -0
  62. package/src/scripts/check_release_highlights.ts +89 -4
  63. package/src/scripts/check_suppression_hygiene.ts +11 -0
  64. package/src/scripts/check_web_launch_readiness.ts +295 -15
  65. package/src/scripts/code_graph/build.ts +230 -33
  66. package/src/scripts/code_graph/extract.ts +168 -33
  67. package/src/scripts/code_graph/types.ts +37 -2
  68. package/src/scripts/code_graph/validate.ts +12 -1
  69. package/src/scripts/conformance_scan.ts +2 -2
  70. package/src/scripts/detect_silent_catch.ts +403 -0
  71. package/src/scripts/detect_verification_tampering.ts +538 -0
  72. package/src/scripts/git_authorization_hook.ts +153 -17
  73. package/src/scripts/hook_manifest.json +1 -1
  74. package/src/scripts/hook_manifest.yaml +33 -19
  75. package/src/scripts/hooks/block_no_verify.ts +3 -3
  76. package/src/scripts/hooks/concern_registry.ts +2 -2
  77. package/src/scripts/hooks/evidence_independence.ts +21 -2
  78. package/src/scripts/hooks/{block_unauthorized_git.ts → git_command_classifier.ts} +25 -369
  79. package/src/scripts/hooks/push_settle_hook.ts +250 -0
  80. package/src/scripts/hooks/ship_diff_volume_hook.ts +1 -1
  81. package/src/scripts/install-hooks.sh +134 -1
  82. package/src/scripts/language_mirror_hook.ts +27 -5
  83. package/src/scripts/measure_release_mix.ts +384 -0
  84. package/src/scripts/release.ts +31 -143
  85. package/src/scripts/release_drill.ts +71 -1
  86. package/src/scripts/release_mix_taxonomy.json +172 -0
  87. package/src/scripts/release_publication.ts +243 -3
  88. package/src/scripts/release_verify.ts +220 -0
  89. package/src/scripts/schemas/review-findings.schema.json +1 -1
  90. package/src/scripts/schemas/skill.schema.json +11 -1
  91. package/src/scripts/self_review_gate.ts +10 -1
  92. package/src/shared/settingsConsent.ts +1 -1
  93. package/src/scripts/attest_artifact.ts +0 -193
@@ -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
  *
@@ -630,10 +635,9 @@ function _errText(err: unknown): string {
630
635
  /**
631
636
  * The largest pull-request number GitHub can issue: a signed 32-bit integer.
632
637
  *
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.
638
+ * Taken from the API contract rather than estimated, and shared with
639
+ * `hooks/git_command_classifier.ts` so the two cannot drift — the failure this
640
+ * file already learned once with its negation vocabulary.
637
641
  */
638
642
  export const PR_NUMBER_MAX = 2147483647;
639
643
 
@@ -665,19 +669,50 @@ export function extractMergeTargets(prompt: string): number[] {
665
669
  }
666
670
 
667
671
  /**
668
- * A human turn that withdraws standing merge authority.
672
+ * A bare stop word — a withdrawal that names no operation at all.
669
673
  *
670
674
  * 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.
675
+ * bare stop word on its own. It is deliberately over-inclusive in the safe
676
+ * direction: a false revocation costs one prompt, a missed revocation costs an
677
+ * unwanted merge. The alternation is orthogonal to negation and is unchanged.
674
678
  */
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;
679
+ const REVOKE_STOP_WORD =
680
+ /\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;
681
+
682
+ /** The merge verb itself, with no negation notion of its own. */
683
+ const MERGE_VERB = /\b(merg(e|en|ing)|zusammenf(ü|ue)hren)\b/giu;
677
684
 
678
685
  /** Does this human turn withdraw standing merge grants? */
679
686
  export function isRevocation(prompt: string): boolean {
680
- return REVOKE_RE.test(prompt);
687
+ if (REVOKE_STOP_WORD.test(prompt) || isBareRefusal(prompt)) {
688
+ return true;
689
+ }
690
+ // ONE negation implementation, both callers. Until 2026-09-04 this function
691
+ // carried its own inline vocabulary and a fixed `{0,30}` BACKWARD window,
692
+ // while `classifyAuthorization` reached the clause-scoped, abbreviation-aware
693
+ // `negatedBefore` about 240 lines below. The two disagreed on real prompts in
694
+ // both directions — measured at b75d7f7cb:
695
+ //
696
+ // "Merge PR #12 auf keinen Fall." isRevocation=false, a standing
697
+ // grant over #12 SURVIVED
698
+ // "Merge #12 under no circumstances." isRevocation=false, same
699
+ // "Please do not push, but merge PR #7." isRevocation=true while
700
+ // classifyAuthorization returned
701
+ // ["pr-merge"] — the two parsers
702
+ // contradicting each other on a
703
+ // corpus row asserted green
704
+ //
705
+ // `NEGATION_WORD`'s docblock already stated the rule this restores: one
706
+ // vocabulary for the whole file, because two drift invisibly until a prompt
707
+ // lands in the gap between them.
708
+ MERGE_VERB.lastIndex = 0;
709
+ let m: RegExpExecArray | null;
710
+ while ((m = MERGE_VERB.exec(prompt)) !== null) {
711
+ if (negatedBefore(prompt, m.index, m[0])) {
712
+ return true;
713
+ }
714
+ }
715
+ return false;
681
716
  }
682
717
 
683
718
  /** Mint a grant id that a replayed ledger cannot collide with. */
@@ -746,9 +781,53 @@ export function foldGrants(
746
781
  * negation vocabularies in one tree drift, and the drift is invisible until a
747
782
  * prompt lands in the gap between them" — so the list moved here rather than
748
783
  * being copied fifteen times.
784
+ *
785
+ * BOTH DIRECTIONS READ IT, and since 2026-09-04 that is checkable rather than
786
+ * aspirational: `classifyAuthorization` reaches it through `negatedBefore`, and
787
+ * `isRevocation` reaches the same `negatedBefore` plus `isBareRefusal`. The
788
+ * revocation path was the copy the original consolidation missed — it kept a
789
+ * ten-form inline list behind a fixed 30-character backward window, and the two
790
+ * grammars disagreed on real prompts in both directions until they were merged.
791
+ * A THIRD caller adds itself here, not next to itself.
792
+ *
793
+ * THE APOSTROPHE IS PART OF THE VOCABULARY, not a typo tolerance. The list
794
+ * read `dont|don't` — ASCII only — while every macOS, iOS, Word and Slack
795
+ * input turns a typed apostrophe into U+2019 by default. Measured at
796
+ * b75d7f7cb, and it leaked in the DANGEROUS direction on the authorization
797
+ * path, not merely the revocation one:
798
+ *
799
+ * "don't merge PR #12" classifyAuthorization = [] (denied)
800
+ * "don\u2019t merge PR #12" classifyAuthorization = ["pr-merge"] (AUTHORIZED)
801
+ * "don\u2019t push" classifyAuthorization = ["push"] (AUTHORIZED)
802
+ *
803
+ * One character of smart-quote substitution turned a prohibition into a grant
804
+ * for an irreversible operation. `don['\u2019\u2018\u02bc]?t` covers the straight, the two
805
+ * typographic and the modifier-letter forms in the one shared list, so both
806
+ * callers gain it at once — which is the whole argument for one vocabulary.
807
+ */
808
+ /**
809
+ * Every apostrophe a keyboard or an autocorrect can produce for one word.
810
+ *
811
+ * Named once and shared by the vocabulary AND the tokenizer below. Written out
812
+ * twice, `don\u2018t` matched the vocabulary and then split into TWO tokens in
813
+ * `isBareRefusal` — this file's own drift failure, one character wide, caught
814
+ * by the council-mandated token-policy test rather than in review.
815
+ */
816
+ const APOSTROPHE = "'\u2019\u2018\u02bc";
817
+
818
+ const NEGATION_ALTERNATION =
819
+ `nicht|nichts|kein(?:e|en|em|er|es)?|niemals|nie|no|not|don[${APOSTROPHE}]?t|never|without|ohne`;
820
+
821
+ const NEGATION_WORD = new RegExp(`\\b(${NEGATION_ALTERNATION})\\b`, "i");
822
+
823
+ /**
824
+ * The same vocabulary, anchored to a whole token.
825
+ *
826
+ * Built from `NEGATION_ALTERNATION` rather than written out a second time —
827
+ * a copied list is the exact drift this file's `NEGATION_WORD` docblock warns
828
+ * about, and repairing one such copy is what this change is for.
749
829
  */
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;
830
+ const NEGATION_TOKEN = new RegExp(`^(?:${NEGATION_ALTERNATION})$`, "i");
752
831
 
753
832
  /**
754
833
  * Is the match at `index` under a negation?
@@ -768,7 +847,9 @@ const NEGATION_WORD =
768
847
  * says why. The 30-character window inside the sentence is inherited from the
769
848
  * `pr-merge` lookbehind that this generalises.
770
849
  */
771
- const CONTRAST_CUE = /\b(aber|sondern|jedoch|but|however|instead)\b/gi;
850
+ const CONTRAST_ALTERNATION = "aber|sondern|jedoch|but|however|instead";
851
+
852
+ const CONTRAST_CUE = new RegExp(`\\b(${CONTRAST_ALTERNATION})\\b`, "gi");
772
853
 
773
854
  /**
774
855
  * Abbreviation and decimal dots are NOT sentence boundaries.
@@ -926,6 +1007,61 @@ export function negatedBefore(text: string, index: number, matched = ""): boolea
926
1007
  return NEGATION_WORD.test(before) || NEGATION_WORD.test(matched) || NEGATION_WORD.test(after);
927
1008
  }
928
1009
 
1010
+ /**
1011
+ * Is any clause of this turn a BARE refusal — negation words and nothing else?
1012
+ *
1013
+ * `negatedBefore` answers "is this operation negated", which needs the
1014
+ * operation to be in the clause. A withdrawal does not have to name one:
1015
+ * `"Merge PR #12? Actually, don't."` puts the merge in a question sentence and
1016
+ * the refusal in the next one, so no clause anywhere holds both. Measured at
1017
+ * b75d7f7cb and again after the shared-parser change: `isRevocation` returned
1018
+ * false and a standing grant over #12 survived.
1019
+ *
1020
+ * The scope is a CLAUSE whose every token is a negation word, which is the
1021
+ * narrow half. `"Do not push."` is not a bare refusal — `push` is a content
1022
+ * word, so the clause names an operation and `negatedBefore` owns it. That
1023
+ * boundary is what keeps this from revoking `"Nicht pushen. Merge PR #12."`,
1024
+ * a corpus row whose merge must still be authorized.
1025
+ *
1026
+ * It reuses `NEGATION_TOKEN`, so the one vocabulary covers this reading too.
1027
+ *
1028
+ * WHAT IT REVOKES — every standing grant, and that is the PRE-EXISTING
1029
+ * contract rather than a new one. `foldGrants` returns `[]` for any revocation,
1030
+ * which is how a bare `"stop"` has always behaved; a bare refusal is the same
1031
+ * class of utterance and takes the same transition. Nothing here narrows or
1032
+ * widens grant selection, so the council's question about which grant a bare
1033
+ * `"don't"` targets is answered by the existing product semantics: all of them,
1034
+ * in the safe direction.
1035
+ *
1036
+ * WHAT IT DOES NOT FIRE ON — a negation carrying any content word, which is
1037
+ * what keeps a conversational aside from costing the user their authority.
1038
+ * Measured against the council's boundary set:
1039
+ *
1040
+ * "Merge #12? Actually, I don't think so." false — "think"/"so" are content
1041
+ * "Merge #12? Don't worry, I'll do it." false — "worry" is content
1042
+ * "Actually, don't worry about it." false — same
1043
+ * "Merge #12? Actually, don't." TRUE — the clause is only "don't"
1044
+ * "Merge #12. Don't." TRUE — a retraction one sentence later
1045
+ * "Merge #12? , ; ." false — no tokens at all
1046
+ */
1047
+ /** A word token, apostrophes included, so `don't` stays ONE token. */
1048
+ const WORD_TOKEN = new RegExp(`[\\p{L}\\p{N}${APOSTROPHE}]+`, "gu");
1049
+
1050
+ /** Clause boundaries, built from the one contrast vocabulary above. */
1051
+ const CLAUSE_SPLIT = new RegExp(`[,;:]|\\b(?:${CONTRAST_ALTERNATION})\\b`, "iu");
1052
+
1053
+ export function isBareRefusal(text: string): boolean {
1054
+ for (const sentence of _sentences(text)) {
1055
+ for (const clause of sentence.split(CLAUSE_SPLIT)) {
1056
+ const tokens = (clause ?? "").match(WORD_TOKEN) ?? [];
1057
+ if (tokens.length > 0 && tokens.every((t) => NEGATION_TOKEN.test(t))) {
1058
+ return true;
1059
+ }
1060
+ }
1061
+ }
1062
+ return false;
1063
+ }
1064
+
929
1065
  /** Classify which ops a prompt authorizes. Exported for direct testing. */
930
1066
  export function classifyAuthorization(prompt: string): {
931
1067
  authorized: GitOp[];
@@ -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":"40918412:83446","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"}}}}
@@ -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):
@@ -1166,16 +1180,16 @@ platforms:
1166
1180
  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
1181
  session_end: [chat-history, memory-learn, session-register, roadmap-progress, telemetry-flush]
1168
1182
  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]
1183
+ 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]
1184
+ 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
1185
 
1172
1186
  claude:
1173
1187
  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
1188
  session_end: [chat-history, memory-learn, session-register, roadmap-progress, telemetry-flush, journal-record]
1175
1189
  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
1190
  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]
1191
+ 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]
1192
+ 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
1193
  # `language-mirror` — round-5 § 6.1. `pre_compact` sets a pin-lost marker;
1180
1194
  # the `post_tool_use` entry above re-emits the pin exactly once while that
1181
1195
  # marker is set, then clears it. One extra injection per compaction EVENT —
@@ -1228,8 +1242,8 @@ platforms:
1228
1242
  # still costs the dispatch, and its entire output is thrown away.
1229
1243
  stop: [chat-history, hot-context, verify-before-complete, self-repair, session-register, roadmap-progress, design-pass-stop]
1230
1244
  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]
1245
+ 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]
1246
+ 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
1247
  # subagent-ledger IS bound here, unlike the two nudges above, and the
1234
1248
  # difference is the delivery channel rather than the platform: the nudges
1235
1249
  # depend on stdout reaching the model, which this trampoline discards by
@@ -1252,7 +1266,7 @@ platforms:
1252
1266
  session_end: [chat-history, memory-learn, session-register, roadmap-progress, telemetry-flush]
1253
1267
  stop: [chat-history, hot-context, verify-before-complete, self-repair, session-register, roadmap-progress, design-pass-stop]
1254
1268
  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]
1269
+ 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
1270
 
1257
1271
  # Phase 7.6 — Cline. Hooks live under `.clinerules/hooks/<HookName>`
1258
1272
  # (project, no file extension, must be executable per Cline docs) or
@@ -1267,7 +1281,7 @@ platforms:
1267
1281
  session_end: [chat-history, memory-learn, session-register, roadmap-progress, telemetry-flush]
1268
1282
  stop: [chat-history, hot-context, verify-before-complete, self-repair, session-register, roadmap-progress, design-pass-stop]
1269
1283
  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]
1284
+ 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
1285
 
1272
1286
  # Phase 7.7 — Windsurf (Cascade). Hooks live at `.windsurf/hooks.json`
1273
1287
  # (project) or `~/.codeium/windsurf/hooks.json` (user). Cascade has
@@ -1303,7 +1317,7 @@ platforms:
1303
1317
  session_end: [chat-history, memory-learn, session-register, roadmap-progress, telemetry-flush]
1304
1318
  stop: [chat-history, hot-context, verify-before-complete, self-repair, session-register, roadmap-progress, design-pass-stop]
1305
1319
  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]
1320
+ 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
1321
 
1308
1322
  # Phase 7.9 — Copilot has no hook surface. Concerns route through
1309
1323
  # rule-only fallback; the dispatcher silently no-ops on --platform copilot.
@@ -34,7 +34,7 @@ import * as fs from 'node:fs';
34
34
  import { fileURLToPath, pathToFileURL } from 'node:url';
35
35
  import * as path from 'node:path';
36
36
  import { readHookStdin } from './hook_stdin.js';
37
- import { substitutionPayloads } from './block_unauthorized_git.js';
37
+ import { substitutionPayloads } from './git_command_classifier.js';
38
38
 
39
39
  const _HERE = fileURLToPath(import.meta.url);
40
40
 
@@ -400,7 +400,7 @@ function _is_blocked(git_tokens: string[]): [boolean, string] {
400
400
  * genuinely unparseable command that DOES invoke git. So the test moves from
401
401
  * "the string contains git" to "some command position is git", with heredoc
402
402
  * bodies removed first — the same data-not-command distinction
403
- * `block_unauthorized_git` already makes.
403
+ * `git_command_classifier` already makes.
404
404
  *
405
405
  * Deliberately regex-shaped rather than tokenised: shlex has already failed by
406
406
  * the time this runs, so no reliable token stream exists. It therefore stays
@@ -450,7 +450,7 @@ export function _looks_like_git_invocation(cmd: string, depth = 0): boolean {
450
450
  * `_git_base` never sees git. The more parseable the command, the less it was
451
451
  * protected. Classification inside the payload is by command position, so a
452
452
  * substitution that INVOKES git is checked and one that merely names it in an
453
- * argument is not — matching what `block_unauthorized_git` does one level up.
453
+ * argument is not — matching what `git_command_classifier` does one level up.
454
454
  *
455
455
  * Heredoc bodies are removed before extraction: a backtick or `$(` inside a
456
456
  * commit message being written to a file is data, and feeding it back through
@@ -41,6 +41,7 @@ import { main as wrapperFreshnessMain } from '../wrapper_freshness_hook.js';
41
41
  import { main as surfaceProbeMain } from '../surface_probe_hook.js';
42
42
  import { main as teamReviewGateMain } from '../team_review_gate_hook.js';
43
43
  import { main as prUrlReminderMain } from '../pr_url_reminder_hook.js';
44
+ import { main as pushSettleMain } from './push_settle_hook.js';
44
45
  import { main as sessionCanaryMain } from '../session_canary_hook.js';
45
46
  import { main as councilAvailabilityMain } from '../council_availability_hook.js';
46
47
  import { main as telemetryDisclosureMain } from '../telemetry_disclosure_hook.js';
@@ -48,7 +49,6 @@ import { main as selfRepairMain } from '../self_repair_hook.js';
48
49
  import { main as sessionRegisterMain } from '../session_register_hook.js';
49
50
  import { main as languageMirrorMain } from '../language_mirror_hook.js';
50
51
  import { main as gitAuthorizationMain } from '../git_authorization_hook.js';
51
- import { main as blockUnauthorizedGitMain } from './block_unauthorized_git.js';
52
52
  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';
@@ -102,6 +102,7 @@ export const CONCERN_REGISTRY: Readonly<Record<string, ConcernMain>> = {
102
102
  'src/scripts/surface_probe_hook.ts': surfaceProbeMain as ConcernMain,
103
103
  'src/scripts/team_review_gate_hook.ts': teamReviewGateMain as ConcernMain,
104
104
  'src/scripts/pr_url_reminder_hook.ts': prUrlReminderMain as ConcernMain,
105
+ 'src/scripts/hooks/push_settle_hook.ts': pushSettleMain as ConcernMain,
105
106
  'src/scripts/session_canary_hook.ts': sessionCanaryMain as ConcernMain,
106
107
  'src/scripts/council_availability_hook.ts': councilAvailabilityMain as ConcernMain,
107
108
  'src/scripts/telemetry_disclosure_hook.ts': telemetryDisclosureMain as ConcernMain,
@@ -109,7 +110,6 @@ export const CONCERN_REGISTRY: Readonly<Record<string, ConcernMain>> = {
109
110
  'src/scripts/session_register_hook.ts': sessionRegisterMain as ConcernMain,
110
111
  'src/scripts/language_mirror_hook.ts': languageMirrorMain as ConcernMain,
111
112
  'src/scripts/git_authorization_hook.ts': gitAuthorizationMain as ConcernMain,
112
- 'src/scripts/hooks/block_unauthorized_git.ts': blockUnauthorizedGitMain as ConcernMain,
113
113
  'src/scripts/hooks/evidence_independence.ts': evidenceIndependenceMain as ConcernMain,
114
114
  'src/scripts/hooks/block_no_verify.ts': blockNoVerifyMain as ConcernMain,
115
115
  'src/scripts/hooks/block_kernel_rule_writes.ts': blockKernelRuleWritesMain as ConcernMain,
@@ -365,8 +365,21 @@ export function run(stdin_text: string, options: { consumer_root: string }): num
365
365
  });
366
366
  try {
367
367
  atomic_write_json(target, state);
368
- } catch {
369
- /* observability only */
368
+ } catch (err) {
369
+ /* Unlike its two siblings in `git_authorization_hook`, this one fails
370
+ OPEN, which is why it gets a diagnostic rather than a shrug. The turn's
371
+ evaluation count lives only in this file: a failed write leaves
372
+ `evaluations` one short, so the NEXT self-commissioned evaluation in the
373
+ same turn reads `priorEvaluations === 0` and the verdict-shopping warn
374
+ does not fire. The item-1 pre-loaded-verdict BLOCK is unaffected — it
375
+ reads the prompt, not this state — so the degradation is bounded to the
376
+ advisory half. Silent was the wrong call for a guard that loses a check
377
+ when it fails. */
378
+ process.stderr.write(
379
+ `evidence-independence: evaluation-count write failed (${_errText(err)}) — ` +
380
+ "this turn's count did NOT advance, so a second self-scoped evaluation " +
381
+ "will not be warned about. The pre-loaded-verdict block is unaffected.\n",
382
+ );
370
383
  }
371
384
  }
372
385
 
@@ -379,6 +392,12 @@ export function run(stdin_text: string, options: { consumer_root: string }): num
379
392
  return decision.exit;
380
393
  }
381
394
 
395
+ /** One-line, bounded rendering of a caught value for a stderr diagnostic. */
396
+ function _errText(err: unknown): string {
397
+ const t = err instanceof Error ? err.message : String(err);
398
+ return t.replace(/\s+/g, " ").trim().slice(0, 200);
399
+ }
400
+
382
401
  export function main(argv?: string[]): number {
383
402
  const args = argv ?? process.argv.slice(2);
384
403
  let consumer_root = process.cwd();