aw-ecc 1.4.32 → 1.4.47

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 (258) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.codex/hooks/aw-post-tool-use.sh +8 -2
  3. package/.codex/hooks/aw-session-start.sh +11 -4
  4. package/.codex/hooks/aw-stop.sh +8 -2
  5. package/.codex/hooks/aw-user-prompt-submit.sh +10 -2
  6. package/.codex/hooks.json +8 -8
  7. package/.cursor/INSTALL.md +7 -5
  8. package/.cursor/hooks/adapter.js +41 -4
  9. package/.cursor/hooks/after-agent-response.js +62 -0
  10. package/.cursor/hooks/before-submit-prompt.js +7 -1
  11. package/.cursor/hooks/post-tool-use-failure.js +21 -0
  12. package/.cursor/hooks/post-tool-use.js +39 -0
  13. package/.cursor/hooks/shared/aw-phase-definitions.js +53 -0
  14. package/.cursor/hooks/shared/aw-phase-runner.js +3 -1
  15. package/.cursor/hooks/subagent-start.js +22 -4
  16. package/.cursor/hooks/subagent-stop.js +18 -1
  17. package/.cursor/hooks.json +23 -2
  18. package/.opencode/package.json +1 -1
  19. package/AGENTS.md +3 -3
  20. package/README.md +5 -5
  21. package/commands/adk.md +52 -0
  22. package/commands/build.md +22 -9
  23. package/commands/deploy.md +12 -0
  24. package/commands/execute.md +9 -0
  25. package/commands/feature.md +333 -0
  26. package/commands/investigate.md +18 -5
  27. package/commands/plan.md +23 -9
  28. package/commands/publish.md +65 -0
  29. package/commands/review.md +12 -0
  30. package/commands/ship.md +12 -0
  31. package/commands/test.md +12 -0
  32. package/commands/verify.md +9 -0
  33. package/hooks/hooks.json +36 -0
  34. package/manifests/install-components.json +8 -0
  35. package/manifests/install-modules.json +83 -0
  36. package/manifests/install-profiles.json +7 -0
  37. package/package.json +1 -1
  38. package/scripts/ci/validate-rules.js +51 -0
  39. package/scripts/cursor-aw-home/hooks.json +23 -2
  40. package/scripts/cursor-aw-hooks/adapter.js +41 -4
  41. package/scripts/cursor-aw-hooks/before-submit-prompt.js +7 -1
  42. package/scripts/hooks/aw-usage-commit-created.js +32 -0
  43. package/scripts/hooks/aw-usage-post-tool-use-failure.js +56 -0
  44. package/scripts/hooks/aw-usage-post-tool-use.js +242 -0
  45. package/scripts/hooks/aw-usage-prompt-submit.js +112 -0
  46. package/scripts/hooks/aw-usage-session-start.js +48 -0
  47. package/scripts/hooks/aw-usage-stop.js +182 -0
  48. package/scripts/hooks/aw-usage-telemetry-send.js +84 -0
  49. package/scripts/hooks/cost-tracker.js +3 -23
  50. package/scripts/hooks/shared/aw-phase-definitions.js +53 -0
  51. package/scripts/hooks/shared/aw-phase-runner.js +3 -1
  52. package/scripts/lib/aw-hook-contract.js +2 -2
  53. package/scripts/lib/aw-pricing.js +306 -0
  54. package/scripts/lib/aw-usage-telemetry.js +472 -0
  55. package/scripts/lib/codex-hook-config.js +8 -8
  56. package/scripts/lib/cursor-hook-config.js +25 -10
  57. package/scripts/lib/install-targets/cursor-project.js +3 -0
  58. package/scripts/lib/install-targets/helpers.js +20 -3
  59. package/skills/aw-adk/SKILL.md +317 -0
  60. package/skills/aw-adk/agents/analyzer.md +113 -0
  61. package/skills/aw-adk/agents/comparator.md +113 -0
  62. package/skills/aw-adk/agents/grader.md +115 -0
  63. package/skills/aw-adk/assets/eval_review.html +76 -0
  64. package/skills/aw-adk/eval-viewer/generate_review.py +164 -0
  65. package/skills/aw-adk/eval-viewer/viewer.html +181 -0
  66. package/skills/aw-adk/evals/eval-colocated-placement.md +84 -0
  67. package/skills/aw-adk/evals/eval-create-agent.md +90 -0
  68. package/skills/aw-adk/evals/eval-create-command.md +98 -0
  69. package/skills/aw-adk/evals/eval-create-eval.md +89 -0
  70. package/skills/aw-adk/evals/eval-create-rule.md +99 -0
  71. package/skills/aw-adk/evals/eval-create-skill.md +97 -0
  72. package/skills/aw-adk/evals/eval-delete-agent.md +79 -0
  73. package/skills/aw-adk/evals/eval-delete-command.md +89 -0
  74. package/skills/aw-adk/evals/eval-delete-rule.md +86 -0
  75. package/skills/aw-adk/evals/eval-delete-skill.md +90 -0
  76. package/skills/aw-adk/evals/eval-meta-eval-coverage.md +78 -0
  77. package/skills/aw-adk/evals/eval-meta-eval-determinism.md +81 -0
  78. package/skills/aw-adk/evals/eval-meta-eval-false-pass.md +81 -0
  79. package/skills/aw-adk/evals/eval-score-accuracy.md +95 -0
  80. package/skills/aw-adk/evals/eval-type-redirect.md +68 -0
  81. package/skills/aw-adk/evals/evals.json +96 -0
  82. package/skills/aw-adk/references/artifact-wiring.md +162 -0
  83. package/skills/aw-adk/references/cross-ide-mapping.md +71 -0
  84. package/skills/aw-adk/references/eval-placement-guide.md +183 -0
  85. package/skills/aw-adk/references/external-resources.md +75 -0
  86. package/skills/aw-adk/references/getting-started.md +66 -0
  87. package/skills/aw-adk/references/registry-structure.md +152 -0
  88. package/skills/aw-adk/references/rubric-agent.md +36 -0
  89. package/skills/aw-adk/references/rubric-command.md +36 -0
  90. package/skills/aw-adk/references/rubric-eval.md +36 -0
  91. package/skills/aw-adk/references/rubric-meta-eval.md +132 -0
  92. package/skills/aw-adk/references/rubric-rule.md +36 -0
  93. package/skills/aw-adk/references/rubric-skill.md +36 -0
  94. package/skills/aw-adk/references/schemas.md +222 -0
  95. package/skills/aw-adk/references/template-agent.md +251 -0
  96. package/skills/aw-adk/references/template-command.md +279 -0
  97. package/skills/aw-adk/references/template-eval.md +176 -0
  98. package/skills/aw-adk/references/template-rule.md +119 -0
  99. package/skills/aw-adk/references/template-skill.md +123 -0
  100. package/skills/aw-adk/references/type-classifier.md +98 -0
  101. package/skills/aw-adk/references/writing-good-agents.md +227 -0
  102. package/skills/aw-adk/references/writing-good-commands.md +258 -0
  103. package/skills/aw-adk/references/writing-good-evals.md +271 -0
  104. package/skills/aw-adk/references/writing-good-rules.md +214 -0
  105. package/skills/aw-adk/references/writing-good-skills.md +159 -0
  106. package/skills/aw-adk/scripts/aggregate-benchmark.py +190 -0
  107. package/skills/aw-adk/scripts/lint-artifact.sh +211 -0
  108. package/skills/aw-adk/scripts/score-artifact.sh +179 -0
  109. package/skills/aw-adk/scripts/trigger-eval.py +192 -0
  110. package/skills/aw-build/SKILL.md +19 -2
  111. package/skills/aw-deploy/SKILL.md +65 -3
  112. package/skills/aw-design/SKILL.md +156 -0
  113. package/skills/aw-design/references/highrise-tokens.md +394 -0
  114. package/skills/aw-design/references/micro-interactions.md +76 -0
  115. package/skills/aw-design/references/prompt-template.md +160 -0
  116. package/skills/aw-design/references/quality-checklist.md +70 -0
  117. package/skills/aw-design/references/self-review.md +497 -0
  118. package/skills/aw-design/references/stitch-workflow.md +127 -0
  119. package/skills/aw-feature/SKILL.md +293 -0
  120. package/skills/aw-investigate/SKILL.md +17 -0
  121. package/skills/aw-plan/SKILL.md +34 -3
  122. package/skills/aw-publish/SKILL.md +300 -0
  123. package/skills/aw-publish/evals/eval-confirmation-gate.md +60 -0
  124. package/skills/aw-publish/evals/eval-intent-detection.md +111 -0
  125. package/skills/aw-publish/evals/eval-push-modes.md +67 -0
  126. package/skills/aw-publish/evals/eval-rules-push.md +60 -0
  127. package/skills/aw-publish/evals/evals.json +29 -0
  128. package/skills/aw-publish/references/push-modes.md +38 -0
  129. package/skills/aw-review/SKILL.md +88 -9
  130. package/skills/aw-rules-review/SKILL.md +124 -0
  131. package/skills/aw-rules-review/agents/openai.yaml +3 -0
  132. package/skills/aw-rules-review/scripts/generate-review-template.mjs +323 -0
  133. package/skills/aw-ship/SKILL.md +16 -0
  134. package/skills/aw-spec/SKILL.md +15 -0
  135. package/skills/aw-tasks/SKILL.md +15 -0
  136. package/skills/aw-test/SKILL.md +16 -0
  137. package/skills/aw-yolo/SKILL.md +4 -0
  138. package/skills/diagnose/SKILL.md +121 -0
  139. package/skills/diagnose/scripts/hitl-loop.template.sh +41 -0
  140. package/skills/finish-only-when-green/SKILL.md +265 -0
  141. package/skills/grill-me/SKILL.md +24 -0
  142. package/skills/grill-with-docs/SKILL.md +92 -0
  143. package/skills/grill-with-docs/adr-format.md +47 -0
  144. package/skills/grill-with-docs/context-format.md +67 -0
  145. package/skills/improve-codebase-architecture/SKILL.md +75 -0
  146. package/skills/improve-codebase-architecture/deepening.md +37 -0
  147. package/skills/improve-codebase-architecture/interface-design.md +44 -0
  148. package/skills/improve-codebase-architecture/language.md +53 -0
  149. package/skills/local-ghl-setup-from-screenshot/SKILL.md +538 -0
  150. package/skills/tdd/SKILL.md +115 -0
  151. package/skills/tdd/deep-modules.md +33 -0
  152. package/skills/tdd/interface-design.md +31 -0
  153. package/skills/tdd/mocking.md +59 -0
  154. package/skills/tdd/refactoring.md +10 -0
  155. package/skills/tdd/tests.md +61 -0
  156. package/skills/to-issues/SKILL.md +62 -0
  157. package/skills/to-prd/SKILL.md +75 -0
  158. package/skills/using-aw-skills/SKILL.md +170 -237
  159. package/skills/using-aw-skills/hooks/session-start.sh +11 -41
  160. package/skills/zoom-out/SKILL.md +24 -0
  161. package/.cursor/rules/common-agents.md +0 -53
  162. package/.cursor/rules/common-aw-routing.md +0 -43
  163. package/.cursor/rules/common-coding-style.md +0 -52
  164. package/.cursor/rules/common-development-workflow.md +0 -33
  165. package/.cursor/rules/common-git-workflow.md +0 -28
  166. package/.cursor/rules/common-hooks.md +0 -34
  167. package/.cursor/rules/common-patterns.md +0 -35
  168. package/.cursor/rules/common-performance.md +0 -59
  169. package/.cursor/rules/common-security.md +0 -33
  170. package/.cursor/rules/common-testing.md +0 -33
  171. package/.cursor/skills/api-and-interface-design/SKILL.md +0 -75
  172. package/.cursor/skills/article-writing/SKILL.md +0 -85
  173. package/.cursor/skills/aw-brainstorm/SKILL.md +0 -115
  174. package/.cursor/skills/aw-build/SKILL.md +0 -152
  175. package/.cursor/skills/aw-build/evals/build-stage-cases.json +0 -28
  176. package/.cursor/skills/aw-debug/SKILL.md +0 -49
  177. package/.cursor/skills/aw-deploy/SKILL.md +0 -101
  178. package/.cursor/skills/aw-deploy/evals/deploy-stage-cases.json +0 -32
  179. package/.cursor/skills/aw-execute/SKILL.md +0 -47
  180. package/.cursor/skills/aw-execute/references/mode-code.md +0 -47
  181. package/.cursor/skills/aw-execute/references/mode-docs.md +0 -28
  182. package/.cursor/skills/aw-execute/references/mode-infra.md +0 -44
  183. package/.cursor/skills/aw-execute/references/mode-migration.md +0 -58
  184. package/.cursor/skills/aw-execute/references/worker-implementer.md +0 -26
  185. package/.cursor/skills/aw-execute/references/worker-parallel-worker.md +0 -23
  186. package/.cursor/skills/aw-execute/references/worker-quality-reviewer.md +0 -23
  187. package/.cursor/skills/aw-execute/references/worker-spec-reviewer.md +0 -23
  188. package/.cursor/skills/aw-execute/scripts/build-worker-bundle.js +0 -229
  189. package/.cursor/skills/aw-finish/SKILL.md +0 -111
  190. package/.cursor/skills/aw-investigate/SKILL.md +0 -109
  191. package/.cursor/skills/aw-plan/SKILL.md +0 -368
  192. package/.cursor/skills/aw-prepare/SKILL.md +0 -118
  193. package/.cursor/skills/aw-review/SKILL.md +0 -118
  194. package/.cursor/skills/aw-ship/SKILL.md +0 -115
  195. package/.cursor/skills/aw-spec/SKILL.md +0 -104
  196. package/.cursor/skills/aw-tasks/SKILL.md +0 -138
  197. package/.cursor/skills/aw-test/SKILL.md +0 -118
  198. package/.cursor/skills/aw-verify/SKILL.md +0 -51
  199. package/.cursor/skills/aw-yolo/SKILL.md +0 -111
  200. package/.cursor/skills/browser-testing-with-devtools/SKILL.md +0 -81
  201. package/.cursor/skills/bun-runtime/SKILL.md +0 -84
  202. package/.cursor/skills/ci-cd-and-automation/SKILL.md +0 -71
  203. package/.cursor/skills/code-simplification/SKILL.md +0 -74
  204. package/.cursor/skills/content-engine/SKILL.md +0 -88
  205. package/.cursor/skills/context-engineering/SKILL.md +0 -74
  206. package/.cursor/skills/deprecation-and-migration/SKILL.md +0 -75
  207. package/.cursor/skills/documentation-and-adrs/SKILL.md +0 -75
  208. package/.cursor/skills/documentation-lookup/SKILL.md +0 -90
  209. package/.cursor/skills/frontend-slides/SKILL.md +0 -184
  210. package/.cursor/skills/frontend-slides/STYLE_PRESETS.md +0 -330
  211. package/.cursor/skills/frontend-ui-engineering/SKILL.md +0 -68
  212. package/.cursor/skills/git-workflow-and-versioning/SKILL.md +0 -75
  213. package/.cursor/skills/idea-refine/SKILL.md +0 -84
  214. package/.cursor/skills/incremental-implementation/SKILL.md +0 -75
  215. package/.cursor/skills/investor-materials/SKILL.md +0 -96
  216. package/.cursor/skills/investor-outreach/SKILL.md +0 -76
  217. package/.cursor/skills/market-research/SKILL.md +0 -75
  218. package/.cursor/skills/mcp-server-patterns/SKILL.md +0 -67
  219. package/.cursor/skills/nextjs-turbopack/SKILL.md +0 -44
  220. package/.cursor/skills/performance-optimization/SKILL.md +0 -77
  221. package/.cursor/skills/security-and-hardening/SKILL.md +0 -70
  222. package/.cursor/skills/using-aw-skills/SKILL.md +0 -290
  223. package/.cursor/skills/using-aw-skills/evals/skill-trigger-cases.tsv +0 -25
  224. package/.cursor/skills/using-aw-skills/evals/test-skill-triggers.sh +0 -171
  225. package/.cursor/skills/using-aw-skills/hooks/hooks.json +0 -9
  226. package/.cursor/skills/using-aw-skills/hooks/session-start.sh +0 -67
  227. package/.cursor/skills/using-platform-skills/SKILL.md +0 -163
  228. package/.cursor/skills/using-platform-skills/evals/platform-selection-cases.json +0 -52
  229. /package/.cursor/rules/{golang-coding-style.md → golang-coding-style.mdc} +0 -0
  230. /package/.cursor/rules/{golang-hooks.md → golang-hooks.mdc} +0 -0
  231. /package/.cursor/rules/{golang-patterns.md → golang-patterns.mdc} +0 -0
  232. /package/.cursor/rules/{golang-security.md → golang-security.mdc} +0 -0
  233. /package/.cursor/rules/{golang-testing.md → golang-testing.mdc} +0 -0
  234. /package/.cursor/rules/{kotlin-coding-style.md → kotlin-coding-style.mdc} +0 -0
  235. /package/.cursor/rules/{kotlin-hooks.md → kotlin-hooks.mdc} +0 -0
  236. /package/.cursor/rules/{kotlin-patterns.md → kotlin-patterns.mdc} +0 -0
  237. /package/.cursor/rules/{kotlin-security.md → kotlin-security.mdc} +0 -0
  238. /package/.cursor/rules/{kotlin-testing.md → kotlin-testing.mdc} +0 -0
  239. /package/.cursor/rules/{php-coding-style.md → php-coding-style.mdc} +0 -0
  240. /package/.cursor/rules/{php-hooks.md → php-hooks.mdc} +0 -0
  241. /package/.cursor/rules/{php-patterns.md → php-patterns.mdc} +0 -0
  242. /package/.cursor/rules/{php-security.md → php-security.mdc} +0 -0
  243. /package/.cursor/rules/{php-testing.md → php-testing.mdc} +0 -0
  244. /package/.cursor/rules/{python-coding-style.md → python-coding-style.mdc} +0 -0
  245. /package/.cursor/rules/{python-hooks.md → python-hooks.mdc} +0 -0
  246. /package/.cursor/rules/{python-patterns.md → python-patterns.mdc} +0 -0
  247. /package/.cursor/rules/{python-security.md → python-security.mdc} +0 -0
  248. /package/.cursor/rules/{python-testing.md → python-testing.mdc} +0 -0
  249. /package/.cursor/rules/{swift-coding-style.md → swift-coding-style.mdc} +0 -0
  250. /package/.cursor/rules/{swift-hooks.md → swift-hooks.mdc} +0 -0
  251. /package/.cursor/rules/{swift-patterns.md → swift-patterns.mdc} +0 -0
  252. /package/.cursor/rules/{swift-security.md → swift-security.mdc} +0 -0
  253. /package/.cursor/rules/{swift-testing.md → swift-testing.mdc} +0 -0
  254. /package/.cursor/rules/{typescript-coding-style.md → typescript-coding-style.mdc} +0 -0
  255. /package/.cursor/rules/{typescript-hooks.md → typescript-hooks.mdc} +0 -0
  256. /package/.cursor/rules/{typescript-patterns.md → typescript-patterns.mdc} +0 -0
  257. /package/.cursor/rules/{typescript-security.md → typescript-security.mdc} +0 -0
  258. /package/.cursor/rules/{typescript-testing.md → typescript-testing.mdc} +0 -0
