@windyroad/itil 0.61.1 → 0.61.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/package.json +7 -2
- package/agents/test/fixtures/proceed-new-genuinely-new.md +0 -43
- package/agents/test/fixtures/proceed-new-subtle-sibling.md +0 -47
- package/agents/test/fixtures/regression-p347-vs-p346.md +0 -54
- package/agents/test/hang-off-check.bats +0 -225
- package/hooks/test/block-list.bats +0 -153
- package/hooks/test/command-detect.bats +0 -181
- package/hooks/test/itil-assistant-output-gate.bats +0 -114
- package/hooks/test/itil-assistant-output-review.bats +0 -224
- package/hooks/test/itil-bash-polling-antipattern-detect.bats +0 -154
- package/hooks/test/itil-changeset-discipline.bats +0 -603
- package/hooks/test/itil-claude-space-protection.bats +0 -294
- package/hooks/test/itil-commit-trailer-transition-advisory.bats +0 -80
- package/hooks/test/itil-correction-detect.bats +0 -189
- package/hooks/test/itil-deferral-cadence-gate.bats +0 -187
- package/hooks/test/itil-fictional-defer-detect.bats +0 -292
- package/hooks/test/itil-fix-title-lifecycle-advisory.bats +0 -129
- package/hooks/test/itil-mid-loop-ask-detect.bats +0 -220
- package/hooks/test/itil-no-implement-draft-gate.bats +0 -210
- package/hooks/test/itil-pending-questions-surface.bats +0 -307
- package/hooks/test/itil-readme-refresh-discipline.bats +0 -642
- package/hooks/test/itil-rfc-oversight-nudge.bats +0 -83
- package/hooks/test/itil-rfc-trailer-advisory.bats +0 -375
- package/hooks/test/itil-story-mirror-migration-nudge.bats +0 -122
- package/hooks/test/manage-problem-enforce-create.bats +0 -424
- package/hooks/test/p057-staging-trap-detect.bats +0 -231
- package/hooks/test/pre-publish-intake-gate.bats +0 -144
- package/hooks/test/runtime-sid-marker.bats +0 -90
- package/hooks/test/session-id.bats +0 -370
- package/scripts/migrate-problems-add-type.sh +0 -116
- package/scripts/test/catchup-scan.bats +0 -274
- package/scripts/test/check-afk-accept-eligible.bats +0 -310
- package/scripts/test/check-fail-soft-skip-discipline.bats +0 -172
- package/scripts/test/check-fix-rfc-trace.bats +0 -164
- package/scripts/test/check-locale-discipline.bats +0 -291
- package/scripts/test/check-problems-readme-budget.bats +0 -192
- package/scripts/test/check-rfc-has-stories.bats +0 -69
- package/scripts/test/check-rfc-rejected-alternatives.bats +0 -108
- package/scripts/test/check-rfc-stories-ratified.bats +0 -82
- package/scripts/test/check-upstream-responses.bats +0 -503
- package/scripts/test/classify-readme-drift.bats +0 -392
- package/scripts/test/derive-first-dispatch.bats +0 -274
- package/scripts/test/derive-release-vehicle.bats +0 -454
- package/scripts/test/detect-unratified-stories-maps.bats +0 -60
- package/scripts/test/dual-tolerant-glob-rfc-002-t2.bats +0 -309
- package/scripts/test/effort-tally.bats +0 -170
- package/scripts/test/evaluate-relevance.bats +0 -773
- package/scripts/test/kind-a-commands.bats +0 -46
- package/scripts/test/mark-create-gate.bats +0 -59
- package/scripts/test/mark-story-oversight-confirmed.bats +0 -53
- package/scripts/test/migrate-problems-add-type.bats +0 -280
- package/scripts/test/migrate-story-status-mirror.bats +0 -167
- package/scripts/test/no-type-regression-guard.bats +0 -74
- package/scripts/test/oversight-mirror-corpus-lint.bats +0 -150
- package/scripts/test/plugin-exercise-index.bats +0 -386
- package/scripts/test/plugin-maturity-doc-lint.bats +0 -470
- package/scripts/test/plugin-maturity-populate.bats +0 -631
- package/scripts/test/plugin-maturity-render.bats +0 -469
- package/scripts/test/plugin-validate-ci-gate.bats +0 -208
- package/scripts/test/reconcile-readme.bats +0 -1007
- package/scripts/test/reconcile-rfcs.bats +0 -496
- package/scripts/test/reconcile-stories.bats +0 -173
- package/scripts/test/reconcile-story-maps.bats +0 -74
- package/scripts/test/release-watch-poll-loop.bats +0 -180
- package/scripts/test/resolve-governance-plugin-dirs.bats +0 -78
- package/scripts/test/rfc-stories-extension.bats +0 -175
- package/scripts/test/skill-invocations.bats +0 -535
- package/scripts/test/skill-md-dual-tolerant-coverage-rfc-002-t3.bats +0 -374
- package/scripts/test/story-oversight-lib.bats +0 -190
- package/scripts/test/update-jtbd-references-related-problems.bats +0 -178
- package/scripts/test/update-problem-references-section.bats +0 -242
- package/scripts/test/update-problem-rfcs-section.bats +0 -242
- package/scripts/test/update-references-section-sibling-helpers.bats +0 -80
- package/scripts/test/update-rfc-commits-section.bats +0 -77
- package/scripts/test/verify-iter-summary.bats +0 -196
- package/scripts/test/working-the-problem-traversal.bats +0 -116
- package/skills/capture-problem/test/capture-problem-step-1-5b-jtbd-trace.bats +0 -398
- package/skills/capture-problem/test/capture-problem.bats +0 -389
- package/skills/capture-story/test/capture-story-behavioural.bats +0 -317
- package/skills/capture-story-map/test/capture-story-map-behavioural.bats +0 -98
- package/skills/close-incident/test/close-incident-contract.bats +0 -146
- package/skills/link-incident/test/link-incident-contract.bats +0 -125
- package/skills/list-incidents/test/list-incidents-contract.bats +0 -115
- package/skills/list-problems/test/list-problems-contract.bats +0 -100
- package/skills/list-stories/test/list-stories-contract.bats +0 -127
- package/skills/list-story-maps/test/list-story-maps-contract.bats +0 -46
- package/skills/manage-incident/test/manage-incident-adr-044-contract.bats +0 -206
- package/skills/manage-incident/test/manage-incident-close-forwarder.bats +0 -67
- package/skills/manage-incident/test/manage-incident-link-forwarder.bats +0 -67
- package/skills/manage-incident/test/manage-incident-list-forwarder.bats +0 -68
- package/skills/manage-incident/test/manage-incident-mitigate-forwarder.bats +0 -66
- package/skills/manage-incident/test/manage-incident-restore-forwarder.bats +0 -66
- package/skills/manage-incident/test/manage-incident.bats +0 -171
- package/skills/manage-problem/test/manage-problem-adr-044-step4-derive-first.bats +0 -151
- package/skills/manage-problem/test/manage-problem-auto-migrate-step.bats +0 -53
- package/skills/manage-problem/test/manage-problem-concern-boundary.bats +0 -64
- package/skills/manage-problem/test/manage-problem-effort-buckets.bats +0 -56
- package/skills/manage-problem/test/manage-problem-external-root-cause-detection.bats +0 -119
- package/skills/manage-problem/test/manage-problem-first-run-intake-prompt.bats +0 -43
- package/skills/manage-problem/test/manage-problem-git-mv-restage-reminder.bats +0 -48
- package/skills/manage-problem/test/manage-problem-id-collision-guard.bats +0 -39
- package/skills/manage-problem/test/manage-problem-list-forwarder.bats +0 -66
- package/skills/manage-problem/test/manage-problem-next-id-origin-lookup.bats +0 -50
- package/skills/manage-problem/test/manage-problem-no-prose-options.bats +0 -74
- package/skills/manage-problem/test/manage-problem-output-formatting.bats +0 -30
- package/skills/manage-problem/test/manage-problem-parked-and-cache.bats +0 -73
- package/skills/manage-problem/test/manage-problem-readme-refresh-on-transition.bats +0 -62
- package/skills/manage-problem/test/manage-problem-readme-tie-break-order.bats +0 -318
- package/skills/manage-problem/test/manage-problem-readme-vq-sort-order.bats +0 -206
- package/skills/manage-problem/test/manage-problem-release-vehicle-seed.bats +0 -83
- package/skills/manage-problem/test/manage-problem-review-forwarder.bats +0 -71
- package/skills/manage-problem/test/manage-problem-step-9d-recovery-path.bats +0 -97
- package/skills/manage-problem/test/manage-problem-transition-forwarder.bats +0 -96
- package/skills/manage-problem/test/manage-problem-transitive-dependencies.bats +0 -365
- package/skills/manage-problem/test/manage-problem-verification-detection.bats +0 -64
- package/skills/manage-problem/test/manage-problem-verification-pending.bats +0 -114
- package/skills/manage-problem/test/manage-problem-work-forwarder.bats +0 -88
- package/skills/manage-story/test/manage-story-contract.bats +0 -174
- package/skills/manage-story-map/test/manage-story-map-contract.bats +0 -63
- package/skills/mitigate-incident/test/mitigate-incident-contract.bats +0 -258
- package/skills/reconcile-readme/test/reconcile-readme-contract.bats +0 -201
- package/skills/report-upstream/test/report-upstream-contract.bats +0 -394
- package/skills/restore-incident/test/restore-incident-contract.bats +0 -170
- package/skills/review-problems/test/inbound-channels-cache-shape.bats +0 -127
- package/skills/review-problems/test/inbound-discovery-contract.bats +0 -383
- package/skills/review-problems/test/jtbd-301-verdict-shape-contract.bats +0 -225
- package/skills/review-problems/test/review-problems-contract.bats +0 -235
- package/skills/review-problems/test/review-problems-likely-verified-cell-shape.bats +0 -229
- package/skills/scaffold-intake/test/scaffold-intake-contract.bats +0 -126
- package/skills/scaffold-intake/test/scaffold-intake-fixture.bats +0 -164
- package/skills/scaffold-intake/test/scaffold-intake-secrets-absent.bats +0 -87
- package/skills/transition-problem/test/transition-problem-contract.bats +0 -285
- package/skills/transition-problems/test/transition-problems-contract.bats +0 -331
- package/skills/update-upstream/test/update-upstream-contract.bats +0 -375
- package/skills/work-problem/test/work-problem-contract.bats +0 -294
- package/skills/work-problems/test/work-problems-above-appetite-remediation.bats +0 -139
- package/skills/work-problems/test/work-problems-adr-013-rule-6-p352-amendment.bats +0 -166
- package/skills/work-problems/test/work-problems-auto-migrate-step.bats +0 -57
- package/skills/work-problems/test/work-problems-cost-logging.bats +0 -109
- package/skills/work-problems/test/work-problems-deviation-candidate-shape.bats +0 -121
- package/skills/work-problems/test/work-problems-first-run-intake-prompt.bats +0 -36
- package/skills/work-problems/test/work-problems-inter-iteration-verify.bats +0 -59
- package/skills/work-problems/test/work-problems-mid-loop-userpromptsubmit-handler.bats +0 -69
- package/skills/work-problems/test/work-problems-no-mid-loop-asking.bats +0 -192
- package/skills/work-problems/test/work-problems-p341-pre-all-done-gate.bats +0 -122
- package/skills/work-problems/test/work-problems-p342-r007-derive-then-pass-flags.bats +0 -170
- package/skills/work-problems/test/work-problems-p342-retro-auto-ticket-carveout.bats +0 -120
- package/skills/work-problems/test/work-problems-preflight-failure-handling.bats +0 -248
- package/skills/work-problems/test/work-problems-preflight-session-continuity.bats +0 -139
- package/skills/work-problems/test/work-problems-preflight.bats +0 -69
- package/skills/work-problems/test/work-problems-release-cadence.bats +0 -63
- package/skills/work-problems/test/work-problems-step-0-iter-error-staleness.bats +0 -93
- package/skills/work-problems/test/work-problems-step-0b-cache-staleness-behavioural.bats +0 -138
- package/skills/work-problems/test/work-problems-step-0c-deferred-placeholder-staleness-behavioural.bats +0 -238
- package/skills/work-problems/test/work-problems-step-0d-outbound-responses-staleness-behavioural.bats +0 -174
- package/skills/work-problems/test/work-problems-step-2-5-routing.bats +0 -80
- package/skills/work-problems/test/work-problems-step-2-5b-cross-halt-routing.bats +0 -149
- package/skills/work-problems/test/work-problems-step-3-5-jtbd-ratification-predicate.bats +0 -191
- package/skills/work-problems/test/work-problems-step-5-bats-polling-discipline.bats +0 -91
- package/skills/work-problems/test/work-problems-step-5-delegation.bats +0 -333
- package/skills/work-problems/test/work-problems-step-5-idle-timeout-sigterm.bats +0 -421
- package/skills/work-problems/test/work-problems-step-5-is-error-transient-halt.bats +0 -278
- package/skills/work-problems/test/work-problems-step-5-iter-changeset-required.bats +0 -95
- package/skills/work-problems/test/work-problems-step-5-prompt-body-re-grounding.bats +0 -128
- package/skills/work-problems/test/work-problems-step-5-stream-timeout-salvage.bats +0 -251
- package/skills/work-problems/test/work-problems-step-6-5-always-drain.bats +0 -203
- package/skills/work-problems/test/work-problems-step-6-5-cache-refresh-chain.bats +0 -174
- package/skills/work-problems/test/work-problems-step-6-5-fix-and-continue.bats +0 -254
- package/skills/work-problems/test/work-problems-step-6-5-postrelease-kv-callback.bats +0 -209
- package/skills/work-problems/test/work-problems-stop-condition-questions.bats +0 -85
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bats
|
|
2
|
-
|
|
3
|
-
# P375 — itil-deferral-cadence-gate.sh PostToolUse:Write|Edit|MultiEdit
|
|
4
|
-
# advisory hook. The ratified Option-C "authoring-time enforcement gate"
|
|
5
|
-
# (core slice, advisory rollout per ADR-057 staged-rollout + the P375
|
|
6
|
-
# architect review 2026-06-28).
|
|
7
|
-
#
|
|
8
|
-
# The gate fires at AUTHORING time on the NEWLY-authored text (Edit
|
|
9
|
-
# new_string / Write content / MultiEdit concatenated new_strings —
|
|
10
|
-
# diff-aware so descriptive prose already on disk never re-triggers) of
|
|
11
|
-
# a SHIPPED authoring surface (SKILL.md, docs/decisions/*.md ADRs,
|
|
12
|
-
# docs/rfcs/*.md RFCs, hook *.sh). When the new text introduces an
|
|
13
|
-
# uncadenced-deferral phrasing (`deferred to <on-demand re-entry>`,
|
|
14
|
-
# `pending review`, `re-rate at next`, `(deferred …`, `next review`,
|
|
15
|
-
# `when ready`, `lands in Slice N`) WITHOUT a cadence annotation naming
|
|
16
|
-
# a SELF-FIRING trigger within the +/-5 line window, it emits a stderr
|
|
17
|
-
# advisory citing P375 + the remedy.
|
|
18
|
-
#
|
|
19
|
-
# THE LOAD-BEARING P375 REFINEMENT vs the P234 sibling
|
|
20
|
-
# (itil-fictional-defer-detect.sh): a bare named on-demand skill
|
|
21
|
-
# (/wr-foo:bar) or a bare ticket ID (Pnnn / RFC-nnn / ADR-nnn) does NOT
|
|
22
|
-
# satisfy the cadence requirement — naming an on-demand re-entry point
|
|
23
|
-
# and treating it as a cadence IS the exact conflation P375 captures
|
|
24
|
-
# ("BUT NOTHING TRIGGERS THAT WORK!!!"). Only a self-firing-CLASS
|
|
25
|
-
# citation satisfies: a hook *.sh, SessionStart, PreToolUse/PostToolUse,
|
|
26
|
-
# .github/workflows/ (CI), cron, or a work-problems Step-0x / pre-flight
|
|
27
|
-
# reference. The existing P234 hook WRONGLY accepts skills + ticket IDs;
|
|
28
|
-
# this hook does not.
|
|
29
|
-
#
|
|
30
|
-
# Core-slice boundary (architect refinement 1, named loudly): the gate
|
|
31
|
-
# checks the cadence annotation names a self-firing-CLASS trigger — it
|
|
32
|
-
# does NOT validate that the named trigger actually exists / fires (the
|
|
33
|
-
# transitive-reachability graph is a deferred later slice). docs/problems/
|
|
34
|
-
# tickets are EXCLUDED (they descriptively narrate deferrals — highest
|
|
35
|
-
# false-positive surface, already covered by the ADR-084 census).
|
|
36
|
-
#
|
|
37
|
-
# Advisory only — NEVER blocks (exit 0 always), per ADR-040/045
|
|
38
|
-
# declarative-first + ADR-013 Rule 6 fail-open. Behavioural per ADR-052
|
|
39
|
-
# (asserts emitted stderr, never source-greps the hook). Hermetic per
|
|
40
|
-
# P391 (unsets inherited suppress vars in setup).
|
|
41
|
-
|
|
42
|
-
setup() {
|
|
43
|
-
REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/../../../.." && pwd)"
|
|
44
|
-
HOOK="$REPO_ROOT/packages/itil/hooks/itil-deferral-cadence-gate.sh"
|
|
45
|
-
# P391 hermeticity: AFK iters export suppress vars that would poison
|
|
46
|
-
# the advisory-fires assertions. Strip them for the test process.
|
|
47
|
-
unset WR_SUPPRESS_DEFERRAL_CADENCE_GATE
|
|
48
|
-
unset WR_SUPPRESS_OVERSIGHT_NUDGE
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
# Emit a PostToolUse stdin payload for an Edit tool call.
|
|
52
|
-
# $1 = file_path, $2 = new_string (the newly-authored text).
|
|
53
|
-
emit_edit() {
|
|
54
|
-
jq -n --arg p "$1" --arg n "$2" '{
|
|
55
|
-
session_id: "deferral-cadence-test",
|
|
56
|
-
tool_name: "Edit",
|
|
57
|
-
tool_input: { file_path: $p, old_string: "X", new_string: $n },
|
|
58
|
-
tool_response: { success: true }
|
|
59
|
-
}'
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
# Emit a PostToolUse stdin payload for a Write tool call.
|
|
63
|
-
emit_write() {
|
|
64
|
-
jq -n --arg p "$1" --arg c "$2" '{
|
|
65
|
-
session_id: "deferral-cadence-test",
|
|
66
|
-
tool_name: "Write",
|
|
67
|
-
tool_input: { file_path: $p, content: $c },
|
|
68
|
-
tool_response: { success: true }
|
|
69
|
-
}'
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
fires() { [[ "$output" == *"P375"* ]] || [[ "$stderr" == *"P375"* ]]; }
|
|
73
|
-
silent() { [[ "$output" != *"P375"* ]] && [[ "$stderr" != *"P375"* ]]; }
|
|
74
|
-
|
|
75
|
-
# --- Positive: uncadenced deferral authored → advisory fires ---
|
|
76
|
-
|
|
77
|
-
@test "fire: SKILL.md deferral citing a bare on-demand skill (the P375 conflation) fires" {
|
|
78
|
-
# This is the case the P234 sibling WRONGLY allows — a named on-demand
|
|
79
|
-
# skill is NOT a self-firing cadence.
|
|
80
|
-
run bash "$HOOK" <<<"$(emit_edit packages/foo/skills/bar/SKILL.md \
|
|
81
|
-
'Full scope deferred to /wr-itil:manage-rfc accepted transition.')"
|
|
82
|
-
[ "$status" -eq 0 ]
|
|
83
|
-
fires
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
@test "fire: ADR new_string deferral with no citation at all fires" {
|
|
87
|
-
run bash "$HOOK" <<<"$(emit_edit docs/decisions/099-thing.proposed.md \
|
|
88
|
-
'Considered Options and Consequences deferred — flesh out later.')"
|
|
89
|
-
[ "$status" -eq 0 ]
|
|
90
|
-
fires
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
@test "fire: RFC deferral citing only a bare ticket ID (not a cadence) fires" {
|
|
94
|
-
# A ticket ID is an audit annotation, not a self-firing trigger.
|
|
95
|
-
run bash "$HOOK" <<<"$(emit_edit docs/rfcs/RFC-099-thing.proposed.md \
|
|
96
|
-
'Scope deferred to next review per P375.')"
|
|
97
|
-
[ "$status" -eq 0 ]
|
|
98
|
-
fires
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
@test "fire: Write of a hook .sh whose content carries an uncadenced deferral fires" {
|
|
102
|
-
run bash "$HOOK" <<<"$(emit_write packages/foo/hooks/foo.sh \
|
|
103
|
-
'# TODO pending review when ready; not wired yet.')"
|
|
104
|
-
[ "$status" -eq 0 ]
|
|
105
|
-
fires
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
@test "fire: deferral with a cadence comment that names an ON-DEMAND skill still fires" {
|
|
109
|
-
# The annotation carrier is fine but its value must name a self-firing
|
|
110
|
-
# CLASS — naming an on-demand skill inside the comment does not help.
|
|
111
|
-
run bash "$HOOK" <<<"$(emit_edit packages/foo/skills/bar/SKILL.md \
|
|
112
|
-
'Tasks deferred. <!-- cadence: /wr-itil:manage-rfc accepted -->')"
|
|
113
|
-
[ "$status" -eq 0 ]
|
|
114
|
-
fires
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
# --- Negative: cadenced deferral or out-of-scope → silent ---
|
|
118
|
-
|
|
119
|
-
@test "allow: deferral citing a self-firing hook .sh in window exits silent" {
|
|
120
|
-
run bash "$HOOK" <<<"$(emit_edit packages/foo/skills/bar/SKILL.md \
|
|
121
|
-
'Re-rate deferred; surfaced every session by retrospective-deferral-census.sh.')"
|
|
122
|
-
[ "$status" -eq 0 ]
|
|
123
|
-
silent
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
@test "allow: deferral with an explicit cadence annotation naming PostToolUse exits silent" {
|
|
127
|
-
run bash "$HOOK" <<<"$(emit_edit docs/decisions/099-thing.proposed.md \
|
|
128
|
-
'Section deferred. <!-- cadence: PostToolUse itil-foo-gate.sh fires on author -->')"
|
|
129
|
-
[ "$status" -eq 0 ]
|
|
130
|
-
silent
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
@test "allow: deferral citing SessionStart self-firing surface exits silent" {
|
|
134
|
-
run bash "$HOOK" <<<"$(emit_edit docs/rfcs/RFC-099-thing.proposed.md \
|
|
135
|
-
'Drain deferred; the SessionStart nudge re-surfaces it every session.')"
|
|
136
|
-
[ "$status" -eq 0 ]
|
|
137
|
-
silent
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
@test "allow: deferral citing a CI workflow exits silent" {
|
|
141
|
-
run bash "$HOOK" <<<"$(emit_edit packages/foo/skills/bar/SKILL.md \
|
|
142
|
-
'Validation deferred to .github/workflows/check.yml on every push.')"
|
|
143
|
-
[ "$status" -eq 0 ]
|
|
144
|
-
silent
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
@test "allow: deferral in a docs/problems/ ticket (excluded surface) exits silent" {
|
|
148
|
-
run bash "$HOOK" <<<"$(emit_edit docs/problems/open/099-thing.open.md \
|
|
149
|
-
'Severity deferred to investigation; expand at next review.')"
|
|
150
|
-
[ "$status" -eq 0 ]
|
|
151
|
-
silent
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
@test "allow: deferral phrasing in a non-authoring file (.ts) exits silent" {
|
|
155
|
-
run bash "$HOOK" <<<"$(emit_edit packages/foo/src/index.ts \
|
|
156
|
-
'// deferred to next review — TODO')"
|
|
157
|
-
[ "$status" -eq 0 ]
|
|
158
|
-
silent
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
@test "allow: authoring-surface edit with NO deferral phrasing exits silent" {
|
|
162
|
-
run bash "$HOOK" <<<"$(emit_edit packages/foo/skills/bar/SKILL.md \
|
|
163
|
-
'This step validates the marker and proceeds to Step 2.')"
|
|
164
|
-
[ "$status" -eq 0 ]
|
|
165
|
-
silent
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
# --- Robustness ---
|
|
169
|
-
|
|
170
|
-
@test "fail-open: empty stdin exits 0 silent" {
|
|
171
|
-
run bash "$HOOK" <<<""
|
|
172
|
-
[ "$status" -eq 0 ]
|
|
173
|
-
silent
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
@test "fail-open: malformed JSON stdin exits 0 silent" {
|
|
177
|
-
run bash "$HOOK" <<<"{not json"
|
|
178
|
-
[ "$status" -eq 0 ]
|
|
179
|
-
silent
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
@test "suppress: WR_SUPPRESS_DEFERRAL_CADENCE_GATE=1 silences the advisory" {
|
|
183
|
-
run env WR_SUPPRESS_DEFERRAL_CADENCE_GATE=1 bash "$HOOK" <<<"$(emit_edit \
|
|
184
|
-
packages/foo/skills/bar/SKILL.md 'deferred to /wr-itil:manage-rfc accepted')"
|
|
185
|
-
[ "$status" -eq 0 ]
|
|
186
|
-
silent
|
|
187
|
-
}
|
|
@@ -1,292 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bats
|
|
2
|
-
|
|
3
|
-
# P234 Phase 1: itil-fictional-defer-detect.sh PostToolUse:Write|Edit
|
|
4
|
-
# hook detects "fictional defer" rationales in `docs/retros/*.md` writes
|
|
5
|
-
# — defer-rationale phrases (`next retro`, `next session`, `defer
|
|
6
|
-
# pending`, `defer with cause:`, `deferred per`) that lack a
|
|
7
|
-
# SCHEDULED-FUTURE-SURFACE citation in surrounding context.
|
|
8
|
-
#
|
|
9
|
-
# Detection signal (per ticket Investigation Task 2 two-axis test):
|
|
10
|
-
# 1. tool_name is Write OR Edit AND file_path matches docs/retros/*.md
|
|
11
|
-
# 2. Written file contains a defer-rationale phrase (case-insensitive)
|
|
12
|
-
# 3. Within +/-5 lines of the match there is NO citation of a
|
|
13
|
-
# SCHEDULED-FUTURE-SURFACE (ticket ID P\d{3} / STORY-\d{3} / R\d{3},
|
|
14
|
-
# skill invocation /wr-[a-z-]+:[a-z-]+, hook script path .sh, CI
|
|
15
|
-
# workflow path .github/workflows/, dated ADR ADR-\d{3} ... YYYY-MM-DD)
|
|
16
|
-
# 4. Match is NOT on the exception allowlist (e.g. `deferred per Branch B`).
|
|
17
|
-
#
|
|
18
|
-
# When all four hold, the hook emits a stderr advisory citing P234 + the
|
|
19
|
-
# SCHEDULED-FUTURE-SURFACE definition. Advisory only — never blocks
|
|
20
|
-
# (exit 0 always). Mirrors the itil-rfc-trailer-advisory.sh PostToolUse
|
|
21
|
-
# precedent (stderr + exit 0) and the itil-mid-loop-ask-detect.sh
|
|
22
|
-
# detection-pattern precedent (per-surface configuration at top).
|
|
23
|
-
#
|
|
24
|
-
# Per ADR-005 / ADR-052 — bats live under packages/<plugin>/hooks/test/
|
|
25
|
-
# and assert on emitted stderr text, not source-content. Per P081 — no
|
|
26
|
-
# source-grep on hook text.
|
|
27
|
-
|
|
28
|
-
setup() {
|
|
29
|
-
REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/../../../.." && pwd)"
|
|
30
|
-
HOOK="$REPO_ROOT/packages/itil/hooks/itil-fictional-defer-detect.sh"
|
|
31
|
-
TMPDIR_="$(mktemp -d)"
|
|
32
|
-
RETRO_DIR="$TMPDIR_/docs/retros"
|
|
33
|
-
mkdir -p "$RETRO_DIR"
|
|
34
|
-
RETRO_FILE="$RETRO_DIR/2026-05-17-session-3.md"
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
teardown() {
|
|
38
|
-
rm -rf "$TMPDIR_"
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
# Helper: emit PostToolUse stdin payload for a Write tool call.
|
|
42
|
-
emit_write_payload() {
|
|
43
|
-
local file_path="$1"
|
|
44
|
-
jq -n --arg p "$file_path" '{
|
|
45
|
-
session_id: "fictional-defer-test",
|
|
46
|
-
tool_name: "Write",
|
|
47
|
-
tool_input: { file_path: $p, content: "(content already on disk)" },
|
|
48
|
-
tool_response: { success: true }
|
|
49
|
-
}'
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
# Helper: emit PostToolUse stdin payload for an Edit tool call.
|
|
53
|
-
emit_edit_payload() {
|
|
54
|
-
local file_path="$1"
|
|
55
|
-
jq -n --arg p "$file_path" '{
|
|
56
|
-
session_id: "fictional-defer-test",
|
|
57
|
-
tool_name: "Edit",
|
|
58
|
-
tool_input: { file_path: $p, old_string: "x", new_string: "y" },
|
|
59
|
-
tool_response: { success: true }
|
|
60
|
-
}'
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
run_hook_with_write() {
|
|
64
|
-
emit_write_payload "$RETRO_FILE" | bash "$HOOK"
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
run_hook_with_edit() {
|
|
68
|
-
emit_edit_payload "$RETRO_FILE" | bash "$HOOK"
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
# --- Positive detection: fictional defer ---
|
|
72
|
-
|
|
73
|
-
@test "detect: defer-to-next-retro with no scheduled-future-surface emits advisory" {
|
|
74
|
-
# Faithful reproduction of the P234 worked-example fictional-defer
|
|
75
|
-
# class — the defer-rationale prose carries no SCHEDULED-FUTURE-
|
|
76
|
-
# SURFACE citation; no ticket ID, no skill invocation, no dated ADR
|
|
77
|
-
# appears in the +/-5 line window around the defer phrase.
|
|
78
|
-
cat > "$RETRO_FILE" <<'EOF'
|
|
79
|
-
# Session 3 Retro
|
|
80
|
-
|
|
81
|
-
## Signal-vs-Noise Pass
|
|
82
|
-
|
|
83
|
-
Deferred this retro per session-length constraint (16+ briefing
|
|
84
|
-
entries across 13 topic files would require ~30 min of per-entry
|
|
85
|
-
scoring). Next retro should run a full pass.
|
|
86
|
-
EOF
|
|
87
|
-
run run_hook_with_write
|
|
88
|
-
[ "$status" -eq 0 ]
|
|
89
|
-
[[ "$stderr" == *"P234"* ]] || [[ "$output" == *"P234"* ]]
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
@test "detect: deferred-pending-design-judgement with no scheduled-future-surface emits advisory" {
|
|
93
|
-
cat > "$RETRO_FILE" <<'EOF'
|
|
94
|
-
# Session 4 Retro
|
|
95
|
-
|
|
96
|
-
## Topic File Rotation Candidates
|
|
97
|
-
|
|
98
|
-
| File | Action |
|
|
99
|
-
|------|--------|
|
|
100
|
-
| governance-workflow.md | deferred pending design judgement (cascade case) |
|
|
101
|
-
| hooks-and-gates.md | deferred pending complexity review |
|
|
102
|
-
EOF
|
|
103
|
-
run run_hook_with_write
|
|
104
|
-
[ "$status" -eq 0 ]
|
|
105
|
-
[[ "$stderr" == *"P234"* ]] || [[ "$output" == *"P234"* ]]
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
@test "detect: defer-with-cause-context-budget with no surface emits advisory" {
|
|
109
|
-
cat > "$RETRO_FILE" <<'EOF'
|
|
110
|
-
# Session 5 Retro
|
|
111
|
-
|
|
112
|
-
## Codification Candidates
|
|
113
|
-
|
|
114
|
-
Deferred with cause: context budget pressure. Next session should
|
|
115
|
-
revisit when fresh context is available.
|
|
116
|
-
EOF
|
|
117
|
-
run run_hook_with_edit
|
|
118
|
-
[ "$status" -eq 0 ]
|
|
119
|
-
[[ "$stderr" == *"P234"* ]] || [[ "$output" == *"P234"* ]]
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
# --- Negative paths: legitimate citations (silent exit) ---
|
|
123
|
-
|
|
124
|
-
@test "allow: defer citing P-ticket within +/-5 lines exits silent" {
|
|
125
|
-
cat > "$RETRO_FILE" <<'EOF'
|
|
126
|
-
# Session 3 Retro
|
|
127
|
-
|
|
128
|
-
## Signal-vs-Noise Pass
|
|
129
|
-
|
|
130
|
-
Deferred per [[P235]] (briefing SVN backlog: 146 entries across 17
|
|
131
|
-
topic files). Next retro will surface P235 if it has been promoted
|
|
132
|
-
to actionable.
|
|
133
|
-
EOF
|
|
134
|
-
run run_hook_with_write
|
|
135
|
-
[ "$status" -eq 0 ]
|
|
136
|
-
[[ "$stderr" != *"P234"* ]]
|
|
137
|
-
[[ "$output" != *"P234"* ]]
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
@test "allow: defer citing skill invocation within +/-5 lines exits silent" {
|
|
141
|
-
cat > "$RETRO_FILE" <<'EOF'
|
|
142
|
-
# Session 4 Retro
|
|
143
|
-
|
|
144
|
-
## Tickets Deferred
|
|
145
|
-
|
|
146
|
-
Deferred pending /wr-itil:work-problems Step 6.5 above-appetite
|
|
147
|
-
release-loop check.
|
|
148
|
-
EOF
|
|
149
|
-
run run_hook_with_edit
|
|
150
|
-
[ "$status" -eq 0 ]
|
|
151
|
-
[[ "$stderr" != *"P234"* ]]
|
|
152
|
-
[[ "$output" != *"P234"* ]]
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
@test "allow: defer citing hook script path within +/-5 lines exits silent" {
|
|
156
|
-
cat > "$RETRO_FILE" <<'EOF'
|
|
157
|
-
# Session 5 Retro
|
|
158
|
-
|
|
159
|
-
## Codification Candidates
|
|
160
|
-
|
|
161
|
-
Defer pending packages/itil/hooks/itil-fictional-defer-detect.sh
|
|
162
|
-
extension to also cover the assistant-output review channel.
|
|
163
|
-
EOF
|
|
164
|
-
run run_hook_with_write
|
|
165
|
-
[ "$status" -eq 0 ]
|
|
166
|
-
[[ "$stderr" != *"P234"* ]]
|
|
167
|
-
[[ "$output" != *"P234"* ]]
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
@test "allow: defer citing dated ADR within +/-5 lines exits silent" {
|
|
171
|
-
cat > "$RETRO_FILE" <<'EOF'
|
|
172
|
-
# Session 6 Retro
|
|
173
|
-
|
|
174
|
-
## Codification Candidates
|
|
175
|
-
|
|
176
|
-
Deferred pending ADR-044 confirmation criterion 3 graduation
|
|
177
|
-
(2026-05-25). Reassess after the criterion lands.
|
|
178
|
-
EOF
|
|
179
|
-
run run_hook_with_write
|
|
180
|
-
[ "$status" -eq 0 ]
|
|
181
|
-
[[ "$stderr" != *"P234"* ]]
|
|
182
|
-
[[ "$output" != *"P234"* ]]
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
# --- Exception allowlist ---
|
|
186
|
-
|
|
187
|
-
@test "allow: deferred-per-Branch-B allowlist phrase exits silent" {
|
|
188
|
-
cat > "$RETRO_FILE" <<'EOF'
|
|
189
|
-
# Session 3 Retro
|
|
190
|
-
|
|
191
|
-
## Topic File Rotation Candidates
|
|
192
|
-
|
|
193
|
-
| File | Action |
|
|
194
|
-
|------|--------|
|
|
195
|
-
| governance-workflow.md (ratio 1.5x) | leave-as-is — deferred per Branch B |
|
|
196
|
-
| hooks-and-gates.md (ratio 1.3x) | leave-as-is — deferred per Branch B |
|
|
197
|
-
EOF
|
|
198
|
-
run run_hook_with_write
|
|
199
|
-
[ "$status" -eq 0 ]
|
|
200
|
-
[[ "$stderr" != *"P234"* ]]
|
|
201
|
-
[[ "$output" != *"P234"* ]]
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
# --- Path / tool short-circuits ---
|
|
205
|
-
|
|
206
|
-
@test "allow: tool_name != Write/Edit exits silent" {
|
|
207
|
-
cat > "$RETRO_FILE" <<'EOF'
|
|
208
|
-
Deferred this retro per session-length constraint. Next retro should run.
|
|
209
|
-
EOF
|
|
210
|
-
payload=$(jq -n --arg p "$RETRO_FILE" '{
|
|
211
|
-
session_id: "x",
|
|
212
|
-
tool_name: "Bash",
|
|
213
|
-
tool_input: { command: "ls" },
|
|
214
|
-
tool_response: { stdout: "" }
|
|
215
|
-
}')
|
|
216
|
-
run bash -c "echo '$payload' | bash '$HOOK'"
|
|
217
|
-
[ "$status" -eq 0 ]
|
|
218
|
-
[[ "$stderr" != *"P234"* ]]
|
|
219
|
-
[[ "$output" != *"P234"* ]]
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
@test "allow: file_path outside docs/retros/ exits silent" {
|
|
223
|
-
OTHER="$TMPDIR_/docs/problems/foo.md"
|
|
224
|
-
mkdir -p "$(dirname "$OTHER")"
|
|
225
|
-
cat > "$OTHER" <<'EOF'
|
|
226
|
-
Deferred this retro per session-length constraint. Next retro should run a full pass.
|
|
227
|
-
EOF
|
|
228
|
-
payload=$(jq -n --arg p "$OTHER" '{
|
|
229
|
-
session_id: "x",
|
|
230
|
-
tool_name: "Write",
|
|
231
|
-
tool_input: { file_path: $p, content: "" },
|
|
232
|
-
tool_response: { success: true }
|
|
233
|
-
}')
|
|
234
|
-
run bash -c "echo '$payload' | bash '$HOOK'"
|
|
235
|
-
[ "$status" -eq 0 ]
|
|
236
|
-
[[ "$stderr" != *"P234"* ]]
|
|
237
|
-
[[ "$output" != *"P234"* ]]
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
@test "allow: missing file_path exits silent" {
|
|
241
|
-
payload=$(jq -n '{
|
|
242
|
-
session_id: "x",
|
|
243
|
-
tool_name: "Write",
|
|
244
|
-
tool_input: {},
|
|
245
|
-
tool_response: { success: true }
|
|
246
|
-
}')
|
|
247
|
-
run bash -c "echo '$payload' | bash '$HOOK'"
|
|
248
|
-
[ "$status" -eq 0 ]
|
|
249
|
-
[[ "$stderr" != *"P234"* ]]
|
|
250
|
-
[[ "$output" != *"P234"* ]]
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
# --- Crash safety ---
|
|
254
|
-
|
|
255
|
-
@test "allow: malformed JSON input does not crash the hook" {
|
|
256
|
-
run bash -c "echo 'not-json' | bash '$HOOK'"
|
|
257
|
-
[ "$status" -eq 0 ]
|
|
258
|
-
# Either silent OR a single advisory — but never a non-zero exit.
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
@test "allow: non-existent retro file exits silent" {
|
|
262
|
-
GHOST="$TMPDIR_/docs/retros/does-not-exist.md"
|
|
263
|
-
payload=$(jq -n --arg p "$GHOST" '{
|
|
264
|
-
session_id: "x",
|
|
265
|
-
tool_name: "Write",
|
|
266
|
-
tool_input: { file_path: $p, content: "" },
|
|
267
|
-
tool_response: { success: true }
|
|
268
|
-
}')
|
|
269
|
-
run bash -c "echo '$payload' | bash '$HOOK'"
|
|
270
|
-
[ "$status" -eq 0 ]
|
|
271
|
-
[[ "$stderr" != *"P234"* ]]
|
|
272
|
-
[[ "$output" != *"P234"* ]]
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
# --- Advisory budget per ADR-045 ---
|
|
276
|
-
|
|
277
|
-
@test "advisory output stays under ADR-045 1000-byte honour-system ceiling" {
|
|
278
|
-
cat > "$RETRO_FILE" <<'EOF'
|
|
279
|
-
# Session 3 Retro
|
|
280
|
-
|
|
281
|
-
## Signal-vs-Noise Pass
|
|
282
|
-
|
|
283
|
-
Deferred this retro per session-length constraint. Next retro
|
|
284
|
-
should run a full pass.
|
|
285
|
-
EOF
|
|
286
|
-
emit_write_payload "$RETRO_FILE" > "$TMPDIR_/payload.json"
|
|
287
|
-
# Capture combined stdout+stderr; advisory channel is stderr per
|
|
288
|
-
# PostToolUse precedent (itil-rfc-trailer-advisory.sh).
|
|
289
|
-
combined=$(bash "$HOOK" < "$TMPDIR_/payload.json" 2>&1)
|
|
290
|
-
[ -n "$combined" ]
|
|
291
|
-
[ "${#combined}" -lt 1000 ]
|
|
292
|
-
}
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bats
|
|
2
|
-
|
|
3
|
-
# P345/RFC-044/STORY-038: itil-fix-title-lifecycle-advisory.sh — post-commit
|
|
4
|
-
# ADVISORY for fix-titled commits whose named P<NNN> ticket is still Open on
|
|
5
|
-
# disk (no paired lifecycle transition in the commit). Advisory-only per
|
|
6
|
-
# ADR-092: never blocks, exit 0 on every path. Behavioural (ADR-052).
|
|
7
|
-
|
|
8
|
-
setup() {
|
|
9
|
-
REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/../../../.." && pwd)"
|
|
10
|
-
HOOK="$REPO_ROOT/packages/itil/hooks/itil-fix-title-lifecycle-advisory.sh"
|
|
11
|
-
DIR="$(mktemp -d)"; cd "$DIR"
|
|
12
|
-
git init -q; git config user.email t@e.x; git config user.name t
|
|
13
|
-
mkdir -p docs/problems/open docs/problems/known-error
|
|
14
|
-
echo x > seed; git add -A; git commit -qm "chore: seed"
|
|
15
|
-
}
|
|
16
|
-
teardown() { cd /; rm -rf "$DIR"; }
|
|
17
|
-
|
|
18
|
-
# Feed the hook a PostToolUse Bash payload for a `git commit` command.
|
|
19
|
-
run_hook() {
|
|
20
|
-
printf '{"tool_name":"Bash","tool_input":{"command":"git commit -m x"}}' | bash "$HOOK"
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
commit() { git commit -q --allow-empty -m "$1"; }
|
|
24
|
-
|
|
25
|
-
@test "advises when a fix-titled commit names a still-Open ticket" {
|
|
26
|
-
echo t > docs/problems/open/501-widget-breaks.md
|
|
27
|
-
commit "fix(itil): P501 stop the widget breaking"
|
|
28
|
-
run run_hook
|
|
29
|
-
[ "$status" -eq 0 ]
|
|
30
|
-
[[ "$output" == *"P501"* ]]
|
|
31
|
-
[[ "$output" == *"Open"* ]]
|
|
32
|
-
[[ "$output" == *"transition"* ]]
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
@test "silent when the named ticket is known-error (transition already happened)" {
|
|
36
|
-
echo t > docs/problems/known-error/501-widget-breaks.md
|
|
37
|
-
commit "fix(itil): P501 stop the widget breaking"
|
|
38
|
-
run run_hook
|
|
39
|
-
[ "$status" -eq 0 ]
|
|
40
|
-
[ -z "$output" ]
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
@test "silent when the named ticket does not exist on disk" {
|
|
44
|
-
commit "fix(itil): P999 phantom ticket"
|
|
45
|
-
run run_hook
|
|
46
|
-
[ "$status" -eq 0 ]
|
|
47
|
-
[ -z "$output" ]
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
@test "silent on a non-fix-typed subject naming a P token" {
|
|
51
|
-
echo t > docs/problems/open/501-widget-breaks.md
|
|
52
|
-
commit "docs(problems): P501 add investigation notes"
|
|
53
|
-
run run_hook
|
|
54
|
-
[ "$status" -eq 0 ]
|
|
55
|
-
[ -z "$output" ]
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
@test "silent on a fix-typed subject with no P token" {
|
|
59
|
-
echo t > docs/problems/open/501-widget-breaks.md
|
|
60
|
-
commit "fix(itil): tidy the widget"
|
|
61
|
-
run run_hook
|
|
62
|
-
[ "$status" -eq 0 ]
|
|
63
|
-
[ -z "$output" ]
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
@test "advises on the bare fix: form too" {
|
|
67
|
-
echo t > docs/problems/open/502-gadget-stuck.md
|
|
68
|
-
commit "fix: P502 unstick the gadget"
|
|
69
|
-
run run_hook
|
|
70
|
-
[ "$status" -eq 0 ]
|
|
71
|
-
[[ "$output" == *"P502"* ]]
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
@test "total emission stays at or under 300 bytes with many still-Open tickets" {
|
|
75
|
-
for n in 511 512 513 514 515 516; do
|
|
76
|
-
echo t > "docs/problems/open/${n}-thing-${n}.md"
|
|
77
|
-
done
|
|
78
|
-
commit "fix(itil): P511 P512 P513 P514 P515 P516 mega sweep"
|
|
79
|
-
run run_hook
|
|
80
|
-
[ "$status" -eq 0 ]
|
|
81
|
-
[ -n "$output" ]
|
|
82
|
-
[ "${#output}" -le 300 ]
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
@test "bypass env var suppresses the advisory" {
|
|
86
|
-
echo t > docs/problems/open/501-widget-breaks.md
|
|
87
|
-
commit "fix(itil): P501 stop the widget breaking"
|
|
88
|
-
run env BYPASS_FIX_TITLE_LIFECYCLE_ADVISORY=1 bash -c 'printf "{\"tool_name\":\"Bash\",\"tool_input\":{\"command\":\"git commit -m x\"}}" | bash "$0"' "$HOOK"
|
|
89
|
-
[ "$status" -eq 0 ]
|
|
90
|
-
[ -z "$output" ]
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
@test "silent on non-Bash tool payloads" {
|
|
94
|
-
echo t > docs/problems/open/501-widget-breaks.md
|
|
95
|
-
commit "fix(itil): P501 stop the widget breaking"
|
|
96
|
-
run bash -c 'printf "{\"tool_name\":\"Write\",\"tool_input\":{}}" | bash "$0"' "$HOOK"
|
|
97
|
-
[ "$status" -eq 0 ]
|
|
98
|
-
[ -z "$output" ]
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
@test "silent on non-commit Bash commands" {
|
|
102
|
-
echo t > docs/problems/open/501-widget-breaks.md
|
|
103
|
-
commit "fix(itil): P501 stop the widget breaking"
|
|
104
|
-
run bash -c 'printf "{\"tool_name\":\"Bash\",\"tool_input\":{\"command\":\"git log --oneline\"}}" | bash "$0"' "$HOOK"
|
|
105
|
-
[ "$status" -eq 0 ]
|
|
106
|
-
[ -z "$output" ]
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
@test "fail-open silent when docs/problems is absent" {
|
|
110
|
-
rm -rf docs/problems
|
|
111
|
-
commit "fix(itil): P501 stop the widget breaking"
|
|
112
|
-
run run_hook
|
|
113
|
-
[ "$status" -eq 0 ]
|
|
114
|
-
[ -z "$output" ]
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
@test "fail-open silent outside a git work tree" {
|
|
118
|
-
NOGIT="$(mktemp -d)"; cd "$NOGIT"
|
|
119
|
-
run run_hook
|
|
120
|
-
[ "$status" -eq 0 ]
|
|
121
|
-
[ -z "$output" ]
|
|
122
|
-
cd /; rm -rf "$NOGIT"
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
@test "fail-open silent on malformed JSON input" {
|
|
126
|
-
run bash -c 'printf "not json at all" | bash "$0"' "$HOOK"
|
|
127
|
-
[ "$status" -eq 0 ]
|
|
128
|
-
[ -z "$output" ]
|
|
129
|
-
}
|