@event4u/agent-config 14.22.0 → 15.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 (557) 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 +333 -356
  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 +48 -39
  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 +1 -1
  60. package/dist/agent-src/commands/roadmap/materialize.md +2 -2
  61. package/dist/agent-src/commands/roadmap/next.md +9 -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 +1 -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 +13 -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 +36 -25
  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/scripts/archive_completed_roadmaps.ts +106 -4
  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-intelligence/SKILL.md +57 -1
  260. package/dist/agent-src/skills/code-refactoring/SKILL.md +3 -3
  261. package/dist/agent-src/skills/code-review/SKILL.md +3 -3
  262. package/dist/agent-src/skills/command-writing/SKILL.md +3 -3
  263. package/dist/agent-src/skills/comp-banding/SKILL.md +1 -1
  264. package/dist/agent-src/skills/competitive-moat-analysis/SKILL.md +1 -1
  265. package/dist/agent-src/skills/competitive-positioning/SKILL.md +2 -2
  266. package/dist/agent-src/skills/complexity-first-planning/SKILL.md +1 -1
  267. package/dist/agent-src/skills/condense-memory/SKILL.md +1 -1
  268. package/dist/agent-src/skills/content-funnel-design/SKILL.md +2 -2
  269. package/dist/agent-src/skills/contracts-cognition/SKILL.md +1 -1
  270. package/dist/agent-src/skills/copilot-agents-optimization/SKILL.md +2 -2
  271. package/dist/agent-src/skills/corpus-grounding/SKILL.md +2 -2
  272. package/dist/agent-src/skills/customer-research/SKILL.md +2 -2
  273. package/dist/agent-src/skills/dashboard-design/SKILL.md +1 -1
  274. package/dist/agent-src/skills/data-handling-judgment/SKILL.md +1 -1
  275. package/dist/agent-src/skills/deal-qualification-meddic/SKILL.md +2 -2
  276. package/dist/agent-src/skills/decision-record/SKILL.md +3 -3
  277. package/dist/agent-src/skills/decision-review/SKILL.md +8 -8
  278. package/dist/agent-src/skills/deep-reading-analyst/SKILL.md +22 -22
  279. package/dist/agent-src/skills/design-intelligence/SKILL.md +4 -4
  280. package/dist/agent-src/skills/design-intelligence/references/context-and-registers.md +2 -2
  281. package/dist/agent-src/skills/design-review/SKILL.md +4 -4
  282. package/dist/agent-src/skills/design-system-capture/references/design-system-json.md +20 -1
  283. package/dist/agent-src/skills/design-tokens/SKILL.md +17 -2
  284. package/dist/agent-src/skills/design-variations/SKILL.md +2 -2
  285. package/dist/agent-src/skills/developer-like-execution/SKILL.md +2 -2
  286. package/dist/agent-src/skills/discovery-interview/SKILL.md +2 -2
  287. package/dist/agent-src/skills/doc-coauthoring/SKILL.md +3 -3
  288. package/dist/agent-src/skills/editorial-calendar/SKILL.md +2 -2
  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/git-workflow/references/push-closes-its-loop.md +9 -0
  305. package/dist/agent-src/skills/gtm-launch/SKILL.md +2 -2
  306. package/dist/agent-src/skills/hiring-loop-design/SKILL.md +1 -1
  307. package/dist/agent-src/skills/html-deck/SKILL.md +5 -5
  308. package/dist/agent-src/skills/humanizer/SKILL.md +1 -1
  309. package/dist/agent-src/skills/humanizer/data/patterns.md +1 -1
  310. package/dist/agent-src/skills/iconography/SKILL.md +3 -3
  311. package/dist/agent-src/skills/judge-synthesis/SKILL.md +1 -1
  312. package/dist/agent-src/skills/laravel-api-endpoint/SKILL.md +2 -2
  313. package/dist/agent-src/skills/launch-readiness/SKILL.md +3 -3
  314. package/dist/agent-src/skills/learning-to-rule-or-skill/SKILL.md +6 -6
  315. package/dist/agent-src/skills/livewire/SKILL.md +1 -1
  316. package/dist/agent-src/skills/market-entry-analysis/SKILL.md +1 -1
  317. package/dist/agent-src/skills/mcp-builder/SKILL.md +1 -1
  318. package/dist/agent-src/skills/memory-consolidation/SKILL.md +3 -3
  319. package/dist/agent-src/skills/messaging-architecture/SKILL.md +2 -2
  320. package/dist/agent-src/skills/monorepo-workspace/SKILL.md +1 -1
  321. package/dist/agent-src/skills/onboarding-design/SKILL.md +2 -2
  322. package/dist/agent-src/skills/onboarding-program/SKILL.md +1 -1
  323. package/dist/agent-src/skills/one-on-one-cadence/SKILL.md +1 -1
  324. package/dist/agent-src/skills/org-design/SKILL.md +1 -1
  325. package/dist/agent-src/skills/overbuild-review-lens/SKILL.md +3 -3
  326. package/dist/agent-src/skills/override-management/SKILL.md +1 -1
  327. package/dist/agent-src/skills/perf-feedback-craft/SKILL.md +1 -1
  328. package/dist/agent-src/skills/persona-writing/SKILL.md +1 -1
  329. package/dist/agent-src/skills/php-coder/SKILL.md +1 -1
  330. package/dist/agent-src/skills/pipeline-strategy/SKILL.md +2 -2
  331. package/dist/agent-src/skills/playwright-testing/SKILL.md +3 -3
  332. package/dist/agent-src/skills/po-discovery/SKILL.md +1 -1
  333. package/dist/agent-src/skills/positioning-strategy/SKILL.md +2 -2
  334. package/dist/agent-src/skills/privacy-review/SKILL.md +1 -1
  335. package/dist/agent-src/skills/prompt-optimizer/SKILL.md +3 -3
  336. package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +1 -1
  337. package/dist/agent-src/skills/reasoning-orchestrator/SKILL.md +2 -2
  338. package/dist/agent-src/skills/receiving-code-review/SKILL.md +1 -1
  339. package/dist/agent-src/skills/refine-ticket/SKILL.md +2 -2
  340. package/dist/agent-src/skills/release-comms/SKILL.md +2 -2
  341. package/dist/agent-src/skills/retention-loops/SKILL.md +2 -2
  342. package/dist/agent-src/skills/review-routing/SKILL.md +2 -2
  343. package/dist/agent-src/skills/roadmap-management/SKILL.md +1 -1
  344. package/dist/agent-src/skills/roadmap-management/references/archival.md +1 -1
  345. package/dist/agent-src/skills/roadmap-writing/SKILL.md +5 -5
  346. package/dist/agent-src/skills/rule-writing/SKILL.md +6 -6
  347. package/dist/agent-src/skills/runway-cognition/SKILL.md +2 -2
  348. package/dist/agent-src/skills/scenario-modeling/SKILL.md +2 -2
  349. package/dist/agent-src/skills/skill-writing/SKILL.md +2 -2
  350. package/dist/agent-src/skills/skill-writing/references/procedure.md +1 -1
  351. package/dist/agent-src/skills/skill-writing/references/section-patterns.md +3 -3
  352. package/dist/agent-src/skills/spreadsheet-authoring/SKILL.md +1 -1
  353. package/dist/agent-src/skills/stakeholder-tradeoff/SKILL.md +3 -3
  354. package/dist/agent-src/skills/subagent-orchestration/SKILL.md +1 -1
  355. package/dist/agent-src/skills/supply-chain-intake/SKILL.md +1 -1
  356. package/dist/agent-src/skills/systematic-debugging/SKILL.md +2 -2
  357. package/dist/agent-src/skills/tailwind-engineer/SKILL.md +60 -4
  358. package/dist/agent-src/skills/throughput-vs-morale-tradeoff/SKILL.md +1 -1
  359. package/dist/agent-src/skills/token-optimizer/SKILL.md +1 -1
  360. package/dist/agent-src/skills/typography-system/SKILL.md +2 -2
  361. package/dist/agent-src/skills/ui-component-architect/SKILL.md +28 -8
  362. package/dist/agent-src/skills/unit-economics-modeling/SKILL.md +2 -2
  363. package/dist/agent-src/skills/upstream-contribute/SKILL.md +1 -1
  364. package/dist/agent-src/skills/validate-feature-fit/SKILL.md +2 -2
  365. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +2 -2
  366. package/dist/agent-src/skills/vision-articulation/SKILL.md +1 -1
  367. package/dist/agent-src/skills/voc-extract/SKILL.md +2 -2
  368. package/dist/agent-src/skills/voice-and-tone-design/SKILL.md +2 -2
  369. package/dist/agent-src/skills/wireframe/SKILL.md +1 -1
  370. package/dist/agent-src/skills/workspace-link/SKILL.md +1 -1
  371. package/dist/agent-src/templates/agent-settings.md +6 -6
  372. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  373. package/dist/agent-src/templates/contexts/knowledge-pages.md +2 -3
  374. package/dist/agent-src/templates/copilot-instructions.md +1 -1
  375. package/dist/agent-src/templates/roadmaps.md +1 -1
  376. package/dist/agent-src/templates/scripts/README.md +2 -2
  377. package/dist/agent-src/user-types/_template/user-type.md +1 -1
  378. package/dist/cli/registry.js +1 -1
  379. package/dist/cli-delegate/archive_completed_roadmaps.js +52 -4
  380. package/dist/cli-delegate/check_update_banner.js +12 -1
  381. package/dist/cli-delegate/{chunk-TGIPZBCW.js → chunk-2KKXJW25.js} +22 -8
  382. package/dist/cli-delegate/{chunk-NLP54U3J.js → chunk-2XY7ILBT.js} +13 -1
  383. package/dist/cli-delegate/{chunk-4FS4WRXP.js → chunk-3FKR64R5.js} +34 -6
  384. package/dist/cli-delegate/{chunk-J3RFNKG4.js → chunk-55ACLDUE.js} +2 -2
  385. package/dist/cli-delegate/{chunk-PKOBQADP.js → chunk-57PN4GYJ.js} +1 -1
  386. package/dist/cli-delegate/{chunk-BIXEDQPZ.js → chunk-AK6HODNQ.js} +4 -4
  387. package/dist/cli-delegate/{chunk-2FTMENJL.js → chunk-GYC3VRYN.js} +1 -1
  388. package/dist/cli-delegate/{chunk-LWTYTX6F.js → chunk-HZ52BRGG.js} +24 -18
  389. package/dist/cli-delegate/{chunk-6RJA2F5A.js → chunk-IVBPRCQO.js} +1 -1
  390. package/dist/cli-delegate/{chunk-I6RHFQEG.js → chunk-YUM5KURG.js} +17 -1
  391. package/dist/cli-delegate/cmd_analyze_session.js +1 -1
  392. package/dist/cli-delegate/cmd_brand_status.js +1 -1
  393. package/dist/cli-delegate/cmd_conformance.js +3 -3
  394. package/dist/cli-delegate/cmd_doctor.js +3 -3
  395. package/dist/cli-delegate/cmd_explain.js +2 -2
  396. package/dist/cli-delegate/cmd_export.js +4 -4
  397. package/dist/cli-delegate/cmd_handoff.js +24 -16
  398. package/dist/cli-delegate/cmd_mcp_available.js +1 -1
  399. package/dist/cli-delegate/cmd_memory_get.js +1 -1
  400. package/dist/cli-delegate/cmd_migrate.js +2 -2
  401. package/dist/cli-delegate/cmd_packs_active.js +2 -2
  402. package/dist/cli-delegate/cmd_prune.js +4 -4
  403. package/dist/cli-delegate/cmd_route_audit.js +3 -3
  404. package/dist/cli-delegate/cmd_route_explain.js +1 -1
  405. package/dist/cli-delegate/cmd_session_recycle.js +4 -14
  406. package/dist/cli-delegate/cmd_settings_get.js +15 -9
  407. package/dist/cli-delegate/cmd_settings_migrate.js +4 -4
  408. package/dist/cli-delegate/cmd_settings_set.js +41 -11
  409. package/dist/cli-delegate/cmd_sync.js +4 -4
  410. package/dist/cli-delegate/cmd_uninstall.js +4 -4
  411. package/dist/cli-delegate/cmd_update.js +1 -1
  412. package/dist/cli-delegate/cmd_upgrade.js +1 -1
  413. package/dist/cli-delegate/cmd_validate.js +4 -4
  414. package/dist/cli-delegate/cmd_versions.js +1 -1
  415. package/dist/discovery/deprecation-report.md +1 -1
  416. package/dist/discovery/discovery-manifest.json +27 -80
  417. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  418. package/dist/discovery/discovery-manifest.summary.md +3 -3
  419. package/dist/discovery/dormancy-report.md +1 -1
  420. package/dist/discovery/orphan-report.md +1 -1
  421. package/dist/discovery/packs.json +5 -7
  422. package/dist/discovery/trust-report.md +2 -2
  423. package/dist/discovery/workspaces.json +4 -6
  424. package/dist/hooks/dispatch.js +9249 -8981
  425. package/dist/install/install.mjs +47 -8
  426. package/dist/mcp/registry-manifest.json +3 -3
  427. package/dist/mcp/server.json +2 -2
  428. package/dist/mcp/server.mjs +5496 -2400
  429. package/dist/router.json +1 -1
  430. package/dist/scripts/_lib/agent_settings.js +73 -0
  431. package/dist/scripts/_lib/agent_src.js +20 -0
  432. package/dist/scripts/_lib/guidelines_lane.js +158 -0
  433. package/dist/scripts/_lib/lean_projection_mode.js +108 -0
  434. package/dist/scripts/_lib/router_match.js +243 -0
  435. package/dist/scripts/_lib/rule_injection.js +216 -0
  436. package/dist/scripts/condense.js +22 -25
  437. package/dist/scripts/project_thin_rules.js +139 -19
  438. package/dist/server/io/yamlIO.js +125 -17
  439. package/dist/server/schemas/settings.js +32 -5
  440. package/dist/shared/settingsSurface.js +6 -1
  441. package/docs/MIGRATION.md +56 -0
  442. package/docs/contracts/settings-classes.md +48 -7
  443. package/docs/guidelines/abstraction-thresholds.md +35 -0
  444. package/docs/guidelines/agent-infra/active-remediation-mechanics.md +3 -3
  445. package/docs/guidelines/agent-infra/false-green.md +2 -2
  446. package/docs/guidelines/agent-infra/notes-horizon-mechanics.md +90 -0
  447. package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
  448. package/docs/guidelines/agent-infra/skill-quality-checklist.md +1 -1
  449. package/docs/guidelines/design-fidelity-mechanics.md +4 -0
  450. package/docs/guidelines/design-fidelity-routing.md +78 -0
  451. package/docs/guidelines/design-reconciliation.md +172 -0
  452. package/docs/guidelines/gtm-handoff.md +2 -2
  453. package/docs/guidelines/wing4-handoff.md +2 -2
  454. package/llms.txt +1 -1
  455. package/package.json +7 -3
  456. package/src/agent-src/scripts/archive_completed_roadmaps.ts +106 -4
  457. package/src/config/agent-settings.template.yml +94 -1
  458. package/src/config/ci-local-parity.yml +34 -0
  459. package/src/config/continuity-surface.json +8 -29
  460. package/src/config/evaluator-budgets.json +4 -4
  461. package/src/config/gate-coverage.yml +31 -8
  462. package/src/config/gate-reachability-exemptions.json +1 -0
  463. package/src/config/gate-violation-baselines.json +3 -3
  464. package/src/config/hook-token-budget.json +8 -7
  465. package/src/config/host-injection-effect.json +2 -2
  466. package/src/config/pack-size-budget.json +55 -4
  467. package/src/config/packed-binary-manifest.json +1 -1
  468. package/src/config/platform-anchor.json +47 -0
  469. package/src/config/preamble-payload-budget.json +2 -3
  470. package/src/config/publish-surface.json +4 -2
  471. package/src/config/ratification-policy.json +7 -0
  472. package/src/config/routing-coverage-seed.json +9 -2
  473. package/src/config/rule-stub-ceilings.json +16 -9
  474. package/src/scripts/_cli/cmd_session_recycle.ts +2 -25
  475. package/src/scripts/_cli/cmd_settings_get.ts +22 -7
  476. package/src/scripts/_cli/handoff_sessions.ts +14 -44
  477. package/src/scripts/_lib/agent_settings.ts +85 -0
  478. package/src/scripts/_lib/agent_src.ts +21 -0
  479. package/src/scripts/_lib/artifact_maturity.ts +242 -0
  480. package/src/scripts/_lib/conformance_report.ts +403 -0
  481. package/src/scripts/_lib/continuity_slot.ts +295 -0
  482. package/src/scripts/_lib/continuity_writer.ts +312 -0
  483. package/src/scripts/_lib/design_system_import.ts +20 -0
  484. package/src/scripts/_lib/design_tolerance.ts +281 -0
  485. package/src/scripts/_lib/guidelines_lane.ts +164 -0
  486. package/src/scripts/_lib/hook_settings.ts +85 -0
  487. package/src/scripts/_lib/lean_projection_mode.ts +127 -0
  488. package/src/scripts/_lib/obligation_frequency.ts +2 -3
  489. package/src/scripts/_lib/packed_binary_predicate.ts +37 -0
  490. package/src/scripts/_lib/platform_anchor.ts +1053 -0
  491. package/src/scripts/_lib/ratification_artifact.ts +278 -0
  492. package/src/scripts/_lib/recycle_envelope_paths.ts +109 -21
  493. package/src/scripts/_lib/regression_neighbourhood.ts +159 -22
  494. package/src/scripts/_lib/security_lint.ts +23 -2
  495. package/src/scripts/_lib/self_repair.ts +21 -0
  496. package/src/scripts/_lib/session_eol.ts +44 -0
  497. package/src/scripts/_lib/session_index_trust.ts +387 -0
  498. package/src/scripts/_lib/standing_bound_ratchet.ts +220 -0
  499. package/src/scripts/_lib/tolerance_shadow.ts +177 -0
  500. package/src/scripts/_lib/vendored_grammar_upstream.ts +280 -0
  501. package/src/scripts/ai_council/redact_low_impact_entry.ts +8 -0
  502. package/src/scripts/audit_mcp_tools.ts +69 -25
  503. package/src/scripts/autonomy_friction_traffic.ts +379 -0
  504. package/src/scripts/build_mcp_catalog.ts +24 -1
  505. package/src/scripts/check_host_tree_parity.ts +291 -0
  506. package/src/scripts/check_kernel_edit_ratified.ts +462 -0
  507. package/src/scripts/check_loss_class_declared.ts +793 -46
  508. package/src/scripts/check_platform_anchor.ts +390 -0
  509. package/src/scripts/check_preamble_payload_budget.ts +424 -7
  510. package/src/scripts/check_projected_rule_routes.ts +395 -0
  511. package/src/scripts/check_rule_projection_integrity.ts +102 -2
  512. package/src/scripts/ci_settle.ts +205 -5
  513. package/src/scripts/code_graph/build.ts +79 -0
  514. package/src/scripts/code_graph/cli.ts +264 -7
  515. package/src/scripts/code_graph/detect.ts +38 -0
  516. package/src/scripts/code_graph/query.ts +25 -2
  517. package/src/scripts/code_graph/sqlite_store.ts +16 -1
  518. package/src/scripts/code_graph/types.ts +52 -3
  519. package/src/scripts/code_graph/validate.ts +3 -1
  520. package/src/scripts/code_graph/verbs.ts +590 -0
  521. package/src/scripts/condense.ts +22 -26
  522. package/src/scripts/generate_host_cost_table.ts +354 -0
  523. package/src/scripts/handoff_context_hook.ts +39 -1
  524. package/src/scripts/hook_manifest.json +1 -1
  525. package/src/scripts/hook_manifest.yaml +59 -28
  526. package/src/scripts/hooks/block_speaking_inbox_dir.ts +182 -16
  527. package/src/scripts/hooks/category_a.ts +1 -1
  528. package/src/scripts/hooks/chain_nudge_hook.ts +311 -25
  529. package/src/scripts/hooks/code_graph_context_hook.ts +7 -18
  530. package/src/scripts/hooks/push_settle_hook.ts +3 -2
  531. package/src/scripts/hooks/rule_inject_hook.ts +107 -20
  532. package/src/scripts/hooks/session_eol_hook.ts +177 -145
  533. package/src/scripts/hooks/source_first_gate_hook.ts +12 -0
  534. package/src/scripts/hooks/ui_route_nudge_hook.ts +52 -15
  535. package/src/scripts/hot_context_hook.ts +103 -408
  536. package/src/scripts/lint_evidence_artifacts.ts +1 -0
  537. package/src/scripts/lint_knowledge_scale.ts +0 -26
  538. package/src/scripts/lint_roadmap_blockers.ts +164 -1
  539. package/src/scripts/mcp_server/consumer_tool_catalog.json +152 -2
  540. package/src/scripts/mcp_server/graph_tools.ts +294 -0
  541. package/src/scripts/mcp_server/path_util.ts +31 -0
  542. package/src/scripts/mcp_server/tool_catalog_source.ts +7 -1
  543. package/src/scripts/mcp_server/tools.ts +3 -13
  544. package/src/scripts/memory_lookup.ts +9 -9
  545. package/src/scripts/model_rule_injection.ts +61 -4
  546. package/src/scripts/project_thin_rules.ts +149 -16
  547. package/src/scripts/report_standing_payload_by_host.ts +650 -0
  548. package/src/scripts/schemas/agent-settings.schema.json +7 -1
  549. package/src/scripts/session_memory_index.ts +86 -8
  550. package/src/scripts/sync_agent_settings.ts +270 -10
  551. package/src/server/io/yamlIO.ts +127 -17
  552. package/src/server/schemas/settings.ts +45 -6
  553. package/src/shared/settingsSurface.ts +13 -2
  554. package/src/templates/compact-instructions.md +8 -3
  555. package/src/vendor/grammars/README.md +27 -2
  556. package/dist/agent-src/commands/chat-history/import.md +0 -170
  557. package/dist/agent-src/commands/chat-history.md +0 -63
