@event4u/agent-config 14.23.0 → 16.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (541) hide show
  1. package/.augment-plugin/marketplace.json +3 -3
  2. package/.augment-plugin/plugin.json +1 -1
  3. package/.claude-plugin/marketplace.json +1 -1
  4. package/CHANGELOG.md +144 -152
  5. package/README.md +1 -1
  6. package/dist/agent-src/commands/agent-handoff.md +8 -7
  7. package/dist/agent-src/commands/agents/init.md +1 -1
  8. package/dist/agent-src/commands/agents/user/accept.md +4 -4
  9. package/dist/agent-src/commands/agents/user/delete.md +2 -2
  10. package/dist/agent-src/commands/agents/user/init.md +3 -3
  11. package/dist/agent-src/commands/agents/user/review.md +3 -3
  12. package/dist/agent-src/commands/agents/user/show.md +3 -3
  13. package/dist/agent-src/commands/agents/user/update.md +2 -2
  14. package/dist/agent-src/commands/agents/user.md +6 -6
  15. package/dist/agent-src/commands/analytics/prune.md +1 -1
  16. package/dist/agent-src/commands/analytics/show.md +2 -2
  17. package/dist/agent-src/commands/analyze/decision.md +2 -2
  18. package/dist/agent-src/commands/analyze/inbox.md +5 -5
  19. package/dist/agent-src/commands/analyze/incident.md +3 -3
  20. package/dist/agent-src/commands/analyze/near-miss.md +3 -3
  21. package/dist/agent-src/commands/analyze/postmortem.md +4 -4
  22. package/dist/agent-src/commands/analyze/premortem.md +2 -2
  23. package/dist/agent-src/commands/analyze.md +2 -2
  24. package/dist/agent-src/commands/bug/fix.md +1 -1
  25. package/dist/agent-src/commands/bug/investigate.md +2 -2
  26. package/dist/agent-src/commands/cost/profile.md +3 -3
  27. package/dist/agent-src/commands/design.md +1 -1
  28. package/dist/agent-src/commands/feature/explore.md +1 -1
  29. package/dist/agent-src/commands/feature/plan.md +2 -2
  30. package/dist/agent-src/commands/feature/roadmap.md +2 -2
  31. package/dist/agent-src/commands/ghostwriter/fetch.md +4 -4
  32. package/dist/agent-src/commands/ghostwriter/list.md +1 -1
  33. package/dist/agent-src/commands/ghostwriter/show.md +1 -1
  34. package/dist/agent-src/commands/ghostwriter/write.md +9 -9
  35. package/dist/agent-src/commands/humanize.md +6 -6
  36. package/dist/agent-src/commands/jira-ticket.md +1 -1
  37. package/dist/agent-src/commands/judge/solo.md +1 -1
  38. package/dist/agent-src/commands/judge.md +1 -1
  39. package/dist/agent-src/commands/knowledge/cross-repo.md +1 -1
  40. package/dist/agent-src/commands/knowledge/forget.md +1 -1
  41. package/dist/agent-src/commands/knowledge/ingest.md +2 -2
  42. package/dist/agent-src/commands/knowledge/list.md +1 -1
  43. package/dist/agent-src/commands/memory/add.md +3 -3
  44. package/dist/agent-src/commands/memory/load.md +4 -4
  45. package/dist/agent-src/commands/memory/mine-session.md +1 -1
  46. package/dist/agent-src/commands/memory/promote.md +4 -4
  47. package/dist/agent-src/commands/memory/propose.md +2 -2
  48. package/dist/agent-src/commands/mode.md +5 -5
  49. package/dist/agent-src/commands/post-as/ghostwriter.md +3 -3
  50. package/dist/agent-src/commands/post-as/me.md +7 -7
  51. package/dist/agent-src/commands/pr/create.md +1 -1
  52. package/dist/agent-src/commands/pr/merge.md +1 -1
  53. package/dist/agent-src/commands/profile/activate.md +1 -1
  54. package/dist/agent-src/commands/profile/show.md +1 -1
  55. package/dist/agent-src/commands/research/deep.md +2 -2
  56. package/dist/agent-src/commands/research/report.md +2 -2
  57. package/dist/agent-src/commands/review/changes.md +1 -1
  58. package/dist/agent-src/commands/review/routing.md +1 -1
  59. package/dist/agent-src/commands/roadmap/create.md +4 -3
  60. package/dist/agent-src/commands/roadmap/materialize.md +2 -2
  61. package/dist/agent-src/commands/roadmap/next.md +1 -1
  62. package/dist/agent-src/commands/roadmap/process-full.md +2 -2
  63. package/dist/agent-src/commands/security-audit-config.md +3 -3
  64. package/dist/agent-src/commands/skill/preview.md +1 -1
  65. package/dist/agent-src/commands/skills/discover.md +1 -1
  66. package/dist/agent-src/commands/sync/agent-settings.md +2 -2
  67. package/dist/agent-src/commands/sync/gitignore/fix.md +1 -1
  68. package/dist/agent-src/commands/tests/create.md +1 -1
  69. package/dist/agent-src/commands/tests/e2e-heal.md +1 -1
  70. package/dist/agent-src/commands/tests/e2e-plan.md +1 -1
  71. package/dist/agent-src/contexts/authority/kernel-rule-edits.md +6 -6
  72. package/dist/agent-src/contexts/communication/rules-auto/slash-command-routing-policy-mechanics.md +1 -2
  73. package/dist/agent-src/contexts/communication/rules-auto/think-before-action-mechanics.md +2 -2
  74. package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +88 -1
  75. package/dist/agent-src/contexts/communication/rules-auto/user-interaction-mechanics.md +51 -1
  76. package/dist/agent-src/contexts/contracts/frugality-charter.md +1 -1
  77. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +1 -1
  78. package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +1 -1
  79. package/dist/agent-src/contexts/execution/autonomy-mechanics.md +1 -1
  80. package/dist/agent-src/contexts/execution/cheap-question-mechanics.md +1 -1
  81. package/dist/agent-src/contexts/execution/contract-decision-sheet.md +3 -3
  82. package/dist/agent-src/contexts/execution/mandated-lines.md +1 -1
  83. package/dist/agent-src/contexts/execution/non-interactive-contract.md +1 -1
  84. package/dist/agent-src/contexts/execution/orchestration-telemetry.md +1 -1
  85. package/dist/agent-src/contexts/execution/plan-confidence-gate.md +5 -5
  86. package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +1 -1
  87. package/dist/agent-src/contexts/execution/subagent-modes-detail.md +1 -1
  88. package/dist/agent-src/contexts/execution/subagent-routing.md +2 -2
  89. package/dist/agent-src/contexts/execution/subagent-spawn-contract.md +1 -1
  90. package/dist/agent-src/contexts/execution/user-memory-channels.md +3 -3
  91. package/dist/agent-src/contexts/execution/verification-mechanics.md +1 -1
  92. package/dist/agent-src/contexts/judges/persona-voice-rubric.md +2 -2
  93. package/dist/agent-src/guidelines/abstraction-thresholds.md +88 -0
  94. package/dist/agent-src/guidelines/agent-infra/5w2h-analysis.md +260 -0
  95. package/dist/agent-src/guidelines/agent-infra/active-remediation-mechanics.md +99 -0
  96. package/dist/agent-src/guidelines/agent-infra/agent-interaction-and-decision-quality.md +325 -0
  97. package/dist/agent-src/guidelines/agent-infra/api-cost-levers.md +177 -0
  98. package/dist/agent-src/guidelines/agent-infra/artifact-drafting-protocol-mechanics.md +222 -0
  99. package/dist/agent-src/guidelines/agent-infra/ask-when-uncertain-demos.md +134 -0
  100. package/dist/agent-src/guidelines/agent-infra/asking-and-brevity-examples.md +198 -0
  101. package/dist/agent-src/guidelines/agent-infra/break-glass-usage.md +113 -0
  102. package/dist/agent-src/guidelines/agent-infra/carve-out-predicates.md +17 -0
  103. package/dist/agent-src/guidelines/agent-infra/comparison-matrix.md +179 -0
  104. package/dist/agent-src/guidelines/agent-infra/context-hygiene-mechanics.md +165 -0
  105. package/dist/agent-src/guidelines/agent-infra/corpus-grounding-authoring.md +91 -0
  106. package/dist/agent-src/guidelines/agent-infra/critical-thinking.md +156 -0
  107. package/dist/agent-src/guidelines/agent-infra/cross-source-consistency-mechanics.md +109 -0
  108. package/dist/agent-src/guidelines/agent-infra/developer-judgment.md +82 -0
  109. package/dist/agent-src/guidelines/agent-infra/direct-answers-demos.md +142 -0
  110. package/dist/agent-src/guidelines/agent-infra/domain-adoption-gates.md +112 -0
  111. package/dist/agent-src/guidelines/agent-infra/domain-eval-anti-pattern.md +53 -0
  112. package/dist/agent-src/guidelines/agent-infra/domain-pack-architecture.md +56 -0
  113. package/dist/agent-src/guidelines/agent-infra/downstream-changes-mechanics.md +91 -0
  114. package/dist/agent-src/guidelines/agent-infra/emphasis-budget.md +45 -0
  115. package/dist/agent-src/guidelines/agent-infra/engineering-memory-data-format.md +210 -0
  116. package/dist/agent-src/guidelines/agent-infra/evaluator-independence-mechanics.md +92 -0
  117. package/dist/agent-src/guidelines/agent-infra/existence-question-verdicts.md +80 -0
  118. package/dist/agent-src/guidelines/agent-infra/failure-signatures.md +70 -0
  119. package/dist/agent-src/guidelines/agent-infra/false-green.md +233 -0
  120. package/dist/agent-src/guidelines/agent-infra/first-principles.md +192 -0
  121. package/dist/agent-src/guidelines/agent-infra/framework-neutrality-patterns.md +66 -0
  122. package/dist/agent-src/guidelines/agent-infra/frontier-reasoning-operating-profile.md +169 -0
  123. package/dist/agent-src/guidelines/agent-infra/gate-authoring.md +177 -0
  124. package/dist/agent-src/guidelines/agent-infra/guarded-baseline.md +39 -0
  125. package/dist/agent-src/guidelines/agent-infra/installed-tools-manifest.md +142 -0
  126. package/dist/agent-src/guidelines/agent-infra/inversion-thinking.md +388 -0
  127. package/dist/agent-src/guidelines/agent-infra/ios-simulator-guide.md +378 -0
  128. package/dist/agent-src/guidelines/agent-infra/language-and-tone-examples.md +141 -0
  129. package/dist/agent-src/guidelines/agent-infra/layered-settings.md +317 -0
  130. package/dist/agent-src/guidelines/agent-infra/linked-projects-onboarding-gate.md +80 -0
  131. package/dist/agent-src/guidelines/agent-infra/mcp-request-signing.md +197 -0
  132. package/dist/agent-src/guidelines/agent-infra/memory-access.md +149 -0
  133. package/dist/agent-src/guidelines/agent-infra/mental-models.md +314 -0
  134. package/dist/agent-src/guidelines/agent-infra/minimal-safe-diff-mechanics.md +241 -0
  135. package/dist/agent-src/guidelines/agent-infra/missing-tool-handling.md +66 -0
  136. package/dist/agent-src/guidelines/agent-infra/model-recommendation.md +101 -0
  137. package/dist/agent-src/guidelines/agent-infra/naming.md +69 -0
  138. package/dist/agent-src/guidelines/agent-infra/notes-horizon-mechanics.md +90 -0
  139. package/dist/agent-src/guidelines/agent-infra/output-patterns.md +117 -0
  140. package/dist/agent-src/guidelines/agent-infra/recurring-criticism-mechanics.md +96 -0
  141. package/dist/agent-src/guidelines/agent-infra/reuse-verdict-mechanics.md +71 -0
  142. package/dist/agent-src/guidelines/agent-infra/review-routing-data-format.md +143 -0
  143. package/dist/agent-src/guidelines/agent-infra/roadmap-deferred-resolution-provenance.md +54 -0
  144. package/dist/agent-src/guidelines/agent-infra/roadmap-progress-mechanics.md +274 -0
  145. package/dist/agent-src/guidelines/agent-infra/role-contracts.md +209 -0
  146. package/dist/agent-src/guidelines/agent-infra/role-mode-router.md +89 -0
  147. package/dist/agent-src/guidelines/agent-infra/rule-body-migration-inventory.md +241 -0
  148. package/dist/agent-src/guidelines/agent-infra/rule-type-governance.md +73 -0
  149. package/dist/agent-src/guidelines/agent-infra/runtime-layer.md +89 -0
  150. package/dist/agent-src/guidelines/agent-infra/scqa-framework.md +526 -0
  151. package/dist/agent-src/guidelines/agent-infra/security-lint-containment.md +121 -0
  152. package/dist/agent-src/guidelines/agent-infra/self-improvement-pipeline.md +134 -0
  153. package/dist/agent-src/guidelines/agent-infra/simplicity-and-goal-demos.md +211 -0
  154. package/dist/agent-src/guidelines/agent-infra/six-hats.md +353 -0
  155. package/dist/agent-src/guidelines/agent-infra/size-and-scope.md +229 -0
  156. package/dist/agent-src/guidelines/agent-infra/skill-quality-checklist.md +157 -0
  157. package/dist/agent-src/guidelines/agent-infra/source-confidentiality-mechanics.md +109 -0
  158. package/dist/agent-src/guidelines/agent-infra/symptom-driven-harvest-loop.md +104 -0
  159. package/dist/agent-src/guidelines/agent-infra/systems-thinking.md +220 -0
  160. package/dist/agent-src/guidelines/agent-infra/tool-description-as-policy.md +35 -0
  161. package/dist/agent-src/guidelines/agent-infra/tool-integration.md +73 -0
  162. package/dist/agent-src/guidelines/agent-infra/traceability-field-mechanics.md +50 -0
  163. package/dist/agent-src/guidelines/agent-infra/untrusted-input-spotlighting.md +166 -0
  164. package/dist/agent-src/guidelines/agent-infra/verify-before-complete-demos.md +128 -0
  165. package/dist/agent-src/guidelines/augment-portability-patterns.md +70 -0
  166. package/dist/agent-src/guidelines/code-clarity.md +350 -0
  167. package/dist/agent-src/guidelines/component-oriented-and-oop-development.md +189 -0
  168. package/dist/agent-src/guidelines/cross-role-handoff.md +127 -0
  169. package/dist/agent-src/guidelines/design-antipatterns-triggers.json +18 -0
  170. package/dist/agent-src/guidelines/design-antipatterns.md +327 -0
  171. package/dist/agent-src/guidelines/design-asset-discipline.md +38 -0
  172. package/dist/agent-src/guidelines/design-canon.md +63 -0
  173. package/dist/agent-src/guidelines/design-fidelity-mechanics.md +293 -0
  174. package/dist/agent-src/guidelines/design-fidelity-routing.md +78 -0
  175. package/dist/agent-src/guidelines/design-handover-extraction.md +117 -0
  176. package/dist/agent-src/guidelines/design-modes.md +143 -0
  177. package/dist/agent-src/guidelines/design-reconciliation.md +172 -0
  178. package/dist/agent-src/guidelines/docs/readme-size-and-splitting.md +209 -0
  179. package/dist/agent-src/guidelines/e2e/playwright.md +363 -0
  180. package/dist/agent-src/guidelines/gtm-handoff.md +114 -0
  181. package/dist/agent-src/guidelines/monorepo-antipatterns.md +141 -0
  182. package/dist/agent-src/guidelines/php/api-design.md +115 -0
  183. package/dist/agent-src/guidelines/php/artisan-commands.md +81 -0
  184. package/dist/agent-src/guidelines/php/blade-ui.md +78 -0
  185. package/dist/agent-src/guidelines/php/controllers.md +90 -0
  186. package/dist/agent-src/guidelines/php/database.md +194 -0
  187. package/dist/agent-src/guidelines/php/eloquent.md +208 -0
  188. package/dist/agent-src/guidelines/php/flux.md +80 -0
  189. package/dist/agent-src/guidelines/php/general.md +207 -0
  190. package/dist/agent-src/guidelines/php/git.md +164 -0
  191. package/dist/agent-src/guidelines/php/jobs.md +111 -0
  192. package/dist/agent-src/guidelines/php/livewire.md +71 -0
  193. package/dist/agent-src/guidelines/php/logging.md +79 -0
  194. package/dist/agent-src/guidelines/php/naming.md +89 -0
  195. package/dist/agent-src/guidelines/php/patterns/dependency-injection.md +57 -0
  196. package/dist/agent-src/guidelines/php/patterns/dtos.md +199 -0
  197. package/dist/agent-src/guidelines/php/patterns/events.md +67 -0
  198. package/dist/agent-src/guidelines/php/patterns/factory.md +53 -0
  199. package/dist/agent-src/guidelines/php/patterns/pipelines.md +66 -0
  200. package/dist/agent-src/guidelines/php/patterns/policies.md +66 -0
  201. package/dist/agent-src/guidelines/php/patterns/repositories.md +122 -0
  202. package/dist/agent-src/guidelines/php/patterns/service-layer.md +64 -0
  203. package/dist/agent-src/guidelines/php/patterns/strategy.md +247 -0
  204. package/dist/agent-src/guidelines/php/patterns.md +28 -0
  205. package/dist/agent-src/guidelines/php/performance.md +92 -0
  206. package/dist/agent-src/guidelines/php/php-coding-patterns.md +80 -0
  207. package/dist/agent-src/guidelines/php/resources.md +100 -0
  208. package/dist/agent-src/guidelines/php/security.md +110 -0
  209. package/dist/agent-src/guidelines/php/sql.md +97 -0
  210. package/dist/agent-src/guidelines/php/validations.md +119 -0
  211. package/dist/agent-src/guidelines/php/websocket.md +100 -0
  212. package/dist/agent-src/guidelines/prompt-templates.md +189 -0
  213. package/dist/agent-src/guidelines/redundancy-taxonomy.md +208 -0
  214. package/dist/agent-src/guidelines/wing4-handoff.md +127 -0
  215. package/dist/agent-src/personas/README.md +1 -1
  216. package/dist/agent-src/personas/_template-specialist/persona.md +1 -1
  217. package/dist/agent-src/personas/product-owner.md +1 -1
  218. package/dist/agent-src/rules/active-remediation.md +1 -1
  219. package/dist/agent-src/rules/architecture.md +2 -2
  220. package/dist/agent-src/rules/artifact-drafting-protocol.md +1 -1
  221. package/dist/agent-src/rules/ask-when-uncertain.md +2 -2
  222. package/dist/agent-src/rules/brand-source-of-truth.md +9 -7
  223. package/dist/agent-src/rules/code-comment-discipline.md +2 -2
  224. package/dist/agent-src/rules/code-provenance.md +1 -1
  225. package/dist/agent-src/rules/content-quoting-floor.md +1 -1
  226. package/dist/agent-src/rules/context-hygiene.md +5 -5
  227. package/dist/agent-src/rules/cross-source-consistency.md +1 -1
  228. package/dist/agent-src/rules/design-fidelity.md +36 -46
  229. package/dist/agent-src/rules/direct-answers.md +2 -2
  230. package/dist/agent-src/rules/domain-adoption-policy.md +1 -1
  231. package/dist/agent-src/rules/evaluator-independence.md +1 -1
  232. package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +1 -1
  233. package/dist/agent-src/rules/icon-consistency.md +5 -1
  234. package/dist/agent-src/rules/improve-before-implement.md +1 -1
  235. package/dist/agent-src/rules/language-and-tone.md +3 -3
  236. package/dist/agent-src/rules/minimal-safe-diff.md +1 -1
  237. package/dist/agent-src/rules/notes-first-reasoning.md +2 -2
  238. package/dist/agent-src/rules/recurring-criticism.md +1 -1
  239. package/dist/agent-src/rules/roadmap-progress-sync.md +1 -1
  240. package/dist/agent-src/rules/role-mode-adherence.md +2 -2
  241. package/dist/agent-src/rules/security-sensitive-stop.md +1 -1
  242. package/dist/agent-src/rules/size-enforcement.md +1 -1
  243. package/dist/agent-src/rules/source-confidentiality.md +2 -2
  244. package/dist/agent-src/rules/think-before-action.md +1 -1
  245. package/dist/agent-src/rules/token-efficiency.md +7 -5
  246. package/dist/agent-src/rules/ui-audit-gate.md +3 -2
  247. package/dist/agent-src/rules/untrusted-input-defense.md +3 -3
  248. package/dist/agent-src/rules/user-interaction.md +31 -30
  249. package/dist/agent-src/skills/activation-design/SKILL.md +2 -2
  250. package/dist/agent-src/skills/adr-create/SKILL.md +5 -5
  251. package/dist/agent-src/skills/ai-council/SKILL.md +1 -1
  252. package/dist/agent-src/skills/ai-council/references/advanced-modes.md +1 -1
  253. package/dist/agent-src/skills/blade-ui/SKILL.md +1 -1
  254. package/dist/agent-src/skills/blast-radius-analyzer/SKILL.md +1 -1
  255. package/dist/agent-src/skills/brand-to-tokens/SKILL.md +24 -3
  256. package/dist/agent-src/skills/bug-analyzer/SKILL.md +1 -1
  257. package/dist/agent-src/skills/build-buy-partner/SKILL.md +1 -1
  258. package/dist/agent-src/skills/churn-prevention/SKILL.md +2 -2
  259. package/dist/agent-src/skills/code-refactoring/SKILL.md +3 -3
  260. package/dist/agent-src/skills/code-review/SKILL.md +3 -3
  261. package/dist/agent-src/skills/command-writing/SKILL.md +3 -3
  262. package/dist/agent-src/skills/comp-banding/SKILL.md +1 -1
  263. package/dist/agent-src/skills/competitive-moat-analysis/SKILL.md +1 -1
  264. package/dist/agent-src/skills/competitive-positioning/SKILL.md +2 -2
  265. package/dist/agent-src/skills/complexity-first-planning/SKILL.md +1 -1
  266. package/dist/agent-src/skills/condense-memory/SKILL.md +1 -1
  267. package/dist/agent-src/skills/content-funnel-design/SKILL.md +2 -2
  268. package/dist/agent-src/skills/contracts-cognition/SKILL.md +1 -1
  269. package/dist/agent-src/skills/copilot-agents-optimization/SKILL.md +2 -2
  270. package/dist/agent-src/skills/corpus-grounding/SKILL.md +2 -2
  271. package/dist/agent-src/skills/customer-research/SKILL.md +2 -2
  272. package/dist/agent-src/skills/dashboard-design/SKILL.md +1 -1
  273. package/dist/agent-src/skills/data-handling-judgment/SKILL.md +1 -1
  274. package/dist/agent-src/skills/deal-qualification-meddic/SKILL.md +2 -2
  275. package/dist/agent-src/skills/decision-record/SKILL.md +3 -3
  276. package/dist/agent-src/skills/decision-review/SKILL.md +8 -8
  277. package/dist/agent-src/skills/deep-reading-analyst/SKILL.md +22 -22
  278. package/dist/agent-src/skills/design-intelligence/SKILL.md +4 -4
  279. package/dist/agent-src/skills/design-intelligence/references/context-and-registers.md +2 -2
  280. package/dist/agent-src/skills/design-review/SKILL.md +4 -4
  281. package/dist/agent-src/skills/design-system-capture/references/design-system-json.md +20 -1
  282. package/dist/agent-src/skills/design-tokens/SKILL.md +17 -2
  283. package/dist/agent-src/skills/design-variations/SKILL.md +2 -2
  284. package/dist/agent-src/skills/developer-like-execution/SKILL.md +2 -2
  285. package/dist/agent-src/skills/discovery-interview/SKILL.md +2 -2
  286. package/dist/agent-src/skills/doc-coauthoring/SKILL.md +3 -3
  287. package/dist/agent-src/skills/editorial-calendar/SKILL.md +2 -2
  288. package/dist/agent-src/skills/error-handling-patterns/SKILL.md +9 -0
  289. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +44 -1
  290. package/dist/agent-src/skills/existing-ui-audit/references/anti-slop-cross-reference.md +2 -2
  291. package/dist/agent-src/skills/expansion-playbook/SKILL.md +2 -2
  292. package/dist/agent-src/skills/experiment-loop/SKILL.md +1 -1
  293. package/dist/agent-src/skills/experiment-loop/references/protocol.md +1 -1
  294. package/dist/agent-src/skills/fe-design/SKILL.md +3 -3
  295. package/dist/agent-src/skills/fe-design/references/design-patterns.md +1 -1
  296. package/dist/agent-src/skills/fe-design/references/design-read-and-memory.md +3 -3
  297. package/dist/agent-src/skills/fe-design/references/source-led-port.md +1 -1
  298. package/dist/agent-src/skills/feature-planning/SKILL.md +1 -1
  299. package/dist/agent-src/skills/flux/SKILL.md +1 -1
  300. package/dist/agent-src/skills/forecast-accuracy/SKILL.md +2 -2
  301. package/dist/agent-src/skills/forecasting/SKILL.md +2 -2
  302. package/dist/agent-src/skills/fundraising-narrative/SKILL.md +2 -2
  303. package/dist/agent-src/skills/funnel-analysis/SKILL.md +2 -2
  304. package/dist/agent-src/skills/gtm-launch/SKILL.md +2 -2
  305. package/dist/agent-src/skills/hiring-loop-design/SKILL.md +1 -1
  306. package/dist/agent-src/skills/html-deck/SKILL.md +5 -5
  307. package/dist/agent-src/skills/humanizer/SKILL.md +1 -1
  308. package/dist/agent-src/skills/humanizer/data/patterns.md +1 -1
  309. package/dist/agent-src/skills/iconography/SKILL.md +3 -3
  310. package/dist/agent-src/skills/judge-synthesis/SKILL.md +1 -1
  311. package/dist/agent-src/skills/laravel-api-endpoint/SKILL.md +2 -2
  312. package/dist/agent-src/skills/launch-readiness/SKILL.md +3 -3
  313. package/dist/agent-src/skills/learning-to-rule-or-skill/SKILL.md +6 -6
  314. package/dist/agent-src/skills/livewire/SKILL.md +1 -1
  315. package/dist/agent-src/skills/market-entry-analysis/SKILL.md +1 -1
  316. package/dist/agent-src/skills/mcp-builder/SKILL.md +1 -1
  317. package/dist/agent-src/skills/memory-consolidation/SKILL.md +3 -3
  318. package/dist/agent-src/skills/messaging-architecture/SKILL.md +2 -2
  319. package/dist/agent-src/skills/monorepo-workspace/SKILL.md +1 -1
  320. package/dist/agent-src/skills/onboarding-design/SKILL.md +2 -2
  321. package/dist/agent-src/skills/onboarding-program/SKILL.md +1 -1
  322. package/dist/agent-src/skills/one-on-one-cadence/SKILL.md +1 -1
  323. package/dist/agent-src/skills/org-design/SKILL.md +1 -1
  324. package/dist/agent-src/skills/overbuild-review-lens/SKILL.md +3 -3
  325. package/dist/agent-src/skills/override-management/SKILL.md +1 -1
  326. package/dist/agent-src/skills/perf-feedback-craft/SKILL.md +1 -1
  327. package/dist/agent-src/skills/persona-writing/SKILL.md +1 -1
  328. package/dist/agent-src/skills/php-coder/SKILL.md +1 -1
  329. package/dist/agent-src/skills/pipeline-strategy/SKILL.md +2 -2
  330. package/dist/agent-src/skills/playwright-testing/SKILL.md +3 -3
  331. package/dist/agent-src/skills/po-discovery/SKILL.md +1 -1
  332. package/dist/agent-src/skills/positioning-strategy/SKILL.md +2 -2
  333. package/dist/agent-src/skills/privacy-review/SKILL.md +1 -1
  334. package/dist/agent-src/skills/prompt-optimizer/SKILL.md +3 -3
  335. package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +1 -1
  336. package/dist/agent-src/skills/reasoning-orchestrator/SKILL.md +2 -2
  337. package/dist/agent-src/skills/receiving-code-review/SKILL.md +1 -1
  338. package/dist/agent-src/skills/refine-ticket/SKILL.md +2 -2
  339. package/dist/agent-src/skills/release-comms/SKILL.md +2 -2
  340. package/dist/agent-src/skills/retention-loops/SKILL.md +2 -2
  341. package/dist/agent-src/skills/review-routing/SKILL.md +2 -2
  342. package/dist/agent-src/skills/roadmap-management/SKILL.md +1 -1
  343. package/dist/agent-src/skills/roadmap-management/references/archival.md +1 -1
  344. package/dist/agent-src/skills/roadmap-writing/SKILL.md +5 -5
  345. package/dist/agent-src/skills/rule-writing/SKILL.md +6 -6
  346. package/dist/agent-src/skills/runway-cognition/SKILL.md +2 -2
  347. package/dist/agent-src/skills/scenario-modeling/SKILL.md +2 -2
  348. package/dist/agent-src/skills/skill-writing/SKILL.md +2 -2
  349. package/dist/agent-src/skills/skill-writing/references/procedure.md +1 -1
  350. package/dist/agent-src/skills/skill-writing/references/section-patterns.md +3 -3
  351. package/dist/agent-src/skills/spreadsheet-authoring/SKILL.md +1 -1
  352. package/dist/agent-src/skills/stakeholder-tradeoff/SKILL.md +3 -3
  353. package/dist/agent-src/skills/subagent-orchestration/SKILL.md +1 -1
  354. package/dist/agent-src/skills/supply-chain-intake/SKILL.md +1 -1
  355. package/dist/agent-src/skills/systematic-debugging/SKILL.md +2 -2
  356. package/dist/agent-src/skills/tailwind-engineer/SKILL.md +11 -5
  357. package/dist/agent-src/skills/throughput-vs-morale-tradeoff/SKILL.md +1 -1
  358. package/dist/agent-src/skills/token-optimizer/SKILL.md +1 -1
  359. package/dist/agent-src/skills/typography-system/SKILL.md +2 -2
  360. package/dist/agent-src/skills/ui-component-architect/SKILL.md +28 -8
  361. package/dist/agent-src/skills/unit-economics-modeling/SKILL.md +2 -2
  362. package/dist/agent-src/skills/upstream-contribute/SKILL.md +1 -1
  363. package/dist/agent-src/skills/validate-feature-fit/SKILL.md +2 -2
  364. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +2 -2
  365. package/dist/agent-src/skills/vision-articulation/SKILL.md +1 -1
  366. package/dist/agent-src/skills/voc-extract/SKILL.md +2 -2
  367. package/dist/agent-src/skills/voice-and-tone-design/SKILL.md +2 -2
  368. package/dist/agent-src/skills/wireframe/SKILL.md +1 -1
  369. package/dist/agent-src/skills/workspace-link/SKILL.md +1 -1
  370. package/dist/agent-src/templates/agent-settings.md +6 -6
  371. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  372. package/dist/agent-src/templates/contexts/knowledge-pages.md +2 -3
  373. package/dist/agent-src/templates/copilot-instructions.md +1 -1
  374. package/dist/agent-src/templates/roadmaps.md +1 -1
  375. package/dist/agent-src/templates/scripts/README.md +2 -2
  376. package/dist/agent-src/user-types/_template/user-type.md +1 -1
  377. package/dist/cli-delegate/check_update_banner.js +12 -1
  378. package/dist/cli-delegate/{chunk-NLP54U3J.js → chunk-2XY7ILBT.js} +13 -1
  379. package/dist/cli-delegate/{chunk-IAI3XL43.js → chunk-3FKR64R5.js} +22 -6
  380. package/dist/cli-delegate/{chunk-J3RFNKG4.js → chunk-55ACLDUE.js} +2 -2
  381. package/dist/cli-delegate/{chunk-PKOBQADP.js → chunk-57PN4GYJ.js} +1 -1
  382. package/dist/cli-delegate/{chunk-KCNTUSPI.js → chunk-AK6HODNQ.js} +4 -4
  383. package/dist/cli-delegate/{chunk-2FTMENJL.js → chunk-GYC3VRYN.js} +1 -1
  384. package/dist/cli-delegate/{chunk-LWTYTX6F.js → chunk-H32DGUJH.js} +15 -84
  385. package/dist/cli-delegate/{chunk-6RJA2F5A.js → chunk-IVBPRCQO.js} +1 -1
  386. package/dist/cli-delegate/chunk-NUHLI2RX.js +80 -0
  387. package/dist/cli-delegate/{chunk-TYSY33MD.js → chunk-QJWAUMJW.js} +12 -2
  388. package/dist/cli-delegate/{chunk-2KKXJW25.js → chunk-S3VFXMTM.js} +1 -1
  389. package/dist/cli-delegate/{chunk-I6RHFQEG.js → chunk-YUM5KURG.js} +17 -1
  390. package/dist/cli-delegate/cmd_analyze_session.js +1 -1
  391. package/dist/cli-delegate/cmd_brand_status.js +1 -1
  392. package/dist/cli-delegate/cmd_conformance.js +834 -275
  393. package/dist/cli-delegate/cmd_doctor.js +3 -3
  394. package/dist/cli-delegate/cmd_explain.js +5 -3
  395. package/dist/cli-delegate/cmd_export.js +4 -4
  396. package/dist/cli-delegate/cmd_handoff.js +6 -6
  397. package/dist/cli-delegate/cmd_mcp_available.js +1 -1
  398. package/dist/cli-delegate/cmd_memory_get.js +1 -1
  399. package/dist/cli-delegate/cmd_migrate.js +2 -2
  400. package/dist/cli-delegate/cmd_packs_active.js +3 -2
  401. package/dist/cli-delegate/cmd_prune.js +4 -4
  402. package/dist/cli-delegate/cmd_route_audit.js +3 -3
  403. package/dist/cli-delegate/cmd_route_explain.js +1 -1
  404. package/dist/cli-delegate/cmd_session_recycle.js +3 -3
  405. package/dist/cli-delegate/cmd_settings_get.js +15 -9
  406. package/dist/cli-delegate/cmd_settings_migrate.js +4 -4
  407. package/dist/cli-delegate/cmd_settings_set.js +54 -11
  408. package/dist/cli-delegate/cmd_sync.js +4 -4
  409. package/dist/cli-delegate/cmd_uninstall.js +4 -4
  410. package/dist/cli-delegate/cmd_update.js +1 -1
  411. package/dist/cli-delegate/cmd_upgrade.js +1 -1
  412. package/dist/cli-delegate/cmd_validate.js +4 -4
  413. package/dist/cli-delegate/cmd_versions.js +1 -1
  414. package/dist/discovery/deprecation-report.md +1 -1
  415. package/dist/discovery/discovery-manifest.json +25 -78
  416. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  417. package/dist/discovery/discovery-manifest.summary.md +3 -3
  418. package/dist/discovery/dormancy-report.md +1 -1
  419. package/dist/discovery/orphan-report.md +1 -1
  420. package/dist/discovery/packs.json +5 -7
  421. package/dist/discovery/trust-report.md +2 -2
  422. package/dist/discovery/workspaces.json +4 -6
  423. package/dist/hooks/dispatch.js +9684 -9304
  424. package/dist/install/install.mjs +36 -8
  425. package/dist/mcp/registry-manifest.json +3 -3
  426. package/dist/mcp/server.json +2 -2
  427. package/dist/mcp/server.mjs +2147 -1470
  428. package/dist/router.json +1 -1
  429. package/dist/scripts/_lib/agent_settings.js +73 -0
  430. package/dist/scripts/_lib/agent_src.js +20 -0
  431. package/dist/scripts/_lib/guidelines_lane.js +158 -0
  432. package/dist/scripts/_lib/installed_lock.js +1 -1
  433. package/dist/scripts/condense.js +2 -5
  434. package/dist/server/io/yamlIO.js +175 -17
  435. package/dist/server/schemas/settings.js +18 -4
  436. package/dist/shared/settingsSurface.js +6 -1
  437. package/docs/contracts/settings-classes.md +18 -9
  438. package/docs/guidelines/abstraction-thresholds.md +35 -0
  439. package/docs/guidelines/agent-infra/active-remediation-mechanics.md +3 -3
  440. package/docs/guidelines/agent-infra/false-green.md +2 -2
  441. package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
  442. package/docs/guidelines/agent-infra/skill-quality-checklist.md +1 -1
  443. package/docs/guidelines/design-fidelity-mechanics.md +4 -0
  444. package/docs/guidelines/design-fidelity-routing.md +78 -0
  445. package/docs/guidelines/design-reconciliation.md +172 -0
  446. package/docs/guidelines/gtm-handoff.md +2 -2
  447. package/docs/guidelines/wing4-handoff.md +2 -2
  448. package/package.json +7 -3
  449. package/src/config/agent-settings.template.yml +55 -8
  450. package/src/config/ci-local-parity.yml +34 -0
  451. package/src/config/continuity-surface.json +11 -32
  452. package/src/config/gate-coverage.yml +31 -8
  453. package/src/config/gate-reachability-exemptions.json +1 -0
  454. package/src/config/gate-violation-baselines.json +3 -3
  455. package/src/config/hook-token-budget.json +1 -1
  456. package/src/config/host-injection-effect.json +2 -2
  457. package/src/config/pack-size-budget.json +55 -4
  458. package/src/config/platform-anchor.json +47 -0
  459. package/src/config/preamble-payload-budget.json +12 -8
  460. package/src/config/preamble-payload-exceptions.json +28 -0
  461. package/src/config/publish-surface.json +4 -2
  462. package/src/config/ratification-policy.json +7 -0
  463. package/src/config/rule-stub-ceilings.json +16 -9
  464. package/src/scripts/_cli/cmd_settings_get.ts +22 -7
  465. package/src/scripts/_dispatch.bash +3 -1
  466. package/src/scripts/_lib/agent_settings.ts +85 -0
  467. package/src/scripts/_lib/agent_src.ts +21 -0
  468. package/src/scripts/_lib/artifact_maturity.ts +242 -0
  469. package/src/scripts/_lib/base_ref_payload.ts +315 -0
  470. package/src/scripts/_lib/conformance_report.ts +403 -0
  471. package/src/scripts/_lib/continuity_writer.ts +72 -13
  472. package/src/scripts/_lib/design_system_import.ts +20 -0
  473. package/src/scripts/_lib/design_tolerance.ts +281 -0
  474. package/src/scripts/_lib/dropped_decision.ts +142 -0
  475. package/src/scripts/_lib/guidelines_lane.ts +164 -0
  476. package/src/scripts/_lib/installed_lock.ts +1 -1
  477. package/src/scripts/_lib/measured_payload_ceiling.ts +424 -0
  478. package/src/scripts/_lib/obligation_frequency.ts +2 -3
  479. package/src/scripts/_lib/payload_catalogue_completeness.ts +211 -0
  480. package/src/scripts/_lib/platform_anchor.ts +1053 -0
  481. package/src/scripts/_lib/ratification_artifact.ts +278 -0
  482. package/src/scripts/_lib/release_findings_ingest.ts +324 -0
  483. package/src/scripts/_lib/release_tag_dispatch.ts +63 -0
  484. package/src/scripts/_lib/review_baseline.ts +254 -0
  485. package/src/scripts/_lib/review_skipped_record.ts +61 -1
  486. package/src/scripts/_lib/security_lint.ts +23 -2
  487. package/src/scripts/_lib/self_repair.ts +21 -0
  488. package/src/scripts/_lib/session_index_trust.ts +42 -1
  489. package/src/scripts/_lib/standing_bound_ratchet.ts +267 -88
  490. package/src/scripts/_lib/tolerance_shadow.ts +177 -0
  491. package/src/scripts/_lib/turn_end_refusals.ts +51 -4
  492. package/src/scripts/ai_council/redact_low_impact_entry.ts +8 -0
  493. package/src/scripts/autonomy_friction_traffic.ts +379 -0
  494. package/src/scripts/check_beta_review_markers.ts +35 -4
  495. package/src/scripts/check_finding_dispositions.ts +167 -16
  496. package/src/scripts/check_held_object_arrivals.ts +381 -0
  497. package/src/scripts/check_kernel_edit_ratified.ts +462 -0
  498. package/src/scripts/check_loss_class_declared.ts +793 -46
  499. package/src/scripts/check_platform_anchor.ts +390 -0
  500. package/src/scripts/check_preamble_payload_budget.ts +672 -107
  501. package/src/scripts/check_projected_rule_routes.ts +395 -0
  502. package/src/scripts/check_release_published.ts +1 -1
  503. package/src/scripts/check_reply_consistency.ts +86 -17
  504. package/src/scripts/code_graph/cli.ts +6 -0
  505. package/src/scripts/condense.ts +2 -6
  506. package/src/scripts/generate_host_cost_table.ts +354 -0
  507. package/src/scripts/hook_manifest.json +1 -1
  508. package/src/scripts/hook_manifest.yaml +74 -30
  509. package/src/scripts/hooks/block_kernel_rule_writes.ts +12 -2
  510. package/src/scripts/hooks/category_a.ts +1 -1
  511. package/src/scripts/hooks/chain_nudge_hook.ts +311 -25
  512. package/src/scripts/hooks/concern_registry.ts +2 -0
  513. package/src/scripts/hooks/end_review_nudge_hook.ts +101 -21
  514. package/src/scripts/hooks/review_baseline_hook.ts +130 -0
  515. package/src/scripts/hooks/session_eol_hook.ts +68 -154
  516. package/src/scripts/hooks/source_first_gate_hook.ts +12 -0
  517. package/src/scripts/hooks/turn_end_gate_hook.ts +232 -14
  518. package/src/scripts/hooks/ui_route_nudge_hook.ts +52 -15
  519. package/src/scripts/hooks_doctor.ts +4 -1
  520. package/src/scripts/hot_context_hook.ts +41 -401
  521. package/src/scripts/install.ts +1 -1
  522. package/src/scripts/interruption_report.ts +8 -2
  523. package/src/scripts/janitor.ts +8 -1
  524. package/src/scripts/lint_evidence_artifacts.ts +1 -0
  525. package/src/scripts/lint_knowledge_scale.ts +0 -26
  526. package/src/scripts/measure_turn_end_gate.ts +302 -5
  527. package/src/scripts/memory_lookup.ts +9 -9
  528. package/src/scripts/release.ts +52 -64
  529. package/src/scripts/release_drill.ts +193 -14
  530. package/src/scripts/release_env.ts +1 -1
  531. package/src/scripts/release_publication.ts +1 -1
  532. package/src/scripts/report_held_object_arrivals.ts +456 -0
  533. package/src/scripts/report_standing_payload_by_host.ts +7 -7
  534. package/src/scripts/session_memory_index.ts +5 -0
  535. package/src/scripts/sync_agent_settings.ts +394 -12
  536. package/src/server/io/yamlIO.ts +175 -17
  537. package/src/server/schemas/settings.ts +25 -5
  538. package/src/shared/settingsSurface.ts +13 -2
  539. package/src/templates/compact-instructions.md +8 -3
  540. package/dist/agent-src/commands/chat-history/import.md +0 -170
  541. package/dist/agent-src/commands/chat-history.md +0 -63
