@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,67 @@
1
+ /**
2
+ * How a browser reads the URLs and names in an SVG, for the safety rules in
3
+ * `svg_rules.ts`: references decoded, controls stripped, CSS escapes resolved,
4
+ * and an element prefix stripped only where it is bound to the SVG namespace.
5
+ * Its own module so `svg_rules.ts` stays under the source-size ceiling.
6
+ */
7
+ /** Prefixes the document binds to the SVG namespace (`xmlns:svg="…/2000/svg"`). */
8
+ export function svgPrefixes(content) {
9
+ const out = new Set();
10
+ const re = /xmlns:([\w.-]+)\s*=\s*["']http:\/\/www\.w3\.org\/2000\/svg["']/gi;
11
+ let m;
12
+ while ((m = re.exec(content)) !== null)
13
+ out.add((m[1] ?? '').toLowerCase());
14
+ return out;
15
+ }
16
+ /** The SVG local name: `svg:script` is a `script` where `svg` is bound to SVG; `foo:script` is not. */
17
+ export function localName(name, prefixes) {
18
+ const colon = name.indexOf(':');
19
+ return colon !== -1 && prefixes.has(name.slice(0, colon)) ? name.slice(colon + 1) : name;
20
+ }
21
+ /** Attributes read from the raw tag, unquoted values included — HTML parses those. */
22
+ export function rawAttrs(raw) {
23
+ const out = {};
24
+ const re = /([\w:.-]+)\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>"'`=]+))/g;
25
+ let m;
26
+ while ((m = re.exec(raw)) !== null)
27
+ out[(m[1] ?? '').toLowerCase()] = m[2] ?? m[3] ?? m[4] ?? '';
28
+ return out;
29
+ }
30
+ /** Attributes whose value is followed as a URL. */
31
+ export const URL_ATTRS = new Set(['href', 'xlink:href', 'src']);
32
+ /** A URL that executes or opens a document when followed. */
33
+ export const isActiveUrl = (raw) => /^(javascript:|data:text\/html)/i.test(resolvedUrl(raw));
34
+ const NAMED_URL_ENTITIES = {
35
+ colon: ':', sol: '/', tab: '\t', newline: '\n', period: '.', lpar: '(', rpar: ')', amp: '&',
36
+ };
37
+ /**
38
+ * The URL a browser would actually resolve from an attribute value: character
39
+ * references decoded, leading/trailing C0 controls and spaces stripped, tab and
40
+ * newline removed anywhere. The trailing `;` of a reference is optional on
41
+ * purpose: an `.svg` parsed as XML needs it, but the same graphic inlined in an
42
+ * HTML host is parsed by the HTML tokenizer, which decodes `&#106avascript:`
43
+ * too — over-reading XML here costs precision, under-reading HTML costs a miss.
44
+ * The raw value is attacker-chosen, so a scheme test
45
+ * against it is a test of one spelling — ` https:`, `ht\ttps:`, `javascript:`
46
+ * all load, and all passed.
47
+ */
48
+ export function resolvedUrl(raw) {
49
+ const decoded = raw.replace(/&(?:#x([0-9a-f]+)|#(\d+)|([a-z]+));?/gi, (m, hex, dec, name) => {
50
+ const cp = hex ? parseInt(hex, 16) : dec ? parseInt(dec, 10) : NaN;
51
+ if (!Number.isNaN(cp))
52
+ return cp <= 0x10ffff ? String.fromCodePoint(cp) : m;
53
+ return NAMED_URL_ENTITIES[name.toLowerCase()] ?? m;
54
+ });
55
+ return decoded.replace(/^[\u0000- ]+|[\u0000- ]+$/g, '').replace(/[\t\n\r]/g, '');
56
+ }
57
+ /** CSS escapes decoded: `\\68 ` and `\\h` both read `h`. */
58
+ export function cssUnescape(raw) {
59
+ return raw.replace(/\\([0-9a-f]{1,6})\s?|\\(.)/gi, (m, hex, ch) => {
60
+ if (hex) {
61
+ const cp = parseInt(hex, 16);
62
+ return cp <= 0x10ffff ? String.fromCodePoint(cp) : m;
63
+ }
64
+ return ch;
65
+ });
66
+ }
67
+ //# sourceMappingURL=svg_urls.js.map
@@ -255,13 +255,90 @@ function _title(s) {
255
255
  * Exported so the WRITER and every DETECTOR share one definition. A gate that
256
256
  * re-spelled this string would drift from the writer silently, and the failure
257
257
  * would be invisible in exactly the direction that matters: a stub the gate
258
- * fails to recognise reads as a complete rule body.
258
+ * fails to recognise reads as a complete rule body. Two gates had done exactly
259
+ * that until step 2.1 of `road-to-a-thinned-layer-measured-in-one-unit`; both
260
+ * import this now.
261
+ *
262
+ * SHORTENED 2026-10-06 from 47 characters to 27 (step 2.2). It is paid once per
263
+ * stub and there were 89 stubs on the measured layer, so the sentence cost
264
+ * 4,183 characters of a 97,496-character standing total; at 27 it costs 2,403,
265
+ * a saving of 1,780 = 20 x 89.
266
+ *
267
+ * WHAT THE SHORTENING WAS NOT ALLOWED TO DO: drop the instruction. This is the
268
+ * only standing text in the whole layer that says what a stub is FOR — "load
269
+ * the body" occurs in no kernel rule and in neither root instruction file — so
270
+ * a bare token like `> thin` would have saved more and left nothing that could
271
+ * be followed. The decision record (D2, K6) rejected that explicitly: nothing
272
+ * in this repository can check whether an instruction nobody states is still
273
+ * obeyed.
274
+ *
275
+ * WHY IT MUST STAY LONG ENOUGH TO BE UNIQUE: {@link is_thin_entry} is a
276
+ * substring test over the whole file, so a marker short or generic enough to
277
+ * occur inside ordinary rule prose would make that rule read as a stub — and
278
+ * nine rule files carry blockquote lines. `thin_marker_unique_in_corpus.test.ts`
279
+ * runs the constant against every rule body in `src/rules/` and against every
280
+ * entry `build_thin` emits, in both directions, which is the check that bounds
281
+ * any further shortening.
259
282
  */
260
- export const THIN_ENTRY_MARKER = '> Routed rule — load the body on trigger-match.';
283
+ export const THIN_ENTRY_MARKER = '> Load the body on a match.';
261
284
  /** Is this projected entry a pointer stub rather than a rule body? */
262
285
  export function is_thin_entry(text) {
263
286
  return text.includes(THIN_ENTRY_MARKER);
264
287
  }
288
+ /**
289
+ * What introduces a stub's body pointer. One writer, one reader.
290
+ *
291
+ * A BARE PATH SINCE 2026-10-06 (step 2.3 of
292
+ * `road-to-a-thinned-layer-measured-in-one-unit`). The pointer used to be a
293
+ * markdown link, ``Body: [`<id>`](<prefix><id>.md)``, whose link TEXT repeated
294
+ * the rule id the target already ends in. That cost `6 + len(id)` per stub over
295
+ * the bare form — 2,359 characters across the 89 stubs of the measured layer,
296
+ * 534 of it pure syntax and the rest the id written a second time.
297
+ *
298
+ * Nothing followed the link as a link. Under `delivery` the hook loads the body
299
+ * and never reads the pointer at all; under `thin` an agent reads the path. A
300
+ * markdown link renders in neither case, so the syntax bought rendering nobody
301
+ * was doing.
302
+ */
303
+ export const THIN_BODY_POINTER_PREFIX = 'Body: ';
304
+ /**
305
+ * The pointer, as the WRITER emits it — exported so a detector cannot re-spell
306
+ * it, which is the same drift {@link THIN_ENTRY_MARKER} documents one screen up
307
+ * and which two gates had already committed there.
308
+ *
309
+ * WHAT IT CAPTURES is the whole tail of the line from `Body: ` to its end, and
310
+ * that is the intended semantic rather than an accident of greediness: the
311
+ * writer emits the pointer LAST on its line, so the tail IS the path. A review
312
+ * round proposed a lazy `(.+?\.md)` to stop at the first `.md`; measured, it
313
+ * changes nothing, because `\s*$` forces the match to reach end of line either
314
+ * way and a lazy quantifier simply backtracks forward to the same place. The
315
+ * greedy form is kept and the property is pinned by a test, so the next reader
316
+ * meets the measurement instead of repeating the proposal.
317
+ *
318
+ * ANCHORED TO END OF LINE, NOT `\S+`. The pointer is the last thing on its
319
+ * line, and a package root may contain spaces; `\S+` would silently stop at the
320
+ * first one and report a well-formed pointer as missing.
321
+ *
322
+ * COMPOSED FROM {@link THIN_BODY_POINTER_PREFIX} rather than re-spelling it.
323
+ * The constant exists so a reader cannot hold its own copy, and a pattern six
324
+ * lines below it holding a literal `Body: ` would have broken that invariant in
325
+ * the file that states it.
326
+ */
327
+ export const THIN_BODY_POINTER_RE = (() => {
328
+ const lit = THIN_BODY_POINTER_PREFIX.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
329
+ // THE LAST PREFIX ON THE LINE, NOT THE FIRST. `thin_entry` puts the rule's
330
+ // own `description` on the SAME line ahead of the pointer, so a description
331
+ // containing the literal `Body: ` used to start the match inside the
332
+ // description and capture it as part of the path — `has_body_pointer` stayed
333
+ // true while the extraction was wrong, which is a wrong assertion rather
334
+ // than a visible failure. Forbidding a second prefix inside the capture
335
+ // makes the first viable start the last occurrence, which is the pointer.
336
+ return new RegExp(`${lit}((?:(?!${lit}).)+\\.md)\\s*$`, 'm');
337
+ })();
338
+ /** Does this entry carry a body pointer the writer would recognise? */
339
+ export function has_body_pointer(text) {
340
+ return THIN_BODY_POINTER_RE.test(text);
341
+ }
265
342
  /**
266
343
  * Where a stub tells a reader the body actually is.
267
344
  *
@@ -318,7 +395,7 @@ export function thin_entry(rule_id, text, bodyLinkPrefix = BODY_LINK_PREFIX) {
318
395
  const fires = hint ? ` Fires on: ${hint}.` : '';
319
396
  return (`## ${title}\n` +
320
397
  `${THIN_ENTRY_MARKER}${fires} ${desc} ` +
321
- `Body: [\`${rule_id}\`](${bodyLinkPrefix}${rule_id}.md)\n`);
398
+ `${THIN_BODY_POINTER_PREFIX}${bodyLinkPrefix}${rule_id}.md\n`);
322
399
  }
323
400
  /**
324
401
  * The marker that opens a stub's copied law block, and the one that closes it
@@ -0,0 +1,324 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * lint_svg_asset — the command-line surface over the SVG rule set.
4
+ *
5
+ * The rules live in `_lib/svg_rules.ts`, because the design pass imports them
6
+ * into the hook bundle and must not drag a CLI in with them (see that file's
7
+ * header for the measurement). Everything this module adds is the part only a
8
+ * command needs: argument parsing, the directory walk, the project config, the
9
+ * scanned-nothing refusal, and the step 1.2 preservation readout.
10
+ *
11
+ * Inline-ignore (same shape as `lint_design_quality`, works in XML comments):
12
+ * svg-asset-disable <rule-id> [-- reason] (file scope)
13
+ * svg-asset-disable-next-line <rule-id> [-- reason]
14
+ * svg-asset-disable-line <rule-id> [-- reason]
15
+ *
16
+ * Per-project config (`.svg-asset.json` in the project root):
17
+ * { "ignoreRules": ["svg-a11y-generic-id"], "ignoreFiles": ["vendor/**"] }
18
+ *
19
+ * Usage:
20
+ * lint_svg_asset --dir <path> [--delivery inline|img|css-bg|document]
21
+ * lint_svg_asset --file <a.svg> [--file <b.svg>] [--delivery …]
22
+ * lint_svg_asset --file <after.svg> --baseline <before.svg> --allow id,id
23
+ *
24
+ * Exit codes: 0 = clean, 2 = findings, 1 = internal error (including the
25
+ * scanned-nothing refusal — a gate that scanned no file is not a clean gate).
26
+ */
27
+ import fs from 'node:fs';
28
+ import path from 'node:path';
29
+ import { assertScanned, DeadScopeError } from './_lib/scan_scope.js';
30
+ import { DELIVERY_MODES, parseElements, scanHostHtml, scanSvg, } from './_lib/svg_rules.js';
31
+ export * from './_lib/svg_rules.js';
32
+ /**
33
+ * Canonicalised attribute map — number formatting, attribute order and
34
+ * whitespace normalised away, so a re-serialisation that changed nothing reads
35
+ * as nothing changed.
36
+ */
37
+ export function canonicalAttrs(attrs) {
38
+ const out = {};
39
+ for (const key of Object.keys(attrs).sort()) {
40
+ const v = (attrs[key] ?? '')
41
+ .replace(/\s+/g, ' ')
42
+ .trim()
43
+ // Numbers only where a number is what it is. A hex color is a
44
+ // TOKEN, not a quantity: normalising inside `#00ff00` collapses it
45
+ // onto `#0ff0`, and the readout then reports no change for a color
46
+ // edit outside the allowed ids — a surgical-edit witness that
47
+ // cannot see a recolour.
48
+ .replace(/#[0-9a-fA-F]+|-?\d+\.?\d*(?:[eE][-+]?\d+)?/g, (tok) => {
49
+ if (tok.startsWith('#'))
50
+ return tok.toLowerCase();
51
+ const num = Number(tok);
52
+ return Number.isFinite(num) ? String(Number(num.toFixed(4))) : tok;
53
+ });
54
+ out[key] = v;
55
+ }
56
+ return out;
57
+ }
58
+ /**
59
+ * Every element outside the allowed set that changed between two revisions.
60
+ *
61
+ * NO PIXEL DIFF decides this. Anti-aliasing and font metrics would make a
62
+ * pixel comparison a per-machine verdict, and the discipline this witnesses —
63
+ * `design-fidelity-mechanics.md` § surgical edits — is about which elements
64
+ * the edit was allowed to touch, which is an attribute fact.
65
+ */
66
+ export function preservationReadout(beforeContent, afterContent, allowedIds) {
67
+ const allow = new Set(allowedIds.map((s) => s.trim()).filter(Boolean));
68
+ /**
69
+ * A stable key per element, and the id chain above it.
70
+ *
71
+ * An element WITHOUT an id is keyed by its nearest id-bearing ancestor plus
72
+ * its tag and its ordinal INSIDE that ancestor — never by a document-wide
73
+ * index. A document-wide index shifts for every element after an allowed
74
+ * deletion, so removing one child of the allowed group reported every
75
+ * un-idded element after it as changed. Measured on the `grouped-transforms`
76
+ * triple: the correct edit reported `rect#7 (element)` and the readout could
77
+ * not tell a clean surgical edit from a dirty one.
78
+ */
79
+ const index = (content) => {
80
+ const map = new Map();
81
+ const stack = [];
82
+ const ordinals = new Map();
83
+ for (const el of parseElements(content)) {
84
+ if (el.closing) {
85
+ if (stack[stack.length - 1]?.name === el.name)
86
+ stack.pop();
87
+ continue;
88
+ }
89
+ const chain = stack.map((f) => f.id).filter((x) => x !== null);
90
+ const ownerId = [...stack].reverse().find((f) => f.id !== null)?.id ?? '';
91
+ const own = el.attrs['id'] ?? null;
92
+ let key;
93
+ if (own) {
94
+ key = own;
95
+ }
96
+ else {
97
+ const bucket = `${ownerId}/${el.name}`;
98
+ const n = (ordinals.get(bucket) ?? 0) + 1;
99
+ ordinals.set(bucket, n);
100
+ key = `${bucket}#${n}`;
101
+ }
102
+ map.set(key, { el, chain: own ? [...chain, own] : chain });
103
+ if (!el.selfClosing)
104
+ stack.push({ name: el.name, id: own });
105
+ }
106
+ return map;
107
+ };
108
+ const before = index(beforeContent);
109
+ const after = index(afterContent);
110
+ const changes = [];
111
+ /** An element inside an allowed subtree is itself allowed. */
112
+ const permitted = (entry) => Boolean(entry && entry.chain.some((id) => allow.has(id)));
113
+ for (const [key, beforeEntry] of before) {
114
+ if (permitted(beforeEntry))
115
+ continue;
116
+ const afterEntry = after.get(key);
117
+ if (!afterEntry) {
118
+ changes.push({
119
+ id: key,
120
+ element: beforeEntry.el.name,
121
+ attribute: '(element)',
122
+ before: 'present',
123
+ after: 'removed',
124
+ });
125
+ continue;
126
+ }
127
+ const a = canonicalAttrs(beforeEntry.el.attrs);
128
+ const b = canonicalAttrs(afterEntry.el.attrs);
129
+ for (const attr of new Set([...Object.keys(a), ...Object.keys(b)])) {
130
+ if ((a[attr] ?? '') === (b[attr] ?? ''))
131
+ continue;
132
+ changes.push({
133
+ id: key,
134
+ element: beforeEntry.el.name,
135
+ attribute: attr,
136
+ before: a[attr] ?? '(absent)',
137
+ after: b[attr] ?? '(absent)',
138
+ });
139
+ }
140
+ }
141
+ for (const [key, afterEntry] of after) {
142
+ if (permitted(afterEntry) || before.has(key))
143
+ continue;
144
+ changes.push({
145
+ id: key,
146
+ element: afterEntry.el.name,
147
+ attribute: '(element)',
148
+ before: 'absent',
149
+ after: 'added',
150
+ });
151
+ }
152
+ return changes;
153
+ }
154
+ export function loadConfig(dir) {
155
+ const configPath = path.join(dir, '.svg-asset.json');
156
+ if (!fs.existsSync(configPath))
157
+ return {};
158
+ try {
159
+ return JSON.parse(fs.readFileSync(configPath, 'utf-8'));
160
+ }
161
+ catch {
162
+ return {};
163
+ }
164
+ }
165
+ function* walkDir(dir, ext) {
166
+ if (!fs.existsSync(dir))
167
+ return;
168
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
169
+ const full = path.join(dir, entry.name);
170
+ if (entry.name.startsWith('.') || entry.name === 'node_modules')
171
+ continue;
172
+ if (entry.isDirectory())
173
+ yield* walkDir(full, ext);
174
+ else if (ext.test(entry.name))
175
+ yield full;
176
+ }
177
+ }
178
+ // ---------------------------------------------------------------------------
179
+ // CLI
180
+ // ---------------------------------------------------------------------------
181
+ function readFlag(args, name) {
182
+ const i = args.indexOf(name);
183
+ return i >= 0 ? args[i + 1] : undefined;
184
+ }
185
+ function readAll(args, name) {
186
+ const out = [];
187
+ for (let i = 0; i < args.length; i++)
188
+ if (args[i] === name && args[i + 1])
189
+ out.push(args[i + 1]);
190
+ return out;
191
+ }
192
+ export function main(argv = process.argv.slice(2)) {
193
+ const args = [...argv];
194
+ const jsonMode = args.includes('--json');
195
+ const quiet = args.includes('--quiet');
196
+ const deliveryRaw = readFlag(args, '--delivery');
197
+ if (deliveryRaw && !DELIVERY_MODES.includes(deliveryRaw)) {
198
+ process.stderr.write(`[lint_svg_asset] unknown --delivery "${deliveryRaw}"; expected one of ${DELIVERY_MODES.join(', ')}\n`);
199
+ return 1;
200
+ }
201
+ const delivery = deliveryRaw;
202
+ // --- step 1.2: preservation readout -------------------------------------
203
+ const baseline = readFlag(args, '--baseline');
204
+ if (baseline) {
205
+ const files = readAll(args, '--file');
206
+ const after = files[0];
207
+ if (!after) {
208
+ process.stderr.write('[lint_svg_asset] --baseline needs a --file <after.svg> to compare against\n');
209
+ return 1;
210
+ }
211
+ if (!fs.existsSync(baseline) || !fs.existsSync(after)) {
212
+ process.stderr.write('[lint_svg_asset] --baseline or --file path not found\n');
213
+ return 1;
214
+ }
215
+ const allow = (readFlag(args, '--allow') ?? '').split(',').map((s) => s.trim()).filter(Boolean);
216
+ const changes = preservationReadout(fs.readFileSync(baseline, 'utf-8'), fs.readFileSync(after, 'utf-8'), allow);
217
+ if (jsonMode) {
218
+ process.stdout.write(`${JSON.stringify(changes, null, 2)}\n`);
219
+ return changes.length ? 2 : 0;
220
+ }
221
+ if (!changes.length) {
222
+ if (!quiet) {
223
+ process.stdout.write(`✅ lint_svg_asset --baseline: nothing changed outside ${allow.length} allowed id(s).\n`);
224
+ }
225
+ return 0;
226
+ }
227
+ for (const c of changes) {
228
+ process.stdout.write(`❌ ${after} [svg-preserve-changed-outside-allowed] <${c.element} id="${c.id}"> ` +
229
+ `${c.attribute}: "${c.before}" → "${c.after}"\n`);
230
+ }
231
+ process.stdout.write(`\nlint_svg_asset: ${changes.length} element change(s) outside the allowed set. ` +
232
+ 'A surgical edit touches only what it declared.\n');
233
+ return 2;
234
+ }
235
+ // --- scanning -----------------------------------------------------------
236
+ const explicit = readAll(args, '--file');
237
+ const dirArg = readFlag(args, '--dir');
238
+ const targets = [];
239
+ let roots = [];
240
+ if (explicit.length) {
241
+ targets.push(...explicit.map((f) => path.resolve(f)));
242
+ roots = targets;
243
+ }
244
+ else {
245
+ const scanDir = dirArg ? path.resolve(dirArg) : path.resolve(process.cwd(), 'src');
246
+ roots = [scanDir];
247
+ if (!fs.existsSync(scanDir)) {
248
+ // The two cases are NOT the same, and collapsing them into exit 0
249
+ // made a renamed or mistyped `--dir` report success in CI. An
250
+ // ABSENT DEFAULT root is the opt-in escape — a consumer with no
251
+ // `src/` has nothing to scan and must not red. An EXPLICIT `--dir`
252
+ // that does not resolve is a broken invocation, and this module's
253
+ // own header already says a gate that scanned no file is not a
254
+ // clean gate.
255
+ if (!quiet)
256
+ process.stderr.write(`[lint_svg_asset] scan directory not found: ${scanDir}\n`);
257
+ if (dirArg)
258
+ return 1;
259
+ process.stderr.write('This linter is opt-in. Run with --dir <path> or --file <a.svg> pointing at your assets.\n');
260
+ return 0;
261
+ }
262
+ for (const f of walkDir(scanDir, /\.(svg|html|htm)$/i))
263
+ targets.push(f);
264
+ }
265
+ const config = loadConfig(process.cwd());
266
+ const ignoreRules = new Set((config.ignoreRules ?? []).map((r) => r.toLowerCase()));
267
+ const ignoreGlobs = config.ignoreFiles ?? [];
268
+ const scanned = targets.filter((f) => !ignoreGlobs.some((g) => f.includes(g.replace('**', ''))));
269
+ try {
270
+ assertScanned({ gate: 'lint_svg_asset', scanned: scanned.length, units: 'SVG/HTML file(s)', roots });
271
+ }
272
+ catch (exc) {
273
+ if (exc instanceof DeadScopeError) {
274
+ process.stderr.write(`❌ ${exc.message}\n`);
275
+ return 1;
276
+ }
277
+ throw exc;
278
+ }
279
+ const all = [];
280
+ for (const abs of scanned) {
281
+ const rel = path.relative(process.cwd(), abs);
282
+ try {
283
+ const content = fs.readFileSync(abs, 'utf-8');
284
+ const findings = /\.svg$/i.test(abs)
285
+ ? scanSvg(content, rel, { delivery })
286
+ : scanHostHtml(content, rel, { delivery });
287
+ all.push(...findings.filter((f) => !ignoreRules.has(f.rule.toLowerCase())));
288
+ }
289
+ catch (err) {
290
+ if (!quiet)
291
+ process.stderr.write(`[lint_svg_asset] error: ${abs}: ${err}\n`);
292
+ }
293
+ }
294
+ if (jsonMode) {
295
+ process.stdout.write(`${JSON.stringify(all, null, 2)}\n`);
296
+ return all.length > 0 ? 2 : 0;
297
+ }
298
+ if (!all.length) {
299
+ if (!quiet) {
300
+ process.stdout.write(`✅ lint_svg_asset: clean — ${scanned.length} file(s) checked, no violations.\n`);
301
+ }
302
+ return 0;
303
+ }
304
+ const errors = all.filter((f) => f.severity === 'error');
305
+ const warnings = all.filter((f) => f.severity === 'warning');
306
+ const inert = all.filter((f) => f.severity === 'inert');
307
+ for (const f of all) {
308
+ const icon = f.severity === 'error' ? '❌' : f.severity === 'warning' ? '⚠️ ' : 'ℹ️ ';
309
+ process.stdout.write(`${icon} ${f.file}:${f.line} [${f.rule}] ${f.snippet}\n`);
310
+ }
311
+ process.stdout.write(`\nlint_svg_asset: ${errors.length} error(s), ${warnings.length} warning(s), ${inert.length} inert. ` +
312
+ 'Use svg-asset-disable-next-line <rule> -- reason or .svg-asset.json to suppress; ' +
313
+ 'svg-safety-* findings yield only to .svg-asset.json, never to a marker in the file. ' +
314
+ 'Advisory: an "inert" row is not a clean row — the same file inlined tomorrow is an error.\n');
315
+ return 2;
316
+ }
317
+ /* c8 ignore start — entrypoint guard, exercised by the CLI not by the tests */
318
+ const invokedDirectly = typeof process !== 'undefined' &&
319
+ Array.isArray(process.argv) &&
320
+ /lint_svg_asset\.(ts|js)$/.test(process.argv[1] ?? '');
321
+ if (invokedDirectly)
322
+ process.exit(main());
323
+ /* c8 ignore stop */
324
+ //# sourceMappingURL=lint_svg_asset.js.map
@@ -155,7 +155,7 @@ export async function createApp(opts) {
155
155
  await app.register(pingRoute({ writeRoot, projectScopeRoot, mode, dryRun, projectSurface: opts.projectSurface === true }));
156
156
  await app.register(discoveryRoute(opts.discoveryManifestPath ? { manifestPath: opts.discoveryManifestPath } : {}));
157
157
  await app.register(schemaRoute());
158
- await app.register(settingsRoute({ writeRoot, legacyReadRoot, packageRoot, dryRun, userGlobalReadRoot: userGlobalRead }));
158
+ await app.register(settingsRoute({ writeRoot, legacyReadRoot, packageRoot, dryRun, userGlobalReadRoot: userGlobalRead, userGlobalWrite: mode === 'global' }));
159
159
  await app.register(settingsChangesRoute({ writeRoot, userGlobalReadRoot: userGlobalRead, dryRun }));
160
160
  await app.register(userMdRoute({ writeRoot, legacyReadRoot, dryRun, userGlobalReadRoot: userGlobalRead }));
161
161
  await app.register(installRoute(opts.installRouteOptions ?? {}));
@@ -167,6 +167,7 @@ export async function createApp(opts) {
167
167
  dryRun,
168
168
  userGlobalReadRoot: userGlobalRead,
169
169
  extendedSteps: opts.extendedSteps === true,
170
+ userGlobalWrite: mode === 'global',
170
171
  ...(opts.initialStep !== undefined ? { initialStep: opts.initialStep } : {}),
171
172
  ...(opts.wizardMode !== undefined ? { wizardMode: opts.wizardMode } : {}),
172
173
  }));
