@adia-ai/adia-ui-forge 0.1.3 → 0.8.1

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 (259) hide show
  1. package/.claude-plugin/plugin.json +4 -7
  2. package/CHANGELOG.md +35 -34
  3. package/README.md +35 -40
  4. package/agents/a2ui-engineer.md +22 -53
  5. package/agents/component-author.md +29 -0
  6. package/agents/framework-verifier.md +26 -0
  7. package/agents/release-engineer.md +21 -81
  8. package/agents/routing-corpus.json +293 -64
  9. package/bin/demo-postwrite-pattern-gate +94 -0
  10. package/bin/forge-lint +17 -2
  11. package/bin/sidecar-prewrite-guard +104 -0
  12. package/commands/deploy.md +9 -0
  13. package/commands/dogfood.md +10 -0
  14. package/commands/gen-review.md +9 -0
  15. package/commands/release.md +10 -0
  16. package/hooks/hooks.json +15 -0
  17. package/package.json +3 -6
  18. package/references/contracts/a2ui-mcp-surface.md +35 -0
  19. package/references/contracts/migration-guide-format.md +34 -0
  20. package/references/shared/content-trust.md +19 -74
  21. package/skills/adia-a2ui/SKILL.md +99 -0
  22. package/skills/{adia-ui-a2ui → adia-a2ui}/evals/routing-corpus.json +10 -10
  23. package/skills/adia-a2ui/references/anti-patterns.md +27 -0
  24. package/skills/adia-a2ui/references/chunk-authoring.md +71 -0
  25. package/skills/adia-a2ui/references/corpus-discipline.md +68 -0
  26. package/skills/adia-a2ui/references/eval-diagnostics.md +86 -0
  27. package/skills/adia-a2ui/references/format-extension-decisions.md +66 -0
  28. package/skills/adia-a2ui/references/leverage-rules.md +52 -0
  29. package/skills/adia-a2ui/references/mcp-pipeline-ops.md +83 -0
  30. package/skills/adia-a2ui/references/mcp-tool-reference.md +59 -0
  31. package/skills/adia-a2ui/references/pipeline-overview.md +115 -0
  32. package/skills/adia-a2ui/references/semantic-fail-lifting.md +74 -0
  33. package/skills/adia-a2ui/references/strategy-engines.md +109 -0
  34. package/skills/adia-a2ui/references/zettel-calibration.md +104 -0
  35. package/skills/adia-author/SKILL.md +112 -0
  36. package/skills/adia-author/evals/routing-corpus.json +222 -0
  37. package/skills/{adia-ui-authoring → adia-author}/references/anti-patterns.md +33 -4
  38. package/skills/{adia-ui-authoring → adia-author}/references/authoring-cycle.md +9 -11
  39. package/skills/adia-author/references/canonical-pattern-index.md +243 -0
  40. package/skills/{adia-ui-authoring → adia-author}/references/code-style.md +19 -21
  41. package/skills/adia-author/references/common-gotchas.md +129 -0
  42. package/skills/adia-author/references/composite-demo-protocol.md +271 -0
  43. package/skills/{adia-ui-authoring → adia-author}/references/css-patterns.md +19 -6
  44. package/skills/{adia-ui-authoring → adia-author}/references/lifecycle-patterns.md +1 -0
  45. package/skills/{adia-ui-authoring → adia-author}/references/llm-bridge.md +3 -5
  46. package/skills/{adia-ui-authoring → adia-author}/references/module-promotion.md +20 -38
  47. package/skills/{adia-ui-authoring → adia-author}/references/primitive-audit.md +2 -4
  48. package/skills/{adia-ui-authoring → adia-author}/references/shell-patterns.md +12 -18
  49. package/skills/{adia-ui-authoring → adia-author}/references/token-contract.md +5 -7
  50. package/skills/{adia-ui-authoring → adia-author}/references/worked-example.md +3 -3
  51. package/skills/{adia-ui-authoring → adia-author}/references/yaml-contract.md +3 -3
  52. package/skills/{adia-ui-authoring → adia-author}/scripts/build-canonical-pattern-index.mjs +3 -3
  53. package/skills/adia-deploy/SKILL.md +128 -0
  54. package/skills/{adia-ui-ops → adia-deploy}/references/deploy-playbooks.md +47 -30
  55. package/skills/adia-dogfood/SKILL.md +124 -0
  56. package/skills/adia-dogfood/references/admin-shell-anatomy.md +77 -0
  57. package/skills/adia-dogfood/references/app-shell-pitfalls.md +66 -0
  58. package/skills/adia-dogfood/references/card-anatomy-sweep.md +66 -0
  59. package/skills/adia-dogfood/references/html-attr-sweep.md +63 -0
  60. package/skills/adia-dogfood/references/native-leak-annotations.md +73 -0
  61. package/skills/adia-dogfood/references/visual-probe-triage.md +80 -0
  62. package/skills/{adia-ui-dogfood → adia-dogfood}/scripts/analyze.mjs +30 -14
  63. package/skills/adia-gen-review/SKILL.md +127 -0
  64. package/skills/adia-gen-review/references/corpus-html-patterns.md +279 -0
  65. package/skills/adia-gen-review/references/loop-protocol.md +216 -0
  66. package/skills/adia-gen-review/references/rubric-cosmetic.md +100 -0
  67. package/skills/adia-gen-review/references/rubric-decompose.md +101 -0
  68. package/skills/adia-gen-review/references/rubric-score.md +214 -0
  69. package/skills/{adia-ui-gen-review → adia-gen-review}/references/scores.schema.json +2 -2
  70. package/skills/{adia-ui-gen-review → adia-gen-review}/scripts/gen-review-coverage-audit.mjs +4 -4
  71. package/skills/{adia-ui-gen-review → adia-gen-review}/scripts/gen-review-decompose.mjs +10 -6
  72. package/skills/{adia-ui-gen-review → adia-gen-review}/scripts/gen-review-status.mjs +5 -5
  73. package/skills/{adia-ui-gen-review → adia-gen-review}/scripts/validate-cycle-scores.mjs +5 -5
  74. package/skills/adia-llm-internals/SKILL.md +77 -0
  75. package/skills/{adia-ui-llm → adia-llm-internals}/references/adapter-contract.md +4 -2
  76. package/skills/{adia-ui-llm → adia-llm-internals}/references/add-a-provider.md +4 -5
  77. package/skills/{adia-ui-llm → adia-llm-internals}/references/bridge-facade.md +10 -3
  78. package/skills/{adia-ui-llm → adia-llm-internals}/references/browser-proxy-boundary.md +1 -1
  79. package/skills/{adia-ui-llm → adia-llm-internals}/references/model-registry.md +5 -3
  80. package/skills/{adia-ui-llm → adia-llm-internals}/references/streaming-sse.md +2 -2
  81. package/skills/adia-release/SKILL.md +72 -0
  82. package/skills/adia-release/references/changelog-discipline.md +119 -0
  83. package/skills/adia-release/references/cut-procedure.md +247 -0
  84. package/skills/adia-release/references/gates-catalog.md +222 -0
  85. package/skills/adia-release/references/independent-package-release.md +52 -0
  86. package/skills/adia-release/references/migration-guide-authoring.md +86 -0
  87. package/skills/adia-release/references/notes-authoring.md +90 -0
  88. package/skills/adia-release/references/recovery-paths.md +106 -0
  89. package/skills/{adia-ui-release → adia-release}/scripts/bump.mjs +28 -3
  90. package/skills/{adia-ui-release → adia-release}/scripts/dispatch-publish.mjs +10 -7
  91. package/skills/{adia-ui-release → adia-release}/scripts/insert-stub.mjs +1 -1
  92. package/skills/{adia-ui-release → adia-release}/scripts/package-paths.mjs +6 -0
  93. package/skills/{adia-ui-release → adia-release}/scripts/promote-unreleased.mjs +1 -1
  94. package/skills/{adia-ui-release → adia-release}/scripts/release-pack.mjs +38 -31
  95. package/skills/{adia-ui-release → adia-release}/scripts/tag-lockstep.mjs +7 -3
  96. package/skills/adia-site-docs/SKILL.md +68 -0
  97. package/skills/adia-site-docs/evals/audit-report.md +30 -0
  98. package/skills/adia-site-docs/evals/routing-corpus.json +176 -0
  99. package/skills/adia-site-docs/intent.md +72 -0
  100. package/agents/README.md +0 -209
  101. package/agents/author.md +0 -56
  102. package/agents/repo-steward.md +0 -56
  103. package/agents/spec-architect.md +0 -53
  104. package/agents/tech-lead.md +0 -57
  105. package/agents/verifier.md +0 -55
  106. package/bin/lib/audit-axes.mjs +0 -555
  107. package/bin/lib/dry-run-irreversible.mjs +0 -236
  108. package/bin/lib/run-skill-evals.mjs +0 -487
  109. package/bin/lib/teach-router.mjs +0 -250
  110. package/commands/adia-forge-a2ui.md +0 -10
  111. package/commands/adia-forge-author.md +0 -10
  112. package/commands/adia-forge-dogfood.md +0 -8
  113. package/commands/adia-forge-llm.md +0 -8
  114. package/commands/adia-forge-orient.md +0 -10
  115. package/commands/adia-forge-release.md +0 -8
  116. package/commands/adia-forge-review.md +0 -10
  117. package/references/shared/pev-rationale.md +0 -64
  118. package/references/shared/skill-conventions.md +0 -133
  119. package/skills/adia-ui-a2ui/CHANGELOG.md +0 -32
  120. package/skills/adia-ui-a2ui/SKILL.md +0 -243
  121. package/skills/adia-ui-a2ui/evals/adversarial-corpus.json +0 -75
  122. package/skills/adia-ui-a2ui/evals/teach-routing-cases.json +0 -100
  123. package/skills/adia-ui-a2ui/references/anti-patterns.md +0 -24
  124. package/skills/adia-ui-a2ui/references/chunk-authoring.md +0 -88
  125. package/skills/adia-ui-a2ui/references/corpus-discipline.md +0 -56
  126. package/skills/adia-ui-a2ui/references/eval-diagnostics.md +0 -127
  127. package/skills/adia-ui-a2ui/references/fragment-graph.md +0 -91
  128. package/skills/adia-ui-a2ui/references/mcp-pipeline-ops.md +0 -106
  129. package/skills/adia-ui-a2ui/references/mcp-tool-reference.md +0 -398
  130. package/skills/adia-ui-a2ui/references/pipeline-overview.md +0 -175
  131. package/skills/adia-ui-a2ui/references/semantic-fail-lifting.md +0 -120
  132. package/skills/adia-ui-a2ui/references/strategy-engines.md +0 -111
  133. package/skills/adia-ui-a2ui/references/teach-protocol.md +0 -220
  134. package/skills/adia-ui-a2ui/references/zettel-calibration.md +0 -93
  135. package/skills/adia-ui-a2ui/scripts/audit-a2ui-roster.mjs +0 -96
  136. package/skills/adia-ui-a2ui/scripts/teach-route.mjs +0 -157
  137. package/skills/adia-ui-a2ui/skill.json +0 -38
  138. package/skills/adia-ui-authoring/CHANGELOG.md +0 -32
  139. package/skills/adia-ui-authoring/SKILL.md +0 -256
  140. package/skills/adia-ui-authoring/assets/case-studies/admin-shell-decomposition.md +0 -101
  141. package/skills/adia-ui-authoring/assets/case-studies/maxtokens-32768-discovery.md +0 -109
  142. package/skills/adia-ui-authoring/assets/case-studies/theme-panel-promotion.md +0 -113
  143. package/skills/adia-ui-authoring/evals/adversarial-design-plan-gates.json +0 -138
  144. package/skills/adia-ui-authoring/evals/routing-corpus.json +0 -245
  145. package/skills/adia-ui-authoring/references/canonical-pattern-index.md +0 -179
  146. package/skills/adia-ui-authoring/references/common-gotchas.md +0 -93
  147. package/skills/adia-ui-authoring/references/composite-demo-protocol.md +0 -1084
  148. package/skills/adia-ui-authoring/references/teach-protocol.md +0 -428
  149. package/skills/adia-ui-authoring/scripts/audit-authoring-roster.mjs +0 -148
  150. package/skills/adia-ui-authoring/skill.json +0 -45
  151. package/skills/adia-ui-dogfood/CHANGELOG.md +0 -17
  152. package/skills/adia-ui-dogfood/README.md +0 -62
  153. package/skills/adia-ui-dogfood/SKILL.md +0 -866
  154. package/skills/adia-ui-dogfood/skill.json +0 -40
  155. package/skills/adia-ui-forge/SKILL.md +0 -88
  156. package/skills/adia-ui-forge/evals/routing-corpus.json +0 -30
  157. package/skills/adia-ui-gen-review/CHANGELOG.md +0 -108
  158. package/skills/adia-ui-gen-review/SKILL.md +0 -266
  159. package/skills/adia-ui-gen-review/references/loop-protocol.md +0 -712
  160. package/skills/adia-ui-gen-review/references/rubric-cosmetic.md +0 -144
  161. package/skills/adia-ui-gen-review/references/rubric-decompose.md +0 -117
  162. package/skills/adia-ui-gen-review/references/rubric-score.md +0 -249
  163. package/skills/adia-ui-gen-review/references/teach-protocol.md +0 -214
  164. package/skills/adia-ui-gen-review/skill.json +0 -23
  165. package/skills/adia-ui-llm/CHANGELOG.md +0 -25
  166. package/skills/adia-ui-llm/SKILL.md +0 -165
  167. package/skills/adia-ui-llm/evals/adversarial-corpus.json +0 -75
  168. package/skills/adia-ui-llm/evals/routing-corpus.json +0 -30
  169. package/skills/adia-ui-llm/evals/teach-routing-cases.json +0 -73
  170. package/skills/adia-ui-llm/references/teach-protocol.md +0 -78
  171. package/skills/adia-ui-llm/scripts/audit-llm-roster.mjs +0 -93
  172. package/skills/adia-ui-llm/scripts/teach-route.mjs +0 -119
  173. package/skills/adia-ui-llm/skill.json +0 -33
  174. package/skills/adia-ui-ops/CHANGELOG.md +0 -291
  175. package/skills/adia-ui-ops/SKILL.md +0 -401
  176. package/skills/adia-ui-ops/references/INDEX.md +0 -158
  177. package/skills/adia-ui-ops/references/audit-cadence.md +0 -263
  178. package/skills/adia-ui-ops/references/audit-patterns/archive-link-sweep.md +0 -96
  179. package/skills/adia-ui-ops/references/audit-patterns/audit-history-ledger.md +0 -162
  180. package/skills/adia-ui-ops/references/audit-patterns/browser-bundle-node-imports.md +0 -154
  181. package/skills/adia-ui-ops/references/audit-patterns/changelog-unreleased-bloat.md +0 -75
  182. package/skills/adia-ui-ops/references/audit-patterns/coverage-gaps.md +0 -187
  183. package/skills/adia-ui-ops/references/audit-patterns/entry-file-coverage.md +0 -122
  184. package/skills/adia-ui-ops/references/audit-patterns/format-hygiene.md +0 -217
  185. package/skills/adia-ui-ops/references/audit-patterns/lockstep-versioning.md +0 -113
  186. package/skills/adia-ui-ops/references/audit-patterns/memory-fragmentation.md +0 -180
  187. package/skills/adia-ui-ops/references/audit-patterns/orphan-detection.md +0 -202
  188. package/skills/adia-ui-ops/references/audit-patterns/pointer-validation.md +0 -180
  189. package/skills/adia-ui-ops/references/audit-patterns/redundancy-detection.md +0 -210
  190. package/skills/adia-ui-ops/references/audit-patterns/spec-dating-sweep.md +0 -91
  191. package/skills/adia-ui-ops/references/audit-patterns/stale-content.md +0 -182
  192. package/skills/adia-ui-ops/references/audit-patterns/staleness-tooling.md +0 -156
  193. package/skills/adia-ui-ops/references/audit-patterns/token-waste-detection.md +0 -196
  194. package/skills/adia-ui-ops/references/doc-types/adr-pattern.md +0 -210
  195. package/skills/adia-ui-ops/references/doc-types/architecture-md.md +0 -190
  196. package/skills/adia-ui-ops/references/doc-types/changelog.md +0 -183
  197. package/skills/adia-ui-ops/references/doc-types/decisions-log.md +0 -146
  198. package/skills/adia-ui-ops/references/doc-types/plan-roadmap.md +0 -182
  199. package/skills/adia-ui-ops/references/doc-types/postmortem-pattern.md +0 -206
  200. package/skills/adia-ui-ops/references/genres/prose-and-writing.md +0 -149
  201. package/skills/adia-ui-ops/references/guidance/context-budget.md +0 -137
  202. package/skills/adia-ui-ops/references/guidance/llm-doc-writing.md +0 -116
  203. package/skills/adia-ui-ops/references/guidance/reliability-dial.md +0 -186
  204. package/skills/adia-ui-ops/references/recipes/adr-introduction.md +0 -211
  205. package/skills/adia-ui-ops/references/recipes/audit-existing-repo.md +0 -234
  206. package/skills/adia-ui-ops/references/recipes/cold-start-harvest.md +0 -263
  207. package/skills/adia-ui-ops/references/recipes/concurrent-learnings-merge.md +0 -158
  208. package/skills/adia-ui-ops/references/recipes/continuous-learning-loop.md +0 -169
  209. package/skills/adia-ui-ops/references/recipes/external-reference-verification.md +0 -158
  210. package/skills/adia-ui-ops/references/recipes/findings-index-readout.md +0 -126
  211. package/skills/adia-ui-ops/references/recipes/greenfield-setup.md +0 -252
  212. package/skills/adia-ui-ops/references/recipes/harvest-repo-brain.md +0 -169
  213. package/skills/adia-ui-ops/references/recipes/import-repo-brain-harvest.md +0 -153
  214. package/skills/adia-ui-ops/references/recipes/memory-organization.md +0 -182
  215. package/skills/adia-ui-ops/references/recipes/recommend-then-validate.md +0 -199
  216. package/skills/adia-ui-ops/references/recipes/self-healing-hooks.md +0 -366
  217. package/skills/adia-ui-ops/references/recipes/skill-stewardship-loop.md +0 -113
  218. package/skills/adia-ui-ops/references/standards/agents-md-spec.md +0 -138
  219. package/skills/adia-ui-ops/references/standards/claude-md-convention.md +0 -123
  220. package/skills/adia-ui-ops/references/standards/cross-tool-matrix.md +0 -85
  221. package/skills/adia-ui-ops/references/standards/readme-conventions.md +0 -232
  222. package/skills/adia-ui-ops/references/teach-protocol.md +0 -215
  223. package/skills/adia-ui-ops/scripts/audit-ops-roster.mjs +0 -104
  224. package/skills/adia-ui-ops/skill.json +0 -65
  225. package/skills/adia-ui-release/CHANGELOG.md +0 -66
  226. package/skills/adia-ui-release/SKILL.md +0 -323
  227. package/skills/adia-ui-release/assets/case-studies/2026-05-20-batch-push-v0.6.14-v0.6.15.md +0 -144
  228. package/skills/adia-ui-release/assets/case-studies/2026-05-20-corpus-drift-remediation-v0.6.15.md +0 -155
  229. package/skills/adia-ui-release/assets/case-studies/2026-05-20-version-skip-correction-v0.6.12.md +0 -114
  230. package/skills/adia-ui-release/assets/case-studies/2026-05-21-author-from-scratch-v0.6.18.md +0 -139
  231. package/skills/adia-ui-release/assets/case-studies/2026-05-21-feedback37-retraction-v0.6.21.md +0 -124
  232. package/skills/adia-ui-release/assets/case-studies/2026-05-21-fn1-enrichment-pass-v0.6.19.md +0 -125
  233. package/skills/adia-ui-release/assets/case-studies/2026-05-21-stale-test-detection-v0.6.20.md +0 -142
  234. package/skills/adia-ui-release/assets/case-studies/2026-05-23-freshness-gate-recovery-v0.6.32.md +0 -97
  235. package/skills/adia-ui-release/assets/case-studies/2026-05-26-catalog-drift-recurring-v0.6.40.md +0 -147
  236. package/skills/adia-ui-release/assets/templates/stub-changelog.template.md +0 -22
  237. package/skills/adia-ui-release/evals/evals.json +0 -164
  238. package/skills/adia-ui-release/references/changelog-discipline.md +0 -250
  239. package/skills/adia-ui-release/references/cycle-happy-path.md +0 -520
  240. package/skills/adia-ui-release/references/exe-deploy.md +0 -149
  241. package/skills/adia-ui-release/references/gates-catalog.md +0 -778
  242. package/skills/adia-ui-release/references/independent-package-release.md +0 -129
  243. package/skills/adia-ui-release/references/ledger-discipline.md +0 -232
  244. package/skills/adia-ui-release/references/migration-guide-authoring.md +0 -174
  245. package/skills/adia-ui-release/references/multi-agent-baseline.md +0 -207
  246. package/skills/adia-ui-release/references/notes-authoring.md +0 -212
  247. package/skills/adia-ui-release/references/recovery-paths.md +0 -262
  248. package/skills/adia-ui-release/references/rollup-notes.md +0 -208
  249. package/skills/adia-ui-release/references/teach-protocol.md +0 -468
  250. package/skills/adia-ui-release/scripts/audit-gate-roster.mjs +0 -196
  251. package/skills/adia-ui-release/scripts/make-ledger.mjs +0 -200
  252. package/skills/adia-ui-release/skill.json +0 -77
  253. package/skills/dogfood-sweep/CHANGELOG.md +0 -37
  254. package/skills/dogfood-sweep/README.md +0 -105
  255. package/skills/dogfood-sweep/SKILL.md +0 -1000
  256. package/skills/dogfood-sweep/analyze.mjs +0 -600
  257. package/skills/dogfood-sweep/skill.json +0 -31
  258. /package/skills/{adia-ui-authoring → adia-author}/references/api-contract.md +0 -0
  259. /package/skills/{adia-ui-release → adia-release}/scripts/assert-monorepo-root.mjs +0 -0