@@ -24,13 +24,22 @@
24
24
  * Usage:
25
25
  * sync_agent_settings # write (default)
26
26
  * sync_agent_settings --dry-run # show diff, no write
27
- * sync_agent_settings --check # exit 2 on drift (for CI)
27
+ * sync_agent_settings --check # exit 2 if a sync is needed (CI)
28
28
  * sync_agent_settings --profile balanced # use a specific profile
29
29
  * sync_agent_settings --path path/to/.agent-settings.yml
30
30
  *
31
31
  * Exit codes:
32
32
  * 0 — already in sync, or changes applied (or --dry-run ran cleanly)
33
- * 2 — drift detected under --check, or invalid arguments / missing files
33
+ * 2 — under --check, synchronization requires intervention; also invalid
34
+ * arguments, missing files, and a duplicate-key repair this tool
35
+ * refuses to perform.
36
+ *
37
+ * `--check` has two diagnostic cases and its stderr line already separates
38
+ * them, because the remedies differ: template drift ("drift detected"), and a
39
+ * duplicate-key repair with no drift ("duplicate keys need collapsing"). Both
40
+ * exit 2 — the target needs a write either way, and a green `--check` over a
41
+ * file the strict reader cannot parse would hide the breakage. A caller that
42
+ * needs the distinction reads the message, not the code.
34
43
  *