@@ -0,0 +1,281 @@
1
+ /**
2
+ * Value reconciliation between a provided design artifact and a project's own
3
+ * tokens — the MEASUREMENT half, shipped; the BEHAVIOURAL half, deliberately
4
+ * not.
5
+ *
6
+ * WHAT THE COUNCIL DECIDED, and why this module is shaped this way.
7
+ *
8
+ * `road-to-design-intent-conformance` put `blocker: approximation-tolerance` to
9
+ * the AI council (anthropic + openai, 2/2, 2026-09-09). Neither member accepted
10
+ * any of the three options as written. Both split step 3.2 the same way: build
11
+ * the metric, the collection and the reporting now; ship **no tolerance
12
+ * constant at all**; defer the behaviour that would let a value change without
13
+ * being asked about.
14
+ *
15
+ * The argument that decided it, and it is the one to re-read before adding a
16
+ * number here: *"a number in a config file, even flagged unmeasured, shapes
17
+ * behaviour and creates path dependency."* Zero of seven design-to-code
18
+ * benchmarks in the evidence set score token conformance, so a shipped
19
+ * threshold would be a guess acquiring the authority of a default. Both
20
+ * `design.tolerance.*` keys therefore ship `null`, and `null` means **preserve
21
+ * and report**, never "reconcile freely".
22
+ *
23
+ * THE METRIC IS A PREREQUISITE the roadmap never named.
24
+ *
25
+ * The council added it: no colour tolerance is meaningful before the distance
26
+ * METHOD is fixed, because RGB Euclidean, ΔE LAB, CIEDE2000 and OKLab/ΔEOK give
27
+ * different numbers for the same pair. `openai` rejected the round's proposed
28
+ * `±5 per RGB channel` on exactly this ground — RGB channel distance is not
29
+ * perceptually uniform, so "likely imperceptible" is an unsupported conclusion.
30
+ *
31
+ * This module fixes the method as **OKLab ΔEOK** (a plain Euclidean distance in
32
+ * OKLab, the metric OKLab was designed to make meaningful) and leaves the
33
+ * threshold empty. Method without threshold is the honest state: the distance
34
+ * on every row is a real, comparable number, and nothing yet says which
35
+ * distances are small enough to act on.
36
+ *
37
+ * LENGTH CARRIES NO SHIPPED NUMBER either.
38
+ *
39
+ * Primer's spacing plugin widens each token's accepted set by ±1px and
40
+ * autofixes. That is the one real measurement in the evidence set and it is
41
+ * recorded as an **externally observed candidate**, not adopted:
42
+ * `OBSERVED_LENGTH_CANDIDATE_PX` exists to be cited, and no code path reads it
43
+ * as a threshold. The round's other proposal, `max(1px, 2%)`, was rejected for
44
+ * growing steadily more permissive at large dimensions with no evidence that
45
+ * this is wanted.
46
+ *
47
+ * EVERY ROW CARRIES ITS DISTANCE, even when the value is preserved.
48
+ *
49
+ * That is the step's own verify clause and it is the property that makes the
50
+ * deferred half decidable later: a shadow window over rows that report
51
+ * distances can produce a distribution, where a window over rows that report
52
+ * only "kept" or "changed" cannot.
53
+ */
54
+
55
+ /** Fixed method. See the header: the threshold is absent, the metric is not. */
56
+ export const COLOR_DISTANCE_METRIC = 'oklab-deltaEOK' as const;
57
+ /** Fixed method for lengths: absolute difference in CSS pixels. */
58
+ export const LENGTH_DISTANCE_METRIC = 'abs-px' as const;
59
+
60
+ /**
61
+ * GitHub Primer's spacing plugin widens each token's accepted set by ±1px.
62
+ * Recorded as an externally observed candidate for a future threshold; **no
63
+ * code path reads this as one**, and a test pins that it never becomes the
64
+ * shipped default without a decision.
65
+ */
66
+ export const OBSERVED_LENGTH_CANDIDATE_PX = 1;
67
+
68
+ export interface ToleranceConfig {
69
+ /** Master switch. Ships `false`; `blocker: fidelity-default-flip` → (a). */
70
+ enabled: boolean;
71
+ /** ΔEOK below which a colour may be reconciled. `null` ships. */
72
+ color: number | null;
73
+ /** Pixels below which a length may be reconciled. `null` ships. */
74
+ length: number | null;
75
+ }
76
+
77
+ /** The shipped configuration. Both thresholds absent, mechanism off. */
78
+ export const SHIPPED_TOLERANCE: ToleranceConfig = { enabled: false, color: null, length: null };
79
+
80
+ export type ReconcileOutcome =
81
+ /** Inside tolerance: the project token wins, and the change is reported. */
82
+ | 'reconciled'
83
+ /** Outside tolerance: the artifact's value is preserved, gap reported. */
84
+ | 'preserved-outside-tolerance'
85
+ /** The mechanism is off, or no threshold is configured: preserve, report. */
86
+ | 'preserved-mechanism-off'
87
+ /** No project token to compare against: nothing to reconcile onto. */
88
+ | 'no-candidate';
89
+
90
+ export interface TokenCandidate {
91
+ name: string;
92
+ value: string;
93
+ }
94
+
95
+ export interface ValueRow {
96
+ /** The artifact's own value, verbatim. */
97
+ artifact: string;
98
+ /** Nearest project token, or null when the project has none of this kind. */
99
+ nearest: TokenCandidate | null;
100
+ /** Distance to `nearest` in the metric named below. Null iff no candidate. */
101
+ distance: number | null;
102
+ metric: typeof COLOR_DISTANCE_METRIC | typeof LENGTH_DISTANCE_METRIC | null;
103
+ /** The value actually written. Equals `artifact` unless reconciled. */
104
+ resolved: string;
105
+ outcome: ReconcileOutcome;
106
+ }
107
+
108
+ // ------------------------------------------------------------------ colour
109
+
110
+ interface Rgb {
111
+ r: number;
112
+ g: number;
113
+ b: number;
114
+ }
115
+
116
+ /**
117
+ * `#rgb` / `#rrggbb` → 0–1 channels, or null when unparseable.
118
+ *
119
+ * An 8-digit `#rrggbbaa` returns NULL rather than its opaque prefix. ΔEOK is a
120
+ * three-channel metric and has nothing to say about alpha, so truncating made
121
+ * `#ff000080` and `#ff0000` measure distance 0 — "identical" for two values a
122
+ * designer chose to differ. Found by a blind review. Null is the honest answer:
123
+ * the row is reported as unmeasured, which is what it is.
124
+ */
125
+ export function parseHex(value: string): Rgb | null {
126
+ const m = /^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.exec(value.trim());
127
+ if (!m) return null;
128
+ let hex = m[1] as string;
129
+ if (hex.length === 3) {
130
+ hex = hex
131
+ .split('')
132
+ .map((c) => c + c)
133
+ .join('');
134
+ }
135
+ return {
136
+ r: parseInt(hex.slice(0, 2), 16) / 255,
137
+ g: parseInt(hex.slice(2, 4), 16) / 255,
138
+ b: parseInt(hex.slice(4, 6), 16) / 255,
139
+ };
140
+ }
141
+
142
+ /** sRGB transfer function, inverted — required before the OKLab matrices. */
143
+ function toLinear(c: number): number {
144
+ return c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
145
+ }
146
+
147
+ /** sRGB → OKLab (Björn Ottosson's published matrices). */
148
+ export function srgbToOklab(rgb: Rgb): { L: number; a: number; b: number } {
149
+ const r = toLinear(rgb.r);
150
+ const g = toLinear(rgb.g);
151
+ const b = toLinear(rgb.b);
152
+ const l = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b);
153
+ const m = Math.cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b);
154
+ const s = Math.cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b);
155
+ return {
156
+ L: 0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s,
157
+ a: 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s,
158
+ b: 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s,
159
+ };
160
+ }
161
+
162
+ /**
163
+ * ΔEOK — Euclidean distance in OKLab. Null when either value is not a hex
164
+ * colour this module can parse; an unparseable value is reported as unmeasured
165
+ * rather than assigned a distance of zero, which would read as "identical".
166
+ */
167
+ export function deltaEOK(a: string, b: string): number | null {
168
+ const ra = parseHex(a);
169
+ const rb = parseHex(b);
170
+ if (!ra || !rb) return null;
171
+ const la = srgbToOklab(ra);
172
+ const lb = srgbToOklab(rb);
173
+ return Math.sqrt((la.L - lb.L) ** 2 + (la.a - lb.a) ** 2 + (la.b - lb.b) ** 2);
174
+ }
175
+
176
+ // ------------------------------------------------------------------ length
177
+
178
+ /** `16px` / `1rem` / `0.5rem` → pixels at a 16px root, or null. */
179
+ export function parseLengthPx(value: string, rootPx = 16): number | null {
180
+ const m = /^(-?\d*\.?\d+)(px|rem|em)$/.exec(value.trim());
181
+ if (!m) return null;
182
+ const n = Number(m[1]);
183
+ if (!Number.isFinite(n)) return null;
184
+ return m[2] === 'px' ? n : n * rootPx;
185
+ }
186
+
187
+ /** Absolute pixel difference, or null when either side is unparseable. */
188
+ export function lengthDistancePx(a: string, b: string, rootPx = 16): number | null {
189
+ const pa = parseLengthPx(a, rootPx);
190
+ const pb = parseLengthPx(b, rootPx);
191
+ if (pa === null || pb === null) return null;
192
+ return Math.abs(pa - pb);
193
+ }
194
+
195
+ // ------------------------------------------------------------- reconcile
196
+
197
+ export type ValueKind = 'color' | 'length';
198
+
199
+ function distanceFor(kind: ValueKind, a: string, b: string): number | null {
200
+ return kind === 'color' ? deltaEOK(a, b) : lengthDistancePx(a, b);
201
+ }
202
+
203
+ /** Nearest candidate by the kind's own metric. Ties break on first-listed. */
204
+ export function nearestToken(
205
+ kind: ValueKind,
206
+ artifact: string,
207
+ candidates: readonly TokenCandidate[],
208
+ ): { candidate: TokenCandidate; distance: number } | null {
209
+ let best: { candidate: TokenCandidate; distance: number } | null = null;
210
+ for (const candidate of candidates) {
211
+ const d = distanceFor(kind, artifact, candidate.value);
212
+ if (d === null) continue;
213
+ if (best === null || d < best.distance) best = { candidate, distance: d };
214
+ }
215
+ return best;
216
+ }
217
+
218
+ /**
219
+ * Reconcile one artifact value against the project's tokens.
220
+ *
221
+ * **The distance is computed and reported on every path**, including every path
222
+ * that preserves the artifact's value — that is the step's verify clause, and
223
+ * it is what makes a later shadow distribution possible.
224
+ */
225
+ export function reconcileValue(
226
+ kind: ValueKind,
227
+ artifact: string,
228
+ candidates: readonly TokenCandidate[],
229
+ config: ToleranceConfig = SHIPPED_TOLERANCE,
230
+ ): ValueRow {
231
+ const metric = kind === 'color' ? COLOR_DISTANCE_METRIC : LENGTH_DISTANCE_METRIC;
232
+ const best = nearestToken(kind, artifact, candidates);
233
+
234
+ if (best === null) {
235
+ return {
236
+ artifact,
237
+ nearest: null,
238
+ distance: null,
239
+ metric: null,
240
+ resolved: artifact,
241
+ outcome: 'no-candidate',
242
+ };
243
+ }
244
+
245
+ const base = {
246
+ artifact,
247
+ nearest: best.candidate,
248
+ distance: best.distance,
249
+ metric,
250
+ } as const;
251
+
252
+ const threshold = kind === 'color' ? config.color : config.length;
253
+
254
+ // Off, or no threshold configured. These are ONE outcome on purpose: a
255
+ // mechanism with no threshold cannot act, so reporting it as anything but
256
+ // "off" would imply a decision nobody made.
257
+ if (!config.enabled || threshold === null) {
258
+ return { ...base, resolved: artifact, outcome: 'preserved-mechanism-off' };
259
+ }
260
+
261
+ if (best.distance <= threshold) {
262
+ return { ...base, resolved: best.candidate.value, outcome: 'reconciled' };
263
+ }
264
+ return { ...base, resolved: artifact, outcome: 'preserved-outside-tolerance' };
265
+ }
266
+
267
+ /** One human-readable row. Always names the distance, never only the verdict. */
268
+ export function formatRow(row: ValueRow): string {
269
+ if (row.nearest === null || row.distance === null) {
270
+ return `${row.artifact} → kept (no project token of this kind to compare against)`;
271
+ }
272
+ const d = `${row.metric ?? '?'} ${row.distance.toFixed(4)}`;
273
+ switch (row.outcome) {
274
+ case 'reconciled':
275
+ return `${row.artifact} → ${row.nearest.name} (${row.nearest.value}); reconciled, distance ${d}`;
276
+ case 'preserved-outside-tolerance':
277
+ return `${row.artifact} → kept; nearest ${row.nearest.name} (${row.nearest.value}) is outside tolerance, distance ${d}`;
278
+ default:
279
+ return `${row.artifact} → kept; nearest ${row.nearest.name} (${row.nearest.value}), distance ${d} (reconciliation off)`;
280
+ }
281
+ }
@@ -0,0 +1,164 @@
1
+ /**
2
+ * The `docs/guidelines/` → `dist/agent-src/guidelines/` projection lane.
3
+ *
4
+ * Why this exists at all: the projected rules declare `routes_to:
5
+ * guideline:<slug>` against **22 distinct targets** and link
6
+ * `../../docs/guidelines/<slug>.md`, and until this lane shipped
7
+ * `dist/agent-src/` carried no `guidelines/` directory — so every one of those
8
+ * routes was declared and dead in a consumer install. (The figure is the gate's own reading. An
9
+ * earlier draft here said "31 rules", which reproduced on nothing: `grep -l`
10
+ * returns 22 in both trees. A blind review checked it; the number is now the
11
+ * one `check_projected_rule_routes` prints.) `AUGMENT_SYMLINK_DIRS`
12
+ * in `condense.ts` has listed `guidelines` since before the lane existed; the
13
+ * symlink simply had nothing to point at.
14
+ *
15
+ * Shape, and why it is a lane rather than a source root: the multi-root
16
+ * resolver in `agent_src.ts` derives an artefact's *identity* from
17
+ * `_root_specs()`, and everything that scans the artefact estate — the
18
+ * discovery manifest, the skill linter, the size and count ratchets — walks
19
+ * that same list. Adding `docs/guidelines` there would reclassify 119
20
+ * guidelines as estate artefacts and move every one of those numbers. So the
21
+ * lane is appended only where the *projection* reads (`iter_all_sources` and
22
+ * `resolve_logical`), exactly as `_iter_domains_commands` already is, and the
23
+ * estate view is left alone.
24
+ *
25
+ * Identity: `docs/guidelines/<subpath>.md` is logical `guidelines/<subpath>.md`
26
+ * — one directory deep in the projection, the same depth as `rules/` and
27
+ * `skills/`, which is what makes the existing `../guidelines/…` rewrite in
28
+ * `condense.ts::_rewrite_body_links` resolve from a projected rule.
29
+ */
30
+ import * as fs from 'node:fs';
31
+ import * as path from 'node:path';
32
+
33
+ /** Logical-path prefix every guideline is projected under. */
34
+ export const GUIDELINES_LOGICAL_PREFIX = 'guidelines/';
35
+
36
+ /** Physical source directory, relative to the repo root. */
37
+ export const GUIDELINES_SOURCE_REL = path.join('docs', 'guidelines');
38
+
39
+ function _isDir(p: string): boolean {
40
+ try {
41
+ return fs.statSync(p).isDirectory();
42
+ } catch {
43
+ return false;
44
+ }
45
+ }
46
+
47
+ function _isFile(p: string): boolean {
48
+ try {
49
+ return fs.statSync(p).isFile();
50
+ } catch {
51
+ return false;
52
+ }
53
+ }
54
+
55
+ /** Recursive, name-sorted at every level so the walk order is deterministic. */
56
+ function* _walkSorted(dir: string): Generator<string> {
57
+ let entries: string[];
58
+ try {
59
+ entries = fs.readdirSync(dir).sort();
60
+ } catch {
61
+ return;
62
+ }
63
+ for (const name of entries) {
64
+ const full = path.join(dir, name);
65
+ if (_isDir(full)) {
66
+ yield* _walkSorted(full);
67
+ } else if (_isFile(full)) {
68
+ yield full;
69
+ }
70
+ }
71
+ }
72
+
73
+ /**
74
+ * Yield `[physical_path, logical_relpath]` for every file under
75
+ * `<root>/docs/guidelines/`. Deterministic order; yields nothing when the
76
+ * directory is absent, which is the normal state of a consumer checkout.
77
+ */
78
+ export function* iter_guidelines(root: string): Generator<[string, string]> {
79
+ const base = path.join(root, GUIDELINES_SOURCE_REL);
80
+ if (!_isDir(base)) {
81
+ return;
82
+ }
83
+ for (const p of _walkSorted(base)) {
84
+ const rel = path.relative(base, p).split(path.sep).join('/');
85
+ yield [p, GUIDELINES_LOGICAL_PREFIX + rel];
86
+ }
87
+ }
88
+
89
+ /**
90
+ * Physical path backing a logical `guidelines/<subpath>`, or `null` when the
91
+ * logical path is not a guideline or the file does not exist.
92
+ */
93
+ export function resolve_guideline(root: string, logical_rel: string): string | null {
94
+ const rel = logical_rel.replaceAll('\\', '/').replace(/^\/+/, '');
95
+ if (!rel.startsWith(GUIDELINES_LOGICAL_PREFIX)) {
96
+ return null;
97
+ }
98
+ const suffix = rel.slice(GUIDELINES_LOGICAL_PREFIX.length);
99
+ if (suffix.length === 0 || suffix.split('/').includes('..')) {
100
+ return null;
101
+ }
102
+ const candidate = path.join(root, GUIDELINES_SOURCE_REL, suffix);
103
+ return _isFile(candidate) ? candidate : null;
104
+ }
105
+
106
+ /**
107
+ * Rewrite a projected body's relative `.md` links onto the projection.
108
+ *
109
+ * Lives here rather than in `condense.ts` for two reasons, and the second is
110
+ * the load-bearing one. It is this lane's own subject: every rule it applies is
111
+ * a statement about which source trees project where, which is what this module
112
+ * exists to know. And `condense.ts` sits ~1,200 lines past the 1,500-line
113
+ * ceiling `check_source_size_budget` ratchets, so every line there costs one
114
+ * unit of excess while every line here costs zero — the doctrine that file's
115
+ * own baseline note prescribes for exactly this case.
116
+ *
117
+ * `prefix` is the caller's depth prefix (`../` per level below
118
+ * `dist/agent-src/`), so a rule at depth 1 and a guideline at depth 2 both
119
+ * resolve.
120
+ */
121
+ export function rewriteProjectedBodyLinks(body: string, prefix: string): string {
122
+ return body
123
+ .replace(BODY_DOCS_RE, (_m, t: string) => prefix + t.replace(/^docs\/guidelines\//, 'guidelines/'))
124
+ .replace(BODY_SRC_FLAT_RE, (_m, t: string) => prefix + t)
125
+ .replace(BODY_SRC_AGENT_RE, (_m, t: string) => prefix + t);
126
+ }
127
+
128
+ /**
129
+ * `docs/guidelines/` is projected and loses its `docs/` segment;
130
+ * `docs/contracts/` is NOT projected and keeps its path unchanged.
131
+ *
132
+ * One-or-more `../` rather than a literal `../../`: the dominant convention in
133
+ * `src/rules/` is a single `../` — 26 sites across 18 rules — so a literal
134
+ * two-level pattern matched only the minority spelling.
135
+ */
136
+ const BODY_DOCS_RE = /(?:\.\.\/)+(docs\/(?:guidelines|contracts)\/[^)\s]+\.md)/g;
137
+
138
+ /**
139
+ * Source trees that project into `dist/agent-src/`, losing their `src/` (and
140
+ * `agent-src/`) segment.
141
+ *
142
+ * Until the guidelines lane shipped, no PROJECTED file linked into `src/`, so
143
+ * this rewrite had nothing to do and did not exist. A guideline does it 209
144
+ * times — a blind review measured 253 of 268 links under
145
+ * `dist/agent-src/guidelines/` resolving to nothing before this was added.
146
+ *
147
+ * TWO patterns, not one, and the difference is load-bearing. `rules` and
148
+ * `skills` are FLAT library roots directly under `src/`; `commands`,
149
+ * `contexts`, `personas`, `user-types`, `templates` and `scripts` exist only
150
+ * under `src/agent-src/`. A single pattern with an optional `agent-src/` group
151
+ * conflates them, and the conflation is not theoretical: it folded
152
+ * `../../src/scripts/media/lib/adapter-contract.md` — a real link in
153
+ * `provider-lifecycle-discipline.md` — onto `../scripts/…`, which resolves to
154
+ * `dist/agent-src/scripts/`, a projection of `src/agent-src/scripts/` and a
155
+ * different tree entirely. `check_condensed_paths` caught it; the first version
156
+ * of this regex turned one resolving link into a broken one.
157
+ *
158
+ * `src/domains` is deliberately absent from both: a domains command projects to
159
+ * `commands/<subpath>.md`, which is a re-shaping rather than a prefix strip,
160
+ * and guessing it would produce a link that looks right and is wrong.
161
+ */
162
+ const BODY_SRC_FLAT_RE = /(?:\.\.\/)+src\/((?:rules|skills)\/[^)\s]+\.md)/g;
163
+ const BODY_SRC_AGENT_RE =
164
+ /(?:\.\.\/)+src\/agent-src\/((?:commands|contexts|personas|user-types|templates|scripts)\/[^)\s]+\.md)/g;
@@ -110,3 +110,88 @@ export function leanProjectionModeRaw(root: string): string {
110
110
  }