@@ -26,27 +26,71 @@ Do not use as a hidden helper that replaces explicit review intent.
26
26
  Start with tests, local validation, E2E, runtime proof, and prior investigation artifacts.
27
27
  2. Load the right org-standard playbooks.
28
28
  Pull in platform review, design, accessibility, and quality-gate playbooks from the resolved baseline.
29
- 3. Review across the five core axes.
29
+ 3. Run BOTH review engines in parallel (DEFAULT, ALWAYS-ON).
30
+ Both of these must run on every non-trivial review — they are complementary,
31
+ not alternatives. Launch them concurrently:
32
+
33
+ **Engine A — Rules-manifest audit** (`aw-rules-review` + `aw-rules` skills):
34
+ Load both `aw-rules-review` (worksheet generator) and `aw-rules` (rule
35
+ definitions, audit criteria, scoring rubric). `aw-rules-review` generates
36
+ the per-file worksheet; `aw-rules` evaluates each rule as pass/fail.
37
+ Invocation:
38
+ - PR: `node ~/.aw/.aw_registry/platform/core/skills/aw-rules-review/scripts/generate-review-template.mjs --pr <number>`
39
+ - branch diff: `... --diff`
40
+ - files: `... --files "<csv>"`
41
+ Output: `.aw_docs/skill-tests/aw-rules-review.md` (worksheet with TODO
42
+ checkboxes per rule per file). Review the worksheet and mark each rule as
43
+ `pass | fail | unknown | not_applicable` with notes on failures/unknowns.
44
+
45
+ **Engine B — Parallel multi-reviewer** (`/aw:platform-core-full-review`):
46
+ Runs up to 10 reviewers across 3 conditional waves in parallel:
47
+ - Wave 1 (always): security, performance, architecture, reliability, maintainability
48
+ - Wave 2 (if frontend files): i18n, frontend-code, frontend-security
49
+ - Wave 3 (if UI components): design, architect
50
+
51
+ **Merge semantics** — treat Engine A and Engine B findings as independent
52
+ inputs into step 5 (severity classification):
53
+ - Engine A failures become blocking rule-manifest findings
54
+ - Engine B critical findings become blocking reviewer findings
55
+ - Cross-reference: a finding flagged by BOTH engines is high-confidence
56
+ and must be treated as blocking
57
+ - Record both in `state.json` and `verification.md`
58
+
59
+ `aw-review` remains the canonical stage contract — both engines feed it;
60
+ aw-review owns severity, governance, and readiness.
61
+
62
+ **Single-reviewer fallback** (rare, must be justified):
63
+ Only skip parallel mode when ALL of the following hold:
64
+ - change is < 50 lines AND single file
65
+ - no auth/payment/schema/public-API surface touched
66
+ - risk classification is Low
67
+ - user explicitly requested single-reviewer mode
68
+ When falling back, use the matching language reviewer agent
69
+ (`typescript-reviewer`, `python-reviewer`, `java-reviewer`, `kotlin-reviewer`,
70
+ `go-reviewer`, `rust-reviewer`, `cpp-reviewer`, `flutter-reviewer`)
71
+ or `code-reviewer`. Record the justification in `state.json`.
72
+
73
+ 4. Review across the five core axes.
30
74
  Correctness, readability and simplicity, architecture, security, and performance.