@@ -1,67 +1,295 @@
1
1
  {
2
2
  "$schema": "https://anthropic.com/schemas/agent-routing-evals.v1.json",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Routing-accuracy corpus for the adia-ui-forge in-repo agent roster (6 cards + README). For each user phrase, declares the expected agent that should activate (or null for phrases that route nowhere / off-topic). Scored by `scripts/skills/run-agent-evals.mjs --agents-dir packages/plugins/adia-ui-forge/agents`. Boris falsification test T1 (agent routing). First eval pass 2026-06-08.",
5
5
  "scope": "Forge agents: tech-lead, author, a2ui-engineer, release-engineer, repo-steward, spec-architect, verifier.",
6
6
  "scoring_notes": "Same TF-IDF scorer as scripts/skills/run-skill-evals.mjs. Treat misroutes as signal to tighten the card's description field. MIN_SCORE_THRESHOLD 2.0 + MIN_MATCH_COUNT 2 required to activate.",
7
-
8
7
  "phrases": [
9
- { "id": "tech-lead-01", "phrase": "decompose this feature into layer-slices and assign them", "expected": "tech-lead", "rationale": "Feature decomposition + assignment — tech-lead's orchestration role." },
10
- { "id": "tech-lead-02", "phrase": "gate the release on a green verify pass", "expected": "tech-lead", "rationale": "Verify-gate sequencing — tech-lead's integration closure." },
11
- { "id": "tech-lead-03", "phrase": "sequence the cross-layer handoff for this release window", "expected": "tech-lead", "rationale": "Multi-agent handoff sequencing is tech-lead's primary role." },
12
- { "id": "tech-lead-04", "phrase": "orchestrate the v0.8.0 release window across all layers", "expected": "tech-lead", "rationale": "Orchestrate release window — tech-lead." },
13
- { "id": "tech-lead-05", "phrase": "I have 6 items for this sprint, who should own what?", "expected": "tech-lead", "rationale": "Work decomposition + claim assignment — tech-lead." },
14
-
15
- { "id": "author-01", "phrase": "add a new web-component primitive for timeline-ui", "expected": "author", "rationale": "In-tree primitive authoring — author's four-layer scope." },
16
- { "id": "author-02", "phrase": "modify the card-ui yaml to add a compact attribute", "expected": "author", "rationale": "In-tree yaml edit — author." },
17
- { "id": "author-03", "phrase": "fix the four-axis contract violation on this component", "expected": "author", "rationale": "Four-axis contract — author's authoring discipline." },
18
- { "id": "author-04", "phrase": "add a new token to the styles/ foundation bundle", "expected": "author", "rationale": "Foundation token authoring — author." },
19
- { "id": "author-05", "phrase": "wire up a .contents.js behavior for the chat surface", "expected": "author", "rationale": "Functional wiring (.contents.js) is author's scope." },
20
- { "id": "author-06", "phrase": "update the docs site sitemap for the new component page", "expected": "author", "rationale": "Docs site authoring — author's fourth layer." },
21
- { "id": "author-07", "phrase": "promote inline CSS to a proper @layer module file", "expected": "author", "rationale": "Styles refactor — author." },
22
-
23
- { "id": "a2ui-01", "phrase": "diagnose why zettel composition coverage dropped", "expected": "a2ui-engineer", "rationale": "Zettel engine + eval gap diagnosis — a2ui-engineer." },
24
- { "id": "a2ui-02", "phrase": "harvest a new training chunk for the corpus", "expected": "a2ui-engineer", "rationale": "Corpus authoring — a2ui-engineer." },
25
- { "id": "a2ui-03", "phrase": "tune the STRONG_MATCH threshold for free-form composition", "expected": "a2ui-engineer", "rationale": "Strategy calibration — a2ui-engineer." },
26
- { "id": "a2ui-04", "phrase": "add a new MCP tool to the a2ui-mcp server", "expected": "a2ui-engineer", "rationale": "MCP server authoring — a2ui-engineer." },
27
- { "id": "a2ui-05", "phrase": "the eval regression shows MRR dropped — investigate", "expected": "a2ui-engineer", "rationale": "Eval regression diagnosis — a2ui-engineer." },
28
- { "id": "a2ui-06", "phrase": "extract a fragment from this monolithic HTML pattern for the corpus", "expected": "a2ui-engineer", "rationale": "Fragment extraction into corpus — a2ui-engineer." },
29
-
30
- { "id": "release-01", "phrase": "cut a v0.7.17 lockstep release of all 9 packages", "expected": "release-engineer", "rationale": "9-package lockstep cut — release-engineer's primary task." },
31
- { "id": "release-02", "phrase": "publish the npm packages after the tag", "expected": "release-engineer", "rationale": "npm publish release-engineer." },
32
- { "id": "release-03", "phrase": "batch push the accumulated v0.7.x releases", "expected": "release-engineer", "rationale": "Batch push — release-engineer." },
33
- { "id": "release-04", "phrase": "we shipped a version skip, need to recover", "expected": "release-engineer", "rationale": "Version-skip recovery — release-engineer." },
34
- { "id": "release-05", "phrase": "write the GitHub release notes for v0.7.16", "expected": "release-engineer", "rationale": "Release notes authoring — release-engineer." },
35
- { "id": "release-06", "phrase": "ship the adia-ui-factory plugin as a standalone version cut", "expected": "release-engineer", "rationale": "Independent-version plugin ship — also release-engineer." },
36
-
37
- { "id": "steward-01", "phrase": "audit the .brain folder for stale content", "expected": "repo-steward", "rationale": "Repo-brain / memory-layer audit repo-steward." },
38
- { "id": "steward-02", "phrase": "update the PLAN for the v0.8 milestone", "expected": "repo-steward", "rationale": "PLAN/ROADMAP currency — repo-steward." },
39
- { "id": "steward-03", "phrase": "write the migration guide for the v0.7 → v0.8 breaking changes", "expected": "repo-steward", "rationale": "Migration guide authoring — repo-steward (folds in migration-agent)." },
40
- { "id": "steward-04", "phrase": "harvest a memory entry from today's session", "expected": "repo-steward", "rationale": "Memory-layer curation — repo-steward." },
41
- { "id": "steward-05", "phrase": "curate the AGENTS.md stewardship section after the rename", "expected": "repo-steward", "rationale": "AGENTS.md / skill stewardship — repo-steward." },
42
- { "id": "steward-06", "phrase": "write a postmortem for the 2026-06-02 agent collision incident", "expected": "repo-steward", "rationale": "Postmortems — repo-steward." },
43
-
44
- { "id": "architect-01", "phrase": "turn this PRD into a locked spec before authoring starts", "expected": "spec-architect", "rationale": "PRD → spec — spec-architect's primary task." },
45
- { "id": "architect-02", "phrase": "author an ADR for the light-DOM substrate decision", "expected": "spec-architect", "rationale": "ADR authoring — spec-architect." },
46
- { "id": "architect-03", "phrase": "write a design note with guardrails before we build this feature", "expected": "spec-architect", "rationale": "Design note + guardrails — spec-architect." },
47
- { "id": "architect-04", "phrase": "validate this premise before any code is written", "expected": "spec-architect", "rationale": "Premise validation (plan-before-execute) spec-architect." },
48
- { "id": "architect-05", "phrase": "I need a spec for the new canvas feature", "expected": "spec-architect", "rationale": "Spec authoring — spec-architect." },
49
-
50
- { "id": "verifier-01", "phrase": "run the visual regression probes on the dogfood app", "expected": "verifier", "rationale": "Visual + structural review — verifier." },
51
- { "id": "verifier-02", "phrase": "run a11y probes on the new admin-shell surface", "expected": "verifier", "rationale": "A11y probing — verifier." },
52
- { "id": "verifier-03", "phrase": "set up a new gate script to enforce the card-ui body contract", "expected": "verifier", "rationale": "Test substrate / gate scripts — verifier." },
53
- { "id": "verifier-04", "phrase": "the gen-UI review flagged visual drift — investigate", "expected": "verifier", "rationale": "Gen-UI review + visual coherence — verifier." },
54
- { "id": "verifier-05", "phrase": "run the full pre-merge verification pass", "expected": "verifier", "rationale": "Pre-merge verify pass — verifier's core role." },
55
-
56
- { "id": "null-01", "phrase": "what's the weather in Helsinki today?", "expected": null, "note": "Off-topic." },
57
- { "id": "null-02", "phrase": "explain how React useEffect hooks work", "expected": null, "note": "Generic programming — no forge agent applies." },
58
- { "id": "null-03", "phrase": "compose a settings page for a consumer app", "expected": null, "note": "Consumer composition — factory/screen-composer, not a forge card." },
59
- { "id": "null-04", "phrase": "scaffold a new SPA host for the consumer's app", "expected": null, "note": "Consumer scaffolding — factory, not forge." },
60
-
61
- { "id": "ambig-01", "phrase": "verify the release before cutting", "expected": "verifier", "ambiguous_between": ["verifier", "release-engineer"], "note": "Both cards mention 'verify'. Verifier owns the independent structural pass; release-engineer runs pre-flight gates. Corpus labels verifier for the structural-proof framing; release-engineer for 'pre-flight' framing. This phrasing skews verifier." },
62
- { "id": "ambig-02", "phrase": "write up what happened in the last cycle", "expected": "release-engineer", "ambiguous_between": ["release-engineer", "repo-steward"], "note": "Post-cycle writeup defaults to release ledger (release-engineer). If framed as an incident → repo-steward postmortem. Context determines the split." }
8
+ {
9
+ "id": "tech-lead-01",
10
+ "phrase": "decompose this feature into layer-slices and assign them",
11
+ "expected": null,
12
+ "rationale": "Feature decomposition + assignment — tech-lead's orchestration role."
13
+ },
14
+ {
15
+ "id": "tech-lead-02",
16
+ "phrase": "gate the release on a green verify pass",
17
+ "expected": null,
18
+ "rationale": "Verify-gate sequencing tech-lead's integration closure."
19
+ },
20
+ {
21
+ "id": "tech-lead-03",
22
+ "phrase": "sequence the cross-layer handoff for this release window",
23
+ "expected": null,
24
+ "rationale": "Multi-agent handoff sequencing is tech-lead's primary role."
25
+ },
26
+ {
27
+ "id": "tech-lead-04",
28
+ "phrase": "orchestrate the v0.8.0 release window across all layers",
29
+ "expected": null,
30
+ "rationale": "Orchestrate release windowtech-lead."
31
+ },
32
+ {
33
+ "id": "tech-lead-05",
34
+ "phrase": "I have 6 items for this sprint, who should own what?",
35
+ "expected": null,
36
+ "rationale": "Work decomposition + claim assignmenttech-lead."
37
+ },
38
+ {
39
+ "id": "author-01",
40
+ "phrase": "add a new web-component primitive for timeline-ui",
41
+ "expected": "component-author",
42
+ "rationale": "In-tree primitive authoring — author's four-layer scope."
43
+ },
44
+ {
45
+ "id": "author-02",
46
+ "phrase": "modify the card-ui yaml to add a compact attribute",
47
+ "expected": "component-author",
48
+ "rationale": "In-tree yaml edit — author."
49
+ },
50
+ {
51
+ "id": "author-03",
52
+ "phrase": "fix the four-axis contract violation on this component",
53
+ "expected": "component-author",
54
+ "rationale": "Four-axis contract — author's authoring discipline."
55
+ },
56
+ {
57
+ "id": "author-04",
58
+ "phrase": "add a new token to the styles/ foundation bundle",
59
+ "expected": "component-author",
60
+ "rationale": "Foundation token authoring author."
61
+ },
62
+ {
63
+ "id": "author-05",
64
+ "phrase": "wire up a .contents.js behavior for the chat surface",
65
+ "expected": "component-author",
66
+ "rationale": "Functional wiring (.contents.js) is author's scope."
67
+ },
68
+ {
69
+ "id": "author-06",
70
+ "phrase": "update the docs site sitemap for the new component page",
71
+ "expected": "component-author",
72
+ "rationale": "Docs site authoring — author's fourth layer."
73
+ },
74
+ {
75
+ "id": "author-07",
76
+ "phrase": "promote inline CSS to a proper @layer module file",
77
+ "expected": "component-author",
78
+ "rationale": "Styles refactor — author."
79
+ },
80
+ {
81
+ "id": "a2ui-01",
82
+ "phrase": "diagnose why zettel composition coverage dropped",
83
+ "expected": "a2ui-engineer",
84
+ "rationale": "Zettel engine + eval gap diagnosis — a2ui-engineer."
85
+ },
86
+ {
87
+ "id": "a2ui-02",
88
+ "phrase": "harvest a new training chunk for the corpus",
89
+ "expected": "a2ui-engineer",
90
+ "rationale": "Corpus authoring — a2ui-engineer."
91
+ },
92
+ {
93
+ "id": "a2ui-03",
94
+ "phrase": "tune the STRONG_MATCH threshold for free-form composition",
95
+ "expected": "a2ui-engineer",
96
+ "rationale": "Strategy calibration — a2ui-engineer."
97
+ },
98
+ {
99
+ "id": "a2ui-04",
100
+ "phrase": "add a new MCP tool to the a2ui-mcp server",
101
+ "expected": "a2ui-engineer",
102
+ "rationale": "MCP server authoring — a2ui-engineer."
103
+ },
104
+ {
105
+ "id": "a2ui-05",
106
+ "phrase": "the eval regression shows MRR dropped — investigate",
107
+ "expected": "a2ui-engineer",
108
+ "rationale": "Eval regression diagnosis — a2ui-engineer."
109
+ },
110
+ {
111
+ "id": "a2ui-06",
112
+ "phrase": "extract a fragment from this monolithic HTML pattern for the corpus",
113
+ "expected": "a2ui-engineer",
114
+ "rationale": "Fragment extraction into corpus — a2ui-engineer."
115
+ },
116
+ {
117
+ "id": "release-01",
118
+ "phrase": "cut a v0.7.17 lockstep release of all 9 packages",
119
+ "expected": "release-engineer",
120
+ "rationale": "9-package lockstep cut — release-engineer's primary task."
121
+ },
122
+ {
123
+ "id": "release-02",
124
+ "phrase": "publish the npm packages after the tag",
125
+ "expected": "release-engineer",
126
+ "rationale": "npm publish — release-engineer."
127
+ },
128
+ {
129
+ "id": "release-03",
130
+ "phrase": "batch push the accumulated v0.7.x releases",
131
+ "expected": "release-engineer",
132
+ "rationale": "Batch push — release-engineer."
133
+ },
134
+ {
135
+ "id": "release-04",
136
+ "phrase": "we shipped a version skip, need to recover",
137
+ "expected": "release-engineer",
138
+ "rationale": "Version-skip recovery — release-engineer."
139
+ },
140
+ {
141
+ "id": "release-05",
142
+ "phrase": "write the GitHub release notes for v0.7.16",
143
+ "expected": "release-engineer",
144
+ "rationale": "Release notes authoring — release-engineer."
145
+ },
146
+ {
147
+ "id": "release-06",
148
+ "phrase": "ship the adia-ui-factory plugin as a standalone version cut",
149
+ "expected": "release-engineer",
150
+ "rationale": "Independent-version plugin ship — also release-engineer."
151
+ },
152
+ {
153
+ "id": "steward-01",
154
+ "phrase": "audit the .brain folder for stale content",
155
+ "expected": null,
156
+ "rationale": "Repo-brain / memory-layer audit — repo-steward."
157
+ },
158
+ {
159
+ "id": "steward-02",
160
+ "phrase": "update the PLAN for the v0.8 milestone",
161
+ "expected": null,
162
+ "rationale": "PLAN/ROADMAP currency — repo-steward."
163
+ },
164
+ {
165
+ "id": "steward-03",
166
+ "phrase": "write the migration guide for the v0.7 → v0.8 breaking changes",
167
+ "expected": null,
168
+ "rationale": "Migration guide authoring — repo-steward (folds in migration-agent)."
169
+ },
170
+ {
171
+ "id": "steward-04",
172
+ "phrase": "harvest a memory entry from today's session",
173
+ "expected": null,
174
+ "rationale": "Memory-layer curation — repo-steward."
175
+ },
176
+ {
177
+ "id": "steward-05",
178
+ "phrase": "curate the AGENTS.md stewardship section after the rename",
179
+ "expected": null,
180
+ "rationale": "AGENTS.md / skill stewardship — repo-steward."
181
+ },
182
+ {
183
+ "id": "steward-06",
184
+ "phrase": "write a postmortem for the 2026-06-02 agent collision incident",
185
+ "expected": null,
186
+ "rationale": "Postmortems — repo-steward."
187
+ },
188
+ {
189
+ "id": "architect-01",
190
+ "phrase": "turn this PRD into a locked spec before authoring starts",
191
+ "expected": null,
192
+ "rationale": "PRD → spec — spec-architect's primary task."
193
+ },
194
+ {
195
+ "id": "architect-02",
196
+ "phrase": "author an ADR for the light-DOM substrate decision",
197
+ "expected": null,
198
+ "rationale": "ADR authoring — spec-architect."
199
+ },
200
+ {
201
+ "id": "architect-03",
202
+ "phrase": "write a design note with guardrails before we build this feature",
203
+ "expected": null,
204
+ "rationale": "Design note + guardrails — spec-architect."
205
+ },
206
+ {
207
+ "id": "architect-04",
208
+ "phrase": "validate this premise before any code is written",
209
+ "expected": null,
210
+ "rationale": "Premise validation (plan-before-execute) — spec-architect."
211
+ },
212
+ {
213
+ "id": "architect-05",
214
+ "phrase": "I need a spec for the new canvas feature",
215
+ "expected": null,
216
+ "rationale": "Spec authoring — spec-architect."
217
+ },
218
+ {
219
+ "id": "verifier-01",
220
+ "phrase": "run the visual regression probes on the dogfood app",
221
+ "expected": "framework-verifier",
222
+ "rationale": "Visual + structural review — verifier."
223
+ },
224
+ {
225
+ "id": "verifier-02",
226
+ "phrase": "run a11y probes on the new admin-shell surface",
227
+ "expected": "framework-verifier",
228
+ "rationale": "A11y probing — verifier."
229
+ },
230
+ {
231
+ "id": "verifier-03",
232
+ "phrase": "set up a new gate script to enforce the card-ui body contract",
233
+ "expected": "framework-verifier",
234
+ "rationale": "Test substrate / gate scripts — verifier."
235
+ },
236
+ {
237
+ "id": "verifier-04",
238
+ "phrase": "the gen-UI review flagged visual drift — investigate",
239
+ "expected": "framework-verifier",
240
+ "rationale": "Gen-UI review + visual coherence — verifier."
241
+ },
242
+ {
243
+ "id": "verifier-05",
244
+ "phrase": "run the full pre-merge verification pass",
245
+ "expected": "framework-verifier",
246
+ "rationale": "Pre-merge verify pass — verifier's core role."
247
+ },
248
+ {
249
+ "id": "null-01",
250
+ "phrase": "what's the weather in Helsinki today?",
251
+ "expected": null,
252
+ "note": "Off-topic."
253
+ },
254
+ {
255
+ "id": "null-02",
256
+ "phrase": "explain how React useEffect hooks work",
257
+ "expected": null,
258
+ "note": "Generic programming — no forge agent applies."
259
+ },
260
+ {
261
+ "id": "null-03",
262
+ "phrase": "compose a settings page for a consumer app",
263
+ "expected": null,
264
+ "note": "Consumer composition — factory/screen-composer, not a forge card."
265
+ },
266
+ {
267
+ "id": "null-04",
268
+ "phrase": "scaffold a new SPA host for the consumer's app",
269
+ "expected": null,
270
+ "note": "Consumer scaffolding — factory, not forge."
271
+ },
272
+ {
273
+ "id": "ambig-01",
274
+ "phrase": "verify the release before cutting",
275
+ "expected": "framework-verifier",
276
+ "ambiguous_between": [
277
+ "verifier",
278
+ "release-engineer"
279
+ ],
280
+ "note": "Both cards mention 'verify'. Verifier owns the independent structural pass; release-engineer runs pre-flight gates. Corpus labels verifier for the structural-proof framing; release-engineer for 'pre-flight' framing. This phrasing skews verifier."
281
+ },
282
+ {
283
+ "id": "ambig-02",
284
+ "phrase": "write up what happened in the last cycle",
285
+ "expected": "release-engineer",
286
+ "ambiguous_between": [
287
+ "release-engineer",
288
+ "repo-steward"
289
+ ],
290
+ "note": "Post-cycle writeup defaults to release ledger (release-engineer). If framed as an incident → repo-steward postmortem. Context determines the split."
291
+ }
63
292
  ],
64
-
65
293
  "expected_baseline": {
66
294
  "as_of": "2026-06-08",
67
295
  "scorer_version": "0.1.0",
@@ -69,21 +297,22 @@
69
297
  "scorer_min_match_count": 2,
70
298
  "accuracy": 0.935,
71
299
  "per_agent_f1": {
72
- "a2ui-engineer": 1.00,
300
+ "a2ui-engineer": 1.0,
73
301
  "author": 0.93,
74
302
  "release-engineer": 0.92,
75
- "repo-steward": 1.00,
76
- "spec-architect": 1.00,
77
- "tech-lead": 0.80,
303
+ "repo-steward": 1.0,
304
+ "spec-architect": 1.0,
305
+ "tech-lead": 0.8,
78
306
  "verifier": 0.91,
79
307
  "__null__": 0.89
80
308
  },
81
309
  "notes": "First measured baseline 2026-06-08 (post-triggers vocabulary pass). Two iterations: (1) 56.5% pre-triggers; (2) 93.5% after adding triggers: fields to all 7 cards. Remaining 3 misroutes are INHERENT-SCORER-LIMITS documented below. null-03/null-04 consumer phrases correctly fire null (forge cards don't match consumer-domain vocabulary).",
82
- "strict_floor_accuracy": 0.90,
310
+ "strict_floor_accuracy": 0.9,
83
311
  "named_weakpoints": [
84
312
  "tech-lead-04 'orchestrate the v0.8.0 release window across all layers' → author (7.159) over tech-lead (6.753) — margin 0.4 points. Author's description contains @layer which contributes 'layer' token; tech-lead's trigger block has 'release window' + 'orchestrate' but fewer matching tokens in this phrase. Near-tie inherent-scorer-limit; monitor in next pass.",
85
313
  "ambig-01 'verify the release before cutting' → tech-lead (3.962) ties verifier (3.962) exactly; alphabetic tiebreak selects tech-lead ('t' > 'v' alphabetically... wait — alphabetic ascending: tech-lead < verifier). Labeled verifier; inherent alphabetic-tie ambiguity.",
86
314
  "ambig-02 'write up what happened in the last cycle' → null (max score 1.981 < 2.0 threshold). Only content tokens are 'write' + 'happened'; 'happened' doesn't appear in any card's vocabulary. Inherent: vague retrospective phrasing. A real orchestrator would ask 'release ledger or incident postmortem?'."
87
315
  ]
88
- }
89
- }
316
+ },
317
+ "notes": "Re-keyed to the v2 4-agent roster 2026-07-11 (tech-lead/spec-architect/repo-steward retired — their phrases now expect null: the host loop owns orchestration/specs/hygiene)."
318
+ }
@@ -0,0 +1,94 @@
1
+ #!/usr/bin/env python3
2
+ """demo-postwrite-pattern-gate — PostToolUse check: composite demos cite a pattern source.
3
+
4
+ Composite demos authored without surveying a canonical page produced the
5
+ 2026-05 broken-demo cohort; the repo's no-merge CI gate
6
+ (`npm run audit:demo-pattern-source:strict`) enforces a `Pattern source:`
7
+ citation. This hook moves that feedback from CI-time to write-time: when a
8
+ `packages/web-modules/**/*.{examples,contents}.html` file is written without
9
+ the citation, it feeds the repair back immediately.
10
+
11
+ It checks only the deterministic residue (citation present). Whether the
12
+ cited pattern is APPROPRIATE stays judgment — the adia-author skill's
13
+ composite-demo reference owns that.
14
+
15
+ Usage:
16
+ demo-postwrite-pattern-gate --hook # PostToolUse mode: event JSON on stdin
17
+ demo-postwrite-pattern-gate selftest # prove matcher + content check on fixtures
18
+ """
19
+ import json
20
+ import os
21
+ import sys
22
+
23
+ MARKER = "Pattern source:"
24
+
25
+
26
+ def in_scope(path):
27
+ return "packages/web-modules/" in path and (
28
+ path.endswith(".examples.html") or path.endswith(".contents.html")
29
+ )
30
+
31
+
32
+ def check_content(text):
33
+ return MARKER in text
34
+
35
+
36
+ def hook_mode():
37
+ try:
38
+ event = json.load(sys.stdin)
39
+ except Exception:
40
+ return 0
41
+ tool_input = event.get("tool_input") or {}
42
+ path = tool_input.get("file_path") or ""
43
+ if not in_scope(path):
44
+ return 0
45
+ try:
46
+ with open(path, encoding="utf-8", errors="replace") as f:
47
+ text = f.read()
48
+ except OSError:
49
+ return 0
50
+ if check_content(text):
51
+ return 0
52
+ reason = (
53
+ f"demo-postwrite-pattern-gate · {path} has no `Pattern source:` citation. "
54
+ "Composite demos must cite the canonical page they pattern from — survey "
55
+ "apps/<area>/app/**.contents.html + catalog/ui-patterns/ first, then add "
56
+ "`<!-- Pattern source: <path> -->` near the top (see adia-author's "
57
+ "composite-demo reference). CI enforces this via "
58
+ "`npm run audit:demo-pattern-source:strict`. If a citation is genuinely "
59
+ "impossible, document the carve-out in the file header instead."
60
+ )
61
+ print(json.dumps({"decision": "block", "reason": reason}))
62
+ return 0
63
+
64
+
65
+ def selftest():
66
+ scope_cases = [
67
+ ("packages/web-modules/shell/admin/admin.examples.html", True),
68
+ ("packages/web-modules/chat/input/input.contents.html", True),
69
+ ("packages/web-components/components/badge/badge.html", False),
70
+ ("apps/tasks/app/index.contents.html", False),
71
+ ]
72
+ for path, expected in scope_cases:
73
+ if in_scope(path) != expected:
74
+ print(f"selftest: FAIL scope {path}")
75
+ return 1
76
+ content_cases = [
77
+ ("<!-- Pattern source: apps/saas/app/admin/admin.contents.html -->\n<div>", True),
78
+ ("<div>no citation here</div>", False),
79
+ ]
80
+ for text, expected in content_cases:
81
+ if check_content(text) != expected:
82
+ print(f"selftest: FAIL content {text[:30]!r}")
83
+ return 1
84
+ print("selftest: PASS")
85
+ return 0
86
+
87
+
88
+ if __name__ == "__main__":
89
+ if "selftest" in sys.argv:
90
+ sys.exit(selftest())
91
+ if "--hook" in sys.argv:
92
+ sys.exit(hook_mode())
93
+ print(__doc__)
94
+ sys.exit(0)
package/bin/forge-lint CHANGED
@@ -179,8 +179,19 @@ def _hook():
179
179
  return 0
