@windyroad/itil 0.23.5 → 0.24.0-preview.268

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.
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "wr-itil",
3
- "version": "0.23.5",
3
+ "version": "0.24.0",
4
4
  "description": "ITIL-aligned IT service management for Claude Code"
5
5
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@windyroad/itil",
3
- "version": "0.23.5",
3
+ "version": "0.24.0-preview.268",
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"
@@ -230,7 +230,7 @@ If the upstream had a matching template (Step 3), fill its required fields from
230
230
  | Upstream template field (typical) | Local ticket source |
231
231
  |---|---|
232
232
  | `plugin` / `package` / `module` | Inferred from upstream repo name or local ticket's "Affected plugin / component" |
233
- | `version` | Local ticket's environment notes; or `npm view <pkg> version` for the latest if ambiguous |
233
+ | `version` (single-slot version field) | Per ADR-033 amendment 2026-05-03 (P128) populate with the local plugin version from the consolidated `## Versions` schema below; the full `## Versions` block is ALSO appended to the body's prose so the upstream maintainer has both the template's structured slot AND every version dimension. |
234
234
  | `claude-code-version` | `claude --version` if the report originates from a Claude Code session |
235
235
  | `os` | Local ticket's environment notes; or `uname -srm` of the reporting host |
236
236
  | `description` | Local ticket's `## Description` section |
@@ -239,6 +239,30 @@ If the upstream had a matching template (Step 3), fill its required fields from
239
239
  | `frequency` | Local ticket's `## Impact Assessment` Frequency line |
240
240
  | `evidence` | Commit SHAs, test output, transcript excerpts from Investigation Tasks |
241
241
 
242
+ #### Versions schema (ADR-033 amendment 2026-05-03, P128)
243
+
244
+ Every body — matched-template path AND structured-default fallback — MUST include a labelled `## Versions` section carrying the five-field schema below. Missing fields render as `not detected` (normative MUST per ADR-033 amendment); omitting a field entirely is non-compliant because triage cannot distinguish *field omitted because not applicable* from *detection failed*.
245
+
246
+ ```markdown
247
+ ## Versions
248
+
249
+ - Local plugin: `@windyroad/<pkg>@<version>` (or "not detected" if reporting against a non-windyroad package)
250
+ - Upstream package: `<pkg>@<version>` (or "not detected" if not applicable)
251
+ - Claude Code CLI: `<claude --version output>` (or "not detected")
252
+ - Node: `<node --version output>` (or "not detected")
253
+ - OS: `<uname -srm output or platform detection>` (or "not detected")
254
+ ```
255
+
256
+ **Auto-population sources** (best-effort; each source returns "not detected" on failure rather than crashing the skill):
257
+
258
+ - **Local plugin** — read `package.json` for `@windyroad/*` dependencies; or run `claude plugin list --json` and pick the matching plugin.
259
+ - **Upstream package** — `gh api repos/<owner>/<repo>/releases/latest` (GitHub-hosted) or `npm view <pkg> version` (npm-published); fall back to the local ticket's environment notes if neither resolves.
260
+ - **Claude Code CLI** — `claude --version`.
261
+ - **Node** — `node --version`.
262
+ - **OS** — `uname -srm` (POSIX) or platform-equivalent.
263
+
264
+ Cost note: `gh api` and `npm view` are network calls; cache within a session where reasonable. The five-field schema is fixed so downstream consumers (P129's inbound version-aware classifier, when it lands) parse against a stable surface.
265
+
242
266
  For upstream repos whose matched template is `bug-report.yml` / `feature-request.yml` / `question.yml` (Step 3 backward-compat fallback), the skill fills the corresponding field set: `reproduction` ← `## Symptoms`; `expected` / `actual` ← observed-vs-expected contrast lines under `## Description`; `proposal` (for features) ← `## Description`.
243
267
 
244
268
  #### Structured default body — problem-shaped (primary, per ADR-033)
@@ -266,12 +290,13 @@ Use this body when the Step 3 classifier picked `problem` shape AND the upstream
266
290
 
267
291
  <from the local ticket's Impact Assessment "Frequency" line>
268
292
 
269
- ## Environment
293
+ ## Versions
270
294
 
271
- - Package: <inferred from upstream repo>
272
- - Version: <detected via npm ls or local ticket's notes>
273
- - Claude Code version: <claude --version>
274
- - OS: <uname -srm>
295
+ - Local plugin: `@windyroad/<pkg>@<version>` (or "not detected")
296
+ - Upstream package: `<pkg>@<version>` (or "not detected")
297
+ - Claude Code CLI: <claude --version output> (or "not detected")
298
+ - Node: <node --version output> (or "not detected")
299
+ - OS: <uname -srm output> (or "not detected")
275
300
 
276
301
  ## Evidence
277
302
 
@@ -284,7 +309,7 @@ Reported from <downstream-repo-url>/<local-ticket-relative-path>
284
309
  This issue is tracked locally as P<NNN> in the downstream project's `docs/problems/` directory.
285
310
  ```
286
311
 
287
- The body MUST include the `## Cross-reference` section so Step 7's back-write contract works (the downstream ticket's `## Reported Upstream` section records the upstream URL; the upstream issue body records the downstream reference).
312
+ The body MUST include the `## Cross-reference` section so Step 7's back-write contract works (the downstream ticket's `## Reported Upstream` section records the upstream URL; the upstream issue body records the downstream reference). The body MUST also include the labelled `## Versions` section per the ADR-033 amendment 2026-05-03 (P128); see the Versions schema block under Step 5's field-mapping table for the five-field contract and "not detected" rendering rule.
288
313
 
