@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
@@ -206,6 +206,56 @@ concerns:
206
206
  fail_closed: false
207
207
  severity: advisory
208
208
  needs_payload_bodies: [input]
209
+ # road-to-frontend-power E1.1 / E1.2 / E1.3 — the DELIVERY carrier the 0.0 %
210
+ # UI-write measurement never had. One script on two slots:
211
+ # design-pass (post_tool_use) — the file just written; findings as
212
+ # context, never a block.
213
+ # design-pass-stop (stop) — every UI file touched this session,
214
+ # deduped against what the post pass already surfaced.
215
+ # P0 objective floors block here (E1.3); P1-P3 never do.
216
+ #
217
+ # post_tool_use rather than pre_tool_use, for two MEASURED reasons recorded in
218
+ # internal/bench/frontend-power/BASELINE-2026-08-23.md:
219
+ # 1. Reach — pre_tool_use is declared by three hosts and honoured by one;
220
+ # post_tool_use is declared by six. The 0.0 % was a delivery failure
221
+ # before it was anything else.
222
+ # 2. _lib/ui_surface.ts is a PATH predicate (recall 20/23, all three misses
223
+ # being a UI request with no UI file yet), so a pre-write gate cannot fire
224
+ # on the FIRST write of a new surface — the write it most wants.
225
+ #
226
+ # Default-OFF (hooks.design_pass.enabled). fail_closed: false — Risk 1 of the
227
+ # parent roadmap is that one false block on clean UI turns the carrier OFF for
228
+ # good, which is the state the 0.0 % already measured.
229
+ design-pass:
230
+ script: src/scripts/hooks/design_pass_hook.ts
231
+ args: []
232
+ fail_closed: false
233
+ severity: advisory
234
+ needs_payload_bodies: [input]
235
+ # `advisory`, and the code MATCHES the declaration rather than the prose.
236
+ #
237
+ # E1.3 specifies "P0 blocks at stop". Declaring `advisory` while returning
238
+ # EXIT_BLOCK would have shipped an INERT block: the dispatcher enforces
239
+ # advisory as a ceiling (`_is_advisory` downgrades EXIT_BLOCK to EXIT_WARN)
240
+ # and `host_semantics.emitFor` maps stop+warn to exit 0 — the exact defect
241
+ # `run-continuation` records in concern_severity.test.ts's allowlist, where
242
+ # `advisory` made a turn-end refusal do nothing while every other assertion
243
+ # about it passed.
244
+ #
245
+ # `blocking` is the honest declaration for a refusal, and it is NOT taken
246
+ # here: that allowlist says in its own header that adding to it is a
247
+ # security-relevant decision, and this would be the THIRD turn-END refusal in
248
+ # the tree — blast radius every session rather than one command. A frontend
249
+ # PR is not where that gets decided unilaterally, and the roadmap already
250
+ # transfers the sibling decision (turning this carrier ON at all) to the
251
+ # owner. So the pass COMPUTES the P0 verdict and reports it as
252
+ # "would block at stop", and the refusal itself is transferred with E1.4.
253
+ # `stubs/road-to-frontend-power-default-flip.md` carries it as a named gate.
254
+ design-pass-stop:
255
+ script: src/scripts/hooks/design_pass_hook.ts
256
+ args: ['--slot', 'stop']
257
+ fail_closed: false
258
+ severity: advisory
209
259
  # road-to-frontend-skill-application Phase 4 — OPTIONAL PreToolUse UI-route
210
260
  # nudge. On a Write/Edit to a UI surface with no design consultation latched
211
261
  # this session, WARNS (exit 2) naming the route; a read or search touching a
@@ -625,6 +675,37 @@ concerns:
625
675
  fail_closed: false
626
676
  severity: advisory
627
677
  nudge_rank: 2
678
+ # road-to-trigger-delivered-rule-bodies Phase 1 — the DELIVERY twin of
679
+ # `skill-route` above: same two slots, opposite payload policy. `skill-route`
680
+ # ships pointers because a skill is invoked; this ships BODIES because a rule
681
+ # is something the agent must already be under, and the only datum on
682
+ # pointer-shaped rule delivery is the 36.2 %-against-48 % run at
683
+ # docs/CLAIMS.md:188-189.
684
+ #
685
+ # DEFAULT OFF, and off means ZERO bytes: the concern returns before reading
686
+ # `dist/router.json` unless `lean_projection.mode: delivery`. Under every
687
+ # shipped default it emits nothing, so its `hook-token-budget.json` row is
688
+ # registered against the derived per-prompt cap rather than a measured
689
+ # emission — there is no measured emission yet, and saying so is the point.
690
+ #
691
+ # DELIBERATELY NOT nudge-class: it carries no `nudge_rank`. A rule body is not
692
+ # a hint the model may ignore, so the one-ranked-nudge-per-slot exclusivity
693
+ # above must not suppress it against `delegation-nudge` / `skill-route`, and it
694
+ # must not suppress them either. It is still advisory and still droppable by
695
+ # the per-turn injection ceiling, which is the budget that should govern it.
696
+ #
697
+ # `pre_compact` re-arms the once-per-session-per-rule seen-set — the same
698
+ # pin-lost shape `language-mirror` uses on that slot. Bound on `claude` only:
699
+ # step 2.4's flip is Claude-only by construction (a thin projection without a
700
+ # body-delivering hook is the pointer arm that already scored 36.2 %), so
701
+ # binding a default-off concern on hosts whose flip can never happen would pay
702
+ # slot cost for nothing. fail_closed: false.
703
+ rule-inject:
704
+ script: src/scripts/hooks/rule_inject_hook.ts
705
+ args: []
706
+ fail_closed: false
707
+ severity: advisory
708
+ needs_payload_bodies: [input]
628
709
  # road-to-orchestrator-discipline-carriers Phase 5 (F4-lite) — end-review