31
- When the review covers concrete code changes, prefer the matching reviewer agent when one exists (`typescript-reviewer`, `python-reviewer`, `java-reviewer`, `kotlin-reviewer`, `go-reviewer`, `rust-reviewer`, `cpp-reviewer`, or `flutter-reviewer`).
32
- Otherwise use `code-reviewer` and keep `aw-review` as the canonical stage contract for severity, governance, and readiness.
75
+ Treat the aggregated findings from parallel execution as the input to severity
76
+ classification (step 5) and governance/readiness (step 7).
33
77
  Use `../../references/review-findings-severity.md`.
34
78
  For readability and maintainability concerns, load `code-simplification`.
35
79
  For public contract or boundary changes, load `api-and-interface-design`.
36
80
  For security-sensitive work, load `security-and-hardening` and `../../references/security-checklist.md`.
37
81
  For performance-sensitive work, load `performance-optimization` and `../../references/performance-checklist.md`.
38
82
  For branch hygiene, save-point quality, or reviewability concerns, load `git-workflow-and-versioning`.
39
- 4. Classify findings explicitly.
83
+ 5. Classify findings explicitly.
40
84
  Separate blocking findings from advisory notes.
41
85
  Name evidence, scope, and required fix.
42
- 5. Continue until the requested review scope is covered.
86
+ 6. Continue until the requested review scope is covered.
43
87
  Do not stop after the first finding or the first review axis if correctness, governance, architecture, security, performance, or readiness checks still remain.