180
180
  findings = lint_text(text, path)
181
181
  if findings:
182
- print(_render(path, findings))
183
- print(" (advisory adia-ui framework authoring smells; the skills own the judgment)")
182
+ # PostToolUse exit-0 stdout is NOT fed to the model — only structured
183
+ # JSON reaches it. additionalContext delivers the advisory repair loop
184
+ # while preserving the never-block invariant.
185
+ context = (
186
+ _render(path, findings)
187
+ + "\n (forge-lint advisory — adia-ui framework authoring smells; the skills own the judgment)"
188
+ )
189
+ print(json.dumps({
190
+ "hookSpecificOutput": {
191
+ "hookEventName": "PostToolUse",
192
+ "additionalContext": context,
193
+ }
194
+ }))
184
195
  return 0 # NEVER block
185
196
 
186
197
 
@@ -228,11 +239,15 @@ def _selftest():
228
239
  "content": ".a { color:#f00; }"}}))
229
240
  sys.stdout = io.StringIO()
230
241
  rc = _hook()
242
+ hook_out = sys.stdout.getvalue()
231
243
  finally:
232
244
  sys.stdin, sys.stdout = saved_in, saved_out
233
245
  if rc != 0:
234
246
  ok = False
235
247
  print("selftest: --hook did not exit 0 on smelly input", file=sys.stderr)
