@event4u/agent-config 14.10.0 → 14.12.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 (667) 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 +161 -208
  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/evidence-discipline.md +26 -0
  16. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +154 -2
  17. package/dist/agent-src/rules/active-remediation.md +3 -3
  18. package/dist/agent-src/rules/code-provenance.md +2 -2
  19. package/dist/agent-src/rules/context-hygiene.md +13 -33
  20. package/dist/agent-src/rules/council-availability.md +2 -2
  21. package/dist/agent-src/rules/decision-revisit-gate.md +3 -1
  22. package/dist/agent-src/rules/design-fidelity.md +18 -0
  23. package/dist/agent-src/rules/design-review-after-ui-write.md +2 -2
  24. package/dist/agent-src/rules/evaluator-independence.md +56 -44
  25. package/dist/agent-src/rules/fix-what-you-see.md +9 -1
  26. package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +1 -1
  27. package/dist/agent-src/rules/minimal-safe-diff.md +14 -20
  28. package/dist/agent-src/rules/missing-skill-recovery.md +13 -1
  29. package/dist/agent-src/rules/playbook-precedence.md +105 -0
  30. package/dist/agent-src/rules/recurring-criticism.md +3 -1
  31. package/dist/agent-src/rules/roadmap-progress-sync.md +14 -13
  32. package/dist/agent-src/rules/scale-discipline.md +24 -0
  33. package/dist/agent-src/rules/security-sensitive-stop.md +2 -2
  34. package/dist/agent-src/rules/settings-ask-protocol.md +2 -2
  35. package/dist/agent-src/rules/ui-audit-gate.md +27 -15
  36. package/dist/agent-src/rules/untrusted-input-defense.md +2 -2
  37. package/dist/agent-src/skills/accessibility-auditor/SKILL.md +19 -0
  38. package/dist/agent-src/skills/adr-create/SKILL.md +7 -0
  39. package/dist/agent-src/skills/agents-md-thin-root/SKILL.md +33 -0
  40. package/dist/agent-src/skills/ai-council/references/advanced-modes.md +17 -3
  41. package/dist/agent-src/skills/ai-council/references/output-and-synthesis.md +31 -0
  42. package/dist/agent-src/skills/ai-council/references/procedure.md +19 -0
  43. package/dist/agent-src/skills/alerting-doctrine/SKILL.md +225 -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-refactoring/SKILL.md +45 -1
  54. package/dist/agent-src/skills/code-review/SKILL.md +75 -5
  55. package/dist/agent-src/skills/command-routing/SKILL.md +6 -0
  56. package/dist/agent-src/skills/command-writing/SKILL.md +35 -0
  57. package/dist/agent-src/skills/condense-memory/SKILL.md +3 -0
  58. package/dist/agent-src/skills/context-authoring/SKILL.md +1 -1
  59. package/dist/agent-src/skills/conventional-commits-writing/SKILL.md +3 -0
  60. package/dist/agent-src/skills/copilot-agents-optimization/SKILL.md +10 -0
  61. package/dist/agent-src/skills/corpus-grounding/SKILL.md +3 -0
  62. package/dist/agent-src/skills/design-intelligence/SKILL.md +3 -0
  63. package/dist/agent-src/skills/design-intelligence/data/landing.csv +36 -35
  64. package/dist/agent-src/skills/design-intelligence/data/stacks/threejs.csv +1 -0
  65. package/dist/agent-src/skills/design-review/SKILL.md +79 -1
  66. package/dist/agent-src/skills/design-review/references/verification-automation.md +41 -0
  67. package/dist/agent-src/skills/design-system-capture/SKILL.md +35 -40
  68. package/dist/agent-src/skills/design-system-capture/references/import-procedure.md +50 -0
  69. package/dist/agent-src/skills/design-tokens/SKILL.md +3 -0
  70. package/dist/agent-src/skills/design-variations/SKILL.md +3 -0
  71. package/dist/agent-src/skills/developer-like-execution/SKILL.md +3 -0
  72. package/dist/agent-src/skills/estimate-ticket/SKILL.md +3 -0
  73. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +28 -4
  74. package/dist/agent-src/skills/fe-design/SKILL.md +74 -41
  75. package/dist/agent-src/skills/fe-design/references/craft-floor.md +52 -0
  76. package/dist/agent-src/skills/fe-design/references/source-led-port.md +36 -0
  77. package/dist/agent-src/skills/file-editor/SKILL.md +5 -0
  78. package/dist/agent-src/skills/finishing-a-development-branch/SKILL.md +2 -2
  79. package/dist/agent-src/skills/git-workflow/SKILL.md +3 -0
  80. package/dist/agent-src/skills/html-deck/SKILL.md +3 -0
  81. package/dist/agent-src/skills/iconography/SKILL.md +3 -0
  82. package/dist/agent-src/skills/image-editing/SKILL.md +3 -0
  83. package/dist/agent-src/skills/image-generation/SKILL.md +3 -0
  84. package/dist/agent-src/skills/image-provider-routing/SKILL.md +3 -0
  85. package/dist/agent-src/skills/incident-commander/SKILL.md +10 -0
  86. package/dist/agent-src/skills/js-library-packaging/SKILL.md +173 -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/motion-choreographer/SKILL.md +6 -0
  97. package/dist/agent-src/skills/multi-tenancy/SKILL.md +4 -0
  98. package/dist/agent-src/skills/operational-readiness/SKILL.md +184 -0
  99. package/dist/agent-src/skills/override-management/SKILL.md +3 -0
  100. package/dist/agent-src/skills/persona-improvement/SKILL.md +3 -0
  101. package/dist/agent-src/skills/pest-testing/SKILL.md +3 -0
  102. package/dist/agent-src/skills/playbook-authoring/SKILL.md +162 -0
  103. package/dist/agent-src/skills/playwright-testing/SKILL.md +3 -0
  104. package/dist/agent-src/skills/privacy-review/SKILL.md +3 -0
  105. package/dist/agent-src/skills/project-analysis-core/SKILL.md +23 -0
  106. package/dist/agent-src/skills/prompt-engineering-image/SKILL.md +3 -0
  107. package/dist/agent-src/skills/quality-tools/SKILL.md +5 -0
  108. package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +81 -33
  109. package/dist/agent-src/skills/readme-reviewer/SKILL.md +3 -0
  110. package/dist/agent-src/skills/readme-writing/SKILL.md +3 -0
  111. package/dist/agent-src/skills/readme-writing-package/SKILL.md +3 -0
  112. package/dist/agent-src/skills/receiving-code-review/SKILL.md +2 -2
  113. package/dist/agent-src/skills/refine-prompt/SKILL.md +3 -0
  114. package/dist/agent-src/skills/refine-ticket/SKILL.md +3 -0
  115. package/dist/agent-src/skills/requesting-code-review/SKILL.md +2 -2
  116. package/dist/agent-src/skills/review-routing/SKILL.md +2 -2
  117. package/dist/agent-src/skills/roadmap-writing/SKILL.md +23 -41
  118. package/dist/agent-src/skills/roadmap-writing/references/follow-up-roadmap-shape.md +47 -0
  119. package/dist/agent-src/skills/rtk-output-filtering/SKILL.md +22 -6
  120. package/dist/agent-src/skills/runway-cognition/SKILL.md +3 -0
  121. package/dist/agent-src/skills/scene-expander/scene-blueprint.schema.yaml +26 -0
  122. package/dist/agent-src/skills/secrets-management/SKILL.md +4 -0
  123. package/dist/agent-src/skills/server-hardening/SKILL.md +159 -0
  124. package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +3 -0
  125. package/dist/agent-src/skills/skill-management/SKILL.md +3 -0
  126. package/dist/agent-src/skills/skill-reviewer/SKILL.md +3 -0
  127. package/dist/agent-src/skills/skill-writing/SKILL.md +6 -0
  128. package/dist/agent-src/skills/skill-writing/references/procedure.md +24 -2
  129. package/dist/agent-src/skills/spreadsheet-authoring/SKILL.md +3 -0
  130. package/dist/agent-src/skills/storybook-workshop/SKILL.md +203 -0
  131. package/dist/agent-src/skills/storybook-workshop/scripts/story_contrast_floor.ts +134 -0
  132. package/dist/agent-src/skills/subagent-orchestration/SKILL.md +1 -1
  133. package/dist/agent-src/skills/subagent-orchestration/prompts/README.md +25 -0
  134. package/dist/agent-src/skills/supply-chain-intake/SKILL.md +12 -0
  135. package/dist/agent-src/skills/systematic-debugging/SKILL.md +1 -1
  136. package/dist/agent-src/skills/terraform/SKILL.md +3 -0
  137. package/dist/agent-src/skills/test-driven-development/SKILL.md +1 -1
  138. package/dist/agent-src/skills/threat-modeling/SKILL.md +0 -3
  139. package/dist/agent-src/skills/token-optimizer/SKILL.md +3 -0
  140. package/dist/agent-src/skills/typography-system/SKILL.md +3 -0
  141. package/dist/agent-src/skills/ui-component-architect/SKILL.md +17 -1
  142. package/dist/agent-src/skills/upstream-contribute/SKILL.md +3 -0
  143. package/dist/agent-src/skills/validate-feature-fit/SKILL.md +3 -0
  144. package/dist/agent-src/skills/verify-completion-evidence/SKILL.md +2 -2
  145. package/dist/agent-src/skills/wireframe/SKILL.md +3 -0
  146. package/dist/agent-src/skills/wireframe/references/story-beat-ledger.schema.json +115 -0
  147. package/dist/agent-src/skills/workspace-link/SKILL.md +131 -0
  148. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  149. package/dist/agent-src/templates/playbook.md +75 -0
  150. package/dist/agent-src/templates/roadmaps.md +37 -0
  151. package/dist/agent-src/templates/scripts/check_playbook_invokes.ts +231 -0
  152. package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +24 -0
  153. package/dist/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +2 -0
  154. package/dist/agent-src/templates/scripts/work_engine/directives/ui/review.ts +216 -0
  155. package/dist/agent-src/templates/scripts/work_engine/directives/ui/scaffold.ts +159 -0
  156. package/dist/agent-src/templates/scripts/work_engine/directives/ui/stack_bundles.ts +73 -4
  157. package/dist/agent-src/templates/scripts/work_engine/stack/detect.ts +325 -40
  158. package/dist/cli/commands/uiAudit.js +221 -0
  159. package/dist/cli/commands/uiRender.js +206 -0
  160. package/dist/cli/main.js +22 -1
  161. package/dist/cli/mcp/content.js +64 -1
  162. package/dist/cli/mcp/dispatch.js +175 -10
  163. package/dist/cli/registry.js +3 -0
  164. package/dist/cli-delegate/{chunk-G23AT6GD.js → chunk-DMSZHXZS.js} +57 -1
  165. package/dist/cli-delegate/{chunk-77GR3VD4.js → chunk-FF7WAFMR.js} +58 -3
  166. package/dist/cli-delegate/{chunk-YM4GZDJG.js → chunk-JCW7ZLHK.js} +10 -0
  167. package/dist/cli-delegate/{chunk-H4VIVD4C.js → chunk-JJA2QEWA.js} +413 -391
  168. package/dist/cli-delegate/{chunk-PLSG6UL5.js → chunk-K4FFODTS.js} +341 -204
  169. package/dist/cli-delegate/{chunk-B2ERU2VA.js → chunk-WOKWX5PL.js} +1 -1
  170. package/dist/cli-delegate/cmd_brand_status.js +8 -6
  171. package/dist/cli-delegate/cmd_conformance.js +3 -3
  172. package/dist/cli-delegate/cmd_doctor.js +3 -3
  173. package/dist/cli-delegate/cmd_export.js +4 -4
  174. package/dist/cli-delegate/cmd_handoff.js +1 -1
  175. package/dist/cli-delegate/cmd_preflight.js +2 -2
  176. package/dist/cli-delegate/cmd_prune.js +4 -4
  177. package/dist/cli-delegate/cmd_session_recycle.js +70 -9
  178. package/dist/cli-delegate/cmd_settings_migrate.js +4 -4
  179. package/dist/cli-delegate/cmd_settings_set.js +1 -1
  180. package/dist/cli-delegate/cmd_sync.js +4 -4
  181. package/dist/cli-delegate/cmd_uninstall.js +4 -4
  182. package/dist/cli-delegate/cmd_validate.js +4 -4
  183. package/dist/discovery/deprecation-report.md +1 -1
  184. package/dist/discovery/discovery-manifest.json +362 -127
  185. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  186. package/dist/discovery/discovery-manifest.summary.md +4 -4
  187. package/dist/discovery/dormancy-report.md +1 -1
  188. package/dist/discovery/orphan-report.md +1 -1
  189. package/dist/discovery/packs.json +18 -8
  190. package/dist/discovery/trust-report.md +3 -3
  191. package/dist/discovery/workspaces.json +16 -6
  192. package/dist/hooks/dispatch.js +2575 -1472
  193. package/dist/install/install.mjs +800 -708
  194. package/dist/mcp/registry-manifest.json +3 -3
  195. package/dist/mcp/server.json +2 -2
  196. package/dist/mcp/server.mjs +1685 -1250
  197. package/dist/router.json +1 -1
  198. package/dist/scripts/_lib/lean_projection_mode.js +40 -0
  199. package/dist/scripts/_lib/scoped_projection.js +84 -0
  200. package/dist/scripts/_lib/ui_surface.js +89 -0
  201. package/dist/scripts/condense.js +6 -10
  202. package/dist/scripts/project_thin_rules.js +40 -2
  203. package/dist/server/schemas/settings.js +6 -0
  204. package/dist/shared/skillRanking.js +159 -0
  205. package/docs/contracts/provider-lifecycle.md +47 -18
  206. package/docs/contracts/settings-classes.md +35 -5
  207. package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +49 -0
  208. package/docs/guidelines/agent-infra/downstream-changes-mechanics.md +91 -0
  209. package/docs/guidelines/agent-infra/evaluator-independence-mechanics.md +92 -0
  210. package/docs/guidelines/agent-infra/minimal-safe-diff-mechanics.md +45 -1
  211. package/docs/guidelines/agent-infra/roadmap-deferred-resolution-provenance.md +54 -0
  212. package/docs/guidelines/code-clarity.md +21 -0
  213. package/docs/guidelines/design-antipatterns.md +4 -2
  214. package/docs/guidelines/design-asset-discipline.md +38 -0
  215. package/docs/guidelines/design-fidelity-mechanics.md +45 -29
  216. package/docs/guidelines/design-handover-extraction.md +35 -5
  217. package/docs/guidelines/design-modes.md +41 -1
  218. package/docs/guidelines/monorepo-antipatterns.md +141 -0
  219. package/docs/guidelines/redundancy-taxonomy.md +180 -0
  220. package/llms.txt +50 -39
  221. package/package.json +6 -2
  222. package/src/agent-src/templates/scripts/check_playbook_invokes.ts +231 -0
  223. package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +24 -0
  224. package/src/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +2 -0
  225. package/src/agent-src/templates/scripts/work_engine/directives/ui/review.ts +216 -0
  226. package/src/agent-src/templates/scripts/work_engine/directives/ui/scaffold.ts +159 -0
  227. package/src/agent-src/templates/scripts/work_engine/directives/ui/stack_bundles.ts +73 -4
  228. package/src/agent-src/templates/scripts/work_engine/stack/detect.ts +325 -40
  229. package/src/config/agent-settings.template.yml +44 -0
  230. package/src/config/assurance-capability-registry.json +223 -0
  231. package/src/config/assurance-threshold-budget.json +65 -0
  232. package/src/config/budgets.yml +19 -0
  233. package/src/config/ci-local-parity.yml +29 -0
  234. package/src/config/discovery/prompt-patterns.yml +56 -0
  235. package/src/config/discovery/unassigned-artefacts.yml +2 -0
  236. package/src/config/dispatch-economy-metrics.json +4 -2
  237. package/src/config/estate-count-budget.json +8 -3
  238. package/src/config/evaluator-budgets.json +14 -14
  239. package/src/config/gate-coverage.yml +392 -8
  240. package/src/config/gate-violation-baselines.json +76 -72
  241. package/src/config/hook-latency-budget.json +1 -0
  242. package/src/config/hook-token-budget.json +137 -125
  243. package/src/config/pack-size-budget.json +39 -10
  244. package/src/config/preamble-payload-budget.json +97 -71
  245. package/src/config/quorum-attendance-budget.json +12 -4
  246. package/src/config/routing-coverage-seed.json +29 -0
  247. package/src/config/rule-activation-census.json +7 -3
  248. package/src/config/rule-enforcement-baseline.json +0 -1
  249. package/src/config/rule-stub-ceilings.json +112 -91
  250. package/src/config/suggestion-capture.json +28 -0
  251. package/src/config/surface-matrix.yml +21 -2
  252. package/src/config/web-launch-readiness.json +188 -0
  253. package/src/scripts/_cli/cmd_doctor.ts +15 -16
  254. package/src/scripts/_cli/doctor_install_mode.ts +49 -0
  255. package/src/scripts/_cli/doctor_overrides.ts +154 -0
  256. package/src/scripts/_dispatch.bash +17 -0
  257. package/src/scripts/_lib/as_of.ts +412 -0
  258. package/src/scripts/_lib/exec_evidence.ts +7 -0
  259. package/src/scripts/_lib/gate_baseline.ts +150 -1
  260. package/src/scripts/_lib/hook_settings.ts +33 -0
  261. package/src/scripts/_lib/host_listing_model.ts +192 -0
  262. package/src/scripts/_lib/lean_projection_mode.ts +44 -0
  263. package/src/scripts/_lib/mcp_bridge.ts +199 -0
  264. package/src/scripts/_lib/review_independence.ts +62 -10
  265. package/src/scripts/_lib/rule_injection.ts +239 -0
  266. package/src/scripts/_lib/run_checkpoint.ts +54 -1
  267. package/src/scripts/_lib/scoped_projection.ts +96 -0
  268. package/src/scripts/_lib/session_register.ts +44 -2
  269. package/src/scripts/_lib/skill_catalogue.ts +38 -2
  270. package/src/scripts/_lib/skill_estate.ts +115 -0
  271. package/src/scripts/_lib/transcript_reads.ts +207 -0
  272. package/src/scripts/_lib/ui_authority.ts +343 -0
  273. package/src/scripts/ai-video/adapters/fal.sh +8 -3
  274. package/src/scripts/ai-video/adapters/gemini-veo.sh +10 -0
  275. package/src/scripts/ai-video/adapters/higgsfield.sh +10 -2
  276. package/src/scripts/ai-video/adapters/kling.sh +10 -0
  277. package/src/scripts/ai-video/adapters/sora.sh +10 -0
  278. package/src/scripts/ai-video/lib/calibrate-cost.sh +145 -0
  279. package/src/scripts/ai-video/lib/model-capabilities/README.md +53 -7
  280. package/src/scripts/ai-video/lib/model-capabilities/comfyui.json +15 -3
  281. package/src/scripts/ai-video/lib/model-capabilities/fal.json +36 -6
  282. package/src/scripts/ai-video/lib/model-capabilities/gemini-veo.json +23 -0
  283. package/src/scripts/ai-video/lib/model-capabilities/higgsfield.json +23 -0
  284. package/src/scripts/ai-video/lib/model-capabilities/kling.json +23 -0
  285. package/src/scripts/ai-video/lib/model-capabilities/musetalk.json +8 -2
  286. package/src/scripts/ai-video/lib/model-capabilities/replicate.json +36 -6
  287. package/src/scripts/ai-video/lib/model-capabilities/sora.json +45 -0
  288. package/src/scripts/ai-video/lib/model-capabilities/syncso.json +8 -2
  289. package/src/scripts/ai-video/lib/parse-blueprint.sh +52 -5
  290. package/src/scripts/ai-video/lib/resume-scan.sh +92 -3
  291. package/src/scripts/ai-video/lib/seam-plan.sh +212 -0
  292. package/src/scripts/ai-video/smoke-trace.sh +450 -2
  293. package/src/scripts/ai-video/stitch.sh +191 -10
  294. package/src/scripts/ai-video/test-pipeline.sh +84 -6
  295. package/src/scripts/ai_council/argument_exhaustion.ts +130 -0
  296. package/src/scripts/ai_council/cli_agency_bounds.ts +139 -0
  297. package/src/scripts/ai_council/cli_least_agency_canary.ts +347 -0
  298. package/src/scripts/ai_council/clients.ts +3 -2
  299. package/src/scripts/ai_council/consensus.ts +63 -6
  300. package/src/scripts/ai_council/events_log.ts +46 -1
  301. package/src/scripts/ai_council/orchestrator.ts +103 -108
  302. package/src/scripts/ai_council/orchestrator_results.ts +166 -0
  303. package/src/scripts/ai_council/prompts.ts +12 -5
  304. package/src/scripts/ai_council/quorum.ts +82 -1
  305. package/src/scripts/ai_council/quorum_wiring.ts +82 -5
  306. package/src/scripts/ai_council/stance_tally.ts +22 -0
  307. package/src/scripts/bench_hook_latency.ts +62 -0
  308. package/src/scripts/build_proof.ts +12 -1
  309. package/src/scripts/capture_skill_catalogue.ts +21 -0
  310. package/src/scripts/check_always_budget.ts +2 -1
  311. package/src/scripts/check_augmentignore.ts +2 -1
  312. package/src/scripts/check_beta_review_markers.ts +2 -1
  313. package/src/scripts/check_bundle_path_leakage.ts +162 -7
  314. package/src/scripts/check_command_examples.ts +557 -0
  315. package/src/scripts/check_composite_arming.ts +364 -0
  316. package/src/scripts/check_corpus_staleness.ts +2 -1
  317. package/src/scripts/check_council_pin_staleness.ts +3 -1
  318. package/src/scripts/check_enforcement_coverage.ts +116 -3
  319. package/src/scripts/check_enforcement_denominator.ts +365 -0
  320. package/src/scripts/check_estate_count.ts +122 -3
  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_preamble_payload_budget.ts +30 -3
  329. package/src/scripts/check_proposal.ts +2 -1
  330. package/src/scripts/check_reach_staleness.ts +2 -1
  331. package/src/scripts/check_release_adjacent_health.ts +2 -1
  332. package/src/scripts/check_release_pr_shape.ts +5 -0
  333. package/src/scripts/check_review_schema.ts +34 -1
  334. package/src/scripts/check_roadmap_trackable.ts +48 -3
  335. package/src/scripts/check_routing_coverage.ts +352 -0
  336. package/src/scripts/check_score_contract.ts +505 -0
  337. package/src/scripts/check_skill_admissions.ts +514 -0
  338. package/src/scripts/check_source_size_budget.ts +2 -1
  339. package/src/scripts/check_standing_payload_delta.ts +505 -0
  340. package/src/scripts/check_trigger_evals.ts +2 -1
  341. package/src/scripts/check_web_launch_readiness.ts +705 -0
  342. package/src/scripts/classify_change_risk.ts +281 -0
  343. package/src/scripts/compute_skill_tiers.ts +186 -0
  344. package/src/scripts/condense.ts +8 -13
  345. package/src/scripts/council_attendance_metrics.ts +183 -0
  346. package/src/scripts/council_cli.ts +10 -8
  347. package/src/scripts/council_parse_rate.ts +116 -0
  348. package/src/scripts/derive_playbooks.ts +406 -0
  349. package/src/scripts/description_route_check.ts +494 -0
  350. package/src/scripts/design_slop_rules.ts +56 -2
  351. package/src/scripts/dispatch_r2_reviewer.ts +16 -0
  352. package/src/scripts/frontend_corpus_hash.ts +116 -0
  353. package/src/scripts/grade_target_readiness.ts +478 -0
  354. package/src/scripts/hook_manifest.json +1 -1
  355. package/src/scripts/hook_manifest.yaml +124 -16
  356. package/src/scripts/hooks/concern_registry.ts +6 -0
  357. package/src/scripts/hooks/design_pass_hook.ts +356 -0
  358. package/src/scripts/hooks/rtk_wrap_hook.ts +30 -7
  359. package/src/scripts/hooks/rule_inject_hook.ts +318 -0
  360. package/src/scripts/hooks/suggestion_capture_hook.ts +368 -0
  361. package/src/scripts/hot_context_hook.ts +74 -7
  362. package/src/scripts/install.ts +40 -89
  363. package/src/scripts/lint_adapter_tier.ts +663 -0
  364. package/src/scripts/lint_archived_skills.ts +93 -0
  365. package/src/scripts/lint_budget_ownership.ts +56 -5
  366. package/src/scripts/lint_deterministic_time.ts +470 -0
  367. package/src/scripts/lint_framework_leakage.ts +5 -0
  368. package/src/scripts/lint_handoffs.ts +525 -1
  369. package/src/scripts/lint_judge_prompt_expectation.ts +155 -0
  370. package/src/scripts/lint_marketplace.ts +88 -0
  371. package/src/scripts/lint_media_policy_linkage.ts +140 -1
  372. package/src/scripts/lint_one_off_age.ts +6 -1
  373. package/src/scripts/lint_override_kernel_guard.ts +87 -5
  374. package/src/scripts/lint_roadmap_complexity.ts +56 -0
  375. package/src/scripts/lint_rule_enforcement_declaration.ts +24 -7
  376. package/src/scripts/lint_rule_norm_pin.ts +321 -0
  377. package/src/scripts/lint_skill_trigger_corpus.ts +349 -0
  378. package/src/scripts/lint_spawn_payload.ts +42 -5
  379. package/src/scripts/lint_symptom_intake.ts +2 -1
  380. package/src/scripts/mcp_parity_smoke.ts +30 -4
  381. package/src/scripts/mcp_render.ts +66 -1
  382. package/src/scripts/mcp_tool_fingerprint.ts +241 -0
  383. package/src/scripts/measure_risk_class_drift.ts +140 -0
  384. package/src/scripts/measure_skill_ranker_baseline.ts +212 -0
  385. package/src/scripts/media/lib/adapter-common.sh +211 -1
  386. package/src/scripts/media/lib/adapter-contract.md +74 -6
  387. package/src/scripts/model_rule_injection.ts +907 -0
  388. package/src/scripts/pack_install_smoke.ts +363 -0
  389. package/src/scripts/pr_conflict_census.ts +187 -0
  390. package/src/scripts/project_thin_rules.ts +45 -2
  391. package/src/scripts/release.ts +66 -860
  392. package/src/scripts/release_drill.ts +59 -3
  393. package/src/scripts/release_env.ts +298 -0
  394. package/src/scripts/release_publication.ts +720 -0
  395. package/src/scripts/report_pack_delta.ts +204 -0
  396. package/src/scripts/roadmap_context.ts +778 -0
  397. package/src/scripts/schemas/fidelity-measurement-sheet.schema.json +169 -0
  398. package/src/scripts/schemas/rule.schema.json +24 -2
  399. package/src/scripts/schemas/skill.schema.json +39 -0
  400. package/src/scripts/schemas/ui-authority.schema.json +114 -0
  401. package/src/scripts/select_analysis_mode.ts +112 -0
  402. package/src/scripts/session_register_hook.ts +29 -3
  403. package/src/scripts/sessions_cli.ts +67 -3
  404. package/src/scripts/skill_tools/score_skill_relevance.ts +36 -53
  405. package/src/scripts/sync_pr_branch.ts +40 -1
  406. package/src/scripts/token_sink_report.ts +239 -0
  407. package/src/scripts/trigger_coverage.ts +122 -3
  408. package/src/scripts/update_counts.ts +7 -3
  409. package/src/scripts/validate_frontmatter.ts +66 -0
  410. package/src/server/schemas/settings.ts +10 -0
  411. package/src/shared/skillRanking.ts +183 -0
  412. package/dist/agent-src/skills/accessibility-auditor/evals/evals.json +0 -15
  413. package/dist/agent-src/skills/agent-security-review/evals/triggers.json +0 -52
  414. package/dist/agent-src/skills/ai-code-blindspots/evals/triggers.json +0 -52
  415. package/dist/agent-src/skills/analysis-skill-router/evals/evals.json +0 -13
  416. package/dist/agent-src/skills/brand/evals/triggers.json +0 -17
  417. package/dist/agent-src/skills/brand-asset-generation/evals/triggers.json +0 -17
  418. package/dist/agent-src/skills/brand-audit/evals/triggers.json +0 -17
  419. package/dist/agent-src/skills/brand-identity/evals/triggers.json +0 -17
  420. package/dist/agent-src/skills/brand-strategy/evals/triggers.json +0 -17
  421. package/dist/agent-src/skills/brand-to-tokens/evals/triggers.json +0 -17
  422. package/dist/agent-src/skills/bug-analyzer/evals/evals.json +0 -13
  423. package/dist/agent-src/skills/canvas-design/evals/triggers.json +0 -17
  424. package/dist/agent-src/skills/character-consistency/evals/evals.json +0 -16
  425. package/dist/agent-src/skills/code-intelligence/evals/triggers.json +0 -52
  426. package/dist/agent-src/skills/code-review/evals/evals.json +0 -100
  427. package/dist/agent-src/skills/command-routing/evals/evals.json +0 -14
  428. package/dist/agent-src/skills/complexity-first-planning/evals/triggers.json +0 -17
  429. package/dist/agent-src/skills/contract-review/evals/triggers.json +0 -17
  430. package/dist/agent-src/skills/conventional-commits-writing/evals/evals.json +0 -15
  431. package/dist/agent-src/skills/corpus-grounding/evals/triggers.json +0 -17
  432. package/dist/agent-src/skills/dashboard-design/evals/evals.json +0 -16
  433. package/dist/agent-src/skills/dcf-modeling/evals/domain-truth.json +0 -29
  434. package/dist/agent-src/skills/dcf-modeling/evals/evals.json +0 -20
  435. package/dist/agent-src/skills/decision-record/evals/evals.json +0 -20
  436. package/dist/agent-src/skills/decision-record/evals/triggers.json +0 -87
  437. package/dist/agent-src/skills/design-intelligence/evals/evals.json +0 -14
  438. package/dist/agent-src/skills/design-intelligence/evals/triggers.json +0 -17
  439. package/dist/agent-src/skills/design-system-capture/evals/evals.json +0 -15
  440. package/dist/agent-src/skills/design-tokens/evals/triggers.json +0 -17
  441. package/dist/agent-src/skills/design-variations/evals/triggers.json +0 -17
  442. package/dist/agent-src/skills/developer-like-execution/evals/evals.json +0 -16
  443. package/dist/agent-src/skills/doc-coauthoring/evals/evals.json +0 -16
  444. package/dist/agent-src/skills/doc-coauthoring/evals/triggers.json +0 -17
  445. package/dist/agent-src/skills/docx-authoring/evals/triggers.json +0 -52
  446. package/dist/agent-src/skills/dpa-review/evals/triggers.json +0 -17
  447. package/dist/agent-src/skills/editorial-calendar/evals/domain-truth.json +0 -16
  448. package/dist/agent-src/skills/editorial-calendar/evals/evals.json +0 -16
  449. package/dist/agent-src/skills/eloquent/evals/triggers.json +0 -17
  450. package/dist/agent-src/skills/estimate-ticket/evals/evals.json +0 -16
  451. package/dist/agent-src/skills/estimate-ticket/evals/output-schema.yml +0 -20
  452. package/dist/agent-src/skills/estimate-ticket/evals/triggers.json +0 -19
  453. package/dist/agent-src/skills/evaluate-llm-feature/evals/triggers.json +0 -52
  454. package/dist/agent-src/skills/existing-ui-audit/evals/triggers.json +0 -47
  455. package/dist/agent-src/skills/experiment-loop/evals/output-schema.yml +0 -27
  456. package/dist/agent-src/skills/experiment-loop/evals/triggers.json +0 -17
  457. package/dist/agent-src/skills/fe-design/evals/triggers.json +0 -55
  458. package/dist/agent-src/skills/forecasting/evals/domain-truth.json +0 -29
  459. package/dist/agent-src/skills/forecasting/evals/evals.json +0 -20
  460. package/dist/agent-src/skills/forensics-report/evals/triggers.json +0 -17
  461. package/dist/agent-src/skills/frontend-render-security/evals/triggers.json +0 -52
  462. package/dist/agent-src/skills/fundraising-narrative/evals/domain-truth.json +0 -16
  463. package/dist/agent-src/skills/fundraising-narrative/evals/evals.json +0 -16
  464. package/dist/agent-src/skills/gated-reach/evals/triggers.json +0 -72
  465. package/dist/agent-src/skills/github-ci/evals/evals.json +0 -25
  466. package/dist/agent-src/skills/history-design/evals/triggers.json +0 -17
  467. package/dist/agent-src/skills/html-deck/evals/triggers.json +0 -17
  468. package/dist/agent-src/skills/humanizer/evals/strip_fixtures.json +0 -57
  469. package/dist/agent-src/skills/humanizer/evals/triggers.json +0 -17
  470. package/dist/agent-src/skills/iconography/evals/triggers.json +0 -17
  471. package/dist/agent-src/skills/image-analyser/evals/triggers.json +0 -17
  472. package/dist/agent-src/skills/image-creator/evals/triggers.json +0 -17
  473. package/dist/agent-src/skills/image-editing/evals/triggers.json +0 -17
  474. package/dist/agent-src/skills/image-generation/evals/triggers.json +0 -17
  475. package/dist/agent-src/skills/image-provider-routing/evals/triggers.json +0 -17
  476. package/dist/agent-src/skills/incident-commander/evals/domain-truth.json +0 -16
  477. package/dist/agent-src/skills/incident-commander/evals/evals.json +0 -20
  478. package/dist/agent-src/skills/judge-artifact-completeness/evals/triggers.json +0 -17
  479. package/dist/agent-src/skills/judge-injection-defense/evals/triggers.json +0 -17
  480. package/dist/agent-src/skills/judge-synthesis/evals/triggers.json +0 -17
  481. package/dist/agent-src/skills/launch-readiness/evals/evals.json +0 -21
  482. package/dist/agent-src/skills/learning-tutor/evals/triggers.json +0 -52
  483. package/dist/agent-src/skills/legal-intake-triage/evals/triggers.json +0 -17
  484. package/dist/agent-src/skills/legal-practice-profile/evals/triggers.json +0 -17
  485. package/dist/agent-src/skills/license-compliance-audit/evals/triggers.json +0 -52
  486. package/dist/agent-src/skills/license-compliance-borrow-check/evals/triggers.json +0 -52
  487. package/dist/agent-src/skills/license-compliance-credits/evals/triggers.json +0 -52
  488. package/dist/agent-src/skills/llm-provider-knowledge/evals/triggers.json +0 -20
  489. package/dist/agent-src/skills/logging-monitoring/evals/evals.json +0 -16
  490. package/dist/agent-src/skills/logo-generation/evals/triggers.json +0 -17
  491. package/dist/agent-src/skills/messaging-architecture/evals/domain-truth.json +0 -16
  492. package/dist/agent-src/skills/messaging-architecture/evals/evals.json +0 -16
  493. package/dist/agent-src/skills/nda-triage/evals/triggers.json +0 -17
  494. package/dist/agent-src/skills/pdf-tools/evals/triggers.json +0 -52
  495. package/dist/agent-src/skills/perf-feedback-craft/evals/evals.json +0 -16
  496. package/dist/agent-src/skills/persona-improvement/evals/triggers.json +0 -52
  497. package/dist/agent-src/skills/php-coder/evals/triggers.json +0 -17
  498. package/dist/agent-src/skills/prediction-pool-optimizer/evals/triggers.json +0 -21
  499. package/dist/agent-src/skills/prompt-engineering-image/evals/triggers.json +0 -17
  500. package/dist/agent-src/skills/prompt-engineering-patterns/evals/evals.json +0 -16
  501. package/dist/agent-src/skills/prompt-validator/evals/triggers.json +0 -17
  502. package/dist/agent-src/skills/quality-tools/evals/evals.json +0 -15
  503. package/dist/agent-src/skills/reasoning-orchestrator/evals/triggers.json +0 -17
  504. package/dist/agent-src/skills/refine-prompt/evals/evals.json +0 -16
  505. package/dist/agent-src/skills/refine-ticket/evals/evals.json +0 -16
  506. package/dist/agent-src/skills/refine-ticket/evals/output-schema.yml +0 -16
  507. package/dist/agent-src/skills/refine-ticket/evals/triggers.json +0 -17
  508. package/dist/agent-src/skills/release-comms/evals/evals.json +0 -16
  509. package/dist/agent-src/skills/rice-prioritization/evals/evals.json +0 -20
  510. package/dist/agent-src/skills/runway-cognition/evals/domain-truth.json +0 -29
  511. package/dist/agent-src/skills/runway-cognition/evals/evals.json +0 -20
  512. package/dist/agent-src/skills/scenario-modeling/evals/domain-truth.json +0 -29
  513. package/dist/agent-src/skills/scenario-modeling/evals/evals.json +0 -20
  514. package/dist/agent-src/skills/schema-review/evals/triggers.json +0 -17
  515. package/dist/agent-src/skills/screenshot-hygiene/evals/triggers.json +0 -52
  516. package/dist/agent-src/skills/security-maturity-assessment/evals/triggers.json +0 -52
  517. package/dist/agent-src/skills/skill-writing/evals/triggers.json +0 -17
  518. package/dist/agent-src/skills/spreadsheet-authoring/evals/triggers.json +0 -47
  519. package/dist/agent-src/skills/subagent-orchestration/evals/evals.json +0 -60
  520. package/dist/agent-src/skills/supply-chain-intake/evals/triggers.json +0 -52
  521. package/dist/agent-src/skills/systematic-debugging/evals/evals.json +0 -20
  522. package/dist/agent-src/skills/test-case-discovery/evals/triggers.json +0 -52
  523. package/dist/agent-src/skills/test-driven-development/evals/evals.json +0 -16
  524. package/dist/agent-src/skills/threat-modeling/evals/evals.json +0 -21
  525. package/dist/agent-src/skills/typography-system/evals/evals.json +0 -14
  526. package/dist/agent-src/skills/typography-system/evals/triggers.json +0 -17
  527. package/dist/agent-src/skills/unit-economics-modeling/evals/domain-truth.json +0 -40
  528. package/dist/agent-src/skills/unit-economics-modeling/evals/evals.json +0 -24
  529. package/dist/agent-src/skills/verify-completion-evidence/evals/evals.json +0 -16
  530. package/dist/agent-src/skills/verify-repair-loop/evals/output-schema.yml +0 -20
  531. package/dist/agent-src/skills/verify-repair-loop/evals/triggers.json +0 -17
  532. package/dist/agent-src/skills/vision-articulation/evals/evals.json +0 -16
  533. package/dist/agent-src/skills/voice-and-tone-design/evals/evals.json +0 -16
  534. package/dist/agent-src/skills/wireframe/evals/triggers.json +0 -17
  535. package/dist/agent-src/skills/worktree-lifecycle/evals/evals.json +0 -38
  536. package/dist/agent-src/skills/worktree-lifecycle/evals/triggers.json +0 -52
  537. package/dist/cli/agent-config.js.map +0 -1
  538. package/dist/cli/bash/runBash.js.map +0 -1
  539. package/dist/cli/commands/commands.js.map +0 -1
  540. package/dist/cli/commands/config.js.map +0 -1
  541. package/dist/cli/commands/doctorShell.js.map +0 -1
  542. package/dist/cli/commands/mcpServer.js.map +0 -1
  543. package/dist/cli/commands/packs.js.map +0 -1
  544. package/dist/cli/commands/profiles.js.map +0 -1
  545. package/dist/cli/commands/recordTriggerEval.js.map +0 -1
  546. package/dist/cli/commands/rtkDetect.js.map +0 -1
  547. package/dist/cli/commands/settings.js.map +0 -1
  548. package/dist/cli/commands/uiServe.js.map +0 -1
  549. package/dist/cli/commands/versions.js.map +0 -1
  550. package/dist/cli/commands/workspaces.js.map +0 -1
  551. package/dist/cli/configRoot.js.map +0 -1
  552. package/dist/cli/discovery/loadManifest.js.map +0 -1
  553. package/dist/cli/firstRunNotice.js.map +0 -1
  554. package/dist/cli/help.js.map +0 -1
  555. package/dist/cli/initRouting.js.map +0 -1
  556. package/dist/cli/log/logger.js.map +0 -1
  557. package/dist/cli/main.js.map +0 -1
  558. package/dist/cli/mcp/content.js.map +0 -1
  559. package/dist/cli/mcp/dispatch.js.map +0 -1
  560. package/dist/cli/mcp/stdio.js.map +0 -1
  561. package/dist/cli/paths.js.map +0 -1
  562. package/dist/cli/python/knowledge_ingest.js.map +0 -1
  563. package/dist/cli/python/workspace_analytics.js.map +0 -1
  564. package/dist/cli/python/workspace_crypto.js.map +0 -1
  565. package/dist/cli/python/workspace_documents.js.map +0 -1
  566. package/dist/cli/python/workspace_drive.js.map +0 -1
  567. package/dist/cli/python/workspace_drive_health.js.map +0 -1
  568. package/dist/cli/python/workspace_explain.js.map +0 -1
  569. package/dist/cli/python/workspace_hosts.js.map +0 -1
  570. package/dist/cli/python/workspace_inbox.js.map +0 -1
  571. package/dist/cli/python/workspace_render.js.map +0 -1
  572. package/dist/cli/python/workspace_roles.js.map +0 -1
  573. package/dist/cli/python/workspace_secrets.js.map +0 -1
  574. package/dist/cli/python/workspace_sessions.js.map +0 -1
  575. package/dist/cli/python/workspace_skills.js.map +0 -1
  576. package/dist/cli/registry.js.map +0 -1
  577. package/dist/install/agentSwitchDetection.js.map +0 -1
  578. package/dist/install/agentSwitchProfile.js.map +0 -1
  579. package/dist/install/atomic.js.map +0 -1
  580. package/dist/install/claudePathsPlan.js.map +0 -1
  581. package/dist/install/conflict.js.map +0 -1
  582. package/dist/install/detect.js.map +0 -1
  583. package/dist/install/emit_host_rules_cli.js.map +0 -1
  584. package/dist/install/globalRuleLayers.js.map +0 -1
  585. package/dist/install/hostLayerFingerprint.js.map +0 -1
  586. package/dist/install/partitionEligibility.js.map +0 -1
  587. package/dist/install/paths.js.map +0 -1
  588. package/dist/install/plan.js.map +0 -1
  589. package/dist/install/preflight.js.map +0 -1
  590. package/dist/install/rtkDetection.js.map +0 -1
  591. package/dist/install/ruleInScope.js.map +0 -1
  592. package/dist/install/ruleLayerPartition.js.map +0 -1
  593. package/dist/install/rule_scope.js.map +0 -1
  594. package/dist/install/rule_scope_cli.js.map +0 -1
  595. package/dist/install/selectedTools.js.map +0 -1
  596. package/dist/install/toolDetection.js.map +0 -1
  597. package/dist/install/txlog.js.map +0 -1
  598. package/dist/install/types.js.map +0 -1
  599. package/dist/install/wizard-plan.js.map +0 -1
  600. package/dist/install/wizardDismissals.js.map +0 -1
  601. package/dist/scripts/_lib/agent_settings.js.map +0 -1
  602. package/dist/scripts/_lib/agent_src.js.map +0 -1
  603. package/dist/scripts/_lib/claude_builtin_names.js.map +0 -1
  604. package/dist/scripts/_lib/claude_plugin.js.map +0 -1
  605. package/dist/scripts/_lib/claude_settings_hooks.js.map +0 -1
  606. package/dist/scripts/_lib/compile_time_toggles.js.map +0 -1
  607. package/dist/scripts/_lib/environment_detector.js.map +0 -1
  608. package/dist/scripts/_lib/host_launch.js.map +0 -1
  609. package/dist/scripts/_lib/install_layout.js.map +0 -1
  610. package/dist/scripts/_lib/installed_lock.js.map +0 -1
  611. package/dist/scripts/_lib/model_tier.js.map +0 -1
  612. package/dist/scripts/_lib/prune_empty_dirs.js.map +0 -1
  613. package/dist/scripts/_lib/scoped_projection.js.map +0 -1
  614. package/dist/scripts/_lib/script_output.js.map +0 -1
  615. package/dist/scripts/_lib/spawn_env.js.map +0 -1
  616. package/dist/scripts/_lib/surface_tiers.js.map +0 -1
  617. package/dist/scripts/_lib/token_count.js.map +0 -1
  618. package/dist/scripts/_lib/trigger_eval_floors.js.map +0 -1
  619. package/dist/scripts/_lib/user_global_paths.js.map +0 -1
  620. package/dist/scripts/ai_council/modes.js.map +0 -1
  621. package/dist/scripts/ai_council/transport_resolver.js.map +0 -1
  622. package/dist/scripts/condense.js.map +0 -1
  623. package/dist/scripts/project_thin_rules.js.map +0 -1
  624. package/dist/server/app.js.map +0 -1
  625. package/dist/server/io/atomicMultiWrite.js.map +0 -1
  626. package/dist/server/io/atomicWrite.js.map +0 -1
  627. package/dist/server/io/sharedWriteCheck.js.map +0 -1
  628. package/dist/server/io/substituteTemplate.js.map +0 -1
  629. package/dist/server/io/yamlIO.js.map +0 -1
  630. package/dist/server/nicknameResolver.js.map +0 -1
  631. package/dist/server/port.js.map +0 -1
  632. package/dist/server/routes/discovery.js.map +0 -1
  633. package/dist/server/routes/install.js.map +0 -1
  634. package/dist/server/routes/ping.js.map +0 -1
  635. package/dist/server/routes/schema.js.map +0 -1
  636. package/dist/server/routes/settings.js.map +0 -1
  637. package/dist/server/routes/settingsChanges.js.map +0 -1
  638. package/dist/server/routes/userMd.js.map +0 -1
  639. package/dist/server/routes/wizard.js.map +0 -1
  640. package/dist/server/routes/workspace.js.map +0 -1
  641. package/dist/server/schemas/settings.js.map +0 -1
  642. package/dist/server/serverInfo.js.map +0 -1
  643. package/dist/server/token.js.map +0 -1
  644. package/dist/server/writeRoot.js.map +0 -1
  645. package/dist/shared/capabilities.js.map +0 -1
  646. package/dist/shared/interactiveContext.js.map +0 -1
  647. package/dist/shared/nicknamePrefill.js.map +0 -1
  648. package/dist/shared/settingsAsks.js.map +0 -1
  649. package/dist/shared/settingsCarveOut.js.map +0 -1
  650. package/dist/shared/settingsClasses.js.map +0 -1
  651. package/dist/shared/settingsConsent.js.map +0 -1
  652. package/dist/shared/settingsSurface.js.map +0 -1
  653. package/dist/shared/userMd/formAdapter.js.map +0 -1
  654. package/dist/shared/userMd/schema.js.map +0 -1
  655. package/dist/shared/userMd/utils.js.map +0 -1
  656. package/dist/ui/assets/index-Cxgy63kz.js.map +0 -1
  657. package/src/scripts/_lib/adr_frontmatter.test.ts +0 -365
  658. package/src/scripts/_lib/adversarial_council_gate.test.ts +0 -112
  659. package/src/scripts/_lib/adversarial_reconcile.test.ts +0 -197
  660. package/src/scripts/_lib/auto_dispatch.corpus.test.ts +0 -150
  661. package/src/scripts/_lib/secret_detector.test.ts +0 -108
  662. package/src/scripts/_lib/secret_detector_adversarial.test.ts +0 -116
  663. package/src/scripts/_lib/untrusted_content.test.ts +0 -175
  664. package/src/scripts/check_secret_leak.test.ts +0 -90
  665. package/src/scripts/design_slop_rules.test.ts +0 -239
  666. package/src/scripts/self_review_gate.test.ts +0 -296
  667. package/src/shared/capabilities.test.ts +0 -43