44
- 6. Check governance and readiness.
88
+ 7. Check governance and readiness.
45
89
  Confirm PR checklist, approvals, status checks, rollback notes, and release recommendation.
46
90
  For architecture or public-behavior changes that need durable rationale, load `documentation-and-adrs`.
47
- 7. Request fresh testing when needed.
91
+ 8. Request fresh testing when needed.
48
92
  If evidence is stale, missing, or too broad, route back to `aw-test` for the smallest targeted rerun.
49
- 8. Persist the result.
93
+ 9. Persist the result.
50
94
  Write `verification.md` and update `state.json`.
51
95
 
52
96
  ## Completion Contract
@@ -80,6 +124,10 @@ Every review handoff must make these things obvious:
80
124
  - PR governance is implied instead of checked
81
125
  - platform review or design playbooks are skipped for applicable work
82
126
  - stale test evidence is reused after repairs
127
+ - single-reviewer mode used without meeting ALL fallback criteria
128
+ - parallel `/aw:platform-core-full-review` skipped on a non-trivial change
129
+ - `aw-rules-review` worksheet skipped (rule-manifest audit is mandatory alongside reviewers)
130
+ - only one engine ran when both should have
83
131
 
84
132
  ## State File
85
133
 
@@ -89,6 +137,15 @@ Every review handoff must make these things obvious:
89
137
  - `stage: "review"`
90
138
  - `mode`
91
139
  - `status`
140
+ - `review_mode`: `"parallel"` (default) | `"single"` (must include justification)
141
+ - `single_mode_justification`: required when `review_mode == "single"`
142
+ - `engines_run`: array of engines executed (e.g., `["aw-rules-review", "platform-core-full-review"]`)
143
+ - `rules_review_worksheet`: path to the aw-rules-review output (e.g., `.aw_docs/skill-tests/aw-rules-review.md`)
144
+ - `rules_review_failures`: count of rule-manifest failures
145
+ - `parallel_run_id`: run_id from `/aw:platform-core-full-review` when parallel mode used
146
+ - `reviewers_active`: list of reviewer agent slugs that executed
147
+ - `waves_executed`: array of wave numbers (e.g., `[1]`, `[1, 2]`, `[1, 2, 3]`)
148
+ - `cross_engine_findings`: findings flagged by BOTH engines (high confidence)
92
149
  - written artifacts
93
150
  - evidence reviewed
94
151
  - reviewer agents or reviewer path used
@@ -96,28 +153,50 @@ Every review handoff must make these things obvious:
96
153
  - advisory notes
97
154
  - governance status
98
155
  - readiness outcome
