@event4u/agent-config 14.9.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 (426) 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 +384 -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/async-python-patterns/SKILL.md +1 -1
  45. package/dist/agent-src/skills/authz-review/SKILL.md +0 -1
  46. package/dist/agent-src/skills/blast-radius-analyzer/SKILL.md +32 -0
  47. package/dist/agent-src/skills/brand/SKILL.md +3 -0
  48. package/dist/agent-src/skills/brand-asset-generation/SKILL.md +3 -0
  49. package/dist/agent-src/skills/brand-audit/SKILL.md +3 -0
  50. package/dist/agent-src/skills/brand-identity/SKILL.md +3 -0
  51. package/dist/agent-src/skills/brand-strategy/SKILL.md +3 -0
  52. package/dist/agent-src/skills/brand-to-tokens/SKILL.md +3 -0
  53. package/dist/agent-src/skills/check-refs/SKILL.md +3 -0
  54. package/dist/agent-src/skills/code-refactoring/SKILL.md +1 -1
  55. package/dist/agent-src/skills/code-review/SKILL.md +11 -0
  56. package/dist/agent-src/skills/command-routing/SKILL.md +6 -0
  57. package/dist/agent-src/skills/condense-memory/SKILL.md +4 -1
  58. package/dist/agent-src/skills/context-authoring/SKILL.md +1 -1
  59. package/dist/agent-src/skills/conventional-commits-writing/SKILL.md +4 -1
  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 +80 -2
  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/discovery-interview/SKILL.md +1 -1
  73. package/dist/agent-src/skills/doc-coauthoring/SKILL.md +1 -1
  74. package/dist/agent-src/skills/docx-authoring/SKILL.md +1 -1
  75. package/dist/agent-src/skills/editorial-calendar/SKILL.md +1 -1
  76. package/dist/agent-src/skills/estimate-ticket/SKILL.md +3 -0
  77. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +20 -3
  78. package/dist/agent-src/skills/fe-design/SKILL.md +74 -41
  79. package/dist/agent-src/skills/fe-design/evals/triggers.json +65 -53
  80. package/dist/agent-src/skills/fe-design/references/craft-floor.md +52 -0
  81. package/dist/agent-src/skills/fe-design/references/source-led-port.md +36 -0
  82. package/dist/agent-src/skills/file-editor/SKILL.md +5 -0
  83. package/dist/agent-src/skills/finishing-a-development-branch/SKILL.md +2 -2
  84. package/dist/agent-src/skills/git-workflow/SKILL.md +3 -0
  85. package/dist/agent-src/skills/github-ci/SKILL.md +1 -1
  86. package/dist/agent-src/skills/html-deck/SKILL.md +3 -0
  87. package/dist/agent-src/skills/iconography/SKILL.md +3 -0
  88. package/dist/agent-src/skills/image-editing/SKILL.md +3 -0
  89. package/dist/agent-src/skills/image-generation/SKILL.md +3 -0
  90. package/dist/agent-src/skills/image-provider-routing/SKILL.md +3 -0
  91. package/dist/agent-src/skills/incident-commander/SKILL.md +10 -0
  92. package/dist/agent-src/skills/js-library-packaging/SKILL.md +173 -0
  93. package/dist/agent-src/skills/js-library-packaging/evals/triggers.json +17 -0
  94. package/dist/agent-src/skills/js-library-packaging/scripts/check_package_surface.ts +270 -0
  95. package/dist/agent-src/skills/judge-artifact-completeness/SKILL.md +1 -1
  96. package/dist/agent-src/skills/judge-injection-defense/SKILL.md +1 -1
  97. package/dist/agent-src/skills/laravel-migration/SKILL.md +3 -0
  98. package/dist/agent-src/skills/laravel-validation/SKILL.md +1 -1
  99. package/dist/agent-src/skills/learning-to-rule-or-skill/SKILL.md +3 -0
  100. package/dist/agent-src/skills/legal-intake-triage/SKILL.md +1 -1
  101. package/dist/agent-src/skills/legal-practice-profile/SKILL.md +1 -1
  102. package/dist/agent-src/skills/lint-skills/SKILL.md +3 -0
  103. package/dist/agent-src/skills/llm-provider-knowledge/SKILL.md +3 -0
  104. package/dist/agent-src/skills/logging-monitoring/SKILL.md +234 -51
  105. package/dist/agent-src/skills/logo-generation/SKILL.md +3 -0
  106. package/dist/agent-src/skills/md-language-check/SKILL.md +3 -0
  107. package/dist/agent-src/skills/messaging-architecture/SKILL.md +1 -1
  108. package/dist/agent-src/skills/migration-architect/SKILL.md +1 -1
  109. package/dist/agent-src/skills/module-detect-on-the-fly/SKILL.md +1 -1
  110. package/dist/agent-src/skills/module-management/SKILL.md +1 -1
  111. package/dist/agent-src/skills/monorepo-workspace/SKILL.md +149 -0
  112. package/dist/agent-src/skills/monorepo-workspace/evals/triggers.json +17 -0
  113. package/dist/agent-src/skills/motion-choreographer/SKILL.md +7 -1
  114. package/dist/agent-src/skills/multi-tenancy/SKILL.md +4 -0
  115. package/dist/agent-src/skills/onboarding-program/SKILL.md +1 -1
  116. package/dist/agent-src/skills/operational-readiness/SKILL.md +184 -0
  117. package/dist/agent-src/skills/operational-readiness/evals/triggers.json +17 -0
  118. package/dist/agent-src/skills/override-management/SKILL.md +3 -0
  119. package/dist/agent-src/skills/perf-feedback-craft/SKILL.md +1 -1
  120. package/dist/agent-src/skills/persona-improvement/SKILL.md +3 -0
  121. package/dist/agent-src/skills/pest-testing/SKILL.md +3 -0
  122. package/dist/agent-src/skills/playbook-authoring/SKILL.md +162 -0
  123. package/dist/agent-src/skills/playwright-testing/SKILL.md +3 -0
  124. package/dist/agent-src/skills/privacy-review/SKILL.md +3 -0
  125. package/dist/agent-src/skills/prompt-engineering-image/SKILL.md +3 -0
  126. package/dist/agent-src/skills/prompt-optimizer/SKILL.md +1 -1
  127. package/dist/agent-src/skills/quality-tools/SKILL.md +5 -0
  128. package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +52 -21
  129. package/dist/agent-src/skills/readme-reviewer/SKILL.md +3 -0
  130. package/dist/agent-src/skills/readme-writing/SKILL.md +3 -0
  131. package/dist/agent-src/skills/readme-writing-package/SKILL.md +3 -0
  132. package/dist/agent-src/skills/receiving-code-review/SKILL.md +3 -3
  133. package/dist/agent-src/skills/refine-prompt/SKILL.md +3 -0
  134. package/dist/agent-src/skills/refine-ticket/SKILL.md +3 -0
  135. package/dist/agent-src/skills/requesting-code-review/SKILL.md +2 -2
  136. package/dist/agent-src/skills/review-routing/SKILL.md +2 -2
  137. package/dist/agent-src/skills/roadmap-writing/SKILL.md +23 -41
  138. package/dist/agent-src/skills/roadmap-writing/references/follow-up-roadmap-shape.md +47 -0
  139. package/dist/agent-src/skills/rtk-output-filtering/SKILL.md +22 -6
  140. package/dist/agent-src/skills/runway-cognition/SKILL.md +3 -0
  141. package/dist/agent-src/skills/scene-expander/SKILL.md +1 -1
  142. package/dist/agent-src/skills/scene-expander/scene-blueprint.schema.yaml +26 -0
  143. package/dist/agent-src/skills/secrets-management/SKILL.md +5 -1
  144. package/dist/agent-src/skills/server-hardening/SKILL.md +159 -0
  145. package/dist/agent-src/skills/server-hardening/evals/triggers.json +17 -0
  146. package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +3 -0
  147. package/dist/agent-src/skills/skill-management/SKILL.md +3 -0
  148. package/dist/agent-src/skills/skill-reviewer/SKILL.md +3 -0
  149. package/dist/agent-src/skills/skill-writing/SKILL.md +6 -0
  150. package/dist/agent-src/skills/spreadsheet-authoring/SKILL.md +3 -0
  151. package/dist/agent-src/skills/storybook-workshop/SKILL.md +194 -0
  152. package/dist/agent-src/skills/storybook-workshop/evals/triggers.json +17 -0
  153. package/dist/agent-src/skills/storybook-workshop/scripts/story_contrast_floor.ts +134 -0
  154. package/dist/agent-src/skills/subagent-orchestration/SKILL.md +1 -1
  155. package/dist/agent-src/skills/subagent-orchestration/prompts/README.md +25 -0
  156. package/dist/agent-src/skills/supply-chain-intake/SKILL.md +12 -0
  157. package/dist/agent-src/skills/systematic-debugging/SKILL.md +1 -1
  158. package/dist/agent-src/skills/terraform/SKILL.md +3 -0
  159. package/dist/agent-src/skills/test-driven-development/SKILL.md +1 -1
  160. package/dist/agent-src/skills/threat-modeling/SKILL.md +0 -3
  161. package/dist/agent-src/skills/token-optimizer/SKILL.md +3 -0
  162. package/dist/agent-src/skills/typography-system/SKILL.md +3 -0
  163. package/dist/agent-src/skills/ui-component-architect/SKILL.md +9 -1
  164. package/dist/agent-src/skills/upstream-contribute/SKILL.md +3 -0
  165. package/dist/agent-src/skills/using-git-worktrees/SKILL.md +1 -1
  166. package/dist/agent-src/skills/validate-feature-fit/SKILL.md +3 -0
  167. package/dist/agent-src/skills/verify-completion-evidence/SKILL.md +2 -2
  168. package/dist/agent-src/skills/wireframe/SKILL.md +3 -0
  169. package/dist/agent-src/skills/wireframe/references/story-beat-ledger.schema.json +115 -0
  170. package/dist/agent-src/skills/workspace-link/SKILL.md +131 -0
  171. package/dist/agent-src/skills/workspace-link/evals/triggers.json +17 -0
  172. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  173. package/dist/agent-src/templates/playbook.md +75 -0
  174. package/dist/agent-src/templates/roadmaps.md +37 -0
  175. package/dist/agent-src/templates/scripts/check_playbook_invokes.ts +231 -0
  176. package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +24 -0
  177. package/dist/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +2 -0
  178. package/dist/agent-src/templates/scripts/work_engine/directives/ui/review.ts +216 -0
  179. package/dist/agent-src/templates/scripts/work_engine/directives/ui/scaffold.ts +159 -0
  180. package/dist/agent-src/templates/scripts/work_engine/directives/ui/stack_bundles.ts +73 -4
  181. package/dist/agent-src/templates/scripts/work_engine/stack/detect.ts +325 -40
  182. package/dist/cli/commands/uiAudit.js +221 -0
  183. package/dist/cli/commands/uiAudit.js.map +1 -0
  184. package/dist/cli/commands/uiRender.js +206 -0
  185. package/dist/cli/commands/uiRender.js.map +1 -0
  186. package/dist/cli/main.js +22 -1
  187. package/dist/cli/main.js.map +1 -1
  188. package/dist/cli/mcp/content.js +64 -1
  189. package/dist/cli/mcp/content.js.map +1 -1
  190. package/dist/cli/mcp/dispatch.js +175 -10
  191. package/dist/cli/mcp/dispatch.js.map +1 -1
  192. package/dist/cli/registry.js +3 -0
  193. package/dist/cli/registry.js.map +1 -1
  194. package/dist/cli-delegate/{chunk-H4VIVD4C.js → chunk-236PNQZK.js} +413 -391
  195. package/dist/cli-delegate/{chunk-G23AT6GD.js → chunk-DMSZHXZS.js} +57 -1
  196. package/dist/cli-delegate/{chunk-77GR3VD4.js → chunk-FF7WAFMR.js} +58 -3
  197. package/dist/cli-delegate/{chunk-PLSG6UL5.js → chunk-K4FFODTS.js} +341 -204
  198. package/dist/cli-delegate/{chunk-YM4GZDJG.js → chunk-L43NCYPB.js} +5 -0
  199. package/dist/cli-delegate/{chunk-B2ERU2VA.js → chunk-WOKWX5PL.js} +1 -1
  200. package/dist/cli-delegate/cmd_brand_status.js +8 -6
  201. package/dist/cli-delegate/cmd_conformance.js +3 -3
  202. package/dist/cli-delegate/cmd_doctor.js +3 -3
  203. package/dist/cli-delegate/cmd_export.js +4 -4
  204. package/dist/cli-delegate/cmd_handoff.js +1 -1
  205. package/dist/cli-delegate/cmd_preflight.js +2 -2
  206. package/dist/cli-delegate/cmd_prune.js +4 -4
  207. package/dist/cli-delegate/cmd_session_recycle.js +70 -9
  208. package/dist/cli-delegate/cmd_settings_migrate.js +4 -4
  209. package/dist/cli-delegate/cmd_settings_set.js +1 -1
  210. package/dist/cli-delegate/cmd_sync.js +4 -4
  211. package/dist/cli-delegate/cmd_uninstall.js +4 -4
  212. package/dist/cli-delegate/cmd_validate.js +4 -4
  213. package/dist/discovery/deprecation-report.md +1 -1
  214. package/dist/discovery/discovery-manifest.json +380 -145
  215. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  216. package/dist/discovery/discovery-manifest.summary.md +4 -4
  217. package/dist/discovery/dormancy-report.md +1 -1
  218. package/dist/discovery/orphan-report.md +1 -1
  219. package/dist/discovery/packs.json +18 -8
  220. package/dist/discovery/trust-report.md +3 -3
  221. package/dist/discovery/workspaces.json +16 -6
  222. package/dist/hooks/dispatch.js +2337 -1436
  223. package/dist/install/install.mjs +795 -708
  224. package/dist/mcp/registry-manifest.json +3 -3
  225. package/dist/mcp/server.json +2 -2
  226. package/dist/mcp/server.mjs +1685 -1250
  227. package/dist/router.json +1 -1
  228. package/dist/scripts/_lib/lean_projection_mode.js +40 -0
  229. package/dist/scripts/_lib/lean_projection_mode.js.map +1 -0
  230. package/dist/scripts/_lib/scoped_projection.js +84 -0
  231. package/dist/scripts/_lib/scoped_projection.js.map +1 -1
  232. package/dist/scripts/_lib/ui_surface.js +89 -0
  233. package/dist/scripts/_lib/ui_surface.js.map +1 -0
  234. package/dist/scripts/condense.js +6 -10
  235. package/dist/scripts/condense.js.map +1 -1
  236. package/dist/scripts/project_thin_rules.js +40 -2
  237. package/dist/scripts/project_thin_rules.js.map +1 -1
  238. package/dist/server/schemas/settings.js +3 -0
  239. package/dist/server/schemas/settings.js.map +1 -1
  240. package/dist/shared/skillRanking.js +159 -0
  241. package/dist/shared/skillRanking.js.map +1 -0
  242. package/docs/contracts/provider-lifecycle.md +47 -18
  243. package/docs/contracts/settings-classes.md +14 -4
  244. package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +49 -0
  245. package/docs/guidelines/agent-infra/evaluator-independence-mechanics.md +92 -0
  246. package/docs/guidelines/agent-infra/minimal-safe-diff-mechanics.md +45 -1
  247. package/docs/guidelines/agent-infra/roadmap-deferred-resolution-provenance.md +54 -0
  248. package/docs/guidelines/design-antipatterns.md +4 -2
  249. package/docs/guidelines/design-asset-discipline.md +38 -0
  250. package/docs/guidelines/design-fidelity-mechanics.md +45 -29
  251. package/docs/guidelines/design-handover-extraction.md +35 -5
  252. package/docs/guidelines/design-modes.md +41 -1
  253. package/docs/guidelines/monorepo-antipatterns.md +141 -0
  254. package/llms.txt +50 -39
  255. package/package.json +1 -1
  256. package/src/agent-src/templates/scripts/check_playbook_invokes.ts +231 -0
  257. package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +24 -0
  258. package/src/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +2 -0
  259. package/src/agent-src/templates/scripts/work_engine/directives/ui/review.ts +216 -0
  260. package/src/agent-src/templates/scripts/work_engine/directives/ui/scaffold.ts +159 -0
  261. package/src/agent-src/templates/scripts/work_engine/directives/ui/stack_bundles.ts +73 -4
  262. package/src/agent-src/templates/scripts/work_engine/stack/detect.ts +325 -40
  263. package/src/config/agent-settings.template.yml +28 -0
  264. package/src/config/assurance-capability-registry.json +223 -0
  265. package/src/config/assurance-threshold-budget.json +65 -0
  266. package/src/config/ci-local-parity.yml +14 -0
  267. package/src/config/discovery/unassigned-artefacts.yml +2 -0
  268. package/src/config/dispatch-economy-metrics.json +4 -2
  269. package/src/config/evaluator-budgets.json +14 -14
  270. package/src/config/gate-coverage.yml +227 -8
  271. package/src/config/gate-violation-baselines.json +76 -72
  272. package/src/config/hook-latency-budget.json +1 -0
  273. package/src/config/hook-token-budget.json +137 -125
  274. package/src/config/pack-size-budget.json +4 -2
  275. package/src/config/preamble-payload-budget.json +71 -67
  276. package/src/config/quorum-attendance-budget.json +12 -4
  277. package/src/config/rule-activation-census.json +7 -3
  278. package/src/config/rule-enforcement-baseline.json +0 -1
  279. package/src/config/rule-stub-ceilings.json +112 -91
  280. package/src/scripts/_cli/cmd_doctor.ts +15 -16
  281. package/src/scripts/_cli/doctor_install_mode.ts +49 -0
  282. package/src/scripts/_cli/doctor_overrides.ts +154 -0
  283. package/src/scripts/_dispatch.bash +17 -0
  284. package/src/scripts/_lib/as_of.ts +412 -0
  285. package/src/scripts/_lib/exec_evidence.ts +7 -0
  286. package/src/scripts/_lib/hook_settings.ts +33 -0
  287. package/src/scripts/_lib/host_listing_model.ts +192 -0
  288. package/src/scripts/_lib/lean_projection_mode.ts +44 -0
  289. package/src/scripts/_lib/mcp_bridge.ts +199 -0
  290. package/src/scripts/_lib/review_independence.ts +62 -10
  291. package/src/scripts/_lib/rule_injection.ts +239 -0
  292. package/src/scripts/_lib/run_checkpoint.ts +54 -1
  293. package/src/scripts/_lib/scoped_projection.ts +96 -0
  294. package/src/scripts/_lib/session_register.ts +44 -2
  295. package/src/scripts/_lib/skill_catalogue.ts +38 -2
  296. package/src/scripts/_lib/transcript_reads.ts +207 -0
  297. package/src/scripts/_lib/ui_authority.test.ts +251 -0
  298. package/src/scripts/_lib/ui_authority.ts +343 -0
  299. package/src/scripts/ai-video/adapters/fal.sh +8 -3
  300. package/src/scripts/ai-video/adapters/gemini-veo.sh +10 -0
  301. package/src/scripts/ai-video/adapters/higgsfield.sh +10 -2
  302. package/src/scripts/ai-video/adapters/kling.sh +10 -0
  303. package/src/scripts/ai-video/adapters/sora.sh +10 -0
  304. package/src/scripts/ai-video/lib/calibrate-cost.sh +145 -0
  305. package/src/scripts/ai-video/lib/model-capabilities/README.md +53 -7
  306. package/src/scripts/ai-video/lib/model-capabilities/comfyui.json +15 -3
  307. package/src/scripts/ai-video/lib/model-capabilities/fal.json +36 -6
  308. package/src/scripts/ai-video/lib/model-capabilities/gemini-veo.json +23 -0
  309. package/src/scripts/ai-video/lib/model-capabilities/higgsfield.json +23 -0
  310. package/src/scripts/ai-video/lib/model-capabilities/kling.json +23 -0
  311. package/src/scripts/ai-video/lib/model-capabilities/musetalk.json +8 -2
  312. package/src/scripts/ai-video/lib/model-capabilities/replicate.json +36 -6
  313. package/src/scripts/ai-video/lib/model-capabilities/sora.json +45 -0
  314. package/src/scripts/ai-video/lib/model-capabilities/syncso.json +8 -2
  315. package/src/scripts/ai-video/lib/parse-blueprint.sh +52 -5
  316. package/src/scripts/ai-video/lib/resume-scan.sh +92 -3
  317. package/src/scripts/ai-video/lib/seam-plan.sh +212 -0
  318. package/src/scripts/ai-video/smoke-trace.sh +450 -2
  319. package/src/scripts/ai-video/stitch.sh +191 -10
  320. package/src/scripts/ai-video/test-pipeline.sh +84 -6
  321. package/src/scripts/ai_council/cli_agency_bounds.ts +139 -0
  322. package/src/scripts/ai_council/cli_least_agency_canary.ts +347 -0
  323. package/src/scripts/ai_council/clients.ts +3 -2
  324. package/src/scripts/ai_council/consensus.ts +63 -6
  325. package/src/scripts/ai_council/events_log.ts +46 -1
  326. package/src/scripts/ai_council/orchestrator.ts +103 -108
  327. package/src/scripts/ai_council/orchestrator_results.ts +166 -0
  328. package/src/scripts/ai_council/prompts.ts +12 -5
  329. package/src/scripts/ai_council/quorum.ts +82 -1
  330. package/src/scripts/ai_council/quorum_wiring.ts +82 -5
  331. package/src/scripts/ai_council/seating.ts +211 -0
  332. package/src/scripts/ai_council/stance_tally.ts +22 -0
  333. package/src/scripts/bench_hook_latency.ts +62 -0
  334. package/src/scripts/build_proof.ts +12 -1
  335. package/src/scripts/capture_skill_catalogue.ts +21 -0
  336. package/src/scripts/check_always_budget.ts +2 -1
  337. package/src/scripts/check_augmentignore.ts +2 -1
  338. package/src/scripts/check_beta_review_markers.ts +2 -1
  339. package/src/scripts/check_composite_arming.ts +364 -0
  340. package/src/scripts/check_corpus_staleness.ts +2 -1
  341. package/src/scripts/check_council_pin_staleness.ts +3 -1
  342. package/src/scripts/check_enforcement_coverage.ts +116 -3
  343. package/src/scripts/check_enforcement_denominator.ts +365 -0
  344. package/src/scripts/check_gate_coverage.ts +2 -1
  345. package/src/scripts/check_hook_bundle_freshness.ts +13 -1
  346. package/src/scripts/check_knowledge_cards.ts +2 -1
  347. package/src/scripts/check_knowledge_pages.ts +3 -2
  348. package/src/scripts/check_memory.ts +2 -1
  349. package/src/scripts/check_no_automerge_key.ts +287 -0
  350. package/src/scripts/check_pack_conformance_fixture.ts +565 -0
  351. package/src/scripts/check_pack_passport_reconciliation.ts +274 -0
  352. package/src/scripts/check_proposal.ts +2 -1
  353. package/src/scripts/check_reach_staleness.ts +2 -1
  354. package/src/scripts/check_release_adjacent_health.ts +2 -1
  355. package/src/scripts/check_release_pr_shape.ts +5 -0
  356. package/src/scripts/check_review_schema.ts +34 -1
  357. package/src/scripts/check_roadmap_trackable.ts +48 -3
  358. package/src/scripts/check_source_size_budget.ts +2 -1
  359. package/src/scripts/check_standing_payload_delta.ts +505 -0
  360. package/src/scripts/check_trigger_evals.ts +2 -1
  361. package/src/scripts/classify_change_risk.ts +281 -0
  362. package/src/scripts/compute_skill_tiers.ts +186 -0
  363. package/src/scripts/condense.ts +8 -13
  364. package/src/scripts/council_attendance_metrics.ts +183 -0
  365. package/src/scripts/council_cli.ts +10 -8
  366. package/src/scripts/council_parse_rate.ts +116 -0
  367. package/src/scripts/derive_playbooks.ts +406 -0
  368. package/src/scripts/design_slop_rules.test.ts +7 -0
  369. package/src/scripts/design_slop_rules.ts +56 -2
  370. package/src/scripts/dispatch_r2_reviewer.ts +16 -0
  371. package/src/scripts/frontend_corpus_hash.ts +116 -0
  372. package/src/scripts/generate_pack_manifests.ts +78 -0
  373. package/src/scripts/grade_target_readiness.ts +478 -0
  374. package/src/scripts/hook_manifest.json +1 -1
  375. package/src/scripts/hook_manifest.yaml +97 -16
  376. package/src/scripts/hooks/concern_registry.ts +4 -0
  377. package/src/scripts/hooks/design_pass_hook.ts +356 -0
  378. package/src/scripts/hooks/rtk_wrap_hook.ts +30 -7
  379. package/src/scripts/hooks/rule_inject_hook.ts +318 -0
  380. package/src/scripts/hot_context_hook.ts +74 -7
  381. package/src/scripts/install.ts +40 -89
  382. package/src/scripts/lint_adapter_tier.ts +663 -0
  383. package/src/scripts/lint_archived_skills.ts +93 -0
  384. package/src/scripts/lint_budget_ownership.ts +2 -1
  385. package/src/scripts/lint_deterministic_time.ts +470 -0
  386. package/src/scripts/lint_framework_leakage.ts +5 -0
  387. package/src/scripts/lint_handoffs.ts +525 -1
  388. package/src/scripts/lint_judge_prompt_expectation.ts +155 -0
  389. package/src/scripts/lint_marketplace.ts +88 -0
  390. package/src/scripts/lint_media_policy_linkage.ts +140 -1
  391. package/src/scripts/lint_one_off_age.ts +6 -1
  392. package/src/scripts/lint_override_kernel_guard.ts +87 -5
  393. package/src/scripts/lint_roadmap_complexity.ts +56 -0
  394. package/src/scripts/lint_rule_enforcement_declaration.ts +24 -7
  395. package/src/scripts/lint_rule_norm_pin.ts +321 -0
  396. package/src/scripts/lint_spawn_payload.ts +42 -5
  397. package/src/scripts/lint_symptom_intake.ts +2 -1
  398. package/src/scripts/mcp_parity_smoke.ts +30 -4
  399. package/src/scripts/mcp_render.ts +66 -1
  400. package/src/scripts/mcp_tool_fingerprint.ts +241 -0
  401. package/src/scripts/measure_risk_class_drift.ts +140 -0
  402. package/src/scripts/measure_skill_ranker_baseline.ts +212 -0
  403. package/src/scripts/media/lib/adapter-common.sh +211 -1
  404. package/src/scripts/media/lib/adapter-contract.md +74 -6
  405. package/src/scripts/model_rule_injection.ts +907 -0
  406. package/src/scripts/project_thin_rules.ts +45 -2
  407. package/src/scripts/release.ts +66 -860
  408. package/src/scripts/release_drill.ts +59 -3
  409. package/src/scripts/release_env.ts +298 -0
  410. package/src/scripts/release_publication.ts +720 -0
  411. package/src/scripts/roadmap_context.ts +778 -0
  412. package/src/scripts/schemas/fidelity-measurement-sheet.schema.json +169 -0
  413. package/src/scripts/schemas/pack.schema.json +62 -4
  414. package/src/scripts/schemas/rule.schema.json +24 -2
  415. package/src/scripts/schemas/skill.schema.json +41 -2
  416. package/src/scripts/schemas/ui-authority.schema.json +114 -0
  417. package/src/scripts/session_register_hook.ts +29 -3
  418. package/src/scripts/sessions_cli.ts +67 -3
  419. package/src/scripts/skill_tools/score_skill_relevance.ts +36 -53
  420. package/src/scripts/tighten_skill_descriptions.ts +264 -0
  421. package/src/scripts/token_sink_report.ts +239 -0
  422. package/src/scripts/trigger_coverage.ts +122 -3
  423. package/src/scripts/update_counts.ts +7 -3
  424. package/src/scripts/validate_frontmatter.ts +66 -0
  425. package/src/server/schemas/settings.ts +5 -0
  426. package/src/shared/skillRanking.ts +183 -0
@@ -0,0 +1,281 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * Deterministic risk class for a change, computed from paths and diff shape.
4
+ *
5
+ * Step 0.3 of `road-to-target-project-assurance-readiness`. **No model call**, by
6
+ * construction: the whole point is a class an agent cannot talk itself out of, and
7
+ * a classifier that asks a model is the agent's self-label wearing a script's
8
+ * clothes.
9
+ *
10
+ * Classes: `R0` cosmetic · `R1` internal · `R2` behaviour-changing · `R3` critical.
11
+ *
12
+ * TIES AND UNKNOWNS RESOLVE UPWARD. That is safe per change and corrosive in
13
+ * aggregate — once most changes read R3 the owed gate set is noise and gets worked
14
+ * around rather than met (Risk 2 of the roadmap). The mitigation is NOT to soften
15
+ * the resolution: it is the nightly R3-rate metric, with **> 40 % of changes
16
+ * classifying R3 named as a defect in the override list** rather than in the people
17
+ * meeting the gates. So this file resolves upward and the drift ledger is what
18
+ * catches an over-broad override list.
19
+ *
20
+ * SELF-PROTECTION. Changes to this classifier, the override list, the hook
21
+ * directories, CI workflows, or the agent's own config are R3 **by construction** —
22
+ * the one place the system can defend itself against being talked down. It is a
23
+ * deliberate refusal to be configurable: an override list that can be lowered by a
24
+ * change the list itself classifies as cosmetic protects nothing.
25
+ *
26
+ * WHAT THIS DOES NOT DO, and it is the reason the roadmap closed on a null: nothing
27
+ * consumes this class. Wiring it into `verify-completion-evidence` is Phase 2, and
28
+ * Phase 2 is cancelled on the pre-registered null route because the human-labelled
29
+ * corpus the class would have been validated against cannot be produced. Giving an
30
+ * unvalidated class real authority over every completion claim is Risk 7. So this
31
+ * ships as a **measurement instrument feeding the nightly drift ledger**, and its
32
+ * verdict owes no gate.
33
+ */
34
+ import { spawnSync } from 'node:child_process';
35
+ import * as path from 'node:path';
36
+ import process from 'node:process';
37
+ import { fileURLToPath } from 'node:url';
38
+
39
+ import { runGateCli, runSelfTest } from './_lib/gate_self_test.js';
40
+
41
+ const _HERE = fileURLToPath(import.meta.url);
42
+ const REPO_ROOT = path.resolve(path.dirname(_HERE), '..', '..');
43
+
44
+ export type RiskClass = 'R0' | 'R1' | 'R2' | 'R3';
45
+
46
+ const ORDER: readonly RiskClass[] = ['R0', 'R1', 'R2', 'R3'];
47
+
48
+ /** Upward resolution, expressed once so no caller can pick the other direction. */
49
+ export function higher(a: RiskClass, b: RiskClass): RiskClass {
50
+ return ORDER.indexOf(a) >= ORDER.indexOf(b) ? a : b;
51
+ }
52
+
53
+ /**
54
+ * Paths whose touch is R3 regardless of anything else.
55
+ *
56
+ * Two groups, and they are listed together because they fail the same way when
57
+ * split: a reviewer reading only one of them cannot tell whether a path is missing
58
+ * on purpose.
59
+ *
60
+ * (1) DOMAIN-CRITICAL — auth, migrations, payment, billing, IaC. These are the
61
+ * surfaces where a wrong class costs money or exposes data.
62
+ * (2) SELF-PROTECTION — this file, the assurance policy, hook directories, CI
63
+ * workflows, and the agent's own settings. Without these the classifier is
64
+ * one cosmetic-looking commit away from classifying itself down.
65
+ */
66
+ export const R3_PATH_PATTERNS: readonly RegExp[] = [
67
+ // (1) domain-critical
68
+ /(^|\/)auth(\/|$)/i,
69
+ /(^|\/)migrations?(\/|$)/i,
70
+ /payment/i,
71
+ /billing/i,
72
+ /(^|\/)(terraform|terragrunt)(\/|$)/i,
73
+ /\.tf$/i,
74
+ /(^|\/)k8s(\/|$)/i,
75
+ /(^|\/)helm(\/|$)/i,
76
+ // (2) self-protection
77
+ /(^|\/)classify_change_risk\.ts$/,
78
+ /(^|\/)assurance-policy\.json$/,
79
+ /(^|\/)\.github\/workflows\//,
80
+ /(^|\/)hooks?\//,
81
+ /(^|\/)hook_manifest\.(yaml|json)$/,
82
+ /(^|\/)\.agent-settings\.ya?ml$/,
83
+ /(^|\/)agent-settings[^/]*\.ya?ml$/,
84
+ /(^|\/)src\/config\//,
85
+ ];
86
+
87
+ /** Dependency manifests and lockfiles — a supply-chain surface, so at least R2. */
88
+ export const DEPENDENCY_PATTERNS: readonly RegExp[] = [
89
+ /(^|\/)package(-lock)?\.json$/,
90
+ /(^|\/)pnpm-lock\.yaml$/,
91
+ /(^|\/)yarn\.lock$/,
92
+ /(^|\/)composer\.(json|lock)$/,
93
+ /(^|\/)(requirements[^/]*\.txt|pyproject\.toml|poetry\.lock|Pipfile(\.lock)?)$/,
94
+ /(^|\/)go\.(mod|sum)$/,
95
+ /(^|\/)Cargo\.(toml|lock)$/,
96
+ ];
97
+
98
+ /**
99
+ * Paths that carry no behaviour.
100
+ *
101
+ * A change touching ONLY these is R0. Deliberately narrow — markdown, licences,
102
+ * editor config, images. `.json` is NOT here: a JSON file is as likely to be a
103
+ * policy as a fixture, and guessing wrong resolves downward, which is the one
104
+ * direction this classifier may not guess in.
105
+ */
106
+ export const COSMETIC_PATTERNS: readonly RegExp[] = [
107
+ /\.(md|markdown|txt|rst|adoc)$/i,
108
+ /\.(png|jpe?g|gif|svg|webp|ico)$/i,
109
+ /(^|\/)(LICENSE|NOTICE|CODEOWNERS|\.gitignore|\.editorconfig|\.gitattributes)$/,
110
+ ];
111
+
112
+ /** Source extensions whose edit can change behaviour. */
113
+ const CODE_RE = /\.(ts|tsx|js|jsx|mjs|cjs|py|php|go|rs|rb|java|kt|swift|sh|bash)$/i;
114
+
115
+ /** Test paths — code, but an edit confined to them is internal by default. */
116
+ const TEST_RE = /(^|\/)(tests?|__tests__|spec)(\/|$)|\.(test|spec)\.[a-z]+$/i;
117
+
118
+ export interface Classification {
119
+ readonly cls: RiskClass;
120
+ /** The single reason that BOUND the class — never a list of contributors. */
121
+ readonly reason: string;
122
+ }
123
+
124
+ /**
125
+ * Classify a change from its touched paths.
126
+ *
127
+ * Reports the reason that BOUND the class, not every reason that applied, for the
128
+ * same argument the readiness matrix makes about its binding dimension: a list of
129
+ * contributing factors invites averaging, and the class is a max rather than a mean.
130
+ */
131
+ export function classifyPaths(paths: readonly string[]): Classification {
132
+ if (paths.length === 0) {
133
+ // An empty diff is UNKNOWN, not cosmetic. Upward resolution applies to the
134
+ // absence of evidence exactly as it applies to ambiguous evidence — and a
135
+ // caller passing no paths has not told us the change is empty, only that it
136
+ // did not say.
137
+ return { cls: 'R3', reason: 'no paths supplied — unknown resolves upward' };
138
+ }
139
+ const norm = paths.map((p) => p.replace(/^\.\//, ''));
140
+
141
+ for (const p of norm) {
142
+ for (const re of R3_PATH_PATTERNS) {
143
+ if (re.test(p)) return { cls: 'R3', reason: `override-list path: ${p}` };
144
+ }
145
+ }
146
+ for (const p of norm) {
147
+ for (const re of DEPENDENCY_PATTERNS) {
148
+ if (re.test(p)) return { cls: 'R2', reason: `dependency manifest: ${p}` };
149
+ }
150
+ }
151
+ if (norm.every((p) => COSMETIC_PATTERNS.some((re) => re.test(p)))) {
152
+ return { cls: 'R0', reason: 'every touched path is non-behavioural' };
153
+ }
154
+ const nonTestCode = norm.filter((p) => CODE_RE.test(p) && !TEST_RE.test(p));
155
+ if (nonTestCode.length > 0) {
156
+ return { cls: 'R2', reason: `production code touched: ${nonTestCode[0]!}` };
157
+ }
158
+ if (norm.some((p) => TEST_RE.test(p))) {
159
+ return { cls: 'R1', reason: 'test-only change' };
160
+ }
161
+ // Reached only by a path that is neither cosmetic, nor code, nor a test, nor on
162
+ // a list — a config or data file the patterns above do not name. Upward.
163
+ return { cls: 'R2', reason: `unrecognised path shape: ${norm[0]!}` };
164
+ }
165
+
166
+ /** `git diff --name-only <range>` — the only git call this script makes. */
167
+ export function changedPaths(range: string, cwd = REPO_ROOT): string[] {
168
+ const r = spawnSync('git', ['diff', '--name-only', range], {
169
+ cwd,
170
+ encoding: 'utf-8',
171
+ maxBuffer: 64 * 1024 * 1024,
172
+ });
173
+ if (r.status !== 0) return [];
174
+ return (r.stdout || '')
175
+ .split('\n')
176
+ .map((l) => l.trim())
177
+ .filter((l) => l !== '');
178
+ }
179
+
180
+ function selfTest(): number {
181
+ const rel = 'src/scripts/classify_change_risk.ts';
182
+ const run = (args: readonly string[]): number => runGateCli(REPO_ROOT, rel, args, REPO_ROOT);
183
+ return runSelfTest({
184
+ gate: 'classify_change_risk',
185
+ minCases: 6,
186
+ minRejectCases: 2,
187
+ cases: [
188
+ {
189
+ // 2.3's property, as far as it can be proven without Phase 2's
190
+ // policy file: an edit to the classifier itself is R3.
191
+ name: 'the classifier classifies an edit to ITSELF as R3',
192
+ expect: 'accept',
193
+ run: () => run(['--paths', rel, '--assert-class', 'R3']),
194
+ },
195
+ {
196
+ name: 'a CI workflow edit is R3',
197
+ expect: 'accept',
198
+ run: () => run(['--paths', '.github/workflows/tests.yml', '--assert-class', 'R3']),
199
+ },
200
+ {
201
+ name: 'a docs-only change is R0',
202
+ expect: 'accept',
203
+ run: () => run(['--paths', 'README.md', '--assert-class', 'R0']),
204
+ },
205
+ {
206
+ name: 'a test-only change is R1',
207
+ expect: 'accept',
208
+ run: () => run(['--paths', 'tests/scripts/x.test.ts', '--assert-class', 'R1']),
209
+ },
210
+ {
211
+ // The reject arms matter more than the accept arms: a suite that
212
+ // only proves passes proves the harness runs, not that the
213
+ // classifier discriminates.
214
+ name: 'asserting R0 for a migrations path is refused',
215
+ expect: 'reject',
216
+ run: () => run(['--paths', 'db/migrations/001.sql', '--assert-class', 'R0']),
217
+ },
218
+ {
219
+ name: 'asserting R1 for production code is refused',
220
+ expect: 'reject',
221
+ run: () => run(['--paths', 'src/scripts/release.ts', '--assert-class', 'R1']),
222
+ },
223
+ {
224
+ name: 'asserting R0 for an empty path set is refused (unknown resolves upward)',
225
+ expect: 'reject',
226
+ run: () => run(['--paths', '', '--assert-class', 'R0']),
227
+ },
228
+ ],
229
+ });
230
+ }
231
+
232
+ export function main(argv: readonly string[]): number {
233
+ if (argv.includes('--self-test')) {
234
+ if (process.env['GATE_SELF_TEST_CHILD'] === '1') {
235
+ process.stderr.write('classify_change_risk: refusing to recurse into --self-test\n');
236
+ return 1;
237
+ }
238
+ return selfTest();
239
+ }
240
+ const pathsIdx = argv.indexOf('--paths');
241
+ const rangeIdx = argv.indexOf('--range');
242
+ const assertIdx = argv.indexOf('--assert-class');
243
+ const json = argv.includes('--json');
244
+
245
+ let paths: string[];
246
+ if (pathsIdx >= 0) {
247
+ paths = (argv[pathsIdx + 1] ?? '')
248
+ .split(',')
249
+ .map((s) => s.trim())
250
+ .filter((s) => s !== '');
251
+ } else {
252
+ paths = changedPaths(rangeIdx >= 0 ? (argv[rangeIdx + 1] ?? 'HEAD~1...HEAD') : 'HEAD~1...HEAD');
253
+ }
254
+
255
+ const v = classifyPaths(paths);
256
+ if (json) {
257
+ process.stdout.write(
258
+ JSON.stringify({ class: v.cls, reason: v.reason, files: paths.length }) + '\n',
259
+ );
260
+ } else {
261
+ process.stdout.write(`${v.cls} — ${v.reason} (${String(paths.length)} file(s))\n`);
262
+ }
263
+
264
+ if (assertIdx >= 0) {
265
+ const want = argv[assertIdx + 1];
266
+ if (want !== v.cls) {
267
+ process.stderr.write(`classify_change_risk: expected ${String(want)}, got ${v.cls}\n`);
268
+ return 1;
269
+ }
270
+ }
271
+ return 0;
272
+ }
273
+
274
+ function _isCliEntry(): boolean {
275
+ const invoked = process.argv[1];
276
+ return invoked !== undefined && path.resolve(invoked) === path.resolve(_HERE);
277
+ }
278
+
279
+ if (_isCliEntry()) {
280
+ process.exit(main(process.argv.slice(2)));
281
+ }
@@ -0,0 +1,186 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * compute_skill_tiers — which skills the host will describe, and which it won't.
4
+ *
5
+ * Phase 2.1 of `road-to-skill-delivery-over-mcp`. Tier A is the set predicted to
6
+ * survive the host's listing budget; Tier B is everything else, which reaches
7
+ * the model only through the turnkey server's `suggest_skill_for_task` /
8
+ * `read_skill`.
9
+ *
10
+ * THE OUTPUT'S REAL JOB IS `model_inputs`, not the split. A tier assignment
11
+ * without the order that produced it is unexplainable and unreproducible, and
12
+ * risk 5 of the roadmap is precisely that a skill flips tiers between installs
13
+ * and nobody can tell why. So every run records the context window, the
14
+ * fraction, the per-entry cap, how many usage rows it actually had, and which
15
+ * fallback it used when it had none.
16
+ *
17
+ * IT WILL USUALLY BE A FALLBACK. `agents/runtime/metrics/skill-usage.jsonl` was
18
+ * last written 2026-05-16 and does not exist in a fresh checkout, so the
19
+ * honest common case is `fallback: "alphabetical"` — and the pinned observation
20
+ * in `tests/scripts/host_listing_model.test.ts` shows that fallback disagreeing
21
+ * with the one real host observation on four of eight sampled entries. A Tier B
22
+ * verdict from a fallback order is therefore a PREDICTION, not a measurement.
23
+ * The `tiered` projection stays opt-in for exactly that reason.
24
+ *
25
+ * Output goes to `agents/runtime/state/skill-tiers.json` (gitignored, per-machine).
26
+ */
27
+
28
+ import * as fs from 'node:fs';
29
+ import * as path from 'node:path';
30
+ import { fileURLToPath } from 'node:url';
31
+
32
+ import {
33
+ CLAUDE_CODE_LISTING_DEFAULTS,
34
+ modelListingBudget,
35
+ type CatalogueEntry,
36
+ type ModelAssumption,
37
+ } from './_lib/host_listing_model.js';
38
+
39
+ const _HERE = fileURLToPath(import.meta.url);
40
+ export const REPO = path.resolve(path.dirname(_HERE), '..', '..');
41
+ export const DEFAULT_SKILLS_DIR = path.join(REPO, 'src', 'skills');
42
+ export const USAGE_PATH = path.join(REPO, 'agents', 'runtime', 'metrics', 'skill-usage.jsonl');
43
+ export const TIERS_PATH = path.join(REPO, 'agents', 'runtime', 'state', 'skill-tiers.json');
44
+
45
+ export type Fallback = 'alphabetical' | 'pack-scope' | null;
46
+
47
+ export interface ModelInputs {
48
+ context_window_tokens: number;
49
+ fraction: number;
50
+ per_entry_cap_chars: number;
51
+ chars_per_token: number;
52
+ budget_chars: number;
53
+ usage_rows_used: number;
54
+ fallback: Fallback;
55
+ fill_order: string;
56
+ }
57
+
58
+ export interface TierSplit {
59
+ schema: 1;
60
+ computed_at: string;
61
+ skills_dir: string;
62
+ catalogue_count: number;
63
+ model_inputs: ModelInputs;
64
+ model_assumptions: readonly ModelAssumption[];
65
+ tier_a: string[];
66
+ tier_b: string[];
67
+ }
68
+
69
+ /** `description:` length in characters, or 0 when the file carries none. */
70
+ function descriptionChars(file: string): number {
71
+ const raw = fs.readFileSync(file, 'utf8');
72
+ const fm = /^---\n([\s\S]*?)\n---/.exec(raw);
73
+ if (!fm) return 0;
74
+ const line = /^description:[ \t]*(.*)$/m.exec(fm[1]!);
75
+ if (!line) return 0;
76
+ return line[1]!.replace(/^["']|["']$/g, '').length;
77
+ }
78
+
79
+ /** The projected catalogue, alphabetically. Missing dir → empty, never a throw. */
80
+ export function readCatalogue(skillsDir: string): CatalogueEntry[] {
81
+ if (!fs.existsSync(skillsDir)) return [];
82
+ return fs
83
+ .readdirSync(skillsDir)
84
+ .filter((slug) => fs.existsSync(path.join(skillsDir, slug, 'SKILL.md')))
85
+ .map((slug) => ({
86
+ name: slug,
87
+ descriptionChars: descriptionChars(path.join(skillsDir, slug, 'SKILL.md')),
88
+ }))
89
+ .sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
90
+ }
91
+
92
+ /**
93
+ * Invocation-frequency order from the usage ledger, most-invoked first.
94
+ *
95
+ * A malformed line is skipped rather than fatal: the ledger is appended by a
96
+ * collector reading host session files, and one bad line must not turn the whole
97
+ * order into a silent empty — which would look identical to "no usage yet" and
98
+ * send every skill to Tier B.
99
+ */
100
+ export function usageOrderFrom(usagePath: string = USAGE_PATH): string[] {
101
+ if (!fs.existsSync(usagePath)) return [];
102
+ const counts = new Map<string, number>();
103
+ for (const line of fs.readFileSync(usagePath, 'utf8').split('\n')) {
104
+ const trimmed = line.trim();
105
+ if (!trimmed) continue;
106
+ let rec: unknown;
107
+ try {
108
+ rec = JSON.parse(trimmed);
109
+ } catch {
110
+ continue;
111
+ }
112
+ if (!rec || typeof rec !== 'object') continue;
113
+ const slug = (rec as Record<string, unknown>).slug;
114
+ if (typeof slug !== 'string' || !slug) continue;
115
+ counts.set(slug, (counts.get(slug) ?? 0) + 1);
116
+ }
117
+ return [...counts.entries()]
118
+ .sort((a, b) => b[1] - a[1] || (a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0))
119
+ .map(([slug]) => slug);
120
+ }
121
+
122
+ export interface ComputeOptions {
123
+ skillsDir?: string;
124
+ /** Explicit order; omit to read the ledger. */
125
+ usageOrder?: readonly string[];
126
+ contextWindowTokens?: number;
127
+ fraction?: number;
128
+ }
129
+
130
+ export function computeTiers(opts: ComputeOptions = {}): TierSplit {
131
+ const skillsDir = opts.skillsDir ?? DEFAULT_SKILLS_DIR;
132
+ const catalogue = readCatalogue(skillsDir);
133
+ const usageOrder = opts.usageOrder ?? usageOrderFrom();
134
+ const contextWindowTokens = opts.contextWindowTokens ?? 200_000;
135
+ const fraction = opts.fraction ?? CLAUDE_CODE_LISTING_DEFAULTS.fraction;
136
+
137
+ const result = modelListingBudget(catalogue, { contextWindowTokens, fraction, usageOrder });
138
+
139
+ return {
140
+ schema: 1,
141
+ computed_at: new Date().toISOString().slice(0, 10),
142
+ skills_dir: skillsDir,
143
+ catalogue_count: catalogue.length,
144
+ model_inputs: {
145
+ context_window_tokens: contextWindowTokens,
146
+ fraction,
147
+ per_entry_cap_chars: CLAUDE_CODE_LISTING_DEFAULTS.perEntryCapChars,
148
+ chars_per_token: CLAUDE_CODE_LISTING_DEFAULTS.charsPerToken,
149
+ budget_chars: result.budgetChars,
150
+ usage_rows_used: usageOrder.length,
151
+ // `pack-scope` is reserved for the day a pack-ordered fallback is
152
+ // wired; today the only fallback that exists is alphabetical, and
153
+ // naming a fallback that never runs would be worse than naming none.
154
+ fallback: usageOrder.length > 0 ? null : 'alphabetical',
155
+ fill_order: result.fillOrder,
156
+ },
157
+ model_assumptions: result.assumptions,
158
+ tier_a: result.surviving,
159
+ tier_b: result.bare,
160
+ };
161
+ }
162
+
163
+ export function main(argv: readonly string[] = process.argv.slice(2)): number {
164
+ const dirIdx = argv.indexOf('--skills-dir');
165
+ const skillsDir = dirIdx >= 0 ? argv[dirIdx + 1] : undefined;
166
+ const split = computeTiers(skillsDir === undefined ? {} : { skillsDir });
167
+ if (argv.includes('--json')) {
168
+ process.stdout.write(`${JSON.stringify(split, null, 2)}\n`);
169
+ return 0;
170
+ }
171
+ fs.mkdirSync(path.dirname(TIERS_PATH), { recursive: true });
172
+ fs.writeFileSync(TIERS_PATH, `${JSON.stringify(split, null, 2)}\n`, 'utf8');
173
+ process.stdout.write(
174
+ `✅ skill tiers → ${path.relative(REPO, TIERS_PATH)}\n` +
175
+ ` Tier A ${split.tier_a.length} · Tier B ${split.tier_b.length} ` +
176
+ `of ${split.catalogue_count}\n` +
177
+ ` order: ${split.model_inputs.fill_order}` +
178
+ `${split.model_inputs.fallback ? ` (fallback: ${split.model_inputs.fallback})` : ''}, ` +
179
+ `${split.model_inputs.usage_rows_used} usage row(s)\n`,
180
+ );
181
+ return 0;
182
+ }
183
+
184
+ if (process.argv[1] && fileURLToPath(import.meta.url) === path.resolve(process.argv[1])) {
185
+ process.exit(main());
186
+ }
@@ -48,6 +48,7 @@ import {
48
48
  // bundled-CLI-entry-guard landmine. Verified before wiring, not assumed.
49
49
  import { build_thin } from './project_thin_rules.js';
50
50
  import { build_claude_hook_matrix } from './_lib/claude_settings_hooks.js';
51
+ import { normalizeLeanProjectionMode, writesThinFiles, type LeanProjectionMode } from './_lib/lean_projection_mode.js';
51
52
  import { is_claude_builtin_name } from './_lib/claude_builtin_names.js';
52
53
  import { project_settings_path, load_agent_settings } from './_lib/agent_settings.js';
53
54
  import { rule_is_compile_enabled } from './_lib/compile_time_toggles.js';
@@ -458,20 +459,14 @@ function _read_projection_scope_dedup(): boolean {
458
459
  }
459
460
 
460
461
 
461
- function _lean_projection_mode(): string {
462
+ function _lean_projection_mode(): LeanProjectionMode {
462
463
  const data = load_agent_settings({ project_path: MODULE_STATE.SETTINGS_FILE });
463
464
  const lean = data['lean_projection'];
464
- if (
465
- typeof lean === 'object' &&
466
- lean !== null &&
467
- !Array.isArray(lean) &&
468
- String((lean as Record<string, unknown>)['mode'] ?? '')
469
- .trim()
470
- .toLowerCase() === 'thin'
471
- ) {
472
- return 'thin';
473
- }
474
- return 'eager-all';
465
+ const raw =
466
+ typeof lean === 'object' && lean !== null && !Array.isArray(lean)
467
+ ? (lean as Record<string, unknown>)['mode']
468
+ : '';
469
+ return normalizeLeanProjectionMode(raw);
475
470
  }
476
471
 
477
472
  // --- hashing -----------------------------------------------------------------
@@ -1126,7 +1121,7 @@ export function generate_rule_symlinks(): number {
1126
1121
  const tool_dirs = _filter_tool_dirs(TOOL_DIRS);
1127
1122
 
1128
1123
  let thin_files: Record<string, string> | null = null;
1129
- if (_lean_projection_mode() === 'thin') {
1124
+ if (writesThinFiles(_lean_projection_mode())) {
1130
1125
  // DEAD-SWITCH REPAIR (road-to-renewal-foundation Phase 2). This branch
1131
1126
  // used to THROW: the port was skipped as "out of scope, not exercised by
1132
1127
  // golden parity", which left a documented, settings-selectable mode that