@event4u/agent-config 14.10.0 → 14.11.0

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 (399) hide show
  1. package/.augment-plugin/marketplace.json +3 -3
  2. package/.augment-plugin/plugin.json +1 -1
  3. package/.claude-plugin/marketplace.json +1 -1
  4. package/CHANGELOG.md +335 -0
  5. package/README.md +1 -1
  6. package/dist/agent-src/commands/design.md +88 -0
  7. package/dist/agent-src/commands/project/analyze.md +47 -0
  8. package/dist/agent-src/commands/review/changes.md +67 -6
  9. package/dist/agent-src/commands/roadmap/create.md +49 -0
  10. package/dist/agent-src/commands/roadmap/next.md +27 -11
  11. package/dist/agent-src/commands/roadmap/process-full.md +14 -0
  12. package/dist/agent-src/commands/video/from-script.md +60 -3
  13. package/dist/agent-src/commands/video/stitch.md +14 -0
  14. package/dist/agent-src/contexts/communication/rules-auto/guidelines-mechanics.md +1 -0
  15. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +154 -2
  16. package/dist/agent-src/rules/active-remediation.md +3 -3
  17. package/dist/agent-src/rules/code-provenance.md +2 -2
  18. package/dist/agent-src/rules/context-hygiene.md +13 -33
  19. package/dist/agent-src/rules/council-availability.md +2 -2
  20. package/dist/agent-src/rules/decision-revisit-gate.md +3 -1
  21. package/dist/agent-src/rules/design-fidelity.md +18 -0
  22. package/dist/agent-src/rules/design-review-after-ui-write.md +2 -2
  23. package/dist/agent-src/rules/evaluator-independence.md +56 -44
  24. package/dist/agent-src/rules/fix-what-you-see.md +9 -1
  25. package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +1 -1
  26. package/dist/agent-src/rules/minimal-safe-diff.md +14 -20
  27. package/dist/agent-src/rules/missing-skill-recovery.md +13 -1
  28. package/dist/agent-src/rules/playbook-precedence.md +105 -0
  29. package/dist/agent-src/rules/recurring-criticism.md +3 -1
  30. package/dist/agent-src/rules/roadmap-progress-sync.md +14 -13
  31. package/dist/agent-src/rules/scale-discipline.md +24 -0
  32. package/dist/agent-src/rules/security-sensitive-stop.md +2 -2
  33. package/dist/agent-src/rules/settings-ask-protocol.md +2 -2
  34. package/dist/agent-src/rules/ui-audit-gate.md +27 -15
  35. package/dist/agent-src/rules/untrusted-input-defense.md +2 -2
  36. package/dist/agent-src/skills/accessibility-auditor/SKILL.md +19 -0
  37. package/dist/agent-src/skills/adr-create/SKILL.md +7 -0
  38. package/dist/agent-src/skills/agents-md-thin-root/SKILL.md +33 -0
  39. package/dist/agent-src/skills/ai-council/references/advanced-modes.md +17 -3
  40. package/dist/agent-src/skills/ai-council/references/output-and-synthesis.md +31 -0
  41. package/dist/agent-src/skills/ai-council/references/procedure.md +19 -0
  42. package/dist/agent-src/skills/alerting-doctrine/SKILL.md +225 -0
  43. package/dist/agent-src/skills/alerting-doctrine/evals/triggers.json +17 -0
  44. package/dist/agent-src/skills/authz-review/SKILL.md +0 -1
  45. package/dist/agent-src/skills/blast-radius-analyzer/SKILL.md +32 -0
  46. package/dist/agent-src/skills/brand/SKILL.md +3 -0
  47. package/dist/agent-src/skills/brand-asset-generation/SKILL.md +3 -0
  48. package/dist/agent-src/skills/brand-audit/SKILL.md +3 -0
  49. package/dist/agent-src/skills/brand-identity/SKILL.md +3 -0
  50. package/dist/agent-src/skills/brand-strategy/SKILL.md +3 -0
  51. package/dist/agent-src/skills/brand-to-tokens/SKILL.md +3 -0
  52. package/dist/agent-src/skills/check-refs/SKILL.md +3 -0
  53. package/dist/agent-src/skills/code-review/SKILL.md +11 -0
  54. package/dist/agent-src/skills/command-routing/SKILL.md +6 -0
  55. package/dist/agent-src/skills/condense-memory/SKILL.md +3 -0
  56. package/dist/agent-src/skills/context-authoring/SKILL.md +1 -1
  57. package/dist/agent-src/skills/conventional-commits-writing/SKILL.md +3 -0
  58. package/dist/agent-src/skills/copilot-agents-optimization/SKILL.md +10 -0
  59. package/dist/agent-src/skills/corpus-grounding/SKILL.md +3 -0
  60. package/dist/agent-src/skills/design-intelligence/SKILL.md +3 -0
  61. package/dist/agent-src/skills/design-intelligence/data/landing.csv +36 -35
  62. package/dist/agent-src/skills/design-intelligence/data/stacks/threejs.csv +1 -0
  63. package/dist/agent-src/skills/design-review/SKILL.md +79 -1
  64. package/dist/agent-src/skills/design-review/references/verification-automation.md +41 -0
  65. package/dist/agent-src/skills/design-system-capture/SKILL.md +35 -40
  66. package/dist/agent-src/skills/design-system-capture/references/import-procedure.md +50 -0
  67. package/dist/agent-src/skills/design-tokens/SKILL.md +3 -0
  68. package/dist/agent-src/skills/design-variations/SKILL.md +3 -0
  69. package/dist/agent-src/skills/developer-like-execution/SKILL.md +3 -0
  70. package/dist/agent-src/skills/estimate-ticket/SKILL.md +3 -0
  71. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +20 -3
  72. package/dist/agent-src/skills/fe-design/SKILL.md +74 -41
  73. package/dist/agent-src/skills/fe-design/evals/triggers.json +65 -53
  74. package/dist/agent-src/skills/fe-design/references/craft-floor.md +52 -0
  75. package/dist/agent-src/skills/fe-design/references/source-led-port.md +36 -0
  76. package/dist/agent-src/skills/file-editor/SKILL.md +5 -0
  77. package/dist/agent-src/skills/finishing-a-development-branch/SKILL.md +2 -2
  78. package/dist/agent-src/skills/git-workflow/SKILL.md +3 -0
  79. package/dist/agent-src/skills/html-deck/SKILL.md +3 -0
  80. package/dist/agent-src/skills/iconography/SKILL.md +3 -0
  81. package/dist/agent-src/skills/image-editing/SKILL.md +3 -0
  82. package/dist/agent-src/skills/image-generation/SKILL.md +3 -0
  83. package/dist/agent-src/skills/image-provider-routing/SKILL.md +3 -0
  84. package/dist/agent-src/skills/incident-commander/SKILL.md +10 -0
  85. package/dist/agent-src/skills/js-library-packaging/SKILL.md +173 -0
  86. package/dist/agent-src/skills/js-library-packaging/evals/triggers.json +17 -0
  87. package/dist/agent-src/skills/js-library-packaging/scripts/check_package_surface.ts +270 -0
  88. package/dist/agent-src/skills/laravel-migration/SKILL.md +3 -0
  89. package/dist/agent-src/skills/learning-to-rule-or-skill/SKILL.md +3 -0
  90. package/dist/agent-src/skills/lint-skills/SKILL.md +3 -0
  91. package/dist/agent-src/skills/llm-provider-knowledge/SKILL.md +3 -0
  92. package/dist/agent-src/skills/logging-monitoring/SKILL.md +234 -51
  93. package/dist/agent-src/skills/logo-generation/SKILL.md +3 -0
  94. package/dist/agent-src/skills/md-language-check/SKILL.md +3 -0
  95. package/dist/agent-src/skills/monorepo-workspace/SKILL.md +149 -0
  96. package/dist/agent-src/skills/monorepo-workspace/evals/triggers.json +17 -0
  97. package/dist/agent-src/skills/motion-choreographer/SKILL.md +6 -0
  98. package/dist/agent-src/skills/multi-tenancy/SKILL.md +4 -0
  99. package/dist/agent-src/skills/operational-readiness/SKILL.md +184 -0
  100. package/dist/agent-src/skills/operational-readiness/evals/triggers.json +17 -0
  101. package/dist/agent-src/skills/override-management/SKILL.md +3 -0
  102. package/dist/agent-src/skills/persona-improvement/SKILL.md +3 -0
  103. package/dist/agent-src/skills/pest-testing/SKILL.md +3 -0
  104. package/dist/agent-src/skills/playbook-authoring/SKILL.md +162 -0
  105. package/dist/agent-src/skills/playwright-testing/SKILL.md +3 -0
  106. package/dist/agent-src/skills/privacy-review/SKILL.md +3 -0
  107. package/dist/agent-src/skills/prompt-engineering-image/SKILL.md +3 -0
  108. package/dist/agent-src/skills/quality-tools/SKILL.md +5 -0
  109. package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +52 -21
  110. package/dist/agent-src/skills/readme-reviewer/SKILL.md +3 -0
  111. package/dist/agent-src/skills/readme-writing/SKILL.md +3 -0
  112. package/dist/agent-src/skills/readme-writing-package/SKILL.md +3 -0
  113. package/dist/agent-src/skills/receiving-code-review/SKILL.md +2 -2
  114. package/dist/agent-src/skills/refine-prompt/SKILL.md +3 -0
  115. package/dist/agent-src/skills/refine-ticket/SKILL.md +3 -0
  116. package/dist/agent-src/skills/requesting-code-review/SKILL.md +2 -2
  117. package/dist/agent-src/skills/review-routing/SKILL.md +2 -2
  118. package/dist/agent-src/skills/roadmap-writing/SKILL.md +23 -41
  119. package/dist/agent-src/skills/roadmap-writing/references/follow-up-roadmap-shape.md +47 -0
  120. package/dist/agent-src/skills/rtk-output-filtering/SKILL.md +22 -6
  121. package/dist/agent-src/skills/runway-cognition/SKILL.md +3 -0
  122. package/dist/agent-src/skills/scene-expander/scene-blueprint.schema.yaml +26 -0
  123. package/dist/agent-src/skills/secrets-management/SKILL.md +4 -0
  124. package/dist/agent-src/skills/server-hardening/SKILL.md +159 -0
  125. package/dist/agent-src/skills/server-hardening/evals/triggers.json +17 -0
  126. package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +3 -0
  127. package/dist/agent-src/skills/skill-management/SKILL.md +3 -0
  128. package/dist/agent-src/skills/skill-reviewer/SKILL.md +3 -0
  129. package/dist/agent-src/skills/skill-writing/SKILL.md +6 -0
  130. package/dist/agent-src/skills/spreadsheet-authoring/SKILL.md +3 -0
  131. package/dist/agent-src/skills/storybook-workshop/SKILL.md +194 -0
  132. package/dist/agent-src/skills/storybook-workshop/evals/triggers.json +17 -0
  133. package/dist/agent-src/skills/storybook-workshop/scripts/story_contrast_floor.ts +134 -0
  134. package/dist/agent-src/skills/subagent-orchestration/SKILL.md +1 -1
  135. package/dist/agent-src/skills/subagent-orchestration/prompts/README.md +25 -0
  136. package/dist/agent-src/skills/supply-chain-intake/SKILL.md +12 -0
  137. package/dist/agent-src/skills/systematic-debugging/SKILL.md +1 -1
  138. package/dist/agent-src/skills/terraform/SKILL.md +3 -0
  139. package/dist/agent-src/skills/test-driven-development/SKILL.md +1 -1
  140. package/dist/agent-src/skills/threat-modeling/SKILL.md +0 -3
  141. package/dist/agent-src/skills/token-optimizer/SKILL.md +3 -0
  142. package/dist/agent-src/skills/typography-system/SKILL.md +3 -0
  143. package/dist/agent-src/skills/ui-component-architect/SKILL.md +9 -1
  144. package/dist/agent-src/skills/upstream-contribute/SKILL.md +3 -0
  145. package/dist/agent-src/skills/validate-feature-fit/SKILL.md +3 -0
  146. package/dist/agent-src/skills/verify-completion-evidence/SKILL.md +2 -2
  147. package/dist/agent-src/skills/wireframe/SKILL.md +3 -0
  148. package/dist/agent-src/skills/wireframe/references/story-beat-ledger.schema.json +115 -0
  149. package/dist/agent-src/skills/workspace-link/SKILL.md +131 -0
  150. package/dist/agent-src/skills/workspace-link/evals/triggers.json +17 -0
  151. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  152. package/dist/agent-src/templates/playbook.md +75 -0
  153. package/dist/agent-src/templates/roadmaps.md +37 -0
  154. package/dist/agent-src/templates/scripts/check_playbook_invokes.ts +231 -0
  155. package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +24 -0
  156. package/dist/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +2 -0
  157. package/dist/agent-src/templates/scripts/work_engine/directives/ui/review.ts +216 -0
  158. package/dist/agent-src/templates/scripts/work_engine/directives/ui/scaffold.ts +159 -0
  159. package/dist/agent-src/templates/scripts/work_engine/directives/ui/stack_bundles.ts +73 -4
  160. package/dist/agent-src/templates/scripts/work_engine/stack/detect.ts +325 -40
  161. package/dist/cli/commands/uiAudit.js +221 -0
  162. package/dist/cli/commands/uiAudit.js.map +1 -0
  163. package/dist/cli/commands/uiRender.js +206 -0
  164. package/dist/cli/commands/uiRender.js.map +1 -0
  165. package/dist/cli/main.js +22 -1
  166. package/dist/cli/main.js.map +1 -1
  167. package/dist/cli/mcp/content.js +64 -1
  168. package/dist/cli/mcp/content.js.map +1 -1
  169. package/dist/cli/mcp/dispatch.js +175 -10
  170. package/dist/cli/mcp/dispatch.js.map +1 -1
  171. package/dist/cli/registry.js +3 -0
  172. package/dist/cli/registry.js.map +1 -1
  173. package/dist/cli-delegate/{chunk-H4VIVD4C.js → chunk-236PNQZK.js} +413 -391
  174. package/dist/cli-delegate/{chunk-G23AT6GD.js → chunk-DMSZHXZS.js} +57 -1
  175. package/dist/cli-delegate/{chunk-77GR3VD4.js → chunk-FF7WAFMR.js} +58 -3
  176. package/dist/cli-delegate/{chunk-PLSG6UL5.js → chunk-K4FFODTS.js} +341 -204
  177. package/dist/cli-delegate/{chunk-YM4GZDJG.js → chunk-L43NCYPB.js} +5 -0
  178. package/dist/cli-delegate/{chunk-B2ERU2VA.js → chunk-WOKWX5PL.js} +1 -1
  179. package/dist/cli-delegate/cmd_brand_status.js +8 -6
  180. package/dist/cli-delegate/cmd_conformance.js +3 -3
  181. package/dist/cli-delegate/cmd_doctor.js +3 -3
  182. package/dist/cli-delegate/cmd_export.js +4 -4
  183. package/dist/cli-delegate/cmd_handoff.js +1 -1
  184. package/dist/cli-delegate/cmd_preflight.js +2 -2
  185. package/dist/cli-delegate/cmd_prune.js +4 -4
  186. package/dist/cli-delegate/cmd_session_recycle.js +70 -9
  187. package/dist/cli-delegate/cmd_settings_migrate.js +4 -4
  188. package/dist/cli-delegate/cmd_settings_set.js +1 -1
  189. package/dist/cli-delegate/cmd_sync.js +4 -4
  190. package/dist/cli-delegate/cmd_uninstall.js +4 -4
  191. package/dist/cli-delegate/cmd_validate.js +4 -4
  192. package/dist/discovery/deprecation-report.md +1 -1
  193. package/dist/discovery/discovery-manifest.json +359 -124
  194. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  195. package/dist/discovery/discovery-manifest.summary.md +4 -4
  196. package/dist/discovery/dormancy-report.md +1 -1
  197. package/dist/discovery/orphan-report.md +1 -1
  198. package/dist/discovery/packs.json +18 -8
  199. package/dist/discovery/trust-report.md +3 -3
  200. package/dist/discovery/workspaces.json +16 -6
  201. package/dist/hooks/dispatch.js +2337 -1436
  202. package/dist/install/install.mjs +795 -708
  203. package/dist/mcp/registry-manifest.json +3 -3
  204. package/dist/mcp/server.json +2 -2
  205. package/dist/mcp/server.mjs +1685 -1250
  206. package/dist/router.json +1 -1
  207. package/dist/scripts/_lib/lean_projection_mode.js +40 -0
  208. package/dist/scripts/_lib/lean_projection_mode.js.map +1 -0
  209. package/dist/scripts/_lib/scoped_projection.js +84 -0
  210. package/dist/scripts/_lib/scoped_projection.js.map +1 -1
  211. package/dist/scripts/_lib/ui_surface.js +89 -0
  212. package/dist/scripts/_lib/ui_surface.js.map +1 -0
  213. package/dist/scripts/condense.js +6 -10
  214. package/dist/scripts/condense.js.map +1 -1
  215. package/dist/scripts/project_thin_rules.js +40 -2
  216. package/dist/scripts/project_thin_rules.js.map +1 -1
  217. package/dist/server/schemas/settings.js +3 -0
  218. package/dist/server/schemas/settings.js.map +1 -1
  219. package/dist/shared/skillRanking.js +159 -0
  220. package/dist/shared/skillRanking.js.map +1 -0
  221. package/docs/contracts/provider-lifecycle.md +47 -18
  222. package/docs/contracts/settings-classes.md +14 -4
  223. package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +49 -0
  224. package/docs/guidelines/agent-infra/evaluator-independence-mechanics.md +92 -0
  225. package/docs/guidelines/agent-infra/minimal-safe-diff-mechanics.md +45 -1
  226. package/docs/guidelines/agent-infra/roadmap-deferred-resolution-provenance.md +54 -0
  227. package/docs/guidelines/design-antipatterns.md +4 -2
  228. package/docs/guidelines/design-asset-discipline.md +38 -0
  229. package/docs/guidelines/design-fidelity-mechanics.md +45 -29
  230. package/docs/guidelines/design-handover-extraction.md +35 -5
  231. package/docs/guidelines/design-modes.md +41 -1
  232. package/docs/guidelines/monorepo-antipatterns.md +141 -0
  233. package/llms.txt +50 -39
  234. package/package.json +1 -1
  235. package/src/agent-src/templates/scripts/check_playbook_invokes.ts +231 -0
  236. package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +24 -0
  237. package/src/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +2 -0
  238. package/src/agent-src/templates/scripts/work_engine/directives/ui/review.ts +216 -0
  239. package/src/agent-src/templates/scripts/work_engine/directives/ui/scaffold.ts +159 -0
  240. package/src/agent-src/templates/scripts/work_engine/directives/ui/stack_bundles.ts +73 -4
  241. package/src/agent-src/templates/scripts/work_engine/stack/detect.ts +325 -40
  242. package/src/config/agent-settings.template.yml +28 -0
  243. package/src/config/assurance-capability-registry.json +223 -0
  244. package/src/config/assurance-threshold-budget.json +65 -0
  245. package/src/config/ci-local-parity.yml +14 -0
  246. package/src/config/discovery/unassigned-artefacts.yml +2 -0
  247. package/src/config/dispatch-economy-metrics.json +4 -2
  248. package/src/config/evaluator-budgets.json +14 -14
  249. package/src/config/gate-coverage.yml +207 -8
  250. package/src/config/gate-violation-baselines.json +76 -72
  251. package/src/config/hook-latency-budget.json +1 -0
  252. package/src/config/hook-token-budget.json +137 -125
  253. package/src/config/pack-size-budget.json +4 -2
  254. package/src/config/quorum-attendance-budget.json +12 -4
  255. package/src/config/rule-activation-census.json +7 -3
  256. package/src/config/rule-enforcement-baseline.json +0 -1
  257. package/src/config/rule-stub-ceilings.json +112 -91
  258. package/src/scripts/_cli/cmd_doctor.ts +15 -16
  259. package/src/scripts/_cli/doctor_install_mode.ts +49 -0
  260. package/src/scripts/_cli/doctor_overrides.ts +154 -0
  261. package/src/scripts/_dispatch.bash +17 -0
  262. package/src/scripts/_lib/as_of.ts +412 -0
  263. package/src/scripts/_lib/exec_evidence.ts +7 -0
  264. package/src/scripts/_lib/hook_settings.ts +33 -0
  265. package/src/scripts/_lib/host_listing_model.ts +192 -0
  266. package/src/scripts/_lib/lean_projection_mode.ts +44 -0
  267. package/src/scripts/_lib/mcp_bridge.ts +199 -0
  268. package/src/scripts/_lib/review_independence.ts +62 -10
  269. package/src/scripts/_lib/rule_injection.ts +239 -0
  270. package/src/scripts/_lib/run_checkpoint.ts +54 -1
  271. package/src/scripts/_lib/scoped_projection.ts +96 -0
  272. package/src/scripts/_lib/session_register.ts +44 -2
  273. package/src/scripts/_lib/skill_catalogue.ts +38 -2
  274. package/src/scripts/_lib/transcript_reads.ts +207 -0
  275. package/src/scripts/_lib/ui_authority.test.ts +251 -0
  276. package/src/scripts/_lib/ui_authority.ts +343 -0
  277. package/src/scripts/ai-video/adapters/fal.sh +8 -3
  278. package/src/scripts/ai-video/adapters/gemini-veo.sh +10 -0
  279. package/src/scripts/ai-video/adapters/higgsfield.sh +10 -2
  280. package/src/scripts/ai-video/adapters/kling.sh +10 -0
  281. package/src/scripts/ai-video/adapters/sora.sh +10 -0
  282. package/src/scripts/ai-video/lib/calibrate-cost.sh +145 -0
  283. package/src/scripts/ai-video/lib/model-capabilities/README.md +53 -7
  284. package/src/scripts/ai-video/lib/model-capabilities/comfyui.json +15 -3
  285. package/src/scripts/ai-video/lib/model-capabilities/fal.json +36 -6
  286. package/src/scripts/ai-video/lib/model-capabilities/gemini-veo.json +23 -0
  287. package/src/scripts/ai-video/lib/model-capabilities/higgsfield.json +23 -0
  288. package/src/scripts/ai-video/lib/model-capabilities/kling.json +23 -0
  289. package/src/scripts/ai-video/lib/model-capabilities/musetalk.json +8 -2
  290. package/src/scripts/ai-video/lib/model-capabilities/replicate.json +36 -6
  291. package/src/scripts/ai-video/lib/model-capabilities/sora.json +45 -0
  292. package/src/scripts/ai-video/lib/model-capabilities/syncso.json +8 -2
  293. package/src/scripts/ai-video/lib/parse-blueprint.sh +52 -5
  294. package/src/scripts/ai-video/lib/resume-scan.sh +92 -3
  295. package/src/scripts/ai-video/lib/seam-plan.sh +212 -0
  296. package/src/scripts/ai-video/smoke-trace.sh +450 -2
  297. package/src/scripts/ai-video/stitch.sh +191 -10
  298. package/src/scripts/ai-video/test-pipeline.sh +84 -6
  299. package/src/scripts/ai_council/cli_agency_bounds.ts +139 -0
  300. package/src/scripts/ai_council/cli_least_agency_canary.ts +347 -0
  301. package/src/scripts/ai_council/clients.ts +3 -2
  302. package/src/scripts/ai_council/consensus.ts +63 -6
  303. package/src/scripts/ai_council/events_log.ts +46 -1
  304. package/src/scripts/ai_council/orchestrator.ts +103 -108
  305. package/src/scripts/ai_council/orchestrator_results.ts +166 -0
  306. package/src/scripts/ai_council/prompts.ts +12 -5
  307. package/src/scripts/ai_council/quorum.ts +82 -1
  308. package/src/scripts/ai_council/quorum_wiring.ts +82 -5
  309. package/src/scripts/ai_council/stance_tally.ts +22 -0
  310. package/src/scripts/bench_hook_latency.ts +62 -0
  311. package/src/scripts/build_proof.ts +12 -1
  312. package/src/scripts/capture_skill_catalogue.ts +21 -0
  313. package/src/scripts/check_always_budget.ts +2 -1
  314. package/src/scripts/check_augmentignore.ts +2 -1
  315. package/src/scripts/check_beta_review_markers.ts +2 -1
  316. package/src/scripts/check_composite_arming.ts +364 -0
  317. package/src/scripts/check_corpus_staleness.ts +2 -1
  318. package/src/scripts/check_council_pin_staleness.ts +3 -1
  319. package/src/scripts/check_enforcement_coverage.ts +116 -3
  320. package/src/scripts/check_enforcement_denominator.ts +365 -0
  321. package/src/scripts/check_gate_coverage.ts +2 -1
  322. package/src/scripts/check_hook_bundle_freshness.ts +13 -1
  323. package/src/scripts/check_knowledge_cards.ts +2 -1
  324. package/src/scripts/check_knowledge_pages.ts +3 -2
  325. package/src/scripts/check_memory.ts +2 -1
  326. package/src/scripts/check_no_automerge_key.ts +287 -0
  327. package/src/scripts/check_pack_conformance_fixture.ts +565 -0
  328. package/src/scripts/check_proposal.ts +2 -1
  329. package/src/scripts/check_reach_staleness.ts +2 -1
  330. package/src/scripts/check_release_adjacent_health.ts +2 -1
  331. package/src/scripts/check_release_pr_shape.ts +5 -0
  332. package/src/scripts/check_review_schema.ts +34 -1
  333. package/src/scripts/check_roadmap_trackable.ts +48 -3
  334. package/src/scripts/check_source_size_budget.ts +2 -1
  335. package/src/scripts/check_standing_payload_delta.ts +505 -0
  336. package/src/scripts/check_trigger_evals.ts +2 -1
  337. package/src/scripts/classify_change_risk.ts +281 -0
  338. package/src/scripts/compute_skill_tiers.ts +186 -0
  339. package/src/scripts/condense.ts +8 -13
  340. package/src/scripts/council_attendance_metrics.ts +183 -0
  341. package/src/scripts/council_cli.ts +10 -8
  342. package/src/scripts/council_parse_rate.ts +116 -0
  343. package/src/scripts/derive_playbooks.ts +406 -0
  344. package/src/scripts/design_slop_rules.test.ts +7 -0
  345. package/src/scripts/design_slop_rules.ts +56 -2
  346. package/src/scripts/dispatch_r2_reviewer.ts +16 -0
  347. package/src/scripts/frontend_corpus_hash.ts +116 -0
  348. package/src/scripts/grade_target_readiness.ts +478 -0
  349. package/src/scripts/hook_manifest.json +1 -1
  350. package/src/scripts/hook_manifest.yaml +97 -16
  351. package/src/scripts/hooks/concern_registry.ts +4 -0
  352. package/src/scripts/hooks/design_pass_hook.ts +356 -0
  353. package/src/scripts/hooks/rtk_wrap_hook.ts +30 -7
  354. package/src/scripts/hooks/rule_inject_hook.ts +318 -0
  355. package/src/scripts/hot_context_hook.ts +74 -7
  356. package/src/scripts/install.ts +40 -89
  357. package/src/scripts/lint_adapter_tier.ts +663 -0
  358. package/src/scripts/lint_archived_skills.ts +93 -0
  359. package/src/scripts/lint_budget_ownership.ts +2 -1
  360. package/src/scripts/lint_deterministic_time.ts +470 -0
  361. package/src/scripts/lint_framework_leakage.ts +5 -0
  362. package/src/scripts/lint_handoffs.ts +525 -1
  363. package/src/scripts/lint_judge_prompt_expectation.ts +155 -0
  364. package/src/scripts/lint_marketplace.ts +88 -0
  365. package/src/scripts/lint_media_policy_linkage.ts +140 -1
  366. package/src/scripts/lint_one_off_age.ts +6 -1
  367. package/src/scripts/lint_override_kernel_guard.ts +87 -5
  368. package/src/scripts/lint_roadmap_complexity.ts +56 -0
  369. package/src/scripts/lint_rule_enforcement_declaration.ts +24 -7
  370. package/src/scripts/lint_rule_norm_pin.ts +321 -0
  371. package/src/scripts/lint_spawn_payload.ts +42 -5
  372. package/src/scripts/lint_symptom_intake.ts +2 -1
  373. package/src/scripts/mcp_parity_smoke.ts +30 -4
  374. package/src/scripts/mcp_render.ts +66 -1
  375. package/src/scripts/mcp_tool_fingerprint.ts +241 -0
  376. package/src/scripts/measure_risk_class_drift.ts +140 -0
  377. package/src/scripts/measure_skill_ranker_baseline.ts +212 -0
  378. package/src/scripts/media/lib/adapter-common.sh +211 -1
  379. package/src/scripts/media/lib/adapter-contract.md +74 -6
  380. package/src/scripts/model_rule_injection.ts +907 -0
  381. package/src/scripts/project_thin_rules.ts +45 -2
  382. package/src/scripts/release.ts +66 -860
  383. package/src/scripts/release_drill.ts +59 -3
  384. package/src/scripts/release_env.ts +298 -0
  385. package/src/scripts/release_publication.ts +720 -0
  386. package/src/scripts/roadmap_context.ts +778 -0
  387. package/src/scripts/schemas/fidelity-measurement-sheet.schema.json +169 -0
  388. package/src/scripts/schemas/rule.schema.json +24 -2
  389. package/src/scripts/schemas/skill.schema.json +39 -0
  390. package/src/scripts/schemas/ui-authority.schema.json +114 -0
  391. package/src/scripts/session_register_hook.ts +29 -3
  392. package/src/scripts/sessions_cli.ts +67 -3
  393. package/src/scripts/skill_tools/score_skill_relevance.ts +36 -53
  394. package/src/scripts/token_sink_report.ts +239 -0
  395. package/src/scripts/trigger_coverage.ts +122 -3
  396. package/src/scripts/update_counts.ts +7 -3
  397. package/src/scripts/validate_frontmatter.ts +66 -0
  398. package/src/server/schemas/settings.ts +5 -0
  399. package/src/shared/skillRanking.ts +183 -0