629
710
  # nudge. Fires ONLY when the session mutated tracked+untracked, non-doc
630
711
  # files beyond MUTATION_LINE_THRESHOLD (50 lines; untracked files added
@@ -948,17 +1029,17 @@ platforms:
948
1029
  augment:
949
1030
  session_start: [chat-history, hot-context, handoff-context, session-canary, council-availability, telemetry-disclosure, first-run-gate, onboarding-gate, verify-before-complete, minimal-safe-diff, profile-staleness, wrapper-freshness, surface-probe, session-register]
950
1031
  session_end: [chat-history, memory-learn, session-register, roadmap-progress, telemetry-flush]
951
- stop: [chat-history, hot-context, verify-before-complete, self-repair, session-register, roadmap-progress]
1032
+ stop: [chat-history, hot-context, verify-before-complete, self-repair, session-register, roadmap-progress, design-pass-stop]
952
1033
  pre_tool_use: [block-no-verify, block-unauthorized-git, evidence-independence, block-kernel-rule-writes, block-config-weakening, rtk-wrap, design-slop, ui-route-nudge, code-graph-nudge, ship-diff-volume, reread-guard]
953
- post_tool_use: [chat-history, roadmap-progress, context-hygiene, verify-before-complete, minimal-safe-diff, injection-scan, pr-url-reminder, orchestration-record, telemetry-usage, tool-result-bytes, edit-shape]
1034
+ post_tool_use: [chat-history, roadmap-progress, context-hygiene, verify-before-complete, minimal-safe-diff, injection-scan, pr-url-reminder, orchestration-record, telemetry-usage, tool-result-bytes, edit-shape, design-pass]
954
1035
 
955
1036
  claude:
956
1037
  session_start: [chat-history, hot-context, handoff-context, session-canary, council-availability, telemetry-disclosure, first-run-gate, onboarding-gate, verify-before-complete, minimal-safe-diff, profile-staleness, wrapper-freshness, surface-probe, session-register]
957
1038
  session_end: [chat-history, memory-learn, session-register, roadmap-progress, telemetry-flush]
958
- stop: [chat-history, hot-context, verify-before-complete, team-review-gate, end-review-nudge, turn-end-gate, self-repair, session-register, session-eol, interruption-ledger, roadmap-progress, run-continuation]
959
- user_prompt_submit: [chat-history, verify-before-complete, minimal-safe-diff, language-mirror, delegation-nudge, skill-route, git-authorization, session-canary, self-repair, session-register]
960
- pre_tool_use: [block-no-verify, block-unauthorized-git, evidence-independence, block-kernel-rule-writes, block-config-weakening, rtk-wrap, design-slop, ui-route-nudge, code-graph-nudge, ship-diff-volume, reread-guard, spawn-guard-shadow, source-first-gate]
961
- post_tool_use: [chat-history, roadmap-progress, context-hygiene, verify-before-complete, minimal-safe-diff, injection-scan, pr-url-reminder, orchestration-record, telemetry-usage, tool-result-bytes, edit-shape, language-mirror]
1039
+ stop: [chat-history, hot-context, verify-before-complete, team-review-gate, end-review-nudge, turn-end-gate, self-repair, session-register, session-eol, interruption-ledger, roadmap-progress, design-pass-stop, run-continuation]
1040
+ user_prompt_submit: [chat-history, verify-before-complete, minimal-safe-diff, language-mirror, delegation-nudge, skill-route, git-authorization, session-canary, self-repair, session-register, rule-inject]
1041
+ pre_tool_use: [block-no-verify, block-unauthorized-git, evidence-independence, block-kernel-rule-writes, block-config-weakening, rtk-wrap, design-slop, ui-route-nudge, code-graph-nudge, ship-diff-volume, reread-guard, spawn-guard-shadow, source-first-gate, rule-inject]
1042
+ post_tool_use: [chat-history, roadmap-progress, context-hygiene, verify-before-complete, minimal-safe-diff, injection-scan, pr-url-reminder, orchestration-record, telemetry-usage, tool-result-bytes, edit-shape, language-mirror, design-pass]
962
1043
  # `language-mirror` — round-5 § 6.1. `pre_compact` sets a pin-lost marker;
963
1044
  # the `post_tool_use` entry above re-emits the pin exactly once while that
964
1045
  # marker is set, then clears it. One extra injection per compaction EVENT —
@@ -975,7 +1056,7 @@ platforms:
975
1056
  # already bound on `stop` and `session_start`; this adds the write at the
976
1057
  # moment the loss actually happens. Deterministic rebuild, emits nothing
977
1058
  # here — the 4,096-byte row it carries is for its session_start restore.
978
- pre_compact: [language-mirror, hot-context]
1059
+ pre_compact: [language-mirror, hot-context, rule-inject]
979
1060
  # road-to-subagent-lifecycle-integrity Phase 1 Step 1. `claude` is the only