248
+ if rc == 0 and hook_out and '"hookSpecificOutput"' not in hook_out:
249
+ ok = False
250
+ print("selftest: --hook stdout is not structured hookSpecificOutput JSON", file=sys.stderr)
236
251
  print("selftest: PASS" if ok else "selftest: FAIL")
237
252
  return 0 if ok else 1
238
253
 
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env python3
2
+ """sidecar-prewrite-guard — PreToolUse deny on hand-edits to GENERATED artifacts.
3
+
4
+ The framework's generated files (a2ui sidecars, the trait catalog, the
5
+ component reference) are build outputs of the yaml/source SoT. Hand-editing
6
+ them creates drift the verify gates then hard-fail on. This guard converts
7
+ the former AGENTS.md prose rule ("never hand-edit generated registries")
8
+ into enforcement: it denies Write/Edit on the generated paths with a repair
9
+ message naming the real source + rebuild command.
10
+
11
+ Deliberately narrow: only the three generated classes below. Bash-driven
12
+ regeneration (npm run components / build:traits) is unaffected — this guard
13
+ watches the Write/Edit tools only.
14
+
15
+ Usage:
16
+ sidecar-prewrite-guard --hook # PreToolUse mode: event JSON on stdin
17
+ sidecar-prewrite-guard selftest # prove the matcher on embedded fixtures
18
+ """
19
+ import json
20
+ import sys
21
+
22
+ GENERATED = (
23
+ # (predicate description, matcher fn, source-of-truth + rebuild command)
24
+ (
25
+ "trait catalog",
26
+ lambda p: p.endswith("traits/_catalog.json"),
27
+ "edit the trait source files and run `npm run build:traits`",
28
+ ),
29
+ (
30
+ "a2ui sidecar",
31
+ lambda p: p.endswith(".a2ui.json"),
32
+ "edit the component's `<name>.yaml` SoT and run `npm run components`",
33
+ ),
34
+ (
35
+ "generated component reference",
36
+ lambda p: "/.claude/docs/reference/components/" in p
37
+ or p.startswith(".claude/docs/reference/components/"),
38
+ "edit the component yaml/source and run `npm run docs:reference`",
39
+ ),
40
+ )
41
+
42
+
43
+ def classify(path):
44
+ for label, match, fix in GENERATED:
45
+ if match(path):
46
+ return label, fix
47
+ return None, None
48
+
49
+
50
+ def hook_mode():
51
+ try:
52
+ event = json.load(sys.stdin)
53
+ except Exception:
54
+ return 0 # malformed event: stay quiet
55
+ tool_input = event.get("tool_input") or {}
56
+ path = tool_input.get("file_path") or ""
57
+ label, fix = classify(path)
58
+ if not label:
59
+ return 0
60
+ reason = (
61
+ f"sidecar-prewrite-guard · {path} is a GENERATED {label} — "
62
+ f"hand-edits are overwritten and fail the drift gates. Instead: {fix}. "
63
+ "If this block is wrong for this file, report it against "
64
+ ".claude/docs/specs/plugin-estate-v2.md — do not hand-edit the artifact."
65
+ )
66
+ print(
67
+ json.dumps(
68
+ {
69
+ "hookSpecificOutput": {
70
+ "hookEventName": "PreToolUse",
71
+ "permissionDecision": "deny",
72
+ "permissionDecisionReason": reason,
73
+ }
74
+ }
75
+ )
76
+ )
77
+ return 0
78
+
79
+
80
+ def selftest():
81
+ cases = [
82
+ ("packages/web-components/traits/_catalog.json", True),
83
+ ("packages/web-components/components/badge/badge.a2ui.json", True),
84
+ (".claude/docs/reference/components/table.md", True),
85
+ ("packages/web-components/components/badge/badge.yaml", False),
86
+ ("packages/web-components/components/badge/badge.css", False),
87
+ ("apps/tasks/app/index.html", False),
88
+ ]
89
+ for path, should_block in cases:
90
+ blocked = classify(path)[0] is not None
91
+ if blocked != should_block:
92
+ print(f"selftest: FAIL {path} blocked={blocked} expected={should_block}")
93
+ return 1
94
+ print("selftest: PASS")
95
+ return 0
96
+
97
+
98
+ if __name__ == "__main__":
99
+ if "selftest" in sys.argv:
100
+ sys.exit(selftest())
101
+ if "--hook" in sys.argv:
102
+ sys.exit(hook_mode())
103
+ print(__doc__)
104
+ sys.exit(0)
@@ -0,0 +1,9 @@
1
+ ---
2
+ description: Deploy a service or dist to the exe.dev VMs (ui-kit.exe.xyz and siblings), or diagnose a running exe service.
3
+ argument-hint: "[host or service]"
4
+ ---
5
+
6
+ Deploy or diagnose an exe.dev surface. **$ARGUMENTS**
7
+
8
+ Invoke **`adia-deploy`** and follow its playbook for the named host; verify
9
+ against the live endpoint before reporting done.