@event4u/agent-config 14.23.0 → 16.0.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 (541) 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 +144 -152
  5. package/README.md +1 -1
  6. package/dist/agent-src/commands/agent-handoff.md +8 -7
  7. package/dist/agent-src/commands/agents/init.md +1 -1
  8. package/dist/agent-src/commands/agents/user/accept.md +4 -4
  9. package/dist/agent-src/commands/agents/user/delete.md +2 -2
  10. package/dist/agent-src/commands/agents/user/init.md +3 -3
  11. package/dist/agent-src/commands/agents/user/review.md +3 -3
  12. package/dist/agent-src/commands/agents/user/show.md +3 -3
  13. package/dist/agent-src/commands/agents/user/update.md +2 -2
  14. package/dist/agent-src/commands/agents/user.md +6 -6
  15. package/dist/agent-src/commands/analytics/prune.md +1 -1
  16. package/dist/agent-src/commands/analytics/show.md +2 -2
  17. package/dist/agent-src/commands/analyze/decision.md +2 -2
  18. package/dist/agent-src/commands/analyze/inbox.md +5 -5
  19. package/dist/agent-src/commands/analyze/incident.md +3 -3
  20. package/dist/agent-src/commands/analyze/near-miss.md +3 -3
  21. package/dist/agent-src/commands/analyze/postmortem.md +4 -4
  22. package/dist/agent-src/commands/analyze/premortem.md +2 -2
  23. package/dist/agent-src/commands/analyze.md +2 -2
  24. package/dist/agent-src/commands/bug/fix.md +1 -1
  25. package/dist/agent-src/commands/bug/investigate.md +2 -2
  26. package/dist/agent-src/commands/cost/profile.md +3 -3
  27. package/dist/agent-src/commands/design.md +1 -1
  28. package/dist/agent-src/commands/feature/explore.md +1 -1
  29. package/dist/agent-src/commands/feature/plan.md +2 -2
  30. package/dist/agent-src/commands/feature/roadmap.md +2 -2
  31. package/dist/agent-src/commands/ghostwriter/fetch.md +4 -4
  32. package/dist/agent-src/commands/ghostwriter/list.md +1 -1
  33. package/dist/agent-src/commands/ghostwriter/show.md +1 -1
  34. package/dist/agent-src/commands/ghostwriter/write.md +9 -9
  35. package/dist/agent-src/commands/humanize.md +6 -6
  36. package/dist/agent-src/commands/jira-ticket.md +1 -1
  37. package/dist/agent-src/commands/judge/solo.md +1 -1
  38. package/dist/agent-src/commands/judge.md +1 -1
  39. package/dist/agent-src/commands/knowledge/cross-repo.md +1 -1
  40. package/dist/agent-src/commands/knowledge/forget.md +1 -1
  41. package/dist/agent-src/commands/knowledge/ingest.md +2 -2
  42. package/dist/agent-src/commands/knowledge/list.md +1 -1
  43. package/dist/agent-src/commands/memory/add.md +3 -3
  44. package/dist/agent-src/commands/memory/load.md +4 -4
  45. package/dist/agent-src/commands/memory/mine-session.md +1 -1
  46. package/dist/agent-src/commands/memory/promote.md +4 -4
  47. package/dist/agent-src/commands/memory/propose.md +2 -2
  48. package/dist/agent-src/commands/mode.md +5 -5
  49. package/dist/agent-src/commands/post-as/ghostwriter.md +3 -3
  50. package/dist/agent-src/commands/post-as/me.md +7 -7
  51. package/dist/agent-src/commands/pr/create.md +1 -1
  52. package/dist/agent-src/commands/pr/merge.md +1 -1
  53. package/dist/agent-src/commands/profile/activate.md +1 -1
  54. package/dist/agent-src/commands/profile/show.md +1 -1
  55. package/dist/agent-src/commands/research/deep.md +2 -2
  56. package/dist/agent-src/commands/research/report.md +2 -2
  57. package/dist/agent-src/commands/review/changes.md +1 -1
  58. package/dist/agent-src/commands/review/routing.md +1 -1
  59. package/dist/agent-src/commands/roadmap/create.md +4 -3
  60. package/dist/agent-src/commands/roadmap/materialize.md +2 -2
  61. package/dist/agent-src/commands/roadmap/next.md +1 -1
  62. package/dist/agent-src/commands/roadmap/process-full.md +2 -2
  63. package/dist/agent-src/commands/security-audit-config.md +3 -3
  64. package/dist/agent-src/commands/skill/preview.md +1 -1
  65. package/dist/agent-src/commands/skills/discover.md +1 -1
  66. package/dist/agent-src/commands/sync/agent-settings.md +2 -2
  67. package/dist/agent-src/commands/sync/gitignore/fix.md +1 -1
  68. package/dist/agent-src/commands/tests/create.md +1 -1
  69. package/dist/agent-src/commands/tests/e2e-heal.md +1 -1
  70. package/dist/agent-src/commands/tests/e2e-plan.md +1 -1
  71. package/dist/agent-src/contexts/authority/kernel-rule-edits.md +6 -6
  72. package/dist/agent-src/contexts/communication/rules-auto/slash-command-routing-policy-mechanics.md +1 -2
  73. package/dist/agent-src/contexts/communication/rules-auto/think-before-action-mechanics.md +2 -2
  74. package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +88 -1
  75. package/dist/agent-src/contexts/communication/rules-auto/user-interaction-mechanics.md +51 -1
  76. package/dist/agent-src/contexts/contracts/frugality-charter.md +1 -1
  77. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +1 -1
  78. package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +1 -1
  79. package/dist/agent-src/contexts/execution/autonomy-mechanics.md +1 -1
  80. package/dist/agent-src/contexts/execution/cheap-question-mechanics.md +1 -1
  81. package/dist/agent-src/contexts/execution/contract-decision-sheet.md +3 -3
  82. package/dist/agent-src/contexts/execution/mandated-lines.md +1 -1
  83. package/dist/agent-src/contexts/execution/non-interactive-contract.md +1 -1
  84. package/dist/agent-src/contexts/execution/orchestration-telemetry.md +1 -1
  85. package/dist/agent-src/contexts/execution/plan-confidence-gate.md +5 -5
  86. package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +1 -1
  87. package/dist/agent-src/contexts/execution/subagent-modes-detail.md +1 -1
  88. package/dist/agent-src/contexts/execution/subagent-routing.md +2 -2
  89. package/dist/agent-src/contexts/execution/subagent-spawn-contract.md +1 -1
  90. package/dist/agent-src/contexts/execution/user-memory-channels.md +3 -3
  91. package/dist/agent-src/contexts/execution/verification-mechanics.md +1 -1
  92. package/dist/agent-src/contexts/judges/persona-voice-rubric.md +2 -2
  93. package/dist/agent-src/guidelines/abstraction-thresholds.md +88 -0
  94. package/dist/agent-src/guidelines/agent-infra/5w2h-analysis.md +260 -0
  95. package/dist/agent-src/guidelines/agent-infra/active-remediation-mechanics.md +99 -0
  96. package/dist/agent-src/guidelines/agent-infra/agent-interaction-and-decision-quality.md +325 -0
  97. package/dist/agent-src/guidelines/agent-infra/api-cost-levers.md +177 -0
  98. package/dist/agent-src/guidelines/agent-infra/artifact-drafting-protocol-mechanics.md +222 -0
  99. package/dist/agent-src/guidelines/agent-infra/ask-when-uncertain-demos.md +134 -0
  100. package/dist/agent-src/guidelines/agent-infra/asking-and-brevity-examples.md +198 -0
  101. package/dist/agent-src/guidelines/agent-infra/break-glass-usage.md +113 -0
  102. package/dist/agent-src/guidelines/agent-infra/carve-out-predicates.md +17 -0
  103. package/dist/agent-src/guidelines/agent-infra/comparison-matrix.md +179 -0
  104. package/dist/agent-src/guidelines/agent-infra/context-hygiene-mechanics.md +165 -0
  105. package/dist/agent-src/guidelines/agent-infra/corpus-grounding-authoring.md +91 -0
  106. package/dist/agent-src/guidelines/agent-infra/critical-thinking.md +156 -0
  107. package/dist/agent-src/guidelines/agent-infra/cross-source-consistency-mechanics.md +109 -0
  108. package/dist/agent-src/guidelines/agent-infra/developer-judgment.md +82 -0
  109. package/dist/agent-src/guidelines/agent-infra/direct-answers-demos.md +142 -0
  110. package/dist/agent-src/guidelines/agent-infra/domain-adoption-gates.md +112 -0
  111. package/dist/agent-src/guidelines/agent-infra/domain-eval-anti-pattern.md +53 -0
  112. package/dist/agent-src/guidelines/agent-infra/domain-pack-architecture.md +56 -0
  113. package/dist/agent-src/guidelines/agent-infra/downstream-changes-mechanics.md +91 -0
  114. package/dist/agent-src/guidelines/agent-infra/emphasis-budget.md +45 -0
  115. package/dist/agent-src/guidelines/agent-infra/engineering-memory-data-format.md +210 -0
  116. package/dist/agent-src/guidelines/agent-infra/evaluator-independence-mechanics.md +92 -0
  117. package/dist/agent-src/guidelines/agent-infra/existence-question-verdicts.md +80 -0
  118. package/dist/agent-src/guidelines/agent-infra/failure-signatures.md +70 -0
  119. package/dist/agent-src/guidelines/agent-infra/false-green.md +233 -0
  120. package/dist/agent-src/guidelines/agent-infra/first-principles.md +192 -0
  121. package/dist/agent-src/guidelines/agent-infra/framework-neutrality-patterns.md +66 -0
  122. package/dist/agent-src/guidelines/agent-infra/frontier-reasoning-operating-profile.md +169 -0
  123. package/dist/agent-src/guidelines/agent-infra/gate-authoring.md +177 -0
  124. package/dist/agent-src/guidelines/agent-infra/guarded-baseline.md +39 -0
  125. package/dist/agent-src/guidelines/agent-infra/installed-tools-manifest.md +142 -0
  126. package/dist/agent-src/guidelines/agent-infra/inversion-thinking.md +388 -0
  127. package/dist/agent-src/guidelines/agent-infra/ios-simulator-guide.md +378 -0
  128. package/dist/agent-src/guidelines/agent-infra/language-and-tone-examples.md +141 -0
  129. package/dist/agent-src/guidelines/agent-infra/layered-settings.md +317 -0
  130. package/dist/agent-src/guidelines/agent-infra/linked-projects-onboarding-gate.md +80 -0
  131. package/dist/agent-src/guidelines/agent-infra/mcp-request-signing.md +197 -0
  132. package/dist/agent-src/guidelines/agent-infra/memory-access.md +149 -0
  133. package/dist/agent-src/guidelines/agent-infra/mental-models.md +314 -0
  134. package/dist/agent-src/guidelines/agent-infra/minimal-safe-diff-mechanics.md +241 -0
  135. package/dist/agent-src/guidelines/agent-infra/missing-tool-handling.md +66 -0
  136. package/dist/agent-src/guidelines/agent-infra/model-recommendation.md +101 -0
  137. package/dist/agent-src/guidelines/agent-infra/naming.md +69 -0
  138. package/dist/agent-src/guidelines/agent-infra/notes-horizon-mechanics.md +90 -0
  139. package/dist/agent-src/guidelines/agent-infra/output-patterns.md +117 -0
  140. package/dist/agent-src/guidelines/agent-infra/recurring-criticism-mechanics.md +96 -0
  141. package/dist/agent-src/guidelines/agent-infra/reuse-verdict-mechanics.md +71 -0
  142. package/dist/agent-src/guidelines/agent-infra/review-routing-data-format.md +143 -0
  143. package/dist/agent-src/guidelines/agent-infra/roadmap-deferred-resolution-provenance.md +54 -0
  144. package/dist/agent-src/guidelines/agent-infra/roadmap-progress-mechanics.md +274 -0
  145. package/dist/agent-src/guidelines/agent-infra/role-contracts.md +209 -0
  146. package/dist/agent-src/guidelines/agent-infra/role-mode-router.md +89 -0
  147. package/dist/agent-src/guidelines/agent-infra/rule-body-migration-inventory.md +241 -0
  148. package/dist/agent-src/guidelines/agent-infra/rule-type-governance.md +73 -0
  149. package/dist/agent-src/guidelines/agent-infra/runtime-layer.md +89 -0
  150. package/dist/agent-src/guidelines/agent-infra/scqa-framework.md +526 -0
  151. package/dist/agent-src/guidelines/agent-infra/security-lint-containment.md +121 -0
  152. package/dist/agent-src/guidelines/agent-infra/self-improvement-pipeline.md +134 -0
  153. package/dist/agent-src/guidelines/agent-infra/simplicity-and-goal-demos.md +211 -0
  154. package/dist/agent-src/guidelines/agent-infra/six-hats.md +353 -0
  155. package/dist/agent-src/guidelines/agent-infra/size-and-scope.md +229 -0
  156. package/dist/agent-src/guidelines/agent-infra/skill-quality-checklist.md +157 -0
  157. package/dist/agent-src/guidelines/agent-infra/source-confidentiality-mechanics.md +109 -0
  158. package/dist/agent-src/guidelines/agent-infra/symptom-driven-harvest-loop.md +104 -0
  159. package/dist/agent-src/guidelines/agent-infra/systems-thinking.md +220 -0
  160. package/dist/agent-src/guidelines/agent-infra/tool-description-as-policy.md +35 -0
  161. package/dist/agent-src/guidelines/agent-infra/tool-integration.md +73 -0
  162. package/dist/agent-src/guidelines/agent-infra/traceability-field-mechanics.md +50 -0
  163. package/dist/agent-src/guidelines/agent-infra/untrusted-input-spotlighting.md +166 -0
  164. package/dist/agent-src/guidelines/agent-infra/verify-before-complete-demos.md +128 -0
  165. package/dist/agent-src/guidelines/augment-portability-patterns.md +70 -0
  166. package/dist/agent-src/guidelines/code-clarity.md +350 -0
  167. package/dist/agent-src/guidelines/component-oriented-and-oop-development.md +189 -0
  168. package/dist/agent-src/guidelines/cross-role-handoff.md +127 -0
  169. package/dist/agent-src/guidelines/design-antipatterns-triggers.json +18 -0
  170. package/dist/agent-src/guidelines/design-antipatterns.md +327 -0
  171. package/dist/agent-src/guidelines/design-asset-discipline.md +38 -0
  172. package/dist/agent-src/guidelines/design-canon.md +63 -0
  173. package/dist/agent-src/guidelines/design-fidelity-mechanics.md +293 -0
  174. package/dist/agent-src/guidelines/design-fidelity-routing.md +78 -0
  175. package/dist/agent-src/guidelines/design-handover-extraction.md +117 -0
  176. package/dist/agent-src/guidelines/design-modes.md +143 -0
  177. package/dist/agent-src/guidelines/design-reconciliation.md +172 -0
  178. package/dist/agent-src/guidelines/docs/readme-size-and-splitting.md +209 -0
  179. package/dist/agent-src/guidelines/e2e/playwright.md +363 -0
  180. package/dist/agent-src/guidelines/gtm-handoff.md +114 -0
  181. package/dist/agent-src/guidelines/monorepo-antipatterns.md +141 -0
  182. package/dist/agent-src/guidelines/php/api-design.md +115 -0
  183. package/dist/agent-src/guidelines/php/artisan-commands.md +81 -0
  184. package/dist/agent-src/guidelines/php/blade-ui.md +78 -0
  185. package/dist/agent-src/guidelines/php/controllers.md +90 -0
  186. package/dist/agent-src/guidelines/php/database.md +194 -0
  187. package/dist/agent-src/guidelines/php/eloquent.md +208 -0
  188. package/dist/agent-src/guidelines/php/flux.md +80 -0
  189. package/dist/agent-src/guidelines/php/general.md +207 -0
  190. package/dist/agent-src/guidelines/php/git.md +164 -0
  191. package/dist/agent-src/guidelines/php/jobs.md +111 -0
  192. package/dist/agent-src/guidelines/php/livewire.md +71 -0
  193. package/dist/agent-src/guidelines/php/logging.md +79 -0
  194. package/dist/agent-src/guidelines/php/naming.md +89 -0
  195. package/dist/agent-src/guidelines/php/patterns/dependency-injection.md +57 -0
  196. package/dist/agent-src/guidelines/php/patterns/dtos.md +199 -0
  197. package/dist/agent-src/guidelines/php/patterns/events.md +67 -0
  198. package/dist/agent-src/guidelines/php/patterns/factory.md +53 -0
  199. package/dist/agent-src/guidelines/php/patterns/pipelines.md +66 -0
  200. package/dist/agent-src/guidelines/php/patterns/policies.md +66 -0
  201. package/dist/agent-src/guidelines/php/patterns/repositories.md +122 -0
  202. package/dist/agent-src/guidelines/php/patterns/service-layer.md +64 -0
  203. package/dist/agent-src/guidelines/php/patterns/strategy.md +247 -0
  204. package/dist/agent-src/guidelines/php/patterns.md +28 -0
  205. package/dist/agent-src/guidelines/php/performance.md +92 -0
  206. package/dist/agent-src/guidelines/php/php-coding-patterns.md +80 -0
  207. package/dist/agent-src/guidelines/php/resources.md +100 -0
  208. package/dist/agent-src/guidelines/php/security.md +110 -0
  209. package/dist/agent-src/guidelines/php/sql.md +97 -0
  210. package/dist/agent-src/guidelines/php/validations.md +119 -0
  211. package/dist/agent-src/guidelines/php/websocket.md +100 -0
  212. package/dist/agent-src/guidelines/prompt-templates.md +189 -0
  213. package/dist/agent-src/guidelines/redundancy-taxonomy.md +208 -0
  214. package/dist/agent-src/guidelines/wing4-handoff.md +127 -0
  215. package/dist/agent-src/personas/README.md +1 -1
  216. package/dist/agent-src/personas/_template-specialist/persona.md +1 -1
  217. package/dist/agent-src/personas/product-owner.md +1 -1
  218. package/dist/agent-src/rules/active-remediation.md +1 -1
  219. package/dist/agent-src/rules/architecture.md +2 -2
  220. package/dist/agent-src/rules/artifact-drafting-protocol.md +1 -1
  221. package/dist/agent-src/rules/ask-when-uncertain.md +2 -2
  222. package/dist/agent-src/rules/brand-source-of-truth.md +9 -7
  223. package/dist/agent-src/rules/code-comment-discipline.md +2 -2
  224. package/dist/agent-src/rules/code-provenance.md +1 -1
  225. package/dist/agent-src/rules/content-quoting-floor.md +1 -1
  226. package/dist/agent-src/rules/context-hygiene.md +5 -5
  227. package/dist/agent-src/rules/cross-source-consistency.md +1 -1
  228. package/dist/agent-src/rules/design-fidelity.md +36 -46
  229. package/dist/agent-src/rules/direct-answers.md +2 -2
  230. package/dist/agent-src/rules/domain-adoption-policy.md +1 -1
  231. package/dist/agent-src/rules/evaluator-independence.md +1 -1
  232. package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +1 -1
  233. package/dist/agent-src/rules/icon-consistency.md +5 -1
  234. package/dist/agent-src/rules/improve-before-implement.md +1 -1
  235. package/dist/agent-src/rules/language-and-tone.md +3 -3
  236. package/dist/agent-src/rules/minimal-safe-diff.md +1 -1
  237. package/dist/agent-src/rules/notes-first-reasoning.md +2 -2
  238. package/dist/agent-src/rules/recurring-criticism.md +1 -1
  239. package/dist/agent-src/rules/roadmap-progress-sync.md +1 -1
  240. package/dist/agent-src/rules/role-mode-adherence.md +2 -2
  241. package/dist/agent-src/rules/security-sensitive-stop.md +1 -1
  242. package/dist/agent-src/rules/size-enforcement.md +1 -1
  243. package/dist/agent-src/rules/source-confidentiality.md +2 -2
  244. package/dist/agent-src/rules/think-before-action.md +1 -1
  245. package/dist/agent-src/rules/token-efficiency.md +7 -5
  246. package/dist/agent-src/rules/ui-audit-gate.md +3 -2
  247. package/dist/agent-src/rules/untrusted-input-defense.md +3 -3
  248. package/dist/agent-src/rules/user-interaction.md +31 -30
  249. package/dist/agent-src/skills/activation-design/SKILL.md +2 -2
  250. package/dist/agent-src/skills/adr-create/SKILL.md +5 -5
  251. package/dist/agent-src/skills/ai-council/SKILL.md +1 -1
  252. package/dist/agent-src/skills/ai-council/references/advanced-modes.md +1 -1
  253. package/dist/agent-src/skills/blade-ui/SKILL.md +1 -1
  254. package/dist/agent-src/skills/blast-radius-analyzer/SKILL.md +1 -1
  255. package/dist/agent-src/skills/brand-to-tokens/SKILL.md +24 -3
  256. package/dist/agent-src/skills/bug-analyzer/SKILL.md +1 -1
  257. package/dist/agent-src/skills/build-buy-partner/SKILL.md +1 -1
  258. package/dist/agent-src/skills/churn-prevention/SKILL.md +2 -2
  259. package/dist/agent-src/skills/code-refactoring/SKILL.md +3 -3
  260. package/dist/agent-src/skills/code-review/SKILL.md +3 -3
  261. package/dist/agent-src/skills/command-writing/SKILL.md +3 -3
  262. package/dist/agent-src/skills/comp-banding/SKILL.md +1 -1
  263. package/dist/agent-src/skills/competitive-moat-analysis/SKILL.md +1 -1
  264. package/dist/agent-src/skills/competitive-positioning/SKILL.md +2 -2
  265. package/dist/agent-src/skills/complexity-first-planning/SKILL.md +1 -1
  266. package/dist/agent-src/skills/condense-memory/SKILL.md +1 -1
  267. package/dist/agent-src/skills/content-funnel-design/SKILL.md +2 -2
  268. package/dist/agent-src/skills/contracts-cognition/SKILL.md +1 -1
  269. package/dist/agent-src/skills/copilot-agents-optimization/SKILL.md +2 -2
  270. package/dist/agent-src/skills/corpus-grounding/SKILL.md +2 -2
  271. package/dist/agent-src/skills/customer-research/SKILL.md +2 -2
  272. package/dist/agent-src/skills/dashboard-design/SKILL.md +1 -1
  273. package/dist/agent-src/skills/data-handling-judgment/SKILL.md +1 -1
  274. package/dist/agent-src/skills/deal-qualification-meddic/SKILL.md +2 -2
  275. package/dist/agent-src/skills/decision-record/SKILL.md +3 -3
  276. package/dist/agent-src/skills/decision-review/SKILL.md +8 -8
  277. package/dist/agent-src/skills/deep-reading-analyst/SKILL.md +22 -22
  278. package/dist/agent-src/skills/design-intelligence/SKILL.md +4 -4
  279. package/dist/agent-src/skills/design-intelligence/references/context-and-registers.md +2 -2
  280. package/dist/agent-src/skills/design-review/SKILL.md +4 -4
  281. package/dist/agent-src/skills/design-system-capture/references/design-system-json.md +20 -1
  282. package/dist/agent-src/skills/design-tokens/SKILL.md +17 -2
  283. package/dist/agent-src/skills/design-variations/SKILL.md +2 -2
  284. package/dist/agent-src/skills/developer-like-execution/SKILL.md +2 -2
  285. package/dist/agent-src/skills/discovery-interview/SKILL.md +2 -2
  286. package/dist/agent-src/skills/doc-coauthoring/SKILL.md +3 -3
  287. package/dist/agent-src/skills/editorial-calendar/SKILL.md +2 -2
  288. package/dist/agent-src/skills/error-handling-patterns/SKILL.md +9 -0
  289. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +44 -1
  290. package/dist/agent-src/skills/existing-ui-audit/references/anti-slop-cross-reference.md +2 -2
  291. package/dist/agent-src/skills/expansion-playbook/SKILL.md +2 -2
  292. package/dist/agent-src/skills/experiment-loop/SKILL.md +1 -1
  293. package/dist/agent-src/skills/experiment-loop/references/protocol.md +1 -1
  294. package/dist/agent-src/skills/fe-design/SKILL.md +3 -3
  295. package/dist/agent-src/skills/fe-design/references/design-patterns.md +1 -1
  296. package/dist/agent-src/skills/fe-design/references/design-read-and-memory.md +3 -3
  297. package/dist/agent-src/skills/fe-design/references/source-led-port.md +1 -1
  298. package/dist/agent-src/skills/feature-planning/SKILL.md +1 -1
  299. package/dist/agent-src/skills/flux/SKILL.md +1 -1
  300. package/dist/agent-src/skills/forecast-accuracy/SKILL.md +2 -2
  301. package/dist/agent-src/skills/forecasting/SKILL.md +2 -2
  302. package/dist/agent-src/skills/fundraising-narrative/SKILL.md +2 -2
  303. package/dist/agent-src/skills/funnel-analysis/SKILL.md +2 -2
  304. package/dist/agent-src/skills/gtm-launch/SKILL.md +2 -2
  305. package/dist/agent-src/skills/hiring-loop-design/SKILL.md +1 -1
  306. package/dist/agent-src/skills/html-deck/SKILL.md +5 -5
  307. package/dist/agent-src/skills/humanizer/SKILL.md +1 -1
  308. package/dist/agent-src/skills/humanizer/data/patterns.md +1 -1
  309. package/dist/agent-src/skills/iconography/SKILL.md +3 -3
  310. package/dist/agent-src/skills/judge-synthesis/SKILL.md +1 -1
  311. package/dist/agent-src/skills/laravel-api-endpoint/SKILL.md +2 -2
  312. package/dist/agent-src/skills/launch-readiness/SKILL.md +3 -3
  313. package/dist/agent-src/skills/learning-to-rule-or-skill/SKILL.md +6 -6
  314. package/dist/agent-src/skills/livewire/SKILL.md +1 -1
  315. package/dist/agent-src/skills/market-entry-analysis/SKILL.md +1 -1
  316. package/dist/agent-src/skills/mcp-builder/SKILL.md +1 -1
  317. package/dist/agent-src/skills/memory-consolidation/SKILL.md +3 -3
  318. package/dist/agent-src/skills/messaging-architecture/SKILL.md +2 -2
  319. package/dist/agent-src/skills/monorepo-workspace/SKILL.md +1 -1
  320. package/dist/agent-src/skills/onboarding-design/SKILL.md +2 -2
  321. package/dist/agent-src/skills/onboarding-program/SKILL.md +1 -1
  322. package/dist/agent-src/skills/one-on-one-cadence/SKILL.md +1 -1
  323. package/dist/agent-src/skills/org-design/SKILL.md +1 -1
  324. package/dist/agent-src/skills/overbuild-review-lens/SKILL.md +3 -3
  325. package/dist/agent-src/skills/override-management/SKILL.md +1 -1
  326. package/dist/agent-src/skills/perf-feedback-craft/SKILL.md +1 -1
  327. package/dist/agent-src/skills/persona-writing/SKILL.md +1 -1
  328. package/dist/agent-src/skills/php-coder/SKILL.md +1 -1
  329. package/dist/agent-src/skills/pipeline-strategy/SKILL.md +2 -2
  330. package/dist/agent-src/skills/playwright-testing/SKILL.md +3 -3
  331. package/dist/agent-src/skills/po-discovery/SKILL.md +1 -1
  332. package/dist/agent-src/skills/positioning-strategy/SKILL.md +2 -2
  333. package/dist/agent-src/skills/privacy-review/SKILL.md +1 -1
  334. package/dist/agent-src/skills/prompt-optimizer/SKILL.md +3 -3
  335. package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +1 -1
  336. package/dist/agent-src/skills/reasoning-orchestrator/SKILL.md +2 -2
  337. package/dist/agent-src/skills/receiving-code-review/SKILL.md +1 -1
  338. package/dist/agent-src/skills/refine-ticket/SKILL.md +2 -2
  339. package/dist/agent-src/skills/release-comms/SKILL.md +2 -2
  340. package/dist/agent-src/skills/retention-loops/SKILL.md +2 -2
  341. package/dist/agent-src/skills/review-routing/SKILL.md +2 -2
  342. package/dist/agent-src/skills/roadmap-management/SKILL.md +1 -1
  343. package/dist/agent-src/skills/roadmap-management/references/archival.md +1 -1
  344. package/dist/agent-src/skills/roadmap-writing/SKILL.md +5 -5
  345. package/dist/agent-src/skills/rule-writing/SKILL.md +6 -6
  346. package/dist/agent-src/skills/runway-cognition/SKILL.md +2 -2
  347. package/dist/agent-src/skills/scenario-modeling/SKILL.md +2 -2
  348. package/dist/agent-src/skills/skill-writing/SKILL.md +2 -2
  349. package/dist/agent-src/skills/skill-writing/references/procedure.md +1 -1
  350. package/dist/agent-src/skills/skill-writing/references/section-patterns.md +3 -3
  351. package/dist/agent-src/skills/spreadsheet-authoring/SKILL.md +1 -1
  352. package/dist/agent-src/skills/stakeholder-tradeoff/SKILL.md +3 -3
  353. package/dist/agent-src/skills/subagent-orchestration/SKILL.md +1 -1
  354. package/dist/agent-src/skills/supply-chain-intake/SKILL.md +1 -1
  355. package/dist/agent-src/skills/systematic-debugging/SKILL.md +2 -2
  356. package/dist/agent-src/skills/tailwind-engineer/SKILL.md +11 -5
  357. package/dist/agent-src/skills/throughput-vs-morale-tradeoff/SKILL.md +1 -1
  358. package/dist/agent-src/skills/token-optimizer/SKILL.md +1 -1
  359. package/dist/agent-src/skills/typography-system/SKILL.md +2 -2
  360. package/dist/agent-src/skills/ui-component-architect/SKILL.md +28 -8
  361. package/dist/agent-src/skills/unit-economics-modeling/SKILL.md +2 -2
  362. package/dist/agent-src/skills/upstream-contribute/SKILL.md +1 -1
  363. package/dist/agent-src/skills/validate-feature-fit/SKILL.md +2 -2
  364. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +2 -2
  365. package/dist/agent-src/skills/vision-articulation/SKILL.md +1 -1
  366. package/dist/agent-src/skills/voc-extract/SKILL.md +2 -2
  367. package/dist/agent-src/skills/voice-and-tone-design/SKILL.md +2 -2
  368. package/dist/agent-src/skills/wireframe/SKILL.md +1 -1
  369. package/dist/agent-src/skills/workspace-link/SKILL.md +1 -1
  370. package/dist/agent-src/templates/agent-settings.md +6 -6
  371. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  372. package/dist/agent-src/templates/contexts/knowledge-pages.md +2 -3
  373. package/dist/agent-src/templates/copilot-instructions.md +1 -1
  374. package/dist/agent-src/templates/roadmaps.md +1 -1
  375. package/dist/agent-src/templates/scripts/README.md +2 -2
  376. package/dist/agent-src/user-types/_template/user-type.md +1 -1
  377. package/dist/cli-delegate/check_update_banner.js +12 -1
  378. package/dist/cli-delegate/{chunk-NLP54U3J.js → chunk-2XY7ILBT.js} +13 -1
  379. package/dist/cli-delegate/{chunk-IAI3XL43.js → chunk-3FKR64R5.js} +22 -6
  380. package/dist/cli-delegate/{chunk-J3RFNKG4.js → chunk-55ACLDUE.js} +2 -2
  381. package/dist/cli-delegate/{chunk-PKOBQADP.js → chunk-57PN4GYJ.js} +1 -1
  382. package/dist/cli-delegate/{chunk-KCNTUSPI.js → chunk-AK6HODNQ.js} +4 -4
  383. package/dist/cli-delegate/{chunk-2FTMENJL.js → chunk-GYC3VRYN.js} +1 -1
  384. package/dist/cli-delegate/{chunk-LWTYTX6F.js → chunk-H32DGUJH.js} +15 -84
  385. package/dist/cli-delegate/{chunk-6RJA2F5A.js → chunk-IVBPRCQO.js} +1 -1
  386. package/dist/cli-delegate/chunk-NUHLI2RX.js +80 -0
  387. package/dist/cli-delegate/{chunk-TYSY33MD.js → chunk-QJWAUMJW.js} +12 -2
  388. package/dist/cli-delegate/{chunk-2KKXJW25.js → chunk-S3VFXMTM.js} +1 -1
  389. package/dist/cli-delegate/{chunk-I6RHFQEG.js → chunk-YUM5KURG.js} +17 -1
  390. package/dist/cli-delegate/cmd_analyze_session.js +1 -1
  391. package/dist/cli-delegate/cmd_brand_status.js +1 -1
  392. package/dist/cli-delegate/cmd_conformance.js +834 -275
  393. package/dist/cli-delegate/cmd_doctor.js +3 -3
  394. package/dist/cli-delegate/cmd_explain.js +5 -3
  395. package/dist/cli-delegate/cmd_export.js +4 -4
  396. package/dist/cli-delegate/cmd_handoff.js +6 -6
  397. package/dist/cli-delegate/cmd_mcp_available.js +1 -1
  398. package/dist/cli-delegate/cmd_memory_get.js +1 -1
  399. package/dist/cli-delegate/cmd_migrate.js +2 -2
  400. package/dist/cli-delegate/cmd_packs_active.js +3 -2
  401. package/dist/cli-delegate/cmd_prune.js +4 -4
  402. package/dist/cli-delegate/cmd_route_audit.js +3 -3
  403. package/dist/cli-delegate/cmd_route_explain.js +1 -1
  404. package/dist/cli-delegate/cmd_session_recycle.js +3 -3
  405. package/dist/cli-delegate/cmd_settings_get.js +15 -9
  406. package/dist/cli-delegate/cmd_settings_migrate.js +4 -4
  407. package/dist/cli-delegate/cmd_settings_set.js +54 -11
  408. package/dist/cli-delegate/cmd_sync.js +4 -4
  409. package/dist/cli-delegate/cmd_uninstall.js +4 -4
  410. package/dist/cli-delegate/cmd_update.js +1 -1
  411. package/dist/cli-delegate/cmd_upgrade.js +1 -1
  412. package/dist/cli-delegate/cmd_validate.js +4 -4
  413. package/dist/cli-delegate/cmd_versions.js +1 -1
  414. package/dist/discovery/deprecation-report.md +1 -1
  415. package/dist/discovery/discovery-manifest.json +25 -78
  416. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  417. package/dist/discovery/discovery-manifest.summary.md +3 -3
  418. package/dist/discovery/dormancy-report.md +1 -1
  419. package/dist/discovery/orphan-report.md +1 -1
  420. package/dist/discovery/packs.json +5 -7
  421. package/dist/discovery/trust-report.md +2 -2
  422. package/dist/discovery/workspaces.json +4 -6
  423. package/dist/hooks/dispatch.js +9684 -9304
  424. package/dist/install/install.mjs +36 -8
  425. package/dist/mcp/registry-manifest.json +3 -3
  426. package/dist/mcp/server.json +2 -2
  427. package/dist/mcp/server.mjs +2147 -1470
  428. package/dist/router.json +1 -1
  429. package/dist/scripts/_lib/agent_settings.js +73 -0
  430. package/dist/scripts/_lib/agent_src.js +20 -0
  431. package/dist/scripts/_lib/guidelines_lane.js +158 -0
  432. package/dist/scripts/_lib/installed_lock.js +1 -1
  433. package/dist/scripts/condense.js +2 -5
  434. package/dist/server/io/yamlIO.js +175 -17
  435. package/dist/server/schemas/settings.js +18 -4
  436. package/dist/shared/settingsSurface.js +6 -1
  437. package/docs/contracts/settings-classes.md +18 -9
  438. package/docs/guidelines/abstraction-thresholds.md +35 -0
  439. package/docs/guidelines/agent-infra/active-remediation-mechanics.md +3 -3
  440. package/docs/guidelines/agent-infra/false-green.md +2 -2
  441. package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
  442. package/docs/guidelines/agent-infra/skill-quality-checklist.md +1 -1
  443. package/docs/guidelines/design-fidelity-mechanics.md +4 -0
  444. package/docs/guidelines/design-fidelity-routing.md +78 -0
  445. package/docs/guidelines/design-reconciliation.md +172 -0
  446. package/docs/guidelines/gtm-handoff.md +2 -2
  447. package/docs/guidelines/wing4-handoff.md +2 -2
  448. package/package.json +7 -3
  449. package/src/config/agent-settings.template.yml +55 -8
  450. package/src/config/ci-local-parity.yml +34 -0
  451. package/src/config/continuity-surface.json +11 -32
  452. package/src/config/gate-coverage.yml +31 -8
  453. package/src/config/gate-reachability-exemptions.json +1 -0
  454. package/src/config/gate-violation-baselines.json +3 -3
  455. package/src/config/hook-token-budget.json +1 -1
  456. package/src/config/host-injection-effect.json +2 -2
  457. package/src/config/pack-size-budget.json +55 -4
  458. package/src/config/platform-anchor.json +47 -0
  459. package/src/config/preamble-payload-budget.json +12 -8
  460. package/src/config/preamble-payload-exceptions.json +28 -0
  461. package/src/config/publish-surface.json +4 -2
  462. package/src/config/ratification-policy.json +7 -0
  463. package/src/config/rule-stub-ceilings.json +16 -9
  464. package/src/scripts/_cli/cmd_settings_get.ts +22 -7
  465. package/src/scripts/_dispatch.bash +3 -1
  466. package/src/scripts/_lib/agent_settings.ts +85 -0
  467. package/src/scripts/_lib/agent_src.ts +21 -0
  468. package/src/scripts/_lib/artifact_maturity.ts +242 -0
  469. package/src/scripts/_lib/base_ref_payload.ts +315 -0
  470. package/src/scripts/_lib/conformance_report.ts +403 -0
  471. package/src/scripts/_lib/continuity_writer.ts +72 -13
  472. package/src/scripts/_lib/design_system_import.ts +20 -0
  473. package/src/scripts/_lib/design_tolerance.ts +281 -0
  474. package/src/scripts/_lib/dropped_decision.ts +142 -0
  475. package/src/scripts/_lib/guidelines_lane.ts +164 -0
  476. package/src/scripts/_lib/installed_lock.ts +1 -1
  477. package/src/scripts/_lib/measured_payload_ceiling.ts +424 -0
  478. package/src/scripts/_lib/obligation_frequency.ts +2 -3
  479. package/src/scripts/_lib/payload_catalogue_completeness.ts +211 -0
  480. package/src/scripts/_lib/platform_anchor.ts +1053 -0
  481. package/src/scripts/_lib/ratification_artifact.ts +278 -0
  482. package/src/scripts/_lib/release_findings_ingest.ts +324 -0
  483. package/src/scripts/_lib/release_tag_dispatch.ts +63 -0
  484. package/src/scripts/_lib/review_baseline.ts +254 -0
  485. package/src/scripts/_lib/review_skipped_record.ts +61 -1
  486. package/src/scripts/_lib/security_lint.ts +23 -2
  487. package/src/scripts/_lib/self_repair.ts +21 -0
  488. package/src/scripts/_lib/session_index_trust.ts +42 -1
  489. package/src/scripts/_lib/standing_bound_ratchet.ts +267 -88
  490. package/src/scripts/_lib/tolerance_shadow.ts +177 -0
  491. package/src/scripts/_lib/turn_end_refusals.ts +51 -4
  492. package/src/scripts/ai_council/redact_low_impact_entry.ts +8 -0
  493. package/src/scripts/autonomy_friction_traffic.ts +379 -0
  494. package/src/scripts/check_beta_review_markers.ts +35 -4
  495. package/src/scripts/check_finding_dispositions.ts +167 -16
  496. package/src/scripts/check_held_object_arrivals.ts +381 -0
  497. package/src/scripts/check_kernel_edit_ratified.ts +462 -0
  498. package/src/scripts/check_loss_class_declared.ts +793 -46
  499. package/src/scripts/check_platform_anchor.ts +390 -0
  500. package/src/scripts/check_preamble_payload_budget.ts +672 -107
  501. package/src/scripts/check_projected_rule_routes.ts +395 -0
  502. package/src/scripts/check_release_published.ts +1 -1
  503. package/src/scripts/check_reply_consistency.ts +86 -17
  504. package/src/scripts/code_graph/cli.ts +6 -0
  505. package/src/scripts/condense.ts +2 -6
  506. package/src/scripts/generate_host_cost_table.ts +354 -0
  507. package/src/scripts/hook_manifest.json +1 -1
  508. package/src/scripts/hook_manifest.yaml +74 -30
  509. package/src/scripts/hooks/block_kernel_rule_writes.ts +12 -2
  510. package/src/scripts/hooks/category_a.ts +1 -1
  511. package/src/scripts/hooks/chain_nudge_hook.ts +311 -25
  512. package/src/scripts/hooks/concern_registry.ts +2 -0
  513. package/src/scripts/hooks/end_review_nudge_hook.ts +101 -21
  514. package/src/scripts/hooks/review_baseline_hook.ts +130 -0
  515. package/src/scripts/hooks/session_eol_hook.ts +68 -154
  516. package/src/scripts/hooks/source_first_gate_hook.ts +12 -0
  517. package/src/scripts/hooks/turn_end_gate_hook.ts +232 -14
  518. package/src/scripts/hooks/ui_route_nudge_hook.ts +52 -15
  519. package/src/scripts/hooks_doctor.ts +4 -1
  520. package/src/scripts/hot_context_hook.ts +41 -401
  521. package/src/scripts/install.ts +1 -1
  522. package/src/scripts/interruption_report.ts +8 -2
  523. package/src/scripts/janitor.ts +8 -1
  524. package/src/scripts/lint_evidence_artifacts.ts +1 -0
  525. package/src/scripts/lint_knowledge_scale.ts +0 -26
  526. package/src/scripts/measure_turn_end_gate.ts +302 -5
  527. package/src/scripts/memory_lookup.ts +9 -9
  528. package/src/scripts/release.ts +52 -64
  529. package/src/scripts/release_drill.ts +193 -14
  530. package/src/scripts/release_env.ts +1 -1
  531. package/src/scripts/release_publication.ts +1 -1
  532. package/src/scripts/report_held_object_arrivals.ts +456 -0
  533. package/src/scripts/report_standing_payload_by_host.ts +7 -7
  534. package/src/scripts/session_memory_index.ts +5 -0
  535. package/src/scripts/sync_agent_settings.ts +394 -12
  536. package/src/server/io/yamlIO.ts +175 -17
  537. package/src/server/schemas/settings.ts +25 -5
  538. package/src/shared/settingsSurface.ts +13 -2
  539. package/src/templates/compact-instructions.md +8 -3
  540. package/dist/agent-src/commands/chat-history/import.md +0 -170
  541. package/dist/agent-src/commands/chat-history.md +0 -63