@@ -0,0 +1,365 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * CI gate: exactly one enforcement denominator is quotable, and it comes from
4
+ * the resolver.
5
+ *
6
+ * WHY. Measured on 2026-08-23, the tree published **five** figures for one
7
+ * property — how many governed rules declare no enforcement backstop.
8
+ * `docs/proof.md` carried **86** in one place and **89** in another (two
9
+ * different frames quoted under one heading); a frontmatter-strict grep of
10
+ * `src/rules/` returned **87**; an any-line grep returned **82**; and a
11
+ * hand-written ledger entry at `docs/CLAIMS.md:203` carried its own snapshot.
12
+ * A reader had no way to tell which was the answer, and correcting any single
13
+ * figure would have left the plurality intact.
14
+ *
15
+ * `check_enforcement_coverage` is the only citable source: it RESOLVES rather
16
+ * than counts (a declared validator no workflow reaches is `unwired`, not
17
+ * covered) and it publishes its denominator with the frame that produced it.
18
+ * `docs/proof.md` § 4b projects that output. This gate is what stops a sixth
19
+ * number appearing — a sixth number would be the defect, not the fix.
20
+ *
21
+ * THE CONTRACT. In the scanned corpus, a line stating an enforcement count is a
22
+ * finding, full stop. Not "a wrong one" — the gate deliberately does NOT compare
23
+ * values against the resolver, because a hand-written figure that happens to be
24
+ * right today is the mechanism by which the plurality returned every previous
25
+ * time. The remedy is to cite the generated projection or the resolver's own
26
+ * output instead of restating a number.
27
+ *
28
+ * SCOPE, and why each exclusion is not a loophole:
29
+ * · `docs/**` plus `README.md` — the published surfaces. `agents/` is
30
+ * excluded wholesale because an evidence artefact records a measurement
31
+ * taken at a stated time, which is its job; freezing those would forbid
32
+ * measurement itself.
33
+ * · `docs/decisions/` — an ADR is a dated record of what was true when the
34
+ * decision was made. Rewriting one to today's number destroys the record.
35
+ * · `docs/archive/` — shipped changelogs, immutable by construction.
36
+ * · Any file whose head declares `GENERATED by` — that IS the resolver's
37
+ * projection, which is the sanctioned home for the number.
38
+ *
39
+ * Escape hatch: `<!-- enforcement-count-ok: <reason> -->` on the line, reason
40
+ * mandatory. A bare marker stays a finding.
41
+ *
42
+ * Exit codes:
43
+ * 0 — no hand-written enforcement count in the published corpus
44
+ * 1 — at least one (or a marker with no reason)
45
+ * 2 — the gate could not run (dead scan scope, bad args)
46
+ */
47
+ import * as fs from 'node:fs';
48
+ import * as os from 'node:os';
49
+ import * as path from 'node:path';
50
+ import { fileURLToPath, pathToFileURL } from 'node:url';
51
+
52
+ import { GateLedger, LedgerUsageError } from './_lib/gate_ledger.js';
53
+ import { runGateCli, runSelfTest, type SelfTestCase } from './_lib/gate_self_test.js';
54
+ import { DeadScopeError, reportScanned } from './_lib/scan_scope.js';
55
+
56
+ const _HERE = fileURLToPath(import.meta.url);
57
+ const DEFAULT_ROOT = path.join(path.dirname(_HERE), '..', '..');
58
+ const SELF = 'src/scripts/check_enforcement_denominator.ts';
59
+
60
+ const SELF_TEST_MIN_CASES = 7;
61
+ const SELF_TEST_MIN_REJECT = 3;
62
+
63
+ /** Roots walked, repo-relative. */
64
+ const SCAN_ROOTS = ['docs', 'README.md'] as const;
65
+
66
+ /** Repo-relative prefixes excluded — see the docstring for why each is not a loophole. */
67
+ const EXCLUDED_PREFIXES = ['docs/decisions/', 'docs/archive/'] as const;
68
+
69
+ /** A file declaring this in its first few lines is the resolver's own projection. */
70
+ const GENERATED_MARKER = 'GENERATED by';
71
+ const GENERATED_HEAD_LINES = 5;
72
+
73
+ /** Same-line exemption; the reason after the colon must be non-empty. */
74
+ const MARKER = 'enforcement-count-ok:';
75
+
76
+ /**
77
+ * A line is a candidate only when it talks about enforcement AND carries a
78
+ * rule-count shape. Both halves are load-bearing: the keyword alone matches
79
+ * every prose mention of a backstop, and the shape alone matches "2 rules" in a
80
+ * concepts page, which is not this property at all.
81
+ */
82
+ const ENFORCEMENT_KEYWORDS =
83
+ /undeclared|enforced_by|enforcement coverage|carry a backstop|backstop that fails/;
84
+
85
+ const COUNT_SHAPES: readonly RegExp[] = [
86
+ /\b\d+\s+of\s+\d+\s+(?:governed\s+)?rules?\b/,
87
+ /\b\d+\s+(?:governed\s+)?rules?\b/,
88
+ /\b\d+\s+undeclared\b/,
89
+ /\bundeclared\s+\d+\b/,
90
+ ];
91
+
92
+ export interface Finding {
93
+ file: string;
94
+ line: number;
95
+ excerpt: string;
96
+ /** `raw` — an unmarked count. `bare-marker` — a marker with no reason. */
97
+ kind: 'raw' | 'bare-marker';
98
+ }
99
+
100
+ function markerOn(line: string): 'none' | 'bare' | 'reasoned' {
101
+ const at = line.indexOf(MARKER);
102
+ if (at < 0) return 'none';
103
+ const tail = line.slice(at + MARKER.length).replace(/-->\s*$/, '').trim();
104
+ return tail === '' ? 'bare' : 'reasoned';
105
+ }
106
+
107
+ export function scanText(relPath: string, text: string): Finding[] {
108
+ const out: Finding[] = [];
109
+ const lines = text.split('\n');
110
+ for (let i = 0; i < lines.length; i += 1) {
111
+ const line = lines[i] ?? '';
112
+ if (!ENFORCEMENT_KEYWORDS.test(line)) continue;
113
+ if (!COUNT_SHAPES.some((re) => re.test(line))) continue;
114
+ const marker = markerOn(line);
115
+ if (marker === 'reasoned') continue;
116
+ out.push({
117
+ file: relPath,
118
+ line: i + 1,
119
+ excerpt: line.trim().slice(0, 120),
120
+ kind: marker === 'bare' ? 'bare-marker' : 'raw',
121
+ });
122
+ }
123
+ return out;
124
+ }
125
+
126
+ /** `true` when the file declares itself generated — i.e. it IS the projection. */
127
+ export function isGenerated(text: string): boolean {
128
+ return text.split('\n', GENERATED_HEAD_LINES).join('\n').includes(GENERATED_MARKER);
129
+ }
130
+
131
+ /** Every markdown file in scope, repo-relative, sorted. */
132
+ export function corpus(root: string): string[] {
133
+ const out: string[] = [];
134
+ const walk = (rel: string): void => {
135
+ const abs = path.join(root, rel);
136
+ let st: fs.Stats;
137
+ try {
138
+ st = fs.statSync(abs);
139
+ } catch {
140
+ return;
141
+ }
142
+ if (st.isFile()) {
143
+ if (!rel.endsWith('.md')) return;
144
+ if (EXCLUDED_PREFIXES.some((p) => rel.startsWith(p))) return;
145
+ out.push(rel);
146
+ return;
147
+ }
148
+ if (!st.isDirectory()) return;
149
+ for (const name of fs.readdirSync(abs).sort()) walk(path.posix.join(rel, name));
150
+ };
151
+ for (const r of SCAN_ROOTS) walk(r);
152
+ return out.sort();
153
+ }
154
+
155
+ export function check(root: string): { code: number; findings: Finding[]; scanned: number } {
156
+ const files = corpus(root);
157
+ const findings: Finding[] = [];
158
+ const ledger = new GateLedger('check_enforcement_denominator');
159
+
160
+ try {
161
+ reportScanned({
162
+ gate: 'check_enforcement_denominator',
163
+ scanned: files.length,
164
+ units: 'published markdown file(s)',
165
+ roots: [...SCAN_ROOTS],
166
+ });
167
+ } catch (err) {
168
+ if (err instanceof DeadScopeError) {
169
+ process.stderr.write(`❌ ${err.message}\n`);
170
+ return { code: 2, findings, scanned: files.length };
171
+ }
172
+ throw err;
173
+ }
174
+
175
+ try {
176
+ ledger.plan(files);
177
+ for (const rel of files) {
178
+ const text = fs.readFileSync(path.join(root, rel), 'utf-8');
179
+ if (isGenerated(text)) {
180
+ ledger.complete(rel);
181
+ continue;
182
+ }
183
+ const found = scanText(rel, text);
184
+ if (found.length > 0) {
185
+ findings.push(...found);
186
+ ledger.fail(rel, `${String(found.length)} hand-written enforcement count(s)`);
187
+ } else {
188
+ ledger.complete(rel);
189
+ }
190
+ }
191
+ } catch (err) {
192
+ if (err instanceof LedgerUsageError) {
193
+ process.stderr.write(`❌ ${err.message}\n`);
194
+ return { code: 2, findings, scanned: files.length };
195
+ }
196
+ throw err;
197
+ }
198
+ ledger.report();
199
+
200
+ return { code: findings.length > 0 ? 1 : 0, findings, scanned: files.length };
201
+ }
202
+
203
+ /* ------------------------------------------------------------------ *
204
+ * Self-test
205
+ * ------------------------------------------------------------------ */
206
+
207
+ function fixtureRoot(files: Record<string, string>): string {
208
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'enf-denom-'));
209
+ for (const [rel, body] of Object.entries(files)) {
210
+ const abs = path.join(dir, rel);
211
+ fs.mkdirSync(path.dirname(abs), { recursive: true });
212
+ fs.writeFileSync(abs, body);
213
+ }
214
+ return dir;
215
+ }
216
+
217
+ export function selfTest(): number {
218
+ const made: string[] = [];
219
+ const run = (files: Record<string, string>): number => {
220
+ const d = fixtureRoot(files);
221
+ made.push(d);
222
+ return runGateCli(DEFAULT_ROOT, SELF, ['--quiet', '--root', d], DEFAULT_ROOT);
223
+ };
224
+ const CLEAN = '# Docs\n\nNothing about counts here.\n';
225
+
226
+ const cases: SelfTestCase[] = [
227
+ {
228
+ name: 'rejects a hand-written "N of M governed rules … backstop" figure',
229
+ expect: 'reject',
230
+ run: () =>
231
+ run({
232
+ 'docs/a.md': '15 of 120 governed rules carry a backstop that fails a CI build.\n',
233
+ }),
234
+ },
235
+ {
236
+ name: 'rejects a hand-written undeclared count',
237
+ expect: 'reject',
238
+ run: () => run({ 'docs/a.md': 'Today 86 rules are undeclared.\n' }),
239
+ },
240
+ {
241
+ name: 'rejects the same figure in README.md',
242
+ expect: 'reject',
243
+ run: () => run({ 'README.md': '86 undeclared rules have no enforced_by.\n' }),
244
+ },
245
+ {
246
+ name: 'rejects a marker with no reason',
247
+ expect: 'reject',
248
+ run: () =>
249
+ run({
250
+ 'docs/a.md': `86 rules are undeclared. <!-- ${MARKER} -->\n`,
251
+ }),
252
+ },
253
+ {
254
+ name: 'accepts a marker carrying a reason',
255
+ expect: 'accept',
256
+ run: () =>
257
+ run({
258
+ 'docs/a.md': `86 rules are undeclared. <!-- ${MARKER} historical, dated in place -->\n`,
259
+ }),
260
+ },
261
+ {
262
+ name: "accepts the resolver's own generated projection",
263
+ expect: 'accept',
264
+ run: () =>
265
+ run({
266
+ 'docs/proof.md':
267
+ `<!-- ${GENERATED_MARKER} src/scripts/build_proof.ts -->\n\n` +
268
+ '120 rules · 15 blocking · 86 undeclared (no enforced_by yet).\n',
269
+ }),
270
+ },
271
+ {
272
+ name: 'accepts a dated ADR record (docs/decisions/ is excluded)',
273
+ expect: 'accept',
274
+ run: () =>
275
+ run({
276
+ 'docs/a.md': CLEAN,
277
+ 'docs/decisions/ADR-001-x.md': '86 rules were undeclared on 2026-08-12.\n',
278
+ }),
279
+ },
280
+ {
281
+ name: 'accepts a rule count with no enforcement sense ("2 rules" in a concepts page)',
282
+ expect: 'accept',
283
+ run: () => run({ 'docs/a.md': 'The kernel splits into 2 rules and a router.\n' }),
284
+ },
285
+ {
286
+ name: 'rejects a moved scan root rather than reporting clean (exit 2)',
287
+ expect: 'reject',
288
+ run: () =>
289
+ runGateCli(
290
+ DEFAULT_ROOT,
291
+ SELF,
292
+ ['--quiet', '--root', path.join(DEFAULT_ROOT, 'no-such-root')],
293
+ DEFAULT_ROOT,
294
+ ),
295
+ },
296
+ ];
297
+
298
+ try {
299
+ return runSelfTest({
300
+ gate: 'check_enforcement_denominator',
301
+ cases,
302
+ minCases: SELF_TEST_MIN_CASES,
303
+ minRejectCases: SELF_TEST_MIN_REJECT,
304
+ });
305
+ } finally {
306
+ for (const d of made) fs.rmSync(d, { recursive: true, force: true });
307
+ }
308
+ }
309
+
310
+ export function main(argv?: readonly string[]): number {
311
+ const args = argv ?? process.argv.slice(2);
312
+ if (args.includes('--self-test')) return selfTest();
313
+ const quiet = args.includes('--quiet');
314
+ const rootIdx = args.indexOf('--root');
315
+ const root = rootIdx >= 0 ? (args[rootIdx + 1] ?? DEFAULT_ROOT) : DEFAULT_ROOT;
316
+
317
+ const { code, findings, scanned } = check(root);
318
+ if (code === 2) return 2;
319
+
320
+ if (findings.length > 0) {
321
+ process.stdout.write('❌ hand-written enforcement count(s) in a published doc:\n\n');
322
+ for (const f of findings) {
323
+ const why =
324
+ f.kind === 'bare-marker' ? `\`${MARKER}\` with no reason` : 'hand-written count';
325
+ process.stdout.write(` ${f.file}:${String(f.line)} — ${why}\n ${f.excerpt}\n`);
326
+ }
327
+ process.stdout.write(
328
+ '\nExactly one enforcement denominator is quotable, and it comes from\n' +
329
+ '`check_enforcement_coverage` — which resolves rather than counts, and prints\n' +
330
+ 'its denominator with the frame that produced it. `docs/proof.md` § 4b projects\n' +
331
+ 'that output; cite the projection instead of restating a number. A figure that\n' +
332
+ 'is right today is how the plurality returned every previous time.\n' +
333
+ `If the number is a dated record rather than a live claim, say so on the line:\n` +
334
+ ` <!-- ${MARKER} <reason> -->\n`,
335
+ );
336
+ return 1;
337
+ }
338
+
339
+ if (!quiet) {
340
+ process.stdout.write(
341
+ `✅ one citable enforcement denominator: ${String(scanned)} published doc(s) restate none of it.\n`,
342
+ );
343
+ }
344
+ return 0;
345
+ }
346
+
347
+ function _isCliEntry(): boolean {
348
+ if (process.argv[1] === undefined) return false;
349
+ const argvUrl = pathToFileURL(path.resolve(process.argv[1])).href;
350
+ if (import.meta.url === argvUrl) return true;
351
+ try {
352
+ return (
353
+ fs.realpathSync(fileURLToPath(import.meta.url)) ===
354
+ fs.realpathSync(path.resolve(process.argv[1]))
355
+ );
356
+ } catch {
357
+ return false;
358
+ }
359
+ }
360
+
361
+ if (_isCliEntry() || process.argv[1] === _HERE) {
362
+ process.exit(main());
363
+ }
364
+
365
+ export { SCAN_ROOTS, EXCLUDED_PREFIXES, MARKER };
@@ -152,6 +152,7 @@ import { reportScanned, DeadScopeError } from './_lib/scan_scope.js';
152
152
  import { GateLedger } from './_lib/gate_ledger.js';