@@ -0,0 +1,115 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "story-beat-ledger.schema.json",
4
+ "title": "Story-beat ledger and style bible",
5
+ "description": "The one cleanly unmet gap Phase 9.1 of road-to-frontend-fidelity-calibration verified: `grep -rilE 'beat ledger|story ledger|style bible' src/` returned zero paths on 2026-08-22. Hosted in `wireframe` because that skill already owns the low-fidelity artefact — a beat ledger IS a low-fidelity artefact, one axis further along than a static skeleton. No skill was created to hold a schema. Two halves in one file, deliberately: the ledger is what happens in order, the style bible is what it looks like throughout, and splitting them into two files would let a beat reference a style that no longer exists.",
6
+ "type": "object",
7
+ "required": [
8
+ "schema_version",
9
+ "beats"
10
+ ],
11
+ "additionalProperties": true,
12
+ "properties": {
13
+ "schema_version": {
14
+ "enum": [
15
+ 1
16
+ ],
17
+ "description": "Pinned. One-member `enum` rather than `const`: this repo's Draft-07 subset validator enforces `enum` and silently ignores `const`."
18
+ },
19
+ "surface": {
20
+ "type": "string",
21
+ "description": "The page or route the ledger describes."
22
+ },
23
+ "style_bible": {
24
+ "type": "object",
25
+ "description": "What holds STILL across every beat. A property that changes per beat belongs on the beat, not here — that split is the point of having a bible at all.",
26
+ "additionalProperties": true,
27
+ "properties": {
28
+ "palette_ref": {
29
+ "type": "string",
30
+ "description": "A token reference, never a literal. `brand-source-of-truth` governs: the consumer's registered tokens win over anything a bible proposes."
31
+ },
32
+ "type_ref": {
33
+ "type": "string",
34
+ "description": "Token reference for the type system, per `typography-system`."
35
+ },
36
+ "motion_band": {
37
+ "type": "string",
38
+ "description": "The motion band this surface sits in. `fe-design` § Motion is the timing source of truth; this names a band, it does not define one."
39
+ },
40
+ "reduced_motion_presentation": {
41
+ "type": "string",
42
+ "description": "What the surface presents INSTEAD of motion when `prefers-reduced-motion` is set. Required by convention on any bible whose beats carry `motion`: `animation: none` is a suppression, not a presentation. This field is the schema half of step 9.3."
43
+ },
44
+ "art_direction_note": {
45
+ "type": "string",
46
+ "description": "The brief-level direction a `design-director` read would judge against. Free text."
47
+ }
48
+ }
49
+ },
50
+ "beats": {
51
+ "type": "array",
52
+ "minItems": 1,
53
+ "description": "Ordered. A scroll-driven surface is a sequence, and the order is the content.",
54
+ "items": {
55
+ "type": "object",
56
+ "required": [
57
+ "id",
58
+ "intent"
59
+ ],
60
+ "additionalProperties": true,
61
+ "properties": {
62
+ "id": {
63
+ "type": "string",
64
+ "description": "Stable beat id. The scroll evidence artefact in `design-review/references/verification-automation.md` references these ids, which is what lets a review check a beat rather than a pixel row."
65
+ },
66
+ "intent": {
67
+ "type": "string",
68
+ "description": "What this beat is FOR, in one sentence. A beat with no intent is a section, and a wireframe does not need a ledger to list sections."
69
+ },
70
+ "enters_at": {
71
+ "type": [
72
+ "string",
73
+ "number",
74
+ "null"
75
+ ],
76
+ "description": "Where the beat begins — a scroll fraction, a viewport-height multiple, or null when the ledger is authored before any layout exists. `null` is the honest value at wireframe stage and must stay allowed."
77
+ },
78
+ "element_states": {
79
+ "type": "array",
80
+ "description": "What is asserted to be true at this beat. The unit a review can check.",
81
+ "items": {
82
+ "type": "object",
83
+ "required": [
84
+ "selector",
85
+ "state"
86
+ ],
87
+ "additionalProperties": true,
88
+ "properties": {
89
+ "selector": {
90
+ "type": "string",
91
+ "description": "A CSS selector, or a wireframe region name before markup exists."
92
+ },
93
+ "state": {
94
+ "type": "string",
95
+ "description": "The asserted state — `visible`, `pinned`, `faded`, `offscreen`, and so on. A vocabulary the reviewer and the ledger share, not a free-form description."
96
+ }
97
+ }
98
+ }
99
+ },
100
+ "motion": {
101
+ "type": "string",
102
+ "description": "The motion this beat uses, if any. A beat carrying this obliges `style_bible.reduced_motion_presentation` to say what replaces it."
103
+ },
104
+ "maturity": {
105
+ "enum": [
106
+ "wireframe",
107
+ "comp"
108
+ ],
109
+ "description": "Which axis of `design-fidelity` § Two axes this beat sits on. A `wireframe` beat carries a STRUCTURE mandate: its greys and its exact offsets are non-decisions and must not be reproduced 1:1. Present so a ledger cannot be handed over as a pixel spec by omission."
110
+ }
111
+ }
112
+ }
113
+ }
114
+ }
115
+ }
@@ -0,0 +1,131 @@
1
+ ---
2
+ model_tier: medium
3
+ name: workspace-link
4
+ description: "Use when a cross-workspace import will not resolve — cannot find module @org/*, TS2307 — to link the packages properly with the workspace: protocol instead of patching tsconfig paths."
5
+ domain: engineering
6
+ workspaces:
7
+ - engineering
8
+ packs:
9
+ - engineering-base
10
+ ---
11
+
12
+ # Linking workspace packages
13
+
14
+ One workspace imports another and the import does not resolve. The fix is a
15
+ **dependency declaration**, not a resolver override.
16
+
17
+ > **Own analysis.** The forms and failure modes below are derived from the
18
+ > public behaviour of the package managers named, not adopted from a third-party
19
+ > artefact, so no provenance ledger entry backs them. Verify the protocol
20
+ > support against the manager version the repository actually pins — see
21
+ > § Check the manager, not the table.
22
+
23
+ ## When to use
24
+
25
+ - `Cannot find module '@org/ui'` or `Cannot find module '@org/ui' or its
26
+ corresponding type declarations`.
27
+ - TypeScript `TS2307`, or a bundler resolving a workspace import to `undefined`.
28
+ - A workspace import that works in the editor and fails in the build (or the
29
+ reverse) — the classic signature of a `paths` patch standing in for a
30
+ dependency.
31
+
32
+ ## Procedure
33
+
34
+ ### 1. Declare the dependency in the importing workspace
35
+
36
+ The importing workspace's `package.json` must name the imported workspace in
37
+ `dependencies` (or `devDependencies` when the import is test-only):
38
+
39
+ ```json
40
+ {
41
+ "name": "@org/web",
42
+ "dependencies": { "@org/ui": "workspace:*" }
43
+ }
44
+ ```
45
+
46
+ The name on the left is the imported package's own `name` field — not its
47
+ directory. Then re-run the install so the manager creates the link.
48
+
49
+ ### 2. Pick the form
50
+
51
+ Four forms, and the difference only shows up at publish time:
52
+
53
+ | Form | Resolves locally to | On publish, rewritten to |
54
+ |---|---|---|
55
+ | `workspace:*` | the local workspace, any version | the exact version at publish |
56
+ | `workspace:^` | the local workspace | `^<version>` |
57
+ | `workspace:~` | the local workspace | `~<version>` |
58
+ | `workspace:<range>` | the local workspace if its version satisfies `<range>`, else fails the install | `<range>` |
59
+
60
+ For a private monorepo that never publishes, `workspace:*` is the right default
61
+ — it cannot drift out of sync with the local version. For packages that *are*
62
+ published, `workspace:^` is what keeps the released range honest.
63
+
64
+ The explicit-range form is the only one that can **fail** the install, and that
65
+ is a feature: it is how a workspace states which version of a sibling it needs.
66
+
67
+ ### 3. Check the manager, not the table
68
+
69
+ Protocol support is not uniform. pnpm and Yarn (berry) implement all four forms;
70
+ Bun implements the protocol; npm's support arrived later than the others.
71
+ Confirm against the version in `packageManager` / the lockfile rather than
72
+ assuming — [`monorepo-workspace`](../monorepo-workspace/SKILL.md) step 1 reports
73
+ which manager this repository actually uses.
74
+
75
+ Where the protocol is unsupported, the correct fallback is still a dependency
76
+ declaration — the sibling's version range — never a resolver override.
77
+
78
+ ### 4. Verify it resolves for real
79
+
80
+ Re-run the failing command, not the editor. A resolved editor and a failing
81
+ build is the exact state a `paths` patch produces, so the build is the probe.
82
+
83
+ ## Output format
84
+
85
+ A workspace-link answer MUST contain, in order:
86
+
87
+ 1. **The unresolved import, named** — the importing workspace path, the imported
88
+ package `name` (not its directory), and the exact error text.
89
+ 2. **The declaration to add** — the `package.json` path, the section
90
+ (`dependencies` or `devDependencies`), and the `workspace:` form chosen, with
91
+ one sentence on why that form (private-and-unpublished → `workspace:*`;
92
+ published → `workspace:^`).
93
+ 3. **The install command for this repository's manager**, read from
94
+ `packageManager` / the lockfile rather than assumed.
95
+ 4. **The verification** — the failing build or test command re-run, not the
96
+ editor, plus its result. A resolved editor and a failing build is the state
97
+ a `paths` patch produces, so the build is the probe.
98
+
99
+ ## Gotcha
100
+
101
+ - Adding the dependency without re-running the install changes nothing: the
102
+ manager creates the symlink at install time.
103
+ - A `workspace:` dependency on a package that is not actually in the workspace
104
+ globs fails with a confusing "not found" — check the globs
105
+ ([`monorepo-workspace`](../monorepo-workspace/SKILL.md) step 2) before the
106
+ spelling of the name.
107
+ - The imported package still needs a valid entry point (`main` / `exports` /
108
+ `types`). A correct link into a package that exports nothing reads as the same
109
+ `TS2307`.
110
+ - Circular workspace dependencies install fine and break the task graph later.
111
+
112
+ ## Do NOT
113
+
114
+ - **Do NOT patch `tsconfig.json` `paths` to point at the sibling's source.** It
115
+ silences the type error in the editor while the runtime and the bundler still
116
+ have no dependency to resolve, and it hides the edge from the task runner, so
117
+ the affected-set calculation and build ordering both go wrong. A `paths` entry
118
+ is a compiler hint, not a dependency.
119
+ - **Do NOT hand-edit `package.json` link fields or the lockfile** to point at a
120
+ relative path (`file:../ui`, a hand-written entry under `node_modules`). It
121
+ works once, on one machine, and is undone by the next install.
122
+ - Do not add the dependency to the *root* `package.json` to make the error go
123
+ away — the importing workspace is what must declare it.
124
+ - Do not install the sibling from the registry to satisfy the import. That
125
+ silently pins a published copy while the local source keeps changing.
126
+
127
+ ## See also
128
+
129
+ - [`monorepo-workspace`](../monorepo-workspace/SKILL.md) — which manager, which workspaces, which graph.
130
+ - [`monorepo-antipatterns`](../../../docs/guidelines/monorepo-antipatterns.md) — the task-graph mistakes a `paths` patch hides.
131
+ - [`blast-radius-analyzer`](../blast-radius-analyzer/SKILL.md) — § Monorepo, once the edge exists.
@@ -0,0 +1,17 @@
1
+ {
2
+ "skill": "workspace-link",
3
+ "last_eval": "2026-08-23",
4
+ "description": "5 should-trigger + 5 should-not-trigger. Should-trigger covers an unresolved cross-workspace import and the workspace: protocol that fixes it, including the editor-resolves-build-fails signature of a tsconfig paths patch. Should-not-trigger covers near-miss neighbors: a third-party package that is genuinely missing, structural orientation (monorepo-workspace), impact analysis (blast-radius-analyzer), a TypeScript type error that is not a resolution failure, and a general dependency upgrade.",
5
+ "queries": [
6
+ {"q": "cannot find module @org/ui when I import it from apps/web", "trigger": true},
7
+ {"q": "TS2307 on a workspace import but the package is right there", "trigger": true},
8
+ {"q": "how do I link one workspace package to another", "trigger": true},
9
+ {"q": "should I use workspace:* or workspace:^ for this dependency", "trigger": true},
10
+ {"q": "the import resolves in my editor but the build cannot find it", "trigger": true},
11
+ {"q": "cannot find module lodash", "trigger": false, "note": "a third-party package that is not installed, not a workspace link"},
12
+ {"q": "which packages depend on @org/ui", "trigger": false, "note": "structural orientation → monorepo-workspace"},
13
+ {"q": "what breaks if I change this shared component", "trigger": false, "note": "impact set → blast-radius-analyzer § Monorepo"},
14
+ {"q": "type error: string is not assignable to number", "trigger": false, "note": "an ordinary type error, nothing to resolve"},
15
+ {"q": "upgrade react to 19 across the repo", "trigger": false, "note": "dependency upgrade → dependency-upgrade"}
16
+ ]
17
+ }
@@ -39,7 +39,7 @@ schema_version: 1
39
39
  # CI guard: a release bump of `package.json` must update this value
