@windyroad/itil 0.56.1 → 0.56.2-preview.909

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.
@@ -497,5 +497,5 @@
497
497
  }
498
498
  },
499
499
  "name": "wr-itil",
500
- "version": "0.56.1"
500
+ "version": "0.56.2"
501
501
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@windyroad/itil",
3
- "version": "0.56.1",
3
+ "version": "0.56.2-preview.909",
4
4
  "description": "ITIL-aligned IT service management for Claude Code (problem, and future incident/change skills)",
5
5
  "bin": {
6
6
  "windyroad-itil": "./bin/install.mjs"
@@ -38,7 +38,8 @@
38
38
  # 0 = OK (full citation emitted, OR de-facto-released graduated-holding
39
39
  # changeset whose code already shipped with a sibling release — P361)
40
40
  # 1 = ticket file not found
41
- # 2 = no changeset reference in ticket body
41
+ # 2 = no changeset reference in ticket body AND no co-committed changeset
42
+ # derivable from the ticket's git history (P389 fallback)
42
43
  # 3 = changeset present in working tree AND not de-facto-released
43
44
  # (genuinely unreleased)
44
45
  # 4 = deletion commit found but no merge PR / merge commit resolvable
@@ -80,7 +81,7 @@ USAGE: derive-release-vehicle.sh <ticket-id> [<problems-dir>]
80
81
  Exit codes:
81
82
  0 ok (full citation, OR de-facto-released graduated-holding changeset — P361)
82
83
  1 ticket file not found
83
- 2 no changeset reference in ticket body
84
+ 2 no changeset reference in body AND no co-committed changeset in ticket history (P389)
84
85
  3 changeset present in working tree AND not de-facto-released (unreleased)
85
86
  4 deletion commit found but no merge PR / merge commit resolvable
86
87
  EOF
@@ -125,8 +126,34 @@ CHANGESET_PATH="$(
125
126
  | head -1
126
127
  )"
127
128
 
129
+ # ── Fallback (P389): body has no changeset reference — recover via co-commit ─
130
+ # An iter that fixes a Known Error sometimes ships the fix + changeset but omits
131
+ # the P330 `**Release vehicle**` seed, leaving the ticket body with no
132
+ # `.changeset/` reference. derive would exit 2 and the post-release K→V
133
+ # enumerator (P228) silently skips the ticket even though its fix shipped. Under
134
+ # ADR-014's one-commit grain the fix commit that authored the changeset also
135
+ # edited this ticket, so a `.changeset/*.md` ADDED by a commit that also touched
136
+ # the ticket file is this ticket's release vehicle. Walk the ticket's commits
137
+ # (newest first, across state renames) and take the first co-committed changeset.
138
+ # ponytail: co-commit join. False negative — the P141 multi-slice case (changeset
139
+ # on an earlier commit that did NOT touch the ticket) still needs the manual P330
140
+ # seed. False positive — a later commit touching the ticket AND adding an
141
+ # unrelated changeset would be picked first; acceptable for a mechanical fallback.
128
142
  if [ -z "$CHANGESET_PATH" ]; then
129
- echo "ERROR: no .changeset/<name>.md reference in $TICKET_FILE" >&2
143
+ while IFS= read -r _commit; do
144
+ [ -z "$_commit" ] && continue
145
+ CHANGESET_PATH="$(
146
+ git show "$_commit" --diff-filter=A --name-only --format='' -- .changeset/ 2>/dev/null \
147
+ | grep -E '\.changeset/[a-z0-9._-]+\.md$' \
148
+ | grep -v -i 'README\.md' \
149
+ | head -1
150
+ )"
151
+ [ -n "$CHANGESET_PATH" ] && break
152
+ done < <(git log --follow --format='%H' -- "$TICKET_FILE" 2>/dev/null)
153
+ fi
154
+
155
+ if [ -z "$CHANGESET_PATH" ]; then
156
+ echo "ERROR: no .changeset/<name>.md reference in $TICKET_FILE (and no co-committed changeset in ticket history — P389)" >&2
130
157
  exit 2
131
158
  fi
132
159
 
@@ -98,6 +98,39 @@ EOF
98
98
  echo "$output" | grep -qiE "no .?changeset|changeset.*reference"
99
99
  }
100
100
 
101
+ @test "derive-release-vehicle: P389 fallback — body has no ref but a co-committed changeset in ticket history is recovered (not a false exit 2)" {
102
+ # An iter shipped the fix + changeset in ONE commit (ADR-014 grain) but omitted
103
+ # the P330 **Release vehicle** seed, so the ticket body has no .changeset ref.
104
+ # Pre-P389 this exited 2 and the K→V enumerator (P228) silently skipped the
105
+ # ticket. The fallback walks the ticket's own commits for a co-committed
106
+ # changeset. Here the changeset is still in the working tree (unreleased), so
107
+ # recovery lands on exit 3 (found-but-unreleased) — NOT exit 2 (not found).
108
+ cat > docs/problems/known-error/101-co-commit-no-seed.md <<'EOF'
109
+ # Problem 101: Fix shipped, seed omitted
110
+
111
+ **Status**: Known Error
112
+
113
+ ## Description
114
+
115
+ The fix landed but the **Release vehicle** seed line was never written, so this
116
+ body references no .changeset filename.
117
+ EOF
118
+ mkdir -p .changeset
119
+ cat > .changeset/p101-co-commit-fix.md <<'EOF'
120
+ ---
121
+ "@windyroad/itil": patch
122
+ ---
123
+
124
+ P101 fix.
125
+ EOF
126
+ git add docs/problems/known-error/101-co-commit-no-seed.md .changeset/p101-co-commit-fix.md
127
+ git commit -q -m "fix(itil): P101 fix + changeset (co-committed, no seed)"
128
+
129
+ run "$SCRIPT" P101 docs/problems
130
+ [ "$status" -eq 3 ]
131
+ echo "$output" | grep -qiE "p101-co-commit-fix|unreleased|working tree"
132
+ }
133
+
101
134
  # ── Exit 3: changeset still present (unreleased) ────────────────────────────
102
135
 
103
136
  @test "derive-release-vehicle: changeset still in working tree (unreleased) → exit 3" {