153
153
  import { resolveBaseRef } from './_lib/ratchet_base_ref.js';
154
154
  import { materialiseSubtree } from './_lib/base_tree.js';
155
+ import { SKILLS_POSIX, measureSkillEstate } from './_lib/skill_estate.js';
155
156
  import { runGateCli, runSelfTest, type SelfTestCase } from './_lib/gate_self_test.js';
156
157
 
157
158
  const GATE = 'check_estate_count';
@@ -171,11 +172,35 @@ export interface EstateCounts {
171
172
  active_roadmaps: number;
172
173
  later_roadmaps: number;
173
174
  open_blockers: number;
175
+ /**
176
+ * Maintained `SKILL.md` files — `lifecycle: deprecated` excluded.
177
+ *
178
+ * A FOURTH corpus on the same machinery, added 2026-08-24 on AI council 2/2
179
+ * over the alternative of a second budget file and a second gate: the
180
+ * floor-from-the-base-ref machinery is the expensive part and should not be
181
+ * written twice, and a second ratchet is a second place to forget.
182
+ */
183
+ skill_count: number;
184
+ /**
185
+ * Exact-BPE tokens across those skills' `description:` fields.
186
+ *
187
+ * The second DIMENSION, not a companion figure. A count ratchet alone is
188
+ * gameable by merging four large skills into one file: the count falls, the
189
+ * payload a host must carry does not. `0` here means UNRESOLVED, never
190
+ * "no tokens" — see `tokensExact`.
191
+ */
192
+ skill_description_tokens: number;
174
193
  }