40
40
  # in lockstep — see scripts/check_template_pin_drift.ts (road-to-
41
41
  # portable-runtime-and-update-check P3.3).
42
- agent_config_version: "14.10.0"
42
+ agent_config_version: "14.11.0"
43
43
 
44
44
  # --- Project identity ---
45
45
  project:
@@ -0,0 +1,75 @@
1
+ # Playbook Template
2
+
3
+ Template for a **`Playbook` context** (ADR-244) — the sixth type, beside Module, Domain,
4
+ Service, Integration and Infrastructure. It lives in the playbook home and reuses the
5
+ `contexts.md` machinery; it is not a new artefact class.
6
+
7
+ The frontmatter below is the **playbook's own**, shown in a fence rather than written as
8
+ this file's frontmatter — a template whose example metadata is real metadata gets read as a
9
+ declaration about the template, which is what `check_discovery_frontmatter` correctly
10
+ objected to. `contexts.md` carries none for the same reason.
11
+
12
+ ```yaml
13
+ ---
14
+ task: "{one line — what this procedure accomplishes}"
15
+ scope: "{a workspace path, e.g. packages/ui — or the literal `repo`}"
16
+ grade: "{configured | observed}"
17
+ invokes:
18
+ - "{script / turbo task / turbo generator id}"
19
+ ---
20
+ ```
21
+
22
+ ## The body
23
+
24
+ # Playbook: {task}
25
+
26
+ > **This is THIS repository's answer, and it outranks a shipped skill.** A shipped skill
27
+ > is a generic answer to a generic question. A playbook encodes decisions this repository
28
+ > already made — file layout, barrel exports, test co-location, naming — that no generic
29
+ > skill can know. When both match, the playbook goes first.
30
+
31
+ ## The grade, and what it is claiming
32
+
33
+ | grade | means | obligation |
34
+ |---|---|---|
35
+ | `configured` | every step invokes something **present in the tree and seen** | **no step may lack an `invokes` entry** |
36
+ | `observed` | the procedure was inferred from a worked example | every step **cites the commit** it was seen in |
37
+
38
+ Do not write `configured` for a generator you did not observe. That is the Class-A rule of
39
+ `standards-from-config` applied to procedure, and the grade is the only field that tells a
40
+ reader whether to trust the steps or check them.
41
+
42
+ ## Steps
43
+
44
+ Numbered, in the `command-writing` shape. **Every step carries both lines** — a step
45
+ without them is a suggestion wearing a procedure's formatting.
46
+
47
+ ### 1. {what this step does}
48
+
49
+ - **Source of truth:** `{the script / generator / task it invokes}` — or, for an
50
+ `observed` playbook, `{commit sha}` where it was seen.
51
+ - **Verify:** `{a command whose output settles whether the step worked}`
52
+
53
+ {Any detail the invocation does not carry: a prompt answer to give, a flag that matters,
54
+ a thing that goes wrong if skipped.}
55
+
56
+ ### 2. {…}
57
+
58
+ - **Source of truth:** `{…}`
59
+ - **Verify:** `{…}`
60
+
61
+ ## What this playbook does NOT cover
62
+
63
+ {State the boundary. A playbook that silently stops short is worse than one that names
64
+ where it ends, because the reader cannot tell completion from omission.}
65
+
66
+ ## Staleness
67
+
68
+ Every `invokes` id is resolved by a deterministic check. When an id no longer exists the
69
+ check **fails naming the id**, and the grade **downgrades** — so a renamed generator
70
+ surfaces as a failure rather than as a playbook quietly instructing the wrong command.
71
+
72
+ First release resolves ids against `package.json#scripts`, `turbo.json` tasks and
73
+ `turbo gen` templates only. Nx generators and Plop are deliberately out of scope (ADR-244
74
+ § What the first release resolves): their discovery needs a consumer binary, and a gate
75
+ that needs the consumer's toolchain installed is a gate that does not run.
@@ -147,6 +147,43 @@ that was never a judgement call.
147
147
  resolves toward serial and a declaration is the cheap way to be right.
