@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.
Files changed (266) hide show
  1. package/.agents/plugins/marketplace.json +12 -0
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.codex-plugin/plugin.json +42 -0
  4. package/README.md +34 -25
  5. package/agents/hang-off-check.md +34 -34
  6. package/bin/install.mjs +71 -5
  7. package/bin/wr-itil-catchup-scan +4 -4
  8. package/bin/wr-itil-check-deferred-placeholder-staleness +4 -4
  9. package/bin/wr-itil-check-fail-soft-skip-discipline +4 -4
  10. package/bin/wr-itil-check-fix-rfc-trace +4 -4
  11. package/bin/wr-itil-check-locale-discipline +4 -4
  12. package/bin/wr-itil-check-outbound-responses-staleness +4 -4
  13. package/bin/wr-itil-check-problems-readme-budget +4 -4
  14. package/bin/wr-itil-check-rfc-has-stories +4 -4
  15. package/bin/wr-itil-check-rfc-stories-ratified +4 -4
  16. package/bin/wr-itil-check-ticket-jtbd-ratification +4 -4
  17. package/bin/wr-itil-check-upstream-cache-staleness +4 -4
  18. package/bin/wr-itil-check-upstream-responses +4 -4
  19. package/bin/wr-itil-classify-readme-drift +4 -4
  20. package/bin/wr-itil-derive-release-vehicle +4 -4
  21. package/bin/wr-itil-detect-unratified-stories-maps +4 -4
  22. package/bin/wr-itil-effort-tally +4 -4
  23. package/bin/wr-itil-enumerate-postrelease-kv-candidates +4 -4
  24. package/bin/wr-itil-evaluate-relevance +4 -4
  25. package/bin/wr-itil-mark-create-gate +4 -4
  26. package/bin/wr-itil-mark-story-oversight-confirmed +4 -4
  27. package/bin/wr-itil-migrate-problems-layout +4 -4
  28. package/bin/wr-itil-migrate-story-status-mirror +4 -4
  29. package/bin/wr-itil-next-rfc-id +4 -4
  30. package/bin/wr-itil-plugin-exercise-index +4 -4
  31. package/bin/wr-itil-plugin-maturity-populate +4 -4
  32. package/bin/wr-itil-plugin-maturity-render +4 -4
  33. package/bin/wr-itil-plugin-validate-ci-gate +4 -4
  34. package/bin/wr-itil-reconcile-readme +4 -4
  35. package/bin/wr-itil-reconcile-rfcs +4 -4
  36. package/bin/wr-itil-reconcile-stories +4 -4
  37. package/bin/wr-itil-reconcile-story-maps +4 -4
  38. package/bin/wr-itil-render-story-map +4 -4
  39. package/bin/wr-itil-resolve-governance-plugin-dirs +4 -4
  40. package/bin/wr-itil-skill-invocations +4 -4
  41. package/bin/wr-itil-story-map-edit +4 -4
  42. package/bin/wr-itil-story-map-query +4 -4
  43. package/bin/wr-itil-update-jtbd-references-section +4 -4
  44. package/bin/wr-itil-update-problem-references-section +4 -4
  45. package/bin/wr-itil-update-problem-rfcs-section +4 -4
  46. package/bin/wr-itil-update-rfc-commits-section +4 -4
  47. package/bin/wr-itil-update-rfc-references-section +4 -4
  48. package/bin/wr-itil-verify-iter-summary +4 -4
  49. package/hooks/itil-assistant-output-gate.sh +3 -3
  50. package/hooks/itil-assistant-output-review.sh +5 -5
  51. package/hooks/itil-bash-polling-antipattern-detect.sh +11 -11
  52. package/hooks/itil-changeset-discipline.sh +24 -24
  53. package/hooks/itil-claude-space-protection.sh +21 -14
  54. package/hooks/itil-codex-dispatch.sh +164 -0
  55. package/hooks/itil-commit-trailer-transition-advisory.sh +11 -11
  56. package/hooks/itil-correction-detect.sh +8 -8
  57. package/hooks/itil-deferral-cadence-gate.sh +23 -23
  58. package/hooks/itil-fictional-defer-detect.sh +16 -16
  59. package/hooks/itil-fix-title-lifecycle-advisory.sh +11 -11
  60. package/hooks/itil-mid-loop-ask-detect.sh +14 -14
  61. package/hooks/itil-no-implement-draft-gate.sh +18 -18
  62. package/hooks/itil-pending-questions-surface.sh +11 -11
  63. package/hooks/itil-readme-refresh-discipline.sh +27 -27
  64. package/hooks/itil-rfc-oversight-nudge.sh +7 -7
  65. package/hooks/itil-rfc-trailer-advisory.sh +28 -28
  66. package/hooks/itil-runtime-sid-marker.sh +11 -11
  67. package/hooks/itil-story-mirror-migration-nudge.sh +7 -7
  68. package/hooks/lib/block-list.sh +17 -17
  69. package/hooks/lib/changeset-detect.sh +27 -27
  70. package/hooks/lib/claude-space-gate.sh +23 -15
  71. package/hooks/lib/command-detect.sh +12 -12
  72. package/hooks/lib/create-gate.sh +9 -39
  73. package/hooks/lib/detectors.sh +12 -12
  74. package/hooks/lib/readme-refresh-detect.sh +51 -51
  75. package/hooks/lib/runtime-sid.sh +12 -12
  76. package/hooks/lib/session-id.sh +28 -28
  77. package/hooks/lib/session-marker.sh +1 -1
  78. package/hooks/lib/staging-detect.sh +13 -13
  79. package/hooks/manage-problem-enforce-create.sh +16 -27
  80. package/hooks/p057-staging-trap-detect.sh +18 -18
  81. package/hooks/pre-publish-intake-gate.sh +5 -5
  82. package/hooks/staleness-check.sh +6 -6
  83. package/hooks-codex/hooks.json +57 -0
  84. package/lib/check-deferred-placeholder-staleness.sh +10 -10
  85. package/lib/check-outbound-responses-staleness.sh +2 -2
  86. package/lib/check-upstream-cache-staleness.sh +2 -2
  87. package/lib/derive-first-dispatch.sh +19 -19
  88. package/lib/enumerate-postrelease-kv-candidates.sh +18 -18
  89. package/lib/migrate-problems-layout.sh +12 -12
  90. package/lib/story-oversight.sh +27 -27
  91. package/package.json +16 -3
  92. package/scripts/catchup-scan.sh +25 -25
  93. package/scripts/check-fail-soft-skip-discipline.sh +10 -10
  94. package/scripts/check-fix-rfc-trace.sh +8 -8
  95. package/scripts/check-locale-discipline.sh +13 -13
  96. package/scripts/check-problems-readme-budget.sh +12 -12
  97. package/scripts/check-rfc-has-stories.sh +7 -7
  98. package/scripts/check-rfc-rejected-alternatives.sh +11 -11
  99. package/scripts/check-rfc-stories-ratified.sh +9 -9
  100. package/scripts/check-ticket-jtbd-ratification.sh +10 -10
  101. package/scripts/check-upstream-responses.sh +22 -22
  102. package/scripts/classify-readme-drift.sh +13 -13
  103. package/scripts/codex-agent.mjs +104 -0
  104. package/scripts/derive-release-vehicle.sh +23 -23
  105. package/scripts/detect-unoversighted-rfcs.sh +3 -3
  106. package/scripts/detect-unratified-stories-maps.sh +5 -5
  107. package/scripts/effort-tally.sh +10 -10
  108. package/scripts/evaluate-relevance.sh +16 -16
  109. package/scripts/mark-create-gate.sh +4 -4
  110. package/scripts/mark-story-oversight-confirmed.sh +14 -14
  111. package/scripts/migrate-story-status-mirror.sh +6 -6
  112. package/scripts/next-rfc-id.sh +5 -5
  113. package/scripts/plugin-exercise-index.sh +26 -26
  114. package/scripts/plugin-maturity-populate.sh +38 -38
  115. package/scripts/plugin-maturity-render.sh +26 -26
  116. package/scripts/plugin-validate-ci-gate.sh +14 -14
  117. package/scripts/reconcile-readme.sh +23 -23
  118. package/scripts/reconcile-rfcs.sh +13 -13
  119. package/scripts/reconcile-stories.sh +12 -12
  120. package/scripts/reconcile-story-maps.sh +6 -6
  121. package/scripts/render-story-map.mjs +24 -24
  122. package/scripts/render-story-map.sh +3 -3
  123. package/scripts/resolve-governance-plugin-dirs.sh +10 -10
  124. package/scripts/run-check-deferred-placeholder-staleness.sh +3 -3
  125. package/scripts/run-check-outbound-responses-staleness.sh +3 -3
  126. package/scripts/run-check-upstream-cache-staleness.sh +3 -3
  127. package/scripts/run-enumerate-postrelease-kv-candidates.sh +3 -3
  128. package/scripts/run-migrate-problems-layout.sh +3 -3
  129. package/scripts/skill-invocations.sh +29 -29
  130. package/scripts/story-map-edit.mjs +6 -6
  131. package/scripts/story-map-edit.sh +3 -3
  132. package/scripts/story-map-query.mjs +8 -8
  133. package/scripts/story-map-query.sh +3 -3
  134. package/scripts/update-jtbd-references-section.sh +8 -8
  135. package/scripts/update-problem-references-section.sh +12 -12
  136. package/scripts/update-problem-rfcs-section.sh +9 -9
  137. package/scripts/update-rfc-commits-section.sh +7 -7
  138. package/scripts/update-rfc-references-section.sh +3 -3
  139. package/scripts/update-story-references-section.sh +5 -5
  140. package/scripts/verify-iter-summary.sh +3 -3
  141. package/skills/capture-problem/REFERENCE.md +33 -33
  142. package/skills/capture-problem/SKILL.md +108 -108
  143. package/skills/capture-problem/agents/openai.yaml +3 -0
  144. package/skills/capture-rfc/SKILL.md +21 -323
  145. package/skills/capture-rfc/agents/openai.yaml +3 -0
  146. package/skills/capture-story/SKILL.md +65 -65
  147. package/skills/capture-story/agents/openai.yaml +3 -0
  148. package/skills/capture-story-map/SKILL.md +31 -31
  149. package/skills/capture-story-map/agents/openai.yaml +3 -0
  150. package/skills/check-upstream-responses/SKILL.md +38 -38
  151. package/skills/check-upstream-responses/agents/openai.yaml +3 -0
  152. package/skills/close-incident/SKILL.md +25 -25
  153. package/skills/close-incident/agents/openai.yaml +3 -0
  154. package/skills/link-incident/SKILL.md +22 -22
  155. package/skills/link-incident/agents/openai.yaml +3 -0
  156. package/skills/list-incidents/SKILL.md +9 -9
  157. package/skills/list-incidents/agents/openai.yaml +3 -0
  158. package/skills/list-problems/SKILL.md +17 -17
  159. package/skills/list-problems/agents/openai.yaml +3 -0
  160. package/skills/list-stories/SKILL.md +23 -23
  161. package/skills/list-stories/agents/openai.yaml +3 -0
  162. package/skills/list-story-maps/SKILL.md +9 -9
  163. package/skills/list-story-maps/agents/openai.yaml +3 -0
  164. package/skills/manage-incident/SKILL.md +59 -59
  165. package/skills/manage-incident/agents/openai.yaml +3 -0
  166. package/skills/manage-problem/SKILL.md +222 -222
  167. package/skills/manage-problem/agents/openai.yaml +3 -0
  168. package/skills/manage-rfc/SKILL.md +62 -62
  169. package/skills/manage-rfc/agents/openai.yaml +3 -0
  170. package/skills/manage-story/SKILL.md +49 -49
  171. package/skills/manage-story/agents/openai.yaml +3 -0
  172. package/skills/manage-story-map/SKILL.md +30 -30
  173. package/skills/manage-story-map/agents/openai.yaml +3 -0
  174. package/skills/mitigate-incident/SKILL.md +40 -40
  175. package/skills/mitigate-incident/agents/openai.yaml +3 -0
  176. package/skills/reconcile-readme/SKILL.md +28 -28
  177. package/skills/reconcile-readme/agents/openai.yaml +3 -0
  178. package/skills/reconcile-stories/SKILL.md +17 -17
  179. package/skills/reconcile-stories/agents/openai.yaml +3 -0
  180. package/skills/reconcile-story-maps/SKILL.md +11 -11
  181. package/skills/reconcile-story-maps/agents/openai.yaml +3 -0
  182. package/skills/report-upstream/SKILL.md +73 -73
  183. package/skills/report-upstream/agents/openai.yaml +3 -0
  184. package/skills/restore-incident/SKILL.md +28 -28
  185. package/skills/restore-incident/agents/openai.yaml +3 -0
  186. package/skills/review-problems/SKILL.md +129 -129
  187. package/skills/review-problems/agents/openai.yaml +3 -0
  188. package/skills/scaffold-intake/SKILL.md +26 -26
  189. package/skills/scaffold-intake/agents/openai.yaml +3 -0
  190. package/skills/transition-problem/SKILL.md +85 -85
  191. package/skills/transition-problem/agents/openai.yaml +3 -0
  192. package/skills/transition-problems/SKILL.md +69 -69
  193. package/skills/transition-problems/agents/openai.yaml +3 -0
  194. package/skills/update-upstream/SKILL.md +97 -97
  195. package/skills/update-upstream/agents/openai.yaml +3 -0
  196. package/skills/work-problem/SKILL.md +42 -42
  197. package/skills/work-problem/agents/openai.yaml +3 -0
  198. package/skills/work-problems/SKILL.md +327 -327
  199. package/skills/work-problems/agents/openai.yaml +3 -0
  200. package/skills-codex/capture-problem/REFERENCE.md +139 -0
  201. package/skills-codex/capture-problem/SKILL.md +438 -0
  202. package/skills-codex/capture-problem/agents/openai.yaml +3 -0
  203. package/skills-codex/capture-rfc/SKILL.md +45 -0
  204. package/skills-codex/capture-rfc/agents/openai.yaml +3 -0
  205. package/skills-codex/capture-story/SKILL.md +407 -0
  206. package/skills-codex/capture-story/agents/openai.yaml +3 -0
  207. package/skills-codex/capture-story-map/SKILL.md +286 -0
  208. package/skills-codex/capture-story-map/agents/openai.yaml +3 -0
  209. package/skills-codex/check-upstream-responses/SKILL.md +160 -0
  210. package/skills-codex/check-upstream-responses/agents/openai.yaml +3 -0
  211. package/skills-codex/close-incident/SKILL.md +192 -0
  212. package/skills-codex/close-incident/agents/openai.yaml +3 -0
  213. package/skills-codex/link-incident/SKILL.md +173 -0
  214. package/skills-codex/link-incident/agents/openai.yaml +3 -0
  215. package/skills-codex/list-incidents/SKILL.md +92 -0
  216. package/skills-codex/list-incidents/agents/openai.yaml +3 -0
  217. package/skills-codex/list-problems/SKILL.md +126 -0
  218. package/skills-codex/list-problems/agents/openai.yaml +3 -0
  219. package/skills-codex/list-stories/SKILL.md +170 -0
  220. package/skills-codex/list-stories/agents/openai.yaml +3 -0
  221. package/skills-codex/list-story-maps/SKILL.md +104 -0
  222. package/skills-codex/list-story-maps/agents/openai.yaml +3 -0
  223. package/skills-codex/manage-incident/SKILL.md +378 -0
  224. package/skills-codex/manage-incident/agents/openai.yaml +3 -0
  225. package/skills-codex/manage-problem/SKILL.md +1180 -0
  226. package/skills-codex/manage-problem/agents/openai.yaml +3 -0
  227. package/skills-codex/manage-rfc/SKILL.md +314 -0
  228. package/skills-codex/manage-rfc/agents/openai.yaml +3 -0
  229. package/skills-codex/manage-story/SKILL.md +284 -0
  230. package/skills-codex/manage-story/agents/openai.yaml +3 -0
  231. package/skills-codex/manage-story-map/SKILL.md +198 -0
  232. package/skills-codex/manage-story-map/agents/openai.yaml +3 -0
  233. package/skills-codex/mitigate-incident/SKILL.md +239 -0
  234. package/skills-codex/mitigate-incident/agents/openai.yaml +3 -0
  235. package/skills-codex/reconcile-readme/SKILL.md +175 -0
  236. package/skills-codex/reconcile-readme/agents/openai.yaml +3 -0
  237. package/skills-codex/reconcile-stories/SKILL.md +124 -0
  238. package/skills-codex/reconcile-stories/agents/openai.yaml +3 -0
  239. package/skills-codex/reconcile-story-maps/SKILL.md +81 -0
  240. package/skills-codex/reconcile-story-maps/agents/openai.yaml +3 -0
  241. package/skills-codex/report-upstream/SKILL.md +716 -0
  242. package/skills-codex/report-upstream/agents/openai.yaml +3 -0
  243. package/skills-codex/restore-incident/SKILL.md +216 -0
  244. package/skills-codex/restore-incident/agents/openai.yaml +3 -0
  245. package/skills-codex/review-problems/SKILL.md +524 -0
  246. package/skills-codex/review-problems/agents/openai.yaml +3 -0
  247. package/skills-codex/scaffold-intake/SKILL.md +209 -0
  248. package/skills-codex/scaffold-intake/agents/openai.yaml +3 -0
  249. package/skills-codex/scaffold-intake/templates/CONTRIBUTING.md.tmpl +31 -0
  250. package/skills-codex/scaffold-intake/templates/SECURITY.md.tmpl +39 -0
  251. package/skills-codex/scaffold-intake/templates/SUPPORT.md.tmpl +32 -0
  252. package/skills-codex/scaffold-intake/templates/config.yml.tmpl +8 -0
  253. package/skills-codex/scaffold-intake/templates/problem-report.yml.tmpl +114 -0
  254. package/skills-codex/transition-problem/SKILL.md +371 -0
  255. package/skills-codex/transition-problem/agents/openai.yaml +3 -0
  256. package/skills-codex/transition-problems/SKILL.md +310 -0
  257. package/skills-codex/transition-problems/agents/openai.yaml +3 -0
  258. package/skills-codex/update-upstream/SKILL.md +583 -0
  259. package/skills-codex/update-upstream/agents/openai.yaml +3 -0
  260. package/skills-codex/work-problem/SKILL.md +160 -0
  261. package/skills-codex/work-problem/agents/openai.yaml +3 -0
  262. package/skills-codex/work-problems/SKILL.md +58 -0
  263. package/skills-codex/work-problems/agents/openai.yaml +3 -0
  264. package/templates/story-map.css +1 -1
  265. package/bin/wr-itil-mark-rfc-capture-gate +0 -51
  266. package/scripts/mark-rfc-capture-gate.sh +0 -32