156
+ - `html_companion_artifacts`
99
157
  - blockers
100
158
  - recommended next commands
101
159
 
160
+ ## Human HTML Companion
161
+
162
+ Markdown `verification.md` remains canonical for agents.
163
+ When review writes or materially updates `verification.md`, also create or refresh `.aw_docs/features/<feature_slug>/verification.html`. HTML sidecars are required stage outputs, not advisory metadata.
164
+
165
+ Delegate to the `aw:echo` subagent with the `pr-one-pager` profile for reviewer-facing summaries and readiness decisions.
166
+ Use `impact-analysis-report` only when the review output is primarily blast radius or customer impact.
167
+ Invoking `/aw:review` in default `dual` mode is explicit authorization to spawn exactly one `aw:echo` subagent for HTML companion generation; do not skip HTML only because no direct command is available.
168
+ Resolve output mode as: explicit user request for Markdown-only -> otherwise `dual`. `.aw_docs/config.json` and `AW_DOCS_OUTPUT_MODE` may request `dual` or `html`, but must not silently suppress required SDLC HTML sidecars.
169
+
170
+ Pass evidence reviewed, engines run, findings, severity, governance status, readiness outcome, repair path, and next command as the source bundle.
171
+ Record the colocated sidecar in `state.json` `html_companion_artifacts` with `source_path`, `html_path`, profile, status, `run_ref` when available, publish status, and any explicit Markdown-only skip or fallback reason.
172
+ Spawn exactly one `aw:echo` subagent and wait for the colocated `.html` sidecar before the final handoff unless the user explicitly asks not to wait. If the harness still cannot spawn `aw:echo`, create a conservative self-contained fallback HTML sidecar in the same turn using the `aw:echo` safety and design contract, record `generated_fallback` plus the blocker, and keep Markdown canonical.
173
+
102
174
  ## Verification
103
175
 
104
176
  Before leaving review, confirm:
105
177
 
106
178
  - [ ] test and runtime evidence were reviewed first
179
+ - [ ] BOTH engines ran by default: `aw-rules-review` AND `/aw:platform-core-full-review`
180
+ - [ ] rules-manifest worksheet was generated and every rule marked pass/fail/unknown/not_applicable
181
+ - [ ] cross-engine findings (flagged by both) are elevated to blocking
182
+ - [ ] if single-reviewer mode was used, justification meets ALL fallback criteria and is recorded in `state.json`
183
+ - [ ] `engines_run`, `rules_review_worksheet`, `parallel_run_id`, `reviewers_active`, and `waves_executed` are recorded
107
184
  - [ ] findings are explicit, evidence-backed, and severity-tagged
108
185
  - [ ] reviewer routing is explicit when the scope included concrete code review
109
186
  - [ ] governance and readiness checks match the resolved baseline
110
187
  - [ ] repairs point back to build or test with clear scope
111
188
  - [ ] `verification.md` and `state.json` are updated
189
+ - [ ] the HTML companion file exists, or the user explicitly requested Markdown-only
112
190
 
113
191
  ## Final Output Shape
114
192
 
115
193
  Always end with:
116
194
 
117
- - `Mode`
195
+ - `Mode` (include: `review_mode = parallel | single`, `engines_run = [...]`, `reviewers_active = N`, `waves_executed = [...]`, `parallel_run_id`, `rules_review_worksheet` path)
118
196
  - `Evidence`
119
197
  - `Findings`
120
198
  - `Governance`
121
199
  - `Readiness`
122
200
  - `Outcome`
201
+ - `HTML Companion`
123
202
  - `Next`
