@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
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# check-rfc-rejected-alternatives.sh —
|
|
3
|
-
#
|
|
2
|
+
# check-rfc-rejected-alternatives.sh — behavioural-tests-default-for-skill-testing-architecture-rule behavioural lint enforcing
|
|
3
|
+
# rfcs-hold-no-independent-decisions-architecture-rule (RFCs hold no independent decisions).
|
|
4
4
|
#
|
|
5
|
-
# Invariant (
|
|
5
|
+
# Invariant (rfcs-hold-no-independent-decisions-architecture-rule § Confirmation): no RFC body in the RFC directory
|
|
6
6
|
# contains a "Considered Options / Alternatives Rejected" block WITHOUT a
|
|
7
|
-
# matching `adrs:` frontmatter reference.
|
|
7
|
+
# matching `adrs:` frontmatter reference. rfcs-hold-no-independent-decisions-architecture-rule line 44 names the
|
|
8
8
|
# machine-detectable tell: "an RFC body containing a rejected-alternatives
|
|
9
9
|
# block with no matching `adrs:` reference is a decision masquerading as
|
|
10
10
|
# scope." Contested choices belong in an ADR (referenced via `adrs:`),
|
|
11
11
|
# never re-argued in the RFC body.
|
|
12
12
|
#
|
|
13
|
-
# This is an ARTEFACT-STATE behavioural check (
|
|
13
|
+
# This is an ARTEFACT-STATE behavioural check (behavioural-tests-default-for-skill-testing-architecture-rule): given an RFC
|
|
14
14
|
# corpus directory, it inspects the on-disk RFC bodies + frontmatter and
|
|
15
15
|
# reports violations. It is NOT a structural grep of any SKILL.md / agent
|
|
16
16
|
# prose. Detection targets a markdown HEADING block (`## ... Considered
|
|
@@ -24,10 +24,10 @@
|
|
|
24
24
|
# "Considered Options" headings — they ARE the decision ledger; this lint
|
|
25
25
|
# never scans them.
|
|
26
26
|
#
|
|
27
|
-
# @adr
|
|
28
|
-
# @adr
|
|
29
|
-
# @adr
|
|
30
|
-
# @problem
|
|
27
|
+
# @adr rfcs-hold-no-independent-decisions-architecture-rule (RFCs hold no independent decisions — the invariant)
|
|
28
|
+
# @adr behavioural-tests-default-for-skill-testing-architecture-rule (behavioural-tests-default — artefact-state assertion)
|
|
29
|
+
# @adr plugin-bundled-scripts-invoked-from-skill-md-resolve-via-bin-on-path-architecture-rule (plugin-bundled scripts; adopters run this over their docs/rfcs)
|
|
30
|
+
# @problem rfcs-carry-independent-decisions-invisible-to-the-human-oversight-net-problem (RFC decisions invisible to the human-oversight-marker-wr-architect-review-decisions-drain-for-recorded-decisions-architecture-rule oversight net)
|
|
31
31
|
|
|
32
32
|
set -euo pipefail
|
|
33
33
|
|
|
@@ -58,7 +58,7 @@ for f in "$rfcs_dir"/RFC-*.md; do
|
|
|
58
58
|
if grep -qE "$heading_re" "$f"; then
|
|
59
59
|
if ! grep -qE "$adrs_re" "$f"; then
|
|
60
60
|
line=$(grep -nE "$heading_re" "$f" | head -1 | cut -d: -f1)
|
|
61
|
-
echo "VIOLATION $f:${line} rejected-alternatives block with empty/absent adrs: frontmatter (
|
|
61
|
+
echo "VIOLATION $f:${line} rejected-alternatives block with empty/absent adrs: frontmatter (rfcs-hold-no-independent-decisions-architecture-rule)"
|
|
62
62
|
violations=$((violations + 1))
|
|
63
63
|
fi
|
|
64
64
|
fi
|
|
@@ -66,7 +66,7 @@ done
|
|
|
66
66
|
shopt -u nullglob
|
|
67
67
|
|
|
68
68
|
if [ "$violations" -gt 0 ]; then
|
|
69
|
-
echo "check-rfc-rejected-alternatives: $violations violation(s) across $scanned RFC(s) — an RFC carrying a rejected-alternatives block must reference its governing ADR(s) in adrs: (
|
|
69
|
+
echo "check-rfc-rejected-alternatives: $violations violation(s) across $scanned RFC(s) — an RFC carrying a rejected-alternatives block must reference its governing ADR(s) in adrs: (rfcs-hold-no-independent-decisions-architecture-rule)." >&2
|
|
70
70
|
exit 1
|
|
71
71
|
fi
|
|
72
72
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# check-rfc-stories-ratified.sh —
|
|
2
|
+
# check-rfc-stories-ratified.sh — a-release-row-is-the-rfc-and-the-map-is-the-approval-surface-architecture-rule (an RFC may reference only APPROVED stories).
|
|
3
3
|
#
|
|
4
4
|
# For each STORY-NNN in the RFC's `stories:` frontmatter, resolve the story file
|
|
5
5
|
# under <stories-root>/*/STORY-NNN-*.md and ask `story_is_approved`: is every map
|
|
6
6
|
# in that story's `story-maps:` field ratified? A story carries no oversight
|
|
7
|
-
# marker of its own (
|
|
7
|
+
# marker of its own (a-release-row-is-the-rfc-and-the-map-is-the-approval-surface-architecture-rule), so the remedy for a failure is always to ratify
|
|
8
8
|
# the MAP. Exit non-zero, with a stderr directive naming the offending stories,
|
|
9
9
|
# if any listed story is unapproved or missing.
|
|
10
10
|
#
|
|
11
|
-
# Composes with check-rfc-has-stories.sh (
|
|
11
|
+
# Composes with check-rfc-has-stories.sh (every-rfc-has-at-least-one-story-architecture-rule): has-stories checks >=1 story
|
|
12
12
|
# exists; this checks each listed story is ratified. An empty `stories:` passes
|
|
13
13
|
# vacuously here (the has-stories gate owns the emptiness rejection).
|
|
14
14
|
#
|
|
@@ -16,10 +16,10 @@
|
|
|
16
16
|
# Exit: 0 = all listed stories ratified (or none listed); 1 = >=1 unratified/missing;
|
|
17
17
|
# 2 = usage / file error.
|
|
18
18
|
#
|
|
19
|
-
# Authority:
|
|
19
|
+
# Authority: story-maps-and-stories-carry-a-drift-invalidated-human-oversight-marker-architecture-rule, a-release-row-is-the-rfc-and-the-map-is-the-approval-surface-architecture-rule. Driver: implement-in-the-skills-and-tests-1-story-per-rfc-story-map-story-ratification-problem Phase 2. Test: check-rfc-stories-ratified.bats.
|
|
20
20
|
set -euo pipefail
|
|
21
21
|
|
|
22
|
-
# Adopter-safe: source the shared lazy-fingerprint lib RELATIVE TO THIS SCRIPT (
|
|
22
|
+
# Adopter-safe: source the shared lazy-fingerprint lib RELATIVE TO THIS SCRIPT (capture-problem-capture-rfc-manage-problem-step-2-create-gate-marker-step-sources-repo-relative-packages-itil-hooks-lib-sh-fails-in-adopter-installs-recurring-published-path-class-problem).
|
|
23
23
|
LIB="$(cd "$(dirname "${BASH_SOURCE[0]}")/../lib" 2>/dev/null && pwd)" || {
|
|
24
24
|
echo "check-rfc-stories-ratified: cannot locate lib dir" >&2; exit 2; }
|
|
25
25
|
# shellcheck source=/dev/null
|
|
@@ -54,16 +54,16 @@ for id in $ids; do
|
|
|
54
54
|
unratified="$unratified $id(missing)"
|
|
55
55
|
continue
|
|
56
56
|
fi
|
|
57
|
-
#
|
|
58
|
-
# predicate alone would re-create the
|
|
59
|
-
# would block on a story
|
|
57
|
+
# a-release-row-is-the-rfc-and-the-map-is-the-approval-surface-architecture-rule: approval reaches a story through its map. Judging it by the story
|
|
58
|
+
# predicate alone would re-create the afk-iter-cannot-progress-a-ratified-known-error-when-the-fix-vehicle-rfc-has-empty-stories-problem deadlock one tier up — the RFC tier
|
|
59
|
+
# would block on a story a-release-row-is-the-rfc-and-the-map-is-the-approval-surface-architecture-rule approves.
|
|
60
60
|
if ! story_is_approved "$f" "$maps_root"; then
|
|
61
61
|
unratified="$unratified $id(unapproved)"
|
|
62
62
|
fi
|
|
63
63
|
done
|
|
64
64
|
|
|
65
65
|
if [ -n "$unratified" ]; then
|
|
66
|
-
echo "check-rfc-stories-ratified: $rfc references unapproved stories:$unratified —
|
|
66
|
+
echo "check-rfc-stories-ratified: $rfc references unapproved stories:$unratified — a-release-row-is-the-rfc-and-the-map-is-the-approval-surface-architecture-rule: an RFC may reference only approved stories, and a story is approved by its story MAP. Ratify the map named in the story's story-maps: field via /wr-itil:manage-story-map <MAP-ID> ratify — a story carries no oversight marker of its own." >&2
|
|
67
67
|
exit 1
|
|
68
68
|
fi
|
|
69
69
|
exit 0
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# wr-itil — predicate: are the JTBDs cited by a problem ticket all ratified?
|
|
3
|
-
# (
|
|
3
|
+
# (wr-itil-work-problems-step-3-5-jtbd-ratification-predicate-check-orchestrator-layer-mirror-of-surface-3-release-design / wr-itil-work-problems-orchestrator-should-predicate-check-the-cited-jtbds-of-the-selected-ticket-before-dispatching-the-iter-worker-wasted-iter-dispatch-class-when-jtbds-are-unratified-problem — orchestrator-layer mirror of jtbd-persona-human-oversight-marker-wr-jtbd-confirm-jobs-and-personas-drain-sibling-of-architecture-rule surface 3)
|
|
4
4
|
#
|
|
5
5
|
# `/wr-itil:work-problems` Step 3.5 invokes this script on the selected
|
|
6
6
|
# ticket BEFORE dispatching the iter-subprocess. The per-iter JTBD review
|
|
7
7
|
# subagent already catches the same class via the [Unratified Dependency]
|
|
8
|
-
# verdict (
|
|
8
|
+
# verdict (jtbd-persona-human-oversight-marker-wr-jtbd-confirm-jobs-and-personas-drain-sibling-of-architecture-rule surface 3), but only AFTER spending iter-dispatch cost.
|
|
9
9
|
# This script shifts the predicate left to the orchestrator layer for the
|
|
10
10
|
# cost of one grep + one shim call per cited JTBD.
|
|
11
11
|
#
|
|
12
|
-
# Polarity (
|
|
12
|
+
# Polarity (wr-itil-work-problems-step-3-5-jtbd-ratification-predicate-check-orchestrator-layer-mirror-of-surface-3-release-design § Scope — outer-script polarity INVERTED vs the inner
|
|
13
13
|
# per-JTBD predicate it dispatches):
|
|
14
14
|
# exit 0 = all cited JTBDs ratified OR ticket cites none → orchestrator
|
|
15
15
|
# proceeds with the dispatch. No stdout.
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
# exit 2 = ticket file missing / unreadable. No stdout; reason on stderr.
|
|
21
21
|
#
|
|
22
22
|
# Silent-pass on missing per-JTBD shim: when `wr-jtbd-is-job-or-persona-
|
|
23
|
-
# unconfirmed` is not on PATH (degenerate adopter case per
|
|
23
|
+
# unconfirmed` is not on PATH (degenerate adopter case per problem-ticket-directory-layout-per-state-subdirectories-under-docs-problems-architecture-rule —
|
|
24
24
|
# adopter installed @windyroad/itil without @windyroad/jtbd), the script
|
|
25
25
|
# silent-passes (exit 0). The iter-subprocess JTBD subagent is the
|
|
26
26
|
# authoritative second-source; orchestrator-layer pre-check is optimisation.
|
|
@@ -30,11 +30,11 @@
|
|
|
30
30
|
# <ticket-file> = path to a problem-ticket .md file (relative or absolute)
|
|
31
31
|
# JTBD_DIR defaults to docs/jtbd
|
|
32
32
|
#
|
|
33
|
-
# @rfc
|
|
34
|
-
# @adr
|
|
35
|
-
# @adr
|
|
36
|
-
# @adr
|
|
37
|
-
# @problem
|
|
33
|
+
# @rfc wr-itil-work-problems-step-3-5-jtbd-ratification-predicate-check-orchestrator-layer-mirror-of-surface-3-release-design (wr-itil-work-problems-orchestrator-should-predicate-check-the-cited-jtbds-of-the-selected-ticket-before-dispatching-the-iter-worker-wasted-iter-dispatch-class-when-jtbds-are-unratified-problem — work-problems Step 3.5 JTBD ratification predicate)
|
|
34
|
+
# @adr jtbd-persona-human-oversight-marker-wr-jtbd-confirm-jobs-and-personas-drain-sibling-of-architecture-rule (JTBD + persona human-oversight marker — surface 3 mirrored)
|
|
35
|
+
# @adr confirm-a-decision-s-substance-before-building-dependent-work-on-it-architecture-rule (substance-confirm-before-build — JTBD-as-driver symmetric)
|
|
36
|
+
# @adr plugin-bundled-scripts-invoked-from-skill-md-resolve-via-bin-on-path-architecture-rule (PATH shim grammar)
|
|
37
|
+
# @problem wr-itil-work-problems-orchestrator-should-predicate-check-the-cited-jtbds-of-the-selected-ticket-before-dispatching-the-iter-worker-wasted-iter-dispatch-class-when-jtbds-are-unratified-problem
|
|
38
38
|
|
|
39
39
|
set -uo pipefail
|
|
40
40
|
|
|
@@ -51,7 +51,7 @@ JTBD_DIR="${2:-docs/jtbd}"
|
|
|
51
51
|
exit 2
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
#
|
|
54
|
+
# problem-ticket-directory-layout-per-state-subdirectories-under-docs-problems-architecture-rule silent-pass: if the per-JTBD predicate shim is absent, the
|
|
55
55
|
# orchestrator-layer pre-check cannot run. The iter-subprocess JTBD
|
|
56
56
|
# subagent will catch any unratified-dep at the inner layer; this script
|
|
57
57
|
# is the optimisation surface, not the authoritative gate.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# packages/itil/scripts/check-upstream-responses.sh
|
|
3
3
|
#
|
|
4
|
-
# Phase 1 of
|
|
4
|
+
# Phase 1 of no-process-for-issue-reporters-to-check-for-responses-symmetric-gap-to-inbound-discovery-problem — outbound symmetric counterpart to inbound-upstream-report-discovery-assessment-pipeline-peer-of-architecture-rule's inbound
|
|
5
5
|
# discovery pipeline. Scans local problem tickets for `## Reported
|
|
6
6
|
# Upstream` back-link sections (written by `/wr-itil:report-upstream`
|
|
7
7
|
# Step 7), polls each upstream issue via `gh issue view`, diffs against
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
#
|
|
11
11
|
# Read-only externally: `gh issue view`, or `gh pr view` plus the pull
|
|
12
12
|
# request's inline review comments via `gh api` — no
|
|
13
|
-
# `gh issue comment` / `gh issue create`. Does NOT trip
|
|
13
|
+
# `gh issue comment` / `gh issue create`. Does NOT trip external-comms-gate-voice-tone-risk-leak-evaluators-on-shared-pretooluse-surface-architecture-rule
|
|
14
14
|
# external-comms gate. AFK-safe.
|
|
15
15
|
#
|
|
16
16
|
# Usage:
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
# 2 = partial — some upstream polls failed; successful ones are still
|
|
29
29
|
# written to cache + audit-log
|
|
30
30
|
#
|
|
31
|
-
# Structured stdout (one per ticket; ≤ 150 bytes per line per
|
|
31
|
+
# Structured stdout (one per ticket; ≤ 150 bytes per line per progressive-disclosure-once-per-session-budget-for-userpromptsubmit-governance-prose-architecture-rule):
|
|
32
32
|
# NEW P<NNN> <url> state=<state> new-responses=<N>
|
|
33
33
|
# STATE P<NNN> <url> state=<old>→<new>
|
|
34
34
|
# LABEL P<NNN> <url> labels-added=<csv> labels-removed=<csv>
|
|
@@ -37,26 +37,26 @@
|
|
|
37
37
|
#
|
|
38
38
|
# Precedence when multiple change classes apply: STATE > NEW (responses) > LABEL > NONE.
|
|
39
39
|
#
|
|
40
|
-
# @problem
|
|
41
|
-
# @adr
|
|
42
|
-
# @adr
|
|
43
|
-
# @adr
|
|
44
|
-
# @adr
|
|
45
|
-
# @adr
|
|
46
|
-
# @adr
|
|
47
|
-
# @adr
|
|
48
|
-
# @adr
|
|
40
|
+
# @problem no-process-for-issue-reporters-to-check-for-responses-symmetric-gap-to-inbound-discovery-problem — no process for issue reporters to check for responses (Phase 1)
|
|
41
|
+
# @adr governance-skills-commit-their-own-completed-work-architecture-rule (governance skills commit their own work)
|
|
42
|
+
# @adr cross-project-problem-reporting-contract-report-upstream-skill-in-windyroad-itil-architecture-rule (back-link source of truth — Reported Upstream URL)
|
|
43
|
+
# @adr problem-ticket-directory-layout-per-state-subdirectories-under-docs-problems-architecture-rule (cache file placement under docs/problems/)
|
|
44
|
+
# @adr governance-skill-invocation-patterns-foreground-background-with-deferred-question-resumption-architecture-rule (foreground synchronous skill)
|
|
45
|
+
# @adr progressive-disclosure-once-per-session-budget-for-userpromptsubmit-governance-prose-architecture-rule (progressive disclosure — per-row byte budget)
|
|
46
|
+
# @adr plugin-bundled-scripts-invoked-from-skill-md-resolve-via-bin-on-path-architecture-rule (invoked via wr-itil-check-upstream-responses bin shim)
|
|
47
|
+
# @adr inbound-upstream-report-discovery-assessment-pipeline-peer-of-architecture-rule (inbound discovery — symmetric counterpart)
|
|
48
|
+
# @adr prefer-an-upstream-pull-request-over-an-issue-when-the-upstream-accepts-pull-requests-architecture-rule (prefer an upstream pull request over an issue — the
|
|
49
49
|
# `## Reported Upstream` disclosure path selects `gh pr view` over
|
|
50
50
|
# `gh issue view`. An ABSENT path means a ticket written before that
|
|
51
|
-
# decision, which the pre-
|
|
51
|
+
# decision, which the pre-prefer-an-upstream-pull-request-over-an-issue-when-the-upstream-accepts-pull-requests-architecture-rule skill could only ever have filed as
|
|
52
52
|
# a public issue — so absent means issue, and no probe is needed. This
|
|
53
|
-
# is the explicit legacy-path decision
|
|
53
|
+
# is the explicit legacy-path decision prefer-an-upstream-pull-request-over-an-issue-when-the-upstream-accepts-pull-requests-architecture-rule requires; an
|
|
54
54
|
# issue-then-pr probe would double the call count for every legacy
|
|
55
55
|
# ticket on every cycle against a `gh` rate budget nothing governs.)
|
|
56
|
-
# @jtbd
|
|
57
|
-
# @jtbd
|
|
58
|
-
# @jtbd
|
|
59
|
-
# @jtbd
|
|
56
|
+
# @jtbd connect-agents-across-repos-to-collaborate-user-outcome (cross-repo coordination — primary anchor)
|
|
57
|
+
# @jtbd progress-the-backlog-while-i-m-away-user-outcome (AFK-safe)
|
|
58
|
+
# @jtbd enforce-governance-without-slowing-down-user-outcome (governance without slowing down)
|
|
59
|
+
# @jtbd restore-service-fast-with-an-audit-trail-user-outcome (audit trail)
|
|
60
60
|
|
|
61
61
|
set -uo pipefail
|
|
62
62
|
|
|
@@ -119,7 +119,7 @@ UPDATED_CACHE="$CACHE_JSON"
|
|
|
119
119
|
|
|
120
120
|
# ── Discover tickets with `## Reported Upstream` URL ────────────────────────
|
|
121
121
|
#
|
|
122
|
-
# Dual-tolerant per
|
|
122
|
+
# Dual-tolerant per docs-problems-flat-layout-migration-per-state-subdirs-adopter-auto-migration-release-design: flat layout `<NNN>-*.<status>.md` AND
|
|
123
123
|
# per-state subdir layout `<status>/<NNN>-*.md`.
|
|
124
124
|
|
|
125
125
|
shopt -s nullglob
|
|
@@ -171,7 +171,7 @@ extract_disclosure_path() {
|
|
|
171
171
|
|
|
172
172
|
# Which `gh` read subcommand polls this ticket's upstream artefact?
|
|
173
173
|
# `pull request` (or `pull-request`) → `gh pr view`; anything else,
|
|
174
|
-
# INCLUDING an absent disclosure path, → `gh issue view` (
|
|
174
|
+
# INCLUDING an absent disclosure path, → `gh issue view` (prefer-an-upstream-pull-request-over-an-issue-when-the-upstream-accepts-pull-requests-architecture-rule).
|
|
175
175
|
upstream_view_noun() {
|
|
176
176
|
case "$1" in
|
|
177
177
|
*pull*request*) echo "pr" ;;
|
|
@@ -349,9 +349,9 @@ if [ ! -f "$AUDIT_LOG" ]; then
|
|
|
349
349
|
cat > "$AUDIT_LOG" <<'EOF'
|
|
350
350
|
# Outbound upstream-response check — audit log
|
|
351
351
|
|
|
352
|
-
> Forward-chronology audit trail of `/wr-itil:check-upstream-responses` passes (
|
|
352
|
+
> Forward-chronology audit trail of `/wr-itil:check-upstream-responses` passes (no-process-for-issue-reporters-to-check-for-responses-symmetric-gap-to-inbound-discovery-problem Phase 1). Each pass appends a `## YYYY-MM-DDTHH:MM:SSZ` heading with tickets polled, response classes observed, and cache refresh confirmation. Mirrors `docs/audits/inbound-discovery-log.md` shape per inbound-upstream-report-discovery-assessment-pipeline-peer-of-architecture-rule's audit-log surface contract.
|
|
353
353
|
>
|
|
354
|
-
> Path is intentional per CLAUDE.md
|
|
354
|
+
> Path is intentional per CLAUDE.md agents-write-project-generated-artefacts-under-claude-user-controlled-config-space-gate-exclusions-are-read-tolerance-not-write-permission-problem — project-generated artefacts go under `docs/`, never `.claude/`.
|
|
355
355
|
|
|
356
356
|
EOF
|
|
357
357
|
fi
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
#
|
|
4
4
|
# Classify reconcile-readme.sh exit-1 drift output as either
|
|
5
5
|
# inline-refresh-deferrable (covered by uncommitted ticket renames in the
|
|
6
|
-
# working tree — in-flow
|
|
7
|
-
# in the upcoming commit per
|
|
6
|
+
# working tree — in-flow problem-094-wr-itil-manage-problem-does-not-refresh-docs-problems-readme-md-on-ticket-creation-problem/problem-062-manage-problem-does-not-refresh-docs-problems-readme-md-on-single-ticket-transitions-fast-path-cache-goes-stale-silently-problem refresh will land the README correction
|
|
7
|
+
# in the upcoming commit per governance-skills-commit-their-own-completed-work-architecture-rule) or halt-route-reconcile (committed
|
|
8
8
|
# cross-session drift — must route to /wr-itil:reconcile-readme).
|
|
9
9
|
#
|
|
10
10
|
# Usage:
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
# Output (stdout, single classification line):
|
|
21
21
|
# INLINE_REFRESH covered=<N> — every drift ID is the destination
|
|
22
22
|
# of a staged rename in the working
|
|
23
|
-
# tree; defer to in-flow
|
|
24
|
-
# refresh per
|
|
23
|
+
# tree; defer to in-flow problem-094-wr-itil-manage-problem-does-not-refresh-docs-problems-readme-md-on-ticket-creation-problem/problem-062-manage-problem-does-not-refresh-docs-problems-readme-md-on-single-ticket-transitions-fast-path-cache-goes-stale-silently-problem
|
|
24
|
+
# refresh per governance-skills-commit-their-own-completed-work-architecture-rule.
|
|
25
25
|
# HALT_ROUTE_RECONCILE uncovered=<N> — at least one drift ID is NOT
|
|
26
26
|
# covered by a working-tree rename;
|
|
27
27
|
# committed cross-session drift OR
|
|
@@ -33,18 +33,18 @@
|
|
|
33
33
|
# 1 = HALT_ROUTE_RECONCILE
|
|
34
34
|
# 2 = parse error (drift-stdout-file missing or empty)
|
|
35
35
|
#
|
|
36
|
-
# @problem
|
|
36
|
+
# @problem wr-itil-manage-problem-step-0-reconcile-halt-on-drift-directive-doesn-t-distinguish-uncommitted-rename-rooted-drift-same-session-pending-from-committed-cross-session-drift-should-refresh-inline-rather-than-halt-for-the-former-case-problem — manage-problem Step 0 reconcile halt-on-drift directive
|
|
37
37
|
# doesn't distinguish uncommitted-rename-rooted drift from
|
|
38
38
|
# committed cross-session drift; this script is the
|
|
39
39
|
# detection mechanism that makes the carve-out behavioural.
|
|
40
|
-
# @adr
|
|
40
|
+
# @adr governance-skills-commit-their-own-completed-work-architecture-rule (single-commit grain — the carve-out preserves it for the
|
|
41
41
|
# in-flow path while keeping cross-session drift safety)
|
|
42
|
-
# @adr
|
|
42
|
+
# @adr structured-user-interaction-for-governance-skill-decisions-architecture-rule Rule 6 (AFK fail-safe — committed drift still routes to
|
|
43
43
|
# /wr-itil:reconcile-readme; only the inline path
|
|
44
44
|
# is added)
|
|
45
|
-
# @adr
|
|
46
|
-
# @jtbd
|
|
47
|
-
# @jtbd
|
|
45
|
+
# @adr progressive-disclosure-once-per-session-budget-for-userpromptsubmit-governance-prose-architecture-rule (progressive disclosure — output is a single terse line)
|
|
46
|
+
# @jtbd progress-the-backlog-while-i-m-away-user-outcome (Progress the Backlog While I'm Away — AFK loop continuity)
|
|
47
|
+
# @jtbd enforce-governance-without-slowing-down-user-outcome (Enforce Governance Without Slowing Down — single-commit grain)
|
|
48
48
|
|
|
49
49
|
set -uo pipefail
|
|
50
50
|
|
|
@@ -84,9 +84,9 @@ fi
|
|
|
84
84
|
#
|
|
85
85
|
# 2. Same-ID D + (A or ??) pair (substantial-body edit defeated rename-
|
|
86
86
|
# detection so the move renders as delete + add for the same ticket ID
|
|
87
|
-
# —
|
|
88
|
-
# coverage purposes: the in-flow
|
|
89
|
-
# README in the upcoming commit per
|
|
87
|
+
# — classify-readme-drift-sh-only-covers-staged-rename-r-entries-a-same-id-delete-add-d-a-pair-is-uncovered-and-false-halts-problem). We treat such a pair as equivalent to an R entry for drift-
|
|
88
|
+
# coverage purposes: the in-flow problem-094-wr-itil-manage-problem-does-not-refresh-docs-problems-readme-md-on-ticket-creation-problem/problem-062-manage-problem-does-not-refresh-docs-problems-readme-md-on-single-ticket-transitions-fast-path-cache-goes-stale-silently-problem refresh will reconcile the
|
|
89
|
+
# README in the upcoming commit per governance-skills-commit-their-own-completed-work-architecture-rule.
|
|
90
90
|
#
|
|
91
91
|
# We match the destination path's ticket ID — the post-rename status is what
|
|
92
92
|
# the in-flow refresh will reconcile.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
5
|
+
import { homedir } from "node:os";
|
|
6
|
+
import { dirname, join, resolve } from "node:path";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
|
|
9
|
+
const root = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
10
|
+
const source = join(root, "agents", "hang-off-check.md");
|
|
11
|
+
const filename = "wr-itil-hang-off-check.toml";
|
|
12
|
+
const owner = "# Generated by @windyroad/itil from agents/hang-off-check.md.";
|
|
13
|
+
const sourceId = /\b(?:ADR-\d{3,}|P-?\d{3}|RFC-\d{3,}|JTBD-\d{3,}|STORY(?:-MAP)?-\d{3,}|R-?\d{3})\b/g;
|
|
14
|
+
|
|
15
|
+
function split(markdown) {
|
|
16
|
+
const end = markdown.indexOf("\n---\n", 4);
|
|
17
|
+
return markdown.startsWith("---\n") && end !== -1
|
|
18
|
+
? { frontmatter: markdown.slice(4, end), body: markdown.slice(end + 5) }
|
|
19
|
+
: { frontmatter: "", body: markdown };
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function description(frontmatter) {
|
|
23
|
+
const lines = frontmatter.split(/\r?\n/);
|
|
24
|
+
const start = lines.findIndex((line) => line.startsWith("description:"));
|
|
25
|
+
if (start === -1) return "Decide whether a problem belongs under an existing ticket.";
|
|
26
|
+
const value = [lines[start].slice("description:".length).trim()];
|
|
27
|
+
for (let index = start + 1; index < lines.length && /^\s+/.test(lines[index]); index += 1) value.push(lines[index].trim());
|
|
28
|
+
return value.filter(Boolean).join(" ").replace(sourceId, "a source governance record");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function instructions(body) {
|
|
32
|
+
return body
|
|
33
|
+
.replaceAll("AskUserQuestion", "request_user_input")
|
|
34
|
+
.replaceAll("Agent tool", "native Codex subagent tool")
|
|
35
|
+
.replaceAll("packages/itil/", "the installed ITIL plugin/")
|
|
36
|
+
.replace(sourceId, "the referenced source governance record");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function payload() {
|
|
40
|
+
const { frontmatter, body } = split(readFileSync(source, "utf8"));
|
|
41
|
+
return [
|
|
42
|
+
"# Do not edit by hand; update agents/hang-off-check.md and reinstall.",
|
|
43
|
+
'name = "wr-itil:hang-off-check"',
|
|
44
|
+
`description = ${JSON.stringify(description(frontmatter))}`,
|
|
45
|
+
'sandbox_mode = "read-only"',
|
|
46
|
+
'developer_instructions = """',
|
|
47
|
+
instructions(body).replace(/\\/g, "\\\\").replace(/"""/g, '\\"\\"\\"').trimEnd(),
|
|
48
|
+
'"""',
|
|
49
|
+
"",
|
|
50
|
+
].join("\n");
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function renderAgent() {
|
|
54
|
+
const content = payload();
|
|
55
|
+
const hash = createHash("sha256").update(content).digest("hex");
|
|
56
|
+
return `${owner}\n# Generated content SHA-256: ${hash}\n${content}`;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function owned(content) {
|
|
60
|
+
if (!content.startsWith(`${owner}\n`)) return false;
|
|
61
|
+
const lines = content.split("\n");
|
|
62
|
+
const match = lines[1]?.match(/^# Generated content SHA-256: ([0-9a-f]{64})$/);
|
|
63
|
+
return Boolean(match && createHash("sha256").update(lines.slice(2).join("\n")).digest("hex") === match[1]);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export function agentDir(scope, cwd = process.cwd(), env = process.env) {
|
|
67
|
+
return scope === "user" ? join(env.CODEX_HOME || join(homedir(), ".codex"), "agents") : join(cwd, ".codex", "agents");
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function installAgent(targetDir, { quiet = false } = {}) {
|
|
71
|
+
mkdirSync(targetDir, { recursive: true });
|
|
72
|
+
const target = join(targetDir, filename);
|
|
73
|
+
const expected = renderAgent();
|
|
74
|
+
if (existsSync(target)) {
|
|
75
|
+
const current = readFileSync(target, "utf8");
|
|
76
|
+
if (current === expected) return false;
|
|
77
|
+
if (!owned(current)) {
|
|
78
|
+
if (!quiet) console.log(`Preserved user-managed Codex agent at ${target}.`);
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
writeFileSync(target, expected, "utf8");
|
|
83
|
+
if (!quiet) console.log(`Codex ITIL agent installed at ${target}.`);
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function uninstallAgent(targetDir) {
|
|
88
|
+
const target = join(targetDir, filename);
|
|
89
|
+
if (existsSync(target) && owned(readFileSync(target, "utf8"))) rmSync(target);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (process.argv[1] && resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
93
|
+
if (process.argv.includes("--session-start") && !process.env.CODEX_THREAD_ID) process.exit(0);
|
|
94
|
+
const scopeIndex = process.argv.indexOf("--scope");
|
|
95
|
+
const scope = scopeIndex === -1 ? (process.argv.includes("--session-start") ? "user" : "project") : process.argv[scopeIndex + 1];
|
|
96
|
+
const target = agentDir(scope);
|
|
97
|
+
if (process.argv.includes("--uninstall")) uninstallAgent(target);
|
|
98
|
+
else {
|
|
99
|
+
const changed = installAgent(target, { quiet: process.argv.includes("--session-start") });
|
|
100
|
+
if (changed && process.argv.includes("--session-start")) {
|
|
101
|
+
console.log(JSON.stringify({ systemMessage: "wr-itil: Codex hang-off-check agent installed; restart Codex to activate it." }));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# packages/itil/scripts/derive-release-vehicle.sh
|
|
3
3
|
#
|
|
4
4
|
# Derive the release-vehicle citation for a problem ticket by walking git
|
|
5
|
-
# history. Input: ticket ID (e.g. `
|
|
5
|
+
# history. Input: ticket ID (e.g. `codify-derive-release-vehicle-sh-helper-for-k-v-release-cycle-citation-problem` or `267`). The script reads the
|
|
6
6
|
# ticket body for a `.changeset/<name>.md` filename reference, finds the
|
|
7
7
|
# `chore: version packages` deletion commit via `git log --diff-filter=D`,
|
|
8
8
|
# resolves the merge PR via the ancestry-path merge commit (or `gh pr list`
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
# <ticket-id>: `P<NNN>` or bare `<NNN>`. Case-insensitive.
|
|
15
15
|
# <problems-dir>: defaults to ./docs/problems. Dual-tolerant lookup spans
|
|
16
16
|
# flat layout (`<problems-dir>/<NNN>-*.md`) AND per-state
|
|
17
|
-
# subdir layout (`<problems-dir>/*/<NNN>-*.md`) per
|
|
17
|
+
# subdir layout (`<problems-dir>/*/<NNN>-*.md`) per problem-ticket-directory-layout-per-state-subdirectories-under-docs-problems-architecture-rule.
|
|
18
18
|
#
|
|
19
19
|
# Output (stdout, multi-line key:value block):
|
|
20
20
|
# RELEASE_VEHICLE:
|
|
@@ -28,40 +28,40 @@
|
|
|
28
28
|
# 0 = OK (full citation emitted)
|
|
29
29
|
# 1 = ticket file not found
|
|
30
30
|
# 2 = no changeset reference in ticket body AND no co-committed changeset
|
|
31
|
-
# derivable from the ticket's git history (
|
|
31
|
+
# derivable from the ticket's git history (work-iters-omit-the-release-vehicle-seed-on-open-known-error-so-the-post-release-k-v-auto-enumerator-silently-skips-them-problem fallback)
|
|
32
32
|
# 3 = changeset present in working tree (unreleased)
|
|
33
33
|
# 4 = deletion commit found but no merge PR / merge commit resolvable
|
|
34
34
|
#
|
|
35
|
-
# @problem
|
|
35
|
+
# @problem codify-derive-release-vehicle-sh-helper-for-k-v-release-cycle-citation-problem — Codify derive-release-vehicle.sh helper for K→V release-
|
|
36
36
|
# cycle citation. K→V transitions composed by hand are
|
|
37
37
|
# fragile to wrong-release-cited errors when sessions
|
|
38
38
|
# pre-apply transitions across sibling tickets (observed
|
|
39
|
-
# 2026-05-18
|
|
40
|
-
# @adr
|
|
39
|
+
# 2026-05-18 work-problems-step-6-5-3-within-appetite-no-drain-clause-defers-low-risk-releases-encoding-accumulation-problem K→V cited run-retro-step-3-tier-3-branch-b-leave-as-is-encodes-fictional-defer-sibling-to-evidence-based-criterion-problem's release refs).
|
|
40
|
+
# @adr plugin-bundled-scripts-invoked-from-skill-md-resolve-via-bin-on-path-architecture-rule (bin/ on PATH shim — adopter-safe script resolution; helper
|
|
41
41
|
# is invoked as `wr-itil-derive-release-vehicle`)
|
|
42
|
-
# @adr
|
|
42
|
+
# @adr problem-lifecycle-add-a-verification-pending-status-between-known-error-and-closed-architecture-rule (Verifying lifecycle — citation supports the K→V transition's
|
|
43
43
|
# `## Fix Released` section)
|
|
44
|
-
# @adr
|
|
45
|
-
# @adr
|
|
46
|
-
# @adr
|
|
47
|
-
# @jtbd
|
|
44
|
+
# @adr governance-skills-commit-their-own-completed-work-architecture-rule (single-commit grain — helper is read-only, no commit impact)
|
|
45
|
+
# @adr progressive-disclosure-once-per-session-budget-for-userpromptsubmit-governance-prose-architecture-rule (progressive disclosure — short structured stdout block)
|
|
46
|
+
# @adr plugin-testing-strategy-architecture-rule (Plugin testing strategy — behavioural bats per problem-081-structural-source-content-tests-are-wasteful-tdd-agent-should-reject-them-and-require-behavioural-tests-framework-stub-enhancements-problem)
|
|
47
|
+
# @jtbd enforce-governance-without-slowing-down-user-outcome (Enforce Governance Without Slowing Down — deterministic
|
|
48
48
|
# citation prevents cross-cite errors)
|
|
49
|
-
# @jtbd
|
|
49
|
+
# @jtbd progress-the-backlog-while-i-m-away-user-outcome (Progress the Backlog While I'm Away — orchestrator per-iter
|
|
50
50
|
# K→V audit trail is trustworthy)
|
|
51
|
-
# @jtbd
|
|
51
|
+
# @jtbd extend-the-suite-with-new-plugins-user-outcome (Extend the Plugin Suite — sibling shim naming grammar)
|
|
52
52
|
|
|
53
53
|
set -uo pipefail
|
|
54
54
|
|
|
55
55
|
usage() {
|
|
56
56
|
cat >&2 <<'EOF'
|
|
57
57
|
USAGE: derive-release-vehicle.sh <ticket-id> [<problems-dir>]
|
|
58
|
-
<ticket-id> — P<NNN> or bare <NNN> (e.g.
|
|
58
|
+
<ticket-id> — P<NNN> or bare <NNN> (e.g. codify-derive-release-vehicle-sh-helper-for-k-v-release-cycle-citation-problem or 267)
|
|
59
59
|
<problems-dir> — defaults to ./docs/problems
|
|
60
60
|
|
|
61
61
|
Exit codes:
|
|
62
62
|
0 ok (full citation)
|
|
63
63
|
1 ticket file not found
|
|
64
|
-
2 no changeset reference in body AND no co-committed changeset in ticket history (
|
|
64
|
+
2 no changeset reference in body AND no co-committed changeset in ticket history (work-iters-omit-the-release-vehicle-seed-on-open-known-error-so-the-post-release-k-v-auto-enumerator-silently-skips-them-problem)
|
|
65
65
|
3 changeset present in working tree (unreleased)
|
|
66
66
|
4 deletion commit found but no merge PR / merge commit resolvable
|
|
67
67
|
EOF
|
|
@@ -83,7 +83,7 @@ if [ -z "$NNN" ]; then
|
|
|
83
83
|
fi
|
|
84
84
|
NNN="$(printf '%03d' "$((10#$NNN))")"
|
|
85
85
|
|
|
86
|
-
# ── Locate ticket file (dual-tolerant per
|
|
86
|
+
# ── Locate ticket file (dual-tolerant per problem-ticket-directory-layout-per-state-subdirectories-under-docs-problems-architecture-rule) ──────────────────────────
|
|
87
87
|
TICKET_FILE=""
|
|
88
88
|
for candidate in \
|
|
89
89
|
"$PROBLEMS_DIR/$NNN-"*.md \
|
|
@@ -106,17 +106,17 @@ CHANGESET_PATH="$(
|
|
|
106
106
|
| head -1
|
|
107
107
|
)"
|
|
108
108
|
|
|
109
|
-
# ── Fallback (
|
|
109
|
+
# ── Fallback (work-iters-omit-the-release-vehicle-seed-on-open-known-error-so-the-post-release-k-v-auto-enumerator-silently-skips-them-problem): body has no changeset reference — recover via co-commit ─
|
|
110
110
|
# An iter that fixes a Known Error sometimes ships the fix + changeset but omits
|
|
111
|
-
# the
|
|
111
|
+
# the derive-release-vehicle-helper-requires-pre-edit-of-ticket-changeset-reference-three-touch-when-one-touch-would-suffice-problem `**Release vehicle**` seed, leaving the ticket body with no
|
|
112
112
|
# `.changeset/` reference. derive would exit 2 and the post-release K→V
|
|
113
|
-
# enumerator (
|
|
114
|
-
#
|
|
113
|
+
# enumerator (known-error-md-verifying-md-transition-not-happening-consistently-at-release-time-problem) silently skips the ticket even though its fix shipped. Under
|
|
114
|
+
# governance-skills-commit-their-own-completed-work-architecture-rule's one-commit grain the fix commit that authored the changeset also
|
|
115
115
|
# edited this ticket, so a `.changeset/*.md` ADDED by a commit that also touched
|
|
116
116
|
# the ticket file is this ticket's release vehicle. Walk the ticket's commits
|
|
117
117
|
# (newest first, across state renames) and take the first co-committed changeset.
|
|
118
|
-
# ponytail: co-commit join. False negative — the
|
|
119
|
-
# on an earlier commit that did NOT touch the ticket) still needs the manual
|
|
118
|
+
# ponytail: co-commit join. False negative — the afk-iter-packages-plugin-commits-without-changesets-orchestrator-main-turn-back-fill-is-fragile-recovery-hook-level-enforcement-preferable-problem multi-slice case (changeset
|
|
119
|
+
# on an earlier commit that did NOT touch the ticket) still needs the manual derive-release-vehicle-helper-requires-pre-edit-of-ticket-changeset-reference-three-touch-when-one-touch-would-suffice-problem
|
|
120
120
|
# seed. False positive — a later commit touching the ticket AND adding an
|
|
121
121
|
# unrelated changeset would be picked first; acceptable for a mechanical fallback.
|
|
122
122
|
if [ -z "$CHANGESET_PATH" ]; then
|
|
@@ -133,7 +133,7 @@ if [ -z "$CHANGESET_PATH" ]; then
|
|
|
133
133
|
fi
|
|
134
134
|
|
|
135
135
|
if [ -z "$CHANGESET_PATH" ]; then
|
|
136
|
-
echo "ERROR: no .changeset/<name>.md reference in $TICKET_FILE (and no co-committed changeset in ticket history —
|
|
136
|
+
echo "ERROR: no .changeset/<name>.md reference in $TICKET_FILE (and no co-committed changeset in ticket history — work-iters-omit-the-release-vehicle-seed-on-open-known-error-so-the-post-release-k-v-auto-enumerator-silently-skips-them-problem)" >&2
|
|
137
137
|
exit 2
|
|
138
138
|
fi
|
|
139
139
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# wr-itil — detect RFCs lacking the human-oversight marker (
|
|
2
|
+
# wr-itil — detect RFCs lacking the human-oversight marker (rfc-lifecycle-is-not-self-maintaining-it-leans-on-human-memory-problem/rfc-lifecycle-self-maintenance-release-design).
|
|
3
3
|
#
|
|
4
|
-
# Clone of the architect/jtbd detect-unoversighted shape (
|
|
4
|
+
# Clone of the architect/jtbd detect-unoversighted shape (human-oversight-marker-wr-architect-review-decisions-drain-for-recorded-decisions-architecture-rule/068): greps
|
|
5
5
|
# each RFC's YAML frontmatter for `human-oversight: confirmed`. No body reads,
|
|
6
6
|
# no per-RFC LLM call. An RFC is "unoversighted" when its frontmatter does not
|
|
7
7
|
# carry that marker line (RFCs are born `human-oversight: unconfirmed` at
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
# confirmed. Always exits 0 (detector, not a gate).
|
|
15
15
|
#
|
|
16
16
|
# Consumed by: itil-rfc-oversight-nudge.sh (SessionStart count). Marker
|
|
17
|
-
# contract:
|
|
17
|
+
# contract: human-oversight-marker-wr-architect-review-decisions-drain-for-recorded-decisions-architecture-rule (human-oversight marker), as extended to RFCs by rfcs-hold-no-independent-decisions-architecture-rule/071.
|
|
18
18
|
|
|
19
19
|
set -euo pipefail
|
|
20
20
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# detect-unratified-stories-maps.sh —
|
|
2
|
+
# detect-unratified-stories-maps.sh — story-maps-and-stories-carry-a-drift-invalidated-human-oversight-marker-architecture-rule detector.
|
|
3
3
|
#
|
|
4
4
|
# Token-cheap detection of story maps that are NOT ratified, plus the stories
|
|
5
5
|
# those maps leave unapproved. Mirrors wr-architect detect-unoversighted.sh.
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
# - drift-reopened (marker says confirmed, but substance changed → mismatch)
|
|
12
12
|
# - legacy confirmed (confirmed but no fingerprint yet — needs one re-ratify)
|
|
13
13
|
#
|
|
14
|
-
# A STORY carries no marker at all (
|
|
14
|
+
# A STORY carries no marker at all (a-release-row-is-the-rfc-and-the-map-is-the-approval-surface-architecture-rule). It is listed when any map in its
|
|
15
15
|
# `story-maps:` field is unratified, or when it names no map — and the remedy is
|
|
16
16
|
# always to ratify the map, never the story.
|
|
17
17
|
#
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
# oversight-unconfirmed drain.
|
|
22
22
|
set -euo pipefail
|
|
23
23
|
|
|
24
|
-
# Adopter-safe: source the shared hash lib RELATIVE TO THIS SCRIPT (
|
|
24
|
+
# Adopter-safe: source the shared hash lib RELATIVE TO THIS SCRIPT (capture-problem-capture-rfc-manage-problem-step-2-create-gate-marker-step-sources-repo-relative-packages-itil-hooks-lib-sh-fails-in-adopter-installs-recurring-published-path-class-problem).
|
|
25
25
|
LIB="$(cd "$(dirname "${BASH_SOURCE[0]}")/../lib" 2>/dev/null && pwd)" || {
|
|
26
26
|
echo "detect-unratified-stories-maps: cannot locate lib dir" >&2; exit 0; }
|
|
27
27
|
# shellcheck source=/dev/null
|
|
@@ -36,9 +36,9 @@ shopt -s nullglob
|
|
|
36
36
|
if [ -d "$STORIES_DIR" ]; then
|
|
37
37
|
for f in "$STORIES_DIR"/*.md "$STORIES_DIR"/*/*.md; do
|
|
38
38
|
[ "$(basename "$f")" = "README.md" ] && continue
|
|
39
|
-
#
|
|
39
|
+
# a-release-row-is-the-rfc-and-the-map-is-the-approval-surface-architecture-rule: a story's approval may be its MAP's. Using the map predicate
|
|
40
40
|
# here would report every story as unratified — stories carry no marker at
|
|
41
|
-
# all — and send the drain to ratify a surface
|
|
41
|
+
# all — and send the drain to ratify a surface a-release-row-is-the-rfc-and-the-map-is-the-approval-surface-architecture-rule removed.
|
|
42
42
|
story_is_approved "$f" "$MAPS_DIR" || echo "$f"
|
|
43
43
|
done
|
|
44
44
|
fi
|