@windyroad/itil 2.0.0 → 2.1.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.
@@ -167,7 +167,7 @@ Update from <downstream-repo-url>/<local-ticket-relative-path>:
167
167
 
168
168
  <one-sentence summary from the local ticket's ## Fix Released section>
169
169
 
170
- Please upgrade and verify when convenient. We'll close this issue after your confirmation OR after a 14-day quiet period (per the "Problem 048: manage-problem does not surface Fix Released problems as verification candidates when the fix path has been exercised" problem default). Local tracking: P<NNN>.
170
+ Please upgrade and verify when convenient. We'll close this issue after your confirmation. If you'd rather we closed it without one, say so here. Local tracking: P<NNN>.
171
171
  ```
172
172
 
173
173
  #### Verification Pending → Closed template
@@ -175,12 +175,38 @@ Please upgrade and verify when convenient. We'll close this issue after your con
175
175
  ```markdown
176
176
  Update from <downstream-repo-url>/<local-ticket-relative-path>:
177
177
 
178
- **Status**: Closed locally after user-side verification.
178
+ **Status**: Closed locally after verification.
179
179
 
180
- Closing this issue to match. Thanks for the report — your filing is what got this on the queue. Local tracking: P<NNN>.
180
+ Thanks for the report — your filing is what got this on the queue. Local tracking: P<NNN>.
181
181
  ```
182
182
 
183
- After posting the Verifying → Closed comment, the skill also runs `gh issue close <n>` (per Step 5b below) so the upstream tracker matches local state.
183
+ After posting the Verifying → Closed comment, leave the foreign issue open by default. Closing it requires the target-bound upstream-party confirmation below.
184
+
185
+ #### Foreign issues close only on target-bound upstream-party confirmation
186
+
187
+ Local evidence or local user confirmation can close our ticket, but neither decides another maintainer's tracker state. Post the lifecycle comment and **stop there** unless the local ticket's `## Reported Upstream` section carries this durable, target-bound signal:
188
+
189
+ ```markdown
190
+ - **Closure authority**: upstream-confirmed <exact GitHub issue-comment URL>
191
+ ```
192
+
193
+ Before running `gh issue close`, validate that URL read-only: it MUST be an `#issuecomment-<id>` URL on the exact `UPSTREAM_OWNER_REPO/issues/UPSTREAM_ISSUE_NUMBER` target; `gh api repos/<owner>/<repo>/issues/comments/<id>` MUST return that exact issue URL; `author_association` MUST be `OWNER`, `MEMBER`, or `COLLABORATOR`; and the comment body MUST unambiguously authorize closing this issue. A missing marker, URL mismatch, API failure, non-maintainer association, or ambiguous body leaves the issue open. Never infer this authority from a local `user-confirmed` Status marker.
194
+
195
+ Read the Status line, not the README's `Likely verified?` cell: the close deletes that row from the Verification Queue before this step runs, so the cell is gone by the time anything could read it.
196
+
197
+ Confirmation from the upstream party may authorize closing their issue; their word, not our evidence, supplies the missing authority. Do not promise a quiet-period close that no mechanism delivers.
198
+
199
+ When target-bound confirmation is absent, use the evidence-authorised local-close-only variant below and record `posted-comment-local-close-only` in the back-write disclosure path. When validation succeeds, use the ordinary Closed template and record `posted-comment-and-closed`.
200
+
201
+ ```markdown
202
+ Update from <downstream-repo-url>/<local-ticket-relative-path>:
203
+
204
+ **Status**: Closed locally. We verified the fix on our side — <one-line evidence citation>.
205
+
206
+ Leaving this issue open for you. Close it whenever you have confirmed the fix works in your setup. Local tracking: P<NNN>.
207
+ ```
208
+
209
+ On this leg, without validated target-bound confirmation from them: comment, do not close. Pull requests are always comment-only, even if they carry a confirmation marker.
184
210
 
185
211
  #### Template-filling rules
186
212
 
@@ -256,7 +282,7 @@ gh issue comment "${UPSTREAM_ISSUE_NUMBER}" \
256
282
 
257
283
  Capture the returned comment URL (gh prints `https://github.com/<owner>/<repo>/issues/<n>#issuecomment-<id>`).
258
284
 
259
- On the **Verifying → Closed** transition, after posting the comment, also close the upstream issue:
285
+ On the **Verifying → Closed** transition, after posting the comment, close the upstream issue only when the target-bound `Closure authority` validation above passed:
260
286
 
261
287
  ```bash
262
288
  gh issue close "${UPSTREAM_ISSUE_NUMBER}" \
@@ -287,7 +313,7 @@ Append a log entry to the local ticket's `## Upstream Lifecycle Updates` section
287
313
  - **<YYYY-MM-DD>** — Open → Known Error
288
314
  - **Target URL**: <upstream-issue-url>
289
315
  - **Comment URL**: <posted-comment-url> (or "queued — see ## Queued Upstream Update" when above-appetite)
290
- - **Disclosure path**: posted-comment | posted-pr-comment (pull-request target, the "Prefer an upstream pull request over an issue when the upstream accepts pull requests" architecture rule — never closed) | posted-comment-and-closed (Verifying → Closed, issue targets only) | queued-above-appetite | closed-already-upstream | skipped-out-of-band
316
+ - **Disclosure path**: posted-comment | posted-pr-comment (pull-request target — never closed) | posted-comment-and-closed (confirmed Verifying → Closed, issue targets only) | posted-comment-local-close-only (outbound evidence-authorised close) | queued-above-appetite | closed-already-upstream | skipped-out-of-band
291
317
  - **Gate verdict**: external-comms <band/score> + voice-tone <pass|fail>
292
318
 
293
319
  - **<YYYY-MM-DD>** — Known Error → Verification Pending
