@event4u/agent-config 16.2.0 → 16.4.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 (651) 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 +337 -234
  5. package/README.md +15 -13
  6. package/agents/templates/.ai-council.yml.example +26 -8
  7. package/dist/agent-src/commands/analyze/inbox.md +11 -8
  8. package/dist/agent-src/commands/analyze/roadmap-repos.md +1 -1
  9. package/dist/agent-src/commands/bug/fix.md +17 -2
  10. package/dist/agent-src/commands/bug/investigate.md +1 -1
  11. package/dist/agent-src/commands/commit/in-chunks.md +40 -31
  12. package/dist/agent-src/commands/commit.md +72 -33
  13. package/dist/agent-src/commands/condense.md +2 -8
  14. package/dist/agent-src/commands/council/debate.md +11 -7
  15. package/dist/agent-src/commands/council/default.md +10 -9
  16. package/dist/agent-src/commands/council.md +1 -1
  17. package/dist/agent-src/commands/estimate-ticket.md +1 -1
  18. package/dist/agent-src/commands/feature/explore.md +3 -3
  19. package/dist/agent-src/commands/feature/plan.md +2 -2
  20. package/dist/agent-src/commands/feature/roadmap.md +1 -1
  21. package/dist/agent-src/commands/fix/ci.md +18 -4
  22. package/dist/agent-src/commands/fix/commit-messages.md +48 -23
  23. package/dist/agent-src/commands/fix/pr-comments.md +3 -6
  24. package/dist/agent-src/commands/implement-ticket.md +4 -4
  25. package/dist/agent-src/commands/jira-ticket.md +1 -1
  26. package/dist/agent-src/commands/memory/add.md +4 -16
  27. package/dist/agent-src/commands/memory/load.md +5 -6
  28. package/dist/agent-src/commands/memory/promote.md +3 -16
  29. package/dist/agent-src/commands/mission/upgrade.md +3 -2
  30. package/dist/agent-src/commands/optimize/agents-dir.md +2 -2
  31. package/dist/agent-src/commands/optimize/deep.md +4 -2
  32. package/dist/agent-src/commands/optimize/rtk.md +4 -26
  33. package/dist/agent-src/commands/pr/create/description-only.md +18 -15
  34. package/dist/agent-src/commands/pr/create.md +42 -34
  35. package/dist/agent-src/commands/pr/merge.md +136 -9
  36. package/dist/agent-src/commands/prepare-for-review.md +13 -11
  37. package/dist/agent-src/commands/project/analyze.md +7 -35
  38. package/dist/agent-src/commands/refine-ticket.md +1 -1
  39. package/dist/agent-src/commands/review/changes.md +14 -19
  40. package/dist/agent-src/commands/roadmap/create.md +1 -1
  41. package/dist/agent-src/commands/roadmap/materialize.md +1 -1
  42. package/dist/agent-src/commands/roadmap/next.md +10 -1
  43. package/dist/agent-src/commands/roadmap/process-full.md +56 -42
  44. package/dist/agent-src/commands/roadmap/resolve-blockers.md +411 -0
  45. package/dist/agent-src/commands/roadmap/triage-parked.md +325 -0
  46. package/dist/agent-src/commands/roadmap.md +18 -4
  47. package/dist/agent-src/commands/tests/create.md +17 -3
  48. package/dist/agent-src/commands/tests/execute.md +22 -5
  49. package/dist/agent-src/commands/worktree/create.md +7 -3
  50. package/dist/agent-src/commands/worktree/verify.md +2 -1
  51. package/dist/agent-src/contexts/authority/decision-revisit-gate-enforcement.md +43 -0
  52. package/dist/agent-src/contexts/communication/rules-auto/design-fidelity-enforcement.md +24 -0
  53. package/dist/agent-src/contexts/communication/rules-auto/think-before-action-mechanics.md +5 -3
  54. package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +7 -9
  55. package/dist/agent-src/contexts/contracts/command-suggestion-flow.md +8 -6
  56. package/dist/agent-src/contexts/contracts/frugality-charter.md +8 -5
  57. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +7 -7
  58. package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +0 -1
  59. package/dist/agent-src/contexts/execution/evidence-discipline.md +2 -2
  60. package/dist/agent-src/contexts/execution/non-interactive-contract.md +5 -8
  61. package/dist/agent-src/contexts/execution/rdp-gate.md +4 -4
  62. package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +9 -8
  63. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +99 -54
  64. package/dist/agent-src/contexts/execution/session-canary-enforcement-history.md +67 -0
  65. package/dist/agent-src/contexts/execution/subagent-routing.md +8 -8
  66. package/dist/agent-src/contexts/execution/subagent-steering.md +6 -4
  67. package/dist/agent-src/contexts/execution/terminal-states.md +2 -2
  68. package/dist/agent-src/contexts/execution/toolchain-resolver.md +95 -7
  69. package/dist/agent-src/contexts/subagent-configuration.md +1 -1
  70. package/dist/agent-src/guidelines/agent-infra/active-remediation-mechanics.md +39 -0
  71. package/dist/agent-src/guidelines/agent-infra/context-hygiene-mechanics.md +1 -1
  72. package/dist/agent-src/guidelines/agent-infra/cross-source-consistency-mechanics.md +8 -10
  73. package/dist/agent-src/guidelines/agent-infra/frontier-reasoning-operating-profile.md +3 -2
  74. package/dist/agent-src/guidelines/agent-infra/layered-settings.md +13 -1
  75. package/dist/agent-src/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
  76. package/dist/agent-src/guidelines/agent-infra/self-improvement-pipeline.md +10 -3
  77. package/dist/agent-src/guidelines/agent-infra/size-and-scope.md +36 -0
  78. package/dist/agent-src/guidelines/php/git.md +15 -2
  79. package/dist/agent-src/rules/active-remediation.md +1 -2
  80. package/dist/agent-src/rules/analysis-skill-routing.md +0 -1
  81. package/dist/agent-src/rules/architecture.md +0 -1
  82. package/dist/agent-src/rules/artifact-drafting-protocol.md +0 -1
  83. package/dist/agent-src/rules/artifact-engagement-recording.md +0 -1
  84. package/dist/agent-src/rules/augment-edit-discipline.md +0 -1
  85. package/dist/agent-src/rules/autonomous-execution.md +1 -1
  86. package/dist/agent-src/rules/brand-consistency.md +0 -1
  87. package/dist/agent-src/rules/brand-source-of-truth.md +0 -1
  88. package/dist/agent-src/rules/broken-access-control.md +1 -1
  89. package/dist/agent-src/rules/cli-output-handling.md +0 -1
  90. package/dist/agent-src/rules/code-comment-discipline.md +0 -1
  91. package/dist/agent-src/rules/code-provenance.md +0 -1
  92. package/dist/agent-src/rules/command-suggestion-policy.md +1 -1
  93. package/dist/agent-src/rules/commit-conventions.md +1 -2
  94. package/dist/agent-src/rules/communication-through-line.md +1 -2
  95. package/dist/agent-src/rules/content-quoting-floor.md +1 -2
  96. package/dist/agent-src/rules/context-hygiene.md +6 -6
  97. package/dist/agent-src/rules/copilot-routing.md +1 -2
  98. package/dist/agent-src/rules/council-availability.md +4 -4
  99. package/dist/agent-src/rules/cross-source-consistency.md +4 -6
  100. package/dist/agent-src/rules/decision-revisit-gate.md +17 -35
  101. package/dist/agent-src/rules/delegation-policy.md +2 -3
  102. package/dist/agent-src/rules/design-fidelity.md +12 -16
  103. package/dist/agent-src/rules/design-review-after-ui-write.md +3 -3
  104. package/dist/agent-src/rules/devcontainer-routing.md +1 -2
  105. package/dist/agent-src/rules/doc-screenshot-hygiene.md +1 -1
  106. package/dist/agent-src/rules/docker-commands.md +0 -1
  107. package/dist/agent-src/rules/domain-adoption-policy.md +0 -1
  108. package/dist/agent-src/rules/domain-safety-disclaimer.md +1 -1
  109. package/dist/agent-src/rules/domain-safety-pii.md +1 -1
  110. package/dist/agent-src/rules/domain-safety-retention.md +1 -1
  111. package/dist/agent-src/rules/downstream-changes.md +0 -1
  112. package/dist/agent-src/rules/engineering-safety-floor.md +1 -1
  113. package/dist/agent-src/rules/evaluator-independence.md +3 -2
  114. package/dist/agent-src/rules/external-code-graph-interop.md +0 -1
  115. package/dist/agent-src/rules/external-reference-deep-dive.md +0 -1
  116. package/dist/agent-src/rules/fast-path-marker-visibility.md +2 -2
  117. package/dist/agent-src/rules/finance-safety-floor.md +1 -1
  118. package/dist/agent-src/rules/fix-what-you-see.md +6 -32
  119. package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +0 -1
  120. package/dist/agent-src/rules/git-history-discipline.md +2 -2
  121. package/dist/agent-src/rules/guidelines.md +0 -1
  122. package/dist/agent-src/rules/history-discipline.md +0 -1
  123. package/dist/agent-src/rules/icon-consistency.md +0 -1
  124. package/dist/agent-src/rules/image-likeness-and-rights.md +1 -1
  125. package/dist/agent-src/rules/improve-before-implement.md +0 -1
  126. package/dist/agent-src/rules/invite-challenge.md +0 -1
  127. package/dist/agent-src/rules/laravel-routing.md +1 -2
  128. package/dist/agent-src/rules/laravel-translations.md +0 -1
  129. package/dist/agent-src/rules/legal-safety-floor.md +3 -3
  130. package/dist/agent-src/rules/lethal-trifecta-guard.md +1 -1
  131. package/dist/agent-src/rules/linked-projects-onboarding-gate.md +0 -1
  132. package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +1 -1
  133. package/dist/agent-src/rules/markdown-safe-codeblocks.md +0 -1
  134. package/dist/agent-src/rules/media-governance-routing.md +13 -17
  135. package/dist/agent-src/rules/media-sync-ground-truth.md +0 -1
  136. package/dist/agent-src/rules/minimal-safe-diff.md +0 -1
  137. package/dist/agent-src/rules/missing-skill-recovery.md +0 -1
  138. package/dist/agent-src/rules/missing-tool-handling.md +0 -1
  139. package/dist/agent-src/rules/model-recommendation.md +0 -1
  140. package/dist/agent-src/rules/neighbour-precedence.md +64 -0
  141. package/dist/agent-src/rules/no-attribution-footers.md +0 -1
  142. package/dist/agent-src/rules/no-decorative-emojis-in-git-surfaces.md +0 -1
  143. package/dist/agent-src/rules/no-pr-progress-comments.md +0 -1
  144. package/dist/agent-src/rules/no-roadmap-references.md +0 -1
  145. package/dist/agent-src/rules/notes-first-reasoning.md +0 -1
  146. package/dist/agent-src/rules/onboarding-gate.md +0 -1
  147. package/dist/agent-src/rules/output-discipline.md +0 -1
  148. package/dist/agent-src/rules/package-ci-checks.md +0 -1
  149. package/dist/agent-src/rules/persona-governance.md +4 -5
  150. package/dist/agent-src/rules/php-coding.md +0 -1
  151. package/dist/agent-src/rules/prefer-enums-over-literals.md +0 -1
  152. package/dist/agent-src/rules/preservation-guard.md +0 -1
  153. package/dist/agent-src/rules/provider-lifecycle-discipline.md +3 -4
  154. package/dist/agent-src/rules/question-not-instruction.md +1 -1
  155. package/dist/agent-src/rules/reviewer-awareness.md +0 -1
  156. package/dist/agent-src/rules/roadmap-ci-steps-policy.md +0 -1
  157. package/dist/agent-src/rules/roadmap-progress-sync.md +4 -7
  158. package/dist/agent-src/rules/role-mode-adherence.md +0 -1
  159. package/dist/agent-src/rules/rule-type-governance.md +0 -1
  160. package/dist/agent-src/rules/runtime-safety.md +1 -1
  161. package/dist/agent-src/rules/scale-discipline.md +0 -1
  162. package/dist/agent-src/rules/secret-vcs-guard.md +1 -1
  163. package/dist/agent-src/rules/security-sensitive-stop.md +3 -3
  164. package/dist/agent-src/rules/self-repair-loop.md +0 -1
  165. package/dist/agent-src/rules/senior-engineering-discipline.md +0 -1
  166. package/dist/agent-src/rules/session-canary.md +7 -62
  167. package/dist/agent-src/rules/settings-ask-protocol.md +6 -6
  168. package/dist/agent-src/rules/size-enforcement.md +0 -1
  169. package/dist/agent-src/rules/skill-improvement-trigger.md +2 -3
  170. package/dist/agent-src/rules/skill-quality.md +0 -1
  171. package/dist/agent-src/rules/slash-command-routing-policy.md +0 -1
  172. package/dist/agent-src/rules/source-confidentiality.md +1 -1
  173. package/dist/agent-src/rules/source-discovery-gate.md +0 -1
  174. package/dist/agent-src/rules/source-of-truth.md +0 -1
  175. package/dist/agent-src/rules/spreadsheet-source-quality.md +1 -2
  176. package/dist/agent-src/rules/strategy-safety-floor.md +1 -1
  177. package/dist/agent-src/rules/symfony-routing.md +1 -2
  178. package/dist/agent-src/rules/think-before-action.md +0 -1
  179. package/dist/agent-src/rules/token-budget-discipline.md +12 -46
  180. package/dist/agent-src/rules/token-efficiency.md +0 -1
  181. package/dist/agent-src/rules/token-optimizer-maintenance.md +0 -1
  182. package/dist/agent-src/rules/tool-safety.md +1 -1
  183. package/dist/agent-src/rules/ui-audit-gate.md +1 -2
  184. package/dist/agent-src/rules/untrusted-input-defense.md +1 -1
  185. package/dist/agent-src/rules/upstream-proposal.md +0 -1
  186. package/dist/agent-src/rules/user-interaction.md +0 -1
  187. package/dist/agent-src/rules/user-interrupt-priority.md +1 -1
  188. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +115 -20
  189. package/dist/agent-src/scripts/deferral_carry.ts +339 -0
  190. package/dist/agent-src/scripts/gate_budget.ts +47 -23
  191. package/dist/agent-src/scripts/gate_execute.ts +12 -4
  192. package/dist/agent-src/scripts/update_roadmap_progress.ts +4 -1
  193. package/dist/agent-src/skills/ai-council/SKILL.md +7 -4
  194. package/dist/agent-src/skills/ai-council/references/cost-and-redaction.md +21 -11
  195. package/dist/agent-src/skills/ai-council/references/procedure.md +12 -6
  196. package/dist/agent-src/skills/analysis-autonomous-mode/SKILL.md +1 -1
  197. package/dist/agent-src/skills/api-design/data/manifest.json +2 -2
  198. package/dist/agent-src/skills/api-testing/SKILL.md +17 -0
  199. package/dist/agent-src/skills/bug-analyzer/SKILL.md +1 -1
  200. package/dist/agent-src/skills/code-intelligence/SKILL.md +14 -2
  201. package/dist/agent-src/skills/command-routing/SKILL.md +3 -4
  202. package/dist/agent-src/skills/conventional-commits-writing/SKILL.md +127 -139
  203. package/dist/agent-src/skills/corpus-grounding/ATTRIBUTION.md +39 -0
  204. package/dist/agent-src/skills/corpus-grounding/SKILL.md +8 -2
  205. package/dist/agent-src/skills/database/data/manifest.json +2 -2
  206. package/dist/agent-src/skills/database/data/query-tuning.csv +13 -13
  207. package/dist/agent-src/skills/design-system-capture/SKILL.md +0 -3
  208. package/dist/agent-src/skills/design-system-capture/references/import-procedure.md +1 -1
  209. package/dist/agent-src/skills/estimate-ticket/SKILL.md +1 -1
  210. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +2 -2
  211. package/dist/agent-src/skills/fe-design/SKILL.md +1 -1
  212. package/dist/agent-src/skills/feature-planning/SKILL.md +1 -1
  213. package/dist/agent-src/skills/git-workflow/SKILL.md +44 -44
  214. package/dist/agent-src/skills/git-workflow/references/branch-update.md +312 -0
  215. package/dist/agent-src/skills/git-workflow/references/commit-subject.md +205 -0
  216. package/dist/agent-src/skills/iconography/SKILL.md +1 -1
  217. package/dist/agent-src/skills/jira-integration/SKILL.md +3 -3
  218. package/dist/agent-src/skills/js-library-packaging/SKILL.md +2 -2
  219. package/dist/agent-src/skills/merge-conflicts/SKILL.md +10 -4
  220. package/dist/agent-src/skills/monorepo-workspace/SKILL.md +1 -1
  221. package/dist/agent-src/skills/po-discovery/SKILL.md +1 -1
  222. package/dist/agent-src/skills/quality-tools/SKILL.md +11 -1
  223. package/dist/agent-src/skills/quality-tools/references/go-tools.md +76 -0
  224. package/dist/agent-src/skills/quality-tools/references/python-tools.md +104 -0
  225. package/dist/agent-src/skills/refine-ticket/SKILL.md +4 -4
  226. package/dist/agent-src/skills/review-routing/SKILL.md +2 -2
  227. package/dist/agent-src/skills/roadmap-writing/SKILL.md +2 -2
  228. package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +5 -3
  229. package/dist/agent-src/skills/source-discovery/SKILL.md +1 -1
  230. package/dist/agent-src/skills/storybook-workshop/SKILL.md +3 -3
  231. package/dist/agent-src/skills/tailwind-engineer/SKILL.md +4 -2
  232. package/dist/agent-src/skills/test-case-discovery/SKILL.md +7 -0
  233. package/dist/agent-src/skills/test-driven-development/SKILL.md +17 -0
  234. package/dist/agent-src/skills/test-performance/SKILL.md +19 -1
  235. package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
  236. package/dist/agent-src/skills/ui-component-architect/SKILL.md +2 -2
  237. package/dist/agent-src/skills/using-git-worktrees/SKILL.md +1 -1
  238. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +2 -2
  239. package/dist/agent-src/templates/AGENTS.md +1 -1
  240. package/dist/agent-src/templates/agent-settings.md +46 -129
  241. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +3 -3
  242. package/dist/agent-src/templates/command.md +2 -2
  243. package/dist/agent-src/templates/roadmaps.md +6 -1
  244. package/dist/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +0 -6
  245. package/dist/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +11 -7
  246. package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +48 -6
  247. package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/decision_trace.ts +3 -2
  248. package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.ts +2 -1
  249. package/dist/agent-src/templates/scripts/work_engine/hooks/settings.ts +0 -6
  250. package/dist/agent-src/templates/scripts/work_engine/scoring/decision_engine.ts +9 -12
  251. package/dist/agent-src/templates/scripts/work_engine/scoring/memory_visibility.ts +2 -1
  252. package/dist/agent-src/templates/scripts/work_engine/stack/runner.ts +774 -109
  253. package/dist/agent-src/templates/skill.md +1 -1
  254. package/dist/cli/registry.js +2 -1
  255. package/dist/cli-delegate/archive_completed_roadmaps.js +92 -12
  256. package/dist/cli-delegate/check_update_banner.js +207 -120
  257. package/dist/cli-delegate/chunk-523HCFYO.js +90 -0
  258. package/dist/cli-delegate/{chunk-FP36SWJD.js → chunk-5GPULQBE.js} +2797 -338
  259. package/dist/cli-delegate/{chunk-IGD6ERX6.js → chunk-6SRJTYJS.js} +42 -176
  260. package/dist/cli-delegate/chunk-6V5FMA3P.js +186 -0
  261. package/dist/cli-delegate/{chunk-M2DPGFZ4.js → chunk-6V6TA25H.js} +22 -152
  262. package/dist/cli-delegate/chunk-6YQC2HLF.js +415 -0
  263. package/dist/cli-delegate/{chunk-E4XIZDIB.js → chunk-7HKRE54K.js} +1 -64
  264. package/dist/cli-delegate/chunk-7IQE3D5S.js +191 -0
  265. package/dist/cli-delegate/{chunk-YJ72UIAK.js → chunk-AED2VQGM.js} +1245 -249
  266. package/dist/cli-delegate/{chunk-7HQ52DHU.js → chunk-AL3RZ22D.js} +1 -1
  267. package/dist/cli-delegate/chunk-DEIV7XP7.js +108 -0
  268. package/dist/cli-delegate/{chunk-DBH4AHDK.js → chunk-ED7KCMLB.js} +9 -11
  269. package/dist/cli-delegate/chunk-F3QDG2GT.js +2569 -0
  270. package/dist/cli-delegate/{chunk-6KFEC3G7.js → chunk-G5VVIZRC.js} +3 -3
  271. package/dist/cli-delegate/{chunk-FC75PGJE.js → chunk-H76PHZBI.js} +149 -61
  272. package/dist/cli-delegate/chunk-IAYTIIQW.js +67 -0
  273. package/dist/cli-delegate/chunk-JQOM7TTM.js +1201 -0
  274. package/dist/cli-delegate/chunk-KB5FZ655.js +208 -0
  275. package/dist/cli-delegate/{chunk-7RQP4UDH.js → chunk-KR6EM23A.js} +235 -1455
  276. package/dist/cli-delegate/{chunk-LTYVIY76.js → chunk-KXXWJTDO.js} +6 -11
  277. package/dist/cli-delegate/{chunk-T7L2QK3K.js → chunk-LQOCRFWT.js} +1 -1
  278. package/dist/cli-delegate/{chunk-6KM6ORRY.js → chunk-MDPPKQCQ.js} +58 -9
  279. package/dist/cli-delegate/{chunk-4XFP2Y3E.js → chunk-MSUL5NYP.js} +5 -5
  280. package/dist/cli-delegate/chunk-OAFSJBHH.js +272 -0
  281. package/dist/cli-delegate/{chunk-4E2W63DA.js → chunk-OKJUIAPS.js} +62 -1
  282. package/dist/cli-delegate/{chunk-QAJS5YWY.js → chunk-PHD7OOLE.js} +2 -1
  283. package/dist/cli-delegate/{chunk-P6ZHP5W2.js → chunk-PWX7CKMD.js} +4 -4
  284. package/dist/cli-delegate/{chunk-NDJLNC6Q.js → chunk-T6BP34WI.js} +1 -0
  285. package/dist/cli-delegate/{chunk-7XGBX6ZH.js → chunk-T7XSJSUQ.js} +1144 -589
  286. package/dist/cli-delegate/chunk-ULQRUR23.js +208 -0
  287. package/dist/cli-delegate/chunk-WQWXGIWB.js +1779 -0
  288. package/dist/cli-delegate/{chunk-RGNIWTEA.js → chunk-XQTPXKFA.js} +1 -1
  289. package/dist/cli-delegate/{chunk-NUHLI2RX.js → chunk-YCU3TIXH.js} +2 -0
  290. package/dist/cli-delegate/chunk-ZBZV2G5R.js +210 -0
  291. package/dist/cli-delegate/{chunk-WGXTVKCQ.js → chunk-ZUZKZYCN.js} +5 -3
  292. package/dist/cli-delegate/cmd_analyze_session.js +223 -43
  293. package/dist/cli-delegate/cmd_brand_status.js +3 -2
  294. package/dist/cli-delegate/cmd_conformance.js +1252 -249
  295. package/dist/cli-delegate/cmd_converge.js +3 -3
  296. package/dist/cli-delegate/cmd_doctor.js +19 -9
  297. package/dist/cli-delegate/cmd_doctor_neighbours.js +30 -0
  298. package/dist/cli-delegate/cmd_explain.js +45 -21
  299. package/dist/cli-delegate/cmd_export.js +13 -10
  300. package/dist/cli-delegate/cmd_fleet.js +3 -3
  301. package/dist/cli-delegate/cmd_git_convention.js +1851 -0
  302. package/dist/cli-delegate/cmd_handoff.js +44 -22
  303. package/dist/cli-delegate/cmd_mcp_available.js +3 -2
  304. package/dist/cli-delegate/cmd_memory_get.js +3 -1
  305. package/dist/cli-delegate/cmd_migrate.js +3 -3
  306. package/dist/cli-delegate/cmd_packs_active.js +5 -4
  307. package/dist/cli-delegate/cmd_preflight.js +6 -6
  308. package/dist/cli-delegate/cmd_prune.js +14 -11
  309. package/dist/cli-delegate/cmd_refresh.js +2 -1
  310. package/dist/cli-delegate/cmd_route_audit.js +10 -8
  311. package/dist/cli-delegate/cmd_route_explain.js +4 -4
  312. package/dist/cli-delegate/cmd_session_recycle.js +10 -7
  313. package/dist/cli-delegate/cmd_settings_check.js +54 -7
  314. package/dist/cli-delegate/cmd_settings_get.js +18 -8
  315. package/dist/cli-delegate/cmd_settings_migrate.js +13 -10
  316. package/dist/cli-delegate/cmd_settings_set.js +4 -4
  317. package/dist/cli-delegate/cmd_sync.js +14 -11
  318. package/dist/cli-delegate/cmd_uninstall.js +15 -12
  319. package/dist/cli-delegate/cmd_update.js +7 -7
  320. package/dist/cli-delegate/cmd_upgrade.js +9 -8
  321. package/dist/cli-delegate/cmd_validate.js +15 -12
  322. package/dist/cli-delegate/cmd_versions.js +5 -5
  323. package/dist/cli-delegate/deferral_carry.js +16 -0
  324. package/dist/cli-delegate/gate_budget.js +1 -1
  325. package/dist/cli-delegate/gate_execute.js +3 -3
  326. package/dist/cli-delegate/roadmap_gates.js +6 -6
  327. package/dist/cli-delegate/update_roadmap_progress.js +1 -1
  328. package/dist/discovery/deprecation-report.md +1 -1
  329. package/dist/discovery/discovery-manifest.json +232 -141
  330. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  331. package/dist/discovery/discovery-manifest.summary.md +3 -3
  332. package/dist/discovery/dormancy-report.md +1 -1
  333. package/dist/discovery/orphan-report.md +1 -1
  334. package/dist/discovery/packs.json +26 -9
  335. package/dist/discovery/trust-report.md +3 -3
  336. package/dist/discovery/workspaces.json +7 -4
  337. package/dist/hooks/dispatch.js +5655 -6623
  338. package/dist/hooks/dispatch.sha256 +1 -1
  339. package/dist/install/claudePathsPlan.js +47 -6
  340. package/dist/install/claudeRuleRewrite.js +7 -0
  341. package/dist/install/emit_host_rules_cli.js +39 -36
  342. package/dist/install/globalRuleScope.js +87 -0
  343. package/dist/install/host_rule_ownership.js +160 -0
  344. package/dist/install/install.mjs +2336 -1249
  345. package/dist/install/installThinLayer.js +289 -0
  346. package/dist/install/installedRuleLinks.js +262 -0
  347. package/dist/install/wizard-plan.js +24 -0
  348. package/dist/mcp/awesome-mcp-servers.row.md +1 -1
  349. package/dist/mcp/mcp-cloudflare-catalogue.json +2 -2
  350. package/dist/mcp/registry-manifest.json +5 -5
  351. package/dist/mcp/server.json +2 -2
  352. package/dist/mcp/server.mjs +36504 -30986
  353. package/dist/router.json +1 -1
  354. package/dist/scripts/_lib/agent_settings.js +26 -120
  355. package/dist/scripts/_lib/claude_settings_hooks.js +10 -8
  356. package/dist/scripts/_lib/compile_time_toggles.js +12 -21
  357. package/dist/scripts/_lib/git_convention.js +232 -0
  358. package/dist/scripts/_lib/global_deploy_inventory.js +730 -0
  359. package/dist/scripts/_lib/installed_layer.js +704 -0
  360. package/dist/scripts/_lib/lean_projection_mode.js +218 -15
  361. package/dist/scripts/_lib/package_root.js +68 -0
  362. package/dist/scripts/_lib/rule_consequence_class.js +45 -0
  363. package/dist/scripts/_lib/rule_injection.js +67 -10
  364. package/dist/scripts/_lib/rule_law_section.js +122 -0
  365. package/dist/scripts/_lib/settings_removed_keys.js +168 -0
  366. package/dist/scripts/_lib/thin_rules.js +535 -0
  367. package/dist/scripts/_lib/windsurf_render.js +60 -0
  368. package/dist/scripts/condense.js +14 -26
  369. package/dist/scripts/project_thin_rules.js +14 -294
  370. package/dist/server/app.js +2 -1
  371. package/dist/server/gitKeysGate.js +105 -0
  372. package/dist/server/routes/settings.js +67 -8
  373. package/dist/server/routes/wizard.js +4 -0
  374. package/dist/server/schemas/settings.js +29 -81
  375. package/dist/shared/skillRanking.js +103 -16
  376. package/dist/ui/assets/{index-Cwq4d0hX.js → index-C3djEJah.js} +2 -2
  377. package/dist/ui/index.html +1 -1
  378. package/docs/MIGRATION.md +72 -1
  379. package/docs/contracts/settings-classes.md +39 -67
  380. package/docs/guidelines/agent-infra/active-remediation-mechanics.md +39 -0
  381. package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +1 -1
  382. package/docs/guidelines/agent-infra/cross-source-consistency-mechanics.md +8 -10
  383. package/docs/guidelines/agent-infra/frontier-reasoning-operating-profile.md +3 -2
  384. package/docs/guidelines/agent-infra/layered-settings.md +13 -1
  385. package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
  386. package/docs/guidelines/agent-infra/self-improvement-pipeline.md +10 -3
  387. package/docs/guidelines/agent-infra/size-and-scope.md +36 -0
  388. package/docs/guidelines/php/git.md +15 -2
  389. package/package.json +1 -1
  390. package/src/agent-src/scripts/archive_completed_roadmaps.ts +115 -20
  391. package/src/agent-src/scripts/deferral_carry.ts +339 -0
  392. package/src/agent-src/scripts/gate_budget.ts +47 -23
  393. package/src/agent-src/scripts/gate_execute.ts +12 -4
  394. package/src/agent-src/scripts/update_roadmap_progress.ts +4 -1
  395. package/src/agent-src/templates/AGENTS.md +1 -1
  396. package/src/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +0 -6
  397. package/src/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +11 -7
  398. package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +48 -6
  399. package/src/agent-src/templates/scripts/work_engine/hooks/builtin/decision_trace.ts +3 -2
  400. package/src/agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.ts +2 -1
  401. package/src/agent-src/templates/scripts/work_engine/hooks/settings.ts +0 -6
  402. package/src/agent-src/templates/scripts/work_engine/scoring/decision_engine.ts +9 -12
  403. package/src/agent-src/templates/scripts/work_engine/scoring/memory_visibility.ts +2 -1
  404. package/src/agent-src/templates/scripts/work_engine/stack/runner.ts +774 -109
  405. package/src/config/agent-settings.template.yml +141 -334
  406. package/src/config/agents-paths.yml +16 -0
  407. package/src/config/assurance-capability-registry.json +7 -3
  408. package/src/config/ci-local-parity.yml +3 -0
  409. package/src/config/continuity-surface.json +10 -3
  410. package/src/config/discovery/packs.yml +17 -1
  411. package/src/config/evaluator-budgets.json +23 -10
  412. package/src/config/gate-coverage.yml +138 -3
  413. package/src/config/gate-violation-baselines.json +64 -16
  414. package/src/config/gitignore-block.txt +19 -0
  415. package/src/config/hook-bundle-budget.json +25 -0
  416. package/src/config/hook-token-budget.json +6 -1
  417. package/src/config/host-instruction-limits.json +33 -0
  418. package/src/config/release-gate-locality.yml +2 -1
  419. package/src/config/routing-coverage-seed.json +67 -4
  420. package/src/config/rule-activation-census.json +7 -3
  421. package/src/config/rule-consequence-class.json +161 -0
  422. package/src/config/rule-law-ceilings.json +105 -0
  423. package/src/config/rule-obligations.json +833 -0
  424. package/src/install/claudePathsPlan.ts +46 -4
  425. package/src/install/claudeRuleRewrite.ts +10 -1
  426. package/src/install/emit_host_rules_cli.ts +43 -34
  427. package/src/install/globalRuleScope.ts +109 -0
  428. package/src/install/host_rule_ownership.ts +170 -0
  429. package/src/install/installThinLayer.ts +378 -0
  430. package/src/install/installedRuleLinks.ts +308 -0
  431. package/src/install/wizard-plan.ts +24 -0
  432. package/src/scripts/_cli/cmd_analyze_session.ts +9 -15
  433. package/src/scripts/_cli/cmd_conformance.ts +13 -2
  434. package/src/scripts/_cli/cmd_doctor.ts +33 -81
  435. package/src/scripts/_cli/cmd_doctor_neighbours.ts +426 -0
  436. package/src/scripts/_cli/cmd_explain.ts +72 -14
  437. package/src/scripts/_cli/cmd_git_convention.ts +637 -0
  438. package/src/scripts/_cli/cmd_settings_check.ts +66 -8
  439. package/src/scripts/_cli/cmd_settings_get.ts +18 -3
  440. package/src/scripts/_cli/doctor_execution.ts +72 -1
  441. package/src/scripts/_dispatch.bash +53 -4
  442. package/src/scripts/_lib/agent_settings.ts +26 -124
  443. package/src/scripts/_lib/blocked_by_marker.ts +1 -1
  444. package/src/scripts/_lib/claude_settings_hooks.ts +10 -8
  445. package/src/scripts/_lib/compile_time_toggles.ts +12 -21
  446. package/src/scripts/_lib/dispatch_import_closure.ts +163 -0
  447. package/src/scripts/_lib/estate_offsets.ts +241 -0
  448. package/src/scripts/_lib/exemption_shape.ts +143 -0
  449. package/src/scripts/_lib/fnv.ts +23 -0
  450. package/src/scripts/_lib/foreign_scan.ts +106 -0
  451. package/src/scripts/_lib/git_base_ref.ts +92 -0
  452. package/src/scripts/_lib/git_convention.ts +291 -0
  453. package/src/scripts/_lib/git_convention_carrier.ts +389 -0
  454. package/src/scripts/_lib/git_convention_grammar.ts +246 -0
  455. package/src/scripts/_lib/git_convention_measure.ts +344 -0
  456. package/src/scripts/_lib/gitignore_block.ts +314 -0
  457. package/src/scripts/_lib/global_deploy_inventory.ts +106 -0
  458. package/src/scripts/_lib/graph_feeder_record.ts +437 -0
  459. package/src/scripts/_lib/hook_settings.ts +73 -0
  460. package/src/scripts/_lib/host_capability.ts +40 -19
  461. package/src/scripts/_lib/host_hook_merge.ts +165 -0
  462. package/src/scripts/_lib/installed_layer.ts +963 -0
  463. package/src/scripts/_lib/json_merge.ts +82 -0
  464. package/src/scripts/_lib/json_pointers.ts +93 -11
  465. package/src/scripts/_lib/knowledge_global.ts +14 -1
  466. package/src/scripts/_lib/lean_projection_mode.ts +275 -15
  467. package/src/scripts/_lib/machine_wake.ts +16 -3
  468. package/src/scripts/_lib/module_reach.ts +456 -0
  469. package/src/scripts/_lib/neighbour_census.ts +760 -0
  470. package/src/scripts/_lib/neighbour_contradictions.ts +236 -0
  471. package/src/scripts/_lib/neighbour_scan.ts +122 -0
  472. package/src/scripts/_lib/neighbour_tool_use.ts +187 -0
  473. package/src/scripts/_lib/prompt_shape.ts +46 -0
  474. package/src/scripts/_lib/ratification_artifact.ts +220 -1
  475. package/src/scripts/_lib/ratification_subject.ts +92 -0
  476. package/src/scripts/_lib/release_findings_ingest.ts +15 -7
  477. package/src/scripts/_lib/release_highlights.ts +5 -0
  478. package/src/scripts/_lib/release_migration_gate.ts +19 -3
  479. package/src/scripts/_lib/reserved_name_sweep.ts +73 -0
  480. package/src/scripts/_lib/review_coverage.ts +134 -0
  481. package/src/scripts/_lib/rule_consequence_class.ts +71 -0
  482. package/src/scripts/_lib/rule_injection.ts +130 -10
  483. package/src/scripts/_lib/rule_law_section.ts +147 -0
  484. package/src/scripts/_lib/rule_layer_overlap.ts +58 -0
  485. package/src/scripts/_lib/rule_obligations.ts +205 -0
  486. package/src/scripts/_lib/self_repair.ts +1 -1
  487. package/src/scripts/_lib/settings_removed_keys.ts +173 -0
  488. package/src/scripts/_lib/skill_origin.ts +254 -0
  489. package/src/scripts/_lib/structured_ask.ts +64 -21
  490. package/src/scripts/_lib/test_red_state.ts +5 -0
  491. package/src/scripts/_lib/thin_rules.ts +620 -0
  492. package/src/scripts/_lib/touched_file_quality.ts +570 -0
  493. package/src/scripts/_lib/turn_end_refusals.ts +77 -2
  494. package/src/scripts/_lib/windsurf_render.ts +63 -0
  495. package/src/scripts/_lib/worker_budget.ts +1 -1
  496. package/src/scripts/adr/regenerate_index.ts +16 -1
  497. package/src/scripts/ai_council/cli_call_budget.ts +13 -5
  498. package/src/scripts/ai_council/clients.ts +26 -57
  499. package/src/scripts/ai_council/config.ts +8 -8
  500. package/src/scripts/ai_council/modification_review.ts +100 -0
  501. package/src/scripts/ai_council/modification_review_questions.ts +90 -0
  502. package/src/scripts/ai_council/orchestrator.ts +5 -5
  503. package/src/scripts/ai_council/spend_gate.ts +18 -7
  504. package/src/scripts/ai_council/vendor_defaults.ts +45 -0
  505. package/src/scripts/ai_team/config.ts +11 -16
  506. package/src/scripts/audit_skill_overlap.ts +261 -0
  507. package/src/scripts/audit_user_type_axis.ts +20 -8
  508. package/src/scripts/before_complete_hook.ts +243 -12
  509. package/src/scripts/bench_ab_clone.ts +1 -2
  510. package/src/scripts/bench_concern_spawn_path.ts +129 -0
  511. package/src/scripts/bench_graph_feeder_latency.ts +584 -0
  512. package/src/scripts/bench_touched_file_quality.ts +238 -0
  513. package/src/scripts/check_agent_artifact_location.ts +36 -0
  514. package/src/scripts/check_branch_freshness.ts +147 -24
  515. package/src/scripts/check_enforcement_coverage.ts +130 -0
  516. package/src/scripts/check_enforcement_matrix.ts +377 -20
  517. package/src/scripts/check_estate_count.ts +130 -153
  518. package/src/scripts/check_evaluator_budgets.ts +4 -0
  519. package/src/scripts/check_finding_dispositions.ts +196 -21
  520. package/src/scripts/check_gate_coverage.ts +4 -3
  521. package/src/scripts/check_gate_reachability.ts +48 -1
  522. package/src/scripts/check_generator_sync.ts +48 -0
  523. package/src/scripts/check_hook_bundle_composition.ts +477 -0
  524. package/src/scripts/check_kernel_edit_ratified.ts +132 -14
  525. package/src/scripts/check_memory.ts +7 -1
  526. package/src/scripts/check_pack_size.ts +1 -1
  527. package/src/scripts/check_release_highlights.ts +10 -0
  528. package/src/scripts/check_release_manifest_content.ts +189 -0
  529. package/src/scripts/check_release_pr_shape.ts +38 -15
  530. package/src/scripts/check_standing_rule_delivery.ts +129 -13
  531. package/src/scripts/check_suppression_hygiene.ts +2 -5
  532. package/src/scripts/check_verify_expectation_delta.ts +521 -0
  533. package/src/scripts/ci_settle.ts +42 -5
  534. package/src/scripts/classify_merge_risk.ts +320 -0
  535. package/src/scripts/closure_scan.ts +91 -1
  536. package/src/scripts/code_graph/detect.ts +127 -7
  537. package/src/scripts/code_graph/foreign.ts +194 -0
  538. package/src/scripts/code_graph/query.ts +217 -4
  539. package/src/scripts/code_graph/types.ts +26 -2
  540. package/src/scripts/code_graph/validate.ts +3 -1
  541. package/src/scripts/code_graph/verbs.ts +103 -0
  542. package/src/scripts/command_suggester/settings.ts +8 -108
  543. package/src/scripts/command_suggester/types.ts +4 -5
  544. package/src/scripts/compile_hook_manifest.ts +33 -1
  545. package/src/scripts/condense.ts +14 -27
  546. package/src/scripts/consumer_matrix.ts +102 -0
  547. package/src/scripts/context_hygiene_hook.ts +13 -23
  548. package/src/scripts/cost/preflight.mjs +12 -1
  549. package/src/scripts/council_cli.ts +7 -7
  550. package/src/scripts/dispatch_r2_reviewer.ts +24 -11
  551. package/src/scripts/estate_exemption_shape.ts +202 -0
  552. package/src/scripts/explain_run.ts +8 -13
  553. package/src/scripts/generate_git_convention_grammar.ts +127 -0
  554. package/src/scripts/generate_host_cost_table.ts +21 -4
  555. package/src/scripts/handoff_context_hook.ts +86 -37
  556. package/src/scripts/hook_manifest.json +1 -1
  557. package/src/scripts/hook_manifest.yaml +175 -15
  558. package/src/scripts/hooks/block_config_weakening.ts +115 -7
  559. package/src/scripts/hooks/block_plumbing_writes.ts +37 -5
  560. package/src/scripts/hooks/code_graph_context_hook.ts +252 -23
  561. package/src/scripts/hooks/concern_failure_policy.ts +280 -0
  562. package/src/scripts/hooks/concern_registry.ts +2 -0
  563. package/src/scripts/hooks/delegation_nudge_hook.ts +2 -3
  564. package/src/scripts/hooks/dispatch_hook.ts +52 -52
  565. package/src/scripts/hooks/evidence_independence.ts +12 -4
  566. package/src/scripts/hooks/exit_codes.ts +2 -1
  567. package/src/scripts/hooks/host_lowering.json +1 -1
  568. package/src/scripts/hooks/host_lowering.ts +19 -1
  569. package/src/scripts/hooks/mcp_usage_observation_hook.ts +121 -0
  570. package/src/scripts/hooks/one_question_per_ask_hook.ts +41 -25
  571. package/src/scripts/hooks/payload_stub.ts +10 -1
  572. package/src/scripts/hooks/push_settle_hook.ts +4 -3
  573. package/src/scripts/hooks/rule_inject_hook.ts +795 -60
  574. package/src/scripts/hooks/state_io.ts +8 -4
  575. package/src/scripts/hooks/table_fingerprint.ts +21 -0
  576. package/src/scripts/hooks/telemetry_usage_hook.ts +24 -7
  577. package/src/scripts/hooks/turn_end_gate_hook.ts +85 -0
  578. package/src/scripts/hooks_status.ts +112 -0
  579. package/src/scripts/injection_scan_hook.ts +7 -0
  580. package/src/scripts/install-hooks.sh +42 -14
  581. package/src/scripts/install.ts +78 -215
  582. package/src/scripts/installed_layer_report.ts +103 -0
  583. package/src/scripts/language_mirror_hook.ts +15 -6
  584. package/src/scripts/learning_sidecar.ts +119 -8
  585. package/src/scripts/lint_blocker_citations.ts +198 -0
  586. package/src/scripts/lint_evidence_artifacts.ts +9 -0
  587. package/src/scripts/lint_hook_concern_budget.ts +10 -21
  588. package/src/scripts/lint_hook_manifest.ts +53 -0
  589. package/src/scripts/lint_major_migration_sections.ts +156 -26
  590. package/src/scripts/lint_pack_boundaries.ts +465 -29
  591. package/src/scripts/lint_roadmap_blockers.ts +282 -29
  592. package/src/scripts/lint_roadmap_complexity.ts +4 -2
  593. package/src/scripts/lint_rule_law_section.ts +647 -0
  594. package/src/scripts/lint_rule_skill_pack_reach.ts +17 -0
  595. package/src/scripts/lint_settings_classes.ts +1 -1
  596. package/src/scripts/lint_ticked_unmet_criteria.ts +165 -0
  597. package/src/scripts/lint_workflow_security.ts +173 -6
  598. package/src/scripts/mcp_server/consumer_tool_catalog.json +53 -0
  599. package/src/scripts/mcp_server/graph_tools.ts +72 -3
  600. package/src/scripts/measure_routing_signal.ts +54 -16
  601. package/src/scripts/measure_skill_ranker_baseline.ts +221 -8
  602. package/src/scripts/memory_learn_hook.ts +91 -6
  603. package/src/scripts/model_rule_injection.ts +55 -8
  604. package/src/scripts/onboarding_gate_hook.ts +7 -6
  605. package/src/scripts/print_required_checks.ts +15 -3
  606. package/src/scripts/probe_host_compliance.ts +33 -5
  607. package/src/scripts/probe_turnaround.ts +183 -3
  608. package/src/scripts/project_thin_rules.ts +34 -327
  609. package/src/scripts/ratification_header.ts +77 -0
  610. package/src/scripts/refusal_envelope.ts +138 -0
  611. package/src/scripts/release_publication.ts +29 -3
  612. package/src/scripts/report_dispatch_import_closure.ts +76 -0
  613. package/src/scripts/report_evidence_temperature.ts +657 -0
  614. package/src/scripts/report_installed_rule_links.ts +274 -0
  615. package/src/scripts/report_label_agreement.ts +233 -0
  616. package/src/scripts/report_module_reach.ts +212 -0
  617. package/src/scripts/report_obligation_mechanism.ts +228 -0
  618. package/src/scripts/report_parked_blockers.ts +222 -0
  619. package/src/scripts/report_required_checks_drift.ts +196 -0
  620. package/src/scripts/report_single_token_triggers.ts +277 -0
  621. package/src/scripts/report_skill_ranker_confusion.ts +543 -0
  622. package/src/scripts/report_standing_payload_by_host.ts +188 -15
  623. package/src/scripts/report_verification_record_coverage.ts +306 -0
  624. package/src/scripts/routing_doctor.ts +2 -2
  625. package/src/scripts/rule_activation_census.ts +5 -2
  626. package/src/scripts/rule_trigger_eval.ts +9 -9
  627. package/src/scripts/schemas/agent-settings.schema.json +17 -31
  628. package/src/scripts/schemas/command.schema.json +1 -1
  629. package/src/scripts/schemas/review-findings.schema.json +3 -2
  630. package/src/scripts/schemas/rule.schema.json +5 -0
  631. package/src/scripts/schemas/skill.schema.json +1 -1
  632. package/src/scripts/self_review_gate.ts +101 -9
  633. package/src/scripts/skill_tools/score_skill_relevance.ts +314 -40
  634. package/src/scripts/sweep_skill_ranker_signals.ts +129 -0
  635. package/src/scripts/sync_gitignore.ts +29 -235
  636. package/src/scripts/sync_pr_branch.ts +403 -132
  637. package/src/scripts/trigger_eval_grandfather.json +0 -21
  638. package/src/server/schemas/settings.ts +42 -176
  639. package/src/shared/skillRanking.ts +169 -14
  640. package/dist/cli-delegate/chunk-5R7HOLAF.js +0 -99
  641. package/dist/cli-delegate/chunk-JNMVLWLR.js +0 -4457
  642. package/dist/cli-delegate/chunk-YDPILCOL.js +0 -152
  643. package/src/scripts/_lib/config_chain.ts +0 -477
  644. package/src/scripts/_lib/conformance_report.ts +0 -403
  645. package/src/scripts/_lib/eval_discrimination.ts +0 -95
  646. package/src/scripts/_lib/evaluator_promotion.ts +0 -225
  647. package/src/scripts/_lib/file_slicer.ts +0 -117
  648. package/src/scripts/_lib/legacy_boundary_map.ts +0 -228
  649. package/src/scripts/_lib/minimality_tiebreak.ts +0 -168
  650. package/src/scripts/_lib/overbuild_lens_contract.ts +0 -196
  651. package/src/scripts/_lib/role_split.ts +0 -338
