@windyroad/itil 0.32.3 → 0.33.0-preview.339
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/package.json
CHANGED
|
@@ -550,6 +550,20 @@ After the iteration's commit lands but before starting the next iteration, check
|
|
|
550
550
|
- **Within appetite (≤ 4/25) AND there is releasable material** (any unpushed commits on `HEAD..origin/<base>` OR any entries in `.changeset/` OR any graduation-eligible entries in `docs/changesets-holding/` per ADR-061 Rule 1 that are not VP-blocked per Rule 2) — drain the queue per the Drain action below, then proceed to Step 6.75. The release-action threshold is "is there something to release?", NOT "has accumulated risk reached the safety band?" Per user direction 2026-05-17 (P250 Description): *"If it's low risk, you should release."* Low cost to release + low residual risk = release now; never accumulate.
|
|
551
551
|
- **Within appetite (≤ 4/25) AND empty queue** (no unpushed commits AND no `.changeset/` entries AND no graduation-eligible held entries) — no drain (literally nothing to release). Proceed to Step 6.75. This is the genuine no-op fast-path; the gate is *absence of releasable material*, not residual band.
|
|
552
552
|
|
|
553
|
+
**Cohort-graduation pre-check (per ADR-061 Rule 5; P246):** when the within-appetite-with-releasable-material branch fires AND `docs/changesets-holding/` is non-empty, invoke the graduation evaluator BEFORE the Drain action. The evaluator is the deterministic Rule 1a join + Rule 2 VP carve-out + Rule 3b cohort-grouping pass shipped in `@windyroad/risk-scorer` Phase 2a/2b. **The graduation criterion is evidence-of-working-as-desired (Rule 4 per-class evidence floor), not elapsed wall-clock time** — per user direction 2026-05-17: *"Dogfooding makes sense, but it shouldn't be time based, it should be until we are happy that it's working as desired."* + *"Why are we waiting? That seems to go against the principles if you ask me."* Calendar predicates are NEVER a primary graduation trigger; the evaluator's `status=resolved` IS the graduation signal.
|
|
554
|
+
|
|
555
|
+
1. Run the shim: `wr-risk-scorer-evaluate-graduation` (resolves to `packages/risk-scorer/scripts/evaluate-graduation.sh` per ADR-049 naming grammar). The script enumerates `docs/changesets-holding/*.md` (excluding README), applies ADR-061 Rule 1a join + Rule 2 VP carve-out + Rule 3b cohort grouping, and emits one `GRADUATION_CANDIDATE:` line per held entry plus a final `GRADUATION_SUMMARY:` line.
|
|
556
|
+
2. Parse each `GRADUATION_CANDIDATE: changeset=<basename> | ticket=<P-id> | priority=<N> | class=<3a|3b> | [cohort=<id> |] status=<resolved|vp-blocked|halt-no-resolution>` line. Branch on `status`:
|
|
557
|
+
- **`status=resolved`** — graduate. Per ADR-061 Rule 5 + ADR-013 Rule 5, this is policy-authorised silent proceed (no `AskUserQuestion`). Perform `git mv docs/changesets-holding/<basename> .changeset/<basename>`. Append the entry to `docs/changesets-holding/README.md` "Recently reinstated" with the citation: `<basename> — graduation criterion met (status=resolved per Rule 1a join to <P-id>, Priority <N>); class <3a|3b>; evidence cited`. For class=3b cohorts, ALL members of the cohort with `status=resolved` graduate together atomically (Rule 3b cohort propagation — entire cohort ships or none does). Amend the iter's main commit per ADR-042 Rule 3 amend-based folding to preserve the ADR-032 one-commit-per-iteration invariant.
|
|
558
|
+
- **`status=vp-blocked`** — skip. Per ADR-061 Rule 2 (Verification Pending carve-out; symmetric to ADR-042 Rule 2b). Do NOT graduate; held entry stays. The `.verifying.md` → `.closed.md` transition auto-clears the carve-out at a later Step 6.5 graduation pass.
|
|
559
|
+
- **`status=halt-no-resolution`** — halt. Per ADR-061 Rule 1a terminal: when neither filename-convention join nor body-grep fallback resolves a ticket, OR the resolved ticket file is missing/unreadable, the orchestrator MUST NOT auto-graduate. Route to the **Step 6.5 cohort-graduation halt-no-resolution** halt point (framework-prescribed halt — see Mid-loop ask discipline subsection); halt-with-batched-questions per the Step 2.5b cross-reference.
|
|
560
|
+
3. After processing all candidates: if anything graduated, the just-moved entries are now in `.changeset/` and ride the existing Drain action (no separate re-entry needed — the Drain action's `release:watch` step picks them up when `.changeset/` is non-empty). Proceed to the Drain action below.
|
|
561
|
+
4. **Governance gates apply (ADR-061 Rule 7)**: every graduation reinstate goes through the standard ADR-014 commit flow — architect / JTBD / risk-scorer gates ride the amend commit; gate rejection routes to ADR-042 Rule 5 halt with the rejection reason logged. The graduation criterion authorises the *intent*; the gates authorise the *action*.
|
|
562
|
+
|
|
563
|
+
**Idempotency**: safe to invoke when holding-area is empty (script exits 1 with `GRADUATION_SUMMARY: total=0` — orchestrator skips graduation, proceeds to Drain action). Safe when no candidates resolve (all `vp-blocked`) — no `git mv` operations, no README mutation, no commit amendment.
|
|
564
|
+
|
|
565
|
+
**Audit trail (ADR-061 Rule 6)**: every `reinstate-from-holding` graduation appends one Auto-apply-trail line to the iter report AND one "Recently reinstated" line to `docs/changesets-holding/README.md` with the resolved problem-ticket ID, Priority value, graduation class (3a or 3b), and the evidence citation. The audit trail is the load-bearing artefact for ADR-026 cite + persist + uncertainty grounding.
|
|
566
|
+
|
|
553
567
|
**Drain action (non-interactive, policy-authorised per ADR-013 Rule 6):**
|
|
554
568
|
|
|
555
569
|
1. Run `npm run push:watch` (push + wait for CI to pass).
|
|
@@ -678,6 +692,9 @@ When `AskUserQuestion` is unavailable or the user is AFK, the skill (and the del
|
|
|
678
692
|
| Commit when risk above appetite | Skip commit, report uncommitted state |
|
|
679
693
|
| Pipeline risk within appetite (≤ 4/25) with releasable material (any unpushed commits OR any `.changeset/` entries OR any graduation-eligible held entries per ADR-061 Rule 1) | Drain release queue (`push:watch` then, if releasable changesets exist, `release:watch`) before next iteration — per ADR-018 (Step 6.5) as amended by P250. Trigger is *presence of releasable material*, not residual band reaching appetite. User direction 2026-05-17: "If it's low risk, you should release." |
|
|
680
694
|
| Pipeline risk within appetite (≤ 4/25) AND empty queue (no unpushed commits AND no `.changeset/` AND no graduation-eligible held entries) | No drain — literally nothing to release. Proceed directly to Step 6.75. The genuine no-op fast-path per P250. |
|
|
695
|
+
| Cohort-graduation pre-check fires before Drain action (within-appetite branch, `docs/changesets-holding/` non-empty) — evaluator returns `status=resolved` | Graduate. Per ADR-061 Rule 5 + ADR-013 Rule 5 policy-authorised silent proceed (no `AskUserQuestion`): `git mv docs/changesets-holding/<basename> .changeset/<basename>`, append README "Recently reinstated" entry, amend the iter's main commit per ADR-042 Rule 3. For class=3b cohorts, all cohort members with `status=resolved` graduate atomically (Rule 3b cohort propagation). Per ADR-061 Rule 5 + Rule 6 + Rule 7 + P246 (Step 6.5 Cohort-graduation pre-check). Graduation criterion is evidence-of-working-as-desired (Rule 4 evidence floor), not elapsed wall-clock time — user direction 2026-05-17: "Dogfooding makes sense, but it shouldn't be time based, it should be until we are happy that it's working as desired." |
|
|
696
|
+
| Cohort-graduation pre-check — evaluator returns `status=vp-blocked` | Skip. Per ADR-061 Rule 2 Verification Pending carve-out (symmetric to ADR-042 Rule 2b). Do NOT graduate; held entry stays. `.verifying.md` → `.closed.md` transition auto-clears the carve-out at a later pass. Per ADR-061 Rule 2 + P246. |
|
|
697
|
+
| Cohort-graduation pre-check — evaluator returns `status=halt-no-resolution` | Halt at the framework-prescribed "Step 6.5 cohort-graduation halt-no-resolution" halt point. Per ADR-061 Rule 1a terminal: ambiguous join is a user-decision surface, not an agent-decision surface. Halt-with-batched-questions per the Step 2.5b cross-reference. Per ADR-061 Rule 1a + P246. |
|
|
681
698
|
| Post-release plugin cache refresh between iters (P233) | After a successful within-appetite Drain action shipped a release to npm, chain `/install-updates` to refresh the plugin cache before the next iter dispatches. Conditional on actual release (skipped when `push:watch` ran alone with no changeset); non-blocking on `/install-updates` failure (degrades to cache-stays-stale, equivalent to pre-amendment behaviour). Mid-loop ask discipline preserved by treating any `/install-updates` AskUserQuestion surface AS the Non-interactive fallback dry-run path. Per ADR-013 Rule 5 + ADR-044 + P130 + P106 + P233 (Step 6.5 Post-release cache refresh subsection). |
|
|
682
699
|
| CI failure during Step 6.5 drain (within-appetite branch) | Diagnose via `gh run view --log-failed`, classify against the closed fixable-in-iter allow-list (P081-class stale-grep-string, hook stub mismatch, test ID drift, environmental flake), fix-and-continue for fixable classes (each retry rides its own ADR-014 commit gate), 3-retry cap per iteration, halt for unrecoverable classes. Ambiguous classification defaults to halt. ADR-013 Rule 5 policy-authorised. Per ADR-026 grounding + ADR-044 framework-resolution boundary + P140 (Step 6.5 Failure handling). |
|
|
683
700
|
| Pipeline risk above appetite (push or release >= 5/25) | Auto-apply scorer remediations incrementally (ADR-042 Rule 2). The agent reads suggestions and decides what to do. Re-score after each apply; drain when within appetite. **Never release above appetite** (ADR-042 Rule 1) — no AskUserQuestion shortcut. Halt the loop with `outcome: halted-above-appetite` if the loop exhausts without convergence (ADR-042 Rule 5). Verification Pending commits excluded from auto-revert (Rule 2b). Per ADR-042 (Step 6.5 Above-appetite branch). |
|
|
@@ -688,7 +705,7 @@ When `AskUserQuestion` is unavailable or the user is AFK, the skill (and the del
|
|
|
688
705
|
| Halt-path final summary with accumulated user-answerable skips (CI failure / Rule 5 above-appetite / dirty-unknown / session-continuity / fetch failure) | Run Step 2.5b's surfacing routine before emitting the halt path's final AFK summary. Step 2.5b is gated on ≥1 accumulated user-answerable skip — empty-skip halts skip the routine. Step 2.5b surfaces *prior-iter accumulated user-answerable skips only*; it does NOT ask the user how to remediate the halt cause itself (CI failure / above-appetite state / dirty-unknown state remain halt-with-bug-signal). Per ADR-013 Rule 1 + ADR-032 + P126 (`halt-paths-must-route-design-questions-through-Step-2.5b`). |
|
|
689
706
|
| Unexpected dirty state between iterations | Halt the loop. Report the `git status --porcelain` output, the last iteration's reported outcome, and the divergence — per P036 (Step 6.75). Run Step 2.5b before emitting the halt summary if ≥1 accumulated user-answerable skip from prior iters (P126). Do NOT attempt non-interactive recovery of the dirty state itself. |
|
|
690
707
|
| External root cause detected at Open → Known Error, or at park with `upstream-blocked` reason | Append the stable `- **Upstream report pending** — external dependency identified; invoke /wr-itil:report-upstream when ready` marker to the ticket's `## Related` section; do NOT auto-invoke `/wr-itil:report-upstream` (Step 6 security-path branch is interactive — per ADR-024 Consequences). Use the already-noted grep check to avoid duplicate lines. Per P063 + ADR-013 Rule 6. |
|
|
691
|
-
| Mid-loop ask between iters in the orchestrator's main turn | Forbidden except at framework-prescribed halt points (Step 0 session-continuity / fetch-failure halt; Step 2.5 / 2.5b loop-end emit; Step 6.5 above-appetite Rule 5 halt; Step 6.5 CI-failure / release:watch halt; Step 6.75 dirty-for-unknown-reason halt). The loop's purpose is **progress + accumulation**; mechanical-stage transitions between iters are framework-resolved and MUST NOT prompt the user. Per ADR-044 framework-resolution boundary + ADR-013 Rule 1 (as amended by ADR-044) + P130. |
|
|
708
|
+
| Mid-loop ask between iters in the orchestrator's main turn | Forbidden except at framework-prescribed halt points (Step 0 session-continuity / fetch-failure halt; Step 2.5 / 2.5b loop-end emit; Step 6.5 above-appetite Rule 5 halt; Step 6.5 CI-failure / release:watch halt; Step 6.5 cohort-graduation halt-no-resolution halt; Step 6.75 dirty-for-unknown-reason halt). The loop's purpose is **progress + accumulation**; mechanical-stage transitions between iters are framework-resolved and MUST NOT prompt the user. Per ADR-044 framework-resolution boundary + ADR-013 Rule 1 (as amended by ADR-044) + P130. |
|
|
692
709
|
|
|
693
710
|
### Mid-loop ask discipline (orchestrator main turn) — P130
|
|
694
711
|
|
|
@@ -701,6 +718,7 @@ The orchestrator MUST NOT call `AskUserQuestion` between iterations except at th
|
|
|
701
718
|
- **Step 2.5 / Step 2.5b loop-end emit** — accumulated `outstanding_questions` queue presented as batched `AskUserQuestion` (or fallback Outstanding Design Questions table per ADR-013 Rule 6). This is the framework's prescribed user-interaction point; do NOT dilute it by asking earlier.
|
|
702
719
|
- **Step 6.5 above-appetite Rule 5 halt** — auto-apply loop exhausted without convergence; halt-with-batched-questions per the Step 2.5b cross-reference (Step 2.5b surfaces *prior-iter accumulated user-answerable skips only* — the halt-causing scorer-gap remains a halt-with-bug-signal per ADR-042 Rule 5).
|
|
703
720
|
- **Step 6.5 CI-failure / `release:watch` failure halt** — push:watch or release:watch failed AND the failure is genuinely-unrecoverable (outside the fixable-in-iter allow-list, or 3-retry cap reached); halt-with-batched-questions per the Step 2.5b cross-reference. Failures inside the closed allow-list route to fix-and-continue per Step 6.5 Failure handling (P140), not this halt point.
|
|
721
|
+
- **Step 6.5 cohort-graduation halt-no-resolution halt (P246)** — graduation evaluator returned `status=halt-no-resolution` for one or more held candidates (Rule 1a terminal: neither filename-convention join nor body-grep fallback resolved a problem ticket, OR the resolved ticket file is missing/unreadable). The orchestrator MUST NOT auto-graduate under ambiguity per ADR-061 Rule 1a; halt-with-batched-questions per the Step 2.5b cross-reference. The halt-causing ambiguity itself remains a halt-with-bug-signal (the held entry stays in `docs/changesets-holding/`; manual reinstate or ticket-file correction required); Step 2.5b surfaces *prior-iter accumulated user-answerable skips only* and does NOT ask the user to resolve the ambiguity itself.
|
|
704
722
|
- **Step 6.75 dirty-for-unknown-reason halt** — `git status --porcelain` divergence; halt-with-batched-questions per the Step 2.5b cross-reference.
|
|
705
723
|
|
|
706
724
|
**No mid-iter ask points.** Every other point in the orchestrator's main turn (between Step 5 dispatch completing and Step 6.5 release-cadence check; between Step 6.75 verification and Step 7 loop-back; between Step 7 and Step 1 next-iteration; between consecutive iters generally) is a mechanical-stage transition that the framework has already resolved. Do NOT introduce ad-hoc `AskUserQuestion` calls at those points to confirm "is it OK to proceed?" or "want me to start the next iter?" — proceeding IS the framework-resolved default. Continue iterating until quota or stop-condition #1/#2/#3 fires.
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
#!/usr/bin/env bats
|
|
2
|
+
|
|
3
|
+
# P246: /wr-itil:work-problems Step 6.5 cohort-graduation pre-check must
|
|
4
|
+
# invoke the deterministic graduation evaluator BEFORE the Drain action
|
|
5
|
+
# when the within-appetite-with-releasable-material branch fires AND
|
|
6
|
+
# docs/changesets-holding/ is non-empty.
|
|
7
|
+
#
|
|
8
|
+
# Refined framing (per user direction 2026-05-17): graduation criterion
|
|
9
|
+
# is positive evidence that the surface works as desired (ADR-061 Rule 4
|
|
10
|
+
# per-class evidence floor), NOT elapsed wall-clock time. Calendar
|
|
11
|
+
# predicates (`≥7 days in-repo dogfood`, `on or after <date>`) are NEVER
|
|
12
|
+
# a primary graduation trigger.
|
|
13
|
+
#
|
|
14
|
+
# Pre-check parses `GRADUATION_CANDIDATE` lines from the evaluator and
|
|
15
|
+
# branches per the 3-status taxonomy the evaluator actually emits:
|
|
16
|
+
#
|
|
17
|
+
# status=resolved → git mv from holding to .changeset/,
|
|
18
|
+
# README "Recently reinstated" append,
|
|
19
|
+
# amend iter commit per ADR-042 Rule 3
|
|
20
|
+
# (policy-authorised silent proceed per
|
|
21
|
+
# ADR-013 Rule 5 + ADR-061 Rule 5).
|
|
22
|
+
# status=vp-blocked → skip (ADR-061 Rule 2 VP carve-out).
|
|
23
|
+
# status=halt-no-resolution → halt at the framework-prescribed
|
|
24
|
+
# "Step 6.5 cohort-graduation halt-
|
|
25
|
+
# no-resolution" halt point (ADR-061
|
|
26
|
+
# Rule 1a terminal).
|
|
27
|
+
#
|
|
28
|
+
# Class=3b cohorts graduate atomically per ADR-061 Rule 3b — entire
|
|
29
|
+
# cohort ships or none does.
|
|
30
|
+
#
|
|
31
|
+
# Doc-lint contract assertions per ADR-037 Permitted Exception (contract-
|
|
32
|
+
# assertion class). The asserted prose IS the load-bearing policy surface
|
|
33
|
+
# — re-reading SKILL.md is the only way an AFK reader (and the iteration
|
|
34
|
+
# subprocess) learns the new pre-check behaviour. These tests function as
|
|
35
|
+
# regression guards against re-introducing calendar-trigger framings,
|
|
36
|
+
# silently removing the pre-check, or drifting the 3-status branching.
|
|
37
|
+
#
|
|
38
|
+
# @problem P246
|
|
39
|
+
# @adr ADR-061 (parent principle — Rules 1/1a/2/3/4/5/6/7)
|
|
40
|
+
# @adr ADR-042 (Rule 3 amend-based folding for graduation reinstate commit)
|
|
41
|
+
# @adr ADR-018 (release-cadence policy parent — drain condition unchanged)
|
|
42
|
+
# @adr ADR-013 (Rule 5 policy-authorised silent proceed)
|
|
43
|
+
# @adr ADR-037 (skill-testing strategy — contract-assertion class)
|
|
44
|
+
# @adr ADR-044 (framework-resolution boundary — no AskUserQuestion mid-iter)
|
|
45
|
+
# @jtbd JTBD-006 (Progress the Backlog While I'm Away — primary)
|
|
46
|
+
# @jtbd JTBD-302 (Trust That the README Describes the Plugin I Just Installed)
|
|
47
|
+
# @jtbd JTBD-001 (Enforce Governance Without Slowing Down)
|
|
48
|
+
# @jtbd JTBD-101 (Extend the Suite with New Plugins)
|
|
49
|
+
|
|
50
|
+
setup() {
|
|
51
|
+
REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/../../../../.." && pwd)"
|
|
52
|
+
SKILL_MD="$REPO_ROOT/packages/itil/skills/work-problems/SKILL.md"
|
|
53
|
+
HOLDING_README="$REPO_ROOT/docs/changesets-holding/README.md"
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
# ── Preconditions ──────────────────────────────────────────────────────────
|
|
57
|
+
|
|
58
|
+
@test "work-problems P246: SKILL.md exists" {
|
|
59
|
+
[ -f "$SKILL_MD" ]
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@test "work-problems P246: changesets-holding README exists" {
|
|
63
|
+
[ -f "$HOLDING_README" ]
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
# ── Pre-check sub-step exists and cites the evaluator shim ────────────────
|
|
67
|
+
|
|
68
|
+
@test "work-problems P246: SKILL.md Step 6.5 contains 'Cohort-graduation pre-check' sub-step" {
|
|
69
|
+
run grep -nE 'Cohort-graduation pre-check.*ADR-061 Rule 5.*P246' "$SKILL_MD"
|
|
70
|
+
[ "$status" -eq 0 ]
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@test "work-problems P246: pre-check invokes wr-risk-scorer-evaluate-graduation shim" {
|
|
74
|
+
run grep -nE 'wr-risk-scorer-evaluate-graduation' "$SKILL_MD"
|
|
75
|
+
[ "$status" -eq 0 ]
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
@test "work-problems P246: pre-check fires BEFORE the Drain action (on within-appetite branch)" {
|
|
79
|
+
# The pre-check must precede the Drain action heading; if SKILL.md
|
|
80
|
+
# ever inverts the order, the just-graduated entries would not ride
|
|
81
|
+
# the existing release flow.
|
|
82
|
+
pre_check_line=$(grep -nE '^\*\*Cohort-graduation pre-check' "$SKILL_MD" | head -1 | cut -d: -f1)
|
|
83
|
+
drain_line=$(grep -nE '^\*\*Drain action ' "$SKILL_MD" | head -1 | cut -d: -f1)
|
|
84
|
+
[ -n "$pre_check_line" ]
|
|
85
|
+
[ -n "$drain_line" ]
|
|
86
|
+
[ "$pre_check_line" -lt "$drain_line" ]
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
# ── Three-status branching contract ───────────────────────────────────────
|
|
90
|
+
|
|
91
|
+
@test "work-problems P246: pre-check branches on status=resolved → graduate" {
|
|
92
|
+
# The load-bearing positive contract: status=resolved means graduate
|
|
93
|
+
# via git mv + README append + ADR-042 Rule 3 amend.
|
|
94
|
+
run grep -nE '`status=resolved`.*graduate' "$SKILL_MD"
|
|
95
|
+
[ "$status" -eq 0 ]
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
@test "work-problems P246: status=resolved branch performs git mv from holding to .changeset/" {
|
|
99
|
+
run grep -nE 'git mv docs/changesets-holding/<basename> \.changeset/<basename>' "$SKILL_MD"
|
|
100
|
+
[ "$status" -eq 0 ]
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
@test "work-problems P246: status=resolved branch amends the iter commit per ADR-042 Rule 3" {
|
|
104
|
+
run grep -nE 'Amend the iter.s main commit per ADR-042 Rule 3 amend-based folding' "$SKILL_MD"
|
|
105
|
+
[ "$status" -eq 0 ]
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
@test "work-problems P246: pre-check branches on status=vp-blocked → skip (ADR-061 Rule 2)" {
|
|
109
|
+
run grep -nE '`status=vp-blocked`.*skip.*ADR-061 Rule 2' "$SKILL_MD"
|
|
110
|
+
[ "$status" -eq 0 ]
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
@test "work-problems P246: pre-check branches on status=halt-no-resolution → halt at framework-prescribed point" {
|
|
114
|
+
run grep -nE '`status=halt-no-resolution`.*halt.*ADR-061 Rule 1a terminal' "$SKILL_MD"
|
|
115
|
+
[ "$status" -eq 0 ]
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
@test "work-problems P246: SKILL.md does NOT branch on non-existent status=no-graduate-evidence-floor" {
|
|
119
|
+
# Architect verdict: the evaluator emits only resolved | vp-blocked |
|
|
120
|
+
# halt-no-resolution. A SKILL branch handling a non-existent token
|
|
121
|
+
# would be dead code (Confirmation Violation).
|
|
122
|
+
run grep -nE 'no-graduate-evidence-floor' "$SKILL_MD"
|
|
123
|
+
[ "$status" -ne 0 ]
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
# ── Cohort propagation (class=3b atomic) ──────────────────────────────────
|
|
127
|
+
|
|
128
|
+
@test "work-problems P246: class=3b cohorts graduate atomically (entire cohort ships or none does)" {
|
|
129
|
+
run grep -nE 'class=3b cohorts.*ALL members.*graduate together atomically|cohort ships or none does' "$SKILL_MD"
|
|
130
|
+
[ "$status" -eq 0 ]
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
@test "work-problems P246: cohort propagation cites ADR-061 Rule 3b" {
|
|
134
|
+
run grep -nE 'Rule 3b cohort propagation' "$SKILL_MD"
|
|
135
|
+
[ "$status" -eq 0 ]
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
# ── Framework-prescribed halt point added ─────────────────────────────────
|
|
139
|
+
|
|
140
|
+
@test "work-problems P246: new halt point 'Step 6.5 cohort-graduation halt-no-resolution' in Mid-loop ask discipline list" {
|
|
141
|
+
run grep -nE 'Step 6\.5 cohort-graduation halt-no-resolution halt.*P246' "$SKILL_MD"
|
|
142
|
+
[ "$status" -eq 0 ]
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
@test "work-problems P246: halt-no-resolution halt routes through Step 2.5b cross-reference" {
|
|
146
|
+
# Architect verdict: halt-no-resolution must inherit the established
|
|
147
|
+
# Step 2.5b routing pattern (CI failure / Rule 5 above-appetite /
|
|
148
|
+
# dirty-unknown all route this way).
|
|
149
|
+
run grep -nE 'cohort-graduation.*Step 2\.5b cross-reference|halt-with-batched-questions per the Step 2\.5b cross-reference' "$SKILL_MD"
|
|
150
|
+
[ "$status" -eq 0 ]
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
@test "work-problems P246: Mid-loop ask between iters row enumerates the new halt point" {
|
|
154
|
+
run grep -nE 'Mid-loop ask between iters.*Step 6\.5 cohort-graduation halt-no-resolution halt' "$SKILL_MD"
|
|
155
|
+
[ "$status" -eq 0 ]
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
# ── Non-Interactive Decision Making table reflects amendment ──────────────
|
|
159
|
+
|
|
160
|
+
@test "work-problems P246: Decision Making table carries the resolved-graduate row" {
|
|
161
|
+
run grep -nE '\| Cohort-graduation pre-check.*status=resolved' "$SKILL_MD"
|
|
162
|
+
[ "$status" -eq 0 ]
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
@test "work-problems P246: Decision Making table carries the vp-blocked-skip row" {
|
|
166
|
+
run grep -nE '\| Cohort-graduation pre-check.*status=vp-blocked' "$SKILL_MD"
|
|
167
|
+
[ "$status" -eq 0 ]
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
@test "work-problems P246: Decision Making table carries the halt-no-resolution-halt row" {
|
|
171
|
+
run grep -nE '\| Cohort-graduation pre-check.*status=halt-no-resolution' "$SKILL_MD"
|
|
172
|
+
[ "$status" -eq 0 ]
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
# ── Evidence-based criterion (calendar-trigger rejection) ─────────────────
|
|
176
|
+
|
|
177
|
+
@test "work-problems P246: pre-check states graduation criterion is evidence-of-working-as-desired, NOT elapsed wall-clock time" {
|
|
178
|
+
run grep -nE 'evidence-of-working-as-desired.*not elapsed wall-clock time|not elapsed wall-clock time' "$SKILL_MD"
|
|
179
|
+
[ "$status" -eq 0 ]
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
@test "work-problems P246: pre-check explicitly rejects calendar predicates as primary triggers" {
|
|
183
|
+
run grep -nE 'Calendar predicates are NEVER a primary graduation trigger' "$SKILL_MD"
|
|
184
|
+
[ "$status" -eq 0 ]
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
@test "work-problems P246: pre-check cites user direction verbatim ('Dogfooding makes sense, but it shouldn't be time based')" {
|
|
188
|
+
run grep -nE "Dogfooding makes sense, but it shouldn.t be time based, it should be until we are happy that it.s working as desired" "$SKILL_MD"
|
|
189
|
+
[ "$status" -eq 0 ]
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
@test "work-problems P246: pre-check cites user correction verbatim ('Why are we waiting?')" {
|
|
193
|
+
run grep -nE "Why are we waiting\?.*That seems to go against the principles if you ask me" "$SKILL_MD"
|
|
194
|
+
[ "$status" -eq 0 ]
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
# ── Policy authorisation (ADR-013 Rule 5 + ADR-061 Rule 5) ────────────────
|
|
198
|
+
|
|
199
|
+
@test "work-problems P246: resolved-branch is policy-authorised silent proceed (no AskUserQuestion)" {
|
|
200
|
+
run grep -nE 'policy-authorised silent proceed.*no.*AskUserQuestion' "$SKILL_MD"
|
|
201
|
+
[ "$status" -eq 0 ]
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
@test "work-problems P246: pre-check cites ADR-013 Rule 5" {
|
|
205
|
+
run grep -nE 'ADR-013 Rule 5' "$SKILL_MD"
|
|
206
|
+
[ "$status" -eq 0 ]
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
@test "work-problems P246: pre-check cites ADR-061 Rule 5" {
|
|
210
|
+
run grep -nE 'ADR-061 Rule 5' "$SKILL_MD"
|
|
211
|
+
[ "$status" -eq 0 ]
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
# ── Governance gates apply (ADR-061 Rule 7) ───────────────────────────────
|
|
215
|
+
|
|
216
|
+
@test "work-problems P246: pre-check governance gates apply per ADR-061 Rule 7" {
|
|
217
|
+
run grep -nE 'Governance gates apply.*ADR-061 Rule 7|graduation reinstate goes through the standard ADR-014 commit flow' "$SKILL_MD"
|
|
218
|
+
[ "$status" -eq 0 ]
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
# ── Audit trail (ADR-061 Rule 6) ──────────────────────────────────────────
|
|
222
|
+
|
|
223
|
+
@test "work-problems P246: pre-check audit trail cites ADR-061 Rule 6" {
|
|
224
|
+
run grep -nE 'Audit trail.*ADR-061 Rule 6' "$SKILL_MD"
|
|
225
|
+
[ "$status" -eq 0 ]
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
@test "work-problems P246: audit trail appends README 'Recently reinstated' entry" {
|
|
229
|
+
run grep -nE 'Recently reinstated.*resolved problem-ticket ID.*Priority value|graduation criterion met.*status=resolved' "$SKILL_MD"
|
|
230
|
+
[ "$status" -eq 0 ]
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
# ── Idempotency ───────────────────────────────────────────────────────────
|
|
234
|
+
|
|
235
|
+
@test "work-problems P246: pre-check is idempotent when holding-area is empty" {
|
|
236
|
+
run grep -nE 'Idempotency.*holding-area is empty|safe to invoke when holding-area is empty' "$SKILL_MD"
|
|
237
|
+
[ "$status" -eq 0 ]
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
@test "work-problems P246: pre-check is idempotent when no candidates resolve (all vp-blocked)" {
|
|
241
|
+
run grep -nE 'Safe when no candidates resolve.*all .vp-blocked.' "$SKILL_MD"
|
|
242
|
+
[ "$status" -eq 0 ]
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
# ── Holding README Process amendment ──────────────────────────────────────
|
|
246
|
+
|
|
247
|
+
@test "work-problems P246: holding README Process step 5 cites P246 refined framing" {
|
|
248
|
+
run grep -nE 'refined by P246|P246 refined framing' "$HOLDING_README"
|
|
249
|
+
[ "$status" -eq 0 ]
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
@test "work-problems P246: holding README Process step 5 states criterion is positive evidence (NOT calendar)" {
|
|
253
|
+
run grep -nE 'positive evidence that the surface works as desired' "$HOLDING_README"
|
|
254
|
+
[ "$status" -eq 0 ]
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
@test "work-problems P246: holding README Process step 5 rejects calendar predicates as primary trigger" {
|
|
258
|
+
run grep -nE 'Calendar predicates.*never.*primary graduation trigger|NEVER a primary graduation trigger' "$HOLDING_README"
|
|
259
|
+
[ "$status" -eq 0 ]
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
@test "work-problems P246: holding README Process step 5 cites user direction verbatim" {
|
|
263
|
+
run grep -nE "Dogfooding makes sense, but it shouldn.t be time based" "$HOLDING_README"
|
|
264
|
+
[ "$status" -eq 0 ]
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
@test "work-problems P246: holding README Process step 5 enumerates the 3-status taxonomy" {
|
|
268
|
+
run grep -nE 'status=<resolved\|vp-blocked\|halt-no-resolution>' "$HOLDING_README"
|
|
269
|
+
[ "$status" -eq 0 ]
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
@test "work-problems P246: holding README Process step 5 explicitly preserves at-hold-time historical contracts" {
|
|
273
|
+
# Architect verdict: per-entry Currently held lines authored BEFORE
|
|
274
|
+
# the P246 framing are retained as at-hold-time historical contracts
|
|
275
|
+
# (not retroactively rewritten).
|
|
276
|
+
run grep -nE 'retained as at-hold-time historical contracts.*not retroactively rewritten' "$HOLDING_README"
|
|
277
|
+
[ "$status" -eq 0 ]
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
# ── P246 self-identification (ticket-trace) ───────────────────────────────
|
|
281
|
+
|
|
282
|
+
@test "work-problems P246: SKILL.md self-identifies the cohort-graduation pre-check as P246's amendment" {
|
|
283
|
+
run grep -nE 'P246' "$SKILL_MD"
|
|
284
|
+
[ "$status" -eq 0 ]
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
@test "work-problems P246: holding README self-identifies the Process amendment as P246's refined framing" {
|
|
288
|
+
run grep -nE 'P246' "$HOLDING_README"
|
|
289
|
+
[ "$status" -eq 0 ]
|
|
290
|
+
}
|