111
111
  return '';
112
112
  }
113
+
114
+ /**
115
+ * Raw `lean_projection.hosts` list out of `.agent-settings.yml`, or `[]`.
116
+ *
117
+ * Same indentation-shaped discipline as `leanProjectionModeRaw` above and for
118
+ * the same reason — a hook must never fail a tool call because a YAML parser
119
+ * could not load — extended to the three list shapes a human writes:
120
+ *
121
+ * lean_projection:
122
+ * hosts: [claude-code] # inline
123
+ * lean_projection:
124
+ * hosts: # block, indented under the key
125
+ * - claude-code
126
+ * lean_projection:
127
+ * hosts: # block, at the key's own indent
128
+ * - claude-code
129
+ *
130
+ * All three are legal YAML and `js-yaml` loads them identically; the third was
131
+ * read as `[]` until 2026-09-08 (R2 finding 2) and is covered by three fixtures
132
+ * in `tests/scripts/lean_projection_hosts.test.ts`.
133
+ *
134
+ * Interpretation is NOT done here. `[]` means "nothing was written", and
135
+ * `_lib/lean_projection_mode.ts::resolveLeanProjectionHosts` decides that this
136
+ * means the default rather than "no host" — keeping that decision in one place
137
+ * is what stops the projector and the delivery concern from disagreeing, which
138
+ * is the whole reason the mode reader is split this way.
139
+ */
140
+ export function leanProjectionHostsRaw(root: string): string[] {
141
+ const file = path.join(root, SETTINGS_FILE);
142
+ let text: string;
143
+ try {
144
+ if (!fs.statSync(file).isFile()) return [];
145
+ text = fs.readFileSync(file, 'utf-8');
146
+ } catch {
147
+ return [];
148
+ }
149
+ const strip = (s: string): string => s.trim().replace(/^["']|["']$/g, '');
150
+ let inSection = false;
151
+ let inBlock = false;
152
+ let blockIndent = -1;
153
+ const out: string[] = [];
154
+ for (const raw of text.split(/\r\n|\r|\n/)) {
155
+ const line = raw.replace(/\s+$/, '');
156
+ if (!line || line.replace(/^\s+/, '').startsWith('#')) continue;
157
+ if (!(line.startsWith(' ') || line.startsWith('\t'))) {
158
+ inSection = /^lean_projection\s*:\s*$/.test(line);
159
+ inBlock = false;
160
+ continue;
161
+ }
162
+ if (!inSection) continue;
163
+ const indent = (/^\s*/.exec(line) as RegExpExecArray)[0].length;
164
+ if (inBlock) {
165
+ const item = /^\s*-\s*(\S.*)$/.exec(line);
166
+ // `>=`, not `>`: YAML lets a block sequence sit at its KEY's own
167
+ // indent, and `js-yaml` — the parser `condense` uses on this same
168
+ // file — loads that shape identically to the deeper-indented one.
169
+ // With `>` the same-indent form parsed as `[]`, which
170
+ // `resolveLeanProjectionHosts` reads as "nothing was written" and
171
+ // answers with the default `[claude-code]` while the projector
172
+ // thins whatever the file actually says. Two readers disagreeing
173
+ // about the delivery-host set is the one failure this split exists
174
+ // to prevent (R2 finding 2). A SHALLOWER item still ends the block:
175
+ // it belongs to a different mapping level, never to `hosts`.
176
+ if (item !== null && indent >= blockIndent) {
177
+ const v = strip(item[1] ?? '');
178
+ if (v !== '') out.push(v);
179
+ continue;
180
+ }
181
+ inBlock = false;
182
+ }
183
+ const inline = /^\s+hosts\s*:\s*\[([^\]]*)\]\s*$/.exec(line);
184
+ if (inline !== null) {
185
+ for (const part of (inline[1] ?? '').split(',')) {
186
+ const v = strip(part);
187
+ if (v !== '') out.push(v);
188
+ }
189
+ continue;
190
+ }
191
+ if (/^\s+hosts\s*:\s*$/.test(line)) {
192
+ inBlock = true;
193
+ blockIndent = indent;
194
+ }
195
+ }
196
+ return out;
197
+ }
@@ -42,3 +42,130 @@ export function writesThinFiles(mode: LeanProjectionMode): boolean {
42
42
  export function deliversBodies(mode: LeanProjectionMode): boolean {
43
43
  return mode === 'delivery';
44
44
  }
45
+
46
+ /**
47
+ * The hosts a thinning mode may actually thin.
48
+ *
49
+ * Deliberately NOT "every host id the package knows". `condense`'s `TOOL_DIRS`
50
+ * writes a per-rule tree for exactly three hosts, so those are the only ids for
51
+ * which `lean_projection.hosts` can mean anything: naming `windsurf` there would
52
+ * be a request to thin a single concatenated file that has no per-rule stub
53
+ * shape, and naming `codex` a request to thin a tree the installer writes and
54
+ * `condense` never touches. Accepting such an id silently would leave the
55
+ * operator believing a host was scoped when nothing reads the entry.
56
+ */
57
+ export const THINNABLE_HOSTS: readonly string[] = ['claude-code', 'cursor', 'cline'];
58
+
59
+ /**
60
+ * The shipped default host set for a thinning mode.
61
+ *
62
+ * One host, and it is the one host that both binds `pre_tool_use` and honours a
63
+ * deny (`docs/enforcement-by-host.md:18-28`) — i.e. the only host where the
64
+ * delivery concern's verdict is acted on. Widening this is a decision, never a
65
+ * default: see `resolveLeanProjectionHosts`, which never widens implicitly.
66
+ */
67
+ export const DEFAULT_LEAN_PROJECTION_HOSTS: readonly string[] = ['claude-code'];
68
+
69
+ /** Why an id in a configured `hosts:` list was not kept. */
70
+ export type DroppedHostReason = 'unknown' | 'not-thinnable';
71
+
72
+ export interface LeanProjectionHosts {
73
+ /** The ids that survived, sorted and de-duplicated. */
74
+ readonly hosts: readonly string[];
75
+ /** Ids that were dropped, with the reason — reported, never silently discarded. */
76
+ readonly dropped: ReadonlyArray<{ readonly id: string; readonly reason: DroppedHostReason }>;
77
+ /** True when nothing was configured and the default was applied. */
78
+ readonly usedDefault: boolean;
79
+ }
80
+
81
+ /**
82
+ * Resolve a configured `lean_projection.hosts` list.
83
+ *
84
+ * Three properties, each of which is a failure this repository has seen in a
85
+ * neighbouring config surface:
86
+ *
87
+ * 1. **Absent means the default, never "all".** An empty or missing list
88
+ * resolves to `DEFAULT_LEAN_PROJECTION_HOSTS`. A key nobody set must not
89
+ * thin every host — that is D1, the defect this axis exists to repair.
90
+ * 2. **The set never widens implicitly.** Every id is checked against
91
+ * `THINNABLE_HOSTS`; anything else is dropped. A typo cannot enrol a host,
92
+ * and neither can a real host id that has no per-rule tree.
93
+ * 3. **A drop is reported, not swallowed.** The caller gets the ids and the
94
+ * reason so it can print them. Silently ignoring an entry an operator wrote
95
+ * is how a setting comes to mean nothing while looking configured.
96
+ *
97
+ * A configured list that resolves to NOTHING keeps `usedDefault: false` and an
98
+ * empty `hosts` — that is "thin no host", which is a legitimate and safe answer
99
+ * and must not fall back to the default. Falling back there would turn a
100
+ * fully-typo'd list into a Claude Code flip the operator never asked for.
101
+ *
102
+ * WHICH FILES REACH THIS AT ALL, stated because R2 finding 6 read the drop path
103
+ * as unreachable: `agent-settings.schema.json` and the wizard's Zod schema both
104
+ * constrain the items to an `enum`, so an out-of-vocabulary id written through
105
+ * either surface is a hard validation FAILURE and never arrives here. What
106
+ * arrives here is a HAND-EDITED `.agent-settings.yml` — the file
107
+ * `condense._lean_projection_settings` and `hooks/rule_inject_hook.gateOpen`
108
+ * both read directly, with no validation step in between. The two layers are
109
+ * defence in depth, not one contract stated twice: the schema is the authoring
110
+ * gate, this function is the read-time gate, and the drop wording below exists
111
+ * for the file the schema never saw.
112
+ */
113
+ export function resolveLeanProjectionHosts(raw: unknown): LeanProjectionHosts {
114
+ const known = new Set(THINNABLE_HOSTS);
115
+ if (!Array.isArray(raw) || raw.length === 0) {
116
+ return { hosts: [...DEFAULT_LEAN_PROJECTION_HOSTS], dropped: [], usedDefault: true };
117
+ }
118
+ const hosts: string[] = [];
119
+ const dropped: Array<{ id: string; reason: DroppedHostReason }> = [];
120
+ for (const entry of raw) {
121
+ const id = typeof entry === 'string' ? entry.trim().toLowerCase() : '';
122
+ if (id === '') {
123
+ dropped.push({ id: String(entry), reason: 'unknown' });
124
+ continue;
125
+ }
126
+ if (!known.has(id)) {
127
+ // `not-thinnable` is reserved for an id this package genuinely knows
128
+ // as a host but which owns no per-rule tree. Everything else is a
129
+ // typo or an invention, and the two deserve different wording
130
+ // because the operator's next action differs: fix the spelling, or
131
+ // learn that the host cannot be thinned at all.
132
+ dropped.push({ id, reason: KNOWN_NON_THINNABLE_HOSTS.has(id) ? 'not-thinnable' : 'unknown' });
133
+ continue;
134
+ }
135
+ if (!hosts.includes(id)) hosts.push(id);
136
+ }
137
+ hosts.sort();
138
+ return { hosts, dropped, usedDefault: false };
139
+ }
140
+
141
+ /**
142
+ * Host ids the package ships surfaces for that own no per-rule rule tree.
143
+ *
144
+ * Only used to word a drop precisely; it grants nothing. Sourced from
145
+ * `condense._ALL_TOOLS` plus the two hosts outside it that the host table
146
+ * carries (`codex`, `cowork`).
147
+ */
148
+ const KNOWN_NON_THINNABLE_HOSTS: ReadonlySet<string> = new Set([
149
+ 'claude-desktop', 'augment', 'copilot', 'windsurf', 'gemini', 'codex', 'cowork',
150
+ ]);
151
+
152
+ /** One line per dropped id, for a caller that prints warnings. Empty when nothing was dropped. */
153
+ export function describeDroppedHosts(res: LeanProjectionHosts): string[] {
154
+ return res.dropped.map(({ id, reason }) =>
155
+ reason === 'not-thinnable'
156
+ ? `lean_projection.hosts: "${id}" is a known host but has no per-rule rule tree — dropped`
157
+ : `lean_projection.hosts: "${id}" is not a thinnable host id — dropped`,
158
+ );
159
+ }
160
+
161
+ /**
162
+ * Does the projector write stubs for this host, under this mode and host set?
163
+ *
164
+ * The single predicate `condense` calls. Mode is checked FIRST and on purpose:
165
+ * with `mode` unset the answer is `false` for every host regardless of what
166
+ * `hosts` says, so a `hosts:` list left behind after a rollback to `eager-all`
167
+ * thins nothing.
168
+ */
169
+ export function thinsHost(mode: LeanProjectionMode, hosts: readonly string[], hostId: string): boolean {
170
+ return writesThinFiles(mode) && hosts.includes(hostId);
171
+ }
@@ -241,9 +241,8 @@ export type Slot =
241
241
  * Default firing period per slot, before per-platform native-event corrections.
242
242
  *
243
243
  * `stop` is per-turn, NOT session end. On Claude Code the native `Stop` event
244
- * fires after every assistant reply — `hook_manifest.yaml` says so itself,
245
- * describing the `stop` write as a "deterministic … overwrite of hot-context.md",
246
- * i.e. a working-memory refresh per reply. True session end is the separate
244
+ * fires after every assistant reply, so a concern bound there runs once per
245
+ * reply rather than once per session. True session end is the separate
247
246
  * `session_end` slot.
248
247
  */
249
248
  const SLOT_FREQUENCY_DEFAULT: Record<Slot, Frequency> = {