@@ -18,11 +18,10 @@
18
18
  * target dir of your choosing — it never overwrites the live `.claude/` /
19
19
  * `.augment/` projections.
20
20
  *
21
- * NOTE (faithful literal): the thin-entry pointer keeps the verbatim
22
- * `Body: [`{rule_id}`](../../dist/agent-src/rules/{rule_id}.md)`
23
- * Markdown link from the retired Python implementation. The same-basename `.py` twin
24
- * carries that literal, so the ADR-051 legacy-path guard exempts this `.ts`
25
- * file by twin-parity.
21
+ * NOTE: the thin-entry pointer literal moved with the mechanism — it is
22
+ * `BODY_LINK_PREFIX` in `_lib/thin_rules.ts` now, so the twin-parity argument
23
+ * that exempted it from the ADR-051 legacy-path guard belongs to THAT file and
24
+ * no longer describes this one, which holds the string nowhere.
26
25
  *
27
26
  * Historical quirks are preserved deliberately — tests and downstream consumers pin the exact behaviour.
28
27
  *
@@ -34,299 +33,20 @@ import * as fs from 'node:fs';
34
33
  import * as path from 'node:path';
35
34
  import process from 'node:process';
36
35
  import { fileURLToPath, pathToFileURL } from 'node:url';
37
- import { pathOnlyRuleIds, triggerlessRuleIds, } from './_lib/rule_injection.js';
38
36
  import * as token_count from './_lib/token_count.js';
