@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,307 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bats
|
|
2
|
-
# Behavioural fixtures for itil-pending-questions-surface.sh (P157).
|
|
3
|
-
#
|
|
4
|
-
# SessionStart hook that reads the AFK-loop-accumulated outstanding-questions
|
|
5
|
-
# JSONL queue at .afk-run-state/outstanding-questions.jsonl, ranks entries
|
|
6
|
-
# per ADR-044 6-class taxonomy, and emits an additionalContext directive on
|
|
7
|
-
# stdout for the agent to surface via AskUserQuestion (batched <=4).
|
|
8
|
-
#
|
|
9
|
-
# Per ADR-052 (behavioural-tests-default), these tests exercise the hook's
|
|
10
|
-
# observable stdout / exit-code behaviour against fixture queue files —
|
|
11
|
-
# NOT the prose contents of the script itself.
|
|
12
|
-
#
|
|
13
|
-
# Behavioural surfaces under test:
|
|
14
|
-
# 1. Silent-on-no-content per ADR-040 Mechanism step 1 — missing or empty
|
|
15
|
-
# queue file produces zero stdout and exits 0.
|
|
16
|
-
# 2. Non-empty queue produces additionalContext naming the entries.
|
|
17
|
-
# 3. ADR-044 6-class precedence — when multiple categories present,
|
|
18
|
-
# deviation-approval ranks first; correction-followup ranks last.
|
|
19
|
-
# 4. Deduplication — identical entries (same category + question + ticket_id)
|
|
20
|
-
# collapse to one.
|
|
21
|
-
# 5. Batching directive — when N > 4, output names the AskUserQuestion
|
|
22
|
-
# batched-call cap.
|
|
23
|
-
# 6. Cleanup directive — output instructs the agent to truncate resolved
|
|
24
|
-
# entries from the queue file.
|
|
25
|
-
# 7. AFK-iter cross-context-leak prevention — WR_SUPPRESS_PENDING_QUESTIONS=1
|
|
26
|
-
# env var forces silent exit even when queue is non-empty.
|
|
27
|
-
#
|
|
28
|
-
# @problem P157
|
|
29
|
-
# @jtbd JTBD-006 (progress backlog while AFK — surface accumulated questions
|
|
30
|
-
# on session resume)
|
|
31
|
-
# @jtbd JTBD-001 (enforce governance without slowing down — direction-class
|
|
32
|
-
# observations resolve before user begins foreground work)
|
|
33
|
-
# @jtbd JTBD-101 (extend the suite — sibling SessionStart hook reuses
|
|
34
|
-
# ADR-040 silent-on-no-content shape)
|
|
35
|
-
# @adr ADR-032 (governance skill invocation patterns — P157 amendment for
|
|
36
|
-
# JSONL-queue SessionStart variant)
|
|
37
|
-
# @adr ADR-040 (session-start briefing surface — SessionStart precedent +
|
|
38
|
-
# silent-on-no-content shape)
|
|
39
|
-
# @adr ADR-044 (decision-delegation contract — 6-class taxonomy precedence)
|
|
40
|
-
# @adr ADR-052 (behavioural-tests-default — these tests exercise hook
|
|
41
|
-
# stdout / exit-code, not script prose)
|
|
42
|
-
|
|
43
|
-
setup() {
|
|
44
|
-
REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/../../../.." && pwd)"
|
|
45
|
-
HOOK_SCRIPT="${REPO_ROOT}/packages/itil/hooks/itil-pending-questions-surface.sh"
|
|
46
|
-
|
|
47
|
-
TMPROOT=$(mktemp -d)
|
|
48
|
-
mkdir -p "$TMPROOT/.afk-run-state"
|
|
49
|
-
QUEUE_FILE="$TMPROOT/.afk-run-state/outstanding-questions.jsonl"
|
|
50
|
-
|
|
51
|
-
export CLAUDE_PROJECT_DIR="$TMPROOT"
|
|
52
|
-
unset WR_SUPPRESS_PENDING_QUESTIONS
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
teardown() {
|
|
56
|
-
rm -rf "$TMPROOT"
|
|
57
|
-
unset CLAUDE_PROJECT_DIR WR_SUPPRESS_PENDING_QUESTIONS
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
# ---------------------------------------------------------------------------
|
|
61
|
-
# Existence — minimum surface required for hooks.json to wire it up.
|
|
62
|
-
# ---------------------------------------------------------------------------
|
|
63
|
-
|
|
64
|
-
@test "hook script exists and is executable" {
|
|
65
|
-
[ -f "$HOOK_SCRIPT" ]
|
|
66
|
-
[ -x "$HOOK_SCRIPT" ]
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
@test "hooks.json registers the SessionStart hook with matcher startup" {
|
|
70
|
-
HOOKS_JSON="${REPO_ROOT}/packages/itil/hooks/hooks.json"
|
|
71
|
-
run jq -r '.hooks.SessionStart[] | select(.matcher == "startup") | .hooks[].command' "$HOOKS_JSON"
|
|
72
|
-
[ "$status" -eq 0 ]
|
|
73
|
-
echo "$output" | grep -qF 'itil-pending-questions-surface.sh'
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
# ---------------------------------------------------------------------------
|
|
77
|
-
# Silent-on-no-content per ADR-040 Mechanism step 1.
|
|
78
|
-
# ---------------------------------------------------------------------------
|
|
79
|
-
|
|
80
|
-
@test "missing queue file: silent exit 0" {
|
|
81
|
-
# No queue file at all (typical state for projects that have never run AFK).
|
|
82
|
-
rm -f "$QUEUE_FILE"
|
|
83
|
-
run "$HOOK_SCRIPT"
|
|
84
|
-
[ "$status" -eq 0 ]
|
|
85
|
-
[ -z "$output" ]
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
@test "empty queue file: silent exit 0" {
|
|
89
|
-
: > "$QUEUE_FILE"
|
|
90
|
-
run "$HOOK_SCRIPT"
|
|
91
|
-
[ "$status" -eq 0 ]
|
|
92
|
-
[ -z "$output" ]
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
@test "queue with only whitespace lines: silent exit 0" {
|
|
96
|
-
printf '\n \n\t\n' > "$QUEUE_FILE"
|
|
97
|
-
run "$HOOK_SCRIPT"
|
|
98
|
-
[ "$status" -eq 0 ]
|
|
99
|
-
[ -z "$output" ]
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
# ---------------------------------------------------------------------------
|
|
103
|
-
# Non-empty queue → additionalContext emitted.
|
|
104
|
-
# ---------------------------------------------------------------------------
|
|
105
|
-
|
|
106
|
-
@test "single entry: additionalContext names the question and ticket_id" {
|
|
107
|
-
cat > "$QUEUE_FILE" <<'JSONL'
|
|
108
|
-
{"category":"direction","question":"Pick A or B for the storage layer?","context":"iter1 P200","ticket_id":"P200"}
|
|
109
|
-
JSONL
|
|
110
|
-
run "$HOOK_SCRIPT"
|
|
111
|
-
[ "$status" -eq 0 ]
|
|
112
|
-
echo "$output" | grep -qF 'Pick A or B for the storage layer?'
|
|
113
|
-
echo "$output" | grep -qF 'P200'
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
@test "single entry: output cites the queue file path so user can inspect" {
|
|
117
|
-
cat > "$QUEUE_FILE" <<'JSONL'
|
|
118
|
-
{"category":"direction","question":"Q1","context":"c1","ticket_id":"P201"}
|
|
119
|
-
JSONL
|
|
120
|
-
run "$HOOK_SCRIPT"
|
|
121
|
-
[ "$status" -eq 0 ]
|
|
122
|
-
echo "$output" | grep -qF '.afk-run-state/outstanding-questions.jsonl'
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
# ---------------------------------------------------------------------------
|
|
126
|
-
# ADR-044 6-class precedence ordering.
|
|
127
|
-
# ---------------------------------------------------------------------------
|
|
128
|
-
|
|
129
|
-
@test "ranking: deviation-approval ranks first among mixed categories" {
|
|
130
|
-
cat > "$QUEUE_FILE" <<'JSONL'
|
|
131
|
-
{"category":"correction-followup","question":"low-rank Q","context":"c","ticket_id":"P301"}
|
|
132
|
-
{"category":"direction","question":"mid-rank Q","context":"c","ticket_id":"P302"}
|
|
133
|
-
{"category":"deviation-approval","existing_decision":"ADR-001","contradicting_evidence":"ev","proposed_shape":"amend","rationale":"r","ticket_id":"P303"}
|
|
134
|
-
JSONL
|
|
135
|
-
run "$HOOK_SCRIPT"
|
|
136
|
-
[ "$status" -eq 0 ]
|
|
137
|
-
# The deviation-approval entry's rationale must appear before the direction Q
|
|
138
|
-
# in the output (precedence: deviation-approval > direction > correction-followup).
|
|
139
|
-
DEVIATION_LINE=$(echo "$output" | grep -n 'P303' | head -1 | cut -d: -f1)
|
|
140
|
-
DIRECTION_LINE=$(echo "$output" | grep -n 'mid-rank Q' | head -1 | cut -d: -f1)
|
|
141
|
-
CORRECTION_LINE=$(echo "$output" | grep -n 'low-rank Q' | head -1 | cut -d: -f1)
|
|
142
|
-
[ -n "$DEVIATION_LINE" ]
|
|
143
|
-
[ -n "$DIRECTION_LINE" ]
|
|
144
|
-
[ -n "$CORRECTION_LINE" ]
|
|
145
|
-
[ "$DEVIATION_LINE" -lt "$DIRECTION_LINE" ]
|
|
146
|
-
[ "$DIRECTION_LINE" -lt "$CORRECTION_LINE" ]
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
@test "ranking: full 6-class precedence is deviation > direction > one-time > silent-framework > taste > correction" {
|
|
150
|
-
cat > "$QUEUE_FILE" <<'JSONL'
|
|
151
|
-
{"category":"taste","question":"q-taste","context":"c","ticket_id":"P401"}
|
|
152
|
-
{"category":"correction-followup","question":"q-correction","context":"c","ticket_id":"P402"}
|
|
153
|
-
{"category":"silent-framework","question":"q-silent","context":"c","ticket_id":"P403"}
|
|
154
|
-
{"category":"one-time-override","question":"q-onetime","context":"c","ticket_id":"P404"}
|
|
155
|
-
{"category":"direction","question":"q-direction","context":"c","ticket_id":"P405"}
|
|
156
|
-
{"category":"deviation-approval","existing_decision":"ADR-X","contradicting_evidence":"ev","proposed_shape":"amend","rationale":"q-deviation","ticket_id":"P406"}
|
|
157
|
-
JSONL
|
|
158
|
-
run "$HOOK_SCRIPT"
|
|
159
|
-
[ "$status" -eq 0 ]
|
|
160
|
-
# Capture the line number of each category-tagged ticket marker; assert order.
|
|
161
|
-
L1=$(echo "$output" | grep -n 'P406' | head -1 | cut -d: -f1)
|
|
162
|
-
L2=$(echo "$output" | grep -n 'q-direction' | head -1 | cut -d: -f1)
|
|
163
|
-
L3=$(echo "$output" | grep -n 'q-onetime' | head -1 | cut -d: -f1)
|
|
164
|
-
L4=$(echo "$output" | grep -n 'q-silent' | head -1 | cut -d: -f1)
|
|
165
|
-
L5=$(echo "$output" | grep -n 'q-taste' | head -1 | cut -d: -f1)
|
|
166
|
-
L6=$(echo "$output" | grep -n 'q-correction' | head -1 | cut -d: -f1)
|
|
167
|
-
[ "$L1" -lt "$L2" ]
|
|
168
|
-
[ "$L2" -lt "$L3" ]
|
|
169
|
-
[ "$L3" -lt "$L4" ]
|
|
170
|
-
[ "$L4" -lt "$L5" ]
|
|
171
|
-
[ "$L5" -lt "$L6" ]
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
# ---------------------------------------------------------------------------
|
|
175
|
-
# Deduplication of identical entries.
|
|
176
|
-
# ---------------------------------------------------------------------------
|
|
177
|
-
|
|
178
|
-
@test "dedup: identical entries (same category+question+ticket_id) collapse to one" {
|
|
179
|
-
cat > "$QUEUE_FILE" <<'JSONL'
|
|
180
|
-
{"category":"direction","question":"Same Q","context":"c","ticket_id":"P500"}
|
|
181
|
-
{"category":"direction","question":"Same Q","context":"c","ticket_id":"P500"}
|
|
182
|
-
{"category":"direction","question":"Same Q","context":"different-context-different-iter","ticket_id":"P500"}
|
|
183
|
-
JSONL
|
|
184
|
-
run "$HOOK_SCRIPT"
|
|
185
|
-
[ "$status" -eq 0 ]
|
|
186
|
-
# "Same Q" should appear exactly once in the output (after dedup).
|
|
187
|
-
COUNT=$(echo "$output" | grep -cF 'Same Q')
|
|
188
|
-
[ "$COUNT" -eq 1 ]
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
@test "dedup: different question text on same ticket survives as two entries" {
|
|
192
|
-
cat > "$QUEUE_FILE" <<'JSONL'
|
|
193
|
-
{"category":"direction","question":"Question one","context":"c","ticket_id":"P501"}
|
|
194
|
-
{"category":"direction","question":"Question two","context":"c","ticket_id":"P501"}
|
|
195
|
-
JSONL
|
|
196
|
-
run "$HOOK_SCRIPT"
|
|
197
|
-
[ "$status" -eq 0 ]
|
|
198
|
-
echo "$output" | grep -qF 'Question one'
|
|
199
|
-
echo "$output" | grep -qF 'Question two'
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
# ---------------------------------------------------------------------------
|
|
203
|
-
# Batching directive — names the AskUserQuestion <=4 cap when N > 4.
|
|
204
|
-
# ---------------------------------------------------------------------------
|
|
205
|
-
|
|
206
|
-
@test "batching: output names AskUserQuestion when entries present" {
|
|
207
|
-
cat > "$QUEUE_FILE" <<'JSONL'
|
|
208
|
-
{"category":"direction","question":"Q1","context":"c","ticket_id":"P600"}
|
|
209
|
-
JSONL
|
|
210
|
-
run "$HOOK_SCRIPT"
|
|
211
|
-
[ "$status" -eq 0 ]
|
|
212
|
-
echo "$output" | grep -qiE 'AskUserQuestion'
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
@test "batching: directive cites the <=4-per-call cap" {
|
|
216
|
-
# 5 entries should trigger the batching note since AskUserQuestion caps at 4.
|
|
217
|
-
cat > "$QUEUE_FILE" <<'JSONL'
|
|
218
|
-
{"category":"direction","question":"Q1","context":"c","ticket_id":"P601"}
|
|
219
|
-
{"category":"direction","question":"Q2","context":"c","ticket_id":"P602"}
|
|
220
|
-
{"category":"direction","question":"Q3","context":"c","ticket_id":"P603"}
|
|
221
|
-
{"category":"direction","question":"Q4","context":"c","ticket_id":"P604"}
|
|
222
|
-
{"category":"direction","question":"Q5","context":"c","ticket_id":"P605"}
|
|
223
|
-
JSONL
|
|
224
|
-
run "$HOOK_SCRIPT"
|
|
225
|
-
[ "$status" -eq 0 ]
|
|
226
|
-
echo "$output" | grep -qE '(<=|≤|max(imum)?[ -]?)4|four'
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
# ---------------------------------------------------------------------------
|
|
230
|
-
# Cleanup-on-resolve directive.
|
|
231
|
-
# ---------------------------------------------------------------------------
|
|
232
|
-
|
|
233
|
-
@test "cleanup: output instructs the agent to remove resolved entries from the queue" {
|
|
234
|
-
cat > "$QUEUE_FILE" <<'JSONL'
|
|
235
|
-
{"category":"direction","question":"Q1","context":"c","ticket_id":"P700"}
|
|
236
|
-
JSONL
|
|
237
|
-
run "$HOOK_SCRIPT"
|
|
238
|
-
[ "$status" -eq 0 ]
|
|
239
|
-
# The cleanup directive must instruct removing resolved entries from the
|
|
240
|
-
# queue file. Match on the load-bearing words rather than exact phrasing.
|
|
241
|
-
echo "$output" | grep -qiE '(remove|delete|truncat|clear).*queue|outstanding-questions\.jsonl'
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
# ---------------------------------------------------------------------------
|
|
245
|
-
# AFK-iter cross-context-leak prevention (architect Note 2).
|
|
246
|
-
# ---------------------------------------------------------------------------
|
|
247
|
-
|
|
248
|
-
@test "WR_SUPPRESS_PENDING_QUESTIONS=1 forces silent exit even when queue non-empty" {
|
|
249
|
-
cat > "$QUEUE_FILE" <<'JSONL'
|
|
250
|
-
{"category":"direction","question":"Q-should-not-leak","context":"c","ticket_id":"P800"}
|
|
251
|
-
JSONL
|
|
252
|
-
export WR_SUPPRESS_PENDING_QUESTIONS=1
|
|
253
|
-
run "$HOOK_SCRIPT"
|
|
254
|
-
[ "$status" -eq 0 ]
|
|
255
|
-
[ -z "$output" ]
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
@test "WR_SUPPRESS_PENDING_QUESTIONS=0 does NOT suppress (only =1 does)" {
|
|
259
|
-
cat > "$QUEUE_FILE" <<'JSONL'
|
|
260
|
-
{"category":"direction","question":"Q-must-surface","context":"c","ticket_id":"P801"}
|
|
261
|
-
JSONL
|
|
262
|
-
export WR_SUPPRESS_PENDING_QUESTIONS=0
|
|
263
|
-
run "$HOOK_SCRIPT"
|
|
264
|
-
[ "$status" -eq 0 ]
|
|
265
|
-
echo "$output" | grep -qF 'Q-must-surface'
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
@test "work-problems Step 5 dispatch block exports WR_SUPPRESS_PENDING_QUESTIONS=1 before claude -p" {
|
|
269
|
-
# The orchestrator MUST set WR_SUPPRESS_PENDING_QUESTIONS=1 before each
|
|
270
|
-
# iter subprocess spawn so the queue does not surface inside iter contexts
|
|
271
|
-
# (cross-context leak per ADR-032 line 127).
|
|
272
|
-
WP_SKILL="${REPO_ROOT}/packages/itil/skills/work-problems/SKILL.md"
|
|
273
|
-
[ -f "$WP_SKILL" ]
|
|
274
|
-
# Find the export line; it must come before the "claude -p" dispatch line in
|
|
275
|
-
# the same Step 5 dispatch block.
|
|
276
|
-
EXPORT_LINE=$(grep -n 'export WR_SUPPRESS_PENDING_QUESTIONS=1' "$WP_SKILL" | head -1 | cut -d: -f1)
|
|
277
|
-
CLAUDE_P_LINE=$(grep -n '^claude -p \\$' "$WP_SKILL" | head -1 | cut -d: -f1)
|
|
278
|
-
[ -n "$EXPORT_LINE" ]
|
|
279
|
-
[ -n "$CLAUDE_P_LINE" ]
|
|
280
|
-
[ "$EXPORT_LINE" -lt "$CLAUDE_P_LINE" ]
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
# ---------------------------------------------------------------------------
|
|
284
|
-
# Malformed input — silent skip, do not crash the SessionStart hook chain.
|
|
285
|
-
# ---------------------------------------------------------------------------
|
|
286
|
-
|
|
287
|
-
@test "malformed JSON line: skipped silently, well-formed lines still surface" {
|
|
288
|
-
cat > "$QUEUE_FILE" <<'JSONL'
|
|
289
|
-
{not valid json at all
|
|
290
|
-
{"category":"direction","question":"Valid Q","context":"c","ticket_id":"P900"}
|
|
291
|
-
JSONL
|
|
292
|
-
run "$HOOK_SCRIPT"
|
|
293
|
-
[ "$status" -eq 0 ]
|
|
294
|
-
echo "$output" | grep -qF 'Valid Q'
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
@test "all-malformed queue: silent exit 0 (do not block session start)" {
|
|
298
|
-
# Defensive — if the queue file is corrupted, the hook MUST NOT prevent
|
|
299
|
-
# the session from starting. SessionStart hook failures cascade into
|
|
300
|
-
# "session won't start" UX which is far worse than missing one surfacing.
|
|
301
|
-
cat > "$QUEUE_FILE" <<'JSONL'
|
|
302
|
-
{not json
|
|
303
|
-
also not json
|
|
304
|
-
JSONL
|
|
305
|
-
run "$HOOK_SCRIPT"
|
|
306
|
-
[ "$status" -eq 0 ]
|
|
307
|
-
}
|