@@ -306,7 +332,51 @@ This leg runs **in addition to** Steps 2–6 (the outbound `## Reported Upstream
306
332
 
307
333
  #### I1. Parse the inbound origin
308
334
 
309
- From the `**Origin**: inbound-reported (#NN)` field, extract the originating issue number `NN`. Resolve the repo it lives on as **our own repo** — the `gh` default for the current working tree (`gh repo view --json nameWithOwner -q .nameWithOwner`), NOT an external upstream owner/repo. If the `**Origin**` field is `internal` or absent, this leg does not run (the no-op is already handled at Step 1 when both surfaces are absent).
335
+ From the `**Origin**: inbound-reported (#NN)` field, extract the candidate number `NN`. That untyped number is not proof of an issue: issues, discussions, and advisories have distinct mutation paths, and numeric identifiers can collide.
336
+
337
+ Before any inbound `gh issue view`, `gh issue comment`, or `gh issue close`, prove the channel from the committed discovery cache:
338
+
339
+ ```bash
340
+ OWN_OWNER_REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner)
341
+ LOCAL_TICKET_ID="P${LOCAL_ID}"
342
+ ISSUE_CHANNEL="github-issues:${OWN_OWNER_REPO}"
343
+ CACHE_REF="HEAD:docs/problems/.upstream-cache.json"
344
+ CACHE_JSON=$(git show "${CACHE_REF}" 2>/dev/null) || CACHE_JSON='{}'
345
+
346
+ ISSUE_NUMBER_MATCHES=$(printf '%s' "${CACHE_JSON}" | jq \
347
+ --arg channel "${ISSUE_CHANNEL}" \
348
+ --argjson number "${NN}" \
349
+ '[.channels[$channel].reports[]? | select(.number == $number)] | length' \
350
+ 2>/dev/null) || ISSUE_NUMBER_MATCHES=0
351
+
352
+ ISSUE_TICKET_MATCHES=$(printf '%s' "${CACHE_JSON}" | jq \
353
+ --arg channel "${ISSUE_CHANNEL}" \
354
+ --argjson number "${NN}" \
355
+ --arg ticket "${LOCAL_TICKET_ID}" \
356
+ '[.channels[$channel].reports[]? |
357
+ select(.number == $number and .matched_local_ticket == $ticket)] | length' \
358
+ 2>/dev/null) || ISSUE_TICKET_MATCHES=0
359
+
360
+ NON_ISSUE_MATCHES=$(printf '%s' "${CACHE_JSON}" | jq \
361
+ --arg issue_channel "${ISSUE_CHANNEL}" \
362
+ --arg repo_suffix ":${OWN_OWNER_REPO}" \
363
+ --argjson number "${NN}" \
364
+ '[.channels | to_entries[] |
365
+ select(.key != $issue_channel and (.key | endswith($repo_suffix))) |
366
+ .value.reports[]? | select(.number == $number)] | length' \
367
+ 2>/dev/null) || NON_ISSUE_MATCHES=0
368
+
369
+ if [ "${ISSUE_NUMBER_MATCHES}" -ne 1 ] || \
370
+ [ "${ISSUE_TICKET_MATCHES}" -ne 1 ] || \
371
+ [ "${NON_ISSUE_MATCHES}" -ne 0 ]; then
372
+ echo "inbound-channel-unresolved: ${LOCAL_TICKET_ID} #${NN}"
373
+ INBOUND_CHANNEL_RESOLVED=0
374
+ else
375
+ INBOUND_CHANNEL_RESOLVED=1
376
+ fi
377
+ ```
378
+
379
+ When `INBOUND_CHANNEL_RESOLVED=0`, skip I2–I6 and perform no inbound issue operation; an independent outbound leg may still continue. Missing committed cache data, zero or multiple issue matches, a repository mismatch, a wrong `matched_local_ticket`, or a discussion/advisory collision all take this path. If the Origin field is `internal` or absent, this leg does not run.
310
380
 
311
381
  #### I2. Determine the transition (same suffix logic as Step 3)
312
382
 
@@ -430,12 +500,14 @@ Above-appetite handling is identical to Step 5c (silent risk-reduce + re-score;
430
500
  gh issue comment "${NN}" --repo "${OWN_OWNER_REPO}" --body "${INBOUND_BODY}"
431
501
  ```
432
502
 
433
- On the **Verification Pending → Closed** transition, after the comment, also close the originating issue so our own tracker matches the local `.closed.md` state (this addresses the "work-problems orchestrator carries prior-ticket Fix Strategy text into iter dispatch without re-grounding in design intent" problem #97 *silent-and-unclosed* witness):
503
+ On the **Verification Pending → Closed** transition, after the comment, close the provenance-proven issue on this project's tracker whether the local close was confirmed or evidence-authorised:
434
504
 
435
505
  ```bash
436
506
  gh issue close "${NN}" --repo "${OWN_OWNER_REPO}" --comment "" --reason completed
437
507
  ```
438
508
 
509
+ This outbound guard does not apply to a provenance-proven GitHub issue on this project's own repository. After the gated comment, close it whether the local close was evidence-authorised or confirmed; the reporter can reopen it. Unknown or non-issue inbound channels already stopped at the provenance guard.
510
+
439
511
  If the issue is already closed (someone closed it manually), `gh issue close` returns a benign error — record `closed-already` in the disclosure path and continue.
440
512
 
441
513
  #### I6. Back-write to the lifecycle log
@@ -446,7 +518,7 @@ Append to the same `## Upstream Lifecycle Updates` log (Step 6 shape), tagged fo
446
518
  - **<YYYY-MM-DD>** — Known Error → Verification Pending (inbound)
447
519
  - **Target**: inbound #<NN> (own repo <OWN_OWNER_REPO>)
448
520
  - **Comment URL**: <posted-comment-url> (or "skipped — already-posted-inbound" when the idempotency guard matched, or "queued — see ## Queued Upstream Update" when above-appetite)
449
- - **Disclosure path**: posted-inbound-comment | posted-inbound-comment-and-closed (Verifying Closed) | already-posted-inbound | queued-above-appetite | closed-already
521
+ - **Disclosure path**: posted-inbound-comment | posted-inbound-comment-and-closed (proven owned issue, confirmed or evidence-authorised close) | already-posted-inbound | queued-above-appetite | closed-already | inbound-channel-unresolved
450
522
  - **Gate verdict**: external-comms <band/score> + voice-tone <pass|fail>
451
523
  ```
452
524
 
@@ -340,7 +340,7 @@ Read `docs/problems/README.md` if it exists and is fresh (check via git history
340
340
  Exclude:
341
341
  - `.closed.md` files (done)
342
342
  - `.parked.md` files (blocked on upstream)
343
- - `.verifying.md` files (Verification Pending — fix released, awaiting user verification per the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule; surfaced in the Verification Queue section, never in dev-work ranking)
343
+ - `.verifying.md` files (Verification Pending — fix released, awaiting verification per the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule; surfaced in the Verification Queue section, never in dev-work ranking). The multiplier-0 ranking exclusion is deliberate and unchanged: verification is not dev work and does not compete for a WSJF slot. Evidence-backed closure reaches these tickets through the Step 6.1 verification drain instead (the "The Verification Pending → Closed transition is reserved for the maintainer, so evidence-based closure never fires and the verification queue grows without bound" problem).
344
344
  - Problems with no WSJF score (need a review first — run `/wr-itil:review-problems` as the first iteration if scores are missing)
345
345
 
346
346
  ### Step 2: Check stop conditions
@@ -348,7 +348,7 @@ Exclude:
348
348
  Stop the loop and report a summary if any of these are true:
349
349
 
350
350
  1. **No actionable problems** — zero open or known-error problems remain
351
- 2. **All remaining problems require interactive input** — e.g., they all need user verification (known-errors with `## Fix Released`), or their scope expanded beyond what's safe to auto-resolve
351
+ 2. **All remaining problems require interactive input** — their scope expanded beyond what's safe to auto-resolve, or they need user verification with **no evidence available**. A verifying ticket carrying cited evidence (a `yes — observed: <citation>` Verification Queue cell, or an in-session exercise the loop can cite) is **not** interactive-gated — it is drainable by evidence-backed closure per the "The Verification Pending → Closed transition is reserved for the maintainer, so evidence-based closure never fires and the verification queue grows without bound" problem, and its presence disproves this stop condition.
352
352
  3. **All remaining problems are blocked** — investigation hit a dead end, or the fix requires changes outside the project
353
353
 
354
354
  **Step 2.5 fires unconditionally at loop end** (the "Decision-delegation contract — agents over-apply Rule 1's interactive default to framework-resolved decisions; codify the framework-resolution boundary + AFK loop's batched-questions-as-deliverable + lazy-AskUserQuestion measurement" problem Phase 3 / the "— Decision-Delegation Contract: when agents act on the framework vs ask the user" architecture rule) — promoted from "fallback when stop-condition #2" to **default loop-end emit shape**. Anti-BUFD framing per the "— Decision-Delegation Contract: when agents act on the framework vs ask the user" architecture rule: the AFK loop is the empirical-discovery engine; direction-class observations + deviation-candidates accumulate from real friction across iters; loop-end batched presentation is the user-facing deliverable. Per-iter surfacing was the old (now-superseded) pattern; Phase 3 makes batch-at-loop-end the default for ALL stop conditions, not just #2.
@@ -361,15 +361,15 @@ Before the orchestrator emits the final `ALL_DONE` sentinel for the AFK loop, it
361
361
 
362
362
  **Gate (0) — Objective backlog-empty assertion (the "agent ends the work-problems loop (emits ALL_DONE) prematurely while actionable Tier-2 backlog remains, by rationalising the remainder as out-of-scope / interactive-gated" problem, fires FIRST, before gate (a)).** Before the rest of the sequence runs, the orchestrator MUST re-scan the live backlog and prove that the Step 2 stop-condition it is about to act on OBJECTIVELY holds. `ALL_DONE` is forbidden while ≥1 dispatchable ticket remains — a non-empty actionable backlog is itself the disproof of stop-condition #1/#2/#3.
363
363
 
364
- 1. *Re-scan.* Re-run the Step 1 dual-tolerant glob `ls docs/problems/*.open.md docs/problems/*.known-error.md docs/problems/open/*.md docs/problems/known-error/*.md 2>/dev/null` (the ": docs/problems/ flat layout migration — per-state subdirs + adopter auto-migration" release design window — both layouts). This is a fresh filesystem read, NOT a re-use of the Step 1 cache or the agent's recollection — tickets may have transitioned, closed, or been created by prior iters / the session-level retro since Step 1.
364
+ 1. *Re-scan.* Re-run the Step 1 dual-tolerant glob, **extended to the verification queue** so evidence-bearing verifying tickets can appear in the classification at all: `ls docs/problems/*.open.md docs/problems/*.known-error.md docs/problems/*.verifying.md docs/problems/open/*.md docs/problems/known-error/*.md docs/problems/verifying/*.md 2>/dev/null` (the ": docs/problems/ flat layout migration — per-state subdirs + adopter auto-migration" release design window — both layouts). Without the `verifying` half the dispatchable-verifying arm below has no input set and the Step 6.1 drain is unreachable — the enumeration is the load-bearing half of the "The Verification Pending → Closed transition is reserved for the maintainer, so evidence-based closure never fires and the verification queue grows without bound" problem fix, not the prose. This is a fresh filesystem read, NOT a re-use of the Step 1 cache or the agent's recollection — tickets may have transitioned, closed, or been created by prior iters / the session-level retro since Step 1.
365
365
 
366
366
  2. *Classify each ticket as dispatchable or not — objectively, per recorded marker, never by salience.* A ticket is **non-dispatchable** ONLY when an objective, recorded condition excludes it:
367
- - it is `verifying` / carries `## Fix Released` awaiting user verification (stop-condition #2, interactive);
367
+ - it is `verifying` / carries `## Fix Released` **and no evidence is available for it** (stop-condition #2, interactive). A verifying ticket is **dispatchable to the verification drain** when its Verification Queue cell reads `yes — observed: <citation>`, or when this session can itself cite an exercise of the fix per the "Agent output grounding — no fabricated quantitative estimates, cite + persist + uncertainty" architecture rule (test invocation + outcome, commit SHA covering the fix path, skill/hook invocation that behaved as the fix contracts, a post-release invocation of the shipped artefact that behaved as the fix contracts). Before classifying such a ticket dispatchable, run `wr-itil-is-close-blocked <NNN> docs/problems`: exit 0 means a recorded do-not-close marker is present, which makes it non-dispatchable on that marker (record the marker line as the deciding evidence in the printed table). Blanket-excluding every `verifying` ticket is the "The Verification Pending → Closed transition is reserved for the maintainer, so evidence-based closure never fires and the verification queue grows without bound" problem defect — it made the queue structurally unreachable, and 153 tickets accumulated behind it;
368
368
  - it carries an upstream-blocked marker (`## Reported Upstream` / `- **Upstream report pending** --` / em-dash legacy) or a recorded blocked classification with a dead-end investigation (stop-condition #3);
369
- - it was filtered out THIS session by Step 3.5 (interactive-ratification predicate) or Step 3.6 (already-shipped relevance gate) — keyed off the durable per-session skip record those steps write (the `outstanding_questions` entry in `.afk-run-state/outstanding-questions.jsonl` carrying the ticket id), NOT agent recollection, so the classification is reproducible across the re-scan and cannot loop forever;
369
+ - it was filtered out THIS session by Step 3.5 (interactive-ratification predicate), Step 3.6 (already-shipped relevance gate), or Step 6.1 (verification drain a candidate whose dispatch failed) — keyed off the durable per-session skip record those steps write (the `outstanding_questions` entry in `.afk-run-state/outstanding-questions.jsonl` carrying the ticket id), NOT agent recollection, so the classification is reproducible across the re-scan and cannot loop forever. Step 6.1's record is load-bearing here: without this clause naming it, a drain-failed `.verifying.md` ticket still carries its evidence cell and still passes `wr-itil-is-close-blocked`, so gate (0) would re-classify it dispatchable, route it back to Step 6.1, and fail again — trading a routes-to-a-step-that-declines-to-run livelock for a routes-to-a-step-that-always-fails one;
370
370
  Every other open / known-error ticket is **dispatchable** — ordinary autonomous fix-and-commit work. The agent MUST NOT reclassify a dispatchable ticket as non-dispatchable because the *salient* remainder of the backlog is interactive-gated, because the ticket "feels" out of scope, or because a user-directed pivot consumed the loop's attention. The subjective "this is a natural stopping point" judgement is exactly the "agent ends the work-problems loop (emits ALL_DONE) prematurely while actionable Tier-2 backlog remains, by rationalising the remainder as out-of-scope / interactive-gated" problem failure; the classification is per-ticket and marker-bound. **The classification MUST be PRINTED as a table in the turn output** (ticket → dispatchable/non-dispatchable → the recorded marker that decided) — not merely computed. A computed-but-unprinted re-scan is invisible to the Step 0e `/goal` external evaluator, which judges only what the transcript surfaces (the "Agent output grounding — no fabricated quantitative estimates, cite + persist + uncertainty" architecture rule grounding); the printed table is the evidence the canonical goal condition names.
371
371
 
372
- 3. *Decide.* If the re-scan yields **≥1 dispatchable ticket**, `ALL_DONE` is FORBIDDEN: the stop-condition the orchestrator was about to emit does NOT objectively hold. The orchestrator loops back to Step 3 tier-first selection (Critical-bypass → Inbound-reported → Internal, within-tier WSJF per the "Inbound-reported problems rank ahead of internally-discovered problems via a sort tier" architecture rule) over the dispatchable set and dispatches the next iter — it does NOT proceed to gate (a)/(b)/(c). Only when the re-scan yields **zero dispatchable tickets** does gate (0) pass and the sequence proceed to gate (a). Gate (0) finding work is a **loopback, not a halt** — it is productive (the loop resumes draining), so it is NOT a Hard-fail halt trigger.
372
+ 3. *Decide.* If the re-scan yields **≥1 dispatchable ticket**, `ALL_DONE` is FORBIDDEN: the stop-condition the orchestrator was about to emit does NOT objectively hold. Route by class. A dispatchable **open / known-error** ticket loops back to Step 3 tier-first selection (Critical-bypass → Inbound-reported → Internal, within-tier WSJF per the "Inbound-reported problems rank ahead of internally-discovered problems via a sort tier" architecture rule) over the dispatchable set. A dispatchable **verifying** ticket routes to the **Step 6.1 verification drain — never to Step 3**: Step 1 excludes `.verifying.md` from dev-work ranking under the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule's multiplier-0 rule and Step 3 selects only from the ranked set, so sending it to Step 3 would either conflict with that rule or leave it with no consumer while this gate forbids `ALL_DONE` — a livelock. Having routed, the orchestrator dispatches the next iter — it does NOT proceed to gate (a)/(b)/(c). Only when the re-scan yields **zero dispatchable tickets** does gate (0) pass and the sequence proceed to gate (a). Gate (0) finding work is a **loopback, not a halt** — it is productive (the loop resumes draining), so it is NOT a Hard-fail halt trigger.
373
373
 
374
374
  **Why gate (0) fires first**: gates (a)/(b)/(c) (surface questions → retro → emit) presume the loop is genuinely done; running the retro and emitting `ALL_DONE` while dispatchable work remains prematurely ends the AFK drain (the "agent ends the work-problems loop (emits ALL_DONE) prematurely while actionable Tier-2 backlog remains, by rationalising the remainder as out-of-scope / interactive-gated" problem), forcing the user to re-prompt "keep working the backlog" and defeating the ": Progress the Backlog While I'm Away" user outcome. Gate (0) makes "the backlog is objectively empty of dispatchable tickets" a hard, re-verified precondition of the whole sequence rather than a subjective agent judgement. A user-directed mid-loop pivot (e.g. an eval-cohort detour) does NOT discharge the Tier-exhaustion obligation: after the pivot, gate (0)'s re-scan resumes tier selection rather than terminating — which also catches the "agent ends the work-problems loop (emits ALL_DONE) prematurely while actionable Tier-2 backlog remains, by rationalising the remainder as out-of-scope / interactive-gated" problem coverage miss where a Tier-1 ticket (the "work-problems `claude -p` iter subprocesses miss project-scoped governance plugins (need `--plugin-dir` in dispatch)" problem) was skipped entirely. Sibling class: the "run-retro skips Step 1.5 / Step 3 / Step 4b Stage 1 under session-length rationalization — recurrence of anti-pattern class on the run-retro meta-surface" problem (run-retro skip rationalisation), the "Agent defers ticket creation to retro summary "Tickets Deferred" section instead of immediately invoking `/wr-itil:manage-problem` — observations could be lost if user is in a rush" problem (Stage-1 ticketing skip), the "Agent over-narrows scope-pin words ("just", "only", "first") into count constraints — halts AFK loop on agent-inferred scope rather than framework-prescribed stop conditions" problem (scope-pin loop-control inference) — all agent-invented loop-control stops the framework did not authorise (the "— Decision-Delegation Contract: when agents act on the framework vs ask the user" architecture rule "Continue / stop loops" is framework-resolved: the natural stop is concrete — `ALL_DONE` conditions objectively met — not "this feels done").
375
375
 
@@ -521,7 +521,9 @@ Read the problem file and apply these deterministic rules:
521
521
 
522
522
  | Problem state | Action | Skip-reason category |
523
523
  |---|---|---|
524
- | `.verifying.md` (Verification Pending, per the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule) | **Skip** fix released, awaiting user verification | user-answerable (verification) |
524
+ <!-- The two verifying rows below are reached from the Step 6.1 verification drain and from gate (0)'s verifying-class routing — NOT from the normal Step 1 → Step 3 path, which excludes .verifying.md from WSJF ranking per the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule (multiplier 0). They are stated here so the classification rule lives in one place; Step 6.1 is where they fire. -->
525
+ | `.verifying.md` (Verification Pending) **carrying cited evidence** — a `yes — observed: <citation>` Verification Queue cell, or an exercise this session can cite per the "Agent output grounding — no fabricated quantitative estimates, cite + persist + uncertainty" architecture rule — and `wr-itil-is-close-blocked` exits 1 | **Work it** — dispatch `/wr-itil:transition-problem <NNN> close`, citing the evidence. Mechanical stage; no `AskUserQuestion` (the "The Verification Pending → Closed transition is reserved for the maintainer, so evidence-based closure never fires and the verification queue grows without bound" problem / the "— Decision-Delegation Contract: when agents act on the framework vs ask the user" architecture rule category 4). Report the recovery path. | — |
526
+ | `.verifying.md` with **no evidence**, or `wr-itil-is-close-blocked` exits 0 (recorded do-not-close marker) | **Skip** — absence of evidence is not evidence; a recorded marker outranks evidence | user-answerable (verification) |
525
527
  | Known Error with fix strategy documented | **Work it** — implement the fix (on release, transition to `.verifying.md` per the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule) | — |
526
528
  | Known Error without fix strategy | **Work it** — produce a fix strategy, then implement | — |
527
529
  | Open problem with preliminary hypothesis or investigation notes | **Work it** — continue the investigation | — |
@@ -844,9 +846,37 @@ Format as a brief status line, not a wall of text. The user will read these when
844
846
  ```
845
847
  [Iteration 1] Worked the "Problem 029: Edit gate overhead disproportionate for governance documentation changes" problem (Edit gate overhead for governance docs) — implemented fix, closed. 8 problems remain. ($0.32, 23s, 171K tokens)
846
848
  [Iteration 2] Worked the "Problem 021: Governance-skill decision prompts must be structured (AskUserQuestion + plan mode), not prose — silent below appetite" problem (Governance skill structured prompts) — investigated root cause, transitioned to known-error. 7 problems remain. Risk register: 1 entry scaffolded (pending review). ($0.85, 47s, 432K tokens)
847
- [Iteration 3] Skipped the "Problem 016: `manage-problem` skill does not flag or split multi-concern tickets" problem (Multi-concern ticket splitting) — fix released, awaiting user verification. Worked the "Problem 024: Risk-scorer WIP mode should flag uncommitted completed work and encourage commits" problem (Risk scorer WIP flag) — implemented fix, closed. 6 problems remain. ($1.12, 62s, 541K tokens)
849
+ [Iteration 3] Skipped the "Problem 016: `manage-problem` skill does not flag or split multi-concern tickets" problem (Multi-concern ticket splitting) — fix released, no evidence available yet. Closed the "Problem 011: Grep-based BATS tests produce false positives on legitimate refactors" problem on evidence (bats 14/14 green at iter 2 exercised the fix path). Worked the "Problem 024: Risk-scorer WIP mode should flag uncommitted completed work and encourage commits" problem (Risk scorer WIP flag) — implemented fix, closed. 6 problems remain. ($1.12, 62s, 541K tokens)
848
850
  ```
849
851
 
852
+ ### Step 6.1: Drain the verification queue on evidence (the "The Verification Pending → Closed transition is reserved for the maintainer, so evidence-based closure never fires and the verification queue grows without bound" problem)
853
+
854
+ Step 1 excludes `.verifying.md` tickets from dev-work ranking and Step 3 never selects one — that is the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule's WSJF multiplier-0 rule and it is **unchanged**. Verification is not dev work, so it gets its own pass rather than competing for a WSJF slot. Without this pass the "The Verification Pending → Closed transition is reserved for the maintainer, so evidence-based closure never fires and the verification queue grows without bound" problem fix would be inert: evidence-backed closure would be authorised and still unreachable, which is the exact shape that let 153 tickets accumulate behind a single populated evidence cell.
855
+
856
+ Fires **once per loop**, after the first iteration's Step 6 report. Cheap: one README read plus a bounded set of dispatches. **Re-entrant on gate-(0) route**: the once-per-loop cadence governs the *scheduled* fire only. If gate (0) later classifies a `.verifying.md` ticket dispatchable and routes it here, this step runs again for that ticket regardless of having already fired — otherwise gate (0) forbids `ALL_DONE` while routing to a step that declines to run, and the loop livelocks with no consumer and no exit.
857
+
858
+ 1. **Enumerate** the Verification Queue rows in `docs/problems/README.md` and filter to rows whose `Likely verified?` cell begins `yes — observed:`. Add any `.verifying.md` ticket this session has itself exercised with a citation that meets the "Agent output grounding — no fabricated quantitative estimates, cite + persist + uncertainty" architecture rule grounding (tool invocation + observable outcome) — a bare "the area was touched" is not a citation and does not qualify.
859
+
860
+ 2. **Guard each candidate** with the do-not-close predicate:
861
+
862
+ ```bash
863
+ wr-itil-is-close-blocked <NNN> docs/problems && close_blocked=1
864
+ ```
865
+
866
+ Exit 0 → **drop the candidate** and record the matched marker line as the reason; a recorded marker outranks any evidence. Exit 1 → proceed. Exit 2 → the ref did not resolve; drop it and record a pre-flight failure. This is what keeps `docs/problems/verifying/151-*.md` and its five siblings from the 2026-07-25 regression sweep out of the drain.
867
+
868
+ 3. **Dispatch** `/wr-itil:transition-problem <NNN> close` per surviving candidate via the Skill tool. `transition-problem` is the sole authoritative executor of V→C per the "Rename `wr-problem` Plugin to `wr-itil`" architecture rule amended the "Problem 093: `/wr-itil:transition-problem` ↔ `/wr-itil:manage-problem` circular delegation for `<NNN> <status>` args" problem — the orchestrator dispatches and reads the outcome, and does NOT re-implement the rename / Status edit / README refresh / commit. Each dispatched transition rides its own the "Governance Skills Commit Their Own Completed Work" architecture rule commit through the gates.
869
+
870
+ 4. **Report** one line per close in the iter summary: `V→C: P<NNN> | evidence=<citation> | recovery=/wr-itil:transition-problem <NNN> known-error`. Report dropped candidates too, with the marker or missing-evidence reason — a silently-dropped candidate reads as "the queue was clean" when it was not.
871
+
872
+ **Mechanical stage — no `AskUserQuestion`** (the "Agents over-ask in interactive sessions — conflating mechanical-stages with user-interactive-stages of multi-stage skill contracts (inverse-)" problem / the "— Decision-Delegation Contract: when agents act on the framework vs ask the user" architecture rule category 4). The evidence-vs-inference split is framework-resolved, the predicate is a field read rather than a judgement, and the close is one skill call from reversible. A per-candidate consent gate here is lazy deferral per the Step 2d Ask Hygiene Pass, and it is the behaviour the "The Verification Pending → Closed transition is reserved for the maintainer, so evidence-based closure never fires and the verification queue grows without bound" problem was captured to remove.
873
+
874
+ **Never close on inference.** Rows reading `no — not observed` are NOT candidates, whatever their age. They stay in the queue and surface for the user. Populating those cells is the complementary work tracked on the "Verification Queue evidence cells are never populated from subsequent-session exercises, so the run-retro Step 4a auto-drain never fires" problem (the evidence write path) — this step consumes cells, it does not manufacture them.
875
+
876
+ **Non-blocking on individual failure**: a failed dispatch (pre-flight reject, gate rejection, the "Problem 057: `git mv` + Edit + `git add` staging-ordering trap drops content edits from the commit" problem staging trap) is logged for that ticket and the drain continues to the next candidate. A single failure MUST NOT halt the loop. **Record the failure in the durable per-session skip record** (`.afk-run-state/outstanding-questions.jsonl`, carrying the ticket id, the failure reason, and `category: "direction"` so Step 2.5's ranking can place it; the skip table's own classification for this row is `user-answerable (verification)`) — the same mechanism Step 3.5 / Step 3.6 use. Gate (0) then classifies that ticket non-dispatchable on the re-scan, so a ticket that cannot be drained does not re-route here forever. Without the record the classification is not reproducible across re-scans and the loop cannot terminate.
877
+
878
+ Authority: the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule (verifying lifecycle; multiplier-0 ranking exclusion preserved), the "Rename `wr-problem` Plugin to `wr-itil`" architecture rule amended the "Problem 093: `/wr-itil:transition-problem` ↔ `/wr-itil:manage-problem` circular delegation for `<NNN> <status>` args" problem (transition-problem authoritative executor), the "Governance Skills Commit Their Own Completed Work" architecture rule (per-transition commit grain), the "Structured User Interaction for Governance-Skill Decisions" architecture rule Rule 5 (policy-authorised silent proceed), the "Agent output grounding — no fabricated quantitative estimates, cite + persist + uncertainty" architecture rule (cited evidence), the "— Decision-Delegation Contract: when agents act on the framework vs ask the user" architecture rule (framework-resolution boundary), the "Evidence-based relevance-close pass for the problem backlog (Phase 1: file-no-longer-exists; Phase 2: ADR-shipped-confirmed + named-skill-exists + self-marker-in-body + driver-child-closed + Phase 1 false-positive fixes)" architecture rule (evidence-based closure precedent), the "The Verification Pending → Closed transition is reserved for the maintainer, so evidence-based closure never fires and the verification queue grows without bound" problem (this step), the "Verification Queue evidence cells are never populated from subsequent-session exercises, so the run-retro Step 4a auto-drain never fires" problem (the write path that feeds it).
879
+
850
880
  ### Step 6.4: Drain risk-register queue (per the "Risk Register Back-Channel Write Contract — agent emits, hook queues, calling skill drains" architecture rule Phase 2b)
851
881
 
852
882
  After the iteration's commit lands and before the release-cadence check, drain any `RISK_REGISTER_HINT` entries that the iteration's pipeline runs enqueued to `.afk-run-state/risk-register-queue.jsonl`. The hook (Phase 2a) writes the queue silently; this step (Phase 2b) materialises queued hints into `docs/risks/R<NNN>-<slug>.active.md` register entries. Per-iter cadence keeps the queue bounded and attaches the resulting `docs(risks): scaffold ...` commit to the iter that produced the hint (preserves the "Governance Skills Commit Their Own Completed Work" architecture rule single-ticket-unit-of-work grain).
@@ -929,7 +959,7 @@ the "Problem lifecycle — add a Verification Pending status between Known Error
929
959
 
930
960
  **Mid-loop ask discipline (the "`/wr-itil:work-problems` orchestrator defaults to subprocess dispatch even when the user is observably interactive — loses real-time presence advantage" problem) preserved**: the dispatched transition-problem skill is wired to skip `AskUserQuestion` when invoked under AFK orchestrator context per its own the "Structured User Interaction for Governance-Skill Decisions" architecture rule Rule 6 fail-safe (transition-problem SKILL.md Step 8 risk-above-appetite branch). The orchestrator MUST NOT introduce any `AskUserQuestion` call at the callback site — the per-candidate routing is framework-resolved per the "— Decision-Delegation Contract: when agents act on the framework vs ask the user" architecture rule, and the callback fires in a mechanical-stage transition between drain step 2 and step 5 (cache refresh).
931
961
 
932
- **V→C remains the maintainer's surface (persona constraint per the ": Progress the Backlog While I'm Away" user outcome)**: this callback fires ONLY for K→V (`known-error → verifying` — "fix released, awaiting verification"). It explicitly does NOT auto-fire V→C the maintainer's judgment-reserved "fix actually works" closure remains untouched and continues to require their return per the existing transition-problem Step 4 `Verification Pending Closed` precondition ("the user has explicitly confirmed the fix works in production").
962
+ **V→C is evidence-authorised, not maintainer-reserved (the "The Verification Pending → Closed transition is reserved for the maintainer, so evidence-based closure never fires and the verification queue grows without bound" problem)**: this callback fires for K→V (`known-error → verifying` — "fix released, awaiting verification"). It does not itself perform V→C. The V→C transition is available to the loop through the Step 4 classifier and the Step 6.1 verification drain, on the same terms every other surface uses: **cited evidence closes; inference never does; a recorded do-not-close marker blocks regardless**. The prior wording here reserved V→C for the maintainer's return, which — combined with the gate (0) blanket exclusion at Step 2.4 — left the verification queue with no agent-driven exit path at all (153 tickets, one populated evidence cell). That reservation was pre-the "Decision-delegation contract agents over-apply Rule 1's interactive default to framework-resolved decisions; codify the framework-resolution boundary + AFK loop's batched-questions-as-deliverable + lazy-AskUserQuestion measurement" problem/the "VQ `Likely verified?` column uses age-based heuristic (≥14 days = yes) instead of session-observed evidence — sibling proxy-for-evidence anti-pattern to" problem residue and already contradicted the shipped `review-problems` Step 4 Bucket 1 and `run-retro` Step 4a sub-step 5, both of which close on evidence in AFK. What survives untouched is the honest half: a fix nobody exercised is not verified, and the maintainer remains the surface for contested evidence, partial fixes, and marker-blocked tickets.
933
963
 
934
964
  **Composition with the Above-appetite branch (below)**: the K→V callback is anchored to the within-appetite Drain action step 4 — it does NOT fire after the above-appetite Rule 5 halt (no release shipped → nothing to match) and it does NOT fire mid-loop in the above-appetite auto-apply loop. When the auto-apply loop converges and re-enters the within-appetite Drain action, the K→V callback fires there per step 4.
935
965
 
@@ -1149,7 +1179,19 @@ The skill should produce a final summary when the loop ends:
1149
1179
  ### Skipped
1150
1180
  | Problem | Skip-reason category | Reason |
1151
1181
  |---------|---------------------|--------|
1152
- | the "Problem 016: `manage-problem` skill does not flag or split multi-concern tickets" problem (Multi-concern splitting) | user-answerable (verification) | Awaiting user verification |
1182
+ | the "Problem 016: `manage-problem` skill does not flag or split multi-concern tickets" problem (Multi-concern splitting) | user-answerable (verification) | Fix released; no evidence available yet |
1183
+
1184
+ ### Verification Drain
1185
+
1186
+ <!-- @jtbd the ": Progress the Backlog While I'm Away" user outcome (Progress the Backlog While I'm Away — the returning maintainer sees what the loop closed on its own evidence and what it declined to, with the reason; a silently-drained queue is indistinguishable from one that never moved) -->
1187
+
1188
+ (Renders when the Step 6.1 verification drain ran. Verifying tickets are outside the Step 1 dev-work set, so they appear here rather than in Completed / Skipped. Reports both closes and drops — a drop reported as nothing reads as "the queue was clean" when it was not. Omitted entirely when the drain found no candidates.)
1189
+
1190
+ | Ticket | Outcome | Evidence / reason |
1191
+ |--------|---------|-------------------|
1192
+ | the "Latent octal-eval bug in next-ID formula across all 4 ticket-creator skills — `$(( $local_max + 1 ))` fails with "value too great for base" when local_max reaches 099" problem (octal next-ID formula) | Closed on evidence | `capture-story` Step 3 ran with `local_max=044`; `10#` guard yielded the ": Outbound lifecycle comments generated from real issue context" delivery story. Recovery: `/wr-itil:transition-problem 164 known-error` |
1193
+ | the "Published skills reference repo-relative script paths — adopter `bash` invocations hard-fail at Step 0" problem (repo-relative script paths) | Held | `wr-itil-is-close-blocked` exit 0 — `## Regression / incomplete observed 2026-07-25 — DO NOT CLOSE` |
1194
+ | the "architect-enforce-edit + jtbd-enforce-edit hooks should add docs/retros/ to their exclusion paths" problem (hook marker TTL) | Held | No citation available — absence of evidence is not evidence |
1153
1195
 
1154
1196
  ### Reported Upstream
1155
1197
 
@@ -54,10 +54,11 @@ The preamble check is a one-shot; the `.intake-scaffold-done` and `.intake-scaff
54
54
  - **Work**: `problem work` — runs a review first, then begins working the highest-WSJF problem
55
55
  - **Review**: `problem review` — re-assess all open problems: update priorities per RISK-POLICY.md, estimate effort, calculate WSJF, and update files
56
56
 
57
- **Closing problems:** Problems are closed ONLY after the user verifies the fix in production — not when the fix is committed or released. The workflow (per the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule):
58
- 1. When the fix is released: `git mv` the file from `.known-error.md` to `.verifying.md`, update the Status field to "Verification Pending", AND add a `## Fix Released` section (e.g., `Deployed in v0.26.X. Awaiting user verification.`). All three edits land in the same commit per the "Governance Skills Commit Their Own Completed Work" architecture rule.
59
- 2. When the user explicitly confirms ("it's fixed", "verified", "working"): `git mv` from `.verifying.md` to `.closed.md`, update the Status field to "Closed", and reference the problem in the commit message (e.g., "Closes the "Problem 008: request_user_input Unavailable When --channels Is Active" problem").
60
- 3. Never assume the fix worksalways wait for explicit user confirmation before closing.
57
+ **Closing problems:** Problems are closed when the fix is **verified** — not when it is committed or released. Verification comes from cited evidence or from the user; it never comes from assuming. The workflow (per the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule, amended by the "The Verification Pending → Closed transition is reserved for the maintainer, so evidence-based closure never fires and the verification queue grows without bound" problem):
58
+ 1. When the fix is released: `git mv` the file from `.known-error.md` to `.verifying.md`, update the Status field to "Verification Pending", AND add a `## Fix Released` section (e.g., `Deployed in v0.26.X. Awaiting verification.`). All three edits land in the same commit per the "Governance Skills Commit Their Own Completed Work" architecture rule.
59
+ 2. When the fix is **verified** — either by cited evidence the agent can point at (a test invocation and its outcome, a commit SHA whose diff covers the fix path, a skill or hook invocation that exercised the fix and behaved as the fix contracts, a post-release invocation of the shipped artefact that behaved as the fix contracts, or an existing `yes — observed: <citation>` Verification Queue cell) **or** by the user explicitly confirming ("it's fixed", "verified", "working"): `git mv` from `.verifying.md` to `.closed.md`, update the Status field to "Closed", record the citation in the closure, and reference the problem in the commit message (e.g., "Closes the "Problem 008: request_user_input Unavailable When --channels Is Active" problem"). **Evidence-backed closure is agent-authorised** and is a mechanical stage — do NOT fire `request_user_input` for it (the "Agents over-ask in interactive sessions — conflating mechanical-stages with user-interactive-stages of multi-stage skill contracts (inverse-)" problem / the "— Decision-Delegation Contract: when agents act on the framework vs ask the user" architecture rule category 4). It is cheap and reversible: report `Recovery: rerun /wr-itil:transition-problem <NNN> known-error to reopen` alongside every close.
60
+ 3. **Never close on inference — absence of evidence is not evidence.** A ticket nobody exercised stays Verification Pending, however old and however plausible the fix looks. "The fix is on disk", "it has been months" and "the ADR that prescribed it shipped" are inference, not observation (the "Relevance-close evaluator over-fires a bare ADR/skill citation is read as "fix shipped", so live tickets return CLOSE-CANDIDATE" problem). Closing tickets nobody exercised is the opposite failure and is exactly as wrong as never closing any.
61
+ 4. **Genuine ambiguity is the user's surface** — contested evidence, a fix covering only part of the ticket, or a recorded do-not-close marker. Run `<itil-plugin-root>/bin/wr-itil-is-close-blocked <NNN> docs/problems` before closing; exit 0 means BLOCKED (do not close, whatever the evidence says — flip back or queue for the user), exit 1 means not blocked, exit 2 means the ref did not resolve and is a pre-flight failure rather than permission.
61
62
 
62
63
  The `.verifying.md` suffix distinguishes "fix released, awaiting user verification" from "root cause identified AND workaround documented; fix not yet proposed" (the Known Error meaning per the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule corrected semantics, 2026-06-08 amendment; the fix proposal happens AFTER Known Error and draws a release row on a story map). See the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule for rationale.
63
64
 
@@ -67,9 +68,9 @@ The `.verifying.md` suffix distinguishes "fix released, awaiting user verificati
67
68
  |--------|-----------|---------|----------------|
68
69
  | **Open** | `.open.md` | Reported, under investigation | New problem identified |
69
70
  | **Known Error** | `.known-error.md` | Root cause identified AND workaround documented; **fix not yet proposed** (the fix proposal draws a release row on a story map) | Root cause documented, reproduction test exists, workaround in place |
70
- | **Verification Pending** | `.verifying.md` | Fix released, awaiting user verification (the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule) | Fix shipped; `## Fix Released` section written; user action remaining |
71
+ | **Verification Pending** | `.verifying.md` | Fix released, awaiting verification (the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule) | Fix shipped; `## Fix Released` section written; verification outstanding by cited evidence or by the user |
71
72
  | **Parked** | `.parked.md` | Blocked on upstream or suspended by user decision | Upstream blocker identified, or user explicitly suspends; reason and un-park trigger documented |
72
- | **Closed** | `.closed.md` | Fix verified in production OR ticket determined no longer relevant via evidence | (a) User explicitly confirms the released fix works (canonical Verifying → Closed path), OR (b) auto-closed by `/wr-itil:review-problems` Step 4.6 relevance-close pass per the "Evidence-based relevance-close pass for the problem backlog (Phase 1: file-no-longer-exists; Phase 2: ADR-shipped-confirmed + named-skill-exists + self-marker-in-body + driver-child-closed + Phase 1 false-positive fixes)" architecture rule Phase 1 + Phase 2 evidence shapes — `file-no-longer-exists` / `ADR-shipped-confirmed` / `named-skill-or-feature-exists` / `self-marker-in-body` / `driver-child-ticket-closed` (cumulative; multi-shape matches emit comma-joined) with `## Closed as no longer relevant` audit section per the "Agent output grounding — no fabricated quantitative estimates, cite + persist + uncertainty" architecture rule grounding (extends the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule lifecycle: Open\|Known Error → Closed bypasses Verifying when no fix was released). Partial-scope umbrellas emit `CLOSE-CANDIDATE-WITH-CAVEAT` and ride the maintainer's `request_user_input` surface-batch-confirm path. |
73
+ | **Closed** | `.closed.md` | Fix verified in production OR ticket determined no longer relevant via evidence | (a) The released fix is verified — either by cited evidence meeting the ticket's own close criterion (agent-authorised, mechanical, no `request_user_input`; blocked when `<itil-plugin-root>/bin/wr-itil-is-close-blocked` exits 0) or by the user explicitly confirming (canonical Verifying → Closed path; the "The Verification Pending → Closed transition is reserved for the maintainer, so evidence-based closure never fires and the verification queue grows without bound" problem), OR (b) auto-closed by `/wr-itil:review-problems` Step 4.6 relevance-close pass per the "Evidence-based relevance-close pass for the problem backlog (Phase 1: file-no-longer-exists; Phase 2: ADR-shipped-confirmed + named-skill-exists + self-marker-in-body + driver-child-closed + Phase 1 false-positive fixes)" architecture rule Phase 1 + Phase 2 evidence shapes — `file-no-longer-exists` / `ADR-shipped-confirmed` / `named-skill-or-feature-exists` / `self-marker-in-body` / `driver-child-ticket-closed` (cumulative; multi-shape matches emit comma-joined) with `## Closed as no longer relevant` audit section per the "Agent output grounding — no fabricated quantitative estimates, cite + persist + uncertainty" architecture rule grounding (extends the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule lifecycle: Open\|Known Error → Closed bypasses Verifying when no fix was released). Partial-scope umbrellas emit `CLOSE-CANDIDATE-WITH-CAVEAT` and ride the maintainer's `request_user_input` surface-batch-confirm path. |
73
74
 
74
75
  **Parked problems** are excluded from WSJF ranking and work selection. They are listed separately in review output so users can see them without them polluting the backlog. To park a problem:
75
76
  1. **If the park reason is `upstream-blocked`**, run the external-root-cause detection block at Step 7 first (see "External-root-cause detection (the "Problem 063: manage-problem does not trigger /wr-itil:report-upstream when root cause is external" problem)"). Park without recording the upstream dependency in `## Related` would be the canonical audit-trail gap this block closes.
@@ -79,7 +80,7 @@ The `.verifying.md` suffix distinguishes "fix released, awaiting user verificati
79
80
 
80
81
  To un-park: `git mv` back to `docs/problems/open/<NNN>-<title>.md` (or `docs/problems/known-error/<NNN>-<title>.md` if root cause is confirmed), update Status, remove `## Parked` section.
81
82
 
82
- **Verification Pending problems** are also excluded from WSJF ranking — their remaining work is user-side verification, not dev effort. They appear in a dedicated "Verification Queue" section in review output so the user can see what's waiting on them without mixing with dev-work ranking. See step 9c for the queue layout.
83
+ **Verification Pending problems** are also excluded from WSJF ranking — their remaining work is verification — by evidence or by the user, not dev effort. They appear in a dedicated "Verification Queue" section in review output so the user can see what's waiting on them without mixing with dev-work ranking. See step 9c for the queue layout.
83
84
 
84
85
  **Allowed optional appendages**: a problem ticket file may carry a `## Reported Upstream` section appended after the standard sections. This is written by the `/wr-itil:report-upstream` skill (per the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule Confirmation criterion 3a) and records the upstream URL — an issue, a pull request (per the "Prefer an upstream pull request over an issue when the upstream accepts pull requests" architecture rule), or an advisory — plus the matched template and the disclosure path. The presence or absence of this section does not affect WSJF ranking or status transitions.
85
86
 
@@ -844,11 +845,26 @@ Then edit the file:
844
845
 
845
846
  Re-stage the `.verifying.md` file explicitly after the `Edit` tool runs (the "Problem 057: `git mv` + Edit + `git add` staging-ordering trap drops content edits from the commit" problem). The trailing `git add` above is NOT redundant — `git mv` alone stages only the rename, not the subsequent content edit; the same `git add` also re-stages the seed Edit content carried across the rename (single staging call, two Edit windows; the "derive-release-vehicle helper requires pre-edit of ticket changeset reference — three-touch when one-touch would suffice" problem + the "Problem 057: `git mv` + Edit + `git add` staging-ordering trap drops content edits from the commit" problem).
846
847
 
847
- Both the `git mv` and the file edits belong in the same commit as the fix implementation per the "Governance Skills Commit Their Own Completed Work" architecture rule (governance skills commit their own work). The `.verifying.md` suffix signals to every downstream consumer (work-problems classifier, review step 9d, README rendering) that the remaining work is user-side verification — no file-body scan needed.
848
+ Both the `git mv` and the file edits belong in the same commit as the fix implementation per the "Governance Skills Commit Their Own Completed Work" architecture rule (governance skills commit their own work). The `.verifying.md` suffix signals to every downstream consumer (work-problems classifier, review step 9d, README rendering) that the remaining work is verification — by evidence or by the user — no file-body scan needed.
848
849
 
849
- **Verification Pending → Closed** (user confirms):
850
+ **Verification Pending → Closed** (verified — by evidence or by the user):
850
851
 
851
- Only the user can make this call. When they explicitly confirm the fix works in production:
852
+ **Sibling-with `/wr-itil:transition-problem` Step 4** per the "Rename `wr-problem` Plugin to `wr-itil`" architecture rule amended the "Problem 093: `/wr-itil:transition-problem` ↔ `/wr-itil:manage-problem` circular delegation for `<NNN> <status>` args" problem (copy-not-move — edit both or neither; drift here is the class the "The Verification Pending → Closed transition is reserved for the maintainer, so evidence-based closure never fires and the verification queue grows without bound" problem fixed). Two admissible triggers:
853
+
854
+ - **Cited evidence** meeting the ticket's own stated close criterion — a test invocation and its outcome, a commit SHA whose diff covers the fix path, a skill or hook invocation that exercised the fix and behaved as the fix contracts, a post-release invocation of the shipped artefact that behaved as the fix contracts, or an existing `yes — observed: <citation>` Verification Queue cell. The agent closes on its own authority and records the citation in the closure. **Mechanical stage — do NOT fire `request_user_input`** (the "Agents over-ask in interactive sessions — conflating mechanical-stages with user-interactive-stages of multi-stage skill contracts (inverse-)" problem / the "— Decision-Delegation Contract: when agents act on the framework vs ask the user" architecture rule category 4). Report `Recovery: rerun /wr-itil:transition-problem <NNN> known-error to reopen`.
855
+
856
+ **Evidence-authorised tracker updates.** Write the basis into the ticket's `**Status**:` line alongside the citation (`**Status**: Closed (closed-on-evidence <YYYY-MM-DD> — <citation>. Recovery: rerun /wr-itil:transition-problem <NNN> known-error to reopen)`). A provenance-proven GitHub issue on this project's tracker receives the gated comment and closes; an unresolved or non-issue inbound origin performs no issue mutation. An issue on another maintainer's tracker receives the comment but stays open on our evidence alone; that upstream party's confirmation may authorize closure. Pull requests remain comment-only.
857
+ - **Explicit user confirmation** that the fix works in production.
858
+
859
+ **Never close on inference** — absence of evidence is not evidence; a ticket nobody exercised stays Verification Pending. **Do-not-close guard**, before either trigger:
860
+
861
+ ```bash
862
+ <itil-plugin-root>/bin/wr-itil-is-close-blocked <NNN> docs/problems && close_blocked=1
863
+ ```
864
+
865
+ Exit 0 → BLOCKED; do not close whatever the evidence says (flip back to `known-error` or queue for the user). Exit 1 → not blocked. Exit 2 → the ref did not resolve; a pre-flight failure, not permission.
866
+
867
+ When one of the two triggers holds and the guard is clear:
852
868
 
853
869
  ```bash
854
870
  git mv docs/problems/verifying/<NNN>-<title>.md docs/problems/closed/<NNN>-<title>.md
@@ -856,7 +872,14 @@ git mv docs/problems/verifying/<NNN>-<title>.md docs/problems/closed/<NNN>-<titl
856
872
  git add docs/problems/closed/<NNN>-<title>.md
857
873
  ```
858
874
 
859
- Update the "Status" field to "Closed". Reference the problem ID in the closure commit message (e.g., "Closes the "Problem 008: request_user_input Unavailable When --channels Is Active" problem"). Step 9d's verification prompt is the structured path that fires this transition during `manage-problem review`. Re-stage the `.closed.md` file explicitly after the Edit (the "Problem 057: `git mv` + Edit + `git add` staging-ordering trap drops content edits from the commit" problem staging trap).
875
+ **Write the close's authority basis into the Status field.** The Status line is the only place the basis survives the `Likely verified?` cell lives in the README's Verification Queue table, and that row is deleted by this very transition, so a downstream reader (Step 7b's upstream leg) would find nothing there. Shape, matching what the 2026-07-15 closes already wrote (`docs/problems/closed/186-*.md:3`):
876
+
877
+ - Evidence-authorised: `**Status**: Closed (closed-on-evidence <YYYY-MM-DD> — <citation>. Recovery: rerun /wr-itil:transition-problem <NNN> known-error to reopen)`
878
+ - User-confirmed: `**Status**: Closed (user-confirmed <YYYY-MM-DD>)`
879
+
880
+ `closed-on-evidence` is what the outbound leg reads to keep a foreign issue open on our evidence alone. The inbound leg uses committed issue-channel provenance instead: ambiguity fails closed before any issue operation.
881
+
882
+ Reference the problem ID in the closure commit message (e.g., "Closes the "Problem 008: request_user_input Unavailable When --channels Is Active" problem"). Step 9d's verification prompt is the structured path that fires this transition during `manage-problem review`. Re-stage the `.closed.md` file explicitly after the Edit (the "Problem 057: `git mv` + Edit + `git add` staging-ordering trap drops content edits from the commit" problem staging trap).
860
883
 
861
884
  #### README.md refresh on every transition (the "Problem 062: `manage-problem` does not refresh `docs/problems/README.md` on single-ticket transitions; fast-path cache goes stale silently" problem)
862
885
 
@@ -32,7 +32,7 @@ When referencing problem IDs, ADR IDs, JTBD IDs, or RFC IDs in prose output (the
32
32
  **In scope** (the ": docs/problems/ flat layout migration — per-state subdirs + adopter auto-migration" release design migration window — each glob is dual-tolerant, covering BOTH the flat `docs/problems/<NNN>-<title>.<state>.md` filename-suffix layout AND the per-state subdir `docs/problems/<state>/<NNN>-<title>.md` layout):
33
33
 
34
34
  - `docs/problems/*.open.md` + `docs/problems/open/*.md` and `docs/problems/*.known-error.md` + `docs/problems/known-error/*.md` — re-scored (Impact × Likelihood × Effort → WSJF); Priority + Effort + WSJF lines updated when they change.
35
- - `docs/problems/*.verifying.md` + `docs/problems/verifying/*.md` — surfaced in the Verification Queue and fed to Step 4's verification prompt (Known Error → Closed path when the user confirms).
35
+ - `docs/problems/*.verifying.md` + `docs/problems/verifying/*.md` — surfaced in the Verification Queue and fed to Step 4's verification routing (the Verification Pending → Closed path Bucket 1 closes on evidence, Bucket 2 asks, Bucket 3 flips back).
36
36
  - `docs/problems/*.parked.md` + `docs/problems/parked/*.md` — listed in the Parked section; NOT re-scored (WSJF multiplier is 0).
37
37
  - `docs/problems/README.md` — rewritten with the refreshed WSJF Rankings + Verification Queue + Parked tables; staged and committed with the review.
38
38
 
@@ -124,7 +124,7 @@ Omit an empty section rather than rendering an empty header.
124
124
 
125
125
  Target the dual-tolerant glob `docs/problems/*.verifying.md docs/problems/verifying/*.md` (the ": docs/problems/ flat layout migration — per-state subdirs + adopter auto-migration" release design migration window) — do NOT scan `.known-error.md` bodies for a `## Fix Released` section (per the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule, Verification Pending is a first-class status, not a substring marker). Bucket each verifying ticket by its Step-3 `Likely verified?` cell (the "VQ `Likely verified?` column uses age-based heuristic (≥14 days = yes) instead of session-observed evidence — sibling proxy-for-evidence anti-pattern to" problem evidence-first cell shape: `yes — observed: <evidence>` / `no — not observed` / `no — observed regression`) and route each bucket differently. **Do NOT fire one `request_user_input` per ticket** — the evidence-backed subset closes on evidence; only the unobserved subset asks.
126
126
 
127
- **Bucket 1 — `yes — observed: <evidence>` → close-on-evidence (framework-mediated, silent agent action per the "— Decision-Delegation Contract: when agents act on the framework vs ask the user" architecture rule + the "Decision-delegation contract — agents over-apply Rule 1's interactive default to framework-resolved decisions; codify the framework-resolution boundary + AFK loop's batched-questions-as-deliverable + lazy-request_user_input measurement" problem).** These rows carry the "Agent output grounding — no fabricated quantitative estimates, cite + persist + uncertainty" architecture rule-grounded cited evidence (a prior Step 4 user confirmation, an in-session test invocation + observable outcome, or a `run-retro` Step 4a close-on-evidence citation — see the Step 3 cell definition). The framework has resolved this decision: a `.verifying.md` ticket with specific cited evidence IS verified per the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule's evidence semantics, so close it mechanically WITHOUT `request_user_input` — mirroring the shipped `run-retro` Step 4a step 5 close-on-evidence. A per-candidate ask here is lazy deferral (sub-contracting a framework-resolved decision back to the user) per the Step 2d Ask Hygiene Pass. For each such ticket: close the problem (`git mv` from `.verifying.md` to `.closed.md`, update Status to "Closed", re-stage per the "Problem 057: `git mv` + Edit + `git add` staging-ordering trap drops content edits from the commit" problem staging trap) and update the `Likely verified?` cell to `yes — observed: closed-on-evidence <YYYY-MM-DD> — <citation>`. Report each closure in the review output with a documented reversible recovery path: `Recovery: rerun /wr-itil:transition-problem <NNN> known-error to reopen` closes are cheap and reversible; user disagreement surfaces via authentic-correction (the "— Decision-Delegation Contract: when agents act on the framework vs ask the user" architecture rule category 6), not a pre-close consent gate.
127
+ **Bucket 1 — `yes — observed: <evidence>` → close-on-evidence.** Specific observed evidence authorizes a mechanical close without asking again. First run `<itil-plugin-root>/bin/wr-itil-is-close-blocked <NNN> docs/problems`: exit 0 keeps the ticket open and reports the matched marker; exit 2 is a pre-flight failure; exit 1 proceeds. Move the ticket to `.closed.md`, re-stage it, and persist the authority in `**Status**: Closed (closed-on-evidence <YYYY-MM-DD> — <citation>. Recovery: rerun /wr-itil:transition-problem <NNN> known-error to reopen)`. A provenance-proven GitHub issue on this project's tracker receives the gated comment and closes; unresolved or non-issue inbound provenance performs no issue mutation. A foreign issue receives the comment but stays open on local evidence alone, while that upstream party's confirmation may authorize closure. Pull requests remain comment-only. Update the review cell with the same evidence citation and report the reversible recovery path.
128
128
 
129
129
  **Bucket 2 — `no — not observed` → ask (genuine user-authority).** No session-observable evidence yet, so the user may hold out-of-band production knowledge the agent cannot observe — this is the genuine user-input surface. Use `request_user_input` to ask whether the fix has been verified in production. The question MUST include a fix summary extracted from the `## Fix Released` section — inline the first sentence (or first bullet list) of that section in the question body or option description per the brief-before-ID discipline, so the user can answer without reading the full problem file. Do NOT ask with only the problem ID + title + version.
130
130
  - If the user confirms: close the problem (`git mv` from `.verifying.md` to `.closed.md`, update Status to "Closed", re-stage per the "Problem 057: `git mv` + Edit + `git add` staging-ordering trap drops content edits from the commit" problem staging trap). Update the `Likely verified?` cell to `yes — observed: user confirmed <YYYY-MM-DD>`.
@@ -29,7 +29,7 @@ The deprecated `/wr-itil:manage-problem <NNN> known-error` subcommand route rema
29
29
  - `<status>` — the destination status. One of:
30
30
  - `known-error` — Open → Known Error (root cause identified AND workaround documented; fix not yet proposed — per the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule corrected semantics; the fix proposal draws a release row on a story map).
31
31
  - `verifying` — Known Error → Verification Pending (fix released, awaiting user verification per the "Problem lifecycle — add a Verification Pending status between Known Error and Closed" architecture rule).
32
- - `close` — Verification Pending → Closed (user has confirmed the fix works in production).
32
+ - `close` — Verification Pending → Closed (cited evidence meets the ticket's own close criterion, OR the user has confirmed the fix works in production — see Step 4).
33
33
 
34
34
  The `<NNN>` and `<status>` tokens are **data parameters**, not word-subcommands. Per the "Problem 071: Argument-based skill subcommands are not discoverable in Codex autocomplete" problem split rule (the "Rename `wr-problem` Plugin to `wr-itil`" architecture rule amended), data parameters (IDs, paths, URLs, enum destinations) are permitted; word-subcommands that name distinct user intents are not. This skill's argument shape is `data + data`, which is the same shape as `/wr-itil:report-upstream <NNN>`.
35
35
 
@@ -79,8 +79,12 @@ Check the current filename suffix and verify the destination status is reachable
79
79
  | `.open.md` | `known-error` | yes |
80
80
  | `.known-error.md` | `verifying` | yes |
81
81
  | `.verifying.md` | `close` | yes |
82
+ | `.verifying.md` | `known-error` | yes — **flip-back**: the fix recurred or proved incomplete. Required by `review-problems` Bucket 3, `manage-problem`, and `run-retro` Step 4a, all of which already instruct it. |
83
+ | `.closed.md` | `known-error` | yes — **reopen**: a close was wrong. This is the recovery path every evidence-authorised close reports (the "The Verification Pending → Closed transition is reserved for the maintainer, so evidence-based closure never fires and the verification queue grows without bound" problem), so it has to be reachable or the reversibility that justifies closing without a consent gate is fiction. |
82
84
  | any other pairing | — | no — emit an error and stop |
83
85
 
86
+ The two backward pairings are what make an agent-authorised close safe to make. The argument for closing on evidence without asking is that the close is cheap and reversible; a reopen route the skill refuses would make that argument false. Both are ordinary renames — `git mv` back to `known-error/`, Status field back to `Known Error`, append the recurrence or mis-close citation to the ticket body, refresh the README, one commit per the "Governance Skills Commit Their Own Completed Work" architecture rule — and neither re-runs the Open → Known Error pre-flight, because root cause and workaround were established the first time round. (the "The transition lifecycle table rejects both the fix-on-capture fast path and its own documented recovery path" problem tracks the wider set of missing pairings, including the fix-on-capture fast path.)
87
+
84
88
  If the pairing is invalid, emit a clear message naming the current status, the requested destination, and the valid next step. Do not silently skip or auto-correct — invalid transitions are almost always user typos and a clear error is the cheapest recovery.
85
89
 
86
90
  ### 4. Run pre-flight checks
@@ -128,9 +132,34 @@ Emit a structured report naming each deferred section + the lifted condition + t
128
132
 
129
133
  This check fires BEFORE the "derive-release-vehicle helper requires pre-edit of ticket changeset reference — three-touch when one-touch would suffice" problem Release-vehicle seed step in Step 6 — halt-on-conditional-deferral is the outer gate, seed-and-rename is the inner mechanic.
130
134
 
131
- **Verification Pending → Closed** (`<status>` = `close`) requires:
135
+ **Verification Pending → Closed** (`<status>` = `close`) requires **either** of:
136
+
137
+ - [ ] **Cited evidence** that meets the ticket's own stated close criterion — a test invocation and its outcome, a commit SHA whose diff covers the fix path, a skill or hook invocation that exercised the fix and behaved as the fix contracts, a post-release invocation of the shipped artefact that behaved as the fix contracts, or a `yes — observed: <citation>` cell already carried in the Verification Queue. The agent closes on its own authority and records the citation in the closure. **Mechanical stage — do NOT fire `request_user_input`** (the "Agents over-ask in interactive sessions — conflating mechanical-stages with user-interactive-stages of multi-stage skill contracts (inverse-)" problem / the "— Decision-Delegation Contract: when agents act on the framework vs ask the user" architecture rule category 4, mirroring the shipped `review-problems` Step 4 Bucket 1 and `run-retro` Step 4a sub-step 5). Surface the recovery path alongside the close: `Recovery: rerun /wr-itil:transition-problem <NNN> known-error to reopen`.
138
+ - [ ] **The user has explicitly confirmed** the fix works in production, or an orchestrator supplied the `close` argument under prior user authorisation.
139
+
140
+ **Never close on inference — absence of evidence is not evidence.** A ticket nobody exercised stays Verification Pending, however old it is and however plausible the fix looks. "The fix is on disk", "it has been months", "that area has been touched a lot" and "the ADR that prescribed it shipped" are inference, not observation — see the "Relevance-close evaluator over-fires — a bare ADR/skill citation is read as "fix shipped", so live tickets return CLOSE-CANDIDATE" problem for what happens when a bare citation is read as proof of shipping. Closing tickets nobody exercised is the opposite failure and is exactly as wrong as never closing any.
141
+
142
+ **Genuine ambiguity stays the user's surface** — contested evidence, a fix that covers only part of the ticket, or a recorded do-not-close marker. Run the mechanical check first; it is a field read, not a judgement:
143
+
144
+ ```bash
145
+ <itil-plugin-root>/bin/wr-itil-is-close-blocked <NNN> docs/problems && close_blocked=1
146
+ ```
147
+
148
+ Exit 0 means **BLOCKED**: the ticket carries a line-anchored `DO NOT CLOSE` marker (`docs/problems/verifying/151-*.md` § "Regression / incomplete observed … DO NOT CLOSE" is the canonical shape). Do NOT close it whatever the evidence says — route it to the `verifying → known-error` flip-back, or queue it for the user. Exit 1 means not blocked. Exit 2 means the ticket ref did not resolve — treat as a pre-flight failure, not as permission.
149
+
150
+ **Evidence-authorised tracker updates.** Write the basis into the ticket's `**Status**:` line alongside the citation (`**Status**: Closed (closed-on-evidence <YYYY-MM-DD> — <citation>. Recovery: rerun /wr-itil:transition-problem <NNN> known-error to reopen)`). A provenance-proven GitHub issue on this project's tracker receives the gated comment and closes; unresolved or non-issue inbound provenance performs no issue mutation. A foreign issue receives the comment but stays open on our evidence alone; that upstream party's confirmation may authorize closure. Pull requests remain comment-only.
132
151
 
133
- - [ ] The user has explicitly confirmed the fix works in production (this skill never auto-closes on inference only on explicit user confirmation or orchestrator-supplied `close` argument)
152
+ Authority: the "— Decision-Delegation Contract: when agents act on the framework vs ask the user" architecture rule (framework-resolution boundary — evidence-backed close is category 4, silent framework action; contested or absent evidence is category 1, queued not guessed), the "Agent output grounding no fabricated quantitative estimates, cite + persist + uncertainty" architecture rule (cite the evidence, persist it, state the uncertainty), the "Structured User Interaction for Governance-Skill Decisions" architecture rule Rule 5 (policy-authorised silent proceed), the "Evidence-based relevance-close pass for the problem backlog (Phase 1: file-no-longer-exists; Phase 2: ADR-shipped-confirmed + named-skill-exists + self-marker-in-body + driver-child-closed + Phase 1 false-positive fixes)" architecture rule (evidence-based closure precedent on the open/known-error side of the same lifecycle), the "The Verification Pending → Closed transition is reserved for the maintainer, so evidence-based closure never fires and the verification queue grows without bound" problem (this contract).
153
+
154
+ **Verification Pending → Known Error** (`<status>` = `known-error` — flip-back) requires:
155
+
156
+ - [ ] A recurrence or incompleteness citation: what was observed, and when. Append it to the ticket body; the `Likely verified?` cell becomes `no — observed regression — <one-line citation>`.
157
+
158
+ **Closed → Known Error** (`<status>` = `known-error` — reopen) requires:
159
+
160
+ - [ ] A stated reason the close was wrong. Nothing more — this is the recovery path for an evidence-authorised close and it must stay one command deep, or the reversibility that justifies closing without a consent gate is not real.
161
+
162
+ Neither backward pairing re-runs the Open → Known Error pre-flight above: root cause and workaround were established when the ticket first reached Known Error and are still on the ticket. Neither fires the "Problem 063: manage-problem does not trigger /wr-itil:report-upstream when root cause is external" problem external-root-cause detection (Step 5 is Open → Known Error only).
134
163
 
135
164
  ### 5. External-root-cause detection (the "Problem 063: manage-problem does not trigger /wr-itil:report-upstream when root cause is external" problem — Open → Known Error only)
136
165
 
@@ -206,7 +235,7 @@ git mv docs/problems/known-error/<NNN>-<title>.md docs/problems/verifying/<NNN>-
206
235
  git add docs/problems/verifying/<NNN>-<title>.md
207
236
  ```
208
237
 
209
- The `## Fix Released` section contains: release marker (version, commit SHA, or date), one-sentence fix summary, "Awaiting user verification" line, and any exercise evidence from the releasing session. The `.verifying.md` suffix signals to every downstream consumer (work-problems classifier, review step 9d, README rendering) that the remaining work is user-side verification — no file-body scan needed.
238
+ The `## Fix Released` section contains: release marker (version, commit SHA, or date), one-sentence fix summary, "Awaiting user verification" line, and any exercise evidence from the releasing session. The `.verifying.md` suffix signals to every downstream consumer (work-problems classifier, review step 9d, README rendering) that the remaining work is verification — by evidence or by the user — no file-body scan needed.
210
239
 
211
240
  When this transition is folded into a `fix(<scope>): ... (closes P<NNN>)` commit (the common case), the `git mv` + `Edit` + re-stage + README refresh all join that single commit — never split across commits.
212
241
 
@@ -241,10 +270,17 @@ Use the structured values verbatim when authoring the `## Fix Released` section'
241
270
 
242
271
  ```bash
243
272
  git mv docs/problems/verifying/<NNN>-<title>.md docs/problems/closed/<NNN>-<title>.md
244
- # ... use the Edit tool to update the Status field to "Closed" ...
273
+ # ... use the Edit tool to update the Status field per the shape below ...
245
274
  git add docs/problems/closed/<NNN>-<title>.md
246
275
  ```
247
276
 
277
+ **Write the close's authority basis into the Status field.** The Status line is the only place the basis survives — the `Likely verified?` cell lives in the README's Verification Queue table, and that row is deleted by this very transition, so a downstream reader (Step 7b's upstream leg) would find nothing there. Shape, matching what the 2026-07-15 closes already wrote (`docs/problems/closed/186-*.md:3`):
278
+
279
+ - Evidence-authorised: `**Status**: Closed (closed-on-evidence <YYYY-MM-DD> — <citation>. Recovery: rerun /wr-itil:transition-problem <NNN> known-error to reopen)`
280
+ - User-confirmed: `**Status**: Closed (user-confirmed <YYYY-MM-DD>)`
281
+
282
+ `closed-on-evidence` is what the outbound leg reads to keep a foreign issue open on our evidence alone. The inbound leg uses committed issue-channel provenance instead: ambiguity fails closed before any issue operation.
283
+
248
284
  ### 7. Refresh docs/problems/README.md (the "Problem 062: `manage-problem` does not refresh `docs/problems/README.md` on single-ticket transitions; fast-path cache goes stale silently" problem)
249
285
 
250
286
  Every Step 7 status transition regenerates `docs/problems/README.md` and stages it in the same commit so the dev-work table, Verification Queue, Parked section, and "Last reviewed" line never lag the on-disk ticket inventory. Without this step, README.md accumulates staleness between review invocations.