39
- const _HERE = fileURLToPath(import.meta.url);
40
- // REPO_ROOT = Path(__file__).resolve().parent.parent.parent — three dirs up
41
- // from src/scripts/<file>.
42
- export const REPO_ROOT = path.resolve(path.dirname(_HERE), '..', '..');
43
- export const RULES_SOURCE = path.join(REPO_ROOT, 'dist/agent-src', 'rules');
44
- export const ROUTER = path.join(REPO_ROOT, 'dist', 'router.json');
45
- /** `sorted(dir.glob("*.md"))` — non-recursive, lexically sorted abs paths. */
46
- function _globSortedMd(dir) {
47
- let names;
48
- try {
49
- names = fs.readdirSync(dir);
50
- }
51
- catch {
52
- return [];
53
- }
54
- const out = names.filter((n) => n.endsWith('.md')).map((n) => path.join(dir, n));
55
- out.sort();
56
- return out;
57
- }
58
- /** The always-full-bodied set — authoritative kernel list from the router. */
59
- export function kernel_ids() {
60
- const data = JSON.parse(fs.readFileSync(ROUTER, 'utf-8'));
61
- const kernel = data.kernel;
62
- if (Array.isArray(kernel)) {
63
- return new Set(kernel.map((x) => String(x)));
64
- }
65
- return new Set();
66
- }
67
- /**
68
- * Tier rules the router gives NO trigger at all.
69
- *
70
- * These cannot be delivered on a match, so thinning them would remove a body
71
- * that nothing can ever put back — a silent hole rather than a saving. They
72
- * project full-bodied, and `measure` reports them by name so the residue is
73
- * visible instead of being absorbed into the pointer count
74
- * (road-to-trigger-delivered-rule-bodies 1.3).
75
- */
76
- /**
77
- * Rules whose ONLY triggers are path-shaped — reachable from `pre_tool_use`
78
- * and from no other slot (road-to-delivery-for-every-host 3.2).
79
- *
80
- * They must never be thinned while the delivery concern is NOT bound on
81
- * `pre_tool_use`, because a stub plus a slot nobody listens on is a rule that
82
- * reaches the model at no scope at all. This is the same failure the
83
- * `no_trigger_ids` exemption prevents, one step out: there the rule has nothing
84
- * to match on, here it has nothing to match ON.
85
- *
86
- * Stated as a PROPERTY rather than a list of ids. If the concern is ever bound
87
- * on `pre_tool_use` again, this exemption is what should be reconsidered — not
88
- * three names someone has to remember.
89
- *
90
- * WHAT THIS EXEMPTION DOES **NOT** COVER — recorded 2026-09-08, R2 finding 1,
91
- * because the silence read as coverage. The predicate is `every` trigger
92
- * path-shaped. A rule with BOTH path and non-path triggers is therefore THINNED,
93
- * and its path-shaped half then has no carrier at all: the stub carries no
94
- * frontmatter (`condense.ts` writes it with `_writeText`, bypassing
95
- * `_emit_claude_rule`'s host-native `paths:` key), `pre_tool_use` lost the
96
- * binding under owner ruling E2, and `user_prompt_submit` never populates
97
- * `openFiles`. Measured over the current `dist/router.json`: **18 such rules**,
98
- * all non-kernel and all thinned — augment-edit-discipline, design-fidelity,
99
- * doc-screenshot-hygiene, domain-adoption-policy,
100
- * framework-neutrality-in-generic-skills, image-likeness-and-rights,
101
- * laravel-translations, lethal-trifecta-guard, linked-projects-onboarding-gate,
102
- * low-impact-corpus-privacy-floor, markdown-safe-codeblocks, onboarding-gate,
103
- * persona-governance, php-coding, provider-lifecycle-discipline,
104
- * roadmap-ci-steps-policy, roadmap-progress-sync, settings-ask-protocol.
105
- *
106
- * They do NOT reach the model at no scope: every non-path route
107
- * (keyword / phrase / command) still delivers the body through the concern, and
108
- * on `claude-code` they never had a separate host-native path route to lose —
109
- * `_claude_paths_plan` emits no `paths:` for a mixed-trigger rule on purpose, so
110
- * under `eager-all` they loaded UNCONDITIONALLY. What is lost is the difference
111
- * between unconditional and prompt-triggered: a session that touches a matching
112
- * file and says nothing that matches gets nothing.
113
- *
114
- * The labelled corpus cannot see this and the endpoint says so rather than
115
- * implying otherwise — `model_rule_injection --endpoints` (b) now publishes the
116
- * shipped `user_prompt_submit` reach beside the pre-registered reading, and
117
- * every one of these 18 has at least one prompt-matching positive, so none
118
- * appears in its "reachable only via a path trigger" column.
119
- *
120
- * WHY THIS IS NOT WIDENED TO `some` HERE. Measured: exempting all 18 moves the
121
- * thin rule layer 23,592 -> 39,921 GPT tok (+16,329, +69 %), which is a budget
122
- * move of a magnitude no agent may take, and it would erase most of the saving
123
- * the flip is licensed on. Restoring a path route needs either that exemption
124
- * under a re-anchored baseline or a `pre_tool_use` binding under a raised slot
125
- * cap — both owner-reserved, so the closure is tracked rather than taken here.
126
- * ADR-267's Consequences section names the receiver.
127
- */
128
- /**
129
- * ONE spelling of the router-derived sets, shared with the injector (R2
130
- * finding 11).
131
- *
132
- * `path_only_ids` and `no_trigger_ids` were each a second, hand-rolled
133
- * implementation of `_lib/rule_injection.ts::pathOnlyRuleIds` /
134
- * `triggerlessRuleIds` — verified identical over the current router at the time
135
- * (symmetric difference empty), so drift risk rather than a live defect. It is
136
- * exactly the hazard `THIN_ENTRY_MARKER`'s own comment argues against one
137
- * screen below ("a gate that re-spelled this string would drift from the writer
138
- * silently"), and the two consumers here are the PROJECTOR's exemption set and
139
- * the INJECTOR's reachability set: they must not be able to disagree about which
140
- * rules the delivery path can reach.
141
- *
142
- * The finding named `path_only_ids`. The defect-pattern sweep found the SECOND
143
- * instance one function down — `no_trigger_ids` against `triggerlessRuleIds` —
144
- * and it is delegated in the same change. Count: 2 of 2 duplicated
145
- * router-derived sets in this file, 0 remaining.
146
- */
147
- function _router() {
148
- return JSON.parse(fs.readFileSync(ROUTER, 'utf-8'));
149
- }
150
- export function path_only_ids() {
151
- return pathOnlyRuleIds(_router());
152
- }
153
- export function no_trigger_ids() {
154
- return new Set(triggerlessRuleIds(_router()));
155
- }
156
- /**
157
- * id → workspaces for every non-kernel router entry (router.json schema v2,
158
- * road-to-request-scoped-rule-load Phase 1). Rules absent from the map (or
159
- * with an empty list) fail safe: they stay in scope.
160
- */
161
- export function rule_workspaces_map() {
162
- const data = JSON.parse(fs.readFileSync(ROUTER, 'utf-8'));
163
- const map = new Map();
164
- for (const tier of ['tier_1', 'tier_2']) {
165
- const entries = data[tier];
166
- if (!Array.isArray(entries))
167
- continue;
168
- for (const e of entries) {
169
- const obj = e;
170
- const ws = Array.isArray(obj.workspaces) ? obj.workspaces.map((w) => String(w)) : [];
171
- map.set(String(obj.id), ws);
172
- }
173
- }
174
- return map;
175
- }
176
- /**
177
- * Whether a rule id survives a workspace scope. Kernel always survives;
178
- * `scope === null` = legacy-all. An out-of-scope non-kernel rule is dropped
179
- * entirely — neither body nor pointer line (the pointer floor shrinks with
180
- * consumer scoping).
181
- */
182
- export function id_in_scope(rule_id, scope, kernel, wsMap, fallback_ws = []) {
183
- if (scope === null || kernel.has(rule_id)) {
184
- return true;
185
- }
186
- // Router map first (schema v2); `type: manual` rules are reference-only
187
- // and never emitted to the router — their frontmatter is the fallback.
188
- const ws = wsMap.get(rule_id) ?? fallback_ws;
189
- if (ws.length === 0) {
190
- return true; // untagged / unknown → fail safe
191
- }
192
- return ws.some((w) => scope.includes(w));
193
- }
194
- /** `workspaces:` list parsed straight from a rule file's frontmatter. */
195
- export function fm_workspaces(text) {
196
- const [fm] = split_frontmatter(text);
197
- // Flow style: `workspaces: [a, b, c]`
198
- const flow = /^workspaces:[ \t]*\[([^\]]*)\]/m.exec(fm);
199
- if (flow) {
200
- return flow[1]
201
- .split(',')
202
- .map((s) => s.trim().replace(/^["']|["']$/g, ''))
203
- .filter((s) => s.length > 0);
204
- }
205
- // Block style; tolerate the list being the LAST frontmatter key.
206
- const m = /^workspaces:[ \t]*\n((?:[ \t]+-[ \t]+.*(?:\n|$))+)/m.exec(fm);
207
- if (!m) {
208
- return [];
209
- }
210
- return [...m[1].matchAll(/-[ \t]+(\S+)/g)].map((x) => x[1]);
211
- }
212
- /** Return [frontmatter_including_fences, body]. Empty fm if none. */
213
- export function split_frontmatter(text) {
214
- if (text.startsWith('---\n')) {
215
- const end = text.indexOf('\n---\n', 4);
216
- if (end !== -1) {
217
- return [text.slice(0, end + 5), text.slice(end + 5)];
218
- }
219
- }
220
- return ['', text];
221
- }
222
- function _description(fm) {
223
- // re.search(r'^description:\s*"?(.+?)"?\s*$', fm, re.MULTILINE)
224
- const m = /^description:\s*"?(.+?)"?\s*$/m.exec(fm);
225
- return m ? m[1].trim() : '';
226
- }
227
- // How many trigger keywords/phrases to surface as the always-on match hint.
228
- const _TRIGGER_HINT_LIMIT = 6;
229
- /** A short, comma-joined sample of the rule's trigger keywords/phrases. */
230
- function _trigger_hint(fm) {
231
- const hits = [];
232
- // re.finditer(r'^\s*-\s*(?:keyword|phrase):\s*"?(.+?)"?\s*$', fm, re.MULTILINE)
233
- const re = /^\s*-\s*(?:keyword|phrase):\s*"?(.+?)"?\s*$/gm;
234
- let m;
235
- while ((m = re.exec(fm)) !== null) {
236
- hits.push(m[1].trim());
237
- if (hits.length >= _TRIGGER_HINT_LIMIT) {
238
- break;
239
- }
240
- }
241
- return hits.join(', ');
242
- }
243
- /** Python `str.title()` — uppercase first alpha of each run, rest lowercase. */
244
- function _title(s) {
245
- return s.replace(/[A-Za-z]+/g, (w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase());
246
- }
247
- /**
248
- * The marker that makes a projected entry recognisable as a stub.
249
- *
250
- * Exported so the WRITER and every DETECTOR share one definition. A gate that
251
- * re-spelled this string would drift from the writer silently, and the failure
252
- * would be invisible in exactly the direction that matters: a stub the gate
253
- * fails to recognise reads as a complete rule body.
254
- */
255
- export const THIN_ENTRY_MARKER = '> Routed rule — load the body on trigger-match.';
256
- /** Is this projected entry a pointer stub rather than a rule body? */
257
- export function is_thin_entry(text) {
258
- return text.includes(THIN_ENTRY_MARKER);
259
- }
260
37
  /**
261
- * Where a stub tells a reader the body actually is.
262
- *
263
- * FIXED 2026-09-07: this pointed into the uncondensed source tree ADR-051
264
- * retired — the literal path is deliberately NOT reproduced here, because
265
- * `check_no_uncondensed_refs` matches the string and cannot tell a repair
266
- * record from a live reference; `git log -S` on this file finds the old value.
267
- * It exists in no checkout, so EVERY stub's fallback pointer
268
- * resolved to nothing — invisible under `delivery`, where the hook loads the
269
- * body from `dist/agent-src/rules` and never follows this link, and total under
270
- * `thin`, where the pointer is the only path to the body there is.
38
+ * The mechanism lives in `_lib/thin_rules.ts`; this file is its CLI.
271
39
  *
272
- * KNOWN LIMIT, stated rather than discovered later: one relative prefix cannot
273
- * be right for every tree, because they sit at different depths — `.claude/rules`
274
- * and `.cursor/rules` are two levels below the repo root and `.clinerules` is
275
- * one. `../../` is correct for the first two, which are the only trees the
276
- * shipped `lean_projection.hosts` default can thin. A stub in `.clinerules`
277
- * needs an operator to have added `cline` to that list, and its pointer is off
278
- * by one level. That is strictly better than the previous state, where the
279
- * pointer was dead in all three, and it is recorded here so the remaining case
280
- * is a known limit rather than a surprise.
40
+ * Re-exported wholesale so every existing importer of
41
+ * `project_thin_rules.{build_thin,thin_entry,is_thin_entry,RULES_SOURCE,…}`
42
+ * keeps working unchanged. The split exists because `src/scripts/install.ts` is
43
+ * a bundle entry and `check_installer_import_purity` forbids it reaching a
44
+ * module-level `process.exit()` — which this file has, at its foot, by design.
281
45
  */
282
- const BODY_LINK_PREFIX = '../../dist/agent-src/rules/';
283
- /** Build the minimal progressive-disclosure pointer for a non-kernel rule. */
284
- export function thin_entry(rule_id, text) {
285
- const [fm] = split_frontmatter(text);
286
- const desc = _description(fm);
287
- const hint = _trigger_hint(fm);
288
- const title = _title(rule_id.replace(/-/g, ' '));
289
- const fires = hint ? ` Fires on: ${hint}.` : '';
290
- return (`## ${title}\n` +
291
- `${THIN_ENTRY_MARKER}${fires} ${desc} ` +
292
- `Body: [\`${rule_id}\`](${BODY_LINK_PREFIX}${rule_id}.md)\n`);
293
- }
294
- /** Map {filename: thin_or_full_text} for every rule. Kernel stays full. */
295
- export function build_thin(rules_dir = RULES_SOURCE, scope = null,
296
- /**
297
- * Optional sink for the D3 diagnostic
298
- * (road-to-delivery-for-every-host 2.2).
299
- *
300
- * An `auto` rule the router gives NO trigger is already kept full-bodied by
301
- * `noTrigger` below, which is the substantive protection and predates this
302
- * roadmap. What did not exist is any way to SEE it happen: the rule is
303
- * silently exempted, so an author who removes a rule's last trigger gets a
304
- * silently eager rule and no signal. The line makes the exemption audible.
305
- */
306
- announce = null) {
307
- const kernel = kernel_ids();
308
- const noTrigger = no_trigger_ids();
309
- const pathOnly = path_only_ids();
310
- const wsMap = scope !== null ? rule_workspaces_map() : new Map();
311
- const out = new Map();
312
- for (const p of _globSortedMd(rules_dir)) {
313
- const text = fs.readFileSync(p, 'utf-8');
314
- const stem = path.basename(p).replace(/\.md$/, '');
315
- if (!id_in_scope(stem, scope, kernel, wsMap, fm_workspaces(text))) {
316
- continue; // out of workspace scope — no body, no pointer line
317
- }
318
- const full = kernel.has(stem) || noTrigger.has(stem) || pathOnly.has(stem);
319
- if (announce !== null && noTrigger.has(stem) && !kernel.has(stem)) {
320
- announce(`D3: trigger-less auto rule ${path.basename(p)} — kept full-bodied, never thinned`);
321
- }
322
- if (announce !== null && pathOnly.has(stem) && !kernel.has(stem) && !noTrigger.has(stem)) {
323
- announce(`E2: path-only auto rule ${path.basename(p)} — kept full-bodied; its only triggers ` +
324
- `are path-shaped and the delivery concern is not bound on pre_tool_use`);
325
- }
326
- out.set(path.basename(p), full ? text : thin_entry(stem, text));
327
- }
328
- return out;
329
- }
46
+ export * from './_lib/thin_rules.js';
47
+ import { _globSortedMd, build_thin, fm_workspaces, id_in_scope, kernel_ids, no_trigger_ids, REPO_ROOT, RULES_SOURCE, rule_workspaces_map, } from './_lib/thin_rules.js';
48
+ void REPO_ROOT;
49
+ const _HERE = fileURLToPath(import.meta.url);
330
50
  /** Python `round(x, 1)` — round-half-to-even at one decimal. */
331
51
  function _python_round1(x) {
332
52
  const scaled = x * 10;
@@ -155,7 +155,7 @@ export async function createApp(opts) {
155
155
  await app.register(pingRoute({ writeRoot, projectScopeRoot, mode, dryRun, projectSurface: opts.projectSurface === true }));
156
156
  await app.register(discoveryRoute(opts.discoveryManifestPath ? { manifestPath: opts.discoveryManifestPath } : {}));
157
157
  await app.register(schemaRoute());
158
- await app.register(settingsRoute({ writeRoot, legacyReadRoot, packageRoot, dryRun, userGlobalReadRoot: userGlobalRead }));
158
+ await app.register(settingsRoute({ writeRoot, legacyReadRoot, packageRoot, dryRun, userGlobalReadRoot: userGlobalRead, userGlobalWrite: mode === 'global' }));
159
159
  await app.register(settingsChangesRoute({ writeRoot, userGlobalReadRoot: userGlobalRead, dryRun }));
160
160
  await app.register(userMdRoute({ writeRoot, legacyReadRoot, dryRun, userGlobalReadRoot: userGlobalRead }));
161
161
  await app.register(installRoute(opts.installRouteOptions ?? {}));
@@ -167,6 +167,7 @@ export async function createApp(opts) {
167
167
  dryRun,
168
168
  userGlobalReadRoot: userGlobalRead,
169
169
  extendedSteps: opts.extendedSteps === true,
170
+ userGlobalWrite: mode === 'global',
170
171
  ...(opts.initialStep !== undefined ? { initialStep: opts.initialStep } : {}),
171
172
  ...(opts.wizardMode !== undefined ? { wizardMode: opts.wizardMode } : {}),
172
173
  }));
@@ -0,0 +1,105 @@
1
+ /**
2
+ * The settings route's handling of the three `git.*` keys.
3
+ *
4
+ * In global mode the route writes the user-global file, and `load_agent_settings`
5
+ * discards `git.*` keys from that file, so a value saved there has no effect in
6
+ * any repository. The form is not offered those keys, and a non-default value is
7
+ * refused with the place a team declares them instead (ADR-283). A template
8
+ * default is accepted: the form round-trips it, and `upgrade` inserts it too.
9
+ *
10
+ * In every mode a value goes through the same check `git:convention show` and
11
+ * `settings:check` run, so a pattern that would reach a shell is refused here as
12
+ * well.
13
+ */
14
+ import { promises as fs } from 'node:fs';
15
+ import { join } from 'node:path';
16
+ import { parseYaml } from './io/yamlIO.js';
17
+ import { GIT_CONVENTION_KEYS, invalidReason } from '../scripts/_lib/git_convention.js';
18
+ export const WITHHELD_GIT_KEYS = GIT_CONVENTION_KEYS.map((k) => `git.${k}`);
19
+ export const WITHHELD_REASON = 'This form writes your user-global settings file, which does not carry git.* keys. ' +
20
+ 'A team declares them in .git-convention.yml at the repository root; one checkout can set them in its project settings file.';
21
+ function _gitSection(values) {
22
+ const git = values['git'];
23
+ return git !== null && typeof git === 'object' && !Array.isArray(git) ? git : null;
24
+ }
25
+ /** The values and the JSON schema with the `git` section removed. */
26
+ export function withholdGitKeys(values, schema) {
27
+ const { git: _git, ...rest } = values;
28
+ const properties = { ...(schema.properties ?? {}) };
29
+ delete properties['git'];
30
+ const next = { ...schema, properties };
31
+ if (Array.isArray(schema.required))
32
+ next.required = schema.required.filter((k) => k !== 'git');
33
+ return { values: rest, schema: next };
34
+ }
35
+ /**
36
+ * Field issues for the `git.*` values of a write. `defaults` is the template's
37
+ * `git` section; `userGlobal` is true when the write lands in the user-global file.
38
+ */
39
+ export function gitKeyWriteIssues(values, defaults, userGlobal) {
40
+ const git = _gitSection(values);
41
+ if (git === null)
42
+ return [];
43
+ const fallback = _gitSection(defaults) ?? {};
44
+ const issues = [];
45
+ for (const key of GIT_CONVENTION_KEYS) {
46
+ const value = git[key];
47
+ if (typeof value !== 'string')
48
+ continue;
49
+ const why = invalidReason(key, value);
50
+ if (why !== null) {
51
+ issues.push({ path: `git.${key}`, message: why });
52
+ continue;
53
+ }
54
+ const def = fallback[key];
55
+ if (userGlobal && !(typeof def === 'string' && def === value)) {
56
+ issues.push({ path: `git.${key}`, message: WITHHELD_REASON });
57
+ }
58
+ }
59
+ return issues;
60
+ }
61
+ /**
62
+ * The write candidate with the `git` section the file already holds. In global
63
+ * mode the form never showed that section, and the schema's `.default({})`
64
+ * fills template defaults into whatever arrives, so a value the user-global
65
+ * file carries would otherwise read as a change the user made: a guarded-key
66
+ * confirmation for a field they never saw, then a silent reset.
67
+ *
68
+ * `fileValues` is that file alone, never the merged view: the merge carries
69
+ * the template defaults and any project layer, and copying a project value
70
+ * here would write it into the user-global file without passing the gate.
71
+ */
72
+ export function keepWithheldGit(candidate, fileValues) {
73
+ const { git: _sent, ...rest } = candidate;
74
+ return 'git' in fileValues ? { ...rest, git: fileValues['git'] } : rest;
75
+ }
76
+ /**
77
+ * The before-side of a global-mode diff: the merged view with its `git` section
78
+ * swapped for the file's own, or dropped when the file has none. The candidate
79
+ * from `keepWithheldGit` carries exactly that section, so comparing it against
80
+ * the merged view would report template defaults and project values as edits
81
+ * to a section the form never showed.
82
+ */
83
+ export function gitDiffBase(merged, fileValues) {
84
+ return keepWithheldGit(merged, fileValues);
85
+ }
86
+ /**
87
+ * The wizard's finish write through the same gate: a 422 is sent and true
88
+ * returned when a `git.*` value is refused. The template's `git` section holds
89
+ * no install placeholder, so it is parsed without substitution.
90
+ */
91
+ export async function refuseGitKeys(reply, values, packageRoot, userGlobal) {
92
+ let defaults = {};
93
+ try {
94
+ defaults = parseYaml(await fs.readFile(join(packageRoot, 'src', 'config', 'agent-settings.template.yml'), 'utf8'));
95
+ }
96
+ catch {
97
+ defaults = {};
98
+ }
99
+ const issues = gitKeyWriteIssues(values, defaults, userGlobal);
100
+ if (issues.length === 0)
101
+ return false;
102
+ await reply.code(422).send({ error: { code: 'VALIDATION', message: 'invalid settings', fields: issues } });
103
+ return true;
104
+ }
105
+ //# sourceMappingURL=gitKeysGate.js.map
@@ -1,12 +1,36 @@
1
1
  import { promises as fs } from 'node:fs';
2
2
  import { dirname, join } from 'node:path';
3
+ import { isDeepStrictEqual } from 'node:util';
3
4
  import { zodToJsonSchema } from 'zod-to-json-schema';
4
5
  import { settingsSchema } from '../schemas/settings.js';
5
- import { parseYaml, mergeIntoTemplate, diffValues, deepMerge, TEMPLATE_PLACEHOLDER_DEFAULTS } from '../io/yamlIO.js';
6
+ import { parseYaml, mergeIntoTemplate, diffValues, deepMerge, renderSparseSettings, substituteTemplatePlaceholders, TEMPLATE_PLACEHOLDER_DEFAULTS } from '../io/yamlIO.js';
7
+ import { sparseSettingsValues } from './wizard.js';
6
8
  import { writeAtomic } from '../io/atomicWrite.js';
9
+ import { WITHHELD_GIT_KEYS, WITHHELD_REASON, gitDiffBase, gitKeyWriteIssues, keepWithheldGit, withholdGitKeys } from '../gitKeysGate.js';
7
10
  import { sharedWriteTarget, resolveThroughSymlinks } from '../io/sharedWriteCheck.js';
8
11
  import { PACKAGE_ROOT } from '../../cli/paths.js';
9
12
  import { buildSettingsClassIndex, guardedChangedKeys, parseSettingsClassRows } from '../../shared/settingsClasses.js';
13
+ /**
14
+ * A fresh user-global file records decisions, not the defaults: the form posts
15
+ * every value, and a copy of the template's would freeze each default at today's
16
+ * value. Only leaves that differ from the template are kept, over the carve-outs.
17
+ */
18
+ async function freshUserGlobalValues(packageRoot, candidate) {
19
+ const templateBody = await fs.readFile(join(packageRoot, 'src', 'config', 'agent-settings.template.yml'), 'utf8');
20
+ const template = parseYaml(substituteTemplatePlaceholders(templateBody));
21
+ const decided = (value, dflt) => {
22
+ if (value !== null && typeof value === 'object' && !Array.isArray(value)) {
23
+ const base = dflt !== null && typeof dflt === 'object' && !Array.isArray(dflt) ? dflt : {};
24
+ const kept = Object.entries(value)
25
+ .map(([k, v]) => [k, decided(v, base[k])])
26
+ .filter(([, v]) => v !== undefined);
27
+ return kept.length === 0 ? undefined : Object.fromEntries(kept);
28
+ }
29
+ return isDeepStrictEqual(value, dflt) ? undefined : value;
30
+ };
31
+ const own = (decided(candidate, template) ?? {});
32
+ return deepMerge(sparseSettingsValues(templateBody, {}), own);
33
+ }
10
34
  /** Sidecar written by `settings:set`, keyed by dotted path. */
11
35
  const PROVENANCE_RELATIVE = join('settings', '.agent-settings.provenance.json');
12
36
  /**
@@ -217,6 +241,8 @@ async function readLayeredSettings(packageRoot, writeRoot, legacyReadRoot, userG
217
241
  ])],
218
242
  project: projectLayer !== null ? dottedLeafPaths(projectLayer.values) : [],
219
243
  },
244
+ writeLayer: globalLayer?.values ?? null,
245
+ writeLayerRaw: globalLayer?.raw ?? null,
220
246
  };
221
247
  }
222
248
  function zodIssuesToFields(issues) {
@@ -234,6 +260,10 @@ export function settingsRoute(opts) {
234
260
  app.get('/api/v1/settings', async (_request, reply) => {
235
261
  try {
236
262
  const state = await readLayeredSettings(packageRoot, opts.writeRoot, opts.legacyReadRoot, opts.userGlobalReadRoot);
263
+ const offered = opts.userGlobalWrite === true
264
+ ? withholdGitKeys(state.values, SETTINGS_JSON_SCHEMA)
265
+ : { values: state.values, schema: SETTINGS_JSON_SCHEMA };
266
+ const withheld = opts.userGlobalWrite === true ? { withheld: { keys: WITHHELD_GIT_KEYS, reason: WITHHELD_REASON } } : {};
237
267
  if (!state.hasRealFile) {
238
268
  // No on-disk file yet — the wizard creates it. Surface the
239
269
  // template-defaults values + schema + path in the body so
@@ -242,19 +272,21 @@ export function settingsRoute(opts) {
242
272
  // `{}` and the user's first save fails schema validation).
243
273
  await reply.code(404).send({
244
274
  error: { code: 'NOT_FOUND', message: 'settings file missing' },
245
- defaults: state.values,
275
+ defaults: offered.values,
246
276
  lastModified: 0,
247
277
  path: SETTINGS_RELATIVE,
248
- schema: SETTINGS_JSON_SCHEMA,
278
+ schema: offered.schema,
279
+ ...withheld,
249
280
  });
250
281
  return reply;
251
282
  }
252
283
  const legacyHints = extractLegacyHints(state.values);
253
284
  return {
254
- values: state.values,
285
+ values: offered.values,
255
286
  lastModified: state.mtimeMs,
256
287
  path: SETTINGS_RELATIVE,
257
- schema: SETTINGS_JSON_SCHEMA,
288
+ schema: offered.schema,
289
+ ...withheld,
258
290
  legacyHints,
259
291
  // Phase 5.4 — per-layer provenance for the settings hub's
260
292
  // "set globally / in this project" source badges.
@@ -293,7 +325,13 @@ export function settingsRoute(opts) {
293
325
  });
294
326
  return reply;
295
327
  }
296
- const changes = diffValues(current.values, parsed.data);
328
+ const candidate = opts.userGlobalWrite === true
329
+ ? keepWithheldGit(parsed.data, current.writeLayer ?? {})
330
+ : parsed.data;
331
+ const before = opts.userGlobalWrite === true
332
+ ? gitDiffBase(current.values, current.writeLayer ?? {})
333
+ : current.values;
334
+ const changes = diffValues(before, candidate);
297
335
  return { changes };
298
336
  });
299
337
  app.put('/api/v1/settings', async (request, reply) => {
@@ -310,6 +348,11 @@ export function settingsRoute(opts) {
310
348
  });
311
349
  return reply;
312
350
  }
351
+ const gitIssues = gitKeyWriteIssues(parsed.data, await loadDefaultSettings(packageRoot), opts.userGlobalWrite === true);
352
+ if (gitIssues.length > 0) {
353
+ await reply.code(422).send({ error: { code: 'VALIDATION', message: 'invalid settings', fields: gitIssues } });
354
+ return reply;
355
+ }
313
356
  const current = await readLayeredSettings(packageRoot, opts.writeRoot, opts.legacyReadRoot, opts.userGlobalReadRoot);
314
357
  if (!current.hasRealFile) {
315
358
  await reply.code(404).send({ error: { code: 'NOT_FOUND', message: 'settings file missing' } });
@@ -322,8 +365,22 @@ export function settingsRoute(opts) {
322
365
  });
323
366
  return reply;
324
367
  }
368
+ const candidate = opts.userGlobalWrite === true
369
+ ? keepWithheldGit(parsed.data, current.writeLayer ?? {})
370
+ : parsed.data;
325
371
  try {
326
- const merged = mergeIntoTemplate(current.raw, parsed.data);
372
+ // In global mode the scaffold may be the project file, whose
373
+ // git section the candidate does not overwrite; the file being
374
+ // written is the base, so a section it lacks stays absent. An
375
+ // absent user-global file is rendered the way the wizard renders
376
+ // a fresh one: merging into an empty body appends flat dotted
377
+ // keys, which no reader resolves.
378
+ const ownRaw = current.writeLayerRaw;
379
+ const merged = opts.userGlobalWrite !== true
380
+ ? mergeIntoTemplate(current.raw, candidate)
381
+ : ownRaw !== null
382
+ ? mergeIntoTemplate(ownRaw, candidate)
383
+ : renderSparseSettings(await freshUserGlobalValues(packageRoot, candidate));
327
384
  if (opts.dryRun === true) {
328
385
  // No disk write, no Last-Modified bump — surface the
329
386
  // rendered body so the maintainer sees what a real
@@ -352,7 +409,9 @@ export function settingsRoute(opts) {
352
409
  // this point and is not gated — it writes nothing.
353
410
  if (body.confirmGuarded !== true) {
354
411
  const classes = await readClassIndex(packageRoot);
355
- const guarded = guardedChangedKeys(classes, diffValues(current.values, parsed.data));
412
+ const guarded = guardedChangedKeys(classes, diffValues(opts.userGlobalWrite === true
413
+ ? gitDiffBase(current.values, current.writeLayer ?? {})
414
+ : current.values, candidate));
356
415
  if (guarded.length > 0) {
357
416
  await reply.code(409).send({
358
417
  error: 'guarded-keys',
@@ -19,6 +19,7 @@ import { detectAgentSwitch, AGENT_SWITCH_INSTALL_COMMAND, AGENT_SWITCH_REPO } fr
19
19
  import { readDismissedRecommendations, dismissRecommendation } from '../../install/wizardDismissals.js';
20
20
  import { installCompleted, installDoneSummary } from '../../install/preserve.js';
21
21
  import { apiOnQuotaView } from '../../scripts/ai_council/transport_resolver.js';
22
+ import { refuseGitKeys } from '../gitKeysGate.js';
22
23
  const STATE_REL = join('state', 'wizard-state.json');
23
24
  const SETTINGS_REL = join('settings', '.agent-settings.yml');
24
25
  const USER_IDENTITY_REL = join('settings', '.agent-user.yml');
@@ -1198,6 +1199,9 @@ export function wizardRoute(opts) {
1198
1199
  const effectiveWriteRoot = scope === 'project' && projectScopeRoot !== null
1199
1200
  ? projectScopeRoot
1200
1201
  : opts.writeRoot;
1202
+ const userGlobalTarget = opts.userGlobalWrite === true && effectiveWriteRoot === opts.writeRoot;
1203
+ if (await refuseGitKeys(reply, settingsParsed.data, opts.packageRoot, userGlobalTarget))
1204
+ return reply;
1201
1205
  try {
1202
1206
  const template = await readTemplate(opts.packageRoot);
1203
1207
  const answers = settingsParsed.data;