@@ -0,0 +1,124 @@
1
+ ---
2
+ name: aw-rules-review
3
+ description: Generate a per-file review worksheet driven by rule-manifest.json. Supports all tracked files, PR diff, branch diff, or explicit file list. Use for isolated manifest-driven rule audits.
4
+ ---
5
+
6
+ # AW Rules Review
7
+
8
+ Generate a per-file review worksheet that maps source files to applicable platform rules from `rule-manifest.json`. Supports multiple scoping modes — full repo, PR diff, branch diff, or explicit file list.
9
+
10
+ ## Required Co-Skill
11
+
12
+ **`aw-rules`** must be loaded alongside this skill. `aw-rules-review` generates the per-file worksheet; `aw-rules` provides the rule definitions, audit criteria, and scoring rubric needed to evaluate each rule as pass/fail. Without `aw-rules`, the worksheet has TODO checkboxes but no way to assess compliance.
13
+
14
+ When invoked from `aw-review` (Engine A), the `aw-rules` skill is loaded automatically.
15
+
16
+ ## What This Skill Does
17
+
18
+ 1. Locates `rule-manifest.json` (workspace `.aw_registry/` → global `~/.aw/.aw_registry/`)
19
+ 2. Collects source files based on the chosen mode (PR, diff, file list, or all)
20
+ 3. Detects each file's domain(s) and stack(s) from its path
21
+ 4. Matches applicable rules by domain + stack overlap
22
+ 5. Generates a per-file checklist worksheet with blank status for each rule
23
+
24
+ ## Modes
25
+
26
+ ### All tracked files (default)
27
+
28
+ ```bash
29
+ node scripts/generate-review-template.mjs
30
+ ```
31
+
32
+ ### PR diff
33
+
34
+ Reviews only files changed in a GitHub PR. Requires `gh` CLI.
35
+
36
+ ```bash
37
+ node scripts/generate-review-template.mjs --pr 1234
38
+ ```
39
+
40
+ ### Branch diff
41
+
42
+ Reviews files changed between the current branch and its merge-base with main/master.
43
+
44
+ ```bash
45
+ node scripts/generate-review-template.mjs --diff
46
+ node scripts/generate-review-template.mjs --diff --base origin/develop
47
+ ```
48
+
49
+ ### Explicit file list
50
+
51
+ ```bash
52
+ node scripts/generate-review-template.mjs --files "src/foo.ts,src/bar.vue"
53
+ ```
54
+
55
+ ### Custom output path
56
+
57
+ ```bash
58
+ node scripts/generate-review-template.mjs --pr 1234 --out review.md
59
+ ```
60
+
61
+ ## Manifest Resolution
62
+
63
+ The script searches for the rule manifest in this order:
64
+
65
+ 1. `$WORKSPACE/.aw_registry/.aw_rules/rule-manifest.json`
66
+ 2. `$WORKSPACE/.aw_registry/.aw_rules/manifest.json` (legacy)
67
+ 3. `~/.aw/.aw_registry/.aw_rules/rule-manifest.json`
68
+ 4. `~/.aw/.aw_registry/.aw_rules/manifest.json` (legacy)
69
+
70
+ Set `AW_RULES_WORKSPACE_ROOT` to override the workspace root.
71
+
72
+ ## Domain Detection
73
+
74
+ Files are mapped to domains by path patterns:
75
+
76
+ | Domain | Matched by |
77
+ |--------|-----------|
78
+ | `infra` | `helm/`, `terraform/`, `Dockerfile`, `Jenkinsfile` |
79
+ | `sdet` | `e2e/`, `playwright/` (E2E tests only — not unit/integration specs) |
80
+ | `mobile` | `*.dart`, `lib/` |
81
+ | `frontend` | `*.vue`, `composables/`, `components/*.ts`, `stores/` |
82
+ | `data` | `*.schema.ts`, `*.migration.*`, `*.repository.ts` |
83
+ | `api-design` | `*.controller.ts`, `dto/`, `*.client.ts` |
84
+ | `backend` | `*.service.ts`, `*.module.ts`, `*.worker.ts`, or any file with "worker" in its name |
85
+
86
+ **Unit/integration test files** (`__tests__/**/*.spec.ts`) inherit the domain of their parent module, not `sdet`. The `sdet` domain is reserved for E2E/Playwright tests only.
87
+
88
+ Rules with `domains: ["all"]` apply to every file. Rules with `stacks` (e.g. `nestjs`, `vue`) only match files detected as that stack.
89
+
90
+ ## Review Procedure
91
+
92
+ 1. Run the script with the appropriate mode flag
93
+ 2. Open the generated worksheet
94
+ 3. Review files in batches
95
+ 4. Replace `TODO` with: `pass`, `fail`, `unknown`, or `not_applicable`
96
+ 5. Add concise notes only for failures, unknowns, or meaningful exemptions
97
+
98
+ ## Expected Output
99
+
100
+ Default: `.aw_docs/skill-tests/aw-rules-review.md`
101
+
102
+ ## CLI Reference
103
+
104
+ ```
105
+ Usage: generate-review-template.mjs [options]
106
+
107
+ Modes (pick one):
108
+ --pr <number> Review files changed in a GitHub PR (requires gh CLI)
109
+ --diff Review files changed vs the current branch's merge-base
110
+ --base <ref> Base ref for --diff mode (default: auto-detected main/master)
111
+ --files <glob,...> Review an explicit comma-separated list of files
112
+ (no flag) Review all tracked files in the repo
113
+
114
+ Options:
115
+ --out, -o <path> Output worksheet path
116
+ --help, -h Show this help
117
+ ```
118
+
119
+ ## Important Limits
120
+
121
+ - The script does not decide pass/fail automatically
122
+ - Semantic rules still need AI or human review
123
+ - Domain detection is path-based — files outside standard paths get only universal rules
124
+ - This skill is intentionally standalone and should not call the existing workspace review command
@@ -0,0 +1,3 @@
1
+ display_name: AW Rules Review
2
+ short_description: Generate a per-file aw-rules review worksheet (full repo, PR diff, branch diff, or file list)
3
+ default_prompt: Generate an aw-rules review worksheet for source files in this workspace. Supports --pr, --diff, --files, or all tracked files.
@@ -0,0 +1,323 @@
1
+ #!/usr/bin/env node
2
+
3
+ import fs from 'node:fs';
4
+ import path from 'node:path';
5
+ import { execSync } from 'node:child_process';
6
+ import { fileURLToPath } from 'node:url';
7
+ import { parseArgs } from 'node:util';
8
+
9
+ const __filename = fileURLToPath(import.meta.url);
10
+ const __dirname = path.dirname(__filename);
11
+
12
+ // ---------------------------------------------------------------------------
13
+ // CLI
14
+ // ---------------------------------------------------------------------------
15
+
16
+ const { values: flags } = parseArgs({
17
+ options: {
18
+ pr: { type: 'string', short: 'p' },
19
+ diff: { type: 'boolean', short: 'd', default: false },
20
+ files: { type: 'string', short: 'f' },
21
+ base: { type: 'string', short: 'b' },
22
+ out: { type: 'string', short: 'o' },
23
+ help: { type: 'boolean', short: 'h', default: false },
24
+ },
25
+ strict: false,
26
+ allowPositionals: true,
27
+ });
28
+
29
+ if (flags.help) {
30
+ console.log(`
31
+ Usage: generate-review-template.mjs [options]
32
+
33
+ Modes (pick one):
34
+ --pr <number> Review files changed in a GitHub PR (requires gh CLI)
35
+ --diff Review files changed vs the current branch's merge-base
36
+ --base <ref> Base ref for --diff mode (default: auto-detected main/master)
37
+ --files <glob,...> Review an explicit comma-separated list of files
38
+ (no flag) Review all tracked files in the repo
39
+
40
+ Options:
41
+ --out, -o <path> Output worksheet path (default: .aw_docs/skill-tests/aw-rules-review.md)
42
+ --help, -h Show this help
43
+ `);
44
+ process.exit(0);
45
+ }
46
+
47
+ // ---------------------------------------------------------------------------
48
+ // Paths
49
+ // ---------------------------------------------------------------------------
50
+
51
+ const workspaceRoot = process.env.AW_RULES_WORKSPACE_ROOT
52
+ ? path.resolve(process.env.AW_RULES_WORKSPACE_ROOT)
53
+ : process.cwd();
54
+
55
+ const defaultOutputPath = path.join(
56
+ workspaceRoot, '.aw_docs', 'skill-tests', 'aw-rules-review.md',
57
+ );
58
+ const outputPath = flags.out
59
+ ? path.resolve(workspaceRoot, flags.out)
60
+ : defaultOutputPath;
61
+
62
+ // ---------------------------------------------------------------------------
63
+ // Locate rule-manifest.json (try workspace first, then global ~/.aw)
64
+ // ---------------------------------------------------------------------------
65
+
66
+ const MANIFEST_CANDIDATES = [
67
+ path.join(workspaceRoot, '.aw_registry', '.aw_rules', 'rule-manifest.json'),
68
+ path.join(workspaceRoot, '.aw_registry', '.aw_rules', 'manifest.json'),
69
+ path.join(process.env.HOME, '.aw', '.aw_registry', '.aw_rules', 'rule-manifest.json'),
70
+ path.join(process.env.HOME, '.aw', '.aw_registry', '.aw_rules', 'manifest.json'),
71
+ ];
72
+
73
+ function findManifest() {
74
+ for (const candidate of MANIFEST_CANDIDATES) {
75
+ if (fs.existsSync(candidate)) return candidate;
76
+ }
77
+ console.error(
78
+ 'ERROR: Could not find rule-manifest.json in any of:\n' +
79
+ MANIFEST_CANDIDATES.map((p) => ` - ${p}`).join('\n'),
80
+ );
81
+ process.exit(1);
82
+ }
83
+
84
+ const manifestPath = findManifest();
85
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
86
+
87
+ console.log(`Manifest: ${manifestPath} (${manifest.rules.length} rules)`);
88
+
89
+ // ---------------------------------------------------------------------------
90
+ // Domain detection — maps file paths to manifest domains
91
+ // ---------------------------------------------------------------------------
92
+
93
+ const DOMAIN_PATTERNS = [
94
+ // infra
95
+ { test: (f) => /\/(helm|terraform)\//i.test(f) || /Dockerfile|Jenkinsfile/i.test(f), domain: 'infra' },
96
+ // sdet / e2e only (not unit/integration specs)
97
+ { test: (f) => /\/(e2e|playwright)\//i.test(f), domain: 'sdet' },
98
+ // mobile / flutter
99
+ { test: (f) => /\.dart$/.test(f) || /\/lib\//.test(f), domain: 'mobile' },
100
+ // frontend
101
+ { test: (f) => /\.vue$/.test(f) || /composables?\//.test(f) || /\/components\/.*\.ts$/.test(f) || /stores?\//.test(f), domain: 'frontend' },
102
+ // data
103
+ { test: (f) => /\.schema\.ts$/.test(f) || /\.migration\./.test(f) || /\.repository\.ts$/.test(f), domain: 'data' },
104
+ // api-design
105
+ { test: (f) => /\.controller\.ts$/.test(f) || /\/dto\//.test(f) || /\.client\.ts$/.test(f), domain: 'api-design' },
106
+ // backend (broad — services, modules, workers, and files with "worker" in the name)
107
+ { test: (f) => /\.(service|module|worker)\.ts$/.test(f) || /worker/i.test(path.basename(f)), domain: 'backend' },
108
+ ];
109
+
110
+ function isUnitOrIntegrationTest(filePath) {
111
+ return /__tests__\//.test(filePath) && /\.spec\.ts$/.test(filePath) && !/\/(e2e|playwright)\//.test(filePath);
112
+ }
113
+
114
+ function detectDomains(filePath) {
115
+ const domains = new Set();
116
+
117
+ // Unit/integration test files inherit the domain of the code they test,
118
+ // not sdet (which is for E2E/Playwright only). Detect from parent path.
119
+ if (isUnitOrIntegrationTest(filePath)) {
120
+ // Strip __tests__/... suffix and re-detect based on the parent module path
121
+ const parentPath = filePath.replace(/__tests__\/.*$/, '');
122
+ // Check if parent contains service/schema/controller/worker patterns
123
+ // but also tag as backend by default since unit tests live in backend modules
124
+ for (const { test, domain } of DOMAIN_PATTERNS) {
125
+ if (test(parentPath)) domains.add(domain);
126
+ }
127
+ if (domains.size === 0) domains.add('backend');
128
+ return [...domains];
129
+ }
130
+
131
+ for (const { test, domain } of DOMAIN_PATTERNS) {
132
+ if (test(filePath)) domains.add(domain);
133
+ }
134
+ // Controllers belong to both api-design and backend
135
+ if (domains.has('api-design')) domains.add('backend');
136
+ // Schemas belong to both data and backend
137
+ if (domains.has('data')) domains.add('backend');
138
+ // If nothing matched, tag as general (universal rules still apply)
139
+ if (domains.size === 0) domains.add('_general');
140
+ return [...domains];
141
+ }
142
+
143
+ // ---------------------------------------------------------------------------
144
+ // Stack detection
145
+ // ---------------------------------------------------------------------------
146
+
147
+ function detectStacks(filePath) {
148
+ const stacks = new Set();
149
+ if (/\.vue$/.test(filePath) || /composables?\//.test(filePath)) stacks.add('vue');
150
+ if (/\/nuxt\.config|\.nuxt\/|\/server\/api\//.test(filePath)) stacks.add('nuxt');
151
+ if (/\.module\.ts$/.test(filePath) || /\.controller\.ts$/.test(filePath) || /\/dto\//.test(filePath)) stacks.add('nestjs');
152
+ if (/\.go$/.test(filePath)) stacks.add('go-connect');
153
+ return [...stacks];
154
+ }
155
+
156
+ // ---------------------------------------------------------------------------
157
+ // Rule matching
158
+ // ---------------------------------------------------------------------------
159
+
160
+ function applicableRules(filePath) {
161
+ const fileDomains = detectDomains(filePath);
162
+ const fileStacks = detectStacks(filePath);
163
+
164
+ return manifest.rules.filter((rule) => {
165
+ // Domain match: rule applies to "all" or overlaps with file domains
166
+ const domainMatch = rule.domains.includes('all') ||
167
+ rule.domains.some((d) => fileDomains.includes(d));
168
+ if (!domainMatch) return false;
169
+
170
+ // Stack match: if rule specifies stacks, file must match at least one
171
+ if (rule.stacks && rule.stacks.length > 0) {
172
+ return rule.stacks.some((s) => fileStacks.includes(s));
173
+ }
174
+ return true;
175
+ });
176
+ }
177
+
178
+ // ---------------------------------------------------------------------------
179
+ // File collection — depends on mode
180
+ // ---------------------------------------------------------------------------
181
+
182
+ function sh(cmd) {
183
+ return execSync(cmd, { cwd: workspaceRoot, encoding: 'utf8' }).trim();
184
+ }
185
+
186
+ function getFilesFromPR(prNumber) {
187
+ const json = sh(`gh api "repos/{owner}/{repo}/pulls/${prNumber}/files?per_page=100"`);
188
+ const files = JSON.parse(json);
189
+ return files.map((f) => f.filename).filter(Boolean);
190
+ }
191
+
192
+ function getFilesFromDiff(baseRef) {
193
+ const base = baseRef || detectBaseRef();
194
+ const mergeBase = sh(`git merge-base ${base} HEAD`);
195
+ return sh(`git diff --name-only ${mergeBase}`)
196
+ .split('\n')
197
+ .filter(Boolean);
198
+ }
199
+
200
+ function detectBaseRef() {
201
+ // Detect the default branch from the remote HEAD
202
+ try {
203
+ const symRef = sh('git symbolic-ref refs/remotes/origin/HEAD');
204
+ return symRef.replace('refs/remotes/', '');
205
+ } catch { /* ignore */ }
206
+ // Fallback: try common names
207
+ for (const ref of ['origin/main', 'origin/master', 'main', 'master']) {
208
+ try { sh(`git rev-parse --verify ${ref}`); return ref; } catch { /* ignore */ }
209
+ }
210
+ return 'master';
211
+ }
212
+
213
+ function getFilesFromList(csv) {
214
+ return csv.split(',').map((f) => f.trim()).filter(Boolean);
215
+ }
216
+
217
+ function getAllTrackedFiles() {
218
+ return sh('git ls-files')
219
+ .split('\n')
220
+ .filter(Boolean);
221
+ }
222
+
223
+ function collectFiles() {
224
+ if (flags.pr) {
225
+ console.log(`Mode: PR #${flags.pr}`);
226
+ return getFilesFromPR(flags.pr);
227
+ }
228
+ if (flags.diff) {
229
+ const base = flags.base || detectBaseRef();
230
+ console.log(`Mode: diff vs ${base}`);
231
+ return getFilesFromDiff(base);
232
+ }
233
+ if (flags.files) {
234
+ console.log(`Mode: explicit file list`);
235
+ return getFilesFromList(flags.files);
236
+ }
237
+ console.log('Mode: all tracked files');
238
+ return getAllTrackedFiles();
239
+ }
240
+
241
+ // Filter to source files only (skip assets, configs, lockfiles, etc.)
242
+ const SOURCE_EXTENSIONS = new Set([
243
+ '.ts', '.tsx', '.js', '.jsx', '.vue', '.dart', '.go', '.yaml', '.yml',
244
+ '.tf', '.hcl', '.md', '.json', '.mjs', '.cjs',
245
+ ]);
246
+
247
+ function isSourceFile(filePath) {
248
+ const ext = path.extname(filePath).toLowerCase();
249
+ if (SOURCE_EXTENSIONS.has(ext)) return true;
250
+ // Dockerfile, Jenkinsfile (no extension)
251
+ const base = path.basename(filePath);
252
+ return /^(Dockerfile|Jenkinsfile)/i.test(base);
253
+ }
254
+
255
+ // ---------------------------------------------------------------------------
256
+ // Generate worksheet
257
+ // ---------------------------------------------------------------------------
258
+
259
+ const files = collectFiles().filter(isSourceFile);
260
+ console.log(`Files to review: ${files.length}`);
261
+
262
+ if (files.length === 0) {
263
+ console.log('No source files found for the selected mode. Nothing to generate.');
264
+ process.exit(0);
265
+ }
266
+
267
+ const modeLabel = flags.pr
268
+ ? `PR #${flags.pr}`
269
+ : flags.diff
270
+ ? `diff vs ${flags.base || 'auto-detected base'}`
271
+ : flags.files
272
+ ? 'explicit file list'
273
+ : 'all tracked files';
274
+
275
+ const sections = files.map((filePath) => {
276
+ const rules = applicableRules(filePath);
277
+ const domains = detectDomains(filePath);
278
+ const stacks = detectStacks(filePath);
279
+
280
+ const ruleLines = rules.length === 0
281
+ ? ['- No applicable manifest rules']
282
+ : rules.map((rule) => {
283
+ return `- [ ] \`${rule.id}\` | severity: \`${rule.severity}\` | status: \`TODO\` | ${rule.description}`;
284
+ });
285
+
286
+ const domainTag = domains.join(', ');
287
+ const stackTag = stacks.length > 0 ? ` | stacks: \`${stacks.join(', ')}\`` : '';
288
+
289
+ return `## \`${filePath}\`
290
+
291
+ - Domains: \`${domainTag}\`${stackTag}
292
+ - Applicable rules: \`${rules.length}\`
293
+
294
+ ${ruleLines.join('\n')}
295
+ `;
296
+ });
297
+
298
+ const output = `# AW Rules Review Worksheet
299
+
300
+ - Mode: **${modeLabel}**
301
+ - Workspace: \`${workspaceRoot}\`
302
+ - Manifest: \`${manifestPath}\`
303
+ - Total rules: \`${manifest.rules.length}\`
304
+ - Files in worksheet: \`${files.length}\`
305
+ - Generated: \`${new Date().toISOString()}\`
306
+
307
+ ## Status legend
308
+
309
+ | Status | Meaning |
310
+ |--------|---------|
311
+ | \`pass\` | Rule satisfied |
312
+ | \`fail\` | Rule violated — add note |
313
+ | \`unknown\` | Cannot determine — add note |
314
+ | \`not_applicable\` | Rule does not apply to this file context |
315
+
316
+ ---
317
+
318
+ ${sections.join('\n')}
319
+ `;
320
+
321
+ fs.mkdirSync(path.dirname(outputPath), { recursive: true });
322
+ fs.writeFileSync(outputPath, output);
323
+ console.log(`Worksheet written to: ${outputPath}`);
@@ -92,15 +92,30 @@ Every shipping handoff must make these things obvious:
92
92
  - rollout plan
93
93
  - rollback path
94
94
  - evidence captured
95
+ - `html_companion_artifacts`
95
96
  - blockers
96
97
  - recommended next commands
97
98
 
99
+ ## Human HTML Companion
100
+
101
+ Markdown `release.md` remains canonical for agents.
102
+ When ship writes or materially updates `release.md`, also create or refresh `.aw_docs/features/<feature_slug>/release.html`. HTML sidecars are required stage outputs, not advisory metadata.
103
+
104
+ Delegate to the `aw:echo` subagent with the `release-report` profile.
105
+ Invoking `/aw:ship` in default `dual` mode is explicit authorization to spawn exactly one `aw:echo` subagent for HTML companion generation; do not skip HTML only because no direct command is available.
106
+ Resolve output mode as: explicit user request for Markdown-only -> otherwise `dual`. `.aw_docs/config.json` and `AW_DOCS_OUTPUT_MODE` may request `dual` or `html`, but must not silently suppress required SDLC HTML sidecars.
107
+
108
+ Pass launch readiness, rollout plan, rollback posture, monitoring or smoke evidence, blockers, ownership, and next command as the source bundle.
109
+ Record the colocated sidecar in `state.json` `html_companion_artifacts` with `source_path`, `html_path`, profile, status, `run_ref` when available, publish status, and any explicit Markdown-only skip or fallback reason.
110
+ Spawn exactly one `aw:echo` subagent and wait for the colocated `.html` sidecar before the final handoff unless the user explicitly asks not to wait. If the harness still cannot spawn `aw:echo`, create a conservative self-contained fallback HTML sidecar in the same turn using the `aw:echo` safety and design contract, record `generated_fallback` plus the blocker, and keep Markdown canonical.
111
+
98
112
  ## Verification
99
113
 
100
114
  - [ ] launch checklist or blocker is explicit
101
115
  - [ ] rollback readiness is documented
102
116
  - [ ] monitoring and smoke expectations are named
103
117
  - [ ] `release.md` and `state.json` are updated with closeout evidence
118
+ - [ ] the HTML companion file exists, or the user explicitly requested Markdown-only
104
119
 
105
120
  ## Final Output Shape
106
121
 
@@ -112,4 +127,5 @@ Always end with:
112
127
  - `Rollback Path`
113
128
  - `Evidence`
114
129
  - `Outcome`
130
+ - `HTML Companion`
115
131
  - `Next`