@windyroad/itil 0.7.2 → 0.8.0-preview.133
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/package.json
CHANGED
|
@@ -47,6 +47,8 @@ To un-park: `git mv` back to `.open.md` (or `.known-error.md` if root cause is c
|
|
|
47
47
|
|
|
48
48
|
**Verification Pending problems** are also excluded from WSJF ranking — their remaining work is user-side verification, not dev effort. They appear in a dedicated "Verification Queue" section in review output so the user can see what's waiting on them without mixing with dev-work ranking. See step 9c for the queue layout.
|
|
49
49
|
|
|
50
|
+
**Allowed optional appendages**: a problem ticket file may carry a `## Reported Upstream` section appended after the standard sections. This is written by the `/wr-itil:report-upstream` skill (per ADR-024 Confirmation criterion 3a) and records the upstream issue or advisory URL, the matched template, and the disclosure path. The presence or absence of this section does not affect WSJF ranking or status transitions.
|
|
51
|
+
|
|
50
52
|
**Test-driven resolution:** When root cause is identified, create a failing test that reproduces the problem. Skip/disable the test if a feature-disabling workaround is applied. Re-enable the test when the permanent fix is implemented — the test passing confirms resolution.
|
|
51
53
|
|
|
52
54
|
## WSJF Prioritisation
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wr-itil:report-upstream
|
|
3
|
+
description: Report a local problem ticket as a structured issue against an upstream repository, with bidirectional cross-references and SECURITY.md-aware routing for security-classified tickets. Implements the contract in ADR-024.
|
|
4
|
+
allowed-tools: Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Report Upstream — Cross-Project Problem-Reporting Skill
|
|
8
|
+
|
|
9
|
+
File a local `docs/problems/<NNN>` ticket as an issue (or private security advisory) against an upstream repository. Discover upstream issue templates, fall through to a structured default when none exist, route security-classified tickets via the upstream's `SECURITY.md`, and back-write a cross-reference into the local ticket.
|
|
10
|
+
|
|
11
|
+
This skill implements the contract documented in [ADR-024](../../../docs/decisions/024-cross-project-problem-reporting-contract.proposed.md) (Cross-project problem-reporting contract). All step numbering below maps 1:1 to ADR-024 Decision Outcome.
|
|
12
|
+
|
|
13
|
+
## Invocation
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
/wr-itil:report-upstream <local-problem-id> <upstream-repo-url> [--severity <level>] [--classification <kind>] [--evidence-url <url>]
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
- `<local-problem-id>`: the `NNN` of the local ticket (e.g. `058`).
|
|
20
|
+
- `<upstream-repo-url>`: GitHub URL of the upstream repo (e.g. `https://github.com/anthropics/claude-code`).
|
|
21
|
+
- `--severity`: optional, overrides the local ticket's severity inference.
|
|
22
|
+
- `--classification`: optional, one of `bug`, `feature`, `question`, `security`. Inferred when absent.
|
|
23
|
+
- `--evidence-url`: optional, an external link (transcript, screenshot, gist) to include in the report.
|
|
24
|
+
|
|
25
|
+
## Step-0 deferral (ADR-027)
|
|
26
|
+
|
|
27
|
+
This skill **does NOT** implement ADR-027's Step-0 auto-delegation pattern. Per ADR-027 Scope, `report-upstream` is held for reassessment with the explicit note: *"narrow workflow; decided at implementation time for that skill"*. Reasons for deferring Step-0 here:
|
|
28
|
+
|
|
29
|
+
- The skill's main-agent context is the right place to read the local ticket, evaluate the security-path branch, and surface the missing-`SECURITY.md` `AskUserQuestion` to the user. Wrapping the flow in a subagent adds a hop without reducing main-agent context cost (the local ticket and ADR-024 contract still need to be in main-agent context for the user's interactive decisions).
|
|
30
|
+
- The interactive `AskUserQuestion` for the missing-SECURITY.md case (Step 6 below) is a per-decision turn the user owns; a subagent would have to bubble it back up anyway.
|
|
31
|
+
- The skill's footprint is small (one local doc edit + one or two `gh` API calls per invocation).
|
|
32
|
+
|
|
33
|
+
**Trigger to revisit**: if a second skill that reads upstream repo content lands (per ADR-024's Reassessment Criteria), reconsider whether the cross-cutting "read upstream" pattern should move into a Step-0-delegated subagent that this skill calls.
|
|
34
|
+
|
|
35
|
+
## Voice-tone gate interaction (ADR-028)
|
|
36
|
+
|
|
37
|
+
The skill's `gh issue create` (Step 5) and `gh api repos/.../security-advisories` (Step 6) calls are **on the gated surface list per [ADR-028](../../../docs/decisions/028-voice-tone-gate-external-comms.proposed.md)** (Voice-tone gate on external communications). Expected behaviour during these tool calls:
|
|
38
|
+
|
|
39
|
+
1. The voice-tone gate fires `PreToolUse:Bash` with a deny-plus-delegate response.
|
|
40
|
+
2. The hook delegates to `wr-voice-tone:agent` to review the drafted body for brand-voice + tone alignment against `docs/VOICE-AND-TONE.md`.
|
|
41
|
+
3. Once the agent's marker lands, the same `gh issue create` or `gh api` call retries and proceeds.
|
|
42
|
+
|
|
43
|
+
The skill should treat this transient deny-plus-delegate as the expected path, not as an error. The voice-tone agent's review covers only the prose body of the upstream report (issue body, advisory body); structural fields (template field IDs, plugin name, version) are not in voice-tone scope.
|
|
44
|
+
|
|
45
|
+
If `wr-voice-tone:agent` is not installed in the project, the gate is dormant and the skill proceeds without delegation.
|
|
46
|
+
|
|
47
|
+
## Steps
|
|
48
|
+
|
|
49
|
+
### 1. Read the local problem ticket
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
LOCAL_TICKET=$(ls docs/problems/${LOCAL_ID}-*.{open,known-error,verifying,closed}.md 2>/dev/null | head -1)
|
|
53
|
+
[ -n "$LOCAL_TICKET" ] || { echo "Error: local ticket P${LOCAL_ID} not found in docs/problems/"; exit 1; }
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Extract:
|
|
57
|
+
- Title (from H1).
|
|
58
|
+
- Status (from frontmatter Status field — Open / Known Error / Verification Pending / Closed).
|
|
59
|
+
- Description, Symptoms, Workaround, Impact Assessment, Root Cause Analysis sections.
|
|
60
|
+
- Priority and severity classification (look for a `security` label or a `## Security classification` section — see Step 4).
|
|
61
|
+
|
|
62
|
+
If the ticket is not found, halt with a clear error: `Error: local ticket P<NNN> not found in docs/problems/. Did you mean a different ID?`
|
|
63
|
+
|
|
64
|
+
### 2. Discover upstream issue templates
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
UPSTREAM_OWNER_REPO=$(echo "$UPSTREAM_URL" | sed -E 's|https?://github.com/([^/]+/[^/]+)(/.*)?|\1|')
|
|
68
|
+
TEMPLATES_JSON=$(gh api "repos/${UPSTREAM_OWNER_REPO}/contents/.github/ISSUE_TEMPLATE" 2>/dev/null)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Parse the response:
|
|
72
|
+
- HTTP 200 with a JSON array → upstream has templates. List the names + types (`.yml` for forms, `.md` for legacy markdown templates).
|
|
73
|
+
- HTTP 404 → upstream has no `.github/ISSUE_TEMPLATE/` directory; treat as no-templates (proceed to structured default in Step 5).
|
|
74
|
+
- Other HTTP error (rate-limit, network) → halt with a clear error and the response body so the user can retry.
|
|
75
|
+
|
|
76
|
+
For each `.yml` template found, fetch the file via `gh api repos/<owner>/<repo>/contents/.github/ISSUE_TEMPLATE/<filename>` and parse the `name:` frontmatter field plus the `body:` field-IDs that have `validations.required: true`.
|
|
77
|
+
|
|
78
|
+
### 3. Classify the local ticket and pick the best-matching template
|
|
79
|
+
|
|
80
|
+
Heuristic:
|
|
81
|
+
- Local ticket title contains `bug`, `defect`, `crash`, `error`, `fails to`, `broken`, `regression` → classify as `bug`.
|
|
82
|
+
- Local ticket title contains `feature`, `add`, `support for`, `would be nice`, `enhancement` → classify as `feature`.
|
|
83
|
+
- Local ticket title is a question → classify as `question`.
|
|
84
|
+
- The CLI `--classification` argument overrides the heuristic.
|
|
85
|
+
|
|
86
|
+
Pick the upstream template whose `name:` (or filename) most closely matches the classification:
|
|
87
|
+
- For `bug`: prefer `bug-report.yml`, `bug.yml`, `bug-report.md`, `bug.md`.
|
|
88
|
+
- For `feature`: prefer `feature-request.yml`, `feature.yml`, `feature-request.md`.
|
|
89
|
+
- For `question`: prefer `question.yml`, `question.md`. If absent, the upstream's `config.yml` likely routes questions elsewhere (Discussions); halt and surface the routing target.
|
|
90
|
+
|
|
91
|
+
Log the matched template name in the Step 7 back-write. If no template matches the classification, fall through to the structured default in Step 5.
|
|
92
|
+
|
|
93
|
+
### 4. Security-path routing check
|
|
94
|
+
|
|
95
|
+
The local ticket is **security-classified** if any of:
|
|
96
|
+
- Its title contains `security`, `vulnerability`, `CVE`, `disclosure`, `RCE`, `injection`, `XSS`, or `auth bypass`.
|
|
97
|
+
- Its frontmatter `Priority:` line contains a `security` label.
|
|
98
|
+
- The ticket body has a `## Security classification` section.
|
|
99
|
+
- The CLI `--classification security` argument was passed.
|
|
100
|
+
|
|
101
|
+
If security-classified, route to Step 6. Otherwise, route to Step 5 (public-issue path).
|
|
102
|
+
|
|
103
|
+
### 5. Public-issue path
|
|
104
|
+
|
|
105
|
+
If the upstream had a matching template (Step 3), fill its required fields from the local ticket:
|
|
106
|
+
|
|
107
|
+
| Upstream template field (typical) | Local ticket source |
|
|
108
|
+
|---|---|
|
|
109
|
+
| `plugin` / `package` / `module` | Inferred from upstream repo name or local ticket's "Affected plugin" section |
|
|
110
|
+
| `version` | Local ticket's environment notes; or `npm view <pkg> version` for the latest if ambiguous |
|
|
111
|
+
| `claude-code-version` | `claude --version` if the report originates from a Claude Code session |
|
|
112
|
+
| `os` | Local ticket's environment notes; or `uname -srm` of the reporting host |
|
|
113
|
+
| `reproduction` | Local ticket's `## Symptoms` section |
|
|
114
|
+
| `expected` | Local ticket's "expected behaviour" line under `## Description` |
|
|
115
|
+
| `actual` | Local ticket's "actual behaviour" line under `## Description` |
|
|
116
|
+
|
|
117
|
+
If no template matches, emit the **structured default** body:
|
|
118
|
+
|
|
119
|
+
```markdown
|
|
120
|
+
## Summary
|
|
121
|
+
|
|
122
|
+
<one-paragraph synthesis of the local ticket's Description>
|
|
123
|
+
|
|
124
|
+
## Steps to reproduce
|
|
125
|
+
|
|
126
|
+
<bullet list or numbered steps from local ticket's Symptoms>
|
|
127
|
+
|
|
128
|
+
## Expected behaviour
|
|
129
|
+
|
|
130
|
+
<from local ticket>
|
|
131
|
+
|
|
132
|
+
## Actual behaviour
|
|
133
|
+
|
|
134
|
+
<from local ticket>
|
|
135
|
+
|
|
136
|
+
## Environment
|
|
137
|
+
|
|
138
|
+
- Package: <inferred from upstream repo>
|
|
139
|
+
- Version: <detected via npm ls or local ticket's notes>
|
|
140
|
+
- Claude Code version: <claude --version>
|
|
141
|
+
- OS: <uname -srm>
|
|
142
|
+
|
|
143
|
+
## Cross-reference
|
|
144
|
+
|
|
145
|
+
Reported from <downstream-repo-url>/<local-ticket-relative-path>
|
|
146
|
+
|
|
147
|
+
This issue is tracked locally as P<NNN> in the downstream project's `docs/problems/` directory.
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Open the issue:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
gh issue create \
|
|
154
|
+
--repo "${UPSTREAM_OWNER_REPO}" \
|
|
155
|
+
--title "${TITLE_PREFIXED_BY_TEMPLATE}" \
|
|
156
|
+
--body "${FILLED_BODY}" \
|
|
157
|
+
--label "${MATCHED_TEMPLATE_LABEL_IF_ANY}"
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Capture the returned issue URL. The voice-tone gate per ADR-028 may delegate-and-retry; treat this as expected (see "Voice-tone gate interaction" above). Proceed to Step 7 once the issue is created.
|
|
161
|
+
|
|
162
|
+
### 6. Security path
|
|
163
|
+
|
|
164
|
+
Fetch the upstream's `SECURITY.md`:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
SECURITY_MD=$(gh api "repos/${UPSTREAM_OWNER_REPO}/contents/SECURITY.md" --jq '.content' 2>/dev/null | base64 -d)
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Parse for a disclosure channel:
|
|
171
|
+
|
|
172
|
+
- **GitHub Security Advisories** (most common — link looks like `github.com/<owner>/<repo>/security/advisories/new` or the body says "use Security Advisories"):
|
|
173
|
+
```bash
|
|
174
|
+
gh api "repos/${UPSTREAM_OWNER_REPO}/security-advisories" --method POST \
|
|
175
|
+
--input - <<EOF
|
|
176
|
+
{
|
|
177
|
+
"summary": "${TITLE}",
|
|
178
|
+
"description": "${STRUCTURED_BODY}",
|
|
179
|
+
"severity": "${SEVERITY}",
|
|
180
|
+
"vulnerabilities": []
|
|
181
|
+
}
|
|
182
|
+
EOF
|
|
183
|
+
```
|
|
184
|
+
- **`security@` mailbox** (or any `mailto:` link): **halt** and surface the mailbox + drafted report to the user. Do NOT auto-send email — out of scope, no infra. Save the drafted report to `docs/problems/<NNN>-<title>.<status>.md`'s `## Drafted Upstream Report` appendage section so the user can copy + send.
|
|
185
|
+
- **Other documented channel** (Tidelift, HackerOne, vendor-specific URL): halt and surface the channel + drafted report.
|
|
186
|
+
|
|
187
|
+
If upstream has **NO `SECURITY.md`** (404):
|
|
188
|
+
- **Interactive context**: use `AskUserQuestion` per ADR-013 Rule 1 with options:
|
|
189
|
+
- `(a) Open a private GitHub Security Advisory` — uses `gh api repos/.../security-advisories` against the upstream if it's GitHub-hosted.
|
|
190
|
+
- `(b) Contact the maintainer out-of-band first` — halt, no automated action.
|
|
191
|
+
- `(c) Downgrade the classification (your judgement)` — re-route via the public-issue path in Step 5.
|
|
192
|
+
- **AFK / non-interactive context**: do NOT auto-resolve. Save the drafted report to the local ticket's `## Drafted Upstream Report` section and **halt the orchestrator** — this is a loop-stopping event per ADR-024 Consequences. AFK orchestrators must never auto-report a security-classified ticket.
|
|
193
|
+
|
|
194
|
+
**Never auto-open a public issue for a security-classified ticket.**
|
|
195
|
+
|
|
196
|
+
### 7. Cross-reference back-write
|
|
197
|
+
|
|
198
|
+
After the upstream issue or advisory is created (or drafted-and-saved in the security-path halt cases), append two things to the local ticket:
|
|
199
|
+
|
|
200
|
+
1. To the existing `## Related` section (or create one if absent):
|
|
201
|
+
```markdown
|
|
202
|
+
- **Reported upstream**: <upstream-issue-or-advisory-url> (<YYYY-MM-DD>)
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
2. A new `## Reported Upstream` section appended after the existing sections (never inserted mid-document — preserve existing structure):
|
|
206
|
+
```markdown
|
|
207
|
+
## Reported Upstream
|
|
208
|
+
|
|
209
|
+
- **URL**: <upstream-issue-or-advisory-url>
|
|
210
|
+
- **Reported**: <YYYY-MM-DD>
|
|
211
|
+
- **Template used**: <template-name-or-"structured default">
|
|
212
|
+
- **Disclosure path**: <public issue | security advisory | drafted-and-saved (mailbox / out-of-band)>
|
|
213
|
+
- **Cross-reference confirmed**: <yes/no — true once the upstream issue body contains the local ticket reference>
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### 8. Commit per ADR-014
|
|
217
|
+
|
|
218
|
+
Follow the ADR-014 ordering:
|
|
219
|
+
|
|
220
|
+
1. `git add docs/problems/<NNN>-<title>.<status>.md` (and any `## Drafted Upstream Report` appendage if security-path halt fired).
|
|
221
|
+
2. Score commit/push/release risk via `wr-risk-scorer:pipeline` subagent (or fall back to `/wr-risk-scorer:assess-release` skill per ADR-015).
|
|
222
|
+
3. `git commit -m "docs(problems): P<NNN> reported upstream — <one-line summary>"`.
|
|
223
|
+
|
|
224
|
+
If the cumulative pipeline risk lands above appetite and `AskUserQuestion` is unavailable, apply the [ADR-013 Rule 6](../../../docs/decisions/013-structured-user-interaction-for-governance-decisions.proposed.md) non-interactive fail-safe: skip the commit and report the uncommitted state. Do NOT auto-commit above appetite without the user's call.
|
|
225
|
+
|
|
226
|
+
## AFK behaviour summary
|
|
227
|
+
|
|
228
|
+
Three distinct AFK branches per the architect review of ADR-024 + ADR-013 Rule 6:
|
|
229
|
+
|
|
230
|
+
| Branch | AFK behaviour | Authority |
|
|
231
|
+
|---|---|---|
|
|
232
|
+
| Public-issue path (Step 5) | Proceeds. Voice-tone gate per ADR-028 may delegate-and-retry; that is the expected extra turn. | ADR-028 line 126 |
|
|
233
|
+
| Security path with declared channel (Step 6, GitHub Advisories) | Proceeds via `gh api .../security-advisories`. | ADR-024 Decision Outcome step 6 |
|
|
234
|
+
| Security path with `security@` / other / missing-SECURITY.md (Step 6) | Save drafted report to local ticket's `## Drafted Upstream Report` section. **Halt the orchestrator** — loop-stopping event. AFK orchestrators must never auto-report a security-classified ticket. | ADR-024 Consequences lines 116, 123 |
|
|
235
|
+
| Above-appetite commit (Step 8) | Skip the commit, report uncommitted state. | ADR-013 Rule 6 |
|
|
236
|
+
|
|
237
|
+
## References
|
|
238
|
+
|
|
239
|
+
- [ADR-024](../../../docs/decisions/024-cross-project-problem-reporting-contract.proposed.md) — primary contract this skill implements.
|
|
240
|
+
- [ADR-027](../../../docs/decisions/027-governance-skill-auto-delegation.proposed.md) — Step-0 deferral rationale (held for reassessment).
|
|
241
|
+
- [ADR-028](../../../docs/decisions/028-voice-tone-gate-external-comms.proposed.md) — voice-tone gate on `gh issue create` and `gh api .../security-advisories`.
|
|
242
|
+
- [ADR-013](../../../docs/decisions/013-structured-user-interaction-for-governance-decisions.proposed.md) — interaction policy; Rule 1 governs Step 6 missing-SECURITY.md `AskUserQuestion`; Rule 6 governs the commit-gate AFK branch.
|
|
243
|
+
- [ADR-014](../../../docs/decisions/014-governance-skills-commit-their-own-work.proposed.md) — work → score → commit ordering.
|
|
244
|
+
- [ADR-015](../../../docs/decisions/015-on-demand-assessment-skills.proposed.md) — fallback path for `wr-risk-scorer:assess-release`.
|
|
245
|
+
- [P055](../../../docs/problems/055-no-standard-problem-reporting-channel.open.md) — upstream problem ticket (Part B).
|
|
246
|
+
- `packages/itil/skills/manage-problem/SKILL.md` — names the optional `## Reported Upstream` section as an allowed appendage to a problem ticket.
|
|
247
|
+
|
|
248
|
+
$ARGUMENTS
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/usr/bin/env bats
|
|
2
|
+
|
|
3
|
+
# Doc-lint structural test (Permitted Exception per ADR-005 — structural
|
|
4
|
+
# SKILL.md content checks, not behavioural). Mirrors the doc-lint pattern
|
|
5
|
+
# established in ADR-011 and ADR-027 Confirmation tests.
|
|
6
|
+
#
|
|
7
|
+
# Asserts the report-upstream skill's SKILL.md encodes the contract
|
|
8
|
+
# documented in ADR-024 Confirmation criterion 2:
|
|
9
|
+
# - template discovery step
|
|
10
|
+
# - security-path routing with SECURITY.md fallback
|
|
11
|
+
# - explicit ban on auto-public-issue for security-classified tickets
|
|
12
|
+
# - cross-reference back-write step
|
|
13
|
+
# - ADR-024 cross-reference
|
|
14
|
+
#
|
|
15
|
+
# Plus two architect-required additions surfaced during P055 Part B
|
|
16
|
+
# implementation review:
|
|
17
|
+
# - ADR-027 Step-0 deferral rationale present
|
|
18
|
+
# - ADR-028 voice-tone gate interaction documented
|
|
19
|
+
|
|
20
|
+
setup() {
|
|
21
|
+
REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/../../../../.." && pwd)"
|
|
22
|
+
SKILL_MD="$REPO_ROOT/packages/itil/skills/report-upstream/SKILL.md"
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@test "report-upstream: SKILL.md exists" {
|
|
26
|
+
[ -f "$SKILL_MD" ]
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@test "report-upstream: SKILL.md documents template discovery via ISSUE_TEMPLATE (ADR-024 Confirmation 2.1)" {
|
|
30
|
+
run grep -F 'ISSUE_TEMPLATE' "$SKILL_MD"
|
|
31
|
+
[ "$status" -eq 0 ]
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@test "report-upstream: SKILL.md routes via SECURITY.md with explicit fallback (ADR-024 Confirmation 2.2)" {
|
|
35
|
+
run grep -ic 'SECURITY.md' "$SKILL_MD"
|
|
36
|
+
[ "$status" -eq 0 ]
|
|
37
|
+
[ "$output" -ge 2 ]
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@test "report-upstream: SKILL.md explicitly bans auto-opening a public issue for security-classified tickets (ADR-024 Confirmation 2.3)" {
|
|
41
|
+
run grep -iE 'never .*auto-open .*public issue' "$SKILL_MD"
|
|
42
|
+
[ "$status" -eq 0 ]
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@test "report-upstream: SKILL.md contains the cross-reference back-write step (ADR-024 Confirmation 2.4)" {
|
|
46
|
+
run grep -F '## Reported Upstream' "$SKILL_MD"
|
|
47
|
+
[ "$status" -eq 0 ]
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@test "report-upstream: SKILL.md cross-references ADR-024 (ADR-024 Confirmation 2.5)" {
|
|
51
|
+
run grep -F 'ADR-024' "$SKILL_MD"
|
|
52
|
+
[ "$status" -eq 0 ]
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@test "report-upstream: SKILL.md documents the ADR-027 Step-0 deferral rationale (architect review)" {
|
|
56
|
+
run grep -F 'ADR-027' "$SKILL_MD"
|
|
57
|
+
[ "$status" -eq 0 ]
|
|
58
|
+
run grep -iE 'step.?0 deferral|step.?0' "$SKILL_MD"
|
|
59
|
+
[ "$status" -eq 0 ]
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@test "report-upstream: SKILL.md documents the ADR-028 voice-tone gate interaction (architect review)" {
|
|
63
|
+
run grep -F 'ADR-028' "$SKILL_MD"
|
|
64
|
+
[ "$status" -eq 0 ]
|
|
65
|
+
run grep -iE 'voice-tone gate' "$SKILL_MD"
|
|
66
|
+
[ "$status" -eq 0 ]
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@test "report-upstream: SKILL.md encodes three distinct AFK branches (architect review)" {
|
|
70
|
+
# Public-issue path / Security path with declared channel / Security path
|
|
71
|
+
# halt-and-surface / Above-appetite commit. The "AFK behaviour summary"
|
|
72
|
+
# table is the canonical place; assert its presence.
|
|
73
|
+
run grep -F 'AFK behaviour summary' "$SKILL_MD"
|
|
74
|
+
[ "$status" -eq 0 ]
|
|
75
|
+
}
|