148
148
  Absent means no declared dependency, never “independent”: the overlap
149
149
  heuristic still runs.
150
+
151
+ **Companion field, same block — `relates:`.** The wider relation, of which
152
+ `depends` is one value:
153
+
154
+ ```yaml
155
+ relates:
156
+ - slug: road-to-other-thing
157
+ relation: extends # extends | supersedes | depends | disjoint
158
+ note: "adds the path axis its § 3 left as slug-only"
159
+ - slug: road-to-old-thing
160
+ relation: supersedes
161
+ note: "same mechanism, this one replaces it"
162
+ ```
163
+
164
+ One row per hit from `agent-config roadmap:context`, which is what the
165
+ authoring surfaces run before drafting. Four relations and no more —
166
+ `extends`, `supersedes`, `depends`, `disjoint`; an unknown value is rejected
167
+ by the roadmap lint, because an open vocabulary here degrades into free-text
168
+ notes nothing can read.
169
+
170
+ A `relation: depends` row **mirrors into `depends:`** so the set contract's
171
+ edge source stays the single one already defined above; `relates:` never
172
+ becomes a second dependency source.
173
+
174
+ An explicit `relates: []` is a complete answer and the common one, but only
175
+ when it carries the probe's `scanned:` line as its justification:
176
+
177
+ ```yaml
178
+ relates: [] # scanned: 716 roadmap file(s), 0 sibling hits
179
+ ```
180
+
181
+ Absent-versus-empty is the whole point. Absent means nobody looked; `[]` with
182
+ a `scanned:` line means somebody looked and found nothing. A `relates: []`
183
+ written by reflex, with a boilerplate note, carries no information and is
184
+ worse than none — the pre-save self-check in
185
+ [`roadmap-writing`](../../skills/roadmap-writing/SKILL.md) asks for exactly
186
+ this distinction.
150
187
  19. **Source-derived roadmaps carry a gap-table + provenance; internally
