@windyroad/itil 0.55.5-preview.850 → 0.56.0-preview.876
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.
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Generated by scripts/sync-shim-wrappers.sh from
|
|
3
|
+
# packages/shared/lib/shim-wrapper-template.sh. DO NOT EDIT individual
|
|
4
|
+
# shim files in packages/*/bin/wr-* directly; edit the template + run
|
|
5
|
+
# `npm run sync:shim-wrappers` to regenerate.
|
|
6
|
+
#
|
|
7
|
+
# Resolution (ADR-080):
|
|
8
|
+
# 1. If the wrapper's parent dir is semver-shaped, treat as installed-
|
|
9
|
+
# cache execution and resolve to the highest-version sibling's
|
|
10
|
+
# scripts/ entry below.
|
|
11
|
+
# 2. Otherwise (parent dir is e.g. `architect`), treat as source-
|
|
12
|
+
# monorepo execution and dispatch to own scripts/. The source-repo-
|
|
13
|
+
# guard `exec` is the anchor parsed by
|
|
14
|
+
# packages/retrospective/scripts/check-tarball-shipped-shims.sh.
|
|
15
|
+
# 3. If the cache parent contains zero semver-shaped siblings, exit
|
|
16
|
+
# 127 with a stderr message naming the cache parent (per SQ-080-2).
|
|
17
|
+
#
|
|
18
|
+
# @adr ADR-080 (highest-version-wins shim wrapper plugin scaffold)
|
|
19
|
+
# @adr ADR-049 (plugin-bundled scripts resolve via bin/ on $PATH — amended)
|
|
20
|
+
# @problem P343 (mid-session staleness window)
|
|
21
|
+
|
|
22
|
+
set -euo pipefail
|
|
23
|
+
|
|
24
|
+
SHIM_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
25
|
+
OWN_VERSION_DIR="$(dirname "$SHIM_DIR")"
|
|
26
|
+
OWN_VERSION_NAME="$(basename "$OWN_VERSION_DIR")"
|
|
27
|
+
CACHE_PARENT="$(dirname "$OWN_VERSION_DIR")"
|
|
28
|
+
|
|
29
|
+
SEMVER_RE='^[0-9]+\.[0-9]+\.[0-9]+([-+][0-9A-Za-z.-]+)?$'
|
|
30
|
+
|
|
31
|
+
# Source-repo guard: own parent dir is NOT semver → dispatch to own scripts/.
|
|
32
|
+
if ! [[ "$OWN_VERSION_NAME" =~ $SEMVER_RE ]]; then
|
|
33
|
+
exec "$SHIM_DIR/../scripts/check-rfc-has-stories.sh" "$@"
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
# Cache execution: pick the highest-semver sibling under CACHE_PARENT.
|
|
37
|
+
HIGHEST=""
|
|
38
|
+
while IFS= read -r dir; do
|
|
39
|
+
name="$(basename "$dir")"
|
|
40
|
+
[[ "$name" =~ $SEMVER_RE ]] || continue
|
|
41
|
+
if [[ -z "$HIGHEST" ]] || [[ "$(printf '%s\n%s\n' "$HIGHEST" "$name" | sort -V | tail -1)" == "$name" ]]; then
|
|
42
|
+
HIGHEST="$name"
|
|
43
|
+
fi
|
|
44
|
+
done < <(find "$CACHE_PARENT" -mindepth 1 -maxdepth 1 -type d 2>/dev/null)
|
|
45
|
+
|
|
46
|
+
if [[ -z "$HIGHEST" ]]; then
|
|
47
|
+
printf 'wr-shim: no cached versions in %s\n' "$CACHE_PARENT" >&2
|
|
48
|
+
exit 127
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
exec "$CACHE_PARENT/$HIGHEST/scripts/check-rfc-has-stories.sh" "$@"
|
package/package.json
CHANGED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# check-rfc-has-stories.sh — ADR-089 (every RFC has at least one story).
|
|
3
|
+
#
|
|
4
|
+
# The load-bearing detection half of the manage-rfc `proposed -> accepted` gate:
|
|
5
|
+
# an RFC must list >=1 story before it can be accepted. Exits non-zero (with a
|
|
6
|
+
# stderr directive) when the RFC's `stories:` frontmatter is empty (`stories: []`)
|
|
7
|
+
# or missing; exits 0 when >=1 `STORY-NNN` is listed (inline or block-list).
|
|
8
|
+
#
|
|
9
|
+
# This removes the pre-ADR-089 empty-stories fallback (the "atomic RFC ships with
|
|
10
|
+
# stories: [] / JTBD-101 friction guard" shape). An atomic fix is now an RFC with
|
|
11
|
+
# exactly one full story, never an empty list.
|
|
12
|
+
#
|
|
13
|
+
# Usage: check-rfc-has-stories.sh <rfc-file>
|
|
14
|
+
# Exit: 0 = >=1 story; 1 = empty/missing stories; 2 = usage / file error.
|
|
15
|
+
#
|
|
16
|
+
# Authority: ADR-089. Driver: P404. Behavioural test: check-rfc-has-stories.bats.
|
|
17
|
+
set -euo pipefail
|
|
18
|
+
|
|
19
|
+
rfc="${1:-}"
|
|
20
|
+
if [ -z "$rfc" ]; then
|
|
21
|
+
echo "check-rfc-has-stories: usage: check-rfc-has-stories.sh <rfc-file>" >&2
|
|
22
|
+
exit 2
|
|
23
|
+
fi
|
|
24
|
+
if [ ! -f "$rfc" ]; then
|
|
25
|
+
echo "check-rfc-has-stories: file not found: $rfc" >&2
|
|
26
|
+
exit 2
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
# The frontmatter `stories:` line (first match; frontmatter is at the top).
|
|
30
|
+
stories_line="$(awk '/^stories:/{print; exit}' "$rfc")"
|
|
31
|
+
|
|
32
|
+
if [ -z "$stories_line" ]; then
|
|
33
|
+
echo "check-rfc-has-stories: $rfc has no 'stories:' field — an RFC must list >=1 story (ADR-089). Decompose the fix into >=1 story before accepting." >&2
|
|
34
|
+
exit 1
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
# Reject an explicit empty inline list: `stories: []`.
|
|
38
|
+
if printf '%s' "$stories_line" | grep -qE '^stories:[[:space:]]*\[[[:space:]]*\][[:space:]]*$'; then
|
|
39
|
+
echo "check-rfc-has-stories: $rfc has empty 'stories: []' — an RFC must list >=1 story (ADR-089; the empty-stories fallback is removed). An atomic fix is an RFC with exactly one full story." >&2
|
|
40
|
+
exit 1
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
# Accept if a STORY-id appears inline on the stories: line.
|
|
44
|
+
if printf '%s' "$stories_line" | grep -qE 'STORY-[0-9]'; then
|
|
45
|
+
exit 0
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
# Accept if a YAML block-list under stories: carries >=1 STORY-id.
|
|
49
|
+
if awk '
|
|
50
|
+
/^stories:/ { inblock=1; next }
|
|
51
|
+
inblock && /^[[:space:]]*-[[:space:]]*STORY-[0-9]/ { found=1 }
|
|
52
|
+
inblock && /^[^[:space:]-]/ { exit }
|
|
53
|
+
END { exit !found }
|
|
54
|
+
' "$rfc"; then
|
|
55
|
+
exit 0
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
echo "check-rfc-has-stories: $rfc 'stories:' lists no STORY- ids — an RFC must list >=1 story (ADR-089)." >&2
|
|
59
|
+
exit 1
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env bats
|
|
2
|
+
# Behavioural test for check-rfc-has-stories.sh (ADR-089 — every RFC has >=1 story).
|
|
3
|
+
# The predicate exits non-zero when an RFC's `stories:` frontmatter is empty or
|
|
4
|
+
# missing (the empty-stories fallback ADR-089 removes); exit 0 when >=1 story is
|
|
5
|
+
# listed. This is the load-bearing detection half of the proposed->accepted gate.
|
|
6
|
+
#
|
|
7
|
+
# @adr ADR-089 (every RFC has at least one story)
|
|
8
|
+
# @problem P404 (implement ADR-089 + ADR-090)
|
|
9
|
+
|
|
10
|
+
setup() {
|
|
11
|
+
REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/../../../.." && pwd)"
|
|
12
|
+
SCRIPT="${REPO_ROOT}/packages/itil/scripts/check-rfc-has-stories.sh"
|
|
13
|
+
TMPD="$(mktemp -d)"
|
|
14
|
+
}
|
|
15
|
+
teardown() { rm -rf "$TMPD"; }
|
|
16
|
+
|
|
17
|
+
@test "check-rfc-has-stories: empty stories: [] is REJECTED (exit non-zero + directive)" {
|
|
18
|
+
cat > "$TMPD/RFC-901-empty.proposed.md" <<'EOF'
|
|
19
|
+
---
|
|
20
|
+
status: proposed
|
|
21
|
+
problems: [P170]
|
|
22
|
+
stories: []
|
|
23
|
+
---
|
|
24
|
+
# RFC-901: empty
|
|
25
|
+
EOF
|
|
26
|
+
run bash "$SCRIPT" "$TMPD/RFC-901-empty.proposed.md"
|
|
27
|
+
[ "$status" -ne 0 ]
|
|
28
|
+
[[ "$output" == *"stories"* ]]
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@test "check-rfc-has-stories: missing stories: field is REJECTED" {
|
|
32
|
+
cat > "$TMPD/RFC-902-none.proposed.md" <<'EOF'
|
|
33
|
+
---
|
|
34
|
+
status: proposed
|
|
35
|
+
problems: [P170]
|
|
36
|
+
---
|
|
37
|
+
# RFC-902: no stories field
|
|
38
|
+
EOF
|
|
39
|
+
run bash "$SCRIPT" "$TMPD/RFC-902-none.proposed.md"
|
|
40
|
+
[ "$status" -ne 0 ]
|
|
41
|
+
[[ "$output" == *"stories"* ]]
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@test "check-rfc-has-stories: inline >=1 story is ACCEPTED (exit 0)" {
|
|
45
|
+
cat > "$TMPD/RFC-903-ok.proposed.md" <<'EOF'
|
|
46
|
+
---
|
|
47
|
+
status: proposed
|
|
48
|
+
problems: [P170]
|
|
49
|
+
stories: [STORY-020, STORY-021]
|
|
50
|
+
---
|
|
51
|
+
# RFC-903: has stories
|
|
52
|
+
EOF
|
|
53
|
+
run bash "$SCRIPT" "$TMPD/RFC-903-ok.proposed.md"
|
|
54
|
+
[ "$status" -eq 0 ]
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@test "check-rfc-has-stories: block-list >=1 story is ACCEPTED (exit 0)" {
|
|
58
|
+
cat > "$TMPD/RFC-904-block.proposed.md" <<'EOF'
|
|
59
|
+
---
|
|
60
|
+
status: proposed
|
|
61
|
+
problems: [P170]
|
|
62
|
+
stories:
|
|
63
|
+
- STORY-020
|
|
64
|
+
---
|
|
65
|
+
# RFC-904: block-list stories
|
|
66
|
+
EOF
|
|
67
|
+
run bash "$SCRIPT" "$TMPD/RFC-904-block.proposed.md"
|
|
68
|
+
[ "$status" -eq 0 ]
|
|
69
|
+
}
|
|
@@ -118,7 +118,7 @@ Each transition is a `git mv` + Edit + `git add` (P057 staging trap) + README re
|
|
|
118
118
|
|
|
119
119
|
| Transition | Checks |
|
|
120
120
|
|------------|--------|
|
|
121
|
-
| `proposed → accepted` | All `problems:` entries resolve. Architect re-review PASS. JTBD re-review PASS. `## Scope` populated (not "deferred"). `## Tasks` decomposed (≥ 1 task; not just deferred placeholder). |
|
|
121
|
+
| `proposed → accepted` | All `problems:` entries resolve. Architect re-review PASS. JTBD re-review PASS. `## Scope` populated (not "deferred"). `## Tasks` decomposed (≥ 1 task; not just deferred placeholder). **`stories:` non-empty — run `wr-itil-check-rfc-has-stories <rfc-file>`; hard-block on non-zero exit (empty `stories: []` or missing).** Per **ADR-089** the empty-stories fallback is removed: an atomic fix is an RFC with exactly one full story; an empty `stories:` is permitted only on a `proposed`/draft RFC before the fix is scoped, never at `accepted`. |
|
|
122
122
|
| `accepted → in-progress` | First commit referencing `Refs: RFC-<NNN>` exists OR is being authored in this same commit. I1 hard-block on missing/orphan trace. |
|
|
123
123
|
| `in-progress → verifying` | All `## Tasks` checked. `## Verification` section drafted (release marker, user-side check, trace closure path). I1 hard-block on missing/orphan trace. |
|
|
124
124
|
| `verifying → closed` | User explicitly confirms (or AFK Rule 6 fallback for evidence-based close per ADR-022 / ADR-044 framework-resolved silent dispatch). I1 advisory-with-escalation if driving problems Closed/Parked. |
|