@@ -32,6 +32,7 @@ import * as path from 'node:path';
32
32
  import { fileURLToPath, pathToFileURL } from 'node:url';
33
33
  import * as YAML from 'yaml';
34
34
  import { _domains_command_logical, artefact_roots as _agent_src_artefact_roots, iter_all_sources as _agent_src_iter_all_sources, resolve_logical as _agent_src_resolve_logical, strip_source_prefix, } from './_lib/agent_src.js';
35
+ import { rewriteProjectedBodyLinks } from './_lib/guidelines_lane.js';
35
36
  // Import-safety note: `project_thin_rules` guards its CLI entry
36
37
  // (`_isCliEntry()` before `process.exit(main())`), so importing it here is
37
38
  // side-effect-free. condense.ts is bundled into the installer, where a bare
@@ -693,7 +694,6 @@ const _PROJECTED_SRC_PREFIX = 'dist/agent-src/';
693
694
  const _LEGACY_PROJECTED_SRC_PREFIX = '.agent-src/';
694
695
  const _FM_LIST_ITEM_RE = /^(\s*-\s*)(["']?)([^"'\n]+?\.md)(["']?)\s*$/;
695
696
  const _FM_PATH_PREFIX_RE = /^(\s*(?:-\s+)?path_prefix:\s*)(["']?)([^"'\n]+?)(["']?)\s*$/;
