@windyroad/itil 0.60.0 → 0.61.0-preview.1033
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.
|
@@ -16,6 +16,24 @@
|
|
|
16
16
|
# Forward-compat: advertises /wr-itil:capture-problem (ADR-032 — not
|
|
17
17
|
# yet shipped) with /wr-itil:manage-problem as the today-target
|
|
18
18
|
# fallback. When capture-problem ships the wording stays valid.
|
|
19
|
+
#
|
|
20
|
+
# P430 / STORY-047 — WR_SUPPRESS_CORRECTION_DETECT is a DISTINCT guard
|
|
21
|
+
# class, not a split of WR_SUPPRESS_OVERSIGHT_NUDGE. That guard means
|
|
22
|
+
# "an absent user cannot ratify"; this one means "nobody authored a
|
|
23
|
+
# correction". A machine-authored iter prompt carrying an ordinary
|
|
24
|
+
# imperative ("DO NOT skip the gate") is not a correction signal, and
|
|
25
|
+
# conflating the two would couple this gate's suppression to the
|
|
26
|
+
# ADR-068 / ADR-047 oversight-nudge contract. Provenance is a property
|
|
27
|
+
# of the spawning process, so the dispatcher asserts it — the hook does
|
|
28
|
+
# not sniff content for it.
|
|
29
|
+
|
|
30
|
+
# Machine-authored prompt: no correction happened and no user is present to act
|
|
31
|
+
# on the nudge. Ahead of the jq parses so the suppressed path costs one string
|
|
32
|
+
# comparison, and before any marker write so the once-per-session budget is not
|
|
33
|
+
# burned by a prompt that produced no output.
|
|
34
|
+
if [ "${WR_SUPPRESS_CORRECTION_DETECT:-}" = "1" ]; then
|
|
35
|
+
exit 0
|
|
36
|
+
fi
|
|
19
37
|
|
|
20
38
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
21
39
|
# shellcheck source=lib/session-marker.sh
|
|
@@ -20,9 +20,15 @@ setup() {
|
|
|
20
20
|
REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/../../../.." && pwd)"
|
|
21
21
|
HOOK="$REPO_ROOT/packages/itil/hooks/itil-correction-detect.sh"
|
|
22
22
|
SID="itil-correction-test-$$-$RANDOM"
|
|
23
|
+
# An AFK iter exports WR_SUPPRESS_CORRECTION_DETECT=1, which the hook
|
|
24
|
+
# self-suppresses on. Unset it so the positive-detection cases below do not
|
|
25
|
+
# false-RED when this suite runs inside such an iter (the P391 hermeticity
|
|
26
|
+
# class). Suppression is asserted per-invocation via `run env ...` instead.
|
|
27
|
+
unset WR_SUPPRESS_CORRECTION_DETECT
|
|
23
28
|
}
|
|
24
29
|
|
|
25
30
|
teardown() {
|
|
31
|
+
unset WR_SUPPRESS_CORRECTION_DETECT
|
|
26
32
|
rm -f "/tmp/itil-correction-detect-announced-${SID}"
|
|
27
33
|
rm -f "/tmp/itil-correction-detect-announced-${SID}-alt"
|
|
28
34
|
}
|
|
@@ -134,3 +140,50 @@ run_hook() {
|
|
|
134
140
|
[ -z "$output" ]
|
|
135
141
|
[ ! -f "/tmp/itil-correction-detect-announced-${SID}" ]
|
|
136
142
|
}
|
|
143
|
+
|
|
144
|
+
# --- P430 / STORY-047: prompt-authorship guard --------------------------------
|
|
145
|
+
# A framework-authored iter prompt carrying an ordinary imperative ("DO NOT
|
|
146
|
+
# skip the gate") is not a correction — nobody is correcting anything, and the
|
|
147
|
+
# absent user cannot act on the nudge. Provenance is a property of the spawning
|
|
148
|
+
# process, so the dispatcher asserts it via env var rather than the hook
|
|
149
|
+
# guessing from content.
|
|
150
|
+
|
|
151
|
+
run_hook_env() {
|
|
152
|
+
local guard="$1" sid="$2" prompt="$3"
|
|
153
|
+
echo "{\"session_id\":\"$sid\",\"prompt\":$(printf '%s' "$prompt" | jq -Rs .)}" \
|
|
154
|
+
| env WR_SUPPRESS_CORRECTION_DETECT="$guard" bash "$HOOK"
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
@test "correction-detect: WR_SUPPRESS_CORRECTION_DETECT=1 suppresses a correction prompt" {
|
|
158
|
+
run run_hook_env 1 "$SID" "DO NOT skip the architect gate"
|
|
159
|
+
[ "$status" -eq 0 ]
|
|
160
|
+
[ -z "$output" ]
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
@test "correction-detect: suppressed path writes no announcement marker" {
|
|
164
|
+
run run_hook_env 1 "$SID" "FFS, you didn't run the test"
|
|
165
|
+
[ "$status" -eq 0 ]
|
|
166
|
+
[ -z "$output" ]
|
|
167
|
+
# The once-per-session budget must survive a prompt that produced no output,
|
|
168
|
+
# or the first real correction in the orchestrator session emits only the
|
|
169
|
+
# terse reminder.
|
|
170
|
+
[ ! -f "/tmp/itil-correction-detect-announced-${SID}" ]
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
@test "correction-detect: same prompt still fires with the guard unset" {
|
|
174
|
+
run run_hook "$SID" "DO NOT skip the architect gate"
|
|
175
|
+
[ "$status" -eq 0 ]
|
|
176
|
+
[ "${#output}" -gt 300 ]
|
|
177
|
+
[[ "$output" == *"MANDATORY"* ]]
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
@test "correction-detect: only the literal value 1 suppresses" {
|
|
181
|
+
for v in 0 true yes ""; do
|
|
182
|
+
run run_hook_env "$v" "$SID-$RANDOM" "FFS, that's wrong"
|
|
183
|
+
[ "$status" -eq 0 ]
|
|
184
|
+
[ -n "$output" ] || {
|
|
185
|
+
echo "guard value '$v' wrongly suppressed"
|
|
186
|
+
false
|
|
187
|
+
}
|
|
188
|
+
done
|
|
189
|
+
}
|
package/package.json
CHANGED
|
@@ -582,6 +582,16 @@ export WR_SUPPRESS_PENDING_QUESTIONS=1
|
|
|
582
582
|
# pending-questions guard above (JTBD-006 friction guard).
|
|
583
583
|
export WR_SUPPRESS_OVERSIGHT_NUDGE=1
|
|
584
584
|
|
|
585
|
+
# AFK-iter correction-signal suppression (P430 / JTBD-006): the iteration prompt
|
|
586
|
+
# this loop writes is machine-authored, so an ordinary imperative in it ("DO NOT
|
|
587
|
+
# skip the gate") is not a user correcting anything, and no user is present to
|
|
588
|
+
# act on the capture nudge. itil-correction-detect.sh self-suppresses when this
|
|
589
|
+
# env var is set. A real correction is typed into the ORCHESTRATOR session,
|
|
590
|
+
# where this is unset, so P078 is preserved. Distinct guard class from the
|
|
591
|
+
# oversight nudge above — that one means "cannot ratify", this one means
|
|
592
|
+
# "nobody authored a correction".
|
|
593
|
+
export WR_SUPPRESS_CORRECTION_DETECT=1
|
|
594
|
+
|
|
585
595
|
# Project-scoped governance plugins are NOT loaded by headless `claude -p`
|
|
586
596
|
# (P382): it activates only USER-scoped enabledPlugins, and project activation
|
|
587
597
|
# is trust-gated (headless skips trust), so `--setting-sources user,project`
|