289
314
  #### Structured default body — bug-shaped (fallback-only)
290
315
 
@@ -307,12 +332,13 @@ Use this body only when the Step 3 classifier picked `bug` shape as backward-com
307
332
 
308
333
  <from local ticket>
309
334
 
310
- ## Environment
335
+ ## Versions
311
336
 
312
- - Package: <inferred from upstream repo>
313
- - Version: <detected via npm ls or local ticket's notes>
314
- - Claude Code version: <claude --version>
315
- - OS: <uname -srm>
337
+ - Local plugin: `@windyroad/<pkg>@<version>` (or "not detected")
338
+ - Upstream package: `<pkg>@<version>` (or "not detected")
339
+ - Claude Code CLI: <claude --version output> (or "not detected")
340
+ - Node: <node --version output> (or "not detected")
341
+ - OS: <uname -srm output> (or "not detected")
316
342
 
317
343
  ## Cross-reference
318
344
 
@@ -321,6 +347,8 @@ Reported from <downstream-repo-url>/<local-ticket-relative-path>
321
347
  This issue is tracked locally as P<NNN> in the downstream project's `docs/problems/` directory.
322
348
  ```
323
349
 
350
+ The bug-shaped fallback also includes the labelled `## Versions` section per the ADR-033 amendment 2026-05-03 (P128) — schema and "not detected" rendering rule are common to both default body shapes.
351
+
324
352
  #### Structured default body — feature-shaped (fallback-only)
325
353
 
326
354
  Use this body only when the Step 3 classifier picked `feature` shape as backward-compat fallback AND the upstream has no matching template:
@@ -1,5 +1,13 @@
1
1
  #!/usr/bin/env bats
2
2
 
3
+ # tdd-review: structural-permitted (justification: P012 skill testing
4
+ # harness scope is open; no behavioural alternative for SKILL.md prose-
5
+ # template structural assertions today. ADR-052 Migration clause permits
6
+ # structural retrofit-via-justification when the linked harness-gap ticket
7
+ # has not yet shipped the primitives. The whole-file annotation covers all
8
+ # assertions in this fixture, including the P128 `## Versions` schema
9
+ # assertions added 2026-05-03.)
10
+ #
3
11
  # Doc-lint structural test (Permitted Exception per ADR-005 — structural