@@ -0,0 +1,716 @@
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 the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule, with the "Report-upstream classifier is problem-first — supersedes Decision Outcome Steps 3 + 5" architecture rule governing problem-first classifier + default body shape.
4
+ allowed-tools: Read, Write, Edit, Bash, Glob, Grep, request_user_input, Skill, Agent
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
+ # Report Upstream — Cross-Project Problem-Reporting Skill
19
+
20
+ Report a local `docs/problems/<NNN>` ticket upstream. **Prefer opening a pull request when the upstream accepts pull requests**; fall back to filing an issue otherwise (or a private security advisory when the ticket is security-classified). Discover upstream 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.
21
+
22
+ This skill implements the contract documented in [the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule](../../../docs/decisions/024-cross-project-problem-reporting-contract.proposed.md) (Cross-project problem-reporting contract). All step numbering below maps 1:1 to the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule Decision Outcome.
23
+
24
+ [the "Report-upstream classifier is problem-first — supersedes Decision Outcome Steps 3 + 5" architecture rule](../../../docs/decisions/033-report-upstream-classifier-problem-first.proposed.md) (Report-upstream classifier is problem-first) partially supersedes the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule Decision Outcome **Steps 3 and 5 only** — the classifier is problem-first with best-fit backward-compat fallback (per Step 3 below), and the structured default body is problem-shaped (per Step 5 below). the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule Steps 1, 2, 4, 6, 7, 8 and all Consequences / Confirmation clauses remain in force unchanged.
25
+
26
+ The **the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule amendment of 2026-04-25 (the "Problem 070: /wr-itil:report-upstream does not check for existing upstream issues before filing" problem)** adds Step 4b (dedup check — own re-run + third-party search across issues and pull requests, followed by inline LLM semantic matching) and Step 5c (kind-aware comment path). AFK comments use the shipped `wr-risk-scorer:external-comms` gate; unresolved above-appetite prose is queued without halting the orchestrator.
27
+
28
+ ## Invocation
29
+
30
+ ```
31
+ /wr-itil:report-upstream <local-problem-id> <upstream-repo-url> [--severity <level>] [--classification <kind>] [--evidence-url <url>]
32
+ ```
33
+
34
+ - `<local-problem-id>`: the `NNN` of the local ticket (e.g. `058`).
35
+ - `<upstream-repo-url>`: GitHub URL of the upstream repo (e.g. `https://github.com/anthropics/claude-code`).
36
+ - `--severity`: optional, overrides the local ticket's severity inference.
37
+ - `--classification`: optional, one of `bug`, `feature`, `question`, `security`. Inferred when absent.
38
+ - `--evidence-url`: optional, an external link (transcript, screenshot, gist) to include in the report.
39
+
40
+ ## Step-0 deferral (the "Governance skill auto-delegation — Step 0 delegates skill workflow to a subagent" architecture rule)
41
+
42
+ This skill **does NOT** implement the "Governance skill auto-delegation — Step 0 delegates skill workflow to a subagent" architecture rule's Step-0 auto-delegation pattern. Per the "Governance skill auto-delegation — Step 0 delegates skill workflow to a subagent" architecture rule 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:
43
+
44
+ - 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` `request_user_input` to the user. Wrapping the flow in a subagent adds a hop without reducing main-agent context cost (the local ticket and the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule contract still need to be in main-agent context for the user's interactive decisions).
45
+ - The interactive `request_user_input` 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.
46
+ - The skill's footprint is small (one local doc edit + one or two `gh` API calls per invocation).
47
+
48
+ **Trigger to revisit**: if a second skill that reads upstream repo content lands (per the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule's Reassessment Criteria), reconsider whether the cross-cutting "read upstream" pattern should move into a Step-0-delegated subagent that this skill calls.
49
+
50
+ ## Reciprocal sibling: scaffold-intake (the "Problem 065: No skill scaffolds intake files (ISSUE_TEMPLATE, SECURITY.md, CONTRIBUTING.md, SUPPORT.md) in downstream projects" problem / the "Scaffold downstream OSS intake — skill + layered triggers" architecture rule)
51
+
52
+ This skill files reports against an upstream's intake surface. Its reciprocal — [`/wr-itil:scaffold-intake`](../scaffold-intake/SKILL.md) — scaffolds the intake surface on a downstream project so that downstream can in turn be a target of further `report-upstream` calls. Together they close the ecosystem-level intake-shape discipline the "Problem 055: No standard problem-reporting channel for plugin users, and no reusable pattern for downstream projects to report upstream" problem partial coverage left open. Adopters who run this skill against a target without an `.github/ISSUE_TEMPLATE/` directory should be encouraged to suggest the target adopt `/wr-itil:scaffold-intake` to gain the full problem-first intake set this skill prefers (per the "Report-upstream classifier is problem-first — supersedes Decision Outcome Steps 3 + 5" architecture rule Step 3 classifier).
53
+
54
+ [the "Scaffold downstream OSS intake — skill + layered triggers" architecture rule](../../../../docs/decisions/036-scaffold-downstream-oss-intake.proposed.md) is the design record for the reciprocal-scaffolding side; it establishes the layered triggers (first-run prompt + pre-publish gate + optional CI check) and the marker-suppressed lifecycle.
55
+
56
+ ## Voice-tone gate interaction (the "External-comms gate — voice-tone + risk/leak evaluators on shared PreToolUse surface" architecture rule)
57
+
58
+ The skill's `gh issue create` (Step 5), `gh pr create` (Step 5b), `gh issue comment` / `gh pr comment` (Step 5c) and `gh api repos/.../security-advisories` (Step 6) calls are **on the gated surface list per [the "External-comms gate — voice-tone + risk/leak evaluators on shared PreToolUse surface" architecture rule](../../../docs/decisions/028-voice-tone-gate-external-comms.proposed.md)** (Voice-tone gate on external communications). Expected behaviour during these tool calls:
59
+
60
+ 1. The voice-tone gate fires `PreToolUse:Bash` with a deny-plus-delegate response.
61
+ 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`.
62
+ 3. Once the agent's marker lands, the same `gh issue create` or `gh api` call retries and proceeds.
63
+
64
+ 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.
65
+
66
+ If `wr-voice-tone:agent` is not installed in the project, the gate is dormant and the skill proceeds without delegation.
67
+
68
+ **A pull request carries two outbound surfaces; only one of them is gated.** The prose must be reviewed, but the shipped hook extracts only the `--body` value. Before `gh pr create`, explicitly send the **combined title and body** through `wr-risk-scorer:external-comms` and `wr-voice-tone:external-comms`; the hook then enforces the body review on the command itself. The **diff is not gated by anything**. Nothing in this repo scores a diff against an upstream's policy or contribution standards. Read the diff yourself before opening the pull request; that gap is tracked as the "An upstream pull-request diff is not scored against the upstream's conventions" problem and is deliberately not closed by this skill.
69
+
70
+ Two mechanical notes so a re-route is not mistaken for a defect:
71
+
72
+ - The surface label is part of the gate's marker key. A body first reviewed as an issue and then re-routed to a pull request misses its marker and pays a second full review by both evaluators, even though the prose is byte-identical. Expected, not a bug.
73
+ - The gate's surface regex anchors on a command start, a `;`, an `&&` or a `||`. A **piped** invocation (`… | gh pr create`) does not match and the gate silently no-ops. Invoke `gh pr create` in an anchor-matching form.
74
+
75
+ ## Steps
76
+
77
+ ### 1. Read the local problem ticket
78
+
79
+ Dual-tolerant lookup spans flat layout AND per-state subdir layout (the ": docs/problems/ flat layout migration — per-state subdirs + adopter auto-migration" release design migration window):
80
+
81
+ ```bash
82
+ LOCAL_TICKET=$(ls docs/problems/${LOCAL_ID}-*.{open,known-error,verifying,closed}.md docs/problems/*/${LOCAL_ID}-*.md 2>/dev/null | head -1)
83
+ [ -n "$LOCAL_TICKET" ] || { echo "Error: local ticket P${LOCAL_ID} not found in docs/problems/"; exit 1; }
84
+ ```
85
+
86
+ Extract:
87
+ - Title (from H1).
88
+ - Status (from frontmatter Status field — Open / Known Error / Verification Pending / Closed).
89
+ - Description, Symptoms, Workaround, Impact Assessment, Root Cause Analysis sections.
90
+ - Priority and severity classification (look for a `security` label or a `## Security classification` section — see Step 4).
91
+
92
+ 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?`
93
+
94
+ ### 2. Discover upstream metadata, contribution guidance, and issue templates
95
+
96
+ ```bash
97
+ UPSTREAM_OWNER_REPO=$(echo "$UPSTREAM_URL" | sed -E 's|https?://github.com/([^/]+/[^/]+)(/.*)?|\1|')
98
+ REPO_JSON=$(gh api "repos/${UPSTREAM_OWNER_REPO}")
99
+ TEMPLATES_JSON=$(gh api "repos/${UPSTREAM_OWNER_REPO}/contents/.github/ISSUE_TEMPLATE" 2>/dev/null)
100
+ CONTRIBUTING_MD=$(gh api "repos/${UPSTREAM_OWNER_REPO}/contents/CONTRIBUTING.md" --jq '.content' 2>/dev/null | base64 -d)
101
+ PR_TEMPLATE_MD=$(gh api "repos/${UPSTREAM_OWNER_REPO}/contents/.github/PULL_REQUEST_TEMPLATE.md" --jq '.content' 2>/dev/null | base64 -d)
102
+ ```
103
+
104
+ If the conventional contribution files are absent, also try `.github/CONTRIBUTING.md`, `.github/pull_request_template.md`, and `docs/PULL_REQUEST_TEMPLATE.md`. A 404 for any optional file means absent; cache successful responses for Steps 4c and 5b. A failure fetching `REPO_JSON` is fatal because its `archived`, `disabled`, and `default_branch` fields govern the route and checkout.
105
+
106
+ Parse the response:
107
+ - HTTP 200 with a JSON array → upstream has templates. List the names + types (`.yml` for forms, `.md` for legacy markdown templates).
108
+ - HTTP 404 → upstream has no `.github/ISSUE_TEMPLATE/` directory; treat as no-templates (proceed to structured default in Step 5).
109
+ - Other HTTP error (rate-limit, network) → halt with a clear error and the response body so the user can retry.
110
+
111
+ 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`.
112
+
113
+ ### 3. Classify the local ticket and pick the best-matching template
114
+
115
+ This step is governed by [the "Report-upstream classifier is problem-first — supersedes Decision Outcome Steps 3 + 5" architecture rule](../../../docs/decisions/033-report-upstream-classifier-problem-first.proposed.md) (Report-upstream classifier is problem-first), which partially supersedes the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule Decision Outcome Step 3. Classification is **problem-first with best-fit backward-compat fallback** — upstream repos that have adopted the problem-first intake shape (per `@windyroad/itil`) are targeted first; older repos that still ship bug/feature/question templates are served via a fallback.
116
+
117
+ **Preference order** (first match wins):
118
+
119
+ 1. **`problem` shape (primary)** — any of the tokens `problem`, `issue`, `concern`, `defect`, `gap` appear in the local ticket title or body; or the body contains a scoped-npm package reference (`@scope/name`); or the body contains any of `root cause`, `reproduction`, `workaround`. This is the default for tickets authored via `/wr-itil:manage-problem`.
120
+ 2. **`bug` shape (backward-compat fallback)** — no primary tokens match, and the prose is defect-like (contains `broken`, `fails`, `error`, `bug`, `regression`, or a specific observed-vs-expected contrast). Produces a bug-shaped body only when the upstream has no `problem-report.yml`.
121
+ 3. **`feature` shape (backward-compat fallback)** — no primary tokens match, and the prose is proposal-like (contains `would be nice`, `enhancement`, `feature request`, `could we`, `wish`).
122
+ 4. **`question` shape (backward-compat fallback)** — trailing fallback when the prose is a genuine question (ends in `?`, contains `how do I`, `is there a way`).
123
+
124
+ The CLI `--classification` argument overrides the heuristic. The security-path check in Step 4 fires **before** this classifier — security-classified tickets bypass the classifier entirely.
125
+
126
+ **Template-discovery preference order** (extends the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule Step 1; search the upstream `.github/ISSUE_TEMPLATE/` directory in this order, first match wins):
127
+
128
+ 1. `problem-report.yml` — preferred; the Windy-Road problem-first shape.
129
+ 2. `problem.yml` — alternate naming for problem-shaped templates.
130
+ 3. `problem-report.md` / `problem.md` — legacy markdown variants of the problem-shaped template.
131
+ 4. `bug-report.yml` / `bug.yml` / `bug-report.md` / `bug.md` — if primary classifier picked `bug` shape OR no problem template exists and fallback is `bug`.
132
+ 5. `feature-request.yml` / `feature.yml` / `feature-request.md` — `feature` shape fallback.
133
+ 6. `question.yml` / `question.md` — `question` shape fallback. If absent, the upstream's `config.yml` likely routes questions elsewhere (Discussions); halt and surface the routing target.
134
+ 7. Structured default body per Step 5 below — if no template matches.
135
+
136
+ Log the matched template name (or `structured default`) in the Step 7 back-write. If no template matches the classification, fall through to the structured default in Step 5.
137
+
138
+ ### 4. Security-path routing check
139
+
140
+ The local ticket is **security-classified** if any of:
141
+ - Its title contains `security`, `vulnerability`, `CVE`, `disclosure`, `RCE`, `injection`, `XSS`, or `auth bypass`.
142
+ - Its frontmatter `Priority:` line contains a `security` label.
143
+ - The ticket body has a `## Security classification` section.
144
+ - The CLI `--classification security` argument was passed.
145
+
146
+ If security-classified, route to Step 6. Otherwise, route to Step 4b (dedup check), then Step 4c (choose the outbound artefact), then Step 5 or Step 5b.
147
+
148
+ Security classification is checked **first and wins outright**. A security-classified ticket never reaches Step 4c, so it can never be routed to a pull request — the private disclosure path in Step 6 stands exactly as it is.
149
+
150
+ ### 4c. Choose the outbound artefact — pull request or issue (the "Prefer an upstream pull request over an issue when the upstream accepts pull requests" architecture rule)
151
+
152
+ This step is governed by [the "Prefer an upstream pull request over an issue when the upstream accepts pull requests" architecture rule](../../../docs/decisions/117-prefer-an-upstream-pull-request-over-an-issue.proposed.md) (Prefer an upstream pull request over an issue when the upstream accepts pull requests), which adds this branch alongside the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule's confirmed reporting contract and ahead of Step 5.
153
+
154
+ **Prefer a pull request. File an issue when one of the four fallbacks below applies.**
155
+
156
+ #### The predicate is "does this upstream accept pull requests"
157
+
158
+ It is **not** "do we have write access". Fork-and-PR is the ordinary way a third party contributes, and it needs no permission we have to negotiate for. Most adopters of this plugin are consumers of their dependencies, not owners of them — a write-access predicate would make this whole branch a no-op for exactly the case the skill was written for.
159
+
160
+ Read the signal from the discovery calls Step 2 makes:
161
+
162
+ - The `repos/<owner>/<repo>` payload's `archived` and `disabled` flags. Either one true → the upstream is not accepting contributions.
163
+ - The presence of `CONTRIBUTING.md`, or of a pull-request template fetched in Step 2. Either is positive evidence that pull requests are wanted.
164
+ - An explicit statement in `CONTRIBUTING.md` that the project does not accept outside contributions.
165
+
166
+ **On an absent or ambiguous signal, default to "accepts".** Do not escalate through a probe ladder to prove acceptance — a refuse-unless-proven predicate is the same failure mode the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule already rejected when it declined to refuse upstreams that ship no issue templates. State which signal was read, or say the signal was absent and the default applied. Do not write "upstream likely accepts pull requests".
167
+
168
+ #### File an issue instead when
169
+
170
+ 1. **The upstream does not accept contributions.** Archived, disabled, or says so.
171
+ 2. **The fix needs a design decision that is the maintainers' to make.** More than one defensible approach, and picking between them is their call, not ours.
172
+ 3. **The ticket is security-classified.** Already routed at Step 4 — this fallback records that the routing exists, and it is Step 6's private path that runs, not this one. Nothing here re-asserts the pre-the "Agent waits for human to initiate upstream report instead of filing on detect — feedback delay class" problem blanket ban.
173
+ 4. **There is no defensible fix in hand.** A symptom, or even a confident diagnosis, is not a change we can responsibly author in a codebase we do not know.
174
+
175
+ #### Fallback 4 is decided silently — never ask the reporter
176
+
177
+ The reporter describes a symptom. That is the whole of their obligation and this decision must not touch it. **Do not raise an `request_user_input` about whether to write a patch.** The skill already carries two interactive gates (Step 4b dedup, Step 6 missing-`SECURITY.md`); a third would push intake past the couple of minutes beyond which a report simply gets abandoned, and it would be asking the reporter to ratify a judgement the agent is there to make.
178
+
179
+ The preference is a preference. It never converts the reporter into a patch author. The added cost lands on agent time and token budget, not on anyone's attention.
180
+
181
+ #### Draft the issue body first; the pull request is an upgrade of it
182
+
183
+ Compose the Step 5 issue body **before** attempting the pull request, always. Then attempt the pull request. If the attempt fails for any reason — fork refused, patch will not apply, upstream tests red, effort budget spent — **file the already-drafted issue** rather than aborting.
184
+
185
+ Without this, a failed pull-request attempt loses a report that the issue-only path would have filed, which is strictly worse than not having tried.
186
+
187
+ #### Effort budget
188
+
189
+ Spend at most **20 minutes of wall-clock and 3 attempts** on getting a working patch. Past that, fall back to fallback 4 and file the drafted issue. The budget is a real number rather than a judgement call because an open-ended "author a fix in an unfamiliar codebase" is how a loop burns a quota and how an idle guard that measures progress in commits kills a session doing legitimate work.
190
+
191
+ ### 4b. Dedup check (the "Problem 070: /wr-itil:report-upstream does not check for existing upstream issues before filing" problem)
192
+
193
+ This step is governed by the [the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule](../../../docs/decisions/024-cross-project-problem-reporting-contract.proposed.md) 2026-04-25 amendment, which adds dedup checking to the Decision Outcome step list (the "Problem 070: /wr-itil:report-upstream does not check for existing upstream issues before filing" problem). Two duplication windows close at the same insertion point: own re-run (4b.1) and third-party search (4b.2). Both branches share the same request_user_input surface and AFK risk-gated queue-and-continue behaviour.
194
+
195
+ > **Serves**: the ": Connect Agents Across Repos to Collaborate" user outcome (cross-repo coordination — dedup is the difference between coordination and spam), the ": Enforce Governance Without Slowing Down" user outcome (solo developer "without slowing down" — dedup protects the user from policing upstream duplicates manually), the ": Progress the Backlog While I'm Away" user outcome (AFK persona — risk-gated queue-and-continue avoids duplicate firing), the "Extend the Suite with New Plugins" user outcome (clear pattern — pattern ships without a duplication hole).
196
+
197
+ #### 4b.1. Own re-run check
198
+
199
+ Detect whether the local ticket already records a previous upstream report. The `## Reported Upstream` section is written by Step 7 (cross-reference back-write) on a successful prior invocation; its presence means the skill has already filed (or commented) for this local ticket.
200
+
201
+ ```bash
202
+ LOCAL_URL=$(grep -A5 '^## Reported Upstream' "$LOCAL_TICKET" | grep -oE 'https?://[^ )]+' | head -1)
203
+ LOCAL_DISCLOSURE=$(grep -A5 '^## Reported Upstream' "$LOCAL_TICKET" | sed -n 's/^- \*\*Disclosure path\*\*: //p' | head -1)
204
+ case "$(printf '%s' "$LOCAL_DISCLOSURE" | tr '[:upper:]' '[:lower:]')" in
205
+ *pull*request*) LOCAL_KIND="pull-request" ;;
206
+ *) LOCAL_KIND="issue" ;;
207
+ esac
208
+ if [ -n "$LOCAL_URL" ]; then
209
+ echo "Local ticket P${LOCAL_ID} already records an existing upstream ${LOCAL_KIND}: $LOCAL_URL"
210
+ # Branch interactive vs AFK below.
211
+ fi
212
+ ```
213
+
214
+ **Interactive branch** — use `request_user_input` per the "Structured User Interaction for Governance-Skill Decisions" architecture rule Rule 1:
215
+
216
+ - `header: "Existing upstream report"`
217
+ - `multiSelect: false`
218
+ - Options:
219
+ 1. `Halt — local ticket already records ${LOCAL_URL}` (Recommended) — abort the invocation; the existing report is current.
220
+ 2. `Comment on the existing upstream report` — route to Step 5c with the existing URL's number and `${LOCAL_KIND}`; appropriate when new evidence has emerged since the previous report.
221
+ 3. `File a new upstream issue anyway (override)` — explicit override after user has reviewed the existing record and judged the second filing warranted (e.g. previous report was closed without resolution and a fresh tracker is needed).
222
+
223
+ **AFK / non-interactive branch** — apply the external-communications gate in the AFK behaviour summary. Below-appetite prose comments on the existing `${LOCAL_KIND}`; unresolved above-appetite prose is queued and the orchestrator continues.
224
+
225
+ #### 4b.2. Third-party search
226
+
227
+ Detect whether a different reporter (or another agent in a parallel session) has already filed a similar issue against the upstream. The Direction decision (2026-04-21) pins a two-stage mechanism: a `gh issue list --search` pre-filter that trims candidates to ~5-10, followed by an **inline LLM semantic match** that judges each candidate's body against the proposed report.
228
+
229
+ ```bash
230
+ # Stage 1: gh-search pre-filter on title keywords (cheap, ~500ms-2s).
231
+ KEYWORDS=$(extract_3-5_keywords_from "$LOCAL_TICKET_TITLE + $LOCAL_TICKET_DESCRIPTION")
232
+ ISSUE_MATCHES=$(gh issue list \
233
+ --repo "$UPSTREAM_OWNER_REPO" \
234
+ --state all \
235
+ --search "$KEYWORDS" \
236
+ --json number,title,state,url \
237
+ --limit 10)
238
+
239
+ # the "Prefer an upstream pull request over an issue when the upstream accepts pull requests" architecture rule: `gh issue list` does NOT return pull requests. Now that this skill
240
+ # opens pull requests, searching issues alone leaves the whole pull-request
241
+ # window open — including against pull requests we opened ourselves.
242
+ PR_MATCHES=$(gh pr list \
243
+ --repo "$UPSTREAM_OWNER_REPO" \
244
+ --state all \
245
+ --search "$KEYWORDS" \
246
+ --json number,title,state,url \
247
+ --limit 10)
248
+
249
+ MATCHES=$(jq -cn \
250
+ --argjson issues "$ISSUE_MATCHES" \
251
+ --argjson prs "$PR_MATCHES" \
252
+ '($issues | map(. + {kind: "issue"})) +
253
+ ($prs | map(. + {kind: "pull-request"}))')
254
+ ```
255
+
256
+ Carry the artefact kind alongside each candidate. Step 5c needs it to pick between `gh issue comment` and `gh pr comment`, and the user needs it to judge a match — "already fixed in an open pull request" is a different situation from "already reported in an open issue".
257
+
258
+ For each candidate returned by Stage 1, fetch the full body and run **Stage 2 — inline LLM semantic judgement**:
259
+
260
+ ```bash
261
+ # Stage 2: per-candidate body fetch + inline classification.
262
+ while IFS=$'\t' read -r kind n; do
263
+ if [ "$kind" = "pull-request" ]; then
264
+ CANDIDATE=$(gh pr view "$n" --repo "$UPSTREAM_OWNER_REPO" --json title,body,state,url)
265
+ else
266
+ CANDIDATE=$(gh issue view "$n" --repo "$UPSTREAM_OWNER_REPO" --json title,body,state,url)
267
+ fi
268
+ # Inline LLM judgement: read {local ticket Description + Symptoms, candidate title + body}
269
+ # and return one of: same-problem | different-problem | uncertain.
270
+ # No subagent dispatch — Direction decision 2026-04-21 pins inline classification
271
+ # for simplicity. Promotion to a `wr-itil:dedup-check` subagent is a future
272
+ # ADR amendment if architect review later flags context-isolation concerns.
273
+ done < <(echo "$MATCHES" | jq -r '.[] | [.kind, .number] | @tsv')
274
+ ```
275
+
276
+ Notes on inline LLM classification:
277
+
278
+ - **No subagent dispatch.** The skill's main-agent context already has the local ticket loaded (Step 1) and the candidate body in scope after `gh issue view`. The Direction decision (2026-04-21) pins inline classification to keep the dedup affordable; the gh-search pre-filter trims input to ~5-10 candidates so the inline reads stay bounded.
279
+ - **Verdicts**: `same-problem` (route to request_user_input with the matched URL); `different-problem` (skip, continue); `uncertain` (always surface to user — never auto-resolve).
280
+ - **Heuristic for "same problem"**: same root cause described, overlapping symptoms, same affected component or scoped npm package. Different reproduction environment alone does NOT downgrade to `different-problem` — environment heterogeneity is normal.
281
+
282
+ If Stage 2 produces one or more `same-problem` matches, surface them to the user in interactive mode:
283
+
284
+ - `header: "Existing upstream issue may match"`
285
+ - `multiSelect: false`
286
+ - Options:
287
+ 1. `Comment on #<N> (Recommended) — <title>` — one option per `same-problem` match; routes to Step 5c with that issue number.
288
+ 2. `File a new upstream issue anyway (override)` — explicit override; user has reviewed the matches and judged them distinct.
289
+ 3. `Cancel` — abort without filing or commenting.
290
+
291
+ `uncertain` matches surface alongside `same-problem` matches with their verdict labelled, so the user can review. The skill never auto-resolves an `uncertain` verdict.
292
+
293
+ **AFK / non-interactive branch** — apply the external-communications gate in the AFK behaviour summary, preserving the matched artefact kind. Below-appetite prose comments on the matching issue or pull request; unresolved above-appetite prose is queued and the orchestrator continues.
294
+
295
+ **Queued Upstream Report save format** (used by both 4b.1 and 4b.2 when risk cannot be reduced within appetite):
296
+
297
+ ```markdown
298
+ ## Queued Upstream Report
299
+
300
+ - **Drafted**: <YYYY-MM-DD>
301
+ - **Target upstream**: <upstream-repo-url>
302
+ - **Queue reason**: dedup match (own re-run | third-party `same-problem`) — external-communications risk remains above appetite
303
+ - **Matched URL(s)**: <existing-issue-or-report-URL(s)>
304
+ - **Drafted body**:
305
+
306
+ <the body that would have been posted as a comment or new report, ready for review>
307
+ ```
308
+
309
+ Queue an `outstanding_questions` entry and include the queued report in the progress summary; do not halt the orchestrator.
310
+
311
+ ### 5. Public-issue path
312
+
313
+ This step is governed by [the "Report-upstream classifier is problem-first — supersedes Decision Outcome Steps 3 + 5" architecture rule](../../../docs/decisions/033-report-upstream-classifier-problem-first.proposed.md) (Report-upstream classifier is problem-first), which partially supersedes the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule Decision Outcome Step 5. The primary structured default body is **problem-shaped** and mirrors the `/wr-itil:manage-problem` ticket shape; the bug-shaped / feature-shaped / question-shaped bodies are retained as fallback-only templates for the backward-compat branches of the Step 3 classifier.
314
+
315
+ If the upstream had a matching template (Step 3), fill its required fields from the local ticket. Field-mapping table for the problem-first case (problem-report.yml template):
316
+
317
+ | Upstream template field (typical) | Local ticket source |
318
+ |---|---|
319
+ | `plugin` / `package` / `module` | Inferred from upstream repo name or local ticket's "Affected plugin / component" |
320
+ | `version` (single-slot version field) | Per the "Report-upstream classifier is problem-first — supersedes Decision Outcome Steps 3 + 5" architecture rule amendment 2026-05-03 (the "/wr-itil:report-upstream report body lacks consolidated Versions section" problem) — populate with the local plugin version from the consolidated `## Versions` schema below; the full `## Versions` block is ALSO appended to the body's prose so the upstream maintainer has both the template's structured slot AND every version dimension. |
321
+ | `claude-code-version` | `codex --version` if the report originates from a Codex session |
322
+ | `os` | Local ticket's environment notes; or `uname -srm` of the reporting host |
323
+ | `description` | Local ticket's `## Description` section |
324
+ | `symptoms` | Local ticket's `## Symptoms` section |
325
+ | `workaround` | Local ticket's `## Workaround` section (or "None identified yet.") |
326
+ | `frequency` | Local ticket's `## Impact Assessment` Frequency line |
327
+ | `evidence` | Commit SHAs, test output, transcript excerpts from Investigation Tasks |
328
+
329
+ #### Versions schema (the "Report-upstream classifier is problem-first — supersedes Decision Outcome Steps 3 + 5" architecture rule amendment 2026-05-03, the "/wr-itil:report-upstream report body lacks consolidated Versions section" problem)
330
+
331
+ Every body — matched-template path AND structured-default fallback — MUST include a labelled `## Versions` section carrying the five-field schema below. Missing fields render as `not detected` (normative MUST per the "Report-upstream classifier is problem-first — supersedes Decision Outcome Steps 3 + 5" architecture rule amendment); omitting a field entirely is non-compliant because triage cannot distinguish *field omitted because not applicable* from *detection failed*.
332
+
333
+ ```markdown
334
+ ## Versions
335
+
336
+ - Local plugin: `@windyroad/<pkg>@<version>` (or "not detected" if reporting against a non-windyroad package)
337
+ - Upstream package: `<pkg>@<version>` (or "not detected" if not applicable)
338
+ - Codex CLI: `<codex --version output>` (or "not detected")
339
+ - Node: `<node --version output>` (or "not detected")
340
+ - OS: `<uname -srm output or platform detection>` (or "not detected")
341
+ ```
342
+
343
+ **Auto-population sources** (best-effort; each source returns "not detected" on failure rather than crashing the skill):
344
+
345
+ - **Local plugin** — read `package.json` for `@windyroad/*` dependencies; or run `codex plugin list` and pick the matching plugin.
346
+ - **Upstream package** — `gh api repos/<owner>/<repo>/releases/latest` (GitHub-hosted) or `npm view <pkg> version` (npm-published); fall back to the local ticket's environment notes if neither resolves.
347
+ - **Codex CLI** — `codex --version`.
348
+ - **Node** — `node --version`.
349
+ - **OS** — `uname -srm` (POSIX) or platform-equivalent.
350
+
351
+ Cost note: `gh api` and `npm view` are network calls; cache within a session where reasonable. The five-field schema is fixed so downstream consumers (the "inbound assessment pipeline lacks version-aware classification — already-fixed-in-newer / recurred / still-active branches" problem's inbound version-aware classifier, when it lands) parse against a stable surface.
352
+
353
+ For upstream repos whose matched template is `bug-report.yml` / `feature-request.yml` / `question.yml` (Step 3 backward-compat fallback), the skill fills the corresponding field set: `reproduction` ← `## Symptoms`; `expected` / `actual` ← observed-vs-expected contrast lines under `## Description`; `proposal` (for features) ← `## Description`.
354
+
355
+ #### Structured default body — problem-shaped (primary, per the "Report-upstream classifier is problem-first — supersedes Decision Outcome Steps 3 + 5" architecture rule)
356
+
357
+ Use this body when the Step 3 classifier picked `problem` shape AND the upstream has no `problem-report.yml` / `problem.yml` / `problem-report.md` / `problem.md`:
358
+
359
+ ```markdown
360
+ ## Description
361
+
362
+ <one-paragraph synthesis of the local ticket's Description>
363
+
364
+ ## Symptoms
365
+
366
+ <bullet list from local ticket's Symptoms>
367
+
368
+ ## Workaround
369
+
370
+ <from local ticket's Workaround section; "None identified yet." if absent>
371
+
372
+ ## Affected plugin / component
373
+
374
+ <inferred from the local ticket's Impact Assessment or inferred from context>
375
+
376
+ ## Frequency
377
+
378
+ <from the local ticket's Impact Assessment "Frequency" line>
379
+
380
+ ## Versions
381
+
382
+ - Local plugin: `@windyroad/<pkg>@<version>` (or "not detected")
383
+ - Upstream package: `<pkg>@<version>` (or "not detected")
384
+ - Codex CLI: <codex --version output> (or "not detected")
385
+ - Node: <node --version output> (or "not detected")
386
+ - OS: <uname -srm output> (or "not detected")
387
+
388
+ ## Evidence
389
+
390
+ <commit SHAs, test output, transcript excerpts — drawn from the local ticket's Investigation Tasks>
391
+
392
+ ## Cross-reference
393
+
394
+ Reported from <downstream-repo-url>/<local-ticket-relative-path>
395
+
396
+ This issue is tracked locally as P<NNN> in the downstream project's `docs/problems/` directory.
397
+ ```
398
+
399
+ The body MUST include the `## Cross-reference` section so Step 7's back-write contract works (the downstream ticket's `## Reported Upstream` section records the upstream URL; the upstream issue body records the downstream reference). The body MUST also include the labelled `## Versions` section per the "Report-upstream classifier is problem-first — supersedes Decision Outcome Steps 3 + 5" architecture rule amendment 2026-05-03 (the "/wr-itil:report-upstream report body lacks consolidated Versions section" problem); see the Versions schema block under Step 5's field-mapping table for the five-field contract and "not detected" rendering rule.
400
+
401
+ #### Structured default body — bug-shaped (fallback-only)
402
+
403
+ Use this body only when the Step 3 classifier picked `bug` shape as backward-compat fallback (no primary `problem` tokens matched) AND the upstream has no matching template:
404
+
405
+ ```markdown
406
+ ## Summary
407
+
408
+ <one-paragraph synthesis of the local ticket's Description>
409
+
410
+ ## Steps to reproduce
411
+
412
+ <bullet list or numbered steps from local ticket's Symptoms>
413
+
414
+ ## Expected behaviour
415
+
416
+ <from local ticket>
417
+
418
+ ## Actual behaviour
419
+
420
+ <from local ticket>
421
+
422
+ ## Versions
423
+
424
+ - Local plugin: `@windyroad/<pkg>@<version>` (or "not detected")
425
+ - Upstream package: `<pkg>@<version>` (or "not detected")
426
+ - Codex CLI: <codex --version output> (or "not detected")
427
+ - Node: <node --version output> (or "not detected")
428
+ - OS: <uname -srm output> (or "not detected")
429
+
430
+ ## Cross-reference
431
+
432
+ Reported from <downstream-repo-url>/<local-ticket-relative-path>
433
+
434
+ This issue is tracked locally as P<NNN> in the downstream project's `docs/problems/` directory.
435
+ ```
436
+
437
+ The bug-shaped fallback also includes the labelled `## Versions` section per the "Report-upstream classifier is problem-first — supersedes Decision Outcome Steps 3 + 5" architecture rule amendment 2026-05-03 (the "/wr-itil:report-upstream report body lacks consolidated Versions section" problem) — schema and "not detected" rendering rule are common to both default body shapes.
438
+
439
+ #### Structured default body — feature-shaped (fallback-only)
440
+
441
+ Use this body only when the Step 3 classifier picked `feature` shape as backward-compat fallback AND the upstream has no matching template:
442
+
443
+ ```markdown
444
+ ## Proposal
445
+
446
+ <one-paragraph synthesis of the local ticket's Description>
447
+
448
+ ## Motivation
449
+
450
+ <why this matters, from local ticket's Impact Assessment>
451
+
452
+ ## Alternatives considered
453
+
454
+ <from local ticket's Root Cause Analysis or Candidate fix options>
455
+
456
+ ## Cross-reference
457
+
458
+ Reported from <downstream-repo-url>/<local-ticket-relative-path>
459
+
460
+ This issue is tracked locally as P<NNN> in the downstream project's `docs/problems/` directory.
461
+ ```
462
+
463
+ #### Structured default body — question-shaped (fallback-only)
464
+
465
+ Use this body only when the Step 3 classifier picked `question` shape as backward-compat fallback AND the upstream has no matching template (and no `config.yml` re-routing to Discussions):
466
+
467
+ ```markdown
468
+ ## Question
469
+
470
+ <the question itself, from the local ticket's title or Description>
471
+
472
+ ## Context
473
+
474
+ <what prompted the question, from local ticket's Description or Symptoms>
475
+
476
+ ## Cross-reference
477
+
478
+ Reported from <downstream-repo-url>/<local-ticket-relative-path>
479
+
480
+ This issue is tracked locally as P<NNN> in the downstream project's `docs/problems/` directory.
481
+ ```
482
+
483
+ Retain the completed issue-shaped body separately so a failed pull-request attempt cannot overwrite its fallback:
484
+
485
+ ```bash
486
+ ISSUE_BODY="${FILLED_BODY}"
487
+ ```
488
+
489
+ Open the issue:
490
+
491
+ ```bash
492
+ gh issue create \
493
+ --repo "${UPSTREAM_OWNER_REPO}" \
494
+ --title "${TITLE_PREFIXED_BY_TEMPLATE}" \
495
+ --body "${ISSUE_BODY}"
496
+ ```
497
+
498
+ Do **not** pass `--label` on this call (the "report-upstream SKILL.md Step 5 example uses --label flag that fails when upstream repo has no labels" problem). Labels are supplied by the matched template's YAML `labels:` frontmatter and applied by GitHub when the issue form is submitted; passing `--label <name>` for a label that has not been pre-created on the upstream repo causes `gh issue create` to hard-fail with `could not add label: '<name>' not found`. The flag is redundant when the matched template carries `labels:` and a hard-fail surface when it does not. If the upstream has no matched template at all (structured-default body path, Step 3 preference order item 7), omit labels entirely — leave triage to the upstream maintainer's existing routing.
499
+
500
+ Capture the returned issue URL. The voice-tone gate per the "External-comms gate — voice-tone + risk/leak evaluators on shared PreToolUse surface" architecture rule may delegate-and-retry; treat this as expected (see "Voice-tone gate interaction" above). Proceed to Step 7 once the issue is created.
501
+
502
+ ### 5b. Pull-request path (the "Prefer an upstream pull request over an issue when the upstream accepts pull requests" architecture rule)
503
+
504
+ Reached when Step 4c chose a pull request. The Step 5 issue body is already drafted at this point and is held as the fallback.
505
+
506
+ #### The body defers to the upstream's own template
507
+
508
+ the "Report-upstream classifier is problem-first — supersedes Decision Outcome Steps 3 + 5" architecture rule's structured default is a **problem report** — Description, Symptoms, Workaround, Affected plugin, Frequency, Versions, Evidence, Cross-reference. That shape is incoherent on a pull request, where the diff already resolves the symptoms it would recite. the "Report-upstream classifier is problem-first — supersedes Decision Outcome Steps 3 + 5" architecture rule's classifier and its structured default remain unchanged and in force on the issue branch; only this branch differs.
509
+
510
+ 1. Fetch `.github/PULL_REQUEST_TEMPLATE.md` (also try `.github/pull_request_template.md` and `docs/PULL_REQUEST_TEMPLATE.md`). **If one exists, fill it.** This is the same posture as respecting the upstream's curated issue templates, applied to a second artefact kind.
511
+ 2. If none exists, use the reduced shape below — rationale plus cross-reference, not a problem report:
512
+
513
+ ```markdown
514
+ ## What this changes
515
+
516
+ <one paragraph: the change, in the upstream's own vocabulary>
517
+
518
+ ## Why
519
+
520
+ <the problem this fixes, stated as the upstream experiences it — not as our
521
+ ticket experiences it. Link an existing upstream issue if one covers it.>
522
+
523
+ ## Cross-reference
524
+
525
+ Reported from <downstream-repo-url>/<local-ticket-relative-path>, where this
526
+ is tracked as P<NNN>.
527
+ ```
528
+
529
+ Keep it short. A pull request body that recites symptoms the diff already answers reads as noise to a reviewer.
530
+
531
+ Retain this separately as `PR_BODY`; never overwrite `ISSUE_BODY`.
532
+
533
+ #### Show the diff before opening it
534
+
535
+ The external-comms gate forces a turn here to review the prose. Nothing reviews the **patch** — no surface in this repo reads a diff against an upstream's conventions (the "An upstream pull-request diff is not scored against the upstream's conventions" problem). So make the patch visible at the stop that is already happening, rather than letting it go out unseen:
536
+
537
+ 1. Print the full patch to the session — `git diff` against the upstream's base branch — immediately before `gh pr create`.
538
+ 2. State in the drafted body which of the upstream's own convention files you read and complied with: `CONTRIBUTING.md`, `.github/PULL_REQUEST_TEMPLATE.md`, a linter config, a CI workflow. Name the file. If you read none, say so.
539
+
540
+ This adds no `request_user_input` and does not reopen Step 4c's silent determination. It converts an invisible diff into a visible one at a turn the reviewer is already stopped on, which is the cheapest control available until the "An upstream pull-request diff is not scored against the upstream's conventions" problem is closed.
541
+
542
+ #### Build and open it from an isolated upstream checkout
543
+
544
+ Do not author the upstream patch in the downstream project's working tree. Use a temporary clone, create one branch, apply the smallest defensible patch, run the upstream's documented checks, commit it, and push it to a fork (or directly only when write access is already available).
545
+
546
+ ```bash
547
+ UPSTREAM_BASE=$(echo "$REPO_JSON" | jq -r '.default_branch')
548
+ UPSTREAM_CHECKOUT=$(mktemp -d)
549
+ BRANCH="windyroad/p${LOCAL_ID}-$(printf '%s' "$TITLE" | tr '[:upper:] ' '[:lower:]-' | tr -cd '[:alnum:]-' | cut -c1-40)"
550
+
551
+ PR_URL=$(
552
+ gh repo clone "$UPSTREAM_OWNER_REPO" "$UPSTREAM_CHECKOUT/repo" -- --filter=blob:none
553
+ cd "$UPSTREAM_CHECKOUT/repo"
554
+ git switch -c "$BRANCH" "origin/$UPSTREAM_BASE"
555
+
556
+ # Apply the patch, run the upstream's documented checks, then:
557
+ git add --all
558
+ git commit -m "fix: <upstream-facing summary>"
559
+ gh repo fork "$UPSTREAM_OWNER_REPO" --remote --remote-name fork
560
+ git push --set-upstream fork "$BRANCH"
561
+
562
+ GH_USER=$(gh api user --jq .login)
563
+ git diff "origin/$UPSTREAM_BASE...HEAD" >&2
564
+ gh pr create \
565
+ --repo "${UPSTREAM_OWNER_REPO}" \
566
+ --base "${UPSTREAM_BASE}" \
567
+ --head "${GH_USER}:${BRANCH}" \
568
+ --title "${TITLE}" \
569
+ --body "${PR_BODY}"
570
+ )
571
+ ```
572
+
573
+ The command substitution is a subshell, so Step 7 resumes in the downstream checkout. Immediately before `gh pr create`, explicitly review `${TITLE}` plus `${PR_BODY}` together through both external-communications evaluators. Do not rely on the command hook for the title: it extracts the body only.
574
+
575
+ Invoke it at a command start or after `;` / `&&` / `||`, never through a pipe, or the external-comms gate does not match the surface and silently skips the review. Do not pass `--label` for the same reason Step 5 does not (the "report-upstream SKILL.md Step 5 example uses --label flag that fails when upstream repo has no labels" problem).
576
+
577
+ Capture the returned pull-request URL and proceed to Step 7, recording disclosure path `pull request`.
578
+
579
+ If the attempt fails at any point, file the drafted Step 5 issue instead and record `public issue`. A failed pull request must never cost us the report.
580
+
581
+ ### 5c. Comment path (the "Problem 070: /wr-itil:report-upstream does not check for existing upstream issues before filing" problem)
582
+
583
+ Used when Step 4b's dedup check (own re-run or third-party search) finds a match AND the user picks the "comment instead" option. Skips `gh issue create` and posts a cross-reference comment on the existing upstream issue:
584
+
585
+ **Branch on what the dedup check actually matched (the "Prefer an upstream pull request over an issue when the upstream accepts pull requests" architecture rule).** Step 4b.2 now searches pull requests as well as issues, so the match may be either. `gh issue comment` errors on a pull request:
586
+
587
+ ```bash
588
+ # Issue match:
589
+ gh issue comment "${EXISTING_NUMBER}" \
590
+ --repo "${UPSTREAM_OWNER_REPO}" \
591
+ --body "${COMMENT_BODY}"
592
+
593
+ # Pull-request match:
594
+ gh pr comment "${EXISTING_NUMBER}" \
595
+ --repo "${UPSTREAM_OWNER_REPO}" \
596
+ --body "${COMMENT_BODY}"
597
+ ```
598
+
599
+ The comment body is a condensed cross-reference, not a full report restatement. Required structure:
600
+
601
+ ```markdown
602
+ Seeing this from <downstream-repo-url>/<local-ticket-relative-path>.
603
+
604
+ ## Additional context
605
+
606
+ - **Local ticket**: P<NNN> (<one-line title>)
607
+ - **Reproduction**: <if local has a fresh repro path the existing issue lacks; otherwise omit>
608
+ - **Environment**: <if differs materially from the existing issue; otherwise omit>
609
+ - **Hypothesis**: <if local has a contradictory or extending root-cause hypothesis; otherwise omit>
610
+
611
+ This issue is tracked locally as P<NNN> in the downstream project's `docs/problems/` directory.
612
+ ```
613
+
614
+ Empty subsections are skipped — the comment should add information, not restate what the existing issue already records. If none of the four "additional context" subsections has content, the comment defaults to a one-line acknowledgement: `Seeing this from <downstream-repo-url>/<local-ticket-relative-path>. Tracked locally as P<NNN>.` This is still useful — it tells the upstream maintainer they have a downstream witness — without spamming the thread with redundant content.
615
+
616
+ The voice-tone gate per the "External-comms gate — voice-tone + risk/leak evaluators on shared PreToolUse surface" architecture rule also fires on `gh issue comment` (per the canonical hook's regex list at the "External-comms gate — voice-tone + risk/leak evaluators on shared PreToolUse surface" architecture rule line 61); treat the deny-plus-delegate-and-retry as expected, same as Step 5.
617
+
618
+ Capture the returned comment URL. The Step 7 back-write records an issue match as `commented-on-existing-issue` and a pull-request match as `commented-on-existing-pull-request`. Proceed to Step 7.
619
+
620
+ ### 6. Security path
621
+
622
+ Fetch the upstream's `SECURITY.md`:
623
+
624
+ ```bash
625
+ SECURITY_MD=$(gh api "repos/${UPSTREAM_OWNER_REPO}/contents/SECURITY.md" --jq '.content' 2>/dev/null | base64 -d)
626
+ ```
627
+
628
+ Parse for a disclosure channel:
629
+
630
+ - **GitHub Security Advisories** (most common — link looks like `github.com/<owner>/<repo>/security/advisories/new` or the body says "use Security Advisories"):
631
+ ```bash
632
+ gh api "repos/${UPSTREAM_OWNER_REPO}/security-advisories" --method POST \
633
+ --input - <<EOF
634
+ {
635
+ "summary": "${TITLE}",
636
+ "description": "${STRUCTURED_BODY}",
637
+ "severity": "${SEVERITY}",
638
+ "vulnerabilities": []
639
+ }
640
+ EOF
641
+ ```
642
+ - **`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 `## Queued Upstream Report` appendage section so the user can copy + send.
643
+ - **Other documented channel** (Tidelift, HackerOne, vendor-specific URL): halt and surface the channel + drafted report.
644
+
645
+ If upstream has **NO `SECURITY.md`** (404):
646
+ - **Interactive context**: use `request_user_input` per the "Structured User Interaction for Governance-Skill Decisions" architecture rule Rule 1 with options:
647
+ - `(a) Open a private GitHub Security Advisory` — uses `gh api repos/.../security-advisories` against the upstream if it's GitHub-hosted.
648
+ - `(b) Contact the maintainer out-of-band first` — halt, no automated action.
649
+ - `(c) Downgrade the classification (your judgement)` — re-route via the public-issue path in Step 5.
650
+ - **AFK / non-interactive context** (per the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule 2026-06-04 (the "Agent waits for human to initiate upstream report instead of filing on detect — feedback delay class" problem) amendment — **supersedes the pre-amendment "must never auto-report a security-classified ticket" rule**): score the drafted prose via `wr-risk-scorer:external-comms` (the "External-comms gate — voice-tone + risk/leak evaluators on shared PreToolUse surface" architecture rule). **Per the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule 2026-06-04 second-amendment leaf (b) — ratified 2026-06-04**: if upstream has a `SECURITY.md` declaring a channel AND scored below-appetite → file via that channel (Step 6 routing). If upstream has NO `SECURITY.md` but another disclosure channel exists → run the external-comms risk assessment considering impact to (i) our repository, (ii) our reputation, (iii) the party we are reporting to. Below-appetite → proceed (save the report to `## Queued Upstream Report` if the channel is non-automatable like a mailbox — the channel-action stays user-side per the no-infra-for-email constraint) + queue `outstanding_questions` entry naming the channel. Above-appetite → risk-reduce + re-score then queue per the same shape (the risk-reducing-measures vocabulary is **open-ended LLM judgement** per leaf (a) — the `wr-risk-scorer:external-comms` agent's own scoring picks the remedy case-by-case; not a bounded enumeration). Orchestrator continues per the "AFK iter default when a skill needs to ask a question and request_user_input is unavailable — should queue the question and move to the next iteration (not halt, not silently skip)" problem queue-and-continue. The pre-amendment "AFK orchestrators must never auto-report" / "Never auto-open a public issue for a security-classified ticket" rules are **superseded** — both are now external-comms-gated per the 2026-06-04 amendment.
651
+
652
+ **[Legacy phrase retained for traceability — superseded by the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule 2026-06-04 amendment]** Never auto-open a public issue for a security-classified ticket — the pre-amendment ban is now subordinated to the external-comms-gated per-classification branching above.
653
+
654
+ ### 7. Cross-reference back-write
655
+
656
+ 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:
657
+
658
+ 1. To the existing `## Related` section (or create one if absent):
659
+ ```markdown
660
+ - **Reported upstream**: <upstream-issue-or-advisory-url> (<YYYY-MM-DD>)
661
+ ```
662
+
663
+ 2. A new `## Reported Upstream` section appended after the existing sections (never inserted mid-document — preserve existing structure):
664
+ ```markdown
665
+ ## Reported Upstream
666
+
667
+ - **URL**: <upstream-issue-or-advisory-url>
668
+ - **Reported**: <YYYY-MM-DD>
669
+ - **Template used**: <template-name-or-"structured default">
670
+ - **Disclosure path**: <public issue | pull request (Step 5b, the "Prefer an upstream pull request over an issue when the upstream accepts pull requests" architecture rule) | security advisory | drafted-and-saved (mailbox / out-of-band) | commented-on-existing-issue (Step 5c, the "Problem 070: /wr-itil:report-upstream does not check for existing upstream issues before filing" problem) | commented-on-existing-pull-request (Step 5c, the "Prefer an upstream pull request over an issue when the upstream accepts pull requests" architecture rule)>
671
+ - **Cross-reference confirmed**: <yes/no — true once the upstream issue body contains the local ticket reference>
672
+ ```
673
+
674
+ The `pull request` and `commented-on-existing-pull-request` values are what `/wr-itil:check-upstream-responses` and `/wr-itil:update-upstream` read to pick `gh pr view` and `gh pr comment` over their issue equivalents. Write them exactly; an absent line is read as `public issue`, which is correct for tickets predating the "Prefer an upstream pull request over an issue when the upstream accepts pull requests" architecture rule but wrong for a pull request.
675
+
676
+ ### 8. Commit per the "Governance Skills Commit Their Own Completed Work" architecture rule
677
+
678
+ Follow the "Governance Skills Commit Their Own Completed Work" architecture rule ordering:
679
+
680
+ 1. `git add docs/problems/<NNN>-<title>.<status>.md` (and any `## Queued Upstream Report` appendage if security-path halt fired).
681
+ 2. Score commit/push/release risk via `wr-risk-scorer:pipeline` subagent (or fall back to `/wr-risk-scorer:assess-release` skill per the "On-Demand Assessment Skills for Governance Plugins" architecture rule).
682
+ 3. `git commit -m "docs(problems): P<NNN> reported upstream — <one-line summary>"`.
683
+
684
+ 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 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.
685
+
686
+ ## AFK behaviour summary
687
+
688
+ Six distinct AFK branches; **per the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule 2026-06-04 (the "Agent waits for human to initiate upstream report instead of filing on detect — feedback delay class" problem) amendment, ALL pre-commit branches now route through the `wr-risk-scorer:external-comms` gate** (the "External-comms gate — voice-tone + risk/leak evaluators on shared PreToolUse surface" architecture rule) — below-appetite proceeds, above-appetite risk-reduces then queues. The legacy "halt the orchestrator" semantics for dedup-match and security-path-without-declared-channel are **superseded** by queue-and-continue per the "AFK iter default when a skill needs to ask a question and request_user_input is unavailable — should queue the question and move to the next iteration (not halt, not silently skip)" problem:
689
+
690
+ | Branch | AFK behaviour | Authority |
691
+ |---|---|---|
692
+ | Public-issue path (Step 5) | Score drafted prose via `wr-risk-scorer:external-comms` (the "External-comms gate — voice-tone + risk/leak evaluators on shared PreToolUse surface" architecture rule). Below-appetite → proceed via `gh issue create`. Above-appetite → risk-reduce + re-score; if within → proceed; else → save draft to `## Queued Upstream Report` + queue `outstanding_questions` entry; orchestrator continues. Risk-reducing measures vocabulary is **open-ended LLM judgement** per the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule 2026-06-04 second-amendment leaf (a) — `wr-risk-scorer:external-comms` picks the remedy case-by-case. Voice-tone gate per the "External-comms gate — voice-tone + risk/leak evaluators on shared PreToolUse surface" architecture rule may also delegate-and-retry on the proceed path. | the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule 2026-06-04 amendment (the "Agent waits for human to initiate upstream report instead of filing on detect — feedback delay class" problem); the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule 2026-06-04 second-amendment (leaf a — open vocabulary); the "External-comms gate — voice-tone + risk/leak evaluators on shared PreToolUse surface" architecture rule line 126 |
693
+ | Dedup match — Step 4b (own re-run OR third-party `same-problem`) | Score the proposed comment body via `wr-risk-scorer:external-comms`. Below-appetite → comment on the matching issue or pull request (Step 5c). Above-appetite → risk-reduce + re-score (open-ended LLM judgement per leaf (a)); if within → proceed; else → save draft to `## Queued Upstream Report` + queue `outstanding_questions` entry; orchestrator continues. | the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule 2026-06-04 amendment (the "Agent waits for human to initiate upstream report instead of filing on detect — feedback delay class" problem); the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule 2026-04-25 amendment (the "Problem 070: /wr-itil:report-upstream does not check for existing upstream issues before filing" problem); the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule 2026-06-04 second-amendment (leaf a) |
694
+ | Security path with declared channel (Step 6, GitHub Advisories — upstream has `SECURITY.md`) | Per the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule 2026-06-04 second-amendment leaf (b) — ratified: if upstream has `SECURITY.md` AND below-appetite → **file** via the SECURITY.md-declared channel. Above-appetite → risk-reduce + re-score (open-ended LLM judgement per leaf (a)); if within → proceed; else → save draft + queue; orchestrator continues. | the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule 2026-06-04 amendment (the "Agent waits for human to initiate upstream report instead of filing on detect — feedback delay class" problem); the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule 2026-06-04 second-amendment (leaf b); the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule Decision Outcome step 6 |
695
+ | Security path with `security@` / other / missing-SECURITY.md (Step 6) | Per the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule 2026-06-04 second-amendment leaf (b) — ratified: when upstream has NO `SECURITY.md` but another disclosure channel exists, score drafted prose via `wr-risk-scorer:external-comms` considering impact to (i) our repository, (ii) our reputation, (iii) the party we are reporting to. Below-appetite → save drafted report to `## Queued Upstream Report` + queue `outstanding_questions` entry naming the channel the user must follow on return (the no-infra-for-email constraint still holds — the channel-action remains user-side, but the queue surface replaces the loop-stopping halt). Above-appetite → risk-reduce + re-score (open-ended LLM judgement per leaf (a)) then queue per the same shape. Orchestrator continues. The pre-2026-06-04 "AFK orchestrators must never auto-report a security-classified ticket" rule is **superseded** by the external-comms-gated per-classification branching. | the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule 2026-06-04 amendment (the "Agent waits for human to initiate upstream report instead of filing on detect — feedback delay class" problem); the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule 2026-06-04 second-amendment (leaf b); the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule Consequences lines 116, 123 (superseded) |
696
+ | **Pull-request path (Step 5b)** | **Degrade to the issue branch.** No unattended session opens a pull request against a repository we do not own. File the issue per the Public-issue-path row above, and append the drafted pull request (body + the change it would have made) to `## Queued Upstream Report` for the interactive return. **Also surface it in the orchestrator's progress summary** — a returning developer must see "a pull request was drafted and queued" without opening the ticket. The external-comms gate reads prose; it cannot authorise pushing code into a third party's repository under our name, and that is a judgement call an unattended loop does not get to make. | the "Prefer an upstream pull request over an issue when the upstream accepts pull requests" architecture rule (AFK degrade); the ": Progress the Backlog While I'm Away" user outcome (no unattended judgement calls; visible on return) |
697
+ | Above-appetite commit (Step 8) | Skip the commit, report uncommitted state. | the "Structured User Interaction for Governance-Skill Decisions" architecture rule Rule 6 |
698
+
699
+ ## References
700
+
701
+ - [the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule](../../../docs/decisions/024-cross-project-problem-reporting-contract.proposed.md) — primary contract this skill implements. Steps 1, 2, 4, 6, 7, 8 and all Consequences remain authoritative; the 2026-04-25 amendment adds Step 4b (dedup) + Step 5c (comment path) for the "Problem 070: /wr-itil:report-upstream does not check for existing upstream issues before filing" problem.
702
+ - [the "Report-upstream classifier is problem-first — supersedes Decision Outcome Steps 3 + 5" architecture rule](../../../docs/decisions/033-report-upstream-classifier-problem-first.proposed.md) — partially supersedes the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule Decision Outcome Steps 3 + 5; governs the problem-first classifier and problem-shaped structured default body.
703
+ - [the "Problem 070: /wr-itil:report-upstream does not check for existing upstream issues before filing" problem](../../../docs/problems/) — driver ticket for the Step 4b dedup check + Step 5c comment path; carries the 2026-04-21 Direction decision (gh search + inline LLM, no subagent dispatch) and the AFK static-heuristic interim behaviour.
704
+ - [the "Governance skill auto-delegation — Step 0 delegates skill workflow to a subagent" architecture rule](../../../docs/decisions/027-governance-skill-auto-delegation.proposed.md) — Step-0 deferral rationale (held for reassessment).
705
+ - [the "Prefer an upstream pull request over an issue when the upstream accepts pull requests" architecture rule](../../../docs/decisions/117-prefer-an-upstream-pull-request-over-an-issue.proposed.md) — prefer an upstream pull request over an issue when the upstream accepts pull requests. Adds Step 4c (artefact choice) and Step 5b (pull-request path), extends Step 4b.2's dedup search to pull requests, branches Step 5c's comment call, and widens Step 7's disclosure-path enumeration without editing the "Cross-project problem-reporting contract — `report-upstream` skill in `@windyroad/itil`" architecture rule or the "Report-upstream classifier is problem-first — supersedes Decision Outcome Steps 3 + 5" architecture rule.
706
+ - [the "An upstream pull-request diff is not scored against the upstream's conventions" problem](../../../docs/problems/open/497-upstream-pull-request-diff-is-unscored.md) — the pull-request **diff** is unscored. The prose is gated; nothing reads the diff against an upstream's policy. Named by the "Prefer an upstream pull request over an issue when the upstream accepts pull requests" architecture rule and deliberately left open.
707
+ - [the "External-comms gate — voice-tone + risk/leak evaluators on shared PreToolUse surface" architecture rule](../../../docs/decisions/028-voice-tone-gate-external-comms.proposed.md) — voice-tone gate on `gh issue create`, `gh pr create`, `gh issue comment`, `gh pr comment` and `gh api .../security-advisories`.
708
+ - [the "Structured User Interaction for Governance-Skill Decisions" architecture rule](../../../docs/decisions/013-structured-user-interaction-for-governance-decisions.proposed.md) — interaction policy; Rule 1 governs Step 6 missing-SECURITY.md `request_user_input`; Rule 6 governs the commit-gate AFK branch.
709
+ - [the "Governance Skills Commit Their Own Completed Work" architecture rule](../../../docs/decisions/014-governance-skills-commit-their-own-work.proposed.md) — work → score → commit ordering.
710
+ - [the "On-Demand Assessment Skills for Governance Plugins" architecture rule](../../../docs/decisions/015-on-demand-assessment-skills.proposed.md) — fallback path for `wr-risk-scorer:assess-release`.
711
+ - [the "Problem 055: No standard problem-reporting channel for plugin users, and no reusable pattern for downstream projects to report upstream" problem](../../../docs/problems/055-no-standard-problem-reporting-channel.open.md) — upstream problem ticket (Part B).
712
+ - **the "Problem 066: Intake templates split bug / feature instead of a problem-first template — misaligned with ITIL problem management" problem** — intake templates in this repo adopted the problem-first shape (must ship before the "Problem 067: /wr-itil:report-upstream classifier is not problem-first — picks bug / feature / question and emits a bug-shaped default" problem so the skill's preference order matches the reference shape).
713
+ - **the "Problem 067: /wr-itil:report-upstream classifier is not problem-first — picks bug / feature / question and emits a bug-shaped default" problem** — driver ticket for the problem-first classifier reform implemented via the "Report-upstream classifier is problem-first — supersedes Decision Outcome Steps 3 + 5" architecture rule.
714
+ - `<itil-plugin-root>/skills/manage-problem/SKILL.md` — names the optional `## Reported Upstream` section as an allowed appendage to a problem ticket.
715
+
716
+ $ARGUMENTS