@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,251 @@
1
+ /**
2
+ * A1.1-A1.5 behaviour, pinned against the frontend corpus fixtures.
3
+ *
4
+ * Every case name here is a real directory under `tests/eval/frontend-corpus/`,
5
+ * authored and hashed BEFORE this resolver existed (`34f7dc400`). That ordering
6
+ * is the point: the fixtures state what the right answer is, and the resolver is
7
+ * scored against them rather than the reverse.
8
+ */
9
+ import { describe, expect, it } from 'vitest';
10
+
11
+ import {
12
+ DEFAULTS,
13
+ OPERATIONS,
14
+ PRESERVE_DELTA_DIMENSIONS,
15
+ degrade,
16
+ operationConflicts,
17
+ preserveViolations,
18
+ resolveUiAuthority,
19
+ type Signals,
20
+ } from './ui_authority.js';
21
+
22
+ describe('A1.1 — one object, fully populated', () => {
23
+ it('always emits every required field', () => {
24
+ const a = resolveUiAuthority();
25
+ for (const k of [
26
+ 'surface_mode',
27
+ 'register',
28
+ 'change_intent',
29
+ 'reference_maturity',
30
+ 'primary_source',
31
+ 'constraints',
32
+ 'conflicts',
33
+ 'provenance',
34
+ 'verification',
35
+ ]) {
36
+ expect(a).toHaveProperty(k);
37
+ }
38
+ expect(a.verification).toBe('verified');
39
+ });
40
+
41
+ it('records provenance for every resolved field, so a wrong answer is traceable', () => {
42
+ const a = resolveUiAuthority({ brief: { register: 'brand', path: 'brief.md' } });
43
+ expect(a.provenance.map((p) => p.field)).toEqual(
44
+ expect.arrayContaining(['surface_mode', 'register', 'change_intent', 'reference_maturity']),
45
+ );
46
+ expect(a.provenance.find((p) => p.field === 'register')).toMatchObject({
47
+ source: 'surface-brief',
48
+ detail: 'brief.md',
49
+ });
50
+ });
51
+
52
+ it('carries fidelity_mandate rather than deriving one', () => {
53
+ expect(resolveUiAuthority({ fidelity_mandate: 'phase-0-output' }).fidelity_mandate).toBe('phase-0-output');
54
+ expect(resolveUiAuthority().fidelity_mandate).toBeNull();
55
+ });
56
+ });
57
+
58
+ describe('A1.2 — explicit user authority wins; quoted text does not', () => {
59
+ it('cases/explicit-redesign: the user’s change_intent beats every inference', () => {
60
+ const a = resolveUiAuthority({
61
+ user: { change_intent: 'redesign', register: 'brand', surface_mode: 'persuade' },
62
+ incumbent: { coherent: true },
63
+ });
64
+ expect(a.change_intent).toBe('redesign');
65
+ expect(a.provenance.find((p) => p.field === 'change_intent')?.source).toBe('user-instruction');
66
+ });
67
+
68
+ it('quoted text inside a supplied document is data, not authorisation', () => {
69
+ const quoted: Signals = {
70
+ user: { change_intent: 'redesign', register: 'brand', quoted: true },
71
+ incumbent: { coherent: true },
72
+ };
73
+ const a = resolveUiAuthority(quoted);
74
+ // The incumbent wins, exactly as if the quoted directive were absent.
75
+ expect(a.change_intent).toBe('extend');
76
+ expect(a.provenance.find((p) => p.field === 'change_intent')?.source).toBe('incumbent-scan');
77
+ });
78
+
79
+ it('a registered hard constraint outranks a user release', () => {
80
+ const a = resolveUiAuthority({
81
+ user: { change_intent: 'redesign' },
82
+ hard_constraints: ['preserve_palette'],
83
+ });
84
+ expect(a.constraints.preserve_palette).toBe(true);
85
+ });
86
+ });
87
+
88
+ describe('A1.3 — a missing DESIGN.md is not new-world', () => {
89
+ it('cases/no-design-md-coherent-incumbent resolves extend with incumbent authority', () => {
90
+ const a = resolveUiAuthority({
91
+ incumbent: { coherent: true, type_families: ['ibm plex sans'] },
92
+ design_md: { present: false },
93
+ });
94
+ expect(a.change_intent).toBe('extend');
95
+ expect(a.primary_source.kind).toBe('incumbent');
96
+ // The provenance assertion is load-bearing, not decoration. `extend` is
97
+ // ALSO the declared default, so a value-only assertion cannot tell
98
+ // "resolved from the coherent incumbent" from "fell through to the
99
+ // default". A sabotage probe that disabled the A1.3 branch left this
100
+ // test green until the source was asserted.
101
+ expect(a.provenance.find((p) => p.field === 'change_intent')).toMatchObject({
102
+ source: 'incumbent-scan',
103
+ detail: expect.stringContaining('A1.3'),
104
+ });
105
+ });
106
+
107
+ it('cases/greenfield — genuinely empty resolves new-world', () => {
108
+ expect(resolveUiAuthority({ design_md: { present: false } }).change_intent).toBe('new-world');
109
+ });
110
+
111
+ it('an incoherent incumbent falls to the declared default, not to new-world', () => {
112
+ const a = resolveUiAuthority({ incumbent: { coherent: false } });
113
+ expect(a.change_intent).toBe(DEFAULTS.change_intent);
114
+ expect(a.change_intent).not.toBe('new-world');
115
+ // Same discriminator in the other direction: this one MUST read
116
+ // `default`, so the pair separates the two paths that both yield
117
+ // `extend`.
118
+ expect(a.provenance.find((p) => p.field === 'change_intent')?.source).toBe('default');
119
+ });
120
+ });
121
+
122
+ describe('A1.4 / A2.1 — surface-local stays local', () => {
123
+ it('near-miss/surface-mode-not-product-mode: the brief outranks PRODUCT.md', () => {
124
+ const a = resolveUiAuthority({
125
+ brief: { surface_mode: 'persuade', register: 'brand', path: 'brief.md' },
126
+ product_md: { present: true, register: 'product' },
127
+ incumbent: { coherent: true },
128
+ });
129
+ expect(a.surface_mode).toBe('persuade');
130
+ expect(a.register).toBe('brand');
131
+ expect(a.provenance.find((p) => p.field === 'register')?.source).toBe('surface-brief');
132
+ });
133
+
134
+ it('PRODUCT.md never supplies surface_mode — only the brief or the user does', () => {
135
+ const a = resolveUiAuthority({ product_md: { present: true, register: 'product' } });
136
+ expect(a.provenance.find((p) => p.field === 'surface_mode')?.source).toBe('default');
137
+ });
138
+ });
139
+
140
+ describe('A1.5 — the intent-aware gate, against the pre-registered threshold', () => {
141
+ const incumbent = {
142
+ palette: ['#16181d', '#ffffff', '#5b616b', '#e3e5e9'],
143
+ type_families: ['newsreader', 'inter'],
144
+ };
145
+
146
+ it('near-miss/refine-preserves-world: a palette delta under preserve blocks', () => {
147
+ const a = resolveUiAuthority({ user: { change_intent: 'preserve' }, incumbent: { coherent: true } });
148
+ const v = preserveViolations(a, incumbent, { palette: ['#16181d', '#ff6a3d'], type_families: ['newsreader'] });
149
+ expect(v).toHaveLength(1);
150
+ expect(v[0]).toContain('palette');
151
+ expect(v[0]).toContain('#ff6a3d');
152
+ });
153
+
154
+ it('a type-family delta under preserve blocks', () => {
155
+ const a = resolveUiAuthority({ user: { change_intent: 'preserve' } });
156
+ const v = preserveViolations(a, incumbent, { palette: [], type_families: ['fraunces'] });
157
+ expect(v).toHaveLength(1);
158
+ expect(v[0]).toContain('type_family');
159
+ });
160
+
161
+ it('near-miss/refine-preserves-world: spacing-only refinement does NOT block', () => {
162
+ // The whole point of the verb. Spacing, rhythm, weight and size are
163
+ // outside the threshold, so a refine that touches only those passes.
164
+ const a = resolveUiAuthority({ user: { change_intent: 'preserve' }, incumbent: { coherent: true } });
165
+ expect(preserveViolations(a, incumbent, incumbent)).toEqual([]);
166
+ });
167
+
168
+ it('cases/explicit-redesign: the same delta under redesign does NOT block', () => {
169
+ const a = resolveUiAuthority({ user: { change_intent: 'redesign' } });
170
+ expect(preserveViolations(a, incumbent, { palette: ['#ff6a3d'], type_families: ['fraunces'] })).toEqual([]);
171
+ });
172
+
173
+ it('transparent / currentColor / inherit are never a palette delta', () => {
174
+ const a = resolveUiAuthority({ user: { change_intent: 'preserve' } });
175
+ expect(
176
+ preserveViolations(a, incumbent, {
177
+ palette: ['transparent', 'currentColor', 'inherit'],
178
+ type_families: [],
179
+ }),
180
+ ).toEqual([]);
181
+ });
182
+
183
+ it('the threshold covers exactly the two pre-registered dimensions', () => {
184
+ expect([...PRESERVE_DELTA_DIMENSIONS]).toEqual(['palette', 'type_family']);
185
+ });
186
+ });
187
+
188
+ describe('A4.1 — six operations as one field, with a conflict path', () => {
189
+ it('exposes exactly the six the step names', () => {
190
+ expect(Object.keys(OPERATIONS).sort()).toEqual([
191
+ 'bolder',
192
+ 'clarify',
193
+ 'distill',
194
+ 'harden',
195
+ 'polish',
196
+ 'quieter',
197
+ ]);
198
+ });
199
+
200
+ it('bolder under preserve surfaces a conflict instead of mutating', () => {
201
+ const a = resolveUiAuthority({ user: { change_intent: 'preserve' } });
202
+ const c = operationConflicts(a, 'bolder');
203
+ expect(c.length).toBeGreaterThan(0);
204
+ expect(c.map((x) => x.dimension).sort()).toEqual(['palette', 'type_family']);
205
+ expect(c[0]!.blocked_by).toMatch(/^preserve_/);
206
+ });
207
+
208
+ it('polish under preserve is clean — it touches no locked dimension', () => {
209
+ const a = resolveUiAuthority({ user: { change_intent: 'preserve' } });
210
+ expect(operationConflicts(a, 'polish')).toEqual([]);
211
+ });
212
+
213
+ it('bolder under redesign is clean', () => {
214
+ expect(operationConflicts(resolveUiAuthority({ user: { change_intent: 'redesign' } }), 'bolder')).toEqual([]);
215
+ });
216
+ });
217
+
218
+ describe('graft 2 — a pass that could not run says so', () => {
219
+ it('degrade carries a reason', () => {
220
+ const d = degrade(resolveUiAuthority(), 'render artefact absent');
221
+ expect(d.verification).toBe('degraded');
222
+ expect(d.degradation_reason).toBe('render artefact absent');
223
+ });
224
+
225
+ it('refuses a reason-free degrade by construction', () => {
226
+ expect(() => degrade(resolveUiAuthority(), ' ')).toThrow(/non-empty degradation_reason/);
227
+ });
228
+
229
+ it('supports unverified as a distinct state', () => {
230
+ expect(degrade(resolveUiAuthority(), 'no host capability', 'unverified').verification).toBe('unverified');
231
+ });
232
+ });
233
+
234
+ describe('reference maturity — the wireframe trap', () => {
235
+ it('cases/wireframe: a wireframe is recorded as structure, never as a pixel mandate', () => {
236
+ const a = resolveUiAuthority({ reference: { maturity: 'wireframe', path: 'wireframe.md' } });
237
+ expect(a.reference_maturity).toBe('wireframe');
238
+ // `brief`, not `comp`: a wireframe does not become the visual source.
239
+ expect(a.primary_source.kind).toBe('brief');
240
+ });
241
+
242
+ it('cases/supplied-runnable-html: a runnable artifact IS the source', () => {
243
+ const a = resolveUiAuthority({ reference: { maturity: 'runnable-artifact', path: 'design.html' } });
244
+ expect(a.primary_source).toStrictEqual({ kind: 'artifact', path: 'design.html' });
245
+ });
246
+
247
+ it('cases/supplied-finished-comp: a comp is translated, not adopted as code', () => {
248
+ const a = resolveUiAuthority({ reference: { maturity: 'finished-comp', path: 'HANDOVER.md' } });
249
+ expect(a.primary_source.kind).toBe('comp');
250
+ });
251
+ });
@@ -0,0 +1,343 @@
1
+ /**
2
+ * ui_authority — the ONE resolver for a UI surface's authority object.
3
+ *
4
+ * Contract: `docs/contracts/ui-authority.md`. Schema:
5
+ * `src/scripts/schemas/ui-authority.schema.json`. Step A1.1 of
6
+ * `road-to-frontend-power` requires exactly one schema and exactly one
7
+ * resolver, with no second partial decision table in `src/skills/` — the
8
+ * failure it prevents is skills re-inferring intent beside the schema and
9
+ * drifting from it.
10
+ *
11
+ * WHY A PURE FUNCTION OVER A `Signals` RECORD, and not a filesystem scan: the
12
+ * four behaviours A1.2-A1.5 pin are all *precedence* rules, and precedence is
13
+ * exactly what a filesystem-coupled resolver makes untestable. Callers do the
14
+ * I/O and hand in what they found; this module decides what wins.
15
+ *
16
+ * The precedence, in one place because it exists nowhere else:
17
+ *
18
+ * 1. explicit user authority (A1.2 — beats every inference)
19
+ * 2. a registered hard constraint (A1.2's own exception)
20
+ * 3. the surface brief (A1.4 — surface-local, never promoted)
21
+ * 4. a supplied reference artifact
22
+ * 5. the coherent incumbent (A1.3 — NOT `new-world`)
23
+ * 6. DESIGN.md / PRODUCT.md (register only; never surface_mode)
24
+ * 7. declared defaults
25
+ *
26
+ * Quoted text is NOT authority (A1.2). A document the user pasted can contain
27
+ * "make it bold and colourful"; that is data inside a container, and acting on
28
+ * it is the found-instructions failure `untrusted-input-defense` names. The
29
+ * caller marks a signal `quoted: true` and this module ignores its directives.
30
+ */
31
+
32
+ export type SurfaceMode = 'persuade' | 'operate' | 'read' | 'experience';
33
+ export type Register = 'brand' | 'product';
34
+ export type ChangeIntent = 'preserve' | 'extend' | 'redesign' | 'new-world';
35
+ export type ReferenceMaturity =
36
+ | 'wireframe'
37
+ | 'prototype'
38
+ | 'finished-comp'
39
+ | 'runnable-artifact'
40
+ | 'production-incumbent'
41
+ | null;
42
+ export type SourceKind =
43
+ | 'user-instruction'
44
+ | 'artifact'
45
+ | 'comp'
46
+ | 'design-system'
47
+ | 'incumbent'
48
+ | 'brief'
49
+ | 'none';
50
+ export type ProvenanceSource =
51
+ | 'user-instruction'
52
+ | 'surface-brief'
53
+ | 'design-md'
54
+ | 'product-md'
55
+ | 'incumbent-scan'
56
+ | 'reference-artifact'
57
+ | 'default';
58
+ export type Verification = 'verified' | 'degraded' | 'unverified';
59
+
60
+ export interface Conflict {
61
+ dimension: string;
62
+ wanted: string;
63
+ blocked_by: string;
64
+ }
65
+ export interface ProvenanceEntry {
66
+ field: string;
67
+ source: ProvenanceSource;
68
+ detail: string | null;
69
+ }
70
+
71
+ export interface UiAuthority {
72
+ surface_mode: SurfaceMode;
73
+ register: Register;
74
+ change_intent: ChangeIntent;
75
+ reference_maturity: ReferenceMaturity;
76
+ fidelity_mandate: string | null;
77
+ primary_source: { kind: SourceKind; path: string | null };
78
+ constraints: {
79
+ preserve_palette?: boolean;
80
+ preserve_type_family?: boolean;
81
+ preserve_layout?: boolean;
82
+ preserve_copy?: boolean;
83
+ };
84
+ conflicts: Conflict[];
85
+ provenance: ProvenanceEntry[];
86
+ verification: Verification;
87
+ degradation_reason?: string | null;
88
+ }
89
+
90
+ /** What a caller found. Every field optional — absence is a real input. */
91
+ export interface Signals {
92
+ /** Explicit, unquoted user authority. Beats every inference (A1.2). */
93
+ user?: {
94
+ surface_mode?: SurfaceMode;
95
+ register?: Register;
96
+ change_intent?: ChangeIntent;
97
+ /** True when the text came from INSIDE a supplied document (A1.2). */
98
+ quoted?: boolean;
99
+ };
100
+ /** A surface-local brief. Never mutates DESIGN.md / PRODUCT.md (A1.4). */
101
+ brief?: { surface_mode?: SurfaceMode; register?: Register; path?: string };
102
+ /** A supplied reference and how finished it is. */
103
+ reference?: { maturity: Exclude<ReferenceMaturity, null>; path?: string };
104
+ /** Result of an incumbent scan — typically from `ui:audit`. */
105
+ incumbent?: { coherent: boolean; palette?: string[]; type_families?: string[] };
106
+ /** Presence and register of the repo-level documents. */
107
+ design_md?: { present: boolean; register?: Register };
108
+ product_md?: { present: boolean; register?: Register };
109
+ /** Carried from the fidelity roadmap's Phase 0, never derived here. */
110
+ fidelity_mandate?: string | null;
111
+ /** A registered hard constraint outranks even explicit user authority. */
112
+ hard_constraints?: Array<keyof UiAuthority['constraints']>;
113
+ }
114
+
115
+ /** Declared defaults, in one place so "where did this come from" has an answer. */
116
+ export const DEFAULTS = {
117
+ surface_mode: 'operate' as SurfaceMode,
118
+ register: 'product' as Register,
119
+ change_intent: 'extend' as ChangeIntent,
120
+ } as const;
121
+
122
+ /**
123
+ * A1.5's threshold, pre-registered in `internal/bench/frontend-power-PREREG.md`
124
+ * § A1.5's delta threshold and NOT chosen here. Palette and type family only —
125
+ * spacing, radius, weight, size and layout are deliberately excluded so
126
+ * `polish` and `refine` can move them under `preserve`, which is the whole
127
+ * point of those verbs.
128
+ */
129
+ export const PRESERVE_DELTA_DIMENSIONS = ['palette', 'type_family'] as const;
130
+ /** Colour keywords that are never a palette delta. */
131
+ const PALETTE_NEUTRALS = new Set(['transparent', 'currentcolor', 'inherit', 'unset', 'initial']);
132
+
133
+ export function resolveUiAuthority(signals: Signals = {}): UiAuthority {
134
+ const provenance: ProvenanceEntry[] = [];
135
+ const conflicts: Conflict[] = [];
136
+ const note = (field: string, source: ProvenanceSource, detail: string | null = null): void => {
137
+ provenance.push({ field, source, detail });
138
+ };
139
+
140
+ // A1.2 — quoted text inside a supplied document is data, not authorisation.
141
+ const user = signals.user?.quoted ? undefined : signals.user;
142
+
143
+ // surface_mode: user → brief → default. DESIGN.md/PRODUCT.md never supply
144
+ // it (A2.1: the surface job is per-surface, persisted in the brief).
145
+ let surface_mode: SurfaceMode;
146
+ if (user?.surface_mode) {
147
+ surface_mode = user.surface_mode;
148
+ note('surface_mode', 'user-instruction');
149
+ } else if (signals.brief?.surface_mode) {
150
+ surface_mode = signals.brief.surface_mode;
151
+ note('surface_mode', 'surface-brief', signals.brief.path ?? null);
152
+ } else {
153
+ surface_mode = DEFAULTS.surface_mode;
154
+ note('surface_mode', 'default', 'no user or brief signal');
155
+ }
156
+
157
+ // register: user → brief → DESIGN.md → PRODUCT.md → default. The brief
158
+ // outranks PRODUCT.md, which is the `surface-mode-not-product-mode` case:
159
+ // a brand surface inside a product repo must not inherit `product`.
160
+ let register: Register;
161
+ if (user?.register) {
162
+ register = user.register;
163
+ note('register', 'user-instruction');
164
+ } else if (signals.brief?.register) {
165
+ register = signals.brief.register;
166
+ note('register', 'surface-brief', signals.brief.path ?? null);
167
+ } else if (signals.design_md?.present && signals.design_md.register) {
168
+ register = signals.design_md.register;
169
+ note('register', 'design-md');
170
+ } else if (signals.product_md?.present && signals.product_md.register) {
171
+ register = signals.product_md.register;
172
+ note('register', 'product-md');
173
+ } else {
174
+ register = DEFAULTS.register;
175
+ note('register', 'default', 'no register signal');
176
+ }
177
+
178
+ // change_intent: user → (incumbent coherence) → default.
179
+ //
180
+ // A1.3 is the load-bearing branch: a MISSING DESIGN.md is not `new-world`.
181
+ // A coherent incumbent resolves to `extend` with incumbent authority, and
182
+ // only a genuinely empty surface — no incumbent, no reference — is
183
+ // `new-world`.
184
+ let change_intent: ChangeIntent;
185
+ if (user?.change_intent) {
186
+ change_intent = user.change_intent;
187
+ note('change_intent', 'user-instruction');
188
+ } else if (signals.incumbent?.coherent) {
189
+ change_intent = 'extend';
190
+ note('change_intent', 'incumbent-scan', 'coherent incumbent — not new-world (A1.3)');
191
+ } else if (!signals.incumbent && !signals.reference && !signals.design_md?.present) {
192
+ change_intent = 'new-world';
193
+ note('change_intent', 'default', 'no incumbent, no reference, no DESIGN.md');
194
+ } else {
195
+ change_intent = DEFAULTS.change_intent;
196
+ note('change_intent', 'default', 'incumbent present but incoherent');
197
+ }
198
+
199
+ const reference_maturity: ReferenceMaturity = signals.reference?.maturity ?? null;
200
+ note(
201
+ 'reference_maturity',
202
+ signals.reference ? 'reference-artifact' : 'default',
203
+ signals.reference?.path ?? 'no reference supplied',
204
+ );
205
+
206
+ // primary_source — which authority the run builds FROM.
207
+ let kind: SourceKind = 'none';
208
+ let sourcePath: string | null = null;
209
+ if (signals.reference) {
210
+ kind =
211
+ signals.reference.maturity === 'runnable-artifact'
212
+ ? 'artifact'
213
+ : signals.reference.maturity === 'finished-comp'
214
+ ? 'comp'
215
+ : signals.reference.maturity === 'production-incumbent'
216
+ ? 'incumbent'
217
+ : 'brief';
218
+ sourcePath = signals.reference.path ?? null;
219
+ } else if (signals.incumbent?.coherent) {
220
+ kind = 'incumbent';
221
+ } else if (signals.design_md?.present) {
222
+ kind = 'design-system';
223
+ } else if (signals.brief) {
224
+ kind = 'brief';
225
+ sourcePath = signals.brief.path ?? null;
226
+ } else if (user) {
227
+ kind = 'user-instruction';
228
+ }
229
+ note('primary_source', signals.reference ? 'reference-artifact' : 'incumbent-scan', kind);
230
+
231
+ // constraints — `preserve` implies the visual world is locked. A hard
232
+ // constraint is additive and, per A1.2, outranks explicit user authority.
233
+ const constraints: UiAuthority['constraints'] = {};
234
+ if (change_intent === 'preserve') {
235
+ constraints.preserve_palette = true;
236
+ constraints.preserve_type_family = true;
237
+ }
238
+ for (const c of signals.hard_constraints ?? []) {
239
+ if (constraints[c] === false) {
240
+ conflicts.push({
241
+ dimension: c,
242
+ wanted: 'released by user instruction',
243
+ blocked_by: 'registered hard constraint',
244
+ });
245
+ }
246
+ constraints[c] = true;
247
+ }
248
+
249
+ return {
250
+ surface_mode,
251
+ register,
252
+ change_intent,
253
+ reference_maturity,
254
+ fidelity_mandate: signals.fidelity_mandate ?? null,
255
+ primary_source: { kind, path: sourcePath },
256
+ constraints,
257
+ conflicts,
258
+ provenance,
259
+ verification: 'verified',
260
+ };
261
+ }
262
+
263
+ /** Mark an object degraded. Refuses a reason-free degrade by construction. */
264
+ export function degrade(a: UiAuthority, reason: string, state: Exclude<Verification, 'verified'> = 'degraded'): UiAuthority {
265
+ if (!reason.trim()) throw new Error('degrade() requires a non-empty degradation_reason');
266
+ return { ...a, verification: state, degradation_reason: reason };
267
+ }
268
+
269
+ export interface WorldSnapshot {
270
+ palette: readonly string[];
271
+ type_families: readonly string[];
272
+ }
273
+
274
+ const norm = (s: string): string => s.trim().toLowerCase();
275
+
276
+ /**
277
+ * A1.5 — the intent-aware gate. Returns the dimensions that changed and are
278
+ * NOT authorised by `change_intent`. Empty array = the write may proceed.
279
+ *
280
+ * Under `preserve` a palette or type-family delta blocks; under `redesign` and
281
+ * `new-world` nothing here blocks. `extend` sits in between and is treated as
282
+ * permissive on this axis deliberately: extending a surface routinely adds a
283
+ * semantic colour, and blocking that would make the verb unusable.
284
+ */
285
+ export function preserveViolations(
286
+ authority: UiAuthority,
287
+ incumbent: WorldSnapshot,
288
+ proposed: WorldSnapshot,
289
+ ): string[] {
290
+ if (authority.change_intent !== 'preserve') return [];
291
+ const out: string[] = [];
292
+
293
+ if (authority.constraints.preserve_palette) {
294
+ const known = new Set(incumbent.palette.map(norm));
295
+ const added = proposed.palette.map(norm).filter((c) => !known.has(c) && !PALETTE_NEUTRALS.has(c));
296
+ if (added.length) out.push(`palette: ${[...new Set(added)].sort().join(', ')}`);
297
+ }
298
+ if (authority.constraints.preserve_type_family) {
299
+ const known = new Set(incumbent.type_families.map(norm));
300
+ const added = proposed.type_families.map(norm).filter((f) => !known.has(f));
301
+ if (added.length) out.push(`type_family: ${[...new Set(added)].sort().join(', ')}`);
302
+ }
303
+ return out;
304
+ }
305
+
306
+ /**
307
+ * A4.1 — the six intervention operations as values of ONE field rather than as
308
+ * six commands. Each declares the dimensions it may touch, so a collision with
309
+ * a constraint is decidable instead of a judgement call.
310
+ */
311
+ export const OPERATIONS = {
312
+ polish: ['spacing', 'rhythm', 'alignment'],
313
+ quieter: ['spacing', 'weight', 'contrast_within_palette'],
314
+ bolder: ['palette', 'type_family', 'weight', 'scale'],
315
+ distill: ['content_density', 'spacing'],
316
+ harden: ['a11y', 'focus', 'contrast_within_palette'],
317
+ clarify: ['hierarchy', 'copy', 'labels'],
318
+ } as const;
319
+ export type Operation = keyof typeof OPERATIONS;
320
+
321
+ /** Maps an operation dimension onto the constraint that would forbid it. */
322
+ const DIMENSION_CONSTRAINT: Readonly<Record<string, keyof UiAuthority['constraints']>> = {
323
+ palette: 'preserve_palette',
324
+ type_family: 'preserve_type_family',
325
+ hierarchy: 'preserve_layout',
326
+ copy: 'preserve_copy',
327
+ labels: 'preserve_copy',
328
+ };
329
+
330
+ /**
331
+ * A4.1 — does `op` collide with the authority's constraints? A collision is
332
+ * returned as conflicts to APPEND; the caller performs no write. `bolder`
333
+ * under `preserve` is the pinned case.
334
+ */
335
+ export function operationConflicts(authority: UiAuthority, op: Operation): Conflict[] {
336
+ const out: Conflict[] = [];
337
+ for (const dim of OPERATIONS[op] as readonly string[]) {
338
+ const c = DIMENSION_CONSTRAINT[dim];
339
+ if (!c || authority.constraints[c] !== true) continue;
340
+ out.push({ dimension: dim, wanted: `${op} may move ${dim}`, blocked_by: c });
341
+ }
342
+ return out;
343
+ }
@@ -288,9 +288,14 @@ aiv_fal_capability() {
288
288
  jq -e --arg m "${model}" '.models[$m]' "${FAL_MANIFEST}" >/dev/null 2>&1 \
289
289
  || aiv_die 7 "${ADAPTER_ID}: model not in manifest: ${model}"
290
290
  _fal_warn_unverified "${model}"
291
- jq --arg m "${model}" \
292
- '.models[$m] | {audio: (if .audio_sync then "native" else "none" end), model: $m} + .' \
293
- "${FAL_MANIFEST}"
291
+ # Emission goes through the shared helper so the decay markers
292
+ # (`verified_at` / `recheck_by`, derived from the trace index) appear here
293
+ # too. fal is the adapter that actually CARRIES smoke_trace ids, so a
294
+ # capability path that skipped them would leave the only traced adapter as
295
+ # the one place the dates are invisible. Model validation, the
296
+ # manifest-missing check and the unverified warning stay above — this
297
+ # replaces the JSON emission only.
298
+ aiv_capability_recheck "${ADAPTER_ID}" "${model}" "${FAL_MANIFEST}"
294
299
  return 0
295
300
  fi
296
301
  if [ -f "${FAL_MANIFEST}" ] && command -v jq >/dev/null 2>&1; then
@@ -243,4 +243,14 @@ aiv_cmd_fetch() {
243
243
  jq -n --arg p "${out}" '{video_path:$p, audio_embedded:true}'
244
244
  }
245
245
 
246
+ # Capability: `capability --model <id>` answers from
247
+ # lib/model-capabilities/gemini-veo.json (schema v2 — durations, modeled cost,
248
+ # and the start_frame/end_frame continuity answers). A bare `capability`
249
+ # keeps the adapter-level audio flag byte-identical to before the manifest.
250
+ sub="${1:-}"
251
+ if [ "${sub}" = "capability" ]; then
252
+ shift
253
+ aiv_manifest_capability "${ADAPTER_ID}" "native" "$@"
254
+ exit 0
255
+ fi
246
256
  aiv_dispatch "${ADAPTER_ID}" "native" "$@"
@@ -41,15 +41,23 @@ higgsfield_audio_for_preset() {
41
41
  }
42
42
 
43
43
  # Override capability handling so `capability --preset <name>` answers
44
- # per-preset before falling through to the generic helper.
44
+ # per-preset, and `capability --model <id>` answers from
45
+ # lib/model-capabilities/higgsfield.json (schema v2), before falling through
46
+ # to the generic helper. Presets and models are different axes: a preset is a
47
+ # motion profile, a model is the DoP endpoint's checkpoint.
45
48
  aiv_higgsfield_capability() {
46
- local preset=""
49
+ local preset="" model=""
47
50
  while [ "$#" -gt 0 ]; do
48
51
  case "$1" in
49
52
  --preset) preset="${2:-}"; shift 2 ;;
53
+ --model) model="${2:-}"; shift 2 ;;
50
54
  *) shift ;;
51
55
  esac
52
56
  done
57
+ if [ -n "${model}" ]; then
58
+ aiv_manifest_capability "${ADAPTER_ID}" "per-model" --model "${model}"
59
+ return 0
60
+ fi
53
61
  if [ -n "${preset}" ]; then
54
62
  printf '{"audio":"%s","preset":"%s"}\n' \
55
63
  "$(higgsfield_audio_for_preset "${preset}")" "${preset}"
@@ -245,4 +245,14 @@ aiv_cmd_fetch() {
245
245
  jq -n --arg p "${out}" '{video_path:$p, audio_embedded:false}'
246
246
  }
247
247
 
248
+ # Capability: `capability --model <id>` answers from
249
+ # lib/model-capabilities/kling.json (schema v2 — durations, modeled cost,
250
+ # and the start_frame/end_frame continuity answers). A bare `capability`
251
+ # keeps the adapter-level audio flag byte-identical to before the manifest.
252
+ sub="${1:-}"
253
+ if [ "${sub}" = "capability" ]; then
254
+ shift
255
+ aiv_manifest_capability "${ADAPTER_ID}" "none" "$@"
256
+ exit 0
257
+ fi
248
258
  aiv_dispatch "${ADAPTER_ID}" "none" "$@"