@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
@@ -37,4 +37,112 @@ export function writesThinFiles(mode) {
37
37
  export function deliversBodies(mode) {
38
38
  return mode === 'delivery';
39
39
  }
40
+ /**
41
+ * The hosts a thinning mode may actually thin.
42
+ *
43
+ * Deliberately NOT "every host id the package knows". `condense`'s `TOOL_DIRS`
44
+ * writes a per-rule tree for exactly three hosts, so those are the only ids for
45
+ * which `lean_projection.hosts` can mean anything: naming `windsurf` there would
46
+ * be a request to thin a single concatenated file that has no per-rule stub
47
+ * shape, and naming `codex` a request to thin a tree the installer writes and
48
+ * `condense` never touches. Accepting such an id silently would leave the
49
+ * operator believing a host was scoped when nothing reads the entry.
50
+ */
51
+ export const THINNABLE_HOSTS = ['claude-code', 'cursor', 'cline'];
52
+ /**
53
+ * The shipped default host set for a thinning mode.
54
+ *
55
+ * One host, and it is the one host that both binds `pre_tool_use` and honours a
56
+ * deny (`docs/enforcement-by-host.md:18-28`) — i.e. the only host where the
57
+ * delivery concern's verdict is acted on. Widening this is a decision, never a
58
+ * default: see `resolveLeanProjectionHosts`, which never widens implicitly.
59
+ */
60
+ export const DEFAULT_LEAN_PROJECTION_HOSTS = ['claude-code'];
61
+ /**
62
+ * Resolve a configured `lean_projection.hosts` list.
63
+ *
64
+ * Three properties, each of which is a failure this repository has seen in a
65
+ * neighbouring config surface:
66
+ *
67
+ * 1. **Absent means the default, never "all".** An empty or missing list
68
+ * resolves to `DEFAULT_LEAN_PROJECTION_HOSTS`. A key nobody set must not
69
+ * thin every host — that is D1, the defect this axis exists to repair.
70
+ * 2. **The set never widens implicitly.** Every id is checked against
71
+ * `THINNABLE_HOSTS`; anything else is dropped. A typo cannot enrol a host,
72
+ * and neither can a real host id that has no per-rule tree.
73
+ * 3. **A drop is reported, not swallowed.** The caller gets the ids and the
74
+ * reason so it can print them. Silently ignoring an entry an operator wrote
75
+ * is how a setting comes to mean nothing while looking configured.
76
+ *
77
+ * A configured list that resolves to NOTHING keeps `usedDefault: false` and an
78
+ * empty `hosts` — that is "thin no host", which is a legitimate and safe answer
79
+ * and must not fall back to the default. Falling back there would turn a
80
+ * fully-typo'd list into a Claude Code flip the operator never asked for.
81
+ *
82
+ * WHICH FILES REACH THIS AT ALL, stated because R2 finding 6 read the drop path
83
+ * as unreachable: `agent-settings.schema.json` and the wizard's Zod schema both
84
+ * constrain the items to an `enum`, so an out-of-vocabulary id written through
85
+ * either surface is a hard validation FAILURE and never arrives here. What
86
+ * arrives here is a HAND-EDITED `.agent-settings.yml` — the file
87
+ * `condense._lean_projection_settings` and `hooks/rule_inject_hook.gateOpen`
88
+ * both read directly, with no validation step in between. The two layers are
89
+ * defence in depth, not one contract stated twice: the schema is the authoring
90
+ * gate, this function is the read-time gate, and the drop wording below exists
91
+ * for the file the schema never saw.
92
+ */
93
+ export function resolveLeanProjectionHosts(raw) {
94
+ const known = new Set(THINNABLE_HOSTS);
95
+ if (!Array.isArray(raw) || raw.length === 0) {
96
+ return { hosts: [...DEFAULT_LEAN_PROJECTION_HOSTS], dropped: [], usedDefault: true };
97
+ }
98
+ const hosts = [];
99
+ const dropped = [];
100
+ for (const entry of raw) {
101
+ const id = typeof entry === 'string' ? entry.trim().toLowerCase() : '';
102
+ if (id === '') {
103
+ dropped.push({ id: String(entry), reason: 'unknown' });
104
+ continue;
105
+ }
106
+ if (!known.has(id)) {
107
+ // `not-thinnable` is reserved for an id this package genuinely knows
108
+ // as a host but which owns no per-rule tree. Everything else is a
109
+ // typo or an invention, and the two deserve different wording
110
+ // because the operator's next action differs: fix the spelling, or
111
+ // learn that the host cannot be thinned at all.
112
+ dropped.push({ id, reason: KNOWN_NON_THINNABLE_HOSTS.has(id) ? 'not-thinnable' : 'unknown' });
113
+ continue;
114
+ }
115
+ if (!hosts.includes(id))
116
+ hosts.push(id);
117
+ }
118
+ hosts.sort();
119
+ return { hosts, dropped, usedDefault: false };
120
+ }
121
+ /**
122
+ * Host ids the package ships surfaces for that own no per-rule rule tree.
123
+ *
124
+ * Only used to word a drop precisely; it grants nothing. Sourced from
125
+ * `condense._ALL_TOOLS` plus the two hosts outside it that the host table
126
+ * carries (`codex`, `cowork`).
127
+ */
128
+ const KNOWN_NON_THINNABLE_HOSTS = new Set([
129
+ 'claude-desktop', 'augment', 'copilot', 'windsurf', 'gemini', 'codex', 'cowork',
130
+ ]);
131
+ /** One line per dropped id, for a caller that prints warnings. Empty when nothing was dropped. */
132
+ export function describeDroppedHosts(res) {
133
+ return res.dropped.map(({ id, reason }) => reason === 'not-thinnable'
134
+ ? `lean_projection.hosts: "${id}" is a known host but has no per-rule rule tree — dropped`
135
+ : `lean_projection.hosts: "${id}" is not a thinnable host id — dropped`);
136
+ }
137
+ /**
138
+ * Does the projector write stubs for this host, under this mode and host set?
139
+ *
140
+ * The single predicate `condense` calls. Mode is checked FIRST and on purpose:
141
+ * with `mode` unset the answer is `false` for every host regardless of what
142
+ * `hosts` says, so a `hosts:` list left behind after a rollback to `eager-all`
143
+ * thins nothing.
144
+ */
145
+ export function thinsHost(mode, hosts, hostId) {
146
+ return writesThinFiles(mode) && hosts.includes(hostId);
147
+ }
40
148
  //# sourceMappingURL=lean_projection_mode.js.map
@@ -0,0 +1,243 @@
1
+ /**
2
+ * THE single trigger-matcher implementation for `dist/router.json`.
3
+ *
4
+ * Parity by construction: every surface that answers "which rules fire on
5
+ * this prompt?" — router replay (`router_telemetry.ts`), trigger-coverage
6
+ * CI (`trigger_coverage.ts`), `agent-config explain route`, and
7
+ * `agent-config route:explain` — MUST import the matchers from this module.
8
+ * A second implementation of these semantics anywhere in the tree is a
9
+ * violation (enforced by `tests/scripts/router_match_parity.test.ts`); the
10
+ * historical divergence this kills was `cmd_explain.ts` shipping unanchored
11
+ * keyword matching while the replay path was anchored.
12
+ *
13
+ * Canonical semantics: `docs/contracts/rule-router.md` § `triggers:` shape
14
+ * (the trigger-semantics table — anchored `keyword`, unanchored `phrase`,
15
+ * `command` prefix, `path_prefix` / `file_pattern` over open files).
16
+ *
17
+ * Extracted verbatim from `router_telemetry.ts` (which re-exports the same
18
+ * names for existing importers). Behaviour is pinned by the routing-matrix
19
+ * and trigger-coverage suites — do not "fix" quirks here.
20
+ */
21
+ // ── fnmatch (Python fnmatch.fnmatch) ─────────────────────────────────────
22
+ /**
23
+ * Translate a Unix shell pattern into a RegExp, matching CPython's
24
+ * `fnmatch.translate`. `*` → `.*`, `?` → `.`, `[...]` char classes
25
+ * preserved (with `!` → `^` negation), everything else escaped.
26
+ * Matching is case-sensitive on POSIX (the corpus paths are POSIX).
27
+ */
28
+ function _fnmatchToRegExp(pat) {
29
+ let res = "";
30
+ let i = 0;
31
+ const n = pat.length;
32
+ while (i < n) {
33
+ const c = pat[i];
34
+ i += 1;
35
+ if (c === "*") {
36
+ res += ".*";
37
+ }
38
+ else if (c === "?") {
39
+ res += ".";
40
+ }
41
+ else if (c === "[") {
42
+ let j = i;
43
+ if (j < n && pat[j] === "!") {
44
+ j += 1;
45
+ }
46
+ if (j < n && pat[j] === "]") {
47
+ j += 1;
48
+ }
49
+ while (j < n && pat[j] !== "]") {
50
+ j += 1;
51
+ }
52
+ if (j >= n) {
53
+ res += "\\[";
54
+ }
55
+ else {
56
+ let stuff = pat.slice(i, j);
57
+ if (!stuff.includes("-")) {
58
+ stuff = stuff.replace(/\\/g, "\\\\");
59
+ }
60
+ else {
61
+ // Faithful port of CPython's dash-handling in fnmatch.translate:
62
+ // split the class body on `-` (bounded to [i, j)), escaping each
63
+ // chunk, then re-join with `-` so ranges survive.
64
+ const chunks = [];
65
+ let k = pat[i] === "!" ? i + 2 : i + 1;
66
+ let start = i;
67
+ while (true) {
68
+ const rel = pat.slice(k, j).indexOf("-");
69
+ if (rel < 0) {
70
+ break;
71
+ }
72
+ const idx = k + rel;
73
+ chunks.push(pat.slice(start, idx));
74
+ start = idx + 1;
75
+ k = idx + 3;
76
+ }
77
+ chunks.push(pat.slice(start, j));
78
+ stuff = chunks
79
+ .map((s) => s.replace(/\\/g, "\\\\").replace(/-/g, "\\-"))
80
+ .join("-");
81
+ }
82
+ // Escape regex set-meta chars except backslash/dash already handled.
83
+ stuff = stuff.replace(/([&~|])/g, "\\$1");
84
+ i = j + 1;
85
+ if (stuff.startsWith("!")) {
86
+ stuff = "^" + stuff.slice(1);
87
+ }
88
+ else if (stuff.startsWith("^") || stuff.startsWith("[")) {
89
+ stuff = "\\" + stuff;
90
+ }
91
+ res += `[${stuff}]`;
92
+ }
93
+ }
94
+ else {
95
+ res += c.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
96
+ }
97
+ }
98
+ return new RegExp(`^(?:${res})$`, "s");
99
+ }
100
+ export function _fnmatch(name, pat) {
101
+ return _fnmatchToRegExp(pat).test(name);
102
+ }
103
+ // ── Trigger matching ─────────────────────────────────────────────────────
104
+ /** Apply one trigger to a prompt + context; return True on match. */
105
+ /** Unicode word character — letters, digits, underscore (incl. umlauts). */
106
+ const _WORD_CHAR = /[\p{L}\p{N}_]/u;
107
+ function _isWordChar(c) {
108
+ return c !== undefined && _WORD_CHAR.test(c);
109
+ }
110
+ /**
111
+ * Word-boundary-anchored keyword match (road-to-tested-routing Phase 3).
112
+ *
113
+ * A `keyword` occurrence counts only when its word-character edges sit on
114
+ * word boundaries: `ac` no longer fires inside "black", `plan` no longer
115
+ * fires inside "planet". Two deliberate reliefs:
116
+ *
117
+ * - An edge that is itself a NON-word character (e.g. `__()`, `/image:`,
118
+ * `trans(`, an emoji) carries no boundary requirement on that side —
119
+ * punctuation-shaped keywords keep their exact substring semantics.
120
+ * - The right boundary accepts one optional plural `s` ("icons", "options",
121
+ * "secrets" still fire their singular keyword). Richer inflection (German
122
+ * verb endings: "implementiere", "committen") is a DOCUMENTED accepted
123
+ * recall cost of anchoring — the matrices carry standalone-token phrasings
124
+ * for those languages instead.
125
+ *
126
+ * `phrase` deliberately stays unanchored substring; since this change the
127
+ * two trigger kinds genuinely differ.
128
+ */
129
+ export function keyword_matches_anchored(prompt_lower, kw_lower) {
130
+ if (kw_lower === "") {
131
+ return false;
132
+ }
133
+ const needLeft = _isWordChar(kw_lower[0]);
134
+ const needRight = _isWordChar(kw_lower[kw_lower.length - 1]);
135
+ let idx = prompt_lower.indexOf(kw_lower);
136
+ while (idx !== -1) {
137
+ const leftOk = !needLeft || !_isWordChar(prompt_lower[idx - 1]);
138
+ let rightOk = true;
139
+ if (needRight) {
140
+ let end = idx + kw_lower.length;
141
+ if (prompt_lower[end] === "s") {
142
+ end += 1; // optional plural `s`
143
+ }
144
+ rightOk = !_isWordChar(prompt_lower[end]);
145
+ }
146
+ if (leftOk && rightOk) {
147
+ return true;
148
+ }
149
+ idx = prompt_lower.indexOf(kw_lower, idx + 1);
150
+ }
151
+ return false;
152
+ }
153
+ export function trigger_matches(trigger, prompt, open_files, command) {
154
+ const prompt_lower = prompt.toLowerCase();
155
+ if ("keyword" in trigger) {
156
+ return keyword_matches_anchored(prompt_lower, String(trigger["keyword"]).toLowerCase());
157
+ }
158
+ if ("phrase" in trigger) {
159
+ return prompt_lower.includes(String(trigger["phrase"]).toLowerCase());
160
+ }
161
+ if ("command" in trigger) {
162
+ if (!command) {
163
+ return false;
164
+ }
165
+ return command.startsWith(String(trigger["command"]));
166
+ }
167
+ if ("path_prefix" in trigger) {
168
+ if (!open_files) {
169
+ return false;
170
+ }
171
+ const pref = String(trigger["path_prefix"]);
172
+ for (const p of open_files) {
173
+ if (String(p).startsWith(pref)) {
174
+ return true;
175
+ }
176
+ }
177
+ return false;
178
+ }
179
+ if ("file_pattern" in trigger) {
180
+ if (!open_files) {
181
+ return false;
182
+ }
183
+ const pat = String(trigger["file_pattern"]);
184
+ for (const p of open_files) {
185
+ if (_fnmatch(String(p), pat)) {
186
+ return true;
187
+ }
188
+ }
189
+ return false;
190
+ }
191
+ return false;
192
+ }
193
+ export function _asRuleList(value) {
194
+ if (!Array.isArray(value)) {
195
+ return [];
196
+ }
197
+ return value;
198
+ }
199
+ export function _asTriggerList(value) {
200
+ if (!Array.isArray(value)) {
201
+ return [];
202
+ }
203
+ return value;
204
+ }
205
+ /**
206
+ * Return the matched-triggers + activated-rules for one prompt.
207
+ *
208
+ * Kernel rules are always active. tier_1 always considered. tier_2
209
+ * only considered when `profile == 'full'`.
210
+ */
211
+ export function match_prompt(router, prompt, profile = "full", open_files, command) {
212
+ const tiers = [
213
+ ["tier_1", _asRuleList(router["tier_1"])],
214
+ ];
215
+ if (profile === "full") {
216
+ tiers.push(["tier_2", _asRuleList(router["tier_2"])]);
217
+ }
218
+ const matched_triggers = [];
219
+ const activated_rules = [];
220
+ for (const [tier_name, rules] of tiers) {
221
+ for (const rule of rules) {
222
+ const rule_id = rule["id"];
223
+ const rule_triggers = _asTriggerList(rule["triggers"]);
224
+ let rule_hit = false;
225
+ for (const trig of rule_triggers) {
226
+ if (trigger_matches(trig, prompt, open_files, command)) {
227
+ matched_triggers.push({ tier: tier_name, rule: rule_id, trigger: trig });
228
+ rule_hit = true;
229
+ }
230
+ }
231
+ if (rule_hit) {
232
+ activated_rules.push({ tier: tier_name, rule: rule_id });
233
+ }
234
+ }
235
+ }
236
+ // Kernel rules are always active.
237
+ const kernel = Array.isArray(router["kernel"]) ? router["kernel"] : [];
238
+ for (const kid of kernel) {
239
+ activated_rules.push({ tier: "kernel", rule: kid });
240
+ }
241
+ return { matched_triggers, activated_rules };
242
+ }
243
+ //# sourceMappingURL=router_match.js.map
@@ -0,0 +1,216 @@
1
+ /**
2
+ * Rule-injection core — THE single module both the offline model and the
3
+ * runtime concern read.
4
+ *
5
+ * WHY ONE MODULE. `road-to-trigger-delivered-rule-bodies` step 0.5 states the
6
+ * failure this prevents in as many words: *an experiment whose offline pricing
7
+ * and runtime delivery use different matchers measures nothing*. So the price /
8
+ * recall model (`src/scripts/model_rule_injection.ts`) and the delivery concern
9
+ * (`src/scripts/hooks/rule_inject_hook.ts`) both import THIS file, and neither
10
+ * re-implements selection, ordering, capping, or body loading.
11
+ *
12
+ * IT OWNS NO MATCHER. Trigger semantics belong to
13
+ * [`_lib/router_match.ts`](router_match.ts), which is already the single
14
+ * implementation for every surface that answers "which rules fire on this
15
+ * prompt?" and is pinned by `tests/scripts/router_match_parity.test.ts`. A
16
+ * second matcher here would be the violation that test exists to catch, so
17
+ * `matchTierRules` is a thin, deterministic wrapper over `match_prompt` and
18
+ * nothing more. Step 0.3's pre-registered comparison found no reason to write
19
+ * one — see `model_rule_injection.ts`'s header for the measured verdict.
20
+ *
21
+ * KERNEL IS NEVER INJECTED. The nine kernel rules are in standing context by
22
+ * definition; injecting one would be paying twice for a body that is already
23
+ * there. `match_prompt` returns kernel ids in `activated_rules` because kernel
24
+ * rules are always active — this module filters them out by construction rather
25
+ * than relying on a caller to remember.
26
+ *
27
+ * IT IMPORTS NO TOKENIZER, AND THAT IS A HOT-PATH FACT RATHER THAN A STYLE
28
+ * CHOICE. `_lib/token_count.ts` resolves `js-tiktoken` AT MODULE LOAD, and the
29
+ * concern that imports this file is statically reachable from
30
+ * `concern_registry.ts` — so importing it here made every hook dispatch on
31
+ * every slot pay a tokenizer load for a concern that is default-OFF and emits
32
+ * nothing. Measured on this tree: unbinding the concern moved the
33
+ * `pre_tool_use` p95 from 202 ms to 196 ms, and the CI latency gate went red on
34
+ * the branch that introduced it while passing on main.
35
+ *
36
+ * So the runtime cap is in BYTES. That is not a weaker bound — it is the same
37
+ * bound in the unit the budget actually enforces: `hook-token-budget.json`
38
+ * measures "bytes of concern stdout payload fields", so the cap and its
39
+ * registered row are now the same number instead of two units that need a
40
+ * conversion factor to compare. The offline model keeps exact-BPE tokens for
41
+ * its price table, where the tokenizer is the point and nothing is on a hot
42
+ * path.
43
+ *
44
+ * DETERMINISM IS THE CONTRACT, and the collision cases are the reason it needs
45
+ * stating. Two triggers on the SAME rule collapse to one entry (a rule is
46
+ * delivered once, however many of its triggers fired) while the trigger count
47
+ * survives as `score`. Two DIFFERENT rules both firing are returned in router
48
+ * declaration order, tier_1 before tier_2 — never in match order, which would
49
+ * make the output depend on trigger authoring order inside a rule. Capping
50
+ * sorts by descending score with router order as the tie-break, so the same
51
+ * prompt against the same router always yields the same bytes.
52
+ */
53
+ import * as fs from 'node:fs';
54
+ import * as path from 'node:path';
55
+ import { match_prompt } from './router_match.js';
56
+ /** Kinds of trigger a prompt alone can never fire. */
57
+ export const PATH_TRIGGER_KINDS = ['path_prefix', 'file_pattern'];
58
+ export function loadRouter(repoRoot) {
59
+ const p = path.join(repoRoot, 'dist', 'router.json');
60
+ return JSON.parse(fs.readFileSync(p, 'utf8'));
61
+ }
62
+ /** Kernel rule ids, as declared by the router. */
63
+ export function kernelIds(router) {
64
+ const k = Array.isArray(router['kernel']) ? router['kernel'] : [];
65
+ return new Set(k.map((x) => String(x)));
66
+ }
67
+ function tierEntries(router, tier) {
68
+ const raw = router[tier];
69
+ if (!Array.isArray(raw))
70
+ return [];
71
+ return raw.map((r) => ({
72
+ id: String(r['id'] ?? ''),
73
+ triggers: Array.isArray(r['triggers']) ? r['triggers'] : [],
74
+ }));
75
+ }
76
+ /** Every tier rule declared by the router, with its trigger list. */
77
+ export function allTierRules(router) {
78
+ const out = [];
79
+ for (const tier of ['tier_1', 'tier_2']) {
80
+ for (const e of tierEntries(router, tier))
81
+ out.push({ ...e, tier });
82
+ }
83
+ return out;
84
+ }
85
+ /** Rules whose triggers are ALL path-shaped — unreachable from a prompt alone. */
86
+ export function pathOnlyRuleIds(router) {
87
+ const ids = new Set();
88
+ for (const r of allTierRules(router)) {
89
+ if (r.triggers.length === 0)
90
+ continue;
91
+ const allPath = r.triggers.every((t) => PATH_TRIGGER_KINDS.some((k) => k in t));
92
+ if (allPath)
93
+ ids.add(r.id);
94
+ }
95
+ return ids;
96
+ }
97
+ /** Rules declaring at least one path-shaped trigger. */
98
+ export function pathCapableRuleIds(router) {
99
+ const ids = new Set();
100
+ for (const r of allTierRules(router)) {
101
+ if (r.triggers.some((t) => PATH_TRIGGER_KINDS.some((k) => k in t)))
102
+ ids.add(r.id);
103
+ }
104
+ return ids;
105
+ }
106
+ /** Rules declaring no trigger at all — cannot be delivered, must stay eager. */
107
+ export function triggerlessRuleIds(router) {
108
+ return allTierRules(router)
109
+ .filter((r) => r.triggers.length === 0)
110
+ .map((r) => r.id);
111
+ }
112
+ /**
113
+ * Which tier rules fire on this prompt (+ optional open files / command).
114
+ *
115
+ * Kernel is excluded. Order is router declaration order, tier_1 first.
116
+ */
117
+ export function matchTierRules(router, prompt, openFiles, command) {
118
+ const kernel = kernelIds(router);
119
+ const res = match_prompt(router, prompt, 'full', openFiles, command);
120
+ const scores = new Map();
121
+ for (const mt of res.matched_triggers) {
122
+ const id = String(mt.rule ?? '');
123
+ if (id === '' || kernel.has(id))
124
+ continue;
125
+ scores.set(id, (scores.get(id) ?? 0) + 1);
126
+ }
127
+ const out = [];
128
+ let order = 0;
129
+ for (const r of allTierRules(router)) {
130
+ const s = scores.get(r.id);
131
+ if (s === undefined) {
132
+ order += 1;
133
+ continue;
134
+ }
135
+ out.push({ id: r.id, tier: r.tier, score: s, order });
136
+ order += 1;
137
+ }
138
+ return out;
139
+ }
140
+ /** Where the projected body of a rule lives. */
141
+ export function ruleBodyPath(repoRoot, id) {
142
+ return path.join(repoRoot, 'dist', 'agent-src', 'rules', `${id}.md`);
143
+ }
144
+ /** The projected body, or `null` when the rule has no projected file. */
145
+ export function loadRuleBody(repoRoot, id) {
146
+ const p = ruleBodyPath(repoRoot, id);
147
+ if (!fs.existsSync(p))
148
+ return null;
149
+ return fs.readFileSync(p, 'utf8');
150
+ }
151
+ /**
152
+ * UTF-8 byte length — the runtime measure, dependency-free by design.
153
+ *
154
+ * Deliberately NOT a token count: see the header. Bytes are exact, need no
155
+ * tokenizer, and are the unit `hook-token-budget.json` enforces.
156
+ */
157
+ export function bytesOf(text) {
158
+ return Buffer.byteLength(text, 'utf8');
159
+ }
160
+ /**
161
+ * Apply the per-prompt BYTE cap.
162
+ *
163
+ * Highest score first, router order as tie-break; a rule whose body would push
164
+ * the running total past `capBytes` is dropped and the walk continues, so one
165
+ * oversized body cannot starve the rest. The returned `selected` list is
166
+ * re-sorted back into router order — cap order is a budgeting concern, delivery
167
+ * order is not.
168
+ *
169
+ * ONE selection for both callers. The offline model and the runtime concern
170
+ * call THIS function with THE SAME cap, so the set the price table prices is
171
+ * byte-for-byte the set the concern delivers. That is step 0.5's requirement,
172
+ * and expressing the cap in bytes makes it hold without a token/byte
173
+ * conversion sitting between the two arms.
174
+ */
175
+ export function selectForInjection(repoRoot, matches, capBytes, shortlist) {
176
+ const bodyBytes = new Map();
177
+ for (const m of matches) {
178
+ const body = loadRuleBody(repoRoot, m.id);
179
+ bodyBytes.set(m.id, body === null ? 0 : bytesOf(body));
180
+ }
181
+ // STEP 6.3 — the optional lexical shortlist, as a TIE-BREAK and nothing more.
182
+ //
183
+ // Absent (the default), the cap order is exactly what it was: score, then
184
+ // router order. Present, it sits BETWEEN them, never above `score` — the
185
+ // matcher's verdict is read first and the shortlist only orders what the
186
+ // matcher already tied. Membership is untouched in both directions: a
187
+ // shortlisted id the matcher did not return is not in `matches` and so is
188
+ // never consulted, and no matched id is dropped for being unshortlisted
189
+ // (it sorts at Infinity, behind the shortlisted ones, and still competes
190
+ // for the cap). That is `_lib/lexical_shortlist.ts`'s "never decides
191
+ // alone" expressed at the one place the cap actually binds.
192
+ const rank = new Map();
193
+ for (const [i, id] of (shortlist ?? []).entries()) {
194
+ if (!rank.has(id))
195
+ rank.set(id, i);
196
+ }
197
+ const ranked = [...matches].sort((a, b) => b.score - a.score ||
198
+ (rank.get(a.id) ?? Infinity) - (rank.get(b.id) ?? Infinity) ||
199
+ a.order - b.order);
200
+ const selected = [];
201
+ const dropped = [];
202
+ let total = 0;
203
+ for (const m of ranked) {
204
+ const t = bodyBytes.get(m.id) ?? 0;
205
+ if (total + t > capBytes && selected.length > 0) {
206
+ dropped.push(m);
207
+ continue;
208
+ }
209
+ selected.push(m);
210
+ total += t;
211
+ }
212
+ selected.sort((a, b) => a.order - b.order);
213
+ dropped.sort((a, b) => a.order - b.order);
214
+ return { selected, dropped, bytes: total, bodyBytes };
215
+ }
216
+ //# sourceMappingURL=rule_injection.js.map
@@ -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
@@ -39,7 +40,7 @@ import { _domains_command_logical, artefact_roots as _agent_src_artefact_roots,
39
40
  // bundled-CLI-entry-guard landmine. Verified before wiring, not assumed.
40
41
  import { build_thin } from './project_thin_rules.js';
41
42
  import { build_claude_hook_matrix } from './_lib/claude_settings_hooks.js';
42
- import { normalizeLeanProjectionMode, writesThinFiles } from './_lib/lean_projection_mode.js';
43
+ import { describeDroppedHosts, normalizeLeanProjectionMode, resolveLeanProjectionHosts, thinsHost, writesThinFiles } from './_lib/lean_projection_mode.js';
43
44
  import { is_claude_builtin_name } from './_lib/claude_builtin_names.js';
44
45
  import { project_settings_path, load_agent_settings } from './_lib/agent_settings.js';
45
46
  import { rule_is_compile_enabled } from './_lib/compile_time_toggles.js';
@@ -383,13 +384,16 @@ function _read_projection_scope_dedup() {
383
384
  }
384
385
  return false;
385
386
  }
386
- function _lean_projection_mode() {
387
+ function _lean_projection_settings() {
387
388
  const data = load_agent_settings({ project_path: MODULE_STATE.SETTINGS_FILE });
388
389
  const lean = data['lean_projection'];
389
- const raw = typeof lean === 'object' && lean !== null && !Array.isArray(lean)
390
- ? lean['mode']
391
- : '';
392
- return normalizeLeanProjectionMode(raw);
390
+ const obj = typeof lean === 'object' && lean !== null && !Array.isArray(lean)
391
+ ? lean
392
+ : {};
393
+ return {
394
+ mode: normalizeLeanProjectionMode(obj['mode'] ?? ''),
395
+ hosts: resolveLeanProjectionHosts(obj['hosts']),
396
+ };
393
397
  }
394
398
  // --- hashing -----------------------------------------------------------------
395
399
  export function apply_path_rewriter(relative_path) {
@@ -690,7 +694,6 @@ const _PROJECTED_SRC_PREFIX = 'dist/agent-src/';
690
694
  const _LEGACY_PROJECTED_SRC_PREFIX = '.agent-src/';
691
695
  const _FM_LIST_ITEM_RE = /^(\s*-\s*)(["']?)([^"'\n]+?\.md)(["']?)\s*$/;
692
696
  const _FM_PATH_PREFIX_RE = /^(\s*(?:-\s+)?path_prefix:\s*)(["']?)([^"'\n]+?)(["']?)\s*$/;
693
- const _BODY_DOCS_RE = /\.\.\/\.\.\/(docs\/(?:guidelines|contracts)\/[^)\s]+\.md)/g;
694
697
  const _FM_PLAIN_LIST_RE = /^\s*-\s*(["']?)([^"'\n]+?)\1\s*$/;
695
698
  const _HRR_BANNER_MARKER = '<!-- agent-config:human-review-banner -->';
696
699
  function _depth_prefix(source_relative_path) {
@@ -763,9 +766,6 @@ function _rewrite_frontmatter_lines(lines, prefix) {
763
766
  }
764
767
  return out;
765
768
  }
766
- function _rewrite_body_links(body, prefix) {
767
- return body.replace(_BODY_DOCS_RE, (_m, tail) => prefix + tail);
768
- }
769
769
  function _parse_trust_and_owner(fm_lines) {
770
770
  let level = 'core';
771
771
  let hrr = false;
@@ -819,7 +819,7 @@ function _inject_hrr_banner(body, level, owner) {
819
819
  export function _rewrite_paths(content, source_relative_path) {
820
820
  const prefix = _depth_prefix(source_relative_path);
821
821
  const [fm_lines, bodyInitial] = _split_frontmatter(content);
822
- let body = _rewrite_body_links(bodyInitial, prefix);
822
+ let body = rewriteProjectedBodyLinks(bodyInitial, prefix);
823
823
  if (fm_lines === null) {
824
824
  return body;
825
825
  }
@@ -985,20 +985,17 @@ export function projected_rule_trees(user_home = process.env['HOME'] ?? os.homed
985
985
  export function generate_rule_symlinks() {
986
986
  const rules = _scoped_rule_basenames();
987
987
  const tool_dirs = _filter_tool_dirs(TOOL_DIRS);
988
+ const lean = _lean_projection_settings();
989
+ for (const warning of describeDroppedHosts(lean.hosts))
990
+ _print(` ⚠️ ${warning}`);
988
991
  let thin_files = null;
989
- if (writesThinFiles(_lean_projection_mode())) {
990
- // DEAD-SWITCH REPAIR (road-to-renewal-foundation Phase 2). This branch
991
- // used to THROW: the port was skipped as "out of scope, not exercised by
992
- // golden parity", which left a documented, settings-selectable mode that
993
- // could only ever crash. `build_thin` was ported and has been present the
994
- // whole time — the wiring was the only thing missing.
995
- //
996
- // Scope note: this repairs the SWITCH only. The default stays
997
- // `eager-all`. Flipping it is parked behind the thin-projection honest
998
- // null (thin win-rate 36.2% < the 48% pre-registered threshold), and
999
- // nothing here disturbs that verdict — but a mode that throws cannot
1000
- // even be re-measured, which is why the repair earns its place alone.
1001
- thin_files = Object.fromEntries(build_thin(MODULE_STATE.RULES_SOURCE, _read_rule_workspaces()));
992
+ if (writesThinFiles(lean.mode)) {
993
+ // `thin` stays parked behind the thin-projection honest null (win-rate
994
+ // 36.2% against a 48% pre-registered threshold, ADR-202). `delivery` is
995
+ // NOT gated by that null and citing it as one is K7: delivery re-delivers
996
+ // identical bytes, is licensed by `docs/CLAIMS.md:365` on delivery
997
+ // equivalence and cost, and needs a recall floor rather than a judge.
998
+ thin_files = Object.fromEntries(build_thin(MODULE_STATE.RULES_SOURCE, _read_rule_workspaces(), (m) => _print(` ⚠️ ${m}`)));
1002
999
  }
1003
1000
  const user_home = process.env['HOME'] ?? os.homedir();
1004
1001
  // Read the emit plan from the exported function rather than recomputing the
@@ -1044,7 +1041,7 @@ export function generate_rule_symlinks() {
1044
1041
  if (_existsOrSymlink(link)) {
1045
1042
  fs.unlinkSync(link);
1046
1043
  }
1047
- if (thin_files !== null) {
1044
+ if (thin_files !== null && thinsHost(lean.mode, lean.hosts.hosts, _DIR_TOOL_ID[tool_dir] ?? '')) {
1048
1045
  _writeText(link, thin_files[rule]);
1049
1046
  }
1050
1047
  else if (tool_dir === '.claude/rules') {