175
194
 
176
195
  export type MetricName = keyof EstateCounts;
177
196
 
178
- export const METRICS: readonly MetricName[] = ['active_roadmaps', 'later_roadmaps', 'open_blockers'];
197
+ export const METRICS: readonly MetricName[] = [
198
+ 'active_roadmaps',
199
+ 'later_roadmaps',
200
+ 'open_blockers',
201
+ 'skill_count',
202
+ 'skill_description_tokens',
203
+ ];
179
204
 
180
205
  export interface EstateBudget {
181
206
  /**
@@ -247,6 +272,16 @@ export interface EstateVerdict {
247
272
  authorisedGrowth: GrowthFinding[];
248
273
  /** The claims found in this change's diff, with their reasons. */
249
274
  claims: GrowthClaim[];
275
+ /**
276
+ * Metrics dropped from the compare, each with its reason.
277
+ *
278
+ * Never empty-and-silent: a skill metric drops when the base ref carries no
279
+ * `src/skills` (an old tag, a shallow clone) or when the tokeniser resolved
280
+ * on one side and not the other. Comparing an exact reading against a proxy
281
+ * one would move the number by more than the growth this gate exists to
282
+ * catch, so the metric is stated unavailable rather than guessed.
283
+ */
284
+ skippedMetrics: { metric: MetricName; reason: string }[];
250
285
  /** `null` when the diff half could not run; the reason is printed either way. */
251
286
  offsets: OffsetLedger | null;
252
287
  offsetSkipReason: string | null;
@@ -342,13 +377,26 @@ export function countEstate(repoRoot: string): EstateCounts {
342
377
  const stats = collect(roadmapRoot);
343
378
  const openOf = (rows: readonly { open_blockers: readonly unknown[] }[]): number =>
344
379
  rows.reduce((n, r) => n + r.open_blockers.length, 0);
380
+ const skills = measureSkillEstate(repoRoot);
345
381
  return {
346
382
  active_roadmaps: stats.length,
347
383
  later_roadmaps: countIn(roadmapRoot, 'later'),
348
384
  open_blockers: openOf(stats) + openOf(laterRoadmaps(roadmapRoot)),
385
+ skill_count: skills.skill_count,
386
+ // 0 stands for unresolved. `skillTokensExact` below is what the caller
387
+ // reads to tell that apart from a genuinely empty corpus, and the
388
+ // verdict skips the metric rather than comparing an exact reading
389
+ // against a proxy one — they differ by more than the growth a ratchet
390
+ // is trying to catch.
391
+ skill_description_tokens: skills.skill_description_tokens ?? 0,
349
392
  };
350
393
  }
351
394
 
395
+ /** Did the tokeniser resolve under `root`? A ratchet must not mix the two modes. */
396
+ export function skillTokensExact(root: string): boolean {
397
+ return measureSkillEstate(root).skill_description_tokens !== null;
398
+ }
399
+
352
400
  /** `agents/roadmaps/<name>.md` — the active top level, never a subdirectory. */
353
401
  function isActiveTopLevel(rel: string): boolean {
354
402
  const norm = rel.split(path.sep).join('/');
@@ -506,19 +554,57 @@ export function evaluate(
506
554
  // property, and unlike a number nobody has to remember to update it.
507
555
  let floor: EstateCounts | null = null;
508
556
  let floorSkipReason: string | null = null;
557
+ /** Set when the base ref carries no `src/skills` — the skill metrics drop. */
558
+ let skillFloorSkipReason: string | null = null;
559
+ /** Set when either side's tokeniser did not resolve — that ONE metric drops. */
560
+ let skillTokenSkipReason: string | null = null;
561
+ if (!skillTokensExact(repoRoot)) {
562
+ skillTokenSkipReason =
563
+ 'the tokeniser did not resolve at HEAD; an exact reading may not be compared ' +
564
+ 'against a proxy one';
565
+ }
509
566
  if (baseRef === null || baseRef === undefined) {
510
567
  floorSkipReason =
511
568
  'no base ref resolved (no origin/main, no merge-commit parent) — the floor cannot be measured';
512
569
  } else {
513
570
  const base = materialiseSubtree(repoRoot, baseRef, ROADMAPS_POSIX);
571
+ // TWO subtrees, because the estate now spans two corpora and the floor
572
+ // must be measured on the base ref's own tree for BOTH. Materialised
573
+ // separately rather than widening the first call: `materialiseSubtree`
574
+ // takes one prefix, and the roadmap tree must stay readable even when
575
+ // the skills read fails (a `src/skills`-less base ref is a real state —
576
+ // an old tag, a shallow clone), in which case the skill metrics skip and
577
+ // the roadmap metrics still ratchet.
578
+ const baseSkills = materialiseSubtree(repoRoot, baseRef, SKILLS_POSIX);
514
579
  try {
515
580
  if (base.error !== null || base.files === 0) {
516
581
  floorSkipReason = `could not read ${ROADMAPS_POSIX} at ${baseRef} — ${base.error ?? 'no files'}`;
517
582
  } else {
518
- floor = countEstate(base.root);
583
+ const roadmapFloor = countEstate(base.root);
584
+ if (baseSkills.error !== null || baseSkills.files === 0) {
585
+ // Roadmap floor stands; the skill floor is stated as
586
+ // unavailable and its metrics are dropped from the compare.
587
+ floor = roadmapFloor;
588
+ skillFloorSkipReason =
589
+ `could not read ${SKILLS_POSIX} at ${baseRef} — ` +
590
+ `${baseSkills.error ?? 'no files'}`;
591
+ } else {
592
+ const s = measureSkillEstate(baseSkills.root);
593
+ floor = {
594
+ ...roadmapFloor,
595
+ skill_count: s.skill_count,
596
+ skill_description_tokens: s.skill_description_tokens ?? 0,
597
+ };
598
+ if (s.skill_description_tokens === null) {
599
+ skillTokenSkipReason =
600
+ `the tokeniser did not resolve at ${baseRef}; an exact reading may ` +
601
+ 'not be compared against a proxy one';
602
+ }
603
+ }
519
604
  }
520
605
  } finally {
521
606
  fs.rmSync(base.root, { recursive: true, force: true });
607
+ fs.rmSync(baseSkills.root, { recursive: true, force: true });
522
608
  }
523
609
  }
524
610
 
@@ -571,11 +657,32 @@ export function evaluate(
571
657
  active_roadmaps: offsets?.exempt.length ?? 0,
572
658
  later_roadmaps: offsets?.parked.length ?? 0,
573
659
  open_blockers: 0,
660
+ // The skill corpus gets NO allowance, and that is the whole point of the
661
+ // metric: the defect it addresses is a corpus that grew +8 in one release
662
+ // with nothing objecting. An addition takes the `estate_growth_exempt`
663
+ // claim path — a recorded reason in the diff — or it fails.
664
+ skill_count: 0,
665
+ skill_description_tokens: 0,
666
+ };
667
+
668
+ /** Metrics dropped from the compare, with the reason, never silently. */
669
+ const skippedMetrics: { metric: MetricName; reason: string }[] = [];
670
+ const skipMetric = (metric: MetricName): boolean => {
671
+ if (skillFloorSkipReason !== null && (metric === 'skill_count' || metric === 'skill_description_tokens')) {
672
+ skippedMetrics.push({ metric, reason: skillFloorSkipReason });
673
+ return true;
674
+ }
675
+ if (skillTokenSkipReason !== null && metric === 'skill_description_tokens') {
676
+ skippedMetrics.push({ metric, reason: skillTokenSkipReason });
677
+ return true;
678
+ }
679
+ return false;
574
680
  };
575
681
 
576
682
  const over: GrowthFinding[] = [];
577
683
  if (floor !== null) {
578
684
  for (const metric of METRICS) {
685
+ if (skipMetric(metric)) continue;
579
686
  const live = counts[metric];
580
687
  const allowed = floor[metric] + allowance[metric];
581
688
  if (live > allowed) {
@@ -596,6 +703,7 @@ export function evaluate(
596
703
  growth,
597
704
  authorisedGrowth,
598
705
  claims,
706
+ skippedMetrics,
599
707
  offsets,
600
708
  offsetSkipReason,
601
709
  unpaid,
@@ -1010,8 +1118,12 @@ export function main(argv: string[] = process.argv.slice(2)): number {
1010
1118
 
1011
1119
  for (const g of verdict.growth) {
1012
1120
  const allow = g.allowance > 0 ? ` (+${String(g.allowance)} allowed here)` : '';
1121
+ // Two corpora share this gate, so the line names which one grew. It used
1122
+ // to say "the roadmap estate" unconditionally, which was already the
1123
+ // wrong noun for `skill_count` the moment that metric landed.
1124
+ const corpus = g.metric.startsWith('skill_') ? 'the skill estate' : 'the roadmap estate';
1013
1125
  process.stderr.write(
1014
- `❌ the roadmap estate grew: ${g.metric} ${String(g.floor)} → ${String(g.live)}${allow}.\n` +
1126
+ `❌ ${corpus} grew: ${g.metric} ${String(g.floor)} → ${String(g.live)}${allow}.\n` +
1015
1127
  ` The floor is the measurement at ${verdict.floorRef ?? 'the base ref'}, not a number in a\n` +
1016
1128
  ' config — so there is no number to edit and nothing to walk. The estate does not\n' +
1017
1129
  ' walk down by itself, which is the defect this ratchet exists for. Either close,\n' +
@@ -1022,6 +1134,13 @@ export function main(argv: string[] = process.argv.slice(2)): number {
1022
1134
  );
1023
1135
  }
1024
1136
 
1137
+ // A dropped metric is REPORTED, never silent: a reader must be able to tell
1138
+ // "within its ratchet" from "within the ratchet of the metrics that could be
1139
+ // measured". This is the same distinction the floor-skip reason above keeps.
1140
+ for (const s of verdict.skippedMetrics) {
1141
+ process.stdout.write(` ⏭️ ${s.metric} not compared — ${s.reason}\n`);
1142
+ }
1143
+
1025
1144
  if (verdict.unpaid > 0 && verdict.offsets !== null) {
1026
1145
  process.stderr.write(
1027
1146
  `❌ ${String(verdict.unpaid)} new active roadmap(s) with no offset in the same change.\n` +
@@ -49,6 +49,7 @@ import process from 'node:process';
49
49
  import { fileURLToPath, pathToFileURL } from 'node:url';
50
50
 
51
51
  import * as yaml from 'js-yaml';
52
+ import { asOf } from './_lib/as_of.js';
52
53
  import { checkRatchet } from './_lib/gate_baseline.js';
53
54
  import { GateLedger, type GateSkipReason } from './_lib/gate_ledger.js';
54
55
  import { runCountedProbe } from './_lib/counted_probe.js';
@@ -979,7 +980,7 @@ function run_canary_mode(specs: readonly GateSpec[], argv: readonly string[]): n
979
980
  process.stdout.write(` ❌ DISAGREEMENT [${d.kind}] ${d.gate}: ${d.detail}\n`);
980
981
  }
981
982
 
982
- const cycleId = `gate-surface-${new Date().toISOString().slice(0, 10)}`;
983
+ const cycleId = `gate-surface-${asOf().toISOString().slice(0, 10)}`;
983
984
  const li = argv.indexOf('--ledger');
984
985
  if (li >= 0 && argv[li + 1] !== undefined) {
985
986
  const out = path.resolve(REPO_ROOT, argv[li + 1] as string);
@@ -28,6 +28,18 @@
28
28
  * A hook fix that cannot reach the agent that wrote it is indistinguishable
29
29
  * from no fix, and nothing said so. This gate says so.
30
30
  *
31
+ * WHAT IT DOES NOT DO — ORDERING IS NOT EQUIVALENCE. This gate compares
32
+ * mtimes, so `touch dist/hooks/dispatch.js` makes every source look older and
33
+ * this gate green while the executing bytes are stale. Demonstrated on this tree
34
+ * rather than argued (2026-08-23): a one-constant edit to
35
+ * `block_unauthorized_git.ts` plus a `touch` on the bundle left THIS gate at
36
+ * exit 0 while `check_hook_bundle_content` exited 1 with executing
37
+ * `sha256 ce21579b7c14` against rebuilt `ac83e2f51118` — identical byte count,
38
+ * different bytes. That is why the success line below says "ordering" and names
39
+ * the digest gate instead of claiming freshness outright, and why preflight runs
40
+ * the two together (`taskfiles/ci-fast.yml`). The content comparison is NOT
41
+ * duplicated here: one home per invariant.
42
+ *
31
43
  * WHAT IT DOES NOT DO: it never builds. Building into a live hook path is a
32
44
  * documented hazard in this repo (an esbuild run that overwrites the
33
45
  * dispatcher a running hook is executing can wedge the tool loop), so the
@@ -169,7 +181,7 @@ export function main(argv: string[] = process.argv.slice(2)): number {
169
181
  if (r.stale.length === 0) {
170
182
  if (!quiet) {
171
183
  process.stdout.write(
172
- `✅ OK hook bundle: fresh (built ${stamp(r.bundleMtimeMs)}, ${String(r.checked)} bundled source(s) checked)\n`,
184
+ `✅ OK hook bundle: ordering fresh (built ${stamp(r.bundleMtimeMs)}, ${String(r.checked)} bundled source(s) checked) — byte-equivalence is check_hook_bundle_content's\n`,
173
185
  );
174
186
  }
175
187
  return 0;
@@ -37,6 +37,7 @@ import { fileURLToPath, pathToFileURL } from 'node:url';
37
37
  // tolerantly (try/except → None) so the project-local linter still runs if the
38
38
  // _lib package layout shifts; the TS twins always exist, so a static import is
39
39
  // byte-faithful for behaviour (the only observable effect is the --global path).
40
+ import { asOf } from './_lib/as_of.js';
40
41
  import * as _kg from './_lib/knowledge_global.js';
41
42
  import * as _kgr from './_lib/knowledge_global_redaction.js';
42
43
  import { assertScanned } from './_lib/scan_scope.js';
@@ -485,7 +486,7 @@ function _maxDate(parsed: PyDate[]): PyDate {
485
486
  }
486
487
 
487
488
  function _todayUtcDate(): PyDate {
488
- const now = new Date();
489
+ const now = asOf();
489
490
  return { year: now.getUTCFullYear(), month: now.getUTCMonth() + 1, day: now.getUTCDate() };
490
491
  }
491
492
 
@@ -29,6 +29,7 @@ import process from 'node:process';
29
29
  import { fileURLToPath } from 'node:url';
30
30
  import YAML from 'yaml';
31
31
 
32
+ import { asOf } from './_lib/as_of.js';
32
33
  import { assertScanned } from './_lib/scan_scope.js';
33
34
 
34
35
  const PROG = 'check_knowledge_pages.ts';
@@ -72,7 +73,7 @@ function bodyLineCount(body: string): number {
72
73
  }
73
74
 
74
75
  /** Lint a single page's already-read content. Pure — no filesystem access — for direct unit testing. */
75
- export function lintPage(relPath: string, content: string, today: Date = new Date()): Warning[] {
76
+ export function lintPage(relPath: string, content: string, today: Date = asOf()): Warning[] {
76
77
  const warnings: Warning[] = [];
77
78
  const fm = readFrontmatter(content);
78
79
 
@@ -145,7 +146,7 @@ function countPages(knowledgeRoot: string): number {
145
146
  );
146
147
  }
147
148
 
148
- export function lintAll(knowledgeRoot: string, today: Date = new Date()): Warning[] {
149
+ export function lintAll(knowledgeRoot: string, today: Date = asOf()): Warning[] {
149
150
  const warnings: Warning[] = [];
150
151
  for (const dir of TYPED_DIRS) {
151
152
  const scanDir = path.join(knowledgeRoot, dir);