151
188
  originated roadmaps carry neither.** This rule fires **only** when a
152
189
  roadmap originates from an external input (a suggestion, a competitive
@@ -0,0 +1,231 @@
1
+ /**
2
+ * check_playbook_invokes — a `configured` playbook may not name a procedure the tree no
3
+ * longer has.
4
+ *
5
+ * Ships in the consumer `scripts/` template so it runs in the CONSUMER's CI, over the
6
+ * consumer's own playbooks and the consumer's own configuration. That placement is the
7
+ * whole design: staleness is a fact about their repository, and a gate in this package
8
+ * could only ever check this package.
9
+ *
10
+ * The grade is the contract (ADR-244). `configured` asserts every step invokes something
11
+ * present in the tree; when a generator is renamed, that assertion becomes false silently —
12
+ * the playbook still reads like a procedure and the command no longer exists. This check is
13
+ * what turns that into a failure instead of a surprise at the next `turbo gen`.
14
+ *
15
+ * Three resolvable kinds, and no more: a script name in the package manifest, a declared
16
+ * task in the task file, and a registered generator template. An Nx or Plop id is reported
17
+ * `unsupported` — NEVER as resolved and never as missing, because discovering those needs a
18
+ * binary this check deliberately does not run. Reporting a real id as missing would be the
19
+ * worse error: it would push a correct playbook to `observed`.
20
+ *
21
+ * Usage:
22
+ * check_playbook_invokes [--root <dir>] [--home <dir>] [--quiet]
23
+ *
24
+ * Exit 0 = every `configured` playbook resolves (or there are none).
25
+ * Exit 1 = at least one `configured` step names an id the tree does not have.
26
+ */
27
+
28
+ import * as fs from 'node:fs';
29
+ import * as path from 'node:path';
30
+
31
+ /** Playbooks are a context type (ADR-244), so the home is the contexts home. */
32
+ const DEFAULT_HOME = path.join('agents', 'settings', 'contexts');
33
+
34
+ export interface PlaybookHead {
35
+ readonly file: string;
36
+ readonly grade: string;
37
+ readonly invokes: readonly string[];
38
+ }
39
+
40
+ export type Verdict = 'resolved' | 'missing' | 'unsupported';
41
+
42
+ export interface Check {
43
+ readonly file: string;
44
+ readonly id: string;
45
+ readonly verdict: Verdict;
46
+ /** Where it resolved, for a `resolved` verdict. */
47
+ readonly where: string | null;
48
+ }
49
+
50
+ /** Ids this check cannot resolve without running a consumer binary. */
51
+ const UNSUPPORTED_PREFIXES = ['nx ', 'nx:', 'plop ', 'plop:'] as const;
52
+
53
+ const readJson = (p: string): Record<string, unknown> | null => {
54
+ try {
55
+ return JSON.parse(fs.readFileSync(p, 'utf8')) as Record<string, unknown>;
56
+ } catch {
57
+ return null;
58
+ }
59
+ };
60
+
61
+ const asRecord = (v: unknown): Record<string, unknown> =>
62
+ v !== null && typeof v === 'object' && !Array.isArray(v) ? (v as Record<string, unknown>) : {};
63
+
64
+ /**
65
+ * Minimal frontmatter read — `grade` and the `invokes` list only.
66
+ *
67
+ * Deliberately not a YAML dependency: this file ships into a consumer repository, where
68
+ * adding a parser dependency to run one gate is a cost the consumer did not ask for.
69
+ */
70
+ export const parseHead = (file: string, text: string): PlaybookHead | null => {
71
+ if (!text.startsWith('---')) return null;
72
+ const end = text.indexOf('\n---', 3);
73
+ if (end < 0) return null;
74
+ const head = text.slice(3, end);
75
+ const gradeMatch = /^grade:\s*["']?([A-Za-z]+)["']?\s*$/m.exec(head);
76
+ if (!gradeMatch) return null;
77
+
78
+ const invokes: string[] = [];
79
+ const lines = head.split('\n');
80
+ let inList = false;
81
+ for (const line of lines) {
82
+ if (/^invokes:\s*$/.test(line)) {
83
+ inList = true;
84
+ continue;
85
+ }
86
+ if (inList) {
87
+ const item = /^\s+-\s*["']?(.+?)["']?\s*$/.exec(line);
88
+ if (item?.[1] !== undefined) {
89
+ invokes.push(item[1]);
90
+ continue;
91
+ }
92
+ inList = false;
93
+ }
94
+ // An inline list is the other legal shape and a reader that only handled the block
95
+ // form would report a correct playbook as having no ids at all.
96
+ const inline = /^invokes:\s*\[(.*)\]\s*$/.exec(line);
97
+ if (inline?.[1] !== undefined) {
98
+ for (const part of inline[1].split(',')) {
99
+ const v = part.trim().replace(/^["']|["']$/g, '');
100
+ if (v.length > 0) invokes.push(v);
101
+ }
102
+ }
103
+ }
104
+ return { file, grade: gradeMatch[1] as string, invokes };
105
+ };
106
+
107
+ /** Generator templates registered in the tree, as `<runner> gen <name>` ids. */
108
+ export const registeredGenerators = (root: string): Map<string, string> => {
109
+ const out = new Map<string, string>();
110
+ const dir = path.join(root, 'turbo', 'generators');
111
+ if (!fs.existsSync(dir)) return out;
112
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
113
+ const full = path.join(dir, entry.name);
114
+ if (entry.isDirectory()) {
115
+ out.set(entry.name, path.relative(root, full));
116
+ continue;
117
+ }
118
+ const text = fs.readFileSync(full, 'utf8');
119
+ for (const m of text.matchAll(/\.(?:set|add)Generator\(\s*['"]([A-Za-z0-9_-]+)['"]/g)) {
120
+ out.set(m[1] as string, path.relative(root, full));
121
+ }
122
+ }
123
+ return out;
124
+ };
125
+
126
+ export const resolveId = (
127
+ root: string,
128
+ id: string,
129
+ gens: Map<string, string>,
130
+ ): { verdict: Verdict; where: string | null } => {
131
+ const lower = id.toLowerCase();
132
+ if (UNSUPPORTED_PREFIXES.some((p) => lower.startsWith(p))) {
133
+ return { verdict: 'unsupported', where: null };
134
+ }
135
+
136
+ const gen = /^\S+\s+gen\s+([A-Za-z0-9_-]+)/.exec(id);
137
+ if (gen) {
138
+ const name = gen[1] as string;
139
+ return gens.has(name)
140
+ ? { verdict: 'resolved', where: gens.get(name) ?? null }
141
+ : { verdict: 'missing', where: null };
142
+ }
143
+
144
+ const tasks = asRecord(readJson(path.join(root, 'turbo.json'))?.tasks);
145
+ if (Object.prototype.hasOwnProperty.call(tasks, id)) {
146
+ return { verdict: 'resolved', where: 'turbo.json#tasks' };
147
+ }
148
+ const scripts = asRecord(readJson(path.join(root, 'package.json'))?.scripts);
149
+ if (Object.prototype.hasOwnProperty.call(scripts, id)) {
150
+ return { verdict: 'resolved', where: 'package.json#scripts' };
151
+ }
152
+ return { verdict: 'missing', where: null };
153
+ };
154
+
155
+ export const checkAll = (root: string, home: string): Check[] => {
156
+ if (!fs.existsSync(home)) return [];
157
+ const gens = registeredGenerators(root);
158
+ const out: Check[] = [];
159
+ for (const name of fs.readdirSync(home).sort()) {
160
+ if (!name.endsWith('.md')) continue;
161
+ const file = path.join(home, name);
162
+ const head = parseHead(file, fs.readFileSync(file, 'utf8'));
163
+ // Only `configured` is a claim about the tree. An `observed` playbook already says
164
+ // its steps are unverified, so failing it here would punish the honest grade.
165
+ if (head === null || head.grade !== 'configured') continue;
166
+ for (const id of head.invokes) {
167
+ const { verdict, where } = resolveId(root, id, gens);
168
+ out.push({ file, id, verdict, where });
169
+ }
170
+ }
171
+ return out;
172
+ };
173
+
174
+ /**
175
+ * The remediation. BOTH options are printed verbatim on every failure, and neither is
176
+ * "delete the line": a playbook that loses its evidence line stops being checkable, which
177
+ * turns a caught drift into an uncatchable one.
178
+ */
179
+ export const REMEDIATION = [
180
+ 'Two ways to fix this, and only two:',
181
+ ' 1. Fix the `invokes` id — the procedure moved, so point the playbook at where it moved to.',
182
+ ' 2. Downgrade the step to `observed` and cite the commit it was last seen working in.',
183
+ 'Do NOT delete the evidence line. A playbook without it is not a weaker claim, it is an',
184
+ 'unverifiable one — and the next drift goes unnoticed.',
185
+ ].join('\n');
186
+
187
+ const main = (): number => {
188
+ const argv = process.argv.slice(2);
189
+ const arg = (flag: string): string | null => {
190
+ const i = argv.indexOf(flag);
191
+ return i >= 0 && i + 1 < argv.length ? String(argv[i + 1]) : null;
192
+ };
193
+ const quiet = argv.includes('--quiet');
194
+ const root = arg('--root') ?? '.';
195
+ const home = arg('--home') ?? path.join(root, DEFAULT_HOME);
196
+
197
+ const checks = checkAll(root, home);
198
+ const missing = checks.filter((c) => c.verdict === 'missing');
199
+ const unsupported = checks.filter((c) => c.verdict === 'unsupported');
200
+
201
+ if (!quiet) {
202
+ for (const u of unsupported) {
203
+ process.stdout.write(
204
+ `ℹ️ ${u.file}: \`${u.id}\` is unsupported by this check (its discovery needs a ` +
205
+ `consumer binary) — reported, not treated as missing\n`,
206
+ );
207
+ }
208
+ process.stdout.write(
209
+ `scanned: ${String(checks.length)} configured step(s) across ${String(new Set(checks.map((c) => c.file)).size)} playbook(s)\n`,
210
+ );
211
+ }
212
+
213
+ if (missing.length === 0) {
214
+ if (!quiet) {
215
+ process.stdout.write('✅ check_playbook_invokes: every configured step resolves in the tree.\n');
216
+ }
217
+ return 0;
218
+ }
219
+
220
+ for (const m of missing) {
221
+ process.stderr.write(
222
+ `❌ ${m.file}: step invoking \`${m.id}\` does not resolve — no such script, task, or generator in the tree\n`,
223
+ );
224
+ }
225
+ process.stderr.write(`\n${REMEDIATION}\n`);
226
+ return 1;
227
+ };
228
+
229
+ if (process.argv[1] !== undefined && process.argv[1].includes('check_playbook_invokes')) {
230
+ process.exit(main());
231
+ }
@@ -18,13 +18,30 @@ import {
18
18
  agent_directive,
19
19
  } from '../../delivery_state.js';
20
20
  import { has_design_system, placeholder_paths, provided_artifact } from './design.js';
21
+ import { _playbook_lines, _scaffold_playbooks } from './scaffold.js';
21
22
  import {
22
23
  is_ambiguous_stack,
23
24
  bundle_line,
25
+ scope_lines,
24
26
  unsupported_stack_questions,
25
27
  } from './stack_bundles.js';
26
28
 
27
29
  /** Map `state.stack.frontend` → agent-directive skill name. */
30
+ /**
31
+ * Task words that make a playbook relevant to the `apply` verb.
32
+ *
33
+ * Same shape as `scaffold`'s list and deliberately a SEPARATE constant: `apply` implements
34
+ * into an existing surface, so a repository may reasonably carry a playbook for one verb and
35
+ * not the other. One shared list would silently dispatch a scaffold-only procedure here.
36
+ */
37
+ export const APPLY_VERB_TERMS: ReadonlyArray<string> = [
38
+ 'component',
39
+ 'page',
40
+ 'route',
41
+ 'screen',
42
+ 'view',
43
+ ];
44
+
28
45
  export const STACK_DIRECTIVES: Record<string, string> = {
29
46
  'blade-livewire-flux': 'ui-apply-blade-livewire-flux',
30
47
  'blade-livewire': 'ui-apply-blade-livewire',
@@ -267,10 +284,17 @@ function _delegate_to_stack_skill(state: DeliveryState): StepResult {
267
284
  });
268
285
  }
269
286
  const provided = provided_artifact(state.ui_design as Record<string, Any> | null);
287
+ // The repository's own procedure goes ahead of the stack skill when it has one. Empty
288
+ // when it does not, which is what keeps a project with no playbook home byte-identical.
289
+ // Imported from `scaffold` rather than duplicated: two copies of a scope-match rule
290
+ // drift, and the drift would be invisible — both lanes would still emit *something*.
291
+ const playbook_lines = _playbook_lines(_scaffold_playbooks(state, APPLY_VERB_TERMS));
270
292
  const lines: string[] = [
271
293
  agent_directive(directive),
294
+ ...playbook_lines,
272
295
  `> Stack: \`${stack_label}\`. Implementing the locked design brief.`,
273
296
  bundle_line(state.stack, 'build', stack_label),
297
+ ...scope_lines(state.stack),
274
298
  '> Microcopy is locked — every button label, empty-state ' +
275
299
  'message, and validation message must come verbatim from ' +
276
300
  '`state.ui_design.microcopy`.',