4
12
  # SKILL.md content checks, not behavioural). Mirrors the doc-lint pattern
5
13
  # established in ADR-011 and ADR-027 Confirmation tests.
@@ -119,26 +127,38 @@ setup() {
119
127
  [ "$status" -eq 0 ]
120
128
  }
121
129
 
122
- @test "report-upstream: SKILL.md structured default uses problem-shaped section order (ADR-033 Step 5)" {
123
- # Problem-shaped default body per ADR-033: Description -> Symptoms ->
124
- # Workaround -> Affected plugin / component -> Frequency -> Environment
125
- # -> Evidence -> Cross-reference. Assert section order in the primary
126
- # default block.
130
+ @test "report-upstream: SKILL.md structured default uses problem-shaped section order (ADR-033 Step 5, amended 2026-05-03 P128)" {
131
+ # Problem-shaped default body per ADR-033 (amended 2026-05-03 by P128):
132
+ # Description -> Symptoms -> Workaround -> Affected plugin / component ->
133
+ # Frequency -> Versions (was Environment pre-amendment) -> Evidence ->
134
+ # Cross-reference. Assert section order in the primary default block.
135
+ #
136
+ # P140 fix-and-continue (Step 6.5 closed allow-list, P081-class stale-grep):
137
+ # iter 16's P128 amendment added a `## Versions` section to the structured
138
+ # default block (~line 293) but TWO other `## Versions` sections coexist —
139
+ # the "Drafted Upstream Report" block (~line 247) and the issue-shaped
140
+ # example block (~line 335). A bare `head -1` picks the earliest match
141
+ # (line 247) and breaks the order assertion `freq_line < versions_line`.
142
+ # Scope the `versions_line` lookup to between `freq_line` and `evidence_line`
143
+ # via awk range so we pick the structured-default block's Versions header.
144
+ # Architect note 2026-05-03: if a second section-name-collides-across-blocks
145
+ # test ever needs the same awk-range scoping, factor a
146
+ # `bats_helpers/section_in_block.bash` helper (P012 / ADR-052 amendment).
127
147
  desc_line=$(grep -n '^## Description$' "$SKILL_MD" | head -1 | cut -d: -f1)
128
148
  symptoms_line=$(grep -n '^## Symptoms$' "$SKILL_MD" | head -1 | cut -d: -f1)
129
149
  workaround_line=$(grep -n '^## Workaround$' "$SKILL_MD" | head -1 | cut -d: -f1)
130
150
  affected_line=$(grep -nE '^## Affected plugin' "$SKILL_MD" | head -1 | cut -d: -f1)
131
151
  freq_line=$(grep -n '^## Frequency$' "$SKILL_MD" | head -1 | cut -d: -f1)
132
- env_line=$(grep -n '^## Environment$' "$SKILL_MD" | head -1 | cut -d: -f1)
133
152
  evidence_line=$(grep -n '^## Evidence$' "$SKILL_MD" | head -1 | cut -d: -f1)
134
153
  xref_line=$(grep -n '^## Cross-reference$' "$SKILL_MD" | head -1 | cut -d: -f1)
154
+ versions_line=$(awk -v lo="${freq_line:-${desc_line:-1}}" -v hi="${evidence_line:-9999}" 'NR>lo && NR<hi && /^## Versions$/{print NR; exit}' "$SKILL_MD")
135
155
 
136
156
  [ -n "$desc_line" ] || { echo "missing ## Description"; return 1; }
137
157
  [ -n "$symptoms_line" ] || { echo "missing ## Symptoms"; return 1; }
138
158
  [ -n "$workaround_line" ] || { echo "missing ## Workaround"; return 1; }
139
159
  [ -n "$affected_line" ] || { echo "missing ## Affected plugin / component"; return 1; }
140
160
  [ -n "$freq_line" ] || { echo "missing ## Frequency"; return 1; }
141
- [ -n "$env_line" ] || { echo "missing ## Environment"; return 1; }
161
+ [ -n "$versions_line" ] || { echo "missing ## Versions"; return 1; }
142
162
  [ -n "$evidence_line" ] || { echo "missing ## Evidence"; return 1; }
143
163
  [ -n "$xref_line" ] || { echo "missing ## Cross-reference"; return 1; }
144
164
 
@@ -146,8 +166,8 @@ setup() {
146
166
  [ "$symptoms_line" -lt "$workaround_line" ]
147
167
  [ "$workaround_line" -lt "$affected_line" ]
148
168
  [ "$affected_line" -lt "$freq_line" ]
149
- [ "$freq_line" -lt "$env_line" ]
150
- [ "$env_line" -lt "$evidence_line" ]
169
+ [ "$freq_line" -lt "$versions_line" ]
170
+ [ "$versions_line" -lt "$evidence_line" ]
151
171
  [ "$evidence_line" -lt "$xref_line" ]
152
172
  }
153
173
 
@@ -247,3 +267,78 @@ setup() {
247
267
  run grep -iE 'dedup.*halt|step 4b.*halt|halt.*dedup|halt-and-save.*dedup' "$SKILL_MD"
248
268
  [ "$status" -eq 0 ]
249
269
  }
270
+
271
+ # ─── P128 consolidated Versions schema (ADR-033 amendment 2026-05-03) ─────────
272
+ #
273
+ # P128 reshapes Step 5's structured default body: the freeform `## Environment`
274
+ # section becomes a labelled `## Versions` section carrying a fixed five-field
275
+ # schema. Missing fields render as `not detected` (normative MUST per the
276
+ # ADR-033 amendment 2026-05-03). The reshape applies to the problem-shaped
277
+ # default AND the bug-shaped fallback default.
278
+
279
+ @test "report-upstream: SKILL.md problem-shaped default body includes ## Versions section (P128)" {
280
+ # The labelled `## Versions` section MUST appear in the SKILL.md so the
281
+ # structured default emits it. Two occurrences expected: one in the
282
+ # field-mapping table's Versions-schema block, one in the problem-shaped
283
+ # default body, and one in the bug-shaped fallback default body — but the
284
+ # minimum invariant is that the section header exists.
285
+ run grep -F '## Versions' "$SKILL_MD"
286
+ [ "$status" -eq 0 ]
287
+ }
288
+
289
+ @test "report-upstream: SKILL.md ## Versions schema lists all five fields (P128)" {
290
+ # Five-field schema per the ADR-033 amendment 2026-05-03: Local plugin,
291
+ # Upstream package, Claude Code CLI, Node, OS. All five labels must appear
292
+ # in the SKILL.md so the structured default's Versions block emits them.
293
+ run grep -iE '^- Local plugin:' "$SKILL_MD"
294
+ [ "$status" -eq 0 ]
295
+ run grep -iE '^- Upstream package:' "$SKILL_MD"
296
+ [ "$status" -eq 0 ]
297
+ run grep -iE '^- Claude Code CLI:' "$SKILL_MD"
298
+ [ "$status" -eq 0 ]
299
+ run grep -iE '^- Node:' "$SKILL_MD"
300
+ [ "$status" -eq 0 ]
301
+ run grep -iE '^- OS:' "$SKILL_MD"
302
+ [ "$status" -eq 0 ]
303
+ }
304
+
305
+ @test "report-upstream: SKILL.md documents not-detected rendering rule for missing version fields (P128)" {
306
+ # Normative rendering rule: missing fields render as "not detected".
307
+ # The literal string MUST appear in the SKILL.md so triage distinguishes
308
+ # field-not-applicable from detection-failed.
309
+ run grep -iE '"not detected"|`not detected`' "$SKILL_MD"
310
+ [ "$status" -eq 0 ]
311
+ }
312
+
313
+ @test "report-upstream: SKILL.md cites ADR-033 amendment authority for the Versions schema (P128)" {
314
+ # The Versions schema authority sits in ADR-033's `## Amendments` section
315
+ # dated 2026-05-03. The SKILL.md must cite the amendment so future readers
316
+ # see the authority inline alongside the schema.
317
+ run grep -iE 'ADR-033 amendment|amendment 2026-05-03' "$SKILL_MD"
318
+ [ "$status" -eq 0 ]
319
+ }
320
+
321
+ @test "report-upstream: SKILL.md documents auto-population sources for each Versions field (P128)" {
322
+ # Auto-population sources: package.json / claude plugin list, gh api releases
323
+ # or npm view, claude --version, node --version, uname -srm. The SKILL.md
324
+ # must enumerate the sources so the LLM-driven skill knows where to look.
325
+ run grep -F 'claude --version' "$SKILL_MD"
326
+ [ "$status" -eq 0 ]
327
+ run grep -F 'node --version' "$SKILL_MD"
328
+ [ "$status" -eq 0 ]
329
+ run grep -F 'uname -srm' "$SKILL_MD"
330
+ [ "$status" -eq 0 ]
331
+ run grep -F 'npm view' "$SKILL_MD"
332
+ [ "$status" -eq 0 ]
333
+ }
334
+
335
+ @test "report-upstream: SKILL.md problem-shaped default body no longer uses freeform ## Environment section (P128)" {
336
+ # The problem-shaped default body (lines under "#### Structured default body
337
+ # — problem-shaped (primary, per ADR-033)") MUST NOT contain a `## Environment`
338
+ # section header per the ADR-033 amendment 2026-05-03. The bug-shaped fallback
339
+ # also retired its `## Environment` section. We assert the headers are absent
340
+ # from the SKILL.md (the field-mapping table's reference to `os` field as a
341
+ # template-slot remains, but the top-level section header should be gone).
342
+ run grep -nE '^## Environment$' "$SKILL_MD"
343
+ [ "$status" -ne 0 ]
344
+ }
@@ -58,15 +58,42 @@ body:
58
58
  validations:
59
59
  required: true
60
60
 
61
- - type: textarea
62
- id: environment
61
+ - type: input
62
+ id: version-local-plugin
63
63
  attributes:
64
- label: Environment
65
- description: Version, runtime, and operating system.
66
- placeholder: |
67
- - {{project_name}} version: x.y.z
68
- - Runtime: Node 20.x / Python 3.12 / ...
69
- - OS: macOS 15.2
64
+ label: Local plugin / project version
65
+ description: The version of {{project_name}} you are running. Enter `not detected` if you cannot determine the version.
66
+ placeholder: "x.y.z"
67
+ validations:
68
+ required: true
69
+
70
+ - type: input
71
+ id: version-upstream-package
72
+ attributes:
73
+ label: Upstream package version
74
+ description: If the problem involves a non-{{project_name}} upstream package, the package name and version. Enter `not applicable` or `not detected` if neither.
75
+ placeholder: "<pkg>@<version>"
76
+
77
+ - type: input
78
+ id: version-claude-code
79
+ attributes:
80
+ label: Claude Code CLI version
81
+ description: Output of `claude --version`. Enter `not detected` if not running through Claude Code.
82
+ placeholder: "1.x.x"
83
+
84
+ - type: input
85
+ id: version-node
86
+ attributes:
87
+ label: Node version
88
+ description: Output of `node --version`. Enter `not detected` if Node is not part of the failure path.
89
+ placeholder: "v20.11.0"
90
+
91
+ - type: input
92
+ id: version-os
93
+ attributes:
94
+ label: Operating system
95
+ description: Output of `uname -srm` (POSIX) or platform-equivalent. Enter `not detected` if you cannot determine.
96
+ placeholder: "Darwin 25.3.0 arm64"
70
97
  validations:
71
98
  required: true
72
99