35
44
  * No behaviour changes vs. the retired Python implementation — historical quirks preserved (consumers pin the exact behaviour).
36
45
  */
@@ -441,11 +450,293 @@ function loadTemplate(p: string, profileValues: Record<string, string>): string
441
450
  return renderTemplate(fs.readFileSync(p, 'utf-8'), profileValues);
442
451
  }
443
452
 
444
- function loadUser(p: string): Record<string, unknown> {
445
- if (!isFile(p)) {
446
- return {};
453
+ /**
454
+ * The comment `mergeIntoTemplate` writes above its appended flat-key block.
455
+ *
456
+ * Duplicated here rather than imported: the writer holds it as a literal in
457
+ * `src/server/io/yamlIO.ts` and exports no constant, and that module belongs
458
+ * to the server tree this CLI does not otherwise depend on. Keep the two in
459
+ * step — a drift makes the sweep below silently stop matching.
460
+ */
461
+ const WIZARD_BLOCK_HEADER = '# Wizard-added keys (no template entry)';
462
+
463
+ /**
464
+ * Drop a wizard-block header the collapse emptied.
465
+ *
466
+ * The non-idempotent writer appended the header AND its keys on every save, so
467
+ * a collapse that removes the later block's key lines leaves that block's
468
+ * header behind with nothing under it — and the next append puts a fresh
469
+ * header below the orphan, one more per save. A header names the keys beneath
470
+ * it; with none beneath it, it names nothing and misleads the next reader.
471
+ *
472
+ * A header counts as emptied only when no key line stands between it and the
473
+ * next header or EOF. Blanks and further comments do not count: a user comment
474
+ * written between the header and its first key is part of the block, not a
475
+ * replacement for it.
476
+ */
477
+ function dropOrphanedWizardHeaders(lines: readonly string[]): string[] {
478
+ const drop = new Set<number>();
479
+ for (let i = 0; i < lines.length; i++) {
480
+ if (lines[i]?.trim() !== WIZARD_BLOCK_HEADER) continue;
481
+ let hasKey = false;
482
+ for (let j = i + 1; j < lines.length; j++) {
483
+ const l = lines[j];
484
+ if (l === undefined) continue;
485
+ if (l.trim() === WIZARD_BLOCK_HEADER) break;
486
+ if (l.trim() === '' || l.trimStart().startsWith('#')) continue;
487
+ hasKey = true;
488
+ break;
489
+ }
490
+ if (hasKey) continue;
491
+ drop.add(i);
492
+ // The writer emits the blank line above the header as part of the block,
493
+ // so removing the header alone widens the gap by one line per repair.
494
+ if (i > 0 && lines[i - 1]?.trim() === '') drop.add(i - 1);
495
+ }
496
+ return drop.size === 0 ? [...lines] : lines.filter((_, i) => !drop.has(i));
497
+ }
498
+
499
+ export interface DuplicateRepair {
500
+ /** The document with every safely-collapsible duplicate run reduced to one. */
501
+ text: string;
502
+ /** Keys that were collapsed, in first-seen order. */
503
+ collapsed: string[];
504
+ /** Duplicated keys this pass refuses to touch, with the reason. */
505
+ unsafe: string[];
506
+ }
507
+
508
+ /**
509
+ * Collapse duplicate TOP-LEVEL inline-scalar keys, keeping the last value.
510
+ *
511
+ * A strict YAML parser rejects a duplicate mapping key outright, so one such
512
+ * pair takes the whole file — and with it `task sync`, `task release-prepare`
513
+ * and every release — out of service with "Map keys must be unique". The
514
+ * duplicates in the wild were written by `mergeIntoTemplate`, whose flat
515
+ * `a.b: value` append was not idempotent before this change: each wizard save
516
+ * re-appended the entire "Wizard-added keys" block. That writer is fixed, but
517
+ * every file it already corrupted stays unreadable until something repairs
518
+ * it, and a release is the worst moment to discover that.
519
+ *
520
+ * Last-wins is value-neutral, not a guess: a lenient reader already resolved
521
+ * such a run that way, so collapsing changes what the file PARSES as in no
522
+ * way — it only changes whether it parses at all.
523
+ *
524
+ * Deliberately narrow, and the narrowness is what makes last-wins safe. A key
525
+ * is collapsible only when EVERY occurrence in the run is ONE-LINE-ONLY — its
526
+ * value sits on the key's own line and it owns no continuation lines at all.
527
+ * Anything else is reported in `unsafe` and left alone, because dropping the
528
+ * loser of a multi-line pair does not drop its body: the body survives, stops
529
+ * being that key's value, and attaches to whatever line precedes it. That
530
+ * turns a parse error into silent data corruption, which is strictly worse.
531
+ *
532
+ * Refused for that reason: a block key with indented children, a block scalar
533
+ * (`|`, `>`), a flow collection opened on one line and closed on another, and
534
+ * an anchor / alias / tag / merge value, whose meaning depends on which
535
+ * occurrence a reader binds rather than only on the value.
536
+ *
537
+ * A multi-document stream (`---` / `...`) is not repaired either. The reader
538
+ * takes a single document and rejects such a file whatever this pass does, so
539
+ * collapsing across a boundary could only merge two documents' keys into one.
540
+ *
541
+ * When — and only when — something did collapse, a wizard-block header the
542
+ * collapse emptied is removed with it; see `dropOrphanedWizardHeaders`.
543
+ */
544
+ export function collapseDuplicateFlatKeys(text: string): DuplicateRepair {
545
+ // Line endings are preserved: splitting on `\n` alone leaves a trailing
546
+ // `\r` on every CRLF line, which the key pattern then never matches — so a
547
+ // CRLF file reported zero duplicates and fell straight into the parse error
548
+ // this pass exists to prevent.
549
+ //
550
+ // The MAJORITY terminator, not "any CRLF present". A mostly-LF file with one
551
+ // stray CRLF line would otherwise be rewritten to CRLF throughout — a whole-
552
+ // file change nobody asked for, on a pass whose entire promise is that it
553
+ // touches only what it must. Matches `sync_yaml_rt.detectEol`.
554
+ const crlfCount = (text.match(/\r\n/g) ?? []).length;
555
+ const lfCount = (text.match(/(^|[^\r])\n/g) ?? []).length;
556
+ const eol = crlfCount > lfCount ? '\r\n' : '\n';
557
+ const lines = text.split(/\r?\n/);
558
+
559
+ // A document separator anywhere means more than one document may be in play.
560
+ if (lines.some((l) => /^(---|\.\.\.)\s*$/.test(l))) {
561
+ return { text, collapsed: [], unsafe: [] };
562
+ }
563
+
564
+ // A mapping key ends at a colon FOLLOWED BY SPACE OR END OF LINE — YAML's
565
+ // own plain-scalar rule. Stopping at the first colon instead reads `a:b: 1`
566
+ // as the key `a`, so a file carrying both `a:b:` and `a:` saw two `a` heads
567
+ // and collapsed them: the `a:b` entry vanished and the result parsed
568
+ // cleanly, so nothing downstream could notice. `sync_yaml_rt`'s own
569
+ // tokeniser already had this right; the two disagreeing was the defect.
570
+ //
571
+ // The value is captured with `[\s\S]` rather than `.`, which does not match
572
+ // a lone `\r`. A line holding one (a value like `"x\ry"`) was not recognised
573
+ // as a head at all, so a duplicate of it stayed invisible and the parse
574
+ // error this pass exists to remove survived untouched.
575
+ const HEAD_RE = /^([A-Za-z_][A-Za-z0-9_.-]*)[ \t]*:(?=[ \t]|$)([\s\S]*)$/;
576
+
577
+ /** Top-level key lines, in order. */
578
+ const heads: { key: string; at: number; rest: string }[] = [];
579
+ for (let i = 0; i < lines.length; i++) {
580
+ const line = lines[i];
581
+ if (line === undefined) continue;
582
+ if (line.trim() === '' || line.trimStart().startsWith('#')) continue;
583
+ // Top level only — an indented `a.b:` is somebody else's child key.
584
+ if (line.length !== line.trimStart().length) continue;
585
+ const m = HEAD_RE.exec(line);
586
+ if (m === null) continue;
587
+ heads.push({ key: m[1] as string, at: i, rest: (m[2] as string).trim() });
588
+ }
589
+
590
+ /**
591
+ * Why this key may NOT be collapsed, or null when it may.
592
+ *
593
+ * Collapsing is safe only for a key that occupies exactly its own line: its
594
+ * value is a plain inline scalar and nothing between here and the next
595
+ * top-level key belongs to it. Everything else keeps its real reason, so the
596
+ * refusal message names what actually blocked it rather than asserting
597
+ * "different children" over a null, an anchor or a block scalar.
598
+ */
599
+ const blocker = (h: { at: number; rest: string }, nextAt: number): string | null => {
600
+ const v = h.rest;
601
+ if (v === '' || v.startsWith('#')) return 'a block key or a null value';
602
+ if (/^[|>]/.test(v)) return 'a block scalar';
603
+ // An anchor, alias or tag ANYWHERE in the value, not merely at its start:
604
+ // `a: [&x 1]` fits on one line, and dropping it deletes an anchor that an
605
+ // alias on some other line binds to — turning a duplicate-key error into
606
+ // an unresolved-alias error. Token position only, so `a&b` in a plain
607
+ // scalar is left alone.
608
+ if (/(^|[\s[{,])[&*!]/.test(v)) return 'an anchor, alias or tag';
609
+ // A flow collection must open and close on this line.
610
+ const opens = (v.match(/[[{]/g) ?? []).length;
611
+ const closes = (v.match(/[\]}]/g) ?? []).length;
612
+ if (opens !== closes) return 'a flow collection spanning lines';
613
+ for (let i = h.at + 1; i < nextAt; i++) {
614
+ const line = lines[i];
615
+ if (line === undefined) continue;
616
+ if (line.trim() === '') continue;
617
+ if (line.trimStart().startsWith('#')) continue;
618
+ return 'a value spanning more than its own line';
619
+ }
620
+ return null;
621
+ };
622
+
623
+ const solo = new Set<number>();
624
+ const why = new Map<number, string>();
625
+ for (let n = 0; n < heads.length; n++) {
626
+ const h = heads[n] as { key: string; at: number; rest: string };
627
+ const nextAt = n + 1 < heads.length ? (heads[n + 1] as { at: number }).at : lines.length;
628
+ const reason = blocker(h, nextAt);
629
+ if (reason === null) solo.add(h.at);
630
+ else why.set(h.at, reason);
447
631
  }
448
- const data = parseYaml(fs.readFileSync(p, 'utf-8'), { version: '1.1' });
632
+
633
+ const seen = new Map<string, number[]>();
634
+ for (const h of heads) {
635
+ const at = seen.get(h.key);
636
+ if (at === undefined) seen.set(h.key, [h.at]);
637
+ else at.push(h.at);
638
+ }
639
+
640
+ const collapsed: string[] = [];
641
+ const unsafe: string[] = [];
642
+ const drop = new Set<number>();
643
+ for (const [key, hits] of seen) {
644
+ if (hits.length < 2) continue;
645
+ if (!hits.every((i) => solo.has(i))) {
646
+ const reason = hits.map((i) => why.get(i)).find((r) => r !== undefined) ?? 'not a plain one-line value';
647
+ unsafe.push(`${key} — ${reason}`);
648
+ continue;
649
+ }
650
+ collapsed.push(key);
651
+ // Keep the LAST occurrence's value at the FIRST occurrence's position, so
652
+ // the surrounding comments stay attached to the line they document.
653
+ lines[hits[0] as number] = lines[hits[hits.length - 1] as number] as string;
654
+ for (let i = 1; i < hits.length; i++) drop.add(hits[i] as number);
655
+ }
656
+
657
+ // Duplicates this pass cannot even SEE, reported rather than skipped.
658
+ //
659
+ // `HEAD_RE` recognises the key shapes the repair understands. A key starting
660
+ // with a digit (`2fa.on`) or a quoted key (`"a:b"`) matches nothing, so a
661
+ // file duplicating one used to come back with zero collapses AND zero
662
+ // refusals — and then died on the strict parse with the same opaque "Map keys
663
+ // must be unique" the whole repair exists to remove, giving the operator no
664
+ // hint that their key was the part being skipped. Shipping a repair pass
665
+ // creates the expectation that it either fixes the file or says why it
666
+ // cannot; silence is neither.
667
+ //
668
+ // Detection only. These keys are never collapsed — the shapes are exactly the
669
+ // ones whose tokenisation this pass does not model, which is why it declines
670
+ // to rewrite them.
671
+ const loose = new Map<string, number>();
672
+ for (let i = 0; i < lines.length; i++) {
673
+ const line = lines[i];
674
+ if (line === undefined) continue;
675
+ if (line.trim() === '' || line.trimStart().startsWith('#')) continue;
676
+ if (line.length !== line.trimStart().length) continue;
677
+ if (HEAD_RE.test(line)) continue;
678
+ const m = /^("[^"]*"|'[^']*'|[^\s:#][^:]*?)[ \t]*:(?=[ \t]|$)/.exec(line);
679
+ if (m === null) continue;
680
+ const key = m[1] as string;
681
+ loose.set(key, (loose.get(key) ?? 0) + 1);
682
+ }
683
+ for (const [key, count] of loose) {
684
+ if (count < 2) continue;
685
+ unsafe.push(`${key} — a key shape this repair does not model (quoted, or not starting with a letter)`);
686
+ }
687
+
688
+ if (collapsed.length === 0) {
689
+ return { text, collapsed, unsafe };
690
+ }
691
+ const kept = dropOrphanedWizardHeaders(lines.filter((_, i) => !drop.has(i)));
692
+ return { text: kept.join(eol), collapsed, unsafe };
693
+ }
694
+
695
+ /**
696
+ * The parse error an input still carries once its duplicate keys are excused,
697
+ * or null when the duplicates were its only problem.
698
+ *
699
+ * `uniqueKeys: false` is what excuses them: the duplicate-key rejection is the
700
+ * single error the collapse has a mandate to remove, so anything the parser
701
+ * still raises is an error the collapse was never licensed to touch.
702
+ */
703
+ function residualParseError(text: string): Error | null {
704
+ try {
705
+ parseYaml(text, { version: '1.1', uniqueKeys: false });
706
+ return null;
707
+ } catch (err) {
708
+ return err instanceof Error ? err : new Error(String(err));
709
+ }
710
+ }
711
+
712
+ /**
713
+ * What the parser reliably exposes about a failure, as one indented block.
714
+ *
715
+ * Available on every `YAMLParseError` observed from this parser: `message`,
716
+ * whose first line already carries `at line L, column C` plus the detail, and
717
+ * `code`, a stable identifier. `linePos` is populated too, but only while
718
+ * `prettyErrors` stays on (the library's own condition), so it is printed when
719
+ * present and never relied on. Nothing here is asserted beyond the parser's
720
+ * own first message line, which is derived in the test rather than hardcoded —
721
+ * pinning a format this module does not own would make a safety test fail on a
722
+ * dependency's wording change.
723
+ */
724
+ function formatParserDetail(err: Error): string {
725
+ const first = err.message.split('\n')[0] ?? err.message;
726
+ const parts: string[] = [` ${first}`];
727
+ const code = (err as { code?: unknown }).code;
728
+ const linePos = (err as { linePos?: { line: number; col: number }[] }).linePos;
729
+ const at = linePos?.[0];
730
+ if (typeof code === 'string' && at !== undefined) {
731
+ parts.push(` (${code} at line ${at.line}, column ${at.col})`);
732
+ } else if (typeof code === 'string') {
733
+ parts.push(` (${code})`);
734
+ }
735
+ return parts.join('\n') + '\n';
736
+ }
737
+
738
+ function loadUserText(raw: string): Record<string, unknown> {
739
+ const data = parseYaml(raw, { version: '1.1' });
449
740
  if (data === null || data === undefined) {
450
741
  return {};
451
742
  }
@@ -655,10 +946,82 @@ export function main(argv: readonly string[] = process.argv.slice(2)): number {
655
946
  const templatePath = args.template;
656
947
  const profileDir = args.profile_dir;
657
948
 
949
+ // Repair BEFORE the first parse. A duplicate mapping key makes the whole
950
+ // file unreadable, so without this the run dies here and takes the release
951
+ // with it — see `collapseDuplicateFlatKeys` for why last-wins is safe.
952
+ const rawText = isFile(target) ? fs.readFileSync(target, 'utf-8') : '';
953
+ const repair = collapseDuplicateFlatKeys(rawText);
954
+ if (repair.unsafe.length > 0) {
955
+ // Each entry carries the reason that key was refused. A single blanket
956
+ // sentence used to claim "different children" for every refusal — over a
957
+ // null value, a block scalar or an anchor that has none — which sends the
958
+ // reader looking for children to merge that are not there.
959
+ process.stderr.write(
960
+ `error: ${target} has duplicate mapping keys this tool will not collapse:\n` +
961
+ repair.unsafe.map((u) => ` - ${u}\n`).join('') +
962
+ `Keeping one occurrence would change what the file means. Merge them by hand, then re-run.\n`,
963
+ );
964
+ return 2;
965
+ }
966
+ if (repair.collapsed.length > 0) {
967
+ // Refuse before anything else in this branch, including the notice below:
968
+ // in write mode that notice is past tense ("collapsed …"), so announcing
969
+ // it and then refusing describes a write that never happened.
970
+ //
971
+ // The collapse's safety rests on preserving the original's last-wins
972
+ // reading, and a document that is invalid for some FURTHER reason has no
973
+ // reading to preserve — the pass can then emit valid YAML carrying
974
+ // structure nobody authored, which every downstream check accepts. A
975
+ // stderr warning (what this branch used to do) is a weak control against a
976
+ // silent outcome; a refusal is loud and the operator can still recover.
977
+ // AI council, 2026-09-11, 2 of 2 seats, converged — including a rejection
978
+ // of any `--repair-anyway` escape: an operator who understands the file
979
+ // well enough to use it understands it well enough to fix the error first,
980
+ // and "read the diff" is not a trustworthy oracle for YAML semantics.
981
+ //
982
+ // Exit 2, per the taxonomy in this file's header: 2 is "this tool cannot
983
+ // proceed with this input", which is also what the sibling refusal above
984
+ // (duplicates it will not collapse) returns. 1 is spoken for — it is the
985
+ // mirrored `install.fail` exit and means a broken install asset.
986
+ //
987
+ // Nothing durable precedes this point: the only write in `main` is the
988
+ // single `writeFileSync` at the end, there is no temporary file and no
989
+ // rename, so the refusal leaves the target byte-for-byte unchanged.
990
+ const residual = residualParseError(rawText);
991
+ if (residual !== null) {
992
+ process.stderr.write(
993
+ `❌ ${target}: refusing the automatic duplicate repair — the file has ` +
994
+ `another YAML error besides its duplicate keys.\n` +
995
+ formatParserDetail(residual) +
996
+ ` Collapsing changes only WHETHER a file parses, never what it parses as, ` +
997
+ `and that promise is empty over a document with no valid reading.\n` +
998
+ ` Fix the syntax error by hand, then re-run to apply the duplicate repair.\n`,
999
+ );
1000
+ return 2;
1001
+ }
1002
+
1003
+ // NOT gated on --quiet, and not on stdout. Both callers that matter run
1004
+ // quiet — the release's `sync-agent-settings` step and the pre-release
1005
+ // probe — so gating this would let a release rewrite the operator's own
1006
+ // settings file with no trace. `--quiet` suppresses routine success
1007
+ // chatter; "I modified your file" is not that.
1008
+ //
1009
+ // The tense follows the mode. `--check` and `--dry-run` never write, so
1010
+ // announcing a completed collapse there describes a write that did not
1011
+ // happen — and the pre-release probe runs `--dry-run`, which made that the
1012
+ // FIRST thing an operator saw on every release with a corrupted file.
1013
+ const writes = !args.check && !args.dry_run;
1014
+ const verb = writes
1015
+ ? `collapsed ${repair.collapsed.length} duplicate key(s), last value kept`
1016
+ : `would collapse ${repair.collapsed.length} duplicate key(s), keeping the last value (no write in this mode)`;
1017
+ process.stderr.write(`🔧 ${target}: ${verb} — ${repair.collapsed.join(', ')}\n`);
1018
+ }
1019
+ const sourceText = repair.text;
1020
+
658
1021
  let profile: string;
659
1022
  let templateBody: string;
660
1023
  try {
661
- const userData = loadUser(target);
1024
+ const userData = loadUserText(sourceText);
662
1025
  const personalRaw = userData['personal'];
663
1026
  const personal =
664
1027
  personalRaw !== null && typeof personalRaw === 'object' && !Array.isArray(personalRaw)
@@ -706,7 +1069,12 @@ export function main(argv: readonly string[] = process.argv.slice(2)): number {
706
1069
  throw err;
707
1070
  }
708
1071
 
709
- const existingText = isFile(target) ? fs.readFileSync(target, 'utf-8') : '';
1072
+ // The merge reads the REPAIRED text; every "did anything change" decision
1073
+ // below compares against `rawText`, what is actually on disk. Comparing
1074
+ // against the repaired text instead would report "already in sync" on a
1075
+ // file whose collapse never reached disk — the repair would run on every
1076
+ // invocation and fix nothing.
1077
+ const existingText = sourceText;
710
1078
 
711
1079
  let newText: string;
712
1080
  if (existingText) {
@@ -724,7 +1092,7 @@ export function main(argv: readonly string[] = process.argv.slice(2)): number {
724
1092
  newText = templateBody;
725
1093
  }
726
1094
 
727
- if (newText === existingText) {
1095
+ if (newText === rawText) {
728
1096
  if (!args.quiet) {
729
1097
  process.stdout.write(`✅ ${target}: already in sync (profile=${profile})\n`);
730
1098
  }
@@ -732,14 +1100,28 @@ export function main(argv: readonly string[] = process.argv.slice(2)): number {
732
1100
  }
733
1101
 
734
1102
  if (args.check) {
735
- const diff = renderDiff(existingText, newText, String(target));
1103
+ const diff = renderDiff(rawText, newText, String(target));
736
1104
  process.stdout.write(diff);
737
- process.stderr.write(`\n❌ ${target}: drift detected (profile=${profile})\n`);
1105
+ // Name WHICH problem, because the two have different remedies and a CI job
1106
+ // reading only "drift detected" cannot tell them apart. A repair-only diff
1107
+ // means the file is corrupt, not out of step with the template; the
1108
+ // discriminator is whether the merge changed anything beyond the collapse.
1109
+ //
1110
+ // Still exit 2 in both cases: the file needs a write either way, and a
1111
+ // `--check` that returned 0 over a file the reader cannot parse would hide
1112
+ // exactly the breakage this whole change exists to surface.
1113
+ const repairOnly = repair.collapsed.length > 0 && newText === sourceText;
1114
+ process.stderr.write(
1115
+ repairOnly
1116
+ ? `\n❌ ${target}: duplicate keys need collapsing — no template drift (profile=${profile})\n` +
1117
+ ` Run \`sync_agent_settings\` without --check to apply the repair.\n`
1118
+ : `\n❌ ${target}: drift detected (profile=${profile})\n`,
1119
+ );
738
1120
  return 2;
739
1121
  }
740
1122
 
741
1123
  if (args.dry_run) {
742
- const diff = renderDiff(existingText, newText, String(target));
1124
+ const diff = renderDiff(rawText, newText, String(target));
743
1125
  process.stdout.write(diff);
744
1126
  if (!args.quiet) {
745
1127
  process.stderr.write(`\n(dry-run) would update ${target} (profile=${profile})\n`);