@@ -0,0 +1,105 @@
1
+ /**
2
+ * The settings route's handling of the three `git.*` keys.
3
+ *
4
+ * In global mode the route writes the user-global file, and `load_agent_settings`
5
+ * discards `git.*` keys from that file, so a value saved there has no effect in
6
+ * any repository. The form is not offered those keys, and a non-default value is
7
+ * refused with the place a team declares them instead (ADR-283). A template
8
+ * default is accepted: the form round-trips it, and `upgrade` inserts it too.
9
+ *
10
+ * In every mode a value goes through the same check `git:convention show` and
11
+ * `settings:check` run, so a pattern that would reach a shell is refused here as
12
+ * well.
13
+ */
14
+ import { promises as fs } from 'node:fs';
15
+ import { join } from 'node:path';
16
+ import { parseYaml } from './io/yamlIO.js';
17
+ import { GIT_CONVENTION_KEYS, invalidReason } from '../scripts/_lib/git_convention.js';
18
+ export const WITHHELD_GIT_KEYS = GIT_CONVENTION_KEYS.map((k) => `git.${k}`);
19
+ export const WITHHELD_REASON = 'This form writes your user-global settings file, which does not carry git.* keys. ' +
20
+ 'A team declares them in .git-convention.yml at the repository root; one checkout can set them in its project settings file.';
21
+ function _gitSection(values) {
22
+ const git = values['git'];
23
+ return git !== null && typeof git === 'object' && !Array.isArray(git) ? git : null;
24
+ }
25
+ /** The values and the JSON schema with the `git` section removed. */
26
+ export function withholdGitKeys(values, schema) {
27
+ const { git: _git, ...rest } = values;
28
+ const properties = { ...(schema.properties ?? {}) };
29
+ delete properties['git'];
30
+ const next = { ...schema, properties };
31
+ if (Array.isArray(schema.required))
32
+ next.required = schema.required.filter((k) => k !== 'git');
33
+ return { values: rest, schema: next };
34
+ }
35
+ /**
36
+ * Field issues for the `git.*` values of a write. `defaults` is the template's
37
+ * `git` section; `userGlobal` is true when the write lands in the user-global file.
38
+ */
39
+ export function gitKeyWriteIssues(values, defaults, userGlobal) {
40
+ const git = _gitSection(values);
41
+ if (git === null)
42
+ return [];
43
+ const fallback = _gitSection(defaults) ?? {};
44
+ const issues = [];
45
+ for (const key of GIT_CONVENTION_KEYS) {
46
+ const value = git[key];
47
+ if (typeof value !== 'string')
48
+ continue;
49
+ const why = invalidReason(key, value);
50
+ if (why !== null) {
51
+ issues.push({ path: `git.${key}`, message: why });
52
+ continue;
53
+ }
54
+ const def = fallback[key];
55
+ if (userGlobal && !(typeof def === 'string' && def === value)) {
56
+ issues.push({ path: `git.${key}`, message: WITHHELD_REASON });
57
+ }
58
+ }
59
+ return issues;
60
+ }
61
+ /**
62
+ * The write candidate with the `git` section the file already holds. In global
63
+ * mode the form never showed that section, and the schema's `.default({})`
64
+ * fills template defaults into whatever arrives, so a value the user-global
65
+ * file carries would otherwise read as a change the user made: a guarded-key
66
+ * confirmation for a field they never saw, then a silent reset.
67
+ *
68
+ * `fileValues` is that file alone, never the merged view: the merge carries
69
+ * the template defaults and any project layer, and copying a project value
70
+ * here would write it into the user-global file without passing the gate.
71
+ */
72
+ export function keepWithheldGit(candidate, fileValues) {
73
+ const { git: _sent, ...rest } = candidate;
74
+ return 'git' in fileValues ? { ...rest, git: fileValues['git'] } : rest;
75
+ }
76
+ /**
77
+ * The before-side of a global-mode diff: the merged view with its `git` section
78
+ * swapped for the file's own, or dropped when the file has none. The candidate
79
+ * from `keepWithheldGit` carries exactly that section, so comparing it against
80
+ * the merged view would report template defaults and project values as edits
81
+ * to a section the form never showed.
82
+ */
83
+ export function gitDiffBase(merged, fileValues) {
84
+ return keepWithheldGit(merged, fileValues);
85
+ }
86
+ /**
87
+ * The wizard's finish write through the same gate: a 422 is sent and true
88
+ * returned when a `git.*` value is refused. The template's `git` section holds
89
+ * no install placeholder, so it is parsed without substitution.
90
+ */
91
+ export async function refuseGitKeys(reply, values, packageRoot, userGlobal) {
92
+ let defaults = {};
93
+ try {
94
+ defaults = parseYaml(await fs.readFile(join(packageRoot, 'src', 'config', 'agent-settings.template.yml'), 'utf8'));
95
+ }
96
+ catch {
97
+ defaults = {};
98
+ }
99
+ const issues = gitKeyWriteIssues(values, defaults, userGlobal);
100
+ if (issues.length === 0)
101
+ return false;
102
+ await reply.code(422).send({ error: { code: 'VALIDATION', message: 'invalid settings', fields: issues } });
103
+ return true;
104
+ }
105
+ //# sourceMappingURL=gitKeysGate.js.map