696
- const _BODY_DOCS_RE = /\.\.\/\.\.\/(docs\/(?:guidelines|contracts)\/[^)\s]+\.md)/g;
697
697
  const _FM_PLAIN_LIST_RE = /^\s*-\s*(["']?)([^"'\n]+?)\1\s*$/;
698
698
  const _HRR_BANNER_MARKER = '<!-- agent-config:human-review-banner -->';
699
699
  function _depth_prefix(source_relative_path) {
@@ -766,9 +766,6 @@ function _rewrite_frontmatter_lines(lines, prefix) {
766
766
  }
767
767
  return out;
768
768
  }
769
- function _rewrite_body_links(body, prefix) {
770
- return body.replace(_BODY_DOCS_RE, (_m, tail) => prefix + tail);
771
- }
772
769
  function _parse_trust_and_owner(fm_lines) {
773
770
  let level = 'core';
774
771
  let hrr = false;
@@ -822,7 +819,7 @@ function _inject_hrr_banner(body, level, owner) {
822
819
  export function _rewrite_paths(content, source_relative_path) {
823
820
  const prefix = _depth_prefix(source_relative_path);
824
821
  const [fm_lines, bodyInitial] = _split_frontmatter(content);
825
- let body = _rewrite_body_links(bodyInitial, prefix);
822
+ let body = rewriteProjectedBodyLinks(bodyInitial, prefix);
826
823
  if (fm_lines === null) {
827
824
  return body;
828
825
  }
@@ -33,6 +33,24 @@ function formatScalar(value) {
33
33
  // Arrays / nested objects: dump inline. Form keeps depth ≤ 2 so this is rare.
34
34
  return yamlDump(value, { lineWidth: -1, flowLevel: 0 }).replace(/\n$/, '').trim();
35
35
  }
36
+ /**
37
+ * A NESTED mapping key, as both the presence probe and the insertion walk read
38
+ * one. Shared so the writer and its own existence-probe cannot drift apart —
39
+ * that drift is the shape this file has now hit four times.
40
+ *
41
+ * `-` is in the class because a dashed key is ordinary YAML (`first-name`,
42
+ * `dry-run`, `retry-count`) and `detectIndentWidth` already accepted one.
43
+ * While this pattern did not, `findScalarLine` could never find such a key:
44
+ * `mergeIntoTemplate` then wrote a bogus top-level `x.first-principles:` line
45
+ * beside the real nested one and the intended value was never written — a save
46
+ * that silently did nothing — and `upsertScalar` appended another child line on
47
+ * EVERY call, growing without bound until the file stopped parsing.
48
+ *
49
+ * `.` stays OUT, deliberately. A dotted key is the FLAT form, which
50
+ * `replaceFlatDottedKey` owns; letting this pattern match `a.b:` would make the
51
+ * nested probe claim a line that is one key literally named "a.b".
52
+ */
53
+ const NESTED_KEY_RE = /^([A-Za-z_][A-Za-z0-9_-]*)\s*:/;
36
54
  function flatten(value, prefix = []) {
37
55
  if (value === null || typeof value !== 'object' || Array.isArray(value)) {
38
56
  return [{ path: prefix, value }];
@@ -55,6 +73,25 @@ export function replaceScalar(template, dottedPath, value) {
55
73
  const sections = dottedPath.slice(0, -1);
56
74
  const key = dottedPath[dottedPath.length - 1];
57
75
  const lines = template.split('\n');
76
+ const at = findScalarLine(lines, sections, key);
77
+ if (at === -1)
78
+ return template;
79
+ const width = detectIndentWidth(lines);
80
+ lines[at] = `${' '.repeat(width * sections.length)}${key}: ${formatScalar(value)}`;
81
+ return lines.join('\n');
82
+ }
83
+ /**
84
+ * Index of the line holding the scalar at `sections`/`key`, or -1.
85
+ *
86
+ * Split out of `replaceScalar` so that "is this path present?" is answerable
87
+ * WITHOUT writing. `mergeIntoTemplate` used to infer presence from
88
+ * `replaceScalar` returning a changed string, which conflates "absent" with
89
+ * "present and already equal to the value being written" — under that test a
90
+ * no-op write reads as a miss and the caller appends a duplicate mapping key.
91
+ * A presence question answered by a mutation's side effect is the shape to
92
+ * look for here; the file already carries two earlier rounds of it.
93
+ */
94
+ function findScalarLine(lines, sections, key) {
58
95
  // The document's own width, the same read `upsertScalar` performs.
59
96
  //
60
97
  // R2 round 5, finding 1, and it is the second half of round 4's finding 7.
@@ -71,9 +108,7 @@ export function replaceScalar(template, dottedPath, value) {
71
108
  // A writer and its own existence-probe disagreeing about the format is the
72
109
  // shape to look for whenever one of a pair is taught something new.
73
110
  const width = detectIndentWidth(lines);
74
- const targetIndent = ' '.repeat(width * sections.length);
75
111
  const currentPath = new Array(sections.length).fill(null);
76
- const formatted = formatScalar(value);
77
112
  for (let i = 0; i < lines.length; i++) {
78
113
  const line = lines[i];
79
114
  if (line === undefined)
@@ -87,7 +122,7 @@ export function replaceScalar(template, dottedPath, value) {
87
122
  const level = indentLen / width;
88
123
  if (level > sections.length)
89
124
  continue;
90
- const m = /^([A-Za-z_][A-Za-z0-9_]*)\s*:/.exec(stripped);
125
+ const m = NESTED_KEY_RE.exec(stripped);
91
126
  if (!m)
92
127
  continue;
93
128
  const lineKey = m[1];
@@ -110,10 +145,9 @@ export function replaceScalar(template, dottedPath, value) {
110
145
  continue;
111
146
  if (lineKey !== key)
112
147
  continue;
113
- lines[i] = `${targetIndent}${key}: ${formatted}`;
114
- return lines.join('\n');
148
+ return i;
115
149
  }
116
- return template;
150
+ return -1;
117
151
  }
118
152
  /**
119
153
  * The indent width this document actually uses, or 2 when it has no nesting.
@@ -181,11 +215,19 @@ export function detectIndentWidth(lines) {
181
215
  export function upsertScalar(template, dottedPath, value) {
182
216
  if (dottedPath.length === 0)
183
217
  return template;
184
- const replaced = replaceScalar(template, dottedPath, value);
185
- if (replaced !== template)
186
- return replaced;
187
218
  const sections = dottedPath.slice(0, -1);
188
219
  const key = dottedPath[dottedPath.length - 1];
220
+ // Presence is asked, never inferred from the write changing the text. The
221
+ // string compare that used to stand here read "key already holds this
222
+ // value" as "key absent" and fell through to the append below — so saving
223
+ // the wizard's council page twice WITHOUT changing a toggle wrote a second
224
+ // `api_on_quota:` into the same block, over two `{ok: true}` responses, and
225
+ // left `.ai-council.yml` rejected by a strict parser. Third instance of one
226
+ // shape in this file; `findScalarLine` exists to end it, and a fix that
227
+ // taught only `mergeIntoTemplate` would have left the live path here.
228
+ if (findScalarLine(template.split('\n'), sections, key) !== -1) {
229
+ return replaceScalar(template, dottedPath, value);
230
+ }
189
231
  const formatted = formatScalar(value);
190
232
  const lines = template.split('\n');
191
233
  // The document's OWN indent width, not an assumed two.
@@ -229,7 +271,7 @@ export function upsertScalar(template, dottedPath, value) {
229
271
  const indentLen = line.length - line.trimStart().length;
230
272
  if (indentLen !== indent.length)
231
273
  continue;
232
- const m = /^([A-Za-z_][A-Za-z0-9_]*)\s*:/.exec(line.trim());
274
+ const m = NESTED_KEY_RE.exec(line.trim());
233
275
  if (m !== null && m[1] === want) {
234
276
  found = i;
235
277
  break;
@@ -271,23 +313,139 @@ export function upsertScalar(template, dottedPath, value) {
271
313
  lines.splice(insertAt, 0, ...block);
272
314
  return lines.join('\n');
273
315
  }
316
+ /**
317
+ * Rewrite an existing top-level `a.b.c: value` line — the FLAT form
318
+ * `mergeIntoTemplate` itself appends when a path has no template entry.
319
+ * Returns the template unchanged when no such line exists.
320
+ *
321
+ * `replaceScalar` cannot see this line: its key pattern is
322
+ * `[A-Za-z_][A-Za-z0-9_]*`, with no dot, so a path this module appended on
323
+ * one pass is invisible to the probe on the next and `mergeIntoTemplate`
324
+ * appends a SECOND copy. Two wizard saves therefore produce a file carrying
325
+ * duplicate mapping keys — a strict parser rejects it outright, which is what
326
+ * wedged `task release`: its `sync` step exits 2 with "Map keys must be
327
+ * unique" before the release does any git work.
328
+ *
329
+ * A pre-existing duplicate run is COLLAPSED, not merely updated: the first
330
+ * occurrence keeps its position and takes the new value, every later one is
331
+ * dropped. Collapsing is value-neutral — a lenient reader already resolved
332
+ * such a run last-wins — and it is the only way a file corrupted by the old
333
+ * behaviour becomes parseable again through the ordinary write path.
334
+ *
335
+ * Deliberately NOT folded into `replaceScalar`: `upsertScalar` calls that
336
+ * probe and documents the flat form as the WRONG shape for a nested key (a
337
+ * reader sees one key literally named "a.b"). Teaching the shared probe to
338
+ * match it would make `upsertScalar` write into that broken line instead of
339
+ * creating the nesting. The flat form is legitimate only here, where this
340
+ * function is the one that wrote it.
341
+ */
342
+ function replaceFlatDottedKey(template, dottedPath, value) {
343
+ if (dottedPath.length < 2)
344
+ return { found: false, body: template };
345
+ const flat = dottedPath.join('.');
346
+ const lines = template.split('\n');
347
+ const hits = [];
348
+ for (let i = 0; i < lines.length; i++) {
349
+ const line = lines[i];
350
+ if (line === undefined)
351
+ continue;
352
+ // Top level only — an indented `a.b:` is somebody else's child key.
353
+ if (line.length !== line.trimStart().length)
354
+ continue;
355
+ const m = /^([A-Za-z_][A-Za-z0-9_.-]*)\s*:/.exec(line);
356
+ if (m === null || m[1] !== flat)
357
+ continue;
358
+ hits.push(i);
359
+ }
360
+ if (hits.length === 0)
361
+ return { found: false, body: template };
362
+ lines[hits[0]] = `${flat}: ${formatScalar(value)}`;
363
+ // Drop the later copies back-to-front so the earlier indices stay valid.
364
+ for (let i = hits.length - 1; i >= 1; i--)
365
+ lines.splice(hits[i], 1);
366
+ return { found: true, body: lines.join('\n') };
367
+ }
368
+ /**
369
+ * Drop every top-level `a.b.c:` line for a path whose NESTED form the caller
370
+ * has just resolved.
371
+ *
372
+ * Which reader this preserves, because the two forms can disagree and only one
373
+ * of them is ever consulted: by YAML semantics `a.b.c` is reached by walking
374
+ * the `a` mapping, so a top-level key literally named "a.b.c" is a DIFFERENT
375
+ * path that no lookup of the dotted one visits. Removing it therefore changes
376
+ * no reader's answer — strict and lenient alike already resolve through the
377
+ * nesting — while leaving it keeps the one line a human scanning the file
378
+ * reads as the value, saying something the program never agreed with. It
379
+ * cannot self-heal either: the duplicate-key pass sees a single occurrence,
380
+ * and `mergeIntoTemplate` writes the nested side, so the line is permanent.
381
+ *
382
+ * The nested twin IS the safety argument, not a convenience. A flat `a.b:`
383
+ * standing ALONE is a key somebody may have meant — `mergeIntoTemplate`'s own
384
+ * fallback branch writes exactly that shape for a path the template lacks — and
385
+ * this function is never reached for one: the caller takes the
386
+ * `replaceFlatDottedKey` branch instead, which updates that line in place.
387
+ *
388
+ * Two bounds, each of which turns the sweep into a data-loss bug if dropped:
389
+ *
390
+ * - Two segments minimum. A one-segment path joins to a name with no dot, so
391
+ * the match below would hit the very line `replaceScalar` just wrote and
392
+ * delete the key the caller asked to set — a rewrite silently becoming a
393
+ * removal. Same guard, same reason, as `replaceFlatDottedKey`.
394
+ * - Top level only, the bound `replaceFlatDottedKey` also draws: an INDENTED
395
+ * `a.b:` is somebody else's child key (`parent:` / ` a.b:` means
396
+ * `parent['a.b']`), an unrelated path this sweep has no claim on.
397
+ */
398
+ function dropFlatDottedTwins(template, dottedPath) {
399
+ if (dottedPath.length < 2)
400
+ return template;
401
+ const flat = dottedPath.join('.');
402
+ const lines = template.split('\n');
403
+ const kept = lines.filter((line) => {
404
+ if (line.length !== line.trimStart().length)
405
+ return true;
406
+ const m = /^([A-Za-z_][A-Za-z0-9_.-]*)\s*:/.exec(line);
407
+ return m === null || m[1] !== flat;
408
+ });
409
+ if (kept.length === lines.length)
410
+ return template;
411
+ return kept.join('\n');
412
+ }
274
413
  /**
275
414
  * Apply every leaf change from `newValues` to `templateBody`. Paths that
276
415
  * are not present in the template are appended at the end. Comments are
277
416
  * preserved for every key that already exists in the template.
417
+ *
418
+ * Idempotent: applying the same values twice yields the same document, so a
419
+ * second wizard save re-writes the flat block instead of duplicating it.
278
420
  */
279
421
  export function mergeIntoTemplate(templateBody, newValues) {
280
422
  let body = templateBody;
281
423
  const appended = [];
282
424
  for (const entry of flatten(newValues)) {
283
- const before = body;
284
- body = replaceScalar(body, entry.path, entry.value);
285
- if (body === before) {
286
- // Path is not in the template — append a flat key=value at EOF.
287
- // Form coverage is asserted by parity test, so this branch only
288
- // fires on hand-edited templates.
289
- appended.push(`${entry.path.join('.')}: ${formatScalar(entry.value)}`);
425
+ const sections = entry.path.slice(0, -1);
426
+ const leaf = entry.path[entry.path.length - 1];
427
+ // Presence is asked, never inferred from the write changing the text —
428
+ // see `findScalarLine`. Writing the value it already holds is a hit.
429
+ if (findScalarLine(body.split('\n'), sections, leaf) !== -1) {
430
+ body = replaceScalar(body, entry.path, entry.value);
431
+ // The nested form won, so any flat twin of this same path is dead
432
+ // and stays dead. The probe above is what licenses the removal:
433
+ // without a nested key to resolve through, a flat `a.b:` is the
434
+ // real entry and the branch below owns it.
435
+ body = dropFlatDottedTwins(body, entry.path);
436
+ continue;
437
+ }
438
+ // Not in the template's nested form. It may still be here as a flat
439
+ // dotted line this function appended on an earlier pass.
440
+ const flat = replaceFlatDottedKey(body, entry.path, entry.value);
441
+ if (flat.found) {
442
+ body = flat.body;
443
+ continue;
290
444
  }
445
+ // Genuinely absent — append a flat key=value at EOF. Form coverage is
446
+ // asserted by parity test, so this branch only fires on hand-edited
447
+ // templates.
448
+ appended.push(`${entry.path.join('.')}: ${formatScalar(entry.value)}`);
291
449
  }
292
450
  if (appended.length > 0) {
293
451
  if (!body.endsWith('\n'))
@@ -101,7 +101,7 @@ export const settingsSchema = z.object({
101
101
  access_style: accessStyle.default('getters_setters').describe('How the agent writes Laravel Eloquent property access. getters_setters = explicit getName() / setName() methods (most refactor-safe). get_attribute = $model->getAttribute("name") (verbose but explicit). magic_properties = $model->name (idiomatic but harder to grep).'),
102
102
  }),
103
103
  chat_history: z.object({
104
- enabled: z.boolean().default(true).describe('Persist a structured log of every chat turn to .agent-config/chat-history/ so /chat-history:show, :import, and :learn can replay sessions. Turn off if you never want chat transcripts on disk.'),
104
+ enabled: z.boolean().default(true).describe('Persist a structured log of every chat turn to agents/runtime/.agent-chat-history (JSONL). Recording only — no command in this package replays a session from the file; it is a record on disk that a human or a later tool can read. Turn off if you never want chat transcripts on disk.'),
105
105
  frequency: chatFreq.default('per_turn').describe('How often the chat-history writer flushes to disk. per_turn = after every user / agent exchange (default, lowest data loss on crash). per_phase = at phase boundaries (cheaper I/O). per_tool = after every tool call (highest fidelity, noisiest log).'),
106
106
  text_limits: z.object({
107
107
  user: z.number().int().min(0).default(0).describe('Per-message character cap for user inputs in the chat-history log. 0 = log verbatim (default). Raise above 0 only if your prompts contain large pasted artefacts you do not want stored.'),
@@ -140,7 +140,21 @@ export const settingsSchema = z.object({
140
140
  }),
141
141
  design: z.object({
142
142
  fidelity_mode: fidelityMode.default('strict').describe('How strictly the agent must follow a user-provided prototype / mockup / design system (consumed by the design-fidelity rule). strict = build 1:1, every visible deviation needs confirmation; structural = structure locked, silent gaps fillable with a stated assumption; hard-floor = any deviation is never autonomous.'),
143
- }).default({ fidelity_mode: 'strict' }),
143
+ approximation: z
144
+ .object({
145
+ enabled: z.boolean().default(false).describe('Whether a value INSIDE the configured tolerance may be replaced by the project\'s own token without a per-value confirmation. Ships false. The distance from the artifact\'s value to the nearest project token is computed and REPORTED on every value row regardless of this switch — what it decides is whether the agent may act on it without asking. Turning it on for a whole install is a consumer-facing default flip and is owner-reserved (agents/roadmaps/stubs/road-to-frontend-power-default-flip.md); design.fidelity_mode: hard-floor overrides it to off.'),
146
+ tolerance: z
147
+ .object({
148
+ color: z.number().nullable().default(null).describe('Colour distance below which a value may be reconciled, in OKLab ΔEOK. Ships null, and null means "preserve and report" rather than "reconcile freely". No number is set because none is supported: zero of seven design-to-code benchmarks in the evidence set score token conformance, and a number in a config file — even flagged unmeasured — shapes behavior and acquires the authority of a default. Not an RGB channel delta: RGB distance is not perceptually uniform.'),
149
+ length: z.number().nullable().default(null).describe('Length distance below which a value may be reconciled, in absolute CSS pixels. Ships null, same reasoning as color. GitHub Primer\'s ±1px spacing widening is recorded as an externally observed candidate in src/scripts/_lib/design_tolerance.ts and is deliberately not the shipped value; max(1px, 2%) was rejected for growing more permissive at large dimensions with no evidence that this is wanted.'),
150
+ })
151
+ .default({ color: null, length: null }),
152
+ })
153
+ .default({ enabled: false, tolerance: { color: null, length: null } }),
154
+ }).default({
155
+ fidelity_mode: 'strict',
156
+ approximation: { enabled: false, tolerance: { color: null, length: null } },
157
+ }),
144
158
  consistency: z.object({
145
159
  cross_source: crossSourceMode.default('on').describe('Consumed by the cross-source-consistency rule. When the agent works from multiple sources (ticket text, an attached image/mockup, the spec, the codebase) it checks them against each other and asks before proceeding on a discrepancy — instead of silently guessing. on (default) = surface every real cross-source contradiction / silent-scope-expansion as one question; auto = surface only high-confidence contradictions, state low-confidence as an assumption; off = no cross-source checking.'),
146
160
  }).default({ cross_source: 'on' }),
@@ -239,8 +253,8 @@ export const settingsSchema = z.object({
239
253
  }),
240
254
  }),
241
255
  continuity: z.object({
242
- auto_record: z.enum(['on', 'off']).default('off').describe('Deterministic continuity-record writer at session end (road-to-continuity-writer-activation Phase 1). on = the session-eol concern writes the continuity_record capsule variant on Stop for a substantive session that has claimed a roadmap; every field is computed from on-disk state, with no model spend and no subprocess. off (default) = no automatic record — while session:recycle is still the normal path, a second producer on it before the parity evidence is in would be unverified.'),
243
- run_checkpoints: z.enum(['on', 'off']).default('on').describe('Deterministic run-checkpoint production at session end (road-to-continuity-writer-activation Phase 1.4). on (default) = a session above the recycle threshold and inside a running roadmap contract leaves agents/runtime/state/checkpoints/<run>.json, so a killed run resumes from a derived checkpoint rather than from bookkeeping. off = no checkpoint; continuity writing, the recycle advisory and the context-fill surface are unaffected. Default ON because it is the behaviour the tree already had — the switch exists to make the three session-end handlers independently disableable, not to change what ships.'),
256
+ auto_record: z.enum(['on', 'off']).default('on').describe('Deterministic continuity-record writer at session end (road-to-continuity-writer-activation Phase 1). on (default since 2026-09-10) = the session-eol concern writes the continuity_record capsule variant on Stop for a substantive session that has claimed a roadmap; every field is computed from on-disk state, with no model spend and no subprocess. off = no automatic record, and only the explicit agent-config session:recycle writes one. The default flipped once the parity evidence landed, so the normal path carries an automatic writer rather than a remembered command; session:recycle is retained because the automatic writer skips a session that claimed no roadmap and omits the git-status anchors.'),
257
+ run_checkpoints: z.enum(['on', 'off']).default('on').describe('Deterministic run-checkpoint production at session end (road-to-continuity-writer-activation Phase 1.4). on (default) = a session above the recycle threshold and inside a running roadmap contract leaves agents/runtime/state/checkpoints/<run>.json, so a killed run resumes from a derived checkpoint rather than from bookkeeping. off = no checkpoint; continuity writing, the recycle advisory and the context-fill surface are unaffected. Default ON because it is the behavior the tree already had — the switch exists to make the three session-end handlers independently disableable, not to change what ships.'),
244
258
  }),
245
259
  memory: z.object({
246
260
  cadence: memoryCadence.default('always').describe('Cadence of the 🧠 memory-visibility line after a memory-consulting step. always (default) = show whenever a memory type was asked; auto = show only when 3+ types were consulted (less noise); never = suppress. Distinct from rule_loading_tier — owns its own key since the 2026-06-01 untangle.'),
@@ -77,7 +77,12 @@ export function computeSurfaceDelta(oldS, newS) {
77
77
  continue;
78
78
  }
79
79
  const o = oldS.entries[key];
80
- if (o.type !== n.type) {
80
+ // `sameJson`, not `!==`: `type` is an array for a nullable key, and two
81
+ // structurally equal arrays are never `===`. Left as a strict compare
82
+ // it reported `type_changed` on EVERY version bump for every nullable
83
+ // key, forever — caught by the identical-surface test the moment the
84
+ // first one shipped (`design.approximation.tolerance.*`).
85
+ if (!sameJson(o.type, n.type)) {
81
86
  changes.push({ key, kind: 'type_changed', old: o, new: n });
82
87
  }
83
88
  if (!sameJson(o.default, n.default)) {
@@ -247,8 +247,8 @@ dispatch runs, not WHETHER the layer exists, so they keep their own C rows.
247
247
  |---|---|
248
248
  | A — preference | 26 |
249
249
  | B — consent | 3 |
250
- | C — guarded | 113 |
251
- | **Total** | **142** |
250
+ | C — guarded | 116 |
251
+ | **Total** | **145** |
252
252
 
253
253
  It rose to 142 on 2026-09-08 from two independent additions that landed in the same
254
254
  day and are counted together here: `lean_projection.hosts` (one C, `policy`, from
@@ -258,9 +258,15 @@ side's figure to the other, which is the arithmetic `lint_settings_classes` chec
258
258
 
259
259
  It rose on 2026-09-08 when `road-to-continuity-writer-activation`
260
260
  step 1.2 added `continuity.auto_record` — one C, `consent`: it arms an automatic
261
- producer on the normal session-end path, and the roadmap step requires the
262
- default to stay `off` until parity is measured, which is a decision no agent may
263
- take by writing the key. Step 1.4 added
261
+ producer on the normal session-end path, and the roadmap step required the
262
+ default to stay `off` until parity was measured, which is a decision no agent may
263
+ take by writing the key. **It ships `on` since 2026-09-10.** The class did not
264
+ change and neither did the write protection — `settings:set` still refuses this
265
+ key. What changed is the shipped default, edited by hand in the template and the
266
+ schema on a recorded AI-council verdict (2026-09-10, 2 seats, convergent, under
267
+ the owner's written delegation), which is the route a class-C default moves by
268
+ and the reason the refusal in `settings:set` is not a contradiction: the guard
269
+ stops an agent from deciding, not a recorded decision from being applied. Step 1.4 added
264
270
  `continuity.run_checkpoints` the same day — a second C, shipping `on` because
265
271
  that is the behavior the tree already had. It exists so the three session-end
266
272
  handlers are independently disableable, which is what the 2026-09-07 council's
@@ -363,9 +369,9 @@ the template, which is the drift this contract exists to prevent.
363
369
  |---|---|
364
370
  | derivable | 83 |
365
371
  | un-inferrable | 9 |
366
- | consent | 43 |
367
- | policy | 7 |
368
- | **Total** | **142** |
372
+ | consent | 44 |
373
+ | policy | 9 |
374
+ | **Total** | **145** |
369
375
 
370
376
  First measured 2026-08-12 at 140 leaves (derivable 88 · consent 38 ·
371
377
  un-inferrable 9 · policy 5), from the table below rather than predicted — the
@@ -531,6 +537,9 @@ Rows follow template order, so a diff against the template reads straight down.
531
537
  | `planning.completion_review` | C | `true` | disables the completion-review validator | derivable — `check_completion_review`'s own scope predicate, bound to the current diff hash |
532
538
  | `quality.local_auto_run` | C | `false` | governs whether local verification runs at all | consent |
533
539
  | `design.fidelity_mode` | C | `strict` | strict-mode selector, one of whose values is a Hard Floor | policy |
540
+ | `design.approximation.enabled` | C | `false` | lets a value change without a per-value confirmation; enabling it is a consumer-facing default flip | consent |
541
+ | `design.approximation.tolerance.color` | C | `null` | decides which colour deviations may be taken silently | policy |
542
+ | `design.approximation.tolerance.length` | C | `null` | decides which length deviations may be taken silently | policy |
534
543
  | `consistency.cross_source` | C | `"on"` | disables the cross-source discrepancy gate | derivable — the rule's own trigger condition; a discrepancy exists only when two present sources contradict |
535
544
  | `screenshots.identity_allowlist` | C | `[]` | allowlist of identities that ship unredacted | consent |
536
545
  | `screenshots.forbid_terminal_capture` | C | `true` | kill-switch over the highest-leak capture path | consent |
@@ -567,7 +576,7 @@ Rows follow template order, so a diff against the template reads straight down.
567
576
  | `commands.create_pr.screenshots` | C | `false` | puts captured screenshots into a published PR body | consent |
568
577
  | `commands.create_pr.ui_paths` | C | `[]` | glob allowlist | derivable — the frontend-surface heuristic the PR-description flow already applies when the glob list is empty |
569
578
  | `commands.create_pr.api_paths` | C | `[]` | glob allowlist | derivable — the API-endpoint heuristic the same flow already applies as its documented empty-list fallback |
570
- | `continuity.auto_record` | C | `"off"` | arms an automatic producer on the normal session-end path | consent |
579
+ | `continuity.auto_record` | C | `"on"` | arms an automatic producer on the normal session-end path | consent |
571
580
  | `continuity.run_checkpoints` | C | `"on"` | disabling it removes a recovery artifact a killed run resumes from | consent |
572
581
  | `memory.cadence` | C | `always` | suppressing the visibility line hides what the agent learned from the user | derivable — the hits/asks count the memory-visibility summary already computes; the line only exists when memory was consulted |
573
582
  | `memory.review_threshold` | A | `10` | when a review preview surfaces; governs no gate | derivable — the unreviewed-intake count `/memory load` already computes before rendering its preview |
@@ -45,6 +45,41 @@ present in the diff** — never speculative abstraction for "this could grow
45
45
  later". See [`component-oriented-and-oop-development`](component-oriented-and-oop-development.md)
46
46
  § The load-bearing caveat.
47
47
 
48
+ ## The provided-artifact clause — repetition observable before the code exists
49
+
50
+ ADR-213 authorises extraction on repetition **already present in the diff**. A
51
+ handed-over **runnable** artifact makes repetition observable before any code
52
+ exists at all: four `<Card>` instances are visible in the handover, so a port
53
+ that writes them one at a time and extracts on the second is doing the
54
+ threshold's own arithmetic in the wrong order.
55
+
56
+ This is a **different mechanism** than the one the threshold tested, not a
57
+ loophole in it. `adr_cite_check ADR-213` reports the record LIVE with an
58
+ **indeterminate** review trigger and `reopen_policy: unclassified`, so
59
+ investigation is permitted; the numbers themselves — 2 · 3+ · ~4+ — are
60
+ **unchanged**, and this clause moves only *when* the count may be taken.
61
+
62
+ **Two guards, both required. The first alone is insufficient.**
63
+
64
+ 1. **A runnable artifact, not a design comp.** A comp shows a picture of four
65
+ cards; a runnable artifact carries four instances of a thing. Counting
66
+ rectangles in an image is not counting repetition, and a comp therefore does
67
+ not qualify.
68
+ 2. **Repetition of the ELEMENT, not of its compositional context.** Four
69
+ `<Card>` instances show that Card is used four times. They do **not** show
70
+ that a `CardGrid` is needed — that needs multiple distinct contexts each
71
+ arranging several cards. Without this guard the clause would license
72
+ extracting a wrapper for every layout the artifact happens to contain once,
73
+ which is speculative abstraction with an artifact as its excuse.
74
+
75
+ **Enforcement, stated honestly: guard (2) is model-carried and audit-enforced.**
76
+ Nothing mechanical separates *"I saw four Cards"* from *"I saw a CardGrid
77
+ pattern"* — the distinction is about what the repetition MEANS, and
78
+ `lint_abstraction_thresholds.ts` checks numeric threshold drift, which is a
79
+ different property. Guard (1) is checkable (is the handover runnable), guard (2)
80
+ is not, and claiming otherwise would be the coverage inflation this tree forbids
81
+ elsewhere. The discipline is the control.
82
+
48
83
  ## See also
49
84
 
50
85
  - [`architecture`](../../src/rules/architecture.md) — the rule that carries the code-level bar.
@@ -67,16 +67,16 @@ Two failure shapes this table exists to name:
67
67
 
68
68
  ### Worked example — a red gate seen mid-task
69
69
 
70
- > `task check` fails; the lint step reports 7 errors, all pre-existing on `main`, in files this branch does not touch.
70
+ > the `check` task fails; the lint step reports 7 errors, all pre-existing on `main`, in files this branch does not touch.
71
71
 
72
- Wrong, and the canonical shape of it: finish the task, and close with *"the only thing still open is the lint finding — 7 errors on main, which makes `task check` unusable as a chain"*. The sentence is accurate, the issue is named, and nothing about it is decided — the next session inherits it verbatim.
72
+ Wrong, and the canonical shape of it: finish the task, and close with *"the only thing still open is the lint finding — 7 errors on main, which makes the `check` task unusable as a chain"*. The sentence is accurate, the issue is named, and nothing about it is decided — the next session inherits it verbatim.
73
73
 
74
74
  Right: the errors are pre-existing, outside the fix-now bar (unrelated files, more than ~10 lines), so they are **note + ask** — after the task is delivered, one block:
75
75
 
76
76
  1. Fix the 3 `no-unused-vars` in `src/a.ts`, `src/b.ts` — ~6 lines, mechanical, ships in this PR.
77
77
  2. Fix all 7 in a separate follow-up PR — keeps this diff single-purpose; needs a branch (permission-gated).
78
78
  3. Suppress the two in generated output with a scoped ignore, fix the rest — smallest green path, adds a suppression to review.
79
- 4. Leave as is — `task check` stays unusable as a chain until someone else picks it up.
79
+ 4. Leave as is — the `check` task stays unusable as a chain until someone else picks it up.
80
80
 
81
81
  One recommendation line names the pick. Whatever the user answers, the item is closed. If they answer nothing, it is raised once at the next task boundary — not carried silently into a third session.
82
82
 
@@ -168,8 +168,8 @@ bash src/scripts/condense.sh --changed # dist != rewrite(src) => the scan
168
168
  ./scripts-run src/scripts/check_condensation --summary # byte-exactness dist vs rewrite(src)
169
169
  ```
170
170
 
171
- **Structural fix:** regenerate before judging (`task sync` then
172
- `task generate-tools`, in that order), and treat a baseline unchanged past
171
+ **Structural fix:** regenerate before judging — this repository's `sync` task
172
+ then its `generate-tools` task, in that order — and treat a baseline unchanged past
173
173
  `STALE_AFTER_DAYS` (56, `_lib/gate_baseline.ts:39`) as suppression rather than
174
174
  as headroom. A completion claim rests on a run made **after** the last edit, not
175
175
  on the freshest run you happen to remember.
@@ -15,7 +15,7 @@ _Origin: migrated from `.agent-src.uncondensed/rules/roadmap-progress-sync.md` p
15
15
  > 2. `.git/hooks/pre-commit` (installed by `scripts/install-hooks.sh`) —
16
16
  > blocks any commit whose staged set touches `agents/roadmaps/` or
17
17
  > `agents/roadmaps-progress.md` while the dashboard is stale.
18
- > 3. `task ci` runs `roadmap-progress-check` so a PR cannot land with a
18
+ > 3. The `ci` task runs `roadmap-progress-check` so a PR cannot land with a
19
19
  > stale dashboard even if local hooks were bypassed.
20
20
  >
21
21
  > Hook is primary; the prose below is the specification the hook
@@ -53,7 +53,7 @@ A field that carries the schema `default` (e.g. `trust.level: core`,
53
53
  `validate_frontmatter.apply_schema_defaults` injects it transparently for
54
54
  every consumer (validator, discovery manifest, drift checksum). Writing it
55
55
  anyway is boilerplate that `scripts/lint_frontmatter_boilerplate.ts` rejects
56
- (wired into `task ci-fast`). To strip it across the tree, run
56
+ (wired into this repository's `ci-fast` task). To strip it across the tree, run
57
57
  `./scripts-run src/scripts/migrate_frontmatter_defaults`. Background:
58
58
  `road-to-abstraction-reduction.md` +
59
59
  `agents/evidence/analysis/abstraction-reduction-preflight.md`.
@@ -230,6 +230,10 @@ unmarked finding is treated as actionable, so the default failure direction is
230
230
 
231
231
  Regression witness: `daf-slop-vs-provided`.
232
232
 
233
+ **Why the default is what it is, and why the 2026-07-31 council lock over this
234
+ loop cannot be discharged by measuring it:**
235
+ [`design-reconciliation § The 2026-07-31 lock`](design-reconciliation.md).
236
+
233
237
  ## Value-level provenance — the finer grain beside the flag
234
238
 
235
239
  The block above is finding-level and stays the default: `artifact_covered` is a
@@ -0,0 +1,78 @@
1
+ # Design-fidelity routing mechanics — how the trigger set is authored
2
+
3
+ Split out of [`design-fidelity-mechanics`](design-fidelity-mechanics.md) on
4
+ 2026-09-09 under `check_depth_budget`'s 16,000-character per-file ceiling. It is
5
+ also a genuinely different subject: that guideline is read while PORTING an
6
+ artifact, and this one is read while EDITING the rule's own trigger set — which
7
+ happens rarely, by a maintainer, and never during a port.
8
+
9
+ ## Routing mechanics
10
+
11
+ Migrated out of `design-fidelity.md` on 2026-09-09 under the council verdict on
12
+ `blocker: rule-body-cap` — a semantic migration that frees rule-body lines for
13
+ the operative pointers the same verdict requires, not an arbitrary line cut. The
14
+ rule keeps the obligations; this holds the reasoning behind them.
15
+
16
+ ### The withdrawn builder-URL trigger
17
+
18
+ A page built in Lovable / v0 / bolt and handed over as a share link is a
19
+ finished spec, and `design-fidelity` does not route it. The obvious trigger was
20
+ tried and **withdrawn**: matching is plain lower-cased substring containment, so
21
+ `https://v0.dev/` also fires on `https://v0.dev/docs`, on a pricing page, and on
22
+ a changelog link — it would treat every mention of the tool's own site as a spec
23
+ handover. That is exactly the `claude.ai` failure the capability-URL trigger
24
+ exists to avoid, and by the rule's own standard it is worse than the gap it
25
+ closes. The alternatives are a bare-host keyword (broader still) or guessing
26
+ each vendor's share-path segment, and a trigger built on a guessed path is not
27
+ evidence.
28
+
29
+ **What closes it:** a verified share-path segment per vendor, or a
30
+ handover-word co-occurrence the matcher cannot express today. Until then the
31
+ class needs one word in the prompt, like any other unlisted filename.
32
+ `near-bare-host-mention` in `ROUTING_MATRIX` pins the bare-host direction silent
33
+ so a future attempt cannot reintroduce the broad form unnoticed.
34
+
35
+ ### The trigger set, class by class
36
+
37
+ Phrase-heavy on the German side and on `artifact` deliberately: a bare
38
+ `artifact` keyword fires on *"the CI build artifact is 40 MB"*, which is CI
39
+ vocabulary and not a handover. `ROUTING_MATRIX` pins both halves — every class
40
+ that must route, and every near-miss that must stay silent (fixture
41
+ `daf-port-trigger-de`).
42
+
43
+ Each shipped class carries its own near-miss row, and the pairing is the
44
+ contract rather than a courtesy:
45
+
46
+ | Class | Its near-miss row | The direction that row tests |
47
+ |---|---|---|
48
+ | `phrase: claude.site/artifacts` | `near-claude-ai-chat-link` | a bare `claude.ai` chat link is a conversation reference, not a spec |
49
+ | `path_prefix: .claude/design-system/` | `near-generic-design-system-dir` | a bare `design-system/` is a normal source folder in a large fraction of frontend repos |
50
+ | `file_pattern: *.dc.html` | `near-plain-html-open-file`, `near-dc-in-a-filename` | an ordinary `.html` file in the tree; a filename that merely contains the letters |
51
+ | the withdrawn builder URL | `near-bare-host-mention` | left behind on purpose, so the broad form stays pinned silent |
52
+
53
+ ### Write the near-miss row first — and test the right direction
54
+
55
+ Extending the trigger set without adding a near-miss row is how an over-broad
56
+ trigger lands. The stronger half of the contract is *which* near-miss:
57
+
58
+ **The row must test the direction the NEW trigger opens, not a direction that
59
+ was already closed.** The withdrawn class is the worked example. Its first
60
+ near-miss row tested a protocol-less mention — silent *before* the change, and
61
+ therefore incapable of catching the over-broadness the change introduced. The
62
+ row that would have caught it is `near-builder-host-non-handover-url`, a
63
+ documentation URL on the same host, and it exists only because a review asked
64
+ for it after the trigger had already shipped.
65
+
66
+ Applied on the next trigger to land: `*.dc.html` (the Claude Design canvas
67
+ artboard, which `*design.html` cannot match because it compiles to
68
+ `^(?:.*design\.html)$`) shipped with `near-plain-html-open-file` and
69
+ `near-dc-in-a-filename` written **before** it, both testing the direction it
70
+ opens — an ordinary `.html` file in the tree, and a filename that merely
71
+ contains the letters. Both were confirmed red-then-green against the real
72
+ matcher rather than asserted.
73
+
74
+ ## See also
75
+
76
+ - [`design-fidelity-mechanics`](design-fidelity-mechanics.md) — the porting half.
77
+ - `tests/scripts/design_fidelity_routing.test.ts` — `ROUTING_MATRIX`, which is
78
+ the measurement this file describes rather than a second copy of it.