@windyroad/itil 1.2.0 → 2.0.0-preview.1111
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/.agents/plugins/marketplace.json +12 -0
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +42 -0
- package/README.md +34 -25
- package/agents/hang-off-check.md +34 -34
- package/bin/install.mjs +71 -5
- package/bin/wr-itil-catchup-scan +4 -4
- package/bin/wr-itil-check-deferred-placeholder-staleness +4 -4
- package/bin/wr-itil-check-fail-soft-skip-discipline +4 -4
- package/bin/wr-itil-check-fix-rfc-trace +4 -4
- package/bin/wr-itil-check-locale-discipline +4 -4
- package/bin/wr-itil-check-outbound-responses-staleness +4 -4
- package/bin/wr-itil-check-problems-readme-budget +4 -4
- package/bin/wr-itil-check-rfc-has-stories +4 -4
- package/bin/wr-itil-check-rfc-stories-ratified +4 -4
- package/bin/wr-itil-check-ticket-jtbd-ratification +4 -4
- package/bin/wr-itil-check-upstream-cache-staleness +4 -4
- package/bin/wr-itil-check-upstream-responses +4 -4
- package/bin/wr-itil-classify-readme-drift +4 -4
- package/bin/wr-itil-derive-release-vehicle +4 -4
- package/bin/wr-itil-detect-unratified-stories-maps +4 -4
- package/bin/wr-itil-effort-tally +4 -4
- package/bin/wr-itil-enumerate-postrelease-kv-candidates +4 -4
- package/bin/wr-itil-evaluate-relevance +4 -4
- package/bin/wr-itil-mark-create-gate +4 -4
- package/bin/wr-itil-mark-story-oversight-confirmed +4 -4
- package/bin/wr-itil-migrate-problems-layout +4 -4
- package/bin/wr-itil-migrate-story-status-mirror +4 -4
- package/bin/wr-itil-next-rfc-id +4 -4
- package/bin/wr-itil-plugin-exercise-index +4 -4
- package/bin/wr-itil-plugin-maturity-populate +4 -4
- package/bin/wr-itil-plugin-maturity-render +4 -4
- package/bin/wr-itil-plugin-validate-ci-gate +4 -4
- package/bin/wr-itil-reconcile-readme +4 -4
- package/bin/wr-itil-reconcile-rfcs +4 -4
- package/bin/wr-itil-reconcile-stories +4 -4
- package/bin/wr-itil-reconcile-story-maps +4 -4
- package/bin/wr-itil-render-story-map +4 -4
- package/bin/wr-itil-resolve-governance-plugin-dirs +4 -4
- package/bin/wr-itil-skill-invocations +4 -4
- package/bin/wr-itil-story-map-edit +4 -4
- package/bin/wr-itil-story-map-query +4 -4
- package/bin/wr-itil-update-jtbd-references-section +4 -4
- package/bin/wr-itil-update-problem-references-section +4 -4
- package/bin/wr-itil-update-problem-rfcs-section +4 -4
- package/bin/wr-itil-update-rfc-commits-section +4 -4
- package/bin/wr-itil-update-rfc-references-section +4 -4
- package/bin/wr-itil-verify-iter-summary +4 -4
- package/hooks/itil-assistant-output-gate.sh +3 -3
- package/hooks/itil-assistant-output-review.sh +5 -5
- package/hooks/itil-bash-polling-antipattern-detect.sh +11 -11
- package/hooks/itil-changeset-discipline.sh +24 -24
- package/hooks/itil-claude-space-protection.sh +21 -14
- package/hooks/itil-codex-dispatch.sh +164 -0
- package/hooks/itil-commit-trailer-transition-advisory.sh +11 -11
- package/hooks/itil-correction-detect.sh +8 -8
- package/hooks/itil-deferral-cadence-gate.sh +23 -23
- package/hooks/itil-fictional-defer-detect.sh +16 -16
- package/hooks/itil-fix-title-lifecycle-advisory.sh +11 -11
- package/hooks/itil-mid-loop-ask-detect.sh +14 -14
- package/hooks/itil-no-implement-draft-gate.sh +18 -18
- package/hooks/itil-pending-questions-surface.sh +11 -11
- package/hooks/itil-readme-refresh-discipline.sh +27 -27
- package/hooks/itil-rfc-oversight-nudge.sh +7 -7
- package/hooks/itil-rfc-trailer-advisory.sh +28 -28
- package/hooks/itil-runtime-sid-marker.sh +11 -11
- package/hooks/itil-story-mirror-migration-nudge.sh +7 -7
- package/hooks/lib/block-list.sh +17 -17
- package/hooks/lib/changeset-detect.sh +27 -27
- package/hooks/lib/claude-space-gate.sh +23 -15
- package/hooks/lib/command-detect.sh +12 -12
- package/hooks/lib/create-gate.sh +9 -39
- package/hooks/lib/detectors.sh +12 -12
- package/hooks/lib/readme-refresh-detect.sh +51 -51
- package/hooks/lib/runtime-sid.sh +12 -12
- package/hooks/lib/session-id.sh +28 -28
- package/hooks/lib/session-marker.sh +1 -1
- package/hooks/lib/staging-detect.sh +13 -13
- package/hooks/manage-problem-enforce-create.sh +16 -27
- package/hooks/p057-staging-trap-detect.sh +18 -18
- package/hooks/pre-publish-intake-gate.sh +5 -5
- package/hooks/staleness-check.sh +6 -6
- package/hooks-codex/hooks.json +57 -0
- package/lib/check-deferred-placeholder-staleness.sh +10 -10
- package/lib/check-outbound-responses-staleness.sh +2 -2
- package/lib/check-upstream-cache-staleness.sh +2 -2
- package/lib/derive-first-dispatch.sh +19 -19
- package/lib/enumerate-postrelease-kv-candidates.sh +18 -18
- package/lib/migrate-problems-layout.sh +12 -12
- package/lib/story-oversight.sh +27 -27
- package/package.json +16 -3
- package/scripts/catchup-scan.sh +25 -25
- package/scripts/check-fail-soft-skip-discipline.sh +10 -10
- package/scripts/check-fix-rfc-trace.sh +8 -8
- package/scripts/check-locale-discipline.sh +13 -13
- package/scripts/check-problems-readme-budget.sh +12 -12
- package/scripts/check-rfc-has-stories.sh +7 -7
- package/scripts/check-rfc-rejected-alternatives.sh +11 -11
- package/scripts/check-rfc-stories-ratified.sh +9 -9
- package/scripts/check-ticket-jtbd-ratification.sh +10 -10
- package/scripts/check-upstream-responses.sh +22 -22
- package/scripts/classify-readme-drift.sh +13 -13
- package/scripts/codex-agent.mjs +104 -0
- package/scripts/derive-release-vehicle.sh +23 -23
- package/scripts/detect-unoversighted-rfcs.sh +3 -3
- package/scripts/detect-unratified-stories-maps.sh +5 -5
- package/scripts/effort-tally.sh +10 -10
- package/scripts/evaluate-relevance.sh +16 -16
- package/scripts/mark-create-gate.sh +4 -4
- package/scripts/mark-story-oversight-confirmed.sh +14 -14
- package/scripts/migrate-story-status-mirror.sh +6 -6
- package/scripts/next-rfc-id.sh +5 -5
- package/scripts/plugin-exercise-index.sh +26 -26
- package/scripts/plugin-maturity-populate.sh +38 -38
- package/scripts/plugin-maturity-render.sh +26 -26
- package/scripts/plugin-validate-ci-gate.sh +14 -14
- package/scripts/reconcile-readme.sh +23 -23
- package/scripts/reconcile-rfcs.sh +13 -13
- package/scripts/reconcile-stories.sh +12 -12
- package/scripts/reconcile-story-maps.sh +6 -6
- package/scripts/render-story-map.mjs +24 -24
- package/scripts/render-story-map.sh +3 -3
- package/scripts/resolve-governance-plugin-dirs.sh +10 -10
- package/scripts/run-check-deferred-placeholder-staleness.sh +3 -3
- package/scripts/run-check-outbound-responses-staleness.sh +3 -3
- package/scripts/run-check-upstream-cache-staleness.sh +3 -3
- package/scripts/run-enumerate-postrelease-kv-candidates.sh +3 -3
- package/scripts/run-migrate-problems-layout.sh +3 -3
- package/scripts/skill-invocations.sh +29 -29
- package/scripts/story-map-edit.mjs +6 -6
- package/scripts/story-map-edit.sh +3 -3
- package/scripts/story-map-query.mjs +8 -8
- package/scripts/story-map-query.sh +3 -3
- package/scripts/update-jtbd-references-section.sh +8 -8
- package/scripts/update-problem-references-section.sh +12 -12
- package/scripts/update-problem-rfcs-section.sh +9 -9
- package/scripts/update-rfc-commits-section.sh +7 -7
- package/scripts/update-rfc-references-section.sh +3 -3
- package/scripts/update-story-references-section.sh +5 -5
- package/scripts/verify-iter-summary.sh +3 -3
- package/skills/capture-problem/REFERENCE.md +33 -33
- package/skills/capture-problem/SKILL.md +108 -108
- package/skills/capture-problem/agents/openai.yaml +3 -0
- package/skills/capture-rfc/SKILL.md +21 -323
- package/skills/capture-rfc/agents/openai.yaml +3 -0
- package/skills/capture-story/SKILL.md +65 -65
- package/skills/capture-story/agents/openai.yaml +3 -0
- package/skills/capture-story-map/SKILL.md +31 -31
- package/skills/capture-story-map/agents/openai.yaml +3 -0
- package/skills/check-upstream-responses/SKILL.md +38 -38
- package/skills/check-upstream-responses/agents/openai.yaml +3 -0
- package/skills/close-incident/SKILL.md +25 -25
- package/skills/close-incident/agents/openai.yaml +3 -0
- package/skills/link-incident/SKILL.md +22 -22
- package/skills/link-incident/agents/openai.yaml +3 -0
- package/skills/list-incidents/SKILL.md +9 -9
- package/skills/list-incidents/agents/openai.yaml +3 -0
- package/skills/list-problems/SKILL.md +17 -17
- package/skills/list-problems/agents/openai.yaml +3 -0
- package/skills/list-stories/SKILL.md +23 -23
- package/skills/list-stories/agents/openai.yaml +3 -0
- package/skills/list-story-maps/SKILL.md +9 -9
- package/skills/list-story-maps/agents/openai.yaml +3 -0
- package/skills/manage-incident/SKILL.md +59 -59
- package/skills/manage-incident/agents/openai.yaml +3 -0
- package/skills/manage-problem/SKILL.md +222 -222
- package/skills/manage-problem/agents/openai.yaml +3 -0
- package/skills/manage-rfc/SKILL.md +62 -62
- package/skills/manage-rfc/agents/openai.yaml +3 -0
- package/skills/manage-story/SKILL.md +49 -49
- package/skills/manage-story/agents/openai.yaml +3 -0
- package/skills/manage-story-map/SKILL.md +30 -30
- package/skills/manage-story-map/agents/openai.yaml +3 -0
- package/skills/mitigate-incident/SKILL.md +40 -40
- package/skills/mitigate-incident/agents/openai.yaml +3 -0
- package/skills/reconcile-readme/SKILL.md +28 -28
- package/skills/reconcile-readme/agents/openai.yaml +3 -0
- package/skills/reconcile-stories/SKILL.md +17 -17
- package/skills/reconcile-stories/agents/openai.yaml +3 -0
- package/skills/reconcile-story-maps/SKILL.md +11 -11
- package/skills/reconcile-story-maps/agents/openai.yaml +3 -0
- package/skills/report-upstream/SKILL.md +73 -73
- package/skills/report-upstream/agents/openai.yaml +3 -0
- package/skills/restore-incident/SKILL.md +28 -28
- package/skills/restore-incident/agents/openai.yaml +3 -0
- package/skills/review-problems/SKILL.md +129 -129
- package/skills/review-problems/agents/openai.yaml +3 -0
- package/skills/scaffold-intake/SKILL.md +26 -26
- package/skills/scaffold-intake/agents/openai.yaml +3 -0
- package/skills/transition-problem/SKILL.md +85 -85
- package/skills/transition-problem/agents/openai.yaml +3 -0
- package/skills/transition-problems/SKILL.md +69 -69
- package/skills/transition-problems/agents/openai.yaml +3 -0
- package/skills/update-upstream/SKILL.md +97 -97
- package/skills/update-upstream/agents/openai.yaml +3 -0
- package/skills/work-problem/SKILL.md +42 -42
- package/skills/work-problem/agents/openai.yaml +3 -0
- package/skills/work-problems/SKILL.md +327 -327
- package/skills/work-problems/agents/openai.yaml +3 -0
- package/skills-codex/capture-problem/REFERENCE.md +139 -0
- package/skills-codex/capture-problem/SKILL.md +438 -0
- package/skills-codex/capture-problem/agents/openai.yaml +3 -0
- package/skills-codex/capture-rfc/SKILL.md +45 -0
- package/skills-codex/capture-rfc/agents/openai.yaml +3 -0
- package/skills-codex/capture-story/SKILL.md +407 -0
- package/skills-codex/capture-story/agents/openai.yaml +3 -0
- package/skills-codex/capture-story-map/SKILL.md +286 -0
- package/skills-codex/capture-story-map/agents/openai.yaml +3 -0
- package/skills-codex/check-upstream-responses/SKILL.md +160 -0
- package/skills-codex/check-upstream-responses/agents/openai.yaml +3 -0
- package/skills-codex/close-incident/SKILL.md +192 -0
- package/skills-codex/close-incident/agents/openai.yaml +3 -0
- package/skills-codex/link-incident/SKILL.md +173 -0
- package/skills-codex/link-incident/agents/openai.yaml +3 -0
- package/skills-codex/list-incidents/SKILL.md +92 -0
- package/skills-codex/list-incidents/agents/openai.yaml +3 -0
- package/skills-codex/list-problems/SKILL.md +126 -0
- package/skills-codex/list-problems/agents/openai.yaml +3 -0
- package/skills-codex/list-stories/SKILL.md +170 -0
- package/skills-codex/list-stories/agents/openai.yaml +3 -0
- package/skills-codex/list-story-maps/SKILL.md +104 -0
- package/skills-codex/list-story-maps/agents/openai.yaml +3 -0
- package/skills-codex/manage-incident/SKILL.md +378 -0
- package/skills-codex/manage-incident/agents/openai.yaml +3 -0
- package/skills-codex/manage-problem/SKILL.md +1180 -0
- package/skills-codex/manage-problem/agents/openai.yaml +3 -0
- package/skills-codex/manage-rfc/SKILL.md +314 -0
- package/skills-codex/manage-rfc/agents/openai.yaml +3 -0
- package/skills-codex/manage-story/SKILL.md +284 -0
- package/skills-codex/manage-story/agents/openai.yaml +3 -0
- package/skills-codex/manage-story-map/SKILL.md +198 -0
- package/skills-codex/manage-story-map/agents/openai.yaml +3 -0
- package/skills-codex/mitigate-incident/SKILL.md +239 -0
- package/skills-codex/mitigate-incident/agents/openai.yaml +3 -0
- package/skills-codex/reconcile-readme/SKILL.md +175 -0
- package/skills-codex/reconcile-readme/agents/openai.yaml +3 -0
- package/skills-codex/reconcile-stories/SKILL.md +124 -0
- package/skills-codex/reconcile-stories/agents/openai.yaml +3 -0
- package/skills-codex/reconcile-story-maps/SKILL.md +81 -0
- package/skills-codex/reconcile-story-maps/agents/openai.yaml +3 -0
- package/skills-codex/report-upstream/SKILL.md +716 -0
- package/skills-codex/report-upstream/agents/openai.yaml +3 -0
- package/skills-codex/restore-incident/SKILL.md +216 -0
- package/skills-codex/restore-incident/agents/openai.yaml +3 -0
- package/skills-codex/review-problems/SKILL.md +524 -0
- package/skills-codex/review-problems/agents/openai.yaml +3 -0
- package/skills-codex/scaffold-intake/SKILL.md +209 -0
- package/skills-codex/scaffold-intake/agents/openai.yaml +3 -0
- package/skills-codex/scaffold-intake/templates/CONTRIBUTING.md.tmpl +31 -0
- package/skills-codex/scaffold-intake/templates/SECURITY.md.tmpl +39 -0
- package/skills-codex/scaffold-intake/templates/SUPPORT.md.tmpl +32 -0
- package/skills-codex/scaffold-intake/templates/config.yml.tmpl +8 -0
- package/skills-codex/scaffold-intake/templates/problem-report.yml.tmpl +114 -0
- package/skills-codex/transition-problem/SKILL.md +371 -0
- package/skills-codex/transition-problem/agents/openai.yaml +3 -0
- package/skills-codex/transition-problems/SKILL.md +310 -0
- package/skills-codex/transition-problems/agents/openai.yaml +3 -0
- package/skills-codex/update-upstream/SKILL.md +583 -0
- package/skills-codex/update-upstream/agents/openai.yaml +3 -0
- package/skills-codex/work-problem/SKILL.md +160 -0
- package/skills-codex/work-problem/agents/openai.yaml +3 -0
- package/skills-codex/work-problems/SKILL.md +58 -0
- package/skills-codex/work-problems/agents/openai.yaml +3 -0
- package/templates/story-map.css +1 -1
- package/bin/wr-itil-mark-rfc-capture-gate +0 -51
- package/scripts/mark-rfc-capture-gate.sh +0 -32
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wr-itil:capture-story-map
|
|
3
|
+
description: Lightweight story-map-capture skill for aside-invocation during foreground work — mandatory leading problem-trace AND JTBD-trace per the "Problem-RFC-Story framework with mandatory problem-trace and unified problem ontology" architecture rule I3 + I4 invariants, skeleton HTML file at `docs/story-maps/draft/STORY-MAP-NNN-<slug>.html` per the "Problem-RFC-Story framework with mandatory problem-trace and unified problem ontology" architecture rule § Phase 2 encoding amendment 2026-05-12, single commit per capture, no inline README refresh. Defers full backbone/ribs/slices authoring + lifecycle transitions to /wr-itil:manage-story-map. Use when the user (or agent) wants to capture a new story-map quickly with clear problem + JTBD anchoring.
|
|
4
|
+
allowed-tools: Read, Write, Edit, Bash, Grep, Glob
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
<!-- Generated from the runtime-neutral skill source. Do not edit. -->
|
|
8
|
+
|
|
9
|
+
> Codex runtime note: use `request_user_input` only where this contract
|
|
10
|
+
> explicitly requires a human decision. Resolve `<itil-plugin-root>` from
|
|
11
|
+
> this installed `SKILL.md`: it is two directories above the skill
|
|
12
|
+
> directory. Run bundled commands from `<itil-plugin-root>/bin/`; do not
|
|
13
|
+
> search the adopter repository or rely on those commands being on `PATH`.
|
|
14
|
+
> Spawn `wr-itil:hang-off-check` with the native Codex subagent tool, wait
|
|
15
|
+
> for it, and close that same agent.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# Capture Story Map Skill
|
|
19
|
+
|
|
20
|
+
Capture a story-map (HTML artefact representing Patton's backbone × ribs × slices layout) quickly during foreground work. Lightweight aside-invocation surface that complements the heavyweight `/wr-itil:manage-story-map` flow. Mirrors `/wr-itil:capture-story` shape per the "Governance skill invocation patterns — foreground + background with deferred-question resumption" architecture rule lightweight + heavyweight skill split, applied at the story-map tier with HTML encoding.
|
|
21
|
+
|
|
22
|
+
**Related JTBDs**: the ": Decompose a Fix Into Coordinated Changes" user outcome (primary — Decompose a Fix Into Coordinated Changes; story-maps represent the journey-context decomposition), the ": Enforce Governance Without Slowing Down" user outcome (extended scope), the "Trust That the README Describes the Plugin I Just Installed" user outcome (README-currency rule for `docs/story-maps/README.md`).
|
|
23
|
+
|
|
24
|
+
## When to invoke
|
|
25
|
+
|
|
26
|
+
- **Decomposing a problem or RFC into a journey-shaped layout** — agent / user observes that the fix decomposes into multiple coordinated changes that map onto a user-journey backbone × ribs × slices spatial layout (per Patton's User Story Mapping). Capture the story-map BEFORE individual stories so the spatial-placement context informs story decomposition.
|
|
27
|
+
- **Retrospective story-map for shipped work** — lifting an existing multi-commit decomposition into a story-map artefact (e.g. the "RFC framework bootstrap journey map" journey map retro on the "Problem tickets strain as fixes decompose into multiple coordinated changes — need an RFC framework that ties all changes back to problems (and unifies technical with user/business problems)" problem Phase 1 + Phase 2 framework code — Slice 14 of the "Problem tickets strain as fixes decompose into multiple coordinated changes — need an RFC framework that ties all changes back to problems (and unifies technical with user/business problems)" problem Phase 2).
|
|
28
|
+
- **Cross-RFC journey lens** — a single story-map can reference stories from multiple RFCs (the map is a journey-context lens on the story corpus per the "Problem-RFC-Story framework with mandatory problem-trace and unified problem ontology" architecture rule line 317).
|
|
29
|
+
|
|
30
|
+
**Use `/wr-itil:manage-story-map` instead** when:
|
|
31
|
+
- The work is moving an existing story-map through its lifecycle (draft → accepted → in-progress → completed → archived).
|
|
32
|
+
- The user wants to author or refine the backbone/ribs/slices structure with full intake.
|
|
33
|
+
- Cross-map coordination decisions need to be captured.
|
|
34
|
+
|
|
35
|
+
## Argument grammar
|
|
36
|
+
|
|
37
|
+
**Positional (both mandatory)**: `<problem-trace> <jtbd-trace> <description>` where:
|
|
38
|
+
- `<problem-trace>` is `P<NNN>` or `P<NNN>,P<NNN>,...`
|
|
39
|
+
- `<jtbd-trace>` is `JTBD-<NNN>` or `JTBD-<NNN>,JTBD-<NNN>,...`
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
/wr-itil:capture-story-map the "Problem tickets strain as fixes decompose into multiple coordinated changes — need an RFC framework that ties all changes back to problems (and unifies technical with user/business problems)" problem the ": Decompose a Fix Into Coordinated Changes" user outcome RFC framework Phase 1 + Phase 2 bootstrap
|
|
43
|
+
/wr-itil:capture-story-map the "Problem tickets strain as fixes decompose into multiple coordinated changes — need an RFC framework that ties all changes back to problems (and unifies technical with user/business problems)" problem the ": Decompose a Fix Into Coordinated Changes" user outcome,the ": Enforce Governance Without Slowing Down" user outcome Story map for the "Problem tickets strain as fixes decompose into multiple coordinated changes — need an RFC framework that ties all changes back to problems (and unifies technical with user/business problems)" problem RFC framework work
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Positional grammar mirrors `/wr-itil:capture-story` shape (footnote per the "Problem-RFC-Story framework with mandatory problem-trace and unified problem ontology" architecture rule line 285 phrasing — `--problem` / `--jtbd` flag-form was the ADR-exemplar but positional is the lightweight-aside grammar that Codex skills support natively).
|
|
47
|
+
|
|
48
|
+
## Rule 6 audit (per the "Governance skill invocation patterns — foreground + background with deferred-question resumption" architecture rule + the "Structured User Interaction for Governance-Skill Decisions" architecture rule + the "Problem-RFC-Story framework with mandatory problem-trace and unified problem ontology" architecture rule)
|
|
49
|
+
|
|
50
|
+
| Decision | Resolution | Authority class |
|
|
51
|
+
|----------|-----------|-----------------|
|
|
52
|
+
| Problem-trace presence | I3 hard-block — refuse on missing trace; emit deny log + halt | direction-setting |
|
|
53
|
+
| Problem-trace validation | Mechanical: each `P<NNN>` exists in `docs/problems/`; dual-tolerant lookup | silent-mechanical |
|
|
54
|
+
| JTBD-trace presence | I4 hard-block — refuse on missing trace; emit deny log + halt | direction-setting |
|
|
55
|
+
| JTBD-trace validation | Mechanical: each `JTBD-<NNN>` resolves to a file in `docs/jtbd/` | silent-mechanical |
|
|
56
|
+
| STORY-MAP ID allocation | Mechanical: `max(local, origin, history) + 1` enumerating `docs/story-maps/*/STORY-MAP-*.html` (the "AFK orchestrator preflight: get the repo into a clean state before starting" architecture rule inline collision-guard) | silent-mechanical |
|
|
57
|
+
| Title kebab-slug | Mechanical: first 8-10 non-stopword tokens of description | silent-mechanical |
|
|
58
|
+
| Title prose refinement | Optional taste request_user_input; silent-default to derived form | taste |
|
|
59
|
+
| HTML file write | Mechanical: schema per the "Problem-RFC-Story framework with mandatory problem-trace and unified problem ontology" architecture rule § Phase 2 encoding amendment 2026-05-12 lines 381-435 | silent-mechanical |
|
|
60
|
+
| Reverse-trace `## Story Maps` refresh | Mechanical: inline on driving problem + JTBD files via Slice 2a/2b helpers | silent-mechanical |
|
|
61
|
+
| README refresh | Mechanical: deferred to `/wr-itil:manage-story-map review` or `<itil-plugin-root>/bin/wr-itil-reconcile-story-maps` | silent-mechanical |
|
|
62
|
+
| Empty arguments | Halt-with-stderr-directive | n/a |
|
|
63
|
+
|
|
64
|
+
## Steps
|
|
65
|
+
|
|
66
|
+
### 0. Preflight
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
<itil-plugin-root>/bin/wr-itil-reconcile-readme docs/problems > /tmp/wr-itil-drift-$$.txt
|
|
70
|
+
reconcile_exit=$?
|
|
71
|
+
# Halt-and-route on drift per the standard pattern.
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 1. Parse arguments
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
problem_trace="$1"; shift
|
|
78
|
+
jtbd_trace="$1"; shift
|
|
79
|
+
description="$*"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Validate `$problem_trace` matches `^P[0-9]{3}(,P[0-9]{3})*$`. Validate `$jtbd_trace` matches `^JTBD-[0-9]{3}(,JTBD-[0-9]{3})*$`. If `$description` is empty, halt with empty-arguments directive.
|
|
83
|
+
|
|
84
|
+
Derive kebab-case title slug from first 8-10 non-stopword tokens of `$description`.
|
|
85
|
+
|
|
86
|
+
### 2. Validate problem trace + I3 hard-block
|
|
87
|
+
|
|
88
|
+
For each `P<NNN>`:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
# Dual-tolerant ticket discovery (the ": docs/problems/ flat layout migration — per-state subdirs + adopter auto-migration" release design migration window).
|
|
92
|
+
trace_files=$(ls docs/problems/<NNN>-*.md docs/problems/*/<NNN>-*.md 2>/dev/null)
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**I3 hard-block** (the "Problem-RFC-Story framework with mandatory problem-trace and unified problem ontology" architecture rule, the story-map schema's `problems:` field): trace absent / malformed / unresolved → emit deny log entry to `logs/story-map-capture-denials.jsonl`, halt with stderr directive naming `/wr-itil:capture-problem` as the open-the-driving-problem-first surface.
|
|
96
|
+
|
|
97
|
+
### 2.5. Validate JTBD trace + I4 hard-block
|
|
98
|
+
|
|
99
|
+
For each `JTBD-<NNN>`:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
jtbd_file=$(ls docs/jtbd/*/JTBD-<NNN>-*.md 2>/dev/null | head -1)
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**I4 hard-block** (the "Problem-RFC-Story framework with mandatory problem-trace and unified problem ontology" architecture rule, the story-map schema's `jtbd:` field): trace absent / malformed / unresolved → emit deny log + halt. Story-maps without JTBD trace are structurally meaningless per the "Problem-RFC-Story framework with mandatory problem-trace and unified problem ontology" architecture rule ("a map with no JTBD trace is structurally meaningless"; Patton's central thesis is journey-around-user-value).
|
|
106
|
+
|
|
107
|
+
### 3. Compute next STORY-MAP ID
|
|
108
|
+
|
|
109
|
+
Inline `max(local, origin, history) + 1` per the "AFK orchestrator preflight: get the repo into a clean state before starting" architecture rule collision-guard (architect Slice 3 design review option a — inline-only path, mirrors capture-rfc + capture-story precedent). Git history keeps deleted IDs retired without adding tombstone files:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
local_max=$(ls docs/story-maps/*/STORY-MAP-*.html 2>/dev/null | sed 's|.*/STORY-MAP-||;s|-.*||' | grep -oE '^[0-9]+' | sort -n | tail -1)
|
|
113
|
+
origin_max=$(git ls-tree -r --name-only origin/main docs/story-maps/ 2>/dev/null | sed 's|.*/STORY-MAP-||;s|-.*||' | grep -oE '^[0-9]+' | sort -n | tail -1)
|
|
114
|
+
history_max=$(git log --all --name-only --format= -- docs/story-maps/ 2>/dev/null | sed 's|.*/STORY-MAP-||;s|-.*||' | grep -oE '^[0-9]+' | sort -n | tail -1)
|
|
115
|
+
next=$(printf '%03d' $(( 10#$(printf '%s\n' "${local_max:-0}" "${origin_max:-0}" "${history_max:-0}" | sort -n | tail -1) + 1 )))
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### 4. Optional taste prompt for title
|
|
119
|
+
|
|
120
|
+
Same shape as capture-story Step 4 — silent-default when unavailable.
|
|
121
|
+
|
|
122
|
+
### 5. Write the story-map JSON, then render it
|
|
123
|
+
|
|
124
|
+
**NEVER hand-write the HTML, and NEVER open an existing map to copy its shape.** Both maps and template drifted together once already: every map in the corpus became a vertical stack of headings — no journey columns, no release rows, no cells — because each new map was cloned from the last. The renderer owns the shape so that cannot recur.
|
|
125
|
+
|
|
126
|
+
**A map is ONE file**: `docs/story-maps/draft/STORY-MAP-<NNN>-<kebab-title>.html`. Its data lives inside it, in a `<script id="story-map-data" type="application/json">` island. The renderer rewrites the presentation around that island. There is no separate source file to fall out of step with the rendered map, and the file a reader opens is the file an author edits.
|
|
127
|
+
|
|
128
|
+
**There is one command and one mode.** To CREATE a map, write a file containing nothing but the data island, then render it — the renderer fills in everything around it:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
# Write docs/story-maps/draft/STORY-MAP-<NNN>-<kebab-title>.html containing only:
|
|
132
|
+
# <script id="story-map-data" type="application/json">
|
|
133
|
+
# { ...the map data... }
|
|
134
|
+
# </script>
|
|
135
|
+
<itil-plugin-root>/bin/wr-itil-render-story-map docs/story-maps/draft/STORY-MAP-<NNN>-<kebab-title>.html
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
**To CHANGE a map**, edit the data island in that same file and run the same command again. Creation and editing are the same operation, so there is no seed file to clean up and no bootstrap mode. Re-rendering is idempotent. Never edit the grid, the `<style>` block, or the `<meta>` block by hand — they are regenerated from the island, and a hand-edit outside it is discarded on the next render.
|
|
139
|
+
|
|
140
|
+
**What a story map is.** A grid, not a list. Backbone activities are COLUMNS across the top and form the user's journey left to right. Release slices are ROWS. Task cards sit in the cells. A row read left to right is everything that ships together — that is the whole point of the artefact, and it is what a vertical stack cannot express.
|
|
141
|
+
|
|
142
|
+
**JSON shape:**
|
|
143
|
+
|
|
144
|
+
Extracted verbatim by `test/documented-island-renders.bats` — editing which keys
|
|
145
|
+
appear here changes what that test asserts, and that binding is deliberate.
|
|
146
|
+
|
|
147
|
+
<!-- documented-island:begin -->
|
|
148
|
+
```json
|
|
149
|
+
{
|
|
150
|
+
"storyMapId": "STORY-MAP-<NNN>",
|
|
151
|
+
"title": "<Title>",
|
|
152
|
+
"status": "draft",
|
|
153
|
+
"persona": "<persona>",
|
|
154
|
+
"reported": "<YYYY-MM-DD>",
|
|
155
|
+
"decisionMakers": "<git config user.name>",
|
|
156
|
+
"traces": { "jtbd": ["JTBD-<NNN>"] },
|
|
157
|
+
"backbone": [
|
|
158
|
+
{ "id": "<slug>", "title": "A. <Activity>", "note": "<optional JTBD or gloss>" }
|
|
159
|
+
],
|
|
160
|
+
"releases": [
|
|
161
|
+
{ "id": "rfc-<nnn>", "name": "<what this release delivers>", "rfc": "RFC-<NNN>", "note": "<optional>" }
|
|
162
|
+
],
|
|
163
|
+
"tasks": [
|
|
164
|
+
{
|
|
165
|
+
"activity": "<backbone id>", "release": "<release id>",
|
|
166
|
+
"title": "<what the persona can do>",
|
|
167
|
+
"storyId": "STORY-<NNN>", "rfc": "RFC-<NNN>", "jtbd": "JTBD-<NNN>",
|
|
168
|
+
"ref": "STORY-<NNN>, P<NNN>"
|
|
169
|
+
}
|
|
170
|
+
]
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
<!-- documented-island:end -->
|
|
174
|
+
|
|
175
|
+
**Authoring rules:**
|
|
176
|
+
|
|
177
|
+
- **The backbone must be a journey, not a list of invariants.** Activities are steps the persona walks through in sequence. "Finish a change → get it assessed → push it → get through CI → release it" is a backbone. "Leave no unscored way out", "score this change not the last one" are invariants, and a column of them is not a map.
|
|
178
|
+
- At capture a map may legitimately have **columns and rows but empty cells**. That is the honest state of unbuilt work, and the renderer says so in place — a wholly empty band carries its own sentence. Do not add prose at the top explaining it.
|
|
179
|
+
- **Composing a row asks two questions, in order.** A row is a release, so putting two stories in one is a claim that they ship together. Answer both before drawing it.
|
|
180
|
+
|
|
181
|
+
**1. Do they NEED to ship together?** Coupling. Is either broken, meaningless or misleading on its own? A migration and the code that depends on it need one row. Two fixes that merely arrived in the same conversation do not. *Absence of a dependency is not a reason to bundle* — it is the reason not to.
|
|
182
|
+
|
|
183
|
+
**2. SHOULD they ship together?** Economics, and this is the question that gets skipped. Batching imposes the delay of the slowest story on everything in the batch. It buys something back only when each release costs a lot to perform — so weigh the holding cost against the per-release transaction cost:
|
|
184
|
+
|
|
185
|
+
- **Producer-side cost is usually near zero here**: release is automated on merge, and this repo has shipped three times in a day. When transaction cost approaches zero the optimal batch approaches one, and bundling is pure loss.
|
|
186
|
+
- **Adopter-side cost is not zero.** Every release asks an adopter to upgrade, and upgrading has known friction. That is the real argument for a larger batch.
|
|
187
|
+
- **Watch for the story that REDUCES that cost.** It ships first and alone. Queueing your transaction-cost reducer behind other work is the expensive mistake, because it makes every later release cheaper — attack the cost, then the batch size falls out.
|
|
188
|
+
- **Cost of delay is per persona, not per story.** A gate blocking most adopters today outweighs an intermittent failure that bites across an upgrade. Name who waits, and what waiting costs each of them, before deciding the row.
|
|
189
|
+
- **Check the package boundary.** Stories in packages that version independently cannot share a release the tooling will actually produce; a row spanning them claims something no changeset emits.
|
|
190
|
+
|
|
191
|
+
The default is one story per row. Two stories share a row when the answer to question 1 is yes, or when question 2 shows a transaction cost high enough to pay for the delay. Neither is assumed.
|
|
192
|
+
|
|
193
|
+
- **A row IS an RFC (the "A release row is the RFC, and the map is the approval surface" architecture rule).** A row a problem has proposed carries its `rfc`; drawing the row is what allocates the identity. There is no separate "not yet allocated" state and no `badge` field — a row's status is derived from its stories, and its label is its RFC id.
|
|
194
|
+
- **Every row carries an identity, and finishing one earns no exemption (the "A story map's RFC list is derived from its release rows" architecture rule).** A row with no `rfc` renders as a defect — a red "Untraced" badge — whether or not its stories are done. Delivery cannot excuse a missing identity, because every row is delivered eventually; that reading would let work nobody proposed become legitimate by being finished.
|
|
195
|
+
|
|
196
|
+
The only exception is a row holding work that shipped **before rows carried identities**, and such a row says so explicitly with `"preRfc": true`. That set is closed. Do not add the marker to a new row: it is a statement about history, not a way to skip allocating an RFC. It appears in no example above because a row that has an `rfc` does not need it, and the example shows the normal case.
|
|
197
|
+
- **A map carries no `traces.rfcs` (the "A story map's RFC list is derived from its release rows" architecture rule).** The map's RFC list is the union of its row identities, so authoring it restates the rows and drifts from them the moment one changes.
|
|
198
|
+
- `storyId` / `rfc` / `jtbd` are optional per task and emit the `data-*` reference layer that reverse-trace and the story-map queries consume. Omit them until stories exist; add them as stories are captured onto the map.
|
|
199
|
+
- **Author nothing a story file already says (the "A story map card stores no value a story file already carries" architecture rule).** A story's lifecycle state, its value statement, and the problems it closes are all read from the story when the map renders — so a transition needs no map edit and does not re-open the map's ratification. There are no `storyStatus`, `value` or row-level `problems` fields, and no `--status` or `--value` flags. A row's problems are the union of its stories'; a map's are the union of its rows'.
|
|
200
|
+
- **A map carries no decision trace (the "A story map carries no decision trace" architecture rule).** There is no `traces.adrs`. A decision constrains how something is built, and the thing built is the story — so a decision reference belongs on the story (`adrs:` in its frontmatter), not on the lens drawn over it.
|
|
201
|
+
- **Write no prose the grid already carries.** There is no `lead` and no `traceProse`. A map is a title, a grid, and the jobs it is drawn for. Where a column or a row needs a note, both carry a `note` field — put it next to the thing it describes, not in a paragraph at the top restating the picture below it. Six kinds of duplication were removed from this format for exactly this reason; the seventh will be whatever gets added back.
|
|
202
|
+
- **Prefer the edit command over hand-editing the island** for structural changes — it validates against the map's own backbone and bands, names what is available when you get an id wrong, and leaves the file untouched on failure:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
<itil-plugin-root>/bin/wr-itil-story-map-edit <map.html> add-card --story STORY-<NNN> --activity <id> --release <id> --title "..." [--ref "..."]
|
|
206
|
+
<itil-plugin-root>/bin/wr-itil-story-map-edit <map.html> move-card --story STORY-<NNN> [--activity <id>] [--release <id>]
|
|
207
|
+
<itil-plugin-root>/bin/wr-itil-story-map-edit <map.html> remove-card --story STORY-<NNN>
|
|
208
|
+
<itil-plugin-root>/bin/wr-itil-story-map-edit <map.html> add-band --id <id> --name "..." [--rfc RFC-<NNN>] [--note "..."]
|
|
209
|
+
<itil-plugin-root>/bin/wr-itil-story-map-edit <map.html> add-activity --id <id> --title "..." [--note "..."]
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Hand-editing the island still works — the renderer reads whatever is there — but the command is the safer path and the one to reach for by default.
|
|
213
|
+
- Every task needs `activity` and `release` matching an `id` in `backbone` / `releases`, or it renders nowhere.
|
|
214
|
+
- Presentation is not yours to set. There is no CSS in the JSON and no inline `style` anywhere; the template is the only styling source.
|
|
215
|
+
- Escape a literal `<` in any string as `\\u003c`. A raw `</script>` inside the island terminates the block early — in the renderer and in a browser — and the renderer will refuse the file rather than emit a truncated map.
|
|
216
|
+
|
|
217
|
+
**Born unconfirmed (the "Story maps and stories carry a drift-invalidated human-oversight marker" architecture rule).** Do NOT author `humanOversight` at all: the renderer treats an absent field as `unconfirmed`, so writing it is writing the default, and the field exists so that `<itil-plugin-root>/bin/wr-itil-mark-story-oversight-confirmed` can set `confirmed` — which an agent must never hand-write (the "iter subprocesses set `human-oversight: confirmed` marker on ADRs / personas / JTBDs without an actual user-confirmation event" problem). The `<meta name="human-oversight">` tag is a projection the renderer regenerates from the island; never author it directly (the "Story maps render from JSON through a canonical template" architecture rule). The map is NOT ratified until a human confirms it via `/wr-itil:manage-story-map <NNN> ratify`, which writes `confirmed` + an `oversight-hash` fingerprint through `<itil-plugin-root>/bin/wr-itil-mark-story-oversight-confirmed`. Until then `<itil-plugin-root>/bin/wr-itil-detect-unratified-stories-maps` surfaces it and an RFC may not reference its stories (`<itil-plugin-root>/bin/wr-itil-check-rfc-stories-ratified`).
|
|
218
|
+
|
|
219
|
+
**What re-opens ratification, and what does not (the "A release row is the RFC, and the map is the approval surface" architecture rule).** A later edit to the map's SUBSTANCE — the map's own substance as the "Story maps and stories carry a drift-invalidated human-oversight marker" architecture rule defines it — its journey, its identity, and what it traces to; `oversight_map_substance_keys()` is the field list — drifts the fingerprint and silently re-opens ratification. Release rows and the cards in them sit OUTSIDE the basis, so drawing a row or adding a story to one changes nothing. Presentation is outside it too: restyling the shared template cannot revoke an approval. Do NOT hand-write `confirmed` — born-unconfirmed is the load-bearing default.
|
|
220
|
+
|
|
221
|
+
### 6. Single commit — `## Story Maps` reverse-trace refresh
|
|
222
|
+
|
|
223
|
+
**Stage list**: the map `.html` (it carries its own data island) AND, on a repository's first map, the shared `docs/story-maps/story-map.css` the renderer places beside them, PLUS driving problem files (refresh `## Story Maps` section via `update-problem-references-section.sh <file> "Story Maps"`) PLUS driving JTBD files (refresh `## Story Maps` section via `update-jtbd-references-section.sh <file> "Story Maps"`). Do NOT stage `docs/story-maps/README.md` (deferred).
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
for pid_token in $(echo "$problem_trace" | tr ',' ' '); do
|
|
227
|
+
pid_num="${pid_token#P}"
|
|
228
|
+
problem_file=$(ls docs/problems/${pid_num}-*.md docs/problems/*/${pid_num}-*.md 2>/dev/null | head -1)
|
|
229
|
+
[ -z "$problem_file" ] && continue
|
|
230
|
+
<itil-plugin-root>/bin/wr-itil-update-problem-references-section "$problem_file" "Story Maps"
|
|
231
|
+
git add "$problem_file"
|
|
232
|
+
done
|
|
233
|
+
|
|
234
|
+
for jid_token in $(echo "$jtbd_trace" | tr ',' ' '); do
|
|
235
|
+
jtbd_file=$(ls docs/jtbd/*/${jid_token}-*.md 2>/dev/null | head -1)
|
|
236
|
+
[ -z "$jtbd_file" ] && continue
|
|
237
|
+
<itil-plugin-root>/bin/wr-itil-update-jtbd-references-section "$jtbd_file" "Story Maps"
|
|
238
|
+
git add "$jtbd_file"
|
|
239
|
+
done
|
|
240
|
+
|
|
241
|
+
git add docs/story-maps/draft/STORY-MAP-<NNN>-<slug>.html
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Commit message:
|
|
245
|
+
|
|
246
|
+
```
|
|
247
|
+
feat(itil): capture STORY-MAP-<NNN> <title>
|
|
248
|
+
|
|
249
|
+
Refs: STORY-MAP-<NNN>
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
### 7. Report
|
|
253
|
+
|
|
254
|
+
After commit, report:
|
|
255
|
+
- New story-map file path + ID.
|
|
256
|
+
- Traced problems + JTBDs.
|
|
257
|
+
- Trailing pointer: `Run /wr-itil:manage-story-map <STORY-MAP-<NNN>> next to author backbone/ribs/slices structure and advance draft → accepted; refresh docs/story-maps/README.md.`
|
|
258
|
+
|
|
259
|
+
## Composition with manage-story-map
|
|
260
|
+
|
|
261
|
+
| Concern | manage-story-map | capture-story-map |
|
|
262
|
+
|---------|------------------|-------------------|
|
|
263
|
+
| I3 + I4 enforcement | Re-validated at every lifecycle transition | Hard-block at capture-time |
|
|
264
|
+
| I5 no-WSJF-leak | Behavioural test asserts no WSJF field at every transition | Already absent at capture (frontmatter has no WSJF) |
|
|
265
|
+
| Backbone/ribs/slices authoring | Step 7-9 author the spatial layout | Deferred-placeholder pattern; one rib placeholder only |
|
|
266
|
+
| Status transitions | draft → accepted → in-progress → completed → archived | Out of scope (creation only) |
|
|
267
|
+
| README refresh | Inline per transition | Deferred to `/wr-itil:manage-story-map review` or `<itil-plugin-root>/bin/wr-itil-reconcile-story-maps` |
|
|
268
|
+
| Commit grain | One commit per intake / per transition | One commit per capture |
|
|
269
|
+
|
|
270
|
+
## Related
|
|
271
|
+
|
|
272
|
+
- **the "Problem-RFC-Story framework with mandatory problem-trace and unified problem ontology" architecture rule** — Problem-RFC-Story framework + Phase 2 amendment 2026-05-10 + encoding amendment 2026-05-12.
|
|
273
|
+
- **the "Problem-RFC-Story framework with mandatory problem-trace and unified problem ontology" architecture rule lines 145-189** — story-map tier spec + I3-I5 invariants.
|
|
274
|
+
- **the "Problem-RFC-Story framework with mandatory problem-trace and unified problem ontology" architecture rule lines 381-435** — HTML encoding schema (the source-of-truth for the file template).
|
|
275
|
+
- **`docs/STYLE-GUIDE.md`** — story-map HTML style rules (prohibited inline `style=""` on data-bearing elements).
|
|
276
|
+
- **`docs/VOICE-AND-TONE.md`** — story-map prose guidance (HTML content section).
|
|
277
|
+
- **`docs/story-maps/README.md`** — story-map tier lifecycle index + schema spec.
|
|
278
|
+
- **the "Problem tickets strain as fixes decompose into multiple coordinated changes — need an RFC framework that ties all changes back to problems (and unifies technical with user/business problems)" problem** — driver problem ticket.
|
|
279
|
+
- **the ": Decompose a Fix Into Coordinated Changes" user outcome** — Decompose a Fix Into Coordinated Changes. Primary persona-anchor.
|
|
280
|
+
- **the "Trust That the README Describes the Plugin I Just Installed" user outcome** — Trust That the README Describes the Plugin I Just Installed (README-currency rule for `docs/story-maps/README.md`).
|
|
281
|
+
- **the "Governance skill invocation patterns — foreground + background with deferred-question resumption" architecture rule** — governance-skill aside-invocation pattern.
|
|
282
|
+
- **the "Plugin-bundled scripts invoked from SKILL.md resolve via `bin/` on `$PATH`" architecture rule** — bin/ on PATH; `<itil-plugin-root>/bin/wr-itil-reconcile-story-maps` shim ships in Slice 5.
|
|
283
|
+
- **the "Behavioural-tests-default for skill testing" architecture rule** — behavioural-tests default. Bats at `<itil-plugin-root>/skills/capture-story-map/test/capture-story-map-behavioural.bats`.
|
|
284
|
+
- **Capture-story precedent** — `<itil-plugin-root>/skills/capture-story/SKILL.md` — sibling skill at the story tier; capture-story-map mirrors with story-map-tier extensions (HTML encoding, no optional --rfc / --story-map flags).
|
|
285
|
+
|
|
286
|
+
$ARGUMENTS
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wr-itil:check-upstream-responses
|
|
3
|
+
description: Poll upstream issues and pull requests we've filed via `/wr-itil:report-upstream` and surface new comments or reviews, state changes, or label changes since last check. Reads `## Reported Upstream` back-link sections in local problem tickets, queries GitHub read-only, diffs against `docs/problems/.outbound-responses-cache.json`, and appends an audit-log entry to `docs/audits/outbound-responses-log.md`. Outbound symmetric counterpart to the "Inbound upstream-report discovery + assessment pipeline (peer of )" architecture rule's inbound discovery pipeline (the "No process for issue reporters to check for responses — symmetric gap to inbound discovery" problem Phase 1).
|
|
4
|
+
allowed-tools: Read, Edit, Write, Bash, Glob, Grep
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
<!-- Generated from the runtime-neutral skill source. Do not edit. -->
|
|
8
|
+
|
|
9
|
+
> Codex runtime note: use `request_user_input` only where this contract
|
|
10
|
+
> explicitly requires a human decision. Resolve `<itil-plugin-root>` from
|
|
11
|
+
> this installed `SKILL.md`: it is two directories above the skill
|
|
12
|
+
> directory. Run bundled commands from `<itil-plugin-root>/bin/`; do not
|
|
13
|
+
> search the adopter repository or rely on those commands being on `PATH`.
|
|
14
|
+
> Spawn `wr-itil:hang-off-check` with the native Codex subagent tool, wait
|
|
15
|
+
> for it, and close that same agent.
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# Check Upstream Responses — Outbound Response-Check Skill
|
|
19
|
+
|
|
20
|
+
Poll the upstream issues we have filed via `/wr-itil:report-upstream` and surface new responses (comments, state changes, label changes) since the last check. This skill closes the outbound half of the feedback loop that the "Inbound upstream-report discovery + assessment pipeline (peer of )" architecture rule's inbound assessment pipeline opens — together they form the bidirectional cross-repo coordination surface the ": Connect Agents Across Repos to Collaborate" user outcome names.
|
|
21
|
+
|
|
22
|
+
This is **Phase 1** of the "No process for issue reporters to check for responses — symmetric gap to inbound discovery" problem. Phase 1 covers the **us-as-upstream-reporter** half (we polling our own filed-upstream reports). Phase 2 — the external-reporter-as-our-reporter half (plugin users polling responses to reports they filed against this repo) — is deferred to a separate iter.
|
|
23
|
+
|
|
24
|
+
## Scope
|
|
25
|
+
|
|
26
|
+
In scope:
|
|
27
|
+
- Scan `docs/problems/**/*.md` for `## Reported Upstream` back-link sections (the contract section written by `/wr-itil:report-upstream` Step 7 — see [the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule](../../../../docs/decisions/024-cross-project-problem-reporting-contract.proposed.md) Step 7).
|
|
28
|
+
- For each ticket with a back-link, extract the `- **URL**:` line and poll the upstream artefact. Read the `- **Disclosure path**:` line to pick the subcommand: any pull-request path uses `gh pr view` plus a read-only `gh api` call for inline review comments; anything else, **including an absent line**, uses `gh issue view`. Absent means a ticket written before the "Prefer an upstream pull request over an issue when the upstream accepts pull requests" architecture rule, which could only have been filed as a public issue — so it is read as an issue, with no probe.
|
|
29
|
+
- Diff against `docs/problems/.outbound-responses-cache.json` (cache file mirroring the inbound `.upstream-cache.json` shape per the "Problem-ticket directory layout — per-state subdirectories under `docs/problems/`" architecture rule § "Cache files live under docs/problems/").
|
|
30
|
+
- Surface five response classes: NEW (new comments, reviews, or other upstream activity), STATE (state change), LABEL (label change), NONE (no change), FAIL (gh poll error).
|
|
31
|
+
- Update the cache file with the latest seen state.
|
|
32
|
+
- Append a timestamped pass entry to `docs/audits/outbound-responses-log.md` (audit-log mirroring `docs/audits/inbound-discovery-log.md` per the "Inbound upstream-report discovery + assessment pipeline (peer of )" architecture rule's audit-log surface contract).
|
|
33
|
+
|
|
34
|
+
Out of scope:
|
|
35
|
+
- Posting comments back to the upstream issue or pull request. The skill is **read-only externally** — does not trip the "External-comms gate — voice-tone + risk/leak evaluators on shared PreToolUse surface" architecture rule's external-comms gate.
|
|
36
|
+
- Auto-transitioning local ticket lifecycle based on upstream state change (that is the "Problem 080: No bidirectional update of upstream-reported problems — local lifecycle transitions never propagate back to the reporter" problem's bidirectional update axis, separate).
|
|
37
|
+
- Polling against the inbound-discovery channels (`docs/problems/.upstream-channels.json`). That is the inverse axis, owned by `/wr-itil:review-problems` Step 4.5 per the "Inbound upstream-report discovery + assessment pipeline (peer of )" architecture rule.
|
|
38
|
+
- Phase 2 external-reporter-as-our-reporter surface (deferred).
|
|
39
|
+
|
|
40
|
+
## Invocation
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
/wr-itil:check-upstream-responses
|
|
44
|
+
[--problems-dir <dir>] default: docs/problems
|
|
45
|
+
[--cache-file <path>] default: <problems-dir>/.outbound-responses-cache.json
|
|
46
|
+
[--audit-log <path>] default: docs/audits/outbound-responses-log.md
|
|
47
|
+
[--ticket P<NNN>] restrict polling to one ticket
|
|
48
|
+
[--force-recheck] ignore cache; treat all as new
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
`/wr-itil:work-problems` Step 0d pre-flights this skill when the outbound-responses cache is stale or missing AND back-link tickets exist (sibling to Step 0b inbound cache check per the "Inbound upstream-report discovery + assessment pipeline (peer of )" architecture rule Confirmation #5; the "manage-problem has no cadence for checking upstream-bound tickets" problem closed the cadence gap). Direct user invocation remains a first-class surface.
|
|
52
|
+
|
|
53
|
+
## AFK behaviour
|
|
54
|
+
|
|
55
|
+
This skill is **AFK-safe by construction**:
|
|
56
|
+
|
|
57
|
+
- Read-only `gh issue view`, `gh pr view`, and pull-request review-comment `gh api` calls — none fires the "External-comms gate — voice-tone + risk/leak evaluators on shared PreToolUse surface" architecture rule's external-comms gate.
|
|
58
|
+
- No `request_user_input` calls — five flag-based knobs (`--problems-dir`, `--cache-file`, `--audit-log`, `--ticket`, `--force-recheck`) are the user-direction surface per CLAUDE.md `act on obvious, request_user_input for ambiguous, NEVER prose-ask` (the "Problem 085: Assistant asks for input when the next step is obvious, AND uses prose asks instead of request_user_input when input is actually needed" problem).
|
|
59
|
+
- Partial-failure exit code (2) lets AFK orchestrators distinguish "some upstream URLs were unreachable" from "everything broke" without halting the loop.
|
|
60
|
+
|
|
61
|
+
## Steps
|
|
62
|
+
|
|
63
|
+
### 1. Run the diagnose+act script
|
|
64
|
+
|
|
65
|
+
Invoke the helper:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
<itil-plugin-root>/bin/wr-itil-check-upstream-responses
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The `<itil-plugin-root>/bin/wr-itil-check-upstream-responses` command is a `$PATH`-resolved shim shipped in `<itil-plugin-root>/bin/` that dispatches the canonical `<itil-plugin-root>/scripts/check-upstream-responses.sh` body. Per [the "Plugin-bundled scripts invoked from SKILL.md resolve via `bin/` on `$PATH`" architecture rule](../../../../docs/decisions/049-plugin-script-resolution-via-bin-on-path.proposed.md) — never invoke the canonical script via repo-relative path; the path does not resolve in adopter trees.
|
|
72
|
+
|
|
73
|
+
The script:
|
|
74
|
+
|
|
75
|
+
1. Walks `<problems-dir>` (both flat layout `<NNN>-*.<state>.md` AND per-state subdir layout `<state>/<NNN>-*.md` per the ": docs/problems/ flat layout migration — per-state subdirs + adopter auto-migration" release design dual-tolerant migration).
|
|
76
|
+
2. For each ticket file, extracts the `## Reported Upstream` URL line. Tickets without that section are silently skipped.
|
|
77
|
+
3. For each URL, calls `gh issue view --json comments,state,labels,updatedAt` or `gh pr view --json comments,reviews,state,labels,updatedAt` (chosen by the disclosure path). Pull requests also fetch inline review comments through `gh api`. The response count and response-specific timestamp combine all three response surfaces; parent metadata changes do not masquerade as review activity. A merged pull request reports `state=MERGED`, distinct from `CLOSED`, so a rejected one is not recorded as a resolution.
|
|
78
|
+
4. Compares the response against the cached entry for that ticket and emits one of: NEW / STATE / LABEL / NONE / FAIL.
|
|
79
|
+
5. Updates the cache file and appends an audit-log entry.
|
|
80
|
+
|
|
81
|
+
Exit codes:
|
|
82
|
+
|
|
83
|
+
- `0` — success. Cache and audit-log have been updated. Per-ticket lines printed to stdout.
|
|
84
|
+
- `1` — error (problems-dir missing, malformed cache, malformed CLI args, jq missing).
|
|
85
|
+
- `2` — partial. Some upstream polls failed; the successful ones are still written to cache + audit-log.
|
|
86
|
+
|
|
87
|
+
### 2. Summarise the response classes inline
|
|
88
|
+
|
|
89
|
+
Read the stdout output and summarise the response classes in chat for the user. The audit-log is the durable surface — the agent's inline summary is the in-session affordance. Do NOT re-dump the full stdout; lead with the most-important classes:
|
|
90
|
+
|
|
91
|
+
- STATE changes (upstream state OPEN → CLOSED / REOPENED) — most actionable; usually a verification signal.
|
|
92
|
+
- NEW responses or activity — second-most actionable; may carry comments, reviews, inline review comments, follow-up questions, or fix confirmation. A zero response delta means an existing response was edited.
|
|
93
|
+
- LABEL changes — informational; signals maintainer triage activity.
|
|
94
|
+
- NONE — quiet; only mention the count, not each ticket.
|
|
95
|
+
- FAIL — call out per-ticket reasons so the user can investigate (URL changed, repo renamed, auth issue).
|
|
96
|
+
|
|
97
|
+
### 3. Commit per the "Governance Skills Commit Their Own Completed Work" architecture rule
|
|
98
|
+
|
|
99
|
+
The cache file and audit-log file ride a single commit:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
git add docs/problems/.outbound-responses-cache.json docs/audits/outbound-responses-log.md
|
|
103
|
+
git commit -m "chore(problems): check upstream responses — <N> polled, <M> new"
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
See [the "Governance Skills Commit Their Own Completed Work" architecture rule](../../../../docs/decisions/014-governance-skills-commit-their-own-work.proposed.md) commit-message-convention table for the canonical row.
|
|
107
|
+
|
|
108
|
+
If the cumulative pipeline risk lands above appetite and `request_user_input` is unavailable, apply the [the "Structured User Interaction for Governance-Skill Decisions" architecture rule](../../../../docs/decisions/013-structured-user-interaction-for-governance-decisions.proposed.md) Rule 6 non-interactive fail-safe: skip the commit and report the uncommitted state.
|
|
109
|
+
|
|
110
|
+
## When invoked
|
|
111
|
+
|
|
112
|
+
Three invocation surfaces:
|
|
113
|
+
|
|
114
|
+
1. **Direct user invocation** — `/wr-itil:check-upstream-responses` (or with flags). The default user-facing surface.
|
|
115
|
+
2. **AFK orchestrator pre-flight** — `/wr-itil:work-problems` Step 0d invokes this skill when the outbound-responses cache is stale, missing, or has `last_checked: null` AND back-link tickets exist, mirroring Step 0b's inbound staleness check per the "Inbound upstream-report discovery + assessment pipeline (peer of )" architecture rule Confirmation #5. Cache TTL defaults to 86400s (24h) symmetric with the inbound axis. the "manage-problem has no cadence for checking upstream-bound tickets" problem closed the cadence gap.
|
|
116
|
+
3. **Manual investigation during a problem-management session** — when a maintainer wants to see if any upstream reports moved before transitioning a `verifying` ticket back to `closed`. Foreground synchronous; the maintainer reads the inline summary and decides next steps.
|
|
117
|
+
|
|
118
|
+
## Confirmation
|
|
119
|
+
|
|
120
|
+
<!-- OUTBOUND-RESPONSES-STALENESS-CONTRACT-SOURCE: <itil-plugin-root>/skills/check-upstream-responses/SKILL.md ## Confirmation -->
|
|
121
|
+
|
|
122
|
+
This skill's contract holds when:
|
|
123
|
+
|
|
124
|
+
1. The script `<itil-plugin-root>/scripts/check-upstream-responses.sh` is read-only externally — `gh issue view`, `gh pr view`, and a pull-request review-comment `gh api` read only; it makes no comment, create, edit, close, or write API call.
|
|
125
|
+
2. The script extracts the URL from `## Reported Upstream` sections matching the format `- **URL**: <url>` per the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule Step 7's back-link contract.
|
|
126
|
+
3. After a successful pass, the cache file exists, is valid JSON, and contains a `tickets.<P<NNN>>` entry for every polled ticket.
|
|
127
|
+
4. After a successful pass, the audit-log file exists and has a new `## YYYY-MM-DDTHH:MM:SSZ` heading appended.
|
|
128
|
+
5. The skill is AFK-safe: zero `request_user_input` calls, zero external-comms gate triggers.
|
|
129
|
+
6. The exit code distinguishes success (0), error (1), and partial failure (2) so AFK orchestrators can branch correctly.
|
|
130
|
+
7. **Staleness contract (the "manage-problem has no cadence for checking upstream-bound tickets" problem)**: TTL defaults to 86400s (24h) symmetric with the inbound axis. Override via `ttl_seconds` field in the cache file. The Step 0d pre-flight helper at `<itil-plugin-root>/lib/check-outbound-responses-staleness.sh` MUST stay symmetric with this contract — any change to TTL semantics MUST update the helper, the Step 0d SKILL block in `/wr-itil:work-problems`, and this Confirmation #7 in the same commit.
|
|
131
|
+
|
|
132
|
+
## ADR alignment
|
|
133
|
+
|
|
134
|
+
- **the "Governance Skills Commit Their Own Completed Work" architecture rule** — governance skills commit their own work. Cache file + audit-log ride a single commit per pass. the "Governance Skills Commit Their Own Completed Work" architecture rule's commit-message-convention table is amended in the same commit as this skill ships to add the canonical row.
|
|
135
|
+
- **the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule** — cross-project problem-reporting contract. The `## Reported Upstream` back-link section (Step 7) is the source of truth this skill reads. the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule's Confirmation section is amended in the same commit to record that the back-link section's URL field is now a load-bearing contract surface for two skills (one writes, one reads).
|
|
136
|
+
- **the "Problem-ticket directory layout — per-state subdirectories under `docs/problems/`" architecture rule** — problem-ticket directory layout. Cache file lives under `docs/problems/` per the same precedent that placed `.upstream-cache.json` and `.upstream-channels.json` there for the inbound axis.
|
|
137
|
+
- **the "Governance skill invocation patterns — foreground + background with deferred-question resumption" architecture rule** — governance skill invocation patterns. Foreground synchronous; no subagent dispatch needed.
|
|
138
|
+
- **the "Skill testing strategy — contract-assertion bats companion to" architecture rule** — skill testing strategy. Behavioural bats at `<itil-plugin-root>/scripts/test/check-upstream-responses.bats` (script-level) covers the contract.
|
|
139
|
+
- **the "Progressive disclosure + once-per-session budget for UserPromptSubmit governance prose" architecture rule** — progressive disclosure. Per-row stdout output ≤ 150 bytes; the agent expands per-ticket detail on demand.
|
|
140
|
+
- **the "Plugin-bundled scripts invoked from SKILL.md resolve via `bin/` on `$PATH`" architecture rule** — bin shim. Script invoked as `<itil-plugin-root>/bin/wr-itil-check-upstream-responses`, not via repo-relative `bash <path>`.
|
|
141
|
+
- **the "Inbound upstream-report discovery + assessment pipeline (peer of )" architecture rule** — inbound upstream-report discovery + assessment pipeline. This skill is the outbound symmetric counterpart; the "Inbound upstream-report discovery + assessment pipeline (peer of )" architecture rule `## Related` is amended in the same commit to forward-point at this skill.
|
|
142
|
+
|
|
143
|
+
## Related
|
|
144
|
+
|
|
145
|
+
- `<itil-plugin-root>/scripts/check-upstream-responses.sh` — the diagnose+act script body.
|
|
146
|
+
- `<itil-plugin-root>/scripts/test/check-upstream-responses.bats` — behavioural bats covering the script contract.
|
|
147
|
+
- `<itil-plugin-root>/skills/report-upstream/SKILL.md` — the writer of the `## Reported Upstream` section this skill reads.
|
|
148
|
+
- `<itil-plugin-root>/skills/review-problems/SKILL.md` — the inbound axis sibling (Step 4.5 inbound-discovery pass per the "Inbound upstream-report discovery + assessment pipeline (peer of )" architecture rule).
|
|
149
|
+
- `docs/audits/inbound-discovery-log.md` — inbound audit-log; symmetric peer of `docs/audits/outbound-responses-log.md`.
|
|
150
|
+
- `docs/problems/.upstream-cache.json` — inbound cache; symmetric peer of `docs/problems/.outbound-responses-cache.json`.
|
|
151
|
+
- `docs/decisions/024-cross-project-problem-reporting-contract.proposed.md` — outbound contract; back-link section is the source of truth.
|
|
152
|
+
- `docs/decisions/062-inbound-upstream-report-discovery-assessment-pipeline.proposed.md` — inbound discovery; this skill is the outbound counterpart.
|
|
153
|
+
- **the "No process for issue reporters to check for responses — symmetric gap to inbound discovery" problem** (`docs/problems/open/249-no-process-for-reporters-to-check-for-responses-symmetric-to-inbound-discovery.md`) — driver ticket. Phase 1 (us-as-upstream-reporter) ships here; Phase 2 (external-reporter-as-our-reporter) deferred.
|
|
154
|
+
- **the "Problem 080: No bidirectional update of upstream-reported problems — local lifecycle transitions never propagate back to the reporter" problem** (`docs/problems/open/080-no-bidirectional-update-of-upstream-reported-problems.md`) — inverse axis (we push local status BACK to upstream issues we ingested). Composes with this skill.
|
|
155
|
+
- **the "Inbound-discovery ack comments are bureaucratic, not verdict-shaped ( violation)" problem** — inbound discovery ack-comment shape gap (verdict-shaped acks). Inverse-shape sibling on the inbound axis.
|
|
156
|
+
- **the ": Connect Agents Across Repos to Collaborate" user outcome** — Connect Agents Across Repos to Collaborate (primary anchor).
|
|
157
|
+
- **the ": Progress the Backlog While I'm Away" user outcome** — Progress the Backlog While I'm Away (AFK-safe).
|
|
158
|
+
- **the ": Enforce Governance Without Slowing Down" user outcome** — Enforce Governance Without Slowing Down (eliminates manual upstream polling).
|
|
159
|
+
- **the "Restore Service Fast with an Audit Trail" user outcome** — Restore Service Fast with an Audit Trail (audit-log replay).
|
|
160
|
+
- **the "Run Pre-Flight Governance Checks Before Release or Handover" user outcome** — Run Pre-Flight Governance Checks Before Release or Handover (state-change signals before retro / release).
|