980
1061
  # platform where both native events were measured present on the installed
981
1062
  # binary (2.1.229 — see the evidence page cited on the alias rows below).
@@ -1009,10 +1090,10 @@ platforms:
1009
1090
  # is later verified to forward it. Binding them here would be dead
1010
1091
  # weight: the concern still runs (git diff, transcript scan, classifier),
1011
1092
  # still costs the dispatch, and its entire output is thrown away.
1012
- stop: [chat-history, hot-context, verify-before-complete, self-repair, session-register, roadmap-progress]
1093
+ stop: [chat-history, hot-context, verify-before-complete, self-repair, session-register, roadmap-progress, design-pass-stop]
1013
1094
  user_prompt_submit: [chat-history, verify-before-complete, minimal-safe-diff, language-mirror, git-authorization, session-canary, self-repair, session-register]
1014
1095
  pre_tool_use: [block-no-verify, block-unauthorized-git, evidence-independence, block-kernel-rule-writes, block-config-weakening, rtk-wrap, design-slop, ui-route-nudge, code-graph-nudge, ship-diff-volume, reread-guard, spawn-guard-shadow, source-first-gate]
1015
- post_tool_use: [chat-history, roadmap-progress, context-hygiene, verify-before-complete, minimal-safe-diff, injection-scan, pr-url-reminder, orchestration-record, telemetry-usage, tool-result-bytes, edit-shape]
1096
+ post_tool_use: [chat-history, roadmap-progress, context-hygiene, verify-before-complete, minimal-safe-diff, injection-scan, pr-url-reminder, orchestration-record, telemetry-usage, tool-result-bytes, edit-shape, design-pass]
1016
1097
  # subagent-ledger IS bound here, unlike the two nudges above, and the
1017
1098
  # difference is the delivery channel rather than the platform: the nudges
1018
1099
  # depend on stdout reaching the model, which this trampoline discards by
@@ -1033,9 +1114,9 @@ platforms:
1033
1114
  cursor:
1034
1115
  session_start: [chat-history, hot-context, handoff-context, session-canary, council-availability, telemetry-disclosure, first-run-gate, onboarding-gate, verify-before-complete, minimal-safe-diff, profile-staleness, wrapper-freshness, surface-probe, session-register]
1035
1116
  session_end: [chat-history, memory-learn, session-register, roadmap-progress, telemetry-flush]
1036
- stop: [chat-history, hot-context, verify-before-complete, self-repair, session-register, roadmap-progress]
1117
+ stop: [chat-history, hot-context, verify-before-complete, self-repair, session-register, roadmap-progress, design-pass-stop]
1037
1118
  user_prompt_submit: [chat-history, verify-before-complete, minimal-safe-diff, language-mirror, git-authorization, session-canary, self-repair, session-register]
1038
- post_tool_use: [chat-history, roadmap-progress, context-hygiene, verify-before-complete, minimal-safe-diff, injection-scan, pr-url-reminder, orchestration-record, telemetry-usage, tool-result-bytes, edit-shape]
1119
+ post_tool_use: [chat-history, roadmap-progress, context-hygiene, verify-before-complete, minimal-safe-diff, injection-scan, pr-url-reminder, orchestration-record, telemetry-usage, tool-result-bytes, edit-shape, design-pass]
1039
1120
 
1040
1121
  # Phase 7.6 — Cline. Hooks live under `.clinerules/hooks/<HookName>`
1041
1122
  # (project, no file extension, must be executable per Cline docs) or
@@ -1048,9 +1129,9 @@ platforms:
1048
1129
  cline:
1049
1130
  session_start: [chat-history, hot-context, handoff-context, session-canary, council-availability, telemetry-disclosure, first-run-gate, onboarding-gate, verify-before-complete, minimal-safe-diff, profile-staleness, wrapper-freshness, surface-probe, session-register]
1050
1131
  session_end: [chat-history, memory-learn, session-register, roadmap-progress, telemetry-flush]
1051
- stop: [chat-history, hot-context, verify-before-complete, self-repair, session-register, roadmap-progress]
1132
+ stop: [chat-history, hot-context, verify-before-complete, self-repair, session-register, roadmap-progress, design-pass-stop]
1052
1133
  user_prompt_submit: [chat-history, verify-before-complete, minimal-safe-diff, language-mirror, git-authorization, session-canary, self-repair, session-register]
1053
- post_tool_use: [chat-history, roadmap-progress, context-hygiene, verify-before-complete, minimal-safe-diff, injection-scan, pr-url-reminder, orchestration-record, telemetry-usage, tool-result-bytes, edit-shape]
1134
+ post_tool_use: [chat-history, roadmap-progress, context-hygiene, verify-before-complete, minimal-safe-diff, injection-scan, pr-url-reminder, orchestration-record, telemetry-usage, tool-result-bytes, edit-shape, design-pass]
1054
1135
 
1055
1136
  # Phase 7.7 — Windsurf (Cascade). Hooks live at `.windsurf/hooks.json`
1056
1137
  # (project) or `~/.codeium/windsurf/hooks.json` (user). Cascade has
@@ -1066,7 +1147,7 @@ platforms:
1066
1147
  # minimal-safe-diff is omitted entirely on Windsurf for the same reason.
1067
1148
  windsurf:
1068
1149
  session_start: [chat-history, hot-context, handoff-context, session-canary, council-availability, telemetry-disclosure, first-run-gate, onboarding-gate, verify-before-complete, profile-staleness, wrapper-freshness, surface-probe, session-register]
1069
- stop: [chat-history, hot-context, verify-before-complete, self-repair, session-register]
1150
+ stop: [chat-history, hot-context, verify-before-complete, self-repair, session-register, design-pass-stop]
1070
1151
  # language-mirror IS bound here: unlike minimal-safe-diff it needs only the
1071
1152
  # user_prompt_submit slot, which Windsurf has.
1072
1153
  user_prompt_submit: [chat-history, verify-before-complete, language-mirror, git-authorization, session-canary, self-repair, session-register]
@@ -1084,9 +1165,9 @@ platforms:
1084
1165
  gemini:
1085
1166
  session_start: [chat-history, hot-context, handoff-context, session-canary, council-availability, telemetry-disclosure, first-run-gate, onboarding-gate, verify-before-complete, minimal-safe-diff, profile-staleness, wrapper-freshness, surface-probe, session-register]
1086
1167
  session_end: [chat-history, memory-learn, session-register, roadmap-progress, telemetry-flush]
1087
- stop: [chat-history, hot-context, verify-before-complete, self-repair, session-register, roadmap-progress]
1168
+ stop: [chat-history, hot-context, verify-before-complete, self-repair, session-register, roadmap-progress, design-pass-stop]
1088
1169
  user_prompt_submit: [chat-history, verify-before-complete, minimal-safe-diff, language-mirror, git-authorization, session-canary, self-repair, session-register]
1089
- post_tool_use: [chat-history, roadmap-progress, context-hygiene, verify-before-complete, minimal-safe-diff, injection-scan, pr-url-reminder, orchestration-record, telemetry-usage, tool-result-bytes, edit-shape]
1170
+ post_tool_use: [chat-history, roadmap-progress, context-hygiene, verify-before-complete, minimal-safe-diff, injection-scan, pr-url-reminder, orchestration-record, telemetry-usage, tool-result-bytes, edit-shape, design-pass]
1090
1171
 
1091
1172
  # Phase 7.9 — Copilot has no hook surface. Concerns route through
1092
1173
  # rule-only fallback; the dispatcher silently no-ops on --platform copilot.
@@ -54,6 +54,7 @@ import { main as blockNoVerifyMain } from './block_no_verify.js';
54
54
  import { main as blockKernelRuleWritesMain } from './block_kernel_rule_writes.js';
55
55
  import { main as blockConfigWeakeningMain } from './block_config_weakening.js';
56
56
  import { main as rtkWrapMain } from './rtk_wrap_hook.js';
57
+ import { _main as designPassMain } from './design_pass_hook.js';
57
58
  import { main as designSlopMain } from './design_slop_hook.js';
58
59
  import { main as codeGraphNudgeMain } from './code_graph_nudge_hook.js';
59
60
  import { main as uiRouteNudgeMain } from './ui_route_nudge_hook.js';
@@ -62,6 +63,7 @@ import { main as telemetryUsageMain } from './telemetry_usage_hook.js';
62
63
  import { main as telemetryFlushMain } from './telemetry_flush_hook.js';
63
64
  import { main as delegationNudgeMain } from './delegation_nudge_hook.js';
64
65
  import { main as skillRouteMain } from './skill_route_hook.js';
66
+ import { main as ruleInjectMain } from './rule_inject_hook.js';
65
67
  import { main as endReviewNudgeMain } from './end_review_nudge_hook.js';
66
68
  import { main as turnEndGateMain } from './turn_end_gate_hook.js';
67
69
  import { main as editShapeMain } from './edit_shape_hook.js';
@@ -109,6 +111,7 @@ export const CONCERN_REGISTRY: Readonly<Record<string, ConcernMain>> = {
109
111
  'src/scripts/hooks/block_kernel_rule_writes.ts': blockKernelRuleWritesMain as ConcernMain,
110
112
  'src/scripts/hooks/block_config_weakening.ts': blockConfigWeakeningMain as ConcernMain,
111
113
  'src/scripts/hooks/rtk_wrap_hook.ts': rtkWrapMain as ConcernMain,
114
+ 'src/scripts/hooks/design_pass_hook.ts': designPassMain as ConcernMain,
112
115
  'src/scripts/hooks/design_slop_hook.ts': designSlopMain as ConcernMain,
113
116
  'src/scripts/hooks/code_graph_nudge_hook.ts': codeGraphNudgeMain as ConcernMain,
114
117
  'src/scripts/hooks/ui_route_nudge_hook.ts': uiRouteNudgeMain as ConcernMain,
@@ -117,6 +120,7 @@ export const CONCERN_REGISTRY: Readonly<Record<string, ConcernMain>> = {
117
120
  'src/scripts/hooks/telemetry_flush_hook.ts': telemetryFlushMain as ConcernMain,
118
121
  'src/scripts/hooks/delegation_nudge_hook.ts': delegationNudgeMain as ConcernMain,
119
122
  'src/scripts/hooks/skill_route_hook.ts': skillRouteMain as ConcernMain,
123
+ 'src/scripts/hooks/rule_inject_hook.ts': ruleInjectMain as ConcernMain,
120
124
  'src/scripts/hooks/end_review_nudge_hook.ts': endReviewNudgeMain as ConcernMain,
121
125
  'src/scripts/hooks/turn_end_gate_hook.ts': turnEndGateMain as ConcernMain,
122
126
  'src/scripts/hooks/edit_shape_hook.ts': editShapeMain as ConcernMain,
@@ -0,0 +1,356 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Design pass — the delivery carrier the 0.0 % measurement never had.
4
+ *
5
+ * Steps E1.1, E1.2 and E1.3 of `road-to-frontend-power`. One script bound on
6
+ * two slots, because the two passes differ in scope and not in logic:
7
+ *
8
+ * post_tool_use (E1.1) — the file just written. Findings as context, exit 0.
9
+ * stop (E1.2) — every UI file touched this session, deduped
10
+ * against what E1.1 already surfaced. P0 blocks (E1.3).
11
+ *
12
+ * WHY post_tool_use AND NOT pre_tool_use, which is where `design-slop` sits.
13
+ * Two measured reasons, both from this branch's Phase 0:
14
+ *
15
+ * 1. REACH. `pre_tool_use` is declared by three hosts (augment, claude,
16
+ * cowork) and honoured by one. `post_tool_use` is declared by six. A
17
+ * carrier that cannot reach the host cannot deliver anything, and the
18
+ * 0.0 % was a delivery failure before it was anything else.
19
+ * 2. THE GREENFIELD ASYMMETRY. `_lib/ui_surface.ts` is a PATH predicate, so a
20
+ * UI intent that has not yet produced a file is invisible to it — measured
21
+ * at 20/23 recall, with all three misses being exactly that case
22
+ * (`internal/bench/frontend-power/BASELINE-2026-08-23.md` § Routing). A
23
+ * pre-write gate keyed on the path therefore cannot fire on the FIRST
24
+ * write of a new surface, which is the write it most wants. After the
25
+ * write the file exists and the predicate answers.
26
+ *
27
+ * SEVERITY CONTRACT, AND THE HONEST LIMIT ON IT. The stop pass COMPUTES a P0
28
+ * verdict and reports it as "would block at stop". It does not return
29
+ * EXIT_BLOCK, because the concern is declared `severity: advisory` and the
30
+ * dispatcher enforces advisory as a CEILING — an EXIT_BLOCK from here would be
31
+ * downgraded to EXIT_WARN and then mapped to exit 0, i.e. an inert refusal that
32
+ * every other assertion about it would still pass. Shipping that is worse than
33
+ * not blocking, so the code matches the declaration.
34
+ *
35
+ * Making the refusal real means adding this to the BLOCKING_ALLOWLIST in
36
+ * `tests/hooks/concern_severity.test.ts`, whose own header says adding to it is
37
+ * a security-relevant decision — and this would be the third turn-END refusal
38
+ * in the tree. That is transferred with E1.4 rather than taken here.
39
+ *
40
+ * P1-P3 are delivered and never block, on either slot —
41
+ * Risk 1 of the parent roadmap is that one false block on clean UI makes an
42
+ * operator disable the carrier for good, which is the OFF state the 0.0 %
43
+ * already recorded. Only P0 blocks, only at stop, and only the objective
44
+ * floors: those are `lint_design_quality`'s territory (contrast, font size,
45
+ * heading skip, focus), never an aesthetic tell.
46
+ *
47
+ * GRAFT 2. A pass that could not run reports `verification: degraded` with a
48
+ * reason instead of passing silently. `src/rules/design-review-after-ui-write.md`
49
+ * already required that in prose with nothing to read it; this emits it.
50
+ *
51
+ * Default-OFF (`hooks.design_pass.enabled`), fail_closed: false.
52
+ *
53
+ * Exit codes (dispatcher contract): 0 allow · 1 block · 2 warn + JSON reason.
54
+ */
55
+ import fs from 'node:fs';
56
+ import path from 'node:path';
57
+ import { fileURLToPath, pathToFileURL } from 'node:url';
58
+
59
+ import { isUiPath, isUiTreePath } from '../_lib/ui_surface.js';
60
+ import { loadDesignContext, scanFile } from '../lint_design_slop.js';
61
+ import { readHookStdin } from './hook_stdin.js';
62
+
63
+ const EXIT_ALLOW = 0;
64
+ const EXIT_WARN = 2;
65
+ const SETTINGS_FILE = '.agent-settings.yml';
66
+ const STATE_REL = path.join('agents', 'runtime', 'state', 'design-pass-hook.json');
67
+ const AUDIT_REL = path.join('agents', 'runtime', 'state', 'ui-audit.json');
68
+
69
+ /**
70
+ * The P0 set — objective floors only, and the list is closed on purpose.
71
+ * Text-overflow and viewport-edge join it once E3's render artefact is a
72
+ * precondition the gate can rely on; until then a static pass cannot see them
73
+ * and claiming otherwise would be the false block Risk 1 names.
74
+ */
75
+ export const P0_FLOOR_IDS = ['Q1', 'Q2', 'Q5', 'Q6'] as const;
76
+
77
+ export type Verification = 'verified' | 'degraded' | 'unverified';
78
+
79
+ export interface Finding {
80
+ file: string;
81
+ severity: 'P0' | 'P1' | 'P2' | 'P3';
82
+ catalogId: string;
83
+ rule: string;
84
+ line: number;
85
+ message: string;
86
+ }
87
+
88
+ export interface PassResult {
89
+ slot: 'post_tool_use' | 'stop';
90
+ findings: Finding[];
91
+ blocked: Finding[];
92
+ audit_missing: string[];
93
+ verification: Verification;
94
+ degradation_reason?: string;
95
+ }
96
+
97
+ /** Minimal settings reader — mirrors design_slop_hook rather than adding a parser. */
98
+ export function enabled(root: string, key = 'design_pass'): boolean {
99
+ let text: string;
100
+ try {
101
+ text = fs.readFileSync(path.join(root, SETTINGS_FILE), 'utf-8');
102
+ } catch {
103
+ return false;
104
+ }
105
+ let inHooks = false;
106
+ let inKey = false;
107
+ for (const raw of text.split(/\r\n|\r|\n/)) {
108
+ const line = raw.replace(/\s+$/, '');
109
+ if (!line || line.trimStart().startsWith('#')) continue;
110
+ if (!/^\s/.test(line)) {
111
+ inHooks = /^hooks\s*:\s*$/.test(line);
112
+ inKey = false;
113
+ continue;
114
+ }
115
+ if (!inHooks) continue;
116
+ const m2 = /^ {2}(\S[^:]*)\s*:\s*$/.exec(line);
117
+ if (m2) {
118
+ inKey = m2[1]!.trim() === key;
119
+ continue;
120
+ }
121
+ if (inKey) {
122
+ const m4 = /^ {4}enabled\s*:\s*(\S+)/.exec(line);
123
+ if (m4) return /^(true|yes|on)$/i.test(m4[1]!);
124
+ }
125
+ }
126
+ return false;
127
+ }
128
+
129
+ export const isUiSurface = (p: string): boolean => isUiPath(p) || isUiTreePath(p);
130
+
131
+ /**
132
+ * E2.2 — is the audit artefact newer than the target?
133
+ *
134
+ * "Newer" is the whole point: a stale artefact is worse than a missing one,
135
+ * because it looks like evidence. An artefact older than the file it is
136
+ * supposed to describe has not seen the change.
137
+ */
138
+ export function auditIsFresh(root: string, target: string): boolean {
139
+ try {
140
+ const a = fs.statSync(path.join(root, AUDIT_REL)).mtimeMs;
141
+ const t = fs.statSync(path.isAbsolute(target) ? target : path.join(root, target)).mtimeMs;
142
+ return a >= t;
143
+ } catch {
144
+ return false;
145
+ }
146
+ }
147
+
148
+ /**
149
+ * `ui-trivial` — decidable from the diff alone, per the two UI rules. All five
150
+ * conditions, not the four the rules' prose carries: `ui_trivial/apply.ts`
151
+ * enforces `new_dependency` too, and a carrier copying the shorter list would
152
+ * inherit a gap the engine does not have.
153
+ */
154
+ export interface DiffShape {
155
+ files: number;
156
+ changedLines: number;
157
+ newComponent: boolean;
158
+ newState: boolean;
159
+ newDependency: boolean;
160
+ }
161
+ export function isUiTrivial(d: DiffShape): boolean {
162
+ return (
163
+ d.files <= 1 &&
164
+ d.changedLines <= 5 &&
165
+ !d.newComponent &&
166
+ !d.newState &&
167
+ !d.newDependency
168
+ );
169
+ }
170
+
171
+ /** Pure core: what the pass decides, given findings and freshness facts. */
172
+ export function decide(
173
+ slot: PassResult['slot'],
174
+ findings: readonly Finding[],
175
+ auditMissing: readonly string[],
176
+ already: ReadonlySet<string>,
177
+ renderAvailable: boolean,
178
+ ): PassResult {
179
+ const sig = (f: Finding): string => `${f.file}::${f.rule}::${f.line}`;
180
+ const fresh = findings.filter((f) => !already.has(sig(f)));
181
+
182
+ // P0 is a stop-slot verdict only. On post_tool_use everything is delivery:
183
+ // a block mid-turn cannot be acted on without re-entering the same write.
184
+ //
185
+ // `blocked` is the COMPUTED verdict, not an exit code. `main` reports it and
186
+ // returns EXIT_WARN — see the severity note in the header for why an
187
+ // EXIT_BLOCK from an advisory concern would be inert rather than strict.
188
+ const blocked = slot === 'stop' ? fresh.filter((f) => f.severity === 'P0') : [];
189
+
190
+ // Graft 2. The absent render artefact is the honest degradation: two P0
191
+ // floors (text overflow, viewport edge) are simply not decidable from text,
192
+ // so a "clean" verdict without a render is scoped, not complete.
193
+ const verification: Verification = renderAvailable ? 'verified' : 'degraded';
194
+
195
+ return {
196
+ slot,
197
+ findings: fresh,
198
+ blocked,
199
+ audit_missing: [...auditMissing],
200
+ verification,
201
+ ...(renderAvailable
202
+ ? {}
203
+ : {
204
+ degradation_reason:
205
+ 'no render artefact under agents/runtime/state/render/ — the viewport-dependent ' +
206
+ 'floors were not checked. Run `agent-config ui:render <path>` to lift this.',
207
+ }),
208
+ };
209
+ }
210
+
211
+ interface State {
212
+ surfaced: string[];
213
+ touched: string[];
214
+ }
215
+
216
+ function readState(root: string): State {
217
+ try {
218
+ const raw = JSON.parse(fs.readFileSync(path.join(root, STATE_REL), 'utf-8')) as Partial<State>;
219
+ return { surfaced: raw.surfaced ?? [], touched: raw.touched ?? [] };
220
+ } catch {
221
+ return { surfaced: [], touched: [] };
222
+ }
223
+ }
224
+
225
+ function writeState(root: string, s: State): void {
226
+ try {
227
+ const p = path.join(root, STATE_REL);
228
+ fs.mkdirSync(path.dirname(p), { recursive: true });
229
+ fs.writeFileSync(p, `${JSON.stringify(s, null, 2)}\n`);
230
+ } catch {
231
+ /* an unwritable state dir costs dedup, never the pass */
232
+ }
233
+ }
234
+
235
+ function renderAvailable(root: string): boolean {
236
+ try {
237
+ return fs.readdirSync(path.join(root, 'agents', 'runtime', 'state', 'render')).length > 0;
238
+ } catch {
239
+ return false;
240
+ }
241
+ }
242
+
243
+ /** Extracts the written path from a tool payload, whichever key the host uses. */
244
+ export function targetPath(payload: unknown): string | null {
245
+ if (typeof payload !== 'object' || payload === null) return null;
246
+ const o = payload as Record<string, unknown>;
247
+ const input = (o['tool_input'] ?? o['input'] ?? o) as Record<string, unknown>;
248
+ for (const k of ['file_path', 'path', 'filePath', 'target_file']) {
249
+ const v = input?.[k];
250
+ if (typeof v === 'string' && v) return v;
251
+ }
252
+ return null;
253
+ }
254
+
255
+ export function render(result: PassResult): string {
256
+ const lines: string[] = [];
257
+ if (result.blocked.length) {
258
+ lines.push(
259
+ `Design pass — ${result.blocked.length} P0 floor violation(s) WOULD BLOCK at stop ` +
260
+ '(reported, not enforced: this concern is advisory — see its manifest note):',
261
+ );
262
+ for (const f of result.blocked) lines.push(` ✗ [${f.catalogId}] ${f.file}:${f.line} — ${f.message}`);
263
+ }
264
+ const advisory = result.findings.filter((f) => !result.blocked.includes(f));
265
+ if (advisory.length) {
266
+ lines.push(`Design pass — ${advisory.length} finding(s), advisory:`);
267
+ for (const f of advisory.slice(0, 12))
268
+ lines.push(` · [${f.severity} ${f.catalogId}] ${f.file}:${f.line} — ${f.message}`);
269
+ if (advisory.length > 12) lines.push(` … and ${advisory.length - 12} more`);
270
+ }
271
+ for (const m of result.audit_missing)
272
+ lines.push(` · no ui-audit.json newer than ${m} — run \`agent-config ui:audit <path>\``);
273
+ lines.push(`verification: ${result.verification}`);
274
+ if (result.degradation_reason) lines.push(`degradation_reason: ${result.degradation_reason}`);
275
+ return lines.join('\n');
276
+ }
277
+
278
+ function main(): number {
279
+ const root = process.env['CLAUDE_PROJECT_DIR'] ?? process.cwd();
280
+ if (!enabled(root)) return EXIT_ALLOW;
281
+
282
+ const slotArg = process.argv.includes('--slot') ? process.argv[process.argv.indexOf('--slot') + 1] : undefined;
283
+ const slot: PassResult['slot'] = slotArg === 'stop' ? 'stop' : 'post_tool_use';
284
+
285
+ let payload: unknown = null;
286
+ try {
287
+ payload = JSON.parse(readHookStdin() || 'null');
288
+ } catch {
289
+ return EXIT_ALLOW; // fail_closed: false — an unparsable payload is not a block
290
+ }
291
+
292
+ const state = readState(root);
293
+ let targets: string[];
294
+ if (slot === 'stop') {
295
+ targets = state.touched;
296
+ } else {
297
+ const t = targetPath(payload);
298
+ if (!t || !isUiSurface(t)) return EXIT_ALLOW;
299
+ targets = [t];
300
+ if (!state.touched.includes(t)) state.touched.push(t);
301
+ }
302
+ if (!targets.length) return EXIT_ALLOW;
303
+
304
+ // Findings come from the shipped registry, via the same entrypoint CI uses.
305
+ const findings: Finding[] = [];
306
+ let scanFailed: string | null = null;
307
+ try {
308
+ const ctx = loadDesignContext(root);
309
+ for (const rel of targets) {
310
+ const abs = path.isAbsolute(rel) ? rel : path.join(root, rel);
311
+ if (!fs.existsSync(abs)) continue;
312
+ // scanFile takes (content, relPath, ctx) — the hook reads the file
313
+ // itself rather than handing over a path, which is also what lets a
314
+ // post-write pass see the bytes that were just written.
315
+ const content = fs.readFileSync(abs, 'utf-8');
316
+ for (const f of scanFile(content, rel, ctx)) {
317
+ findings.push({
318
+ file: rel,
319
+ severity: f.severity as Finding['severity'],
320
+ catalogId: f.catalogId,
321
+ rule: f.rule,
322
+ line: f.line,
323
+ message: f.message,
324
+ });
325
+ }
326
+ }
327
+ } catch (err) {
328
+ scanFailed = String(err);
329
+ }
330
+
331
+ const auditMissing = targets.filter((t) => !auditIsFresh(root, t));
332
+ let result = decide(slot, findings, auditMissing, new Set(state.surfaced), renderAvailable(root));
333
+ if (scanFailed) {
334
+ result = { ...result, verification: 'unverified', degradation_reason: `detector unavailable: ${scanFailed}` };
335
+ }
336
+
337
+ for (const f of result.findings) state.surfaced.push(`${f.file}::${f.rule}::${f.line}`);
338
+ if (slot === 'stop') state.touched = [];
339
+ writeState(root, state);
340
+
341
+ if (!result.findings.length && !result.audit_missing.length && result.verification === 'verified') {
342
+ return EXIT_ALLOW;
343
+ }
344
+
345
+ process.stdout.write(`${JSON.stringify({ reason: render(result) })}\n`);
346
+ // Deliberately EXIT_WARN even with a P0 verdict. EXIT_BLOCK is unreachable
347
+ // for an advisory concern (the dispatcher downgrades it), so returning it
348
+ // would claim a refusal the transport discards.
349
+ return EXIT_WARN;
350
+ }
351
+
352
+ if (process.argv[1] && pathToFileURL(process.argv[1]).href === import.meta.url) {
353
+ process.exit(main());
354
+ }
355
+ export { main as _main };
356
+ export const _HERE = fileURLToPath(import.meta.url);
@@ -10,12 +10,30 @@
10
10
  * Killer is installed AND the agent is about to run a single verbose CLI
11
11
  * command that is NOT completeness-critical, it surfaces (warn) "re-run
12
12
  * wrapped with rtk" so the upstream-reported 60–90% output-token saving is
13
- * captured. It NEVER blocks (the v1
14
- * dispatcher contract is allow/block/warn — there is no transparent
15
- * `updatedInput` rewrite — and, like `injection_scan_hook`, warn preserves
16
- * agency). It NEVER fires when rtk is absent (silent plain-command fallback,
13
+ * captured. It NEVER blocks, and like `injection_scan_hook`, warn preserves
14
+ * agency. It NEVER fires when rtk is absent (silent plain-command fallback,
17
15
  * no nag).
18
16
  *
17
+ * CORRECTED 2026-08-23 (re-probed, Claude Code 2.1.241). This header used to say
18
+ * "the v1 dispatcher contract is allow/block/warn — there is no transparent
19
+ * `updatedInput` rewrite". **That was false for this host build**, and it was also
20
+ * undated, which is the worse half: an unpinned capability claim cannot be checked
21
+ * against the build it was true for. The host documents
22
+ * `` `updatedInput` - Modified tool input (PreToolUse only) ``, validates its
23
+ * schema, and logs a fallback when it is absent
24
+ * (`agents/evidence/analysis/host-input-rewrite-probe-2026-08-23.md`).
25
+ *
26
+ * What IS true, and is why this hook still only warns: **this dispatcher does not
27
+ * emit it, and no accepted composition policy exists for it.** The dispatcher
28
+ * aggregates many concerns per event and reduces them to one exit code; what
29
+ * happens when two concerns both want to rewrite the same tool input is an
30
+ * unanswered design question, not a plumbing detail. A default-OFF hook that
31
+ * silently changes what the agent runs is also a materially different safety
32
+ * posture from one that warns. AI council 2026-08-23, 2/2 convergent, chose the
33
+ * warn and recorded the rewrite as REJECTED-FOR-NOW on those two grounds rather
34
+ * than on the refuted host claim — with a reopening condition, so a temporary
35
+ * design gap does not become permanent inertia.
36
+ *
19
37
  * Default-OFF. Fires only when `hooks.rtk_wrap.enabled: true` in
20
38
  * `.agent-settings.yml`. Disabled / missing / rtk-absent → no-op exit 0.
21
39
  * fail_closed: false — any parse/probe error returns allow (never break a
@@ -186,9 +204,14 @@ export function classify(command: string): Eligibility {
186
204
  }
187
205
 
188
206
  // ── Unbounded-output cap ADVISORY (token-economy-cache Phase 4.2) ──────────
189
- // The roadmap step asked for a deterministic PreToolUse cap REWRITE; the v1
190
- // dispatcher contract carries no `updatedInput`, so per the roadmap's
191
- // pre-registered consequence this degrades to an ADVISORY: a committed
207
+ // The roadmap step asked for a deterministic PreToolUse cap REWRITE. It degrades
208
+ // to an ADVISORY per that roadmap's pre-registered consequence — but NOT for the
209
+ // reason recorded here until 2026-08-23, which was "the v1 dispatcher contract
210
+ // carries no `updatedInput`". Re-probed against Claude Code 2.1.241: the host
211
+ // carries it (see the header, and
212
+ // agents/evidence/analysis/host-input-rewrite-probe-2026-08-23.md). The real
213
+ // reason is that THIS dispatcher emits no such field and has no accepted
214
+ // composition policy for one across concerns. Same outcome, correct cause: a committed
192
215
  // per-command cap table (this constant — rows individually removable,
193
216
  // per-row opt-out via `enabled`) and a warn naming the bounded alternative.
194
217
  // Nothing is ever truncated; ignoring the advisory IS the uncapped re-run,