@event4u/agent-config 16.3.0 → 16.5.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 (532) 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 +178 -78
  5. package/README.md +2 -2
  6. package/agents/templates/.ai-council.yml.example +26 -8
  7. package/dist/agent-src/commands/analyze/inbox.md +10 -7
  8. package/dist/agent-src/commands/bug/investigate.md +1 -1
  9. package/dist/agent-src/commands/commit/in-chunks.md +40 -31
  10. package/dist/agent-src/commands/commit.md +72 -33
  11. package/dist/agent-src/commands/condense.md +2 -8
  12. package/dist/agent-src/commands/council/debate.md +11 -7
  13. package/dist/agent-src/commands/council/default.md +10 -9
  14. package/dist/agent-src/commands/council.md +1 -1
  15. package/dist/agent-src/commands/design.md +1 -1
  16. package/dist/agent-src/commands/estimate-ticket.md +1 -1
  17. package/dist/agent-src/commands/feature/explore.md +3 -3
  18. package/dist/agent-src/commands/feature/plan.md +1 -1
  19. package/dist/agent-src/commands/fix/ci.md +17 -3
  20. package/dist/agent-src/commands/fix/commit-messages.md +48 -23
  21. package/dist/agent-src/commands/fix/pr-comments.md +3 -6
  22. package/dist/agent-src/commands/implement-ticket.md +3 -3
  23. package/dist/agent-src/commands/memory/add.md +4 -16
  24. package/dist/agent-src/commands/memory/load.md +5 -6
  25. package/dist/agent-src/commands/memory/promote.md +3 -16
  26. package/dist/agent-src/commands/mission/upgrade.md +3 -2
  27. package/dist/agent-src/commands/optimize/agents-dir.md +2 -2
  28. package/dist/agent-src/commands/optimize/deep.md +4 -2
  29. package/dist/agent-src/commands/optimize/rtk.md +4 -26
  30. package/dist/agent-src/commands/pr/create/description-only.md +18 -15
  31. package/dist/agent-src/commands/pr/create.md +42 -34
  32. package/dist/agent-src/commands/pr/merge.md +136 -9
  33. package/dist/agent-src/commands/prepare-for-review.md +13 -11
  34. package/dist/agent-src/commands/project/analyze.md +7 -35
  35. package/dist/agent-src/commands/refine-ticket.md +1 -1
  36. package/dist/agent-src/commands/review/changes.md +14 -19
  37. package/dist/agent-src/commands/roadmap/next.md +10 -1
  38. package/dist/agent-src/commands/roadmap/process-full.md +52 -38
  39. package/dist/agent-src/commands/roadmap/resolve-blockers.md +64 -14
  40. package/dist/agent-src/commands/worktree/create.md +7 -3
  41. package/dist/agent-src/commands/worktree/verify.md +2 -1
  42. package/dist/agent-src/contexts/communication/rules-auto/think-before-action-mechanics.md +5 -3
  43. package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +7 -9
  44. package/dist/agent-src/contexts/contracts/command-suggestion-flow.md +8 -6
  45. package/dist/agent-src/contexts/contracts/frugality-charter.md +8 -5
  46. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +1 -1
  47. package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +0 -1
  48. package/dist/agent-src/contexts/execution/evidence-discipline.md +2 -2
  49. package/dist/agent-src/contexts/execution/non-interactive-contract.md +5 -8
  50. package/dist/agent-src/contexts/execution/rdp-gate.md +4 -4
  51. package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +9 -8
  52. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +67 -52
  53. package/dist/agent-src/contexts/execution/subagent-routing.md +8 -8
  54. package/dist/agent-src/contexts/execution/subagent-steering.md +6 -4
  55. package/dist/agent-src/contexts/execution/terminal-states.md +2 -2
  56. package/dist/agent-src/contexts/execution/toolchain-resolver.md +4 -10
  57. package/dist/agent-src/contexts/subagent-configuration.md +1 -1
  58. package/dist/agent-src/guidelines/agent-infra/active-remediation-mechanics.md +39 -0
  59. package/dist/agent-src/guidelines/agent-infra/context-hygiene-mechanics.md +1 -1
  60. package/dist/agent-src/guidelines/agent-infra/cross-source-consistency-mechanics.md +8 -10
  61. package/dist/agent-src/guidelines/agent-infra/frontier-reasoning-operating-profile.md +3 -2
  62. package/dist/agent-src/guidelines/agent-infra/layered-settings.md +13 -1
  63. package/dist/agent-src/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
  64. package/dist/agent-src/guidelines/agent-infra/self-improvement-pipeline.md +10 -3
  65. package/dist/agent-src/guidelines/agent-infra/size-and-scope.md +36 -0
  66. package/dist/agent-src/guidelines/design-antipatterns.md +1 -1
  67. package/dist/agent-src/guidelines/php/git.md +15 -2
  68. package/dist/agent-src/rules/active-remediation.md +0 -1
  69. package/dist/agent-src/rules/analysis-skill-routing.md +0 -1
  70. package/dist/agent-src/rules/architecture.md +0 -1
  71. package/dist/agent-src/rules/artifact-drafting-protocol.md +0 -1
  72. package/dist/agent-src/rules/artifact-engagement-recording.md +0 -1
  73. package/dist/agent-src/rules/augment-edit-discipline.md +0 -1
  74. package/dist/agent-src/rules/autonomous-execution.md +0 -1
  75. package/dist/agent-src/rules/brand-consistency.md +0 -1
  76. package/dist/agent-src/rules/brand-source-of-truth.md +0 -1
  77. package/dist/agent-src/rules/broken-access-control.md +0 -1
  78. package/dist/agent-src/rules/cli-output-handling.md +0 -1
  79. package/dist/agent-src/rules/code-comment-discipline.md +0 -1
  80. package/dist/agent-src/rules/code-provenance.md +0 -1
  81. package/dist/agent-src/rules/command-suggestion-policy.md +0 -1
  82. package/dist/agent-src/rules/commit-conventions.md +1 -2
  83. package/dist/agent-src/rules/communication-through-line.md +1 -2
  84. package/dist/agent-src/rules/content-quoting-floor.md +1 -2
  85. package/dist/agent-src/rules/context-hygiene.md +5 -5
  86. package/dist/agent-src/rules/copilot-routing.md +1 -2
  87. package/dist/agent-src/rules/council-availability.md +4 -4
  88. package/dist/agent-src/rules/cross-source-consistency.md +4 -6
  89. package/dist/agent-src/rules/decision-revisit-gate.md +2 -3
  90. package/dist/agent-src/rules/delegation-policy.md +2 -3
  91. package/dist/agent-src/rules/design-fidelity.md +0 -1
  92. package/dist/agent-src/rules/design-review-after-ui-write.md +3 -3
  93. package/dist/agent-src/rules/devcontainer-routing.md +1 -2
  94. package/dist/agent-src/rules/doc-screenshot-hygiene.md +0 -1
  95. package/dist/agent-src/rules/docker-commands.md +0 -1
  96. package/dist/agent-src/rules/domain-adoption-policy.md +0 -1
  97. package/dist/agent-src/rules/domain-safety-disclaimer.md +0 -1
  98. package/dist/agent-src/rules/domain-safety-pii.md +0 -1
  99. package/dist/agent-src/rules/domain-safety-retention.md +0 -1
  100. package/dist/agent-src/rules/downstream-changes.md +0 -1
  101. package/dist/agent-src/rules/engineering-safety-floor.md +0 -1
  102. package/dist/agent-src/rules/external-code-graph-interop.md +0 -1
  103. package/dist/agent-src/rules/external-reference-deep-dive.md +0 -1
  104. package/dist/agent-src/rules/fast-path-marker-visibility.md +1 -2
  105. package/dist/agent-src/rules/finance-safety-floor.md +0 -1
  106. package/dist/agent-src/rules/fix-what-you-see.md +6 -32
  107. package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +0 -1
  108. package/dist/agent-src/rules/git-history-discipline.md +1 -2
  109. package/dist/agent-src/rules/guidelines.md +0 -1
  110. package/dist/agent-src/rules/history-discipline.md +0 -1
  111. package/dist/agent-src/rules/icon-consistency.md +0 -1
  112. package/dist/agent-src/rules/image-likeness-and-rights.md +0 -1
  113. package/dist/agent-src/rules/improve-before-implement.md +0 -1
  114. package/dist/agent-src/rules/invite-challenge.md +0 -1
  115. package/dist/agent-src/rules/laravel-routing.md +1 -2
  116. package/dist/agent-src/rules/laravel-translations.md +0 -1
  117. package/dist/agent-src/rules/legal-safety-floor.md +0 -1
  118. package/dist/agent-src/rules/lethal-trifecta-guard.md +0 -1
  119. package/dist/agent-src/rules/linked-projects-onboarding-gate.md +0 -1
  120. package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +0 -1
  121. package/dist/agent-src/rules/markdown-safe-codeblocks.md +0 -1
  122. package/dist/agent-src/rules/media-governance-routing.md +1 -2
  123. package/dist/agent-src/rules/media-sync-ground-truth.md +0 -1
  124. package/dist/agent-src/rules/minimal-safe-diff.md +0 -1
  125. package/dist/agent-src/rules/missing-skill-recovery.md +0 -1
  126. package/dist/agent-src/rules/missing-tool-handling.md +0 -1
  127. package/dist/agent-src/rules/model-recommendation.md +0 -1
  128. package/dist/agent-src/rules/neighbour-precedence.md +64 -0
  129. package/dist/agent-src/rules/no-attribution-footers.md +0 -1
  130. package/dist/agent-src/rules/no-decorative-emojis-in-git-surfaces.md +0 -1
  131. package/dist/agent-src/rules/no-pr-progress-comments.md +0 -1
  132. package/dist/agent-src/rules/no-roadmap-references.md +0 -1
  133. package/dist/agent-src/rules/notes-first-reasoning.md +0 -1
  134. package/dist/agent-src/rules/onboarding-gate.md +0 -1
  135. package/dist/agent-src/rules/output-discipline.md +0 -1
  136. package/dist/agent-src/rules/package-ci-checks.md +0 -1
  137. package/dist/agent-src/rules/persona-governance.md +2 -3
  138. package/dist/agent-src/rules/php-coding.md +0 -1
  139. package/dist/agent-src/rules/prefer-enums-over-literals.md +0 -1
  140. package/dist/agent-src/rules/preservation-guard.md +0 -1
  141. package/dist/agent-src/rules/provider-lifecycle-discipline.md +2 -3
  142. package/dist/agent-src/rules/question-not-instruction.md +0 -1
  143. package/dist/agent-src/rules/reviewer-awareness.md +0 -1
  144. package/dist/agent-src/rules/roadmap-ci-steps-policy.md +0 -1
  145. package/dist/agent-src/rules/roadmap-progress-sync.md +3 -6
  146. package/dist/agent-src/rules/role-mode-adherence.md +0 -1
  147. package/dist/agent-src/rules/rule-type-governance.md +0 -1
  148. package/dist/agent-src/rules/runtime-safety.md +0 -1
  149. package/dist/agent-src/rules/scale-discipline.md +0 -1
  150. package/dist/agent-src/rules/secret-vcs-guard.md +0 -1
  151. package/dist/agent-src/rules/security-sensitive-stop.md +0 -1
  152. package/dist/agent-src/rules/self-repair-loop.md +0 -1
  153. package/dist/agent-src/rules/senior-engineering-discipline.md +0 -1
  154. package/dist/agent-src/rules/session-canary.md +0 -1
  155. package/dist/agent-src/rules/settings-ask-protocol.md +5 -6
  156. package/dist/agent-src/rules/size-enforcement.md +0 -1
  157. package/dist/agent-src/rules/skill-improvement-trigger.md +2 -3
  158. package/dist/agent-src/rules/skill-quality.md +0 -1
  159. package/dist/agent-src/rules/slash-command-routing-policy.md +0 -1
  160. package/dist/agent-src/rules/source-confidentiality.md +0 -1
  161. package/dist/agent-src/rules/source-discovery-gate.md +0 -1
  162. package/dist/agent-src/rules/source-of-truth.md +0 -1
  163. package/dist/agent-src/rules/spreadsheet-source-quality.md +1 -2
  164. package/dist/agent-src/rules/strategy-safety-floor.md +0 -1
  165. package/dist/agent-src/rules/symfony-routing.md +1 -2
  166. package/dist/agent-src/rules/think-before-action.md +0 -1
  167. package/dist/agent-src/rules/token-budget-discipline.md +14 -48
  168. package/dist/agent-src/rules/token-efficiency.md +0 -1
  169. package/dist/agent-src/rules/token-optimizer-maintenance.md +0 -1
  170. package/dist/agent-src/rules/tool-safety.md +0 -1
  171. package/dist/agent-src/rules/ui-audit-gate.md +1 -2
  172. package/dist/agent-src/rules/untrusted-input-defense.md +0 -1
  173. package/dist/agent-src/rules/upstream-proposal.md +0 -1
  174. package/dist/agent-src/rules/user-interaction.md +0 -1
  175. package/dist/agent-src/rules/user-interrupt-priority.md +0 -1
  176. package/dist/agent-src/scripts/gate_budget.ts +47 -23
  177. package/dist/agent-src/scripts/gate_execute.ts +12 -4
  178. package/dist/agent-src/skills/accessibility-auditor/data/aria-patterns.csv +2 -0
  179. package/dist/agent-src/skills/accessibility-auditor/data/manifest.json +3 -3
  180. package/dist/agent-src/skills/ai-council/SKILL.md +7 -4
  181. package/dist/agent-src/skills/ai-council/references/cost-and-redaction.md +21 -11
  182. package/dist/agent-src/skills/ai-council/references/procedure.md +12 -6
  183. package/dist/agent-src/skills/analysis-autonomous-mode/SKILL.md +1 -1
  184. package/dist/agent-src/skills/bug-analyzer/SKILL.md +1 -1
  185. package/dist/agent-src/skills/canvas-design/SKILL.md +4 -2
  186. package/dist/agent-src/skills/command-routing/SKILL.md +3 -4
  187. package/dist/agent-src/skills/conventional-commits-writing/SKILL.md +127 -139
  188. package/dist/agent-src/skills/corpus-grounding/ATTRIBUTION.md +39 -0
  189. package/dist/agent-src/skills/corpus-grounding/SKILL.md +8 -2
  190. package/dist/agent-src/skills/database/data/manifest.json +2 -2
  191. package/dist/agent-src/skills/database/data/query-tuning.csv +13 -13
  192. package/dist/agent-src/skills/design-intelligence/references/integration-mapping.md +13 -10
  193. package/dist/agent-src/skills/design-system-capture/SKILL.md +0 -3
  194. package/dist/agent-src/skills/estimate-ticket/SKILL.md +1 -1
  195. package/dist/agent-src/skills/fe-design/references/design-patterns.md +49 -2
  196. package/dist/agent-src/skills/feature-planning/SKILL.md +1 -1
  197. package/dist/agent-src/skills/frontend-render-security/SKILL.md +9 -0
  198. package/dist/agent-src/skills/git-workflow/SKILL.md +44 -44
  199. package/dist/agent-src/skills/git-workflow/references/branch-update.md +312 -0
  200. package/dist/agent-src/skills/git-workflow/references/commit-subject.md +205 -0
  201. package/dist/agent-src/skills/iconography/SKILL.md +4 -2
  202. package/dist/agent-src/skills/image-provider-routing/SKILL.md +16 -5
  203. package/dist/agent-src/skills/jira-integration/SKILL.md +3 -3
  204. package/dist/agent-src/skills/logo-generation/SKILL.md +12 -8
  205. package/dist/agent-src/skills/merge-conflicts/SKILL.md +10 -4
  206. package/dist/agent-src/skills/po-discovery/SKILL.md +1 -1
  207. package/dist/agent-src/skills/refine-ticket/SKILL.md +4 -4
  208. package/dist/agent-src/skills/roadmap-writing/SKILL.md +2 -2
  209. package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +4 -2
  210. package/dist/agent-src/skills/source-discovery/SKILL.md +1 -1
  211. package/dist/agent-src/skills/svg-authoring/SKILL.md +318 -0
  212. package/dist/agent-src/skills/tailwind-engineer/SKILL.md +3 -1
  213. package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
  214. package/dist/agent-src/skills/using-git-worktrees/SKILL.md +1 -1
  215. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +2 -2
  216. package/dist/agent-src/skills/wireframe/SKILL.md +5 -2
  217. package/dist/agent-src/templates/AGENTS.md +1 -1
  218. package/dist/agent-src/templates/agent-settings.md +46 -129
  219. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +3 -3
  220. package/dist/agent-src/templates/command.md +2 -2
  221. package/dist/agent-src/templates/roadmaps.md +6 -1
  222. package/dist/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +0 -6
  223. package/dist/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +11 -7
  224. package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/decision_trace.ts +3 -2
  225. package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.ts +2 -1
  226. package/dist/agent-src/templates/scripts/work_engine/hooks/settings.ts +0 -6
  227. package/dist/agent-src/templates/scripts/work_engine/scoring/decision_engine.ts +9 -12
  228. package/dist/agent-src/templates/scripts/work_engine/scoring/memory_visibility.ts +2 -1
  229. package/dist/agent-src/templates/skill.md +1 -1
  230. package/dist/cli/commands/uiRender.js +201 -4
  231. package/dist/cli/commands/uiRenderAsset.js +1308 -0
  232. package/dist/cli/commands/uiRenderAssetCompare.js +752 -0
  233. package/dist/cli/commands/uiRenderAssetGrid.js +265 -0
  234. package/dist/cli/commands/uiRenderAssetGrounds.js +323 -0
  235. package/dist/cli/commands/uiRenderAssetIsolation.js +85 -0
  236. package/dist/cli/commands/uiRenderAssetTypes.js +145 -0
  237. package/dist/cli/main.js +47 -1
  238. package/dist/cli/registry.js +2 -1
  239. package/dist/cli-delegate/check_update_banner.js +195 -119
  240. package/dist/cli-delegate/{chunk-S4UMZNES.js → chunk-4DBG5K7M.js} +5 -5
  241. package/dist/cli-delegate/{chunk-TRI6DQZ6.js → chunk-5GPULQBE.js} +60 -42
  242. package/dist/cli-delegate/{chunk-JQVYKIZA.js → chunk-6SRJTYJS.js} +33 -177
  243. package/dist/cli-delegate/chunk-6V5FMA3P.js +186 -0
  244. package/dist/cli-delegate/chunk-6YQC2HLF.js +415 -0
  245. package/dist/cli-delegate/{chunk-E4XIZDIB.js → chunk-7HKRE54K.js} +1 -64
  246. package/dist/cli-delegate/{chunk-7HQ52DHU.js → chunk-AL3RZ22D.js} +1 -1
  247. package/dist/cli-delegate/{chunk-DBH4AHDK.js → chunk-ED7KCMLB.js} +9 -11
  248. package/dist/cli-delegate/{chunk-NXEILF2K.js → chunk-F3QDG2GT.js} +481 -72
  249. package/dist/cli-delegate/{chunk-CQWX336L.js → chunk-G5VVIZRC.js} +3 -3
  250. package/dist/cli-delegate/{chunk-JY2I2DXV.js → chunk-H76PHZBI.js} +137 -60
  251. package/dist/cli-delegate/chunk-IAYTIIQW.js +67 -0
  252. package/dist/cli-delegate/{chunk-LIYTLH6O.js → chunk-KXXWJTDO.js} +5 -10
  253. package/dist/cli-delegate/{chunk-T7L2QK3K.js → chunk-LQOCRFWT.js} +1 -1
  254. package/dist/cli-delegate/{chunk-S4YWNRKO.js → chunk-MDPPKQCQ.js} +34 -1
  255. package/dist/cli-delegate/chunk-OAFSJBHH.js +272 -0
  256. package/dist/cli-delegate/{chunk-GKE7ZVFA.js → chunk-PWX7CKMD.js} +1 -1
  257. package/dist/cli-delegate/{chunk-NDJLNC6Q.js → chunk-T6BP34WI.js} +1 -0
  258. package/dist/cli-delegate/{chunk-RQNNW7IF.js → chunk-T7XSJSUQ.js} +433 -632
  259. package/dist/cli-delegate/{chunk-NQ7WT43P.js → chunk-TMWYUOK4.js} +75 -12
  260. package/dist/cli-delegate/{chunk-EEHDXSYD.js → chunk-WQWXGIWB.js} +12 -273
  261. package/dist/cli-delegate/{chunk-QLDHIPWR.js → chunk-XQTPXKFA.js} +1 -1
  262. package/dist/cli-delegate/cmd_analyze_session.js +223 -43
  263. package/dist/cli-delegate/cmd_brand_status.js +3 -2
  264. package/dist/cli-delegate/cmd_conformance.js +489 -238
  265. package/dist/cli-delegate/cmd_converge.js +3 -3
  266. package/dist/cli-delegate/cmd_doctor.js +15 -12
  267. package/dist/cli-delegate/cmd_doctor_neighbours.js +11 -4
  268. package/dist/cli-delegate/cmd_explain.js +43 -19
  269. package/dist/cli-delegate/cmd_export.js +10 -10
  270. package/dist/cli-delegate/cmd_git_convention.js +1851 -0
  271. package/dist/cli-delegate/cmd_handoff.js +40 -21
  272. package/dist/cli-delegate/cmd_mcp_available.js +3 -2
  273. package/dist/cli-delegate/cmd_migrate.js +3 -3
  274. package/dist/cli-delegate/cmd_packs_active.js +4 -3
  275. package/dist/cli-delegate/cmd_prune.js +10 -10
  276. package/dist/cli-delegate/cmd_route_audit.js +7 -7
  277. package/dist/cli-delegate/cmd_route_explain.js +5 -5
  278. package/dist/cli-delegate/cmd_session_recycle.js +9 -7
  279. package/dist/cli-delegate/cmd_settings_check.js +54 -7
  280. package/dist/cli-delegate/cmd_settings_get.js +18 -8
  281. package/dist/cli-delegate/cmd_settings_migrate.js +10 -10
  282. package/dist/cli-delegate/cmd_settings_set.js +1 -1
  283. package/dist/cli-delegate/cmd_sync.js +10 -10
  284. package/dist/cli-delegate/cmd_uninstall.js +10 -10
  285. package/dist/cli-delegate/cmd_update.js +7 -7
  286. package/dist/cli-delegate/cmd_upgrade.js +7 -7
  287. package/dist/cli-delegate/cmd_validate.js +10 -10
  288. package/dist/cli-delegate/cmd_versions.js +5 -5
  289. package/dist/cli-delegate/gate_budget.js +1 -1
  290. package/dist/cli-delegate/gate_execute.js +2 -2
  291. package/dist/cli-delegate/roadmap_gates.js +2 -2
  292. package/dist/discovery/deprecation-report.md +1 -1
  293. package/dist/discovery/discovery-manifest.json +171 -107
  294. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  295. package/dist/discovery/discovery-manifest.summary.md +7 -7
  296. package/dist/discovery/dormancy-report.md +1 -1
  297. package/dist/discovery/orphan-report.md +1 -1
  298. package/dist/discovery/packs.json +41 -22
  299. package/dist/discovery/trust-report.md +3 -3
  300. package/dist/discovery/workspaces.json +16 -11
  301. package/dist/hooks/dispatch.js +2520 -1924
  302. package/dist/hooks/dispatch.sha256 +1 -1
  303. package/dist/hooks/svg_rules.chunk.cjs +1626 -0
  304. package/dist/hooks/svg_rules.chunk.cjs.sha256 +1 -0
  305. package/dist/install/install.mjs +462 -431
  306. package/dist/install/installThinLayer.js +40 -12
  307. package/dist/install/installedRuleLinks.js +105 -19
  308. package/dist/mcp/awesome-mcp-servers.row.md +1 -1
  309. package/dist/mcp/mcp-cloudflare-catalogue.json +2 -2
  310. package/dist/mcp/registry-manifest.json +5 -5
  311. package/dist/mcp/server.json +2 -2
  312. package/dist/mcp/server.mjs +3063 -2160
  313. package/dist/router.json +1 -1
  314. package/dist/scripts/_lib/agent_settings.js +15 -120
  315. package/dist/scripts/_lib/compile_time_toggles.js +12 -21
  316. package/dist/scripts/_lib/git_convention.js +232 -0
  317. package/dist/scripts/_lib/global_deploy_inventory.js +730 -0
  318. package/dist/scripts/_lib/installed_layer.js +344 -18
  319. package/dist/scripts/_lib/package_root.js +68 -0
  320. package/dist/scripts/_lib/rule_law_section.js +1 -1
  321. package/dist/scripts/_lib/scan_scope.js +105 -0
  322. package/dist/scripts/_lib/settings_removed_keys.js +168 -0
  323. package/dist/scripts/_lib/svg_dom.js +284 -0
  324. package/dist/scripts/_lib/svg_geometry.js +477 -0
  325. package/dist/scripts/_lib/svg_motion.js +179 -0
  326. package/dist/scripts/_lib/svg_rules.js +1337 -0
  327. package/dist/scripts/_lib/svg_urls.js +67 -0
  328. package/dist/scripts/_lib/thin_rules.js +80 -3
  329. package/dist/scripts/lint_svg_asset.js +324 -0
  330. package/dist/server/app.js +2 -1
  331. package/dist/server/gitKeysGate.js +105 -0
  332. package/dist/server/routes/settings.js +67 -8
  333. package/dist/server/routes/wizard.js +4 -0
  334. package/dist/server/schemas/settings.js +23 -81
  335. package/dist/shared/skillRanking.js +30 -4
  336. package/dist/ui/assets/{index-Cwq4d0hX.js → index-C3djEJah.js} +2 -2
  337. package/dist/ui/index.html +1 -1
  338. package/docs/MIGRATION.md +72 -1
  339. package/docs/contracts/settings-classes.md +35 -65
  340. package/docs/guidelines/agent-infra/active-remediation-mechanics.md +39 -0
  341. package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +1 -1
  342. package/docs/guidelines/agent-infra/cross-source-consistency-mechanics.md +8 -10
  343. package/docs/guidelines/agent-infra/frontier-reasoning-operating-profile.md +3 -2
  344. package/docs/guidelines/agent-infra/layered-settings.md +13 -1
  345. package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
  346. package/docs/guidelines/agent-infra/self-improvement-pipeline.md +10 -3
  347. package/docs/guidelines/agent-infra/size-and-scope.md +36 -0
  348. package/docs/guidelines/design-antipatterns.md +1 -1
  349. package/docs/guidelines/php/git.md +15 -2
  350. package/package.json +4 -3
  351. package/src/agent-src/scripts/gate_budget.ts +47 -23
  352. package/src/agent-src/scripts/gate_execute.ts +12 -4
  353. package/src/agent-src/templates/AGENTS.md +1 -1
  354. package/src/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +0 -6
  355. package/src/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +11 -7
  356. package/src/agent-src/templates/scripts/work_engine/hooks/builtin/decision_trace.ts +3 -2
  357. package/src/agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.ts +2 -1
  358. package/src/agent-src/templates/scripts/work_engine/hooks/settings.ts +0 -6
  359. package/src/agent-src/templates/scripts/work_engine/scoring/decision_engine.ts +9 -12
  360. package/src/agent-src/templates/scripts/work_engine/scoring/memory_visibility.ts +2 -1
  361. package/src/config/agent-settings.template.yml +79 -312
  362. package/src/config/agents-paths.yml +16 -0
  363. package/src/config/assurance-capability-registry.json +7 -3
  364. package/src/config/ci-local-parity.yml +3 -0
  365. package/src/config/continuity-surface.json +3 -3
  366. package/src/config/discovery/packs.yml +17 -1
  367. package/src/config/evaluator-budgets.json +19 -6
  368. package/src/config/gate-coverage.yml +65 -23
  369. package/src/config/gate-violation-baselines.json +56 -16
  370. package/src/config/gitignore-block.txt +19 -0
  371. package/src/config/hook-bundle-budget.json +1 -1
  372. package/src/config/release-gate-locality.yml +2 -1
  373. package/src/config/routing-coverage-seed.json +55 -6
  374. package/src/config/rule-law-ceilings.json +12 -6
  375. package/src/config/rule-obligations.json +833 -0
  376. package/src/install/installThinLayer.ts +76 -10
  377. package/src/install/installedRuleLinks.ts +105 -17
  378. package/src/scripts/_cli/cmd_analyze_session.ts +9 -15
  379. package/src/scripts/_cli/cmd_conformance.ts +13 -2
  380. package/src/scripts/_cli/cmd_doctor.ts +10 -10
  381. package/src/scripts/_cli/cmd_doctor_neighbours.ts +133 -0
  382. package/src/scripts/_cli/cmd_explain.ts +72 -14
  383. package/src/scripts/_cli/cmd_git_convention.ts +637 -0
  384. package/src/scripts/_cli/cmd_settings_check.ts +66 -8
  385. package/src/scripts/_cli/cmd_settings_get.ts +18 -3
  386. package/src/scripts/_cli/doctor_execution.ts +72 -1
  387. package/src/scripts/_dispatch.bash +37 -2
  388. package/src/scripts/_lib/agent_settings.ts +15 -124
  389. package/src/scripts/_lib/blocked_by_marker.ts +1 -1
  390. package/src/scripts/_lib/compile_time_toggles.ts +12 -21
  391. package/src/scripts/_lib/dispatch_import_closure.ts +163 -0
  392. package/src/scripts/_lib/git_base_ref.ts +92 -0
  393. package/src/scripts/_lib/git_convention.ts +291 -0
  394. package/src/scripts/_lib/git_convention_carrier.ts +389 -0
  395. package/src/scripts/_lib/git_convention_grammar.ts +246 -0
  396. package/src/scripts/_lib/git_convention_measure.ts +344 -0
  397. package/src/scripts/_lib/global_deploy_inventory.ts +74 -0
  398. package/src/scripts/_lib/graph_feeder_record.ts +236 -13
  399. package/src/scripts/_lib/installed_layer.ts +448 -23
  400. package/src/scripts/_lib/knowledge_global.ts +14 -1
  401. package/src/scripts/_lib/module_reach.ts +456 -0
  402. package/src/scripts/_lib/neighbour_contradictions.ts +236 -0
  403. package/src/scripts/_lib/neighbour_tool_use.ts +8 -10
  404. package/src/scripts/_lib/ratification_artifact.ts +220 -1
  405. package/src/scripts/_lib/ratification_subject.ts +92 -0
  406. package/src/scripts/_lib/release_findings_ingest.ts +15 -7
  407. package/src/scripts/_lib/release_highlights.ts +5 -0
  408. package/src/scripts/_lib/rule_law_section.ts +1 -1
  409. package/src/scripts/_lib/rule_obligations.ts +205 -0
  410. package/src/scripts/_lib/self_repair.ts +1 -1
  411. package/src/scripts/_lib/settings_removed_keys.ts +173 -0
  412. package/src/scripts/_lib/svg_dom.ts +318 -0
  413. package/src/scripts/_lib/svg_geometry.ts +480 -0
  414. package/src/scripts/_lib/svg_motion.ts +208 -0
  415. package/src/scripts/_lib/svg_rules.ts +1453 -0
  416. package/src/scripts/_lib/svg_urls.ts +72 -0
  417. package/src/scripts/_lib/test_red_state.ts +5 -0
  418. package/src/scripts/_lib/thin_rules.ts +83 -3
  419. package/src/scripts/_lib/touched_file_quality.ts +142 -6
  420. package/src/scripts/_lib/verification_command.ts +59 -0
  421. package/src/scripts/_lib/verify_clause.ts +27 -17
  422. package/src/scripts/_lib/worker_budget.ts +1 -1
  423. package/src/scripts/adr/regenerate_index.ts +16 -1
  424. package/src/scripts/ai_council/config.ts +7 -7
  425. package/src/scripts/ai_council/modification_review.ts +100 -0
  426. package/src/scripts/ai_council/modification_review_questions.ts +90 -0
  427. package/src/scripts/ai_council/orchestrator.ts +5 -5
  428. package/src/scripts/ai_council/spend_gate.ts +18 -7
  429. package/src/scripts/ai_team/config.ts +11 -16
  430. package/src/scripts/audit_user_type_axis.ts +20 -8
  431. package/src/scripts/bench_ab_clone.ts +1 -2
  432. package/src/scripts/bench_concern_spawn_path.ts +129 -0
  433. package/src/scripts/bench_graph_feeder_latency.ts +584 -0
  434. package/src/scripts/check_agent_artifact_location.ts +36 -0
  435. package/src/scripts/check_branch_freshness.ts +147 -24
  436. package/src/scripts/check_enforcement_coverage.ts +130 -0
  437. package/src/scripts/check_evaluator_budgets.ts +4 -0
  438. package/src/scripts/check_finding_dispositions.ts +88 -25
  439. package/src/scripts/check_gate_coverage.ts +4 -3
  440. package/src/scripts/check_gate_reachability.ts +48 -1
  441. package/src/scripts/check_generator_sync.ts +48 -0
  442. package/src/scripts/check_hook_bundle_composition.ts +107 -0
  443. package/src/scripts/check_kernel_edit_ratified.ts +86 -6
  444. package/src/scripts/check_pack_size.ts +1 -1
  445. package/src/scripts/check_release_manifest_content.ts +189 -0
  446. package/src/scripts/check_standing_rule_delivery.ts +96 -0
  447. package/src/scripts/check_suppression_hygiene.ts +2 -5
  448. package/src/scripts/ci_settle.ts +42 -5
  449. package/src/scripts/classify_merge_risk.ts +320 -0
  450. package/src/scripts/closure_scan.ts +91 -1
  451. package/src/scripts/command_suggester/settings.ts +8 -108
  452. package/src/scripts/command_suggester/types.ts +4 -5
  453. package/src/scripts/consumer_matrix.ts +102 -0
  454. package/src/scripts/context_hygiene_hook.ts +13 -23
  455. package/src/scripts/cost/preflight.mjs +12 -1
  456. package/src/scripts/council_cli.ts +7 -7
  457. package/src/scripts/dispatch_r2_reviewer.ts +24 -11
  458. package/src/scripts/explain_run.ts +8 -13
  459. package/src/scripts/generate_git_convention_grammar.ts +127 -0
  460. package/src/scripts/generate_host_cost_table.ts +20 -3
  461. package/src/scripts/handoff_context_hook.ts +86 -37
  462. package/src/scripts/hook_manifest.json +1 -1
  463. package/src/scripts/hook_manifest.yaml +25 -6
  464. package/src/scripts/hooks/block_config_weakening.ts +48 -5
  465. package/src/scripts/hooks/block_plumbing_writes.ts +8 -4
  466. package/src/scripts/hooks/block_speaking_inbox_dir.ts +16 -1
  467. package/src/scripts/hooks/concern_registry.ts +2 -0
  468. package/src/scripts/hooks/delegation_nudge_hook.ts +2 -3
  469. package/src/scripts/hooks/design_pass_hook.ts +157 -3
  470. package/src/scripts/hooks/evidence_independence.ts +12 -4
  471. package/src/scripts/hooks/mcp_usage_observation_hook.ts +121 -0
  472. package/src/scripts/hooks/push_settle_hook.ts +4 -3
  473. package/src/scripts/hooks/rule_inject_hook.ts +44 -3
  474. package/src/scripts/hooks/state_io.ts +8 -4
  475. package/src/scripts/hooks/svg_obligation.ts +497 -0
  476. package/src/scripts/hooks/svg_rules_loader.ts +133 -0
  477. package/src/scripts/hooks/telemetry_usage_hook.ts +7 -46
  478. package/src/scripts/hooks/turn_end_gate_hook.ts +6 -3
  479. package/src/scripts/install-hooks.sh +42 -14
  480. package/src/scripts/install.ts +7 -31
  481. package/src/scripts/lint_blocker_citations.ts +198 -0
  482. package/src/scripts/lint_consolidation_lineage.ts +6 -3
  483. package/src/scripts/lint_design_quality.ts +60 -12
  484. package/src/scripts/lint_evidence_artifacts.ts +9 -0
  485. package/src/scripts/lint_hook_concern_budget.ts +10 -21
  486. package/src/scripts/lint_motion_authority_drift.ts +27 -0
  487. package/src/scripts/lint_pack_boundaries.ts +406 -28
  488. package/src/scripts/lint_roadmap_blockers.ts +282 -29
  489. package/src/scripts/lint_roadmap_complexity.ts +4 -2
  490. package/src/scripts/lint_rule_law_section.ts +151 -21
  491. package/src/scripts/lint_rule_skill_pack_reach.ts +17 -0
  492. package/src/scripts/lint_settings_classes.ts +1 -1
  493. package/src/scripts/lint_svg_asset.ts +365 -0
  494. package/src/scripts/lint_ticked_unmet_criteria.ts +165 -0
  495. package/src/scripts/lint_workflow_security.ts +12 -1
  496. package/src/scripts/measure_skill_ranker_baseline.ts +5 -0
  497. package/src/scripts/model_rule_injection.ts +3 -3
  498. package/src/scripts/onboarding_gate_hook.ts +7 -6
  499. package/src/scripts/print_required_checks.ts +15 -3
  500. package/src/scripts/probe_host_compliance.ts +33 -5
  501. package/src/scripts/probe_turnaround.ts +183 -3
  502. package/src/scripts/ratification_header.ts +77 -0
  503. package/src/scripts/refusal_envelope.ts +138 -0
  504. package/src/scripts/release_publication.ts +29 -3
  505. package/src/scripts/report_dispatch_import_closure.ts +76 -0
  506. package/src/scripts/report_installed_rule_links.ts +118 -1
  507. package/src/scripts/report_module_reach.ts +212 -0
  508. package/src/scripts/report_obligation_mechanism.ts +16 -18
  509. package/src/scripts/report_parked_blockers.ts +222 -0
  510. package/src/scripts/report_required_checks_drift.ts +196 -0
  511. package/src/scripts/report_skill_ranker_confusion.ts +103 -2
  512. package/src/scripts/report_standing_payload_by_host.ts +1 -1
  513. package/src/scripts/routing_doctor.ts +2 -2
  514. package/src/scripts/schemas/agent-settings.schema.json +17 -31
  515. package/src/scripts/schemas/command.schema.json +1 -1
  516. package/src/scripts/schemas/skill.schema.json +1 -1
  517. package/src/scripts/self_review_gate.ts +39 -2
  518. package/src/scripts/skill_tools/score_skill_relevance.ts +28 -19
  519. package/src/scripts/sync_pr_branch.ts +403 -132
  520. package/src/scripts/trigger_eval_grandfather.json +0 -16
  521. package/src/server/schemas/settings.ts +33 -177
  522. package/src/shared/skillRanking.ts +53 -4
  523. package/dist/cli-delegate/chunk-NYX3L2PZ.js +0 -99
  524. package/src/scripts/_lib/config_chain.ts +0 -477
  525. package/src/scripts/_lib/conformance_report.ts +0 -403
  526. package/src/scripts/_lib/eval_discrimination.ts +0 -95
  527. package/src/scripts/_lib/evaluator_promotion.ts +0 -225
  528. package/src/scripts/_lib/file_slicer.ts +0 -117
  529. package/src/scripts/_lib/legacy_boundary_map.ts +0 -228
  530. package/src/scripts/_lib/minimality_tiebreak.ts +0 -168
  531. package/src/scripts/_lib/overbuild_lens_contract.ts +0 -196
  532. package/src/scripts/_lib/role_split.ts +0 -338
@@ -0,0 +1,265 @@
1
+ /**
2
+ * uiRenderAssetGrid — the incumbent icon grid, read from the set's own SVGs.
3
+ *
4
+ * Step E6 of `road-to-svg-with-a-witness`, carrying findings 2.1 and 2.2 of
5
+ * `road-to-svg-rules-in-the-dispatch-path`. Its own module because
6
+ * `uiRenderAsset.ts` is over the source-size budget and this is the most
7
+ * self-contained reading in it: no browser, no page, no shared state — bytes
8
+ * in, one grading out, which is also why its two findings are exercisable
9
+ * without a render.
10
+ */
11
+ import * as fs from 'node:fs';
12
+ import * as path from 'node:path';
13
+ import { elementExtent, parseElements, readViewBox } from '../../scripts/lint_svg_asset.js';
14
+ /**
15
+ * Elements whose contents DEFINE something rather than paint it.
16
+ *
17
+ * A shape inside one of these never appears on the canvas on its own, so it
18
+ * must not contribute to the graphic's extent. `<pattern>` and `<symbol>` join
19
+ * the three obvious ones for the same reason.
20
+ */
21
+ const NON_RENDERING = new Set(['defs', 'clippath', 'mask', 'symbol', 'marker', 'pattern']);
22
+ /**
23
+ * The elements that actually paint: everything outside a transformed subtree
24
+ * and outside a non-rendering container.
25
+ *
26
+ * Extracted by finding 9 of this change's second completion review. The extent
27
+ * reading did this walk and the stroke-width reading did not, so an icon whose
28
+ * clip path carried `stroke-width="8"` reported 8 as its stroke while its
29
+ * padding was measured from the 1.5 the viewer sees. Two readings of the same
30
+ * file disagreeing about which elements are in it is the shape a shared walk
31
+ * removes by construction — the previous fix widened the extent half and left
32
+ * the other, which is exactly how the pair came to disagree.
33
+ */
34
+ function renderingElements(elements) {
35
+ const out = [];
36
+ const openSkips = [];
37
+ let skipDepth = 0;
38
+ for (const el of elements) {
39
+ if (el.closing) {
40
+ const was = openSkips.pop();
41
+ if (was === true)
42
+ skipDepth -= 1;
43
+ continue;
44
+ }
45
+ const carries = Boolean(el.attrs['transform'] || el.attrs['style']?.includes('transform')) ||
46
+ NON_RENDERING.has(el.name);
47
+ if (!el.selfClosing) {
48
+ openSkips.push(carries);
49
+ if (carries)
50
+ skipDepth += 1;
51
+ }
52
+ if (skipDepth > 0 || (el.selfClosing && carries))
53
+ continue;
54
+ out.push(el);
55
+ }
56
+ return out;
57
+ }
58
+ /**
59
+ * The centreline extent of one graphic's own geometry, in user units.
60
+ *
61
+ * Shared by the references and by the candidate — finding 2.2 is precisely
62
+ * that the two used to be measured by different methods, so the one thing this
63
+ * function must never grow is a second caller-specific branch.
64
+ *
65
+ * A TRANSFORM ANYWHERE ABOVE A SHAPE DISQUALIFIES IT, not only one on the
66
+ * shape. `elementExtent` refuses an element that carries its own `transform`,
67
+ * and a flat element list makes it easy to miss that a `<g transform="…">`
68
+ * moves everything inside it — measured here: a rect inside a rotated group
69
+ * read as if the group were not there, and the file reported a padding it does
70
+ * not have. The depth stack below is what carries the inheritance; without it
71
+ * the refusal is a half-refusal, which is worse than none because it looks
72
+ * like a reading.
73
+ */
74
+ export function centrelineExtent(elements) {
75
+ let minX = Number.POSITIVE_INFINITY;
76
+ let minY = Number.POSITIVE_INFINITY;
77
+ let maxX = Number.NEGATIVE_INFINITY;
78
+ let maxY = Number.NEGATIVE_INFINITY;
79
+ // Two reasons to skip a subtree, tracked on one stack: an ancestor carries
80
+ // a transform, or an ancestor DOES NOT RENDER.
81
+ //
82
+ // The second is finding 3 of this change's completion review. Geometry
83
+ // inside `<defs>`, `<clipPath>`, `<mask>`, `<symbol>`, `<marker>` or
84
+ // `<pattern>` is a definition, not paint — and a clip path is usually a
85
+ // full-bleed rect, so an exported icon reported padding 0 on BOTH sides
86
+ // and the comparison finding 2.2 exists to make meaningful compared two
87
+ // zeroes. The old `d`-scraping reader had the same blind spot; reading
88
+ // primitives widened it, because clip and mask shapes are rects and
89
+ // circles.
90
+ for (const el of renderingElements(elements)) {
91
+ const box = elementExtent(el);
92
+ if (!box)
93
+ continue;
94
+ minX = Math.min(minX, box.minX);
95
+ maxX = Math.max(maxX, box.maxX);
96
+ minY = Math.min(minY, box.minY);
97
+ maxY = Math.max(maxY, box.maxY);
98
+ }
99
+ return Number.isFinite(minX) ? { minX, minY, maxX, maxY } : null;
100
+ }
101
+ /** Smallest distance from a viewBox edge to an extent. Negative when it overflows. */
102
+ export function paddingFromExtent(vb, ext) {
103
+ return Math.min(ext.minX - vb.x, ext.minY - vb.y, vb.x + vb.w - ext.maxX, vb.y + vb.h - ext.maxY);
104
+ }
105
+ /**
106
+ * Stroke width and padding of each reference icon, read from its own bytes.
107
+ * Padding is the smallest distance from a viewBox edge to the drawn geometry.
108
+ * Nothing is declared here and no grid table is vendored (E6, Non-goals).
109
+ *
110
+ * Finding 2.1 of `road-to-svg-rules-in-the-dispatch-path`, both halves. This
111
+ * used to scrape `d` with a loose number-pair regex, so:
112
+ *
113
+ * · a reference drawn with `<rect>` / `<circle>` / `<line>` yielded no
114
+ * extent, was dropped, and — when every reference was drawn that way —
115
+ * the reading then said "no icon reference set was supplied" although one
116
+ * was. It now reads every primitive, and a file it still cannot read is
117
+ * returned in `skipped` with the reason rather than vanishing.
118
+ * · relative commands were read as absolute, so a path drawn with `m`/`l`
119
+ * reported an extent anchored near the origin. `pathExtent` walks the
120
+ * current point.
121
+ *
122
+ * The reading degrades to `unverified` rather than to a pass, so no verdict
123
+ * was wrong before this — but the reason given for the degradation was.
124
+ */
125
+ export function readIconReferencesDetailed(files) {
126
+ const refs = [];
127
+ const skipped = [];
128
+ for (const file of files) {
129
+ if (!fs.existsSync(file)) {
130
+ skipped.push({ file, reason: 'file does not exist' });
131
+ continue;
132
+ }
133
+ const content = fs.readFileSync(file, 'utf8');
134
+ const elements = parseElements(content);
135
+ const root = elements.find((el) => el.name === 'svg' && !el.closing);
136
+ const vb = readViewBox(root);
137
+ if (!vb) {
138
+ skipped.push({ file, reason: 'no readable viewBox' });
139
+ continue;
140
+ }
141
+ // The SAME walk the candidate's stroke reading uses. Finding 5 of the
142
+ // third completion review: the candidate side was moved onto
143
+ // `renderingElements` and the reference side was not, so a reference
144
+ // icon's clip path contributed a stroke the viewer never sees.
145
+ // Reproduced: two byte-identical files reported 1.5 against [1.5, 8].
146
+ // The same defect as finding 9 of the previous round, in the other
147
+ // half of the same pair — which is what a defect-pattern sweep over
148
+ // the construct, rather than over the one reported site, is for.
149
+ const strokes = new Set();
150
+ for (const el of renderingElements(elements)) {
151
+ const sw = Number(el.attrs['stroke-width']);
152
+ if (Number.isFinite(sw) && sw > 0)
153
+ strokes.add(sw);
154
+ }
155
+ const ext = centrelineExtent(elements.filter((el) => el.name !== 'svg'));
156
+ if (!ext) {
157
+ skipped.push({ file, reason: 'no element in it carries readable geometry (every shape transformed, or none drawn)' });
158
+ continue;
159
+ }
160
+ refs.push({
161
+ file,
162
+ viewBox: vb,
163
+ strokeWidths: [...strokes].sort((a, b) => a - b),
164
+ padding: paddingFromExtent(vb, ext),
165
+ });
166
+ }
167
+ return { refs, skipped };
168
+ }
169
+ /** The list-only form, kept because every existing caller wants exactly that. */
170
+ export function readIconReferences(files) {
171
+ return readIconReferencesDetailed(files).refs;
172
+ }
173
+ /**
174
+ * Graded against the incumbent set, both sides measured the same way (2.2).
175
+ *
176
+ * Exported so the grading can be exercised without launching a browser: the
177
+ * two findings it carries are a padding-method mismatch and a reference set
178
+ * dropped silently, and neither needs a render to reproduce.
179
+ */
180
+ export function gradeIconGrid(file, vb, elements, iconSet,
181
+ /**
182
+ * The RENDERED painted box. Kept in the signature and deliberately unread:
183
+ * it is what the candidate's padding used to come from (finding 2.2), and
184
+ * dropping the parameter would make a caller that still passes it look
185
+ * correct while silently changing which argument lands where. Named with a
186
+ * leading underscore so the linter agrees it is not used.
187
+ */
188
+ _paintedBox) {
189
+ const self = path.resolve(file);
190
+ const { refs, skipped } = readIconReferencesDetailed(iconSet.map((f) => path.resolve(f)).filter((f) => f !== self));
191
+ const comparable = vb ? refs.filter((r) => r.viewBox.w === vb.w && r.viewBox.h === vb.h) : [];
192
+ const strokes = new Set();
193
+ for (const el of renderingElements(elements)) {
194
+ const sw = Number(el.attrs['stroke-width']);
195
+ if (Number.isFinite(sw) && sw > 0)
196
+ strokes.add(sw);
197
+ }
198
+ const strokeWidth = strokes.size > 0 ? Math.max(...strokes) : null;
199
+ /**
200
+ * Finding 2.2: BOTH sides are centreline extents now.
201
+ *
202
+ * The candidate's padding used to come from `painted_box`, a RENDERED box
203
+ * that includes half the stroke and the caps, while the references came
204
+ * from raw coordinates. A candidate matching a reference exactly therefore
205
+ * measured one half-stroke less padding than it — latent rather than live
206
+ * only because the shipped icon pair happens to sit outside the band, so a
207
+ * new fixture at a different stroke width would have made it fire on a
208
+ * clean twin (Risk 7).
209
+ *
210
+ * Fixed by measuring, not by widening a threshold: `centrelineExtent` is
211
+ * the same function the references go through. `painted_box` keeps its own
212
+ * meaning everywhere else in the reading — it is simply not the thing to
213
+ * compare against a centreline.
214
+ */
215
+ const selfExt = centrelineExtent(elements.filter((el) => el.name !== 'svg'));
216
+ const padding = vb && selfExt ? paddingFromExtent(vb, selfExt) : null;
217
+ if (comparable.length === 0) {
218
+ const unreadable = skipped.length
219
+ ? ` ${String(skipped.length)} supplied file(s) could not be read: ${skipped
220
+ .map((s) => `${path.basename(s.file)} (${s.reason})`)
221
+ .join('; ')}.`
222
+ : '';
223
+ return {
224
+ status: 'unverified',
225
+ reference_files: refs.map((r) => path.basename(r.file)),
226
+ reference_stroke_widths: [],
227
+ reference_padding: [],
228
+ stroke_width: strokeWidth,
229
+ padding,
230
+ reason: refs.length === 0
231
+ ? (refs.length === 0 && skipped.length === 0 && iconSet.length > 0
232
+ ? 'every file in the supplied icon reference set is the file under test, so there is ' +
233
+ 'nothing to compare against'
234
+ : iconSet.length === 0
235
+ ? 'no icon reference set was supplied, so the incumbent grid was never read (E6)'
236
+ : 'an icon reference set was supplied but no file in it yielded a reading, so there ' +
237
+ 'is no grid to compare against') + unreadable
238
+ : vb === null
239
+ ? // Finding 8 of the fifth completion review: a CANDIDATE
240
+ // with no readable viewBox reached the same branch as a
241
+ // reference set that shares no size, and was told that
242
+ // no reference shares its viewBox — a statement about
243
+ // the references, when the unreadable thing is the file
244
+ // in front of the author. The reason has to name what
245
+ // is actually missing or the author fixes the wrong
246
+ // file.
247
+ 'this file has no readable viewBox, so its grid cannot be compared against any ' +
248
+ 'reference' + unreadable
249
+ : 'no reference icon shares this viewBox size, so there is no grid to compare against' +
250
+ unreadable,
251
+ };
252
+ }
253
+ const refStrokes = [...new Set(comparable.flatMap((r) => r.strokeWidths))].sort((a, b) => a - b);
254
+ const refPadding = [...new Set(comparable.map((r) => r.padding))].sort((a, b) => a - b);
255
+ return {
256
+ status: 'read',
257
+ reference_files: comparable.map((r) => path.basename(r.file)),
258
+ reference_stroke_widths: refStrokes,
259
+ reference_padding: refPadding,
260
+ stroke_width: strokeWidth,
261
+ padding,
262
+ reason: `read from ${comparable.length} incumbent SVG(s)`,
263
+ };
264
+ }
265
+ //# sourceMappingURL=uiRenderAssetGrid.js.map
@@ -0,0 +1,323 @@
1
+ import { HOST_BASENAME, MIN_CONTRAST_RATIO, } from './uiRenderAssetTypes.js';
2
+ /**
3
+ * The per-ground readings — steps 4.1 and 4.2 of
4
+ * `road-to-svg-from-a-live-session`.
5
+ *
6
+ * Three images, read in one scratch page so nothing is decoded twice:
7
+ *
8
+ * transparent the file on no ground at all, which is where its own
9
+ * silhouette comes from. A silhouette taken from the light
10
+ * capture would lose every white part of the graphic, which is
11
+ * precisely the paint these two readings are about.
12
+ * light / dark the two captures the profile already wrote.
13
+ *
14
+ * Inside that silhouette, two counts per ground. A pixel whose contrast ratio
15
+ * against the ground is below 3:1 is hard to see there (4.2) — a wordmark in
16
+ * dark violet shipped unreadable on a dark ground and the variant was never
17
+ * built. A pixel whose colour sits within the anti-alias band of the ground is
18
+ * the ground showing THROUGH the graphic (4.1) — the hairline seams between
19
+ * abutting traced segments, invisible on white and obvious on black.
20
+ *
21
+ * Holes are excluded by declaration, never by geometry: a ring's middle is
22
+ * ground on purpose, and only the author can say which gaps are intended.
23
+ */
24
+ /**
25
+ * What FRACTION of the capture the graphic covers, width and height.
26
+ *
27
+ * Finding 4 of this change's second completion review. The capture is the
28
+ * VIEWPORT, floored at 64 px, while the page is `margin:0` with
29
+ * `body>svg{width:cssWidth}` — so the graphic sits in the top-left corner and
30
+ * covers only part of the image whenever `cssWidth` is smaller. Every icon is
31
+ * such a case: the sizes are 16/24/48 against a floor of 64. Mapping a
32
+ * user-unit box across the whole capture therefore put every declared hole and
33
+ * every declared-translucent shape 4/3 too far out, and the exclusions the
34
+ * author declared were applied to the wrong part of their own file.
35
+ *
36
+ * A FRACTION rather than a pixel count, because the image's size is known only
37
+ * inside the page while everything this needs is known outside it — which is
38
+ * also what makes the arithmetic testable without a renderer. Clamped to 1:
39
+ * `cssWidth` above the viewport is the graphic filling the capture, not
40
+ * overflowing the coordinate space.
41
+ */
42
+ export function graphicFraction(spec) {
43
+ if (spec.width <= 0 || spec.height <= 0 || spec.cssWidth <= 0)
44
+ return { w: 1, h: 1 };
45
+ const w = Math.min(1, spec.cssWidth / spec.width);
46
+ const vb = spec.viewBox;
47
+ if (!vb || vb.w <= 0)
48
+ return { w, h: 1 };
49
+ // The rendered height follows the viewBox aspect from the rendered width.
50
+ const cssHeight = spec.cssWidth * (vb.h / vb.w);
51
+ return { w, h: Math.min(1, cssHeight / spec.height) };
52
+ }
53
+ export async function readGrounds(context, openPage, spec) {
54
+ // The transparent render: `omitBackground` leaves alpha 0 where the file
55
+ // paints nothing, which is the only honest source for a silhouette.
56
+ const clear = await openPage(context, {
57
+ url: spec.url,
58
+ hostHtml: spec.hostHtml,
59
+ hostBasename: HOST_BASENAME,
60
+ width: spec.width,
61
+ height: spec.height,
62
+ background: 'transparent',
63
+ cssWidth: spec.cssWidth,
64
+ blocked: spec.blocked,
65
+ });
66
+ let silhouette;
67
+ try {
68
+ silhouette = await clear.screenshot({ omitBackground: true });
69
+ }
70
+ finally {
71
+ await clear.close();
72
+ }
73
+ const out = [];
74
+ for (const mode of ['light', 'dark']) {
75
+ const colour = spec.backgrounds[mode];
76
+ const page = await openPage(context, {
77
+ url: spec.url,
78
+ hostHtml: spec.hostHtml,
79
+ hostBasename: HOST_BASENAME,
80
+ width: spec.width,
81
+ height: spec.height,
82
+ background: colour,
83
+ cssWidth: spec.cssWidth,
84
+ blocked: spec.blocked,
85
+ });
86
+ let shot;
87
+ try {
88
+ shot = await page.screenshot();
89
+ }
90
+ finally {
91
+ await page.close();
92
+ }
93
+ const scratch = await context.newPage();
94
+ try {
95
+ await scratch.setContent('<!doctype html><body></body>');
96
+ const counts = await scratch.evaluate(async (args) => {
97
+ const load = async (b64) => {
98
+ const img = new Image();
99
+ img.src = `data:image/png;base64,${b64}`;
100
+ try {
101
+ await img.decode();
102
+ }
103
+ catch {
104
+ return null;
105
+ }
106
+ return img;
107
+ };
108
+ const a = await load(args.silhouette);
109
+ const b = await load(args.ground);
110
+ if (!a || !b)
111
+ return null;
112
+ const w = Math.min(a.naturalWidth, b.naturalWidth);
113
+ const h = Math.min(a.naturalHeight, b.naturalHeight);
114
+ if (w === 0 || h === 0)
115
+ return null;
116
+ const read = (img) => {
117
+ const c = document.createElement('canvas');
118
+ c.width = w;
119
+ c.height = h;
120
+ const cx = c.getContext('2d', { willReadFrequently: true });
121
+ if (!cx)
122
+ return null;
123
+ cx.clearRect(0, 0, w, h);
124
+ cx.drawImage(img, 0, 0);
125
+ return cx.getImageData(0, 0, w, h).data;
126
+ };
127
+ const alpha = read(a);
128
+ const px = read(b);
129
+ if (!alpha || !px)
130
+ return null;
131
+ const hex = args.colour.trim();
132
+ const parse = (v) => {
133
+ const m3 = /^#([0-9a-f])([0-9a-f])([0-9a-f])$/i.exec(v);
134
+ if (m3) {
135
+ return [
136
+ parseInt(m3[1].repeat(2), 16),
137
+ parseInt(m3[2].repeat(2), 16),
138
+ parseInt(m3[3].repeat(2), 16),
139
+ ];
140
+ }
141
+ // 4 and 8 digits carry an ALPHA the ground does not
142
+ // need; 6 is the plain case. Finding 5 of the fifth
143
+ // completion review: this handled 3 and 6 while the
144
+ // token reader that produces the value accepts 3 to 8,
145
+ // so a `#rrggbbaa` background fell through to the
146
+ // white fallback and every contrast ratio on that
147
+ // ground was computed against a colour nobody chose —
148
+ // silently, because white is a plausible answer.
149
+ const m68 = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})(?:[0-9a-f]{2})?$/i.exec(v);
150
+ if (m68) {
151
+ return [
152
+ parseInt(m68[1], 16),
153
+ parseInt(m68[2], 16),
154
+ parseInt(m68[3], 16),
155
+ ];
156
+ }
157
+ const m4 = /^#([0-9a-f])([0-9a-f])([0-9a-f])[0-9a-f]$/i.exec(v);
158
+ if (m4) {
159
+ return [
160
+ parseInt(m4[1].repeat(2), 16),
161
+ parseInt(m4[2].repeat(2), 16),
162
+ parseInt(m4[3].repeat(2), 16),
163
+ ];
164
+ }
165
+ const rgb = /rgba?\(\s*(\d+)[,\s]+(\d+)[,\s]+(\d+)/.exec(v);
166
+ if (rgb) {
167
+ return [Number(rgb[1]), Number(rgb[2]), Number(rgb[3])];
168
+ }
169
+ return [255, 255, 255];
170
+ };
171
+ const ground = parse(hex);
172
+ const lum = (c) => {
173
+ const f = (v) => {
174
+ const x = v / 255;
175
+ return x <= 0.03928 ? x / 12.92 : ((x + 0.055) / 1.055) ** 2.4;
176
+ };
177
+ return 0.2126 * f(c[0]) + 0.7152 * f(c[1]) + 0.0722 * f(c[2]);
178
+ };
179
+ const groundLum = lum(ground);
180
+ const ratio = (c) => {
181
+ const l = lum(c);
182
+ const hi = Math.max(l, groundLum);
183
+ const lo = Math.min(l, groundLum);
184
+ return (hi + 0.05) / (lo + 0.05);
185
+ };
186
+ // Declared holes and translucent shapes, mapped from user
187
+ // units into this image.
188
+ //
189
+ // The graphic's own extent in IMAGE pixels, which is what a
190
+ // user-unit coordinate maps into — not the capture's. The
191
+ // page is `margin:0` with `body>svg{width:cssWidth}`, so it
192
+ // sits at the top-left corner and the height follows the
193
+ // viewBox aspect. A file with no viewBox is not mapped at
194
+ // all (the guard below), so there is no aspect to miss.
195
+ const gW = w * args.graphic.w;
196
+ const gH = h * args.graphic.h;
197
+ const within = (boxes, x, y) => {
198
+ if (!args.vb || boxes.length === 0)
199
+ return false;
200
+ if (gW <= 0 || gH <= 0 || x >= gW || y >= gH)
201
+ return false;
202
+ const ux = args.vb.x + (x / gW) * args.vb.w;
203
+ const uy = args.vb.y + (y / gH) * args.vb.h;
204
+ return boxes.some((box) => ux >= box.x && ux <= box.x + box.w && uy >= box.y && uy <= box.y + box.h);
205
+ };
206
+ const inHole = (x, y) => within(args.holes, x, y);
207
+ const inSoft = (x, y) => within(args.soft, x, y);
208
+ // The OUTER silhouette: flood the transparent region
209
+ // inwards from the border. What the flood cannot reach is
210
+ // inside the graphic — including the hairline gaps between
211
+ // abutting shapes, which is the thing step 4.1 counts and
212
+ // which an `alpha >= 200` definition excludes by
213
+ // construction (measured: 0 bleed pixels on the planted
214
+ // fixture before this).
215
+ const opaque = (i) => alpha[i * 4 + 3] >= 200;
216
+ const outside = new Uint8Array(w * h);
217
+ const stack = [];
218
+ const push = (i) => {
219
+ if (outside[i] === 1 || opaque(i))
220
+ return;
221
+ outside[i] = 1;
222
+ stack.push(i);
223
+ };
224
+ for (let x = 0; x < w; x += 1) {
225
+ push(x);
226
+ push((h - 1) * w + x);
227
+ }
228
+ for (let y = 0; y < h; y += 1) {
229
+ push(y * w);
230
+ push(y * w + (w - 1));
231
+ }
232
+ while (stack.length > 0) {
233
+ const i = stack.pop();
234
+ const x = i % w;
235
+ const y = (i - x) / w;
236
+ if (x > 0)
237
+ push(i - 1);
238
+ if (x + 1 < w)
239
+ push(i + 1);
240
+ if (y > 0)
241
+ push(i - w);
242
+ if (y + 1 < h)
243
+ push(i + w);
244
+ }
245
+ let sil = 0;
246
+ let painted = 0;
247
+ let low = 0;
248
+ let bleed = 0;
249
+ for (let i = 0; i < w * h; i += 1) {
250
+ if (outside[i] === 1)
251
+ continue;
252
+ sil += 1;
253
+ const c = [
254
+ px[i * 4],
255
+ px[i * 4 + 1],
256
+ px[i * 4 + 2],
257
+ ];
258
+ // Contrast is asked of PAINTED pixels only: the ratio
259
+ // of a gap against the ground showing through it is the
260
+ // ratio of the ground against itself.
261
+ if (opaque(i)) {
262
+ painted += 1;
263
+ if (ratio(c) < args.minContrast)
264
+ low += 1;
265
+ }
266
+ // Bleed is an INTERIOR pixel the graphic does not fully
267
+ // cover, so the ground shows through it.
268
+ //
269
+ // Measured, and this is the second definition: comparing
270
+ // the pixel's colour against the ground within a
271
+ // tolerance read 0 on the planted fixture, because a
272
+ // half-covered seam composites to a BLEND of the two
273
+ // greys and the ground — nowhere near the ground itself.
274
+ // Alpha is the thing that is actually wrong, and it is
275
+ // the same number whatever colour the ground is, which
276
+ // is why the finding fires on the dark row: that is the
277
+ // capture where the consequence is visible.
278
+ // Finding 7: a legitimately TRANSLUCENT interior is
279
+ // not a seam. A `fill-opacity="0.5"` shape is excluded
280
+ // from `painted` and would otherwise be counted as
281
+ // near-total bleed against a 0.002 threshold — a
282
+ // warning on a correct file, which is the Risk 1
283
+ // failure this whole concern is shaped around. The
284
+ // caller passes those shapes' extents the same way it
285
+ // passes declared holes, because "is this coverage
286
+ // intended" is again a question only the author
287
+ // answers.
288
+ const x = i % w;
289
+ const y = Math.floor(i / w);
290
+ if (!opaque(i) && !inHole(x, y) && !inSoft(x, y))
291
+ bleed += 1;
292
+ }
293
+ return { silhouette: sil, painted, low, bleed };
294
+ }, {
295
+ silhouette: silhouette.toString('base64'),
296
+ ground: shot.toString('base64'),
297
+ colour,
298
+ holes: spec.holeBoxes,
299
+ soft: spec.softBoxes,
300
+ vb: spec.viewBox,
301
+ minContrast: MIN_CONTRAST_RATIO,
302
+ graphic: graphicFraction(spec),
303
+ });
304
+ if (counts === null)
305
+ continue;
306
+ out.push({
307
+ background: mode,
308
+ background_color: colour,
309
+ silhouette_px: counts.silhouette,
310
+ painted_px: counts.painted,
311
+ low_contrast_px: counts.low,
312
+ low_contrast_share: counts.painted === 0 ? 0 : counts.low / counts.painted,
313
+ bleed_px: counts.bleed,
314
+ bleed_share: counts.silhouette === 0 ? 0 : counts.bleed / counts.silhouette,
315
+ });
316
+ }
317
+ finally {
318
+ await scratch.close();
319
+ }
320
+ }
321
+ return out;
322
+ }
323
+ //# sourceMappingURL=uiRenderAssetGrounds.js.map
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Isolation of the asset under test — which is untrusted input — during its
3
+ * own witness (16.5.0 release review).
4
+ *
5
+ * Scripts are disabled for the whole browser context, so a `<script>` or `on*`
6
+ * handler in the asset never runs; that is also what keeps WebSocket and
7
+ * WebRTC closed, since `page.route` intercepts neither. A request is allowed
8
+ * only on the `file:`, `data:`, `blob:` and `about:` schemes, and a `file:`
9
+ * request only when it resolves inside the project root or the asset's own
10
+ * directory, so an asset cannot pull an arbitrary local file into a capture.
11
+ * The comparison pages inline everything they read, so they allow no `file:`.
12
+ *
13
+ * The cost, accepted: a host document that builds its visual state with
14
+ * JavaScript is witnessed as its static markup, not as it would run.
15
+ */
16
+ import * as fs from 'node:fs';
17
+ import * as path from 'node:path';
18
+ import { fileURLToPath } from 'node:url';
19
+ import { ALLOWED_SCHEMES } from './uiRenderAssetTypes.js';
20
+ /** The directories a `file:` request may resolve into for this asset. */
21
+ export function fileRootsFor(projectRoot, file) {
22
+ return [projectRoot, path.dirname(path.resolve(file))];
23
+ }
24
+ /** True unless `url` is a `file:` URL resolving outside `root` (symlinks followed). */
25
+ export function fileInside(url, root) {
26
+ if (!url.startsWith('file:'))
27
+ return true;
28
+ const real = (p) => {
29
+ try {
30
+ return fs.realpathSync(p);
31
+ }
32
+ catch {
33
+ return path.resolve(p);
34
+ }
35
+ };
36
+ let target;
37
+ try {
38
+ target = real(fileURLToPath(url));
39
+ }
40
+ catch {
41
+ return false;
42
+ }
43
+ const base = real(root);
44
+ return target === base || target.startsWith(base + path.sep);
45
+ }
46
+ /**
47
+ * May the witness page load `url`? A `file:` URL needs a root it resolves
48
+ * inside; with no roots — a page that inlines everything it reads — none does.
49
+ */
50
+ export function requestAllowed(url, fileRoots) {
51
+ if (!ALLOWED_SCHEMES.some((s) => url.startsWith(s)))
52
+ return false;
53
+ return !url.startsWith('file:') || fileRoots.some((root) => fileInside(url, root));
54
+ }
55
+ /**
56
+ * Route every request of `page` through `requestAllowed`, recording what was
57
+ * refused. One opener for every witness page, so no page confines less than
58
+ * another (16.5.0 review: the comparison pages checked the scheme only).
59
+ */
60
+ export async function confinePage(page, blocked, fileRoots, fulfil) {
61
+ await page.route('**/*', async (route) => {
62
+ if (fulfil && (await fulfil(route)))
63
+ return;
64
+ const url = route.request().url();
65
+ if (!requestAllowed(url, fileRoots)) {
66
+ blocked.push(url);
67
+ await route.abort();
68
+ return;
69
+ }
70
+ await route.continue();
71
+ });
72
+ }
73
+ /**
74
+ * Add a stylesheet to the page. Not `page.addStyleTag`: it waits on a
75
+ * page-script `onload`, which never fires with scripts disabled, while
76
+ * `evaluate` runs outside the page's own scripts.
77
+ */
78
+ export async function injectStyle(page, css) {
79
+ await page.evaluate((text) => {
80
+ const style = document.createElement('style');
81
+ style.textContent = text;
82
+ (document.head ?? document.documentElement).appendChild(style);
83
+ }, css);
84
+ }
85
+ //# sourceMappingURL=uiRenderAssetIsolation.js.map