@event4u/agent-config 16.3.0 → 16.5.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 (532) 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 +178 -78
  5. package/README.md +2 -2
  6. package/agents/templates/.ai-council.yml.example +26 -8
  7. package/dist/agent-src/commands/analyze/inbox.md +10 -7
  8. package/dist/agent-src/commands/bug/investigate.md +1 -1
  9. package/dist/agent-src/commands/commit/in-chunks.md +40 -31
  10. package/dist/agent-src/commands/commit.md +72 -33
  11. package/dist/agent-src/commands/condense.md +2 -8
  12. package/dist/agent-src/commands/council/debate.md +11 -7
  13. package/dist/agent-src/commands/council/default.md +10 -9
  14. package/dist/agent-src/commands/council.md +1 -1
  15. package/dist/agent-src/commands/design.md +1 -1
  16. package/dist/agent-src/commands/estimate-ticket.md +1 -1
  17. package/dist/agent-src/commands/feature/explore.md +3 -3
  18. package/dist/agent-src/commands/feature/plan.md +1 -1
  19. package/dist/agent-src/commands/fix/ci.md +17 -3
  20. package/dist/agent-src/commands/fix/commit-messages.md +48 -23
  21. package/dist/agent-src/commands/fix/pr-comments.md +3 -6
  22. package/dist/agent-src/commands/implement-ticket.md +3 -3
  23. package/dist/agent-src/commands/memory/add.md +4 -16
  24. package/dist/agent-src/commands/memory/load.md +5 -6
  25. package/dist/agent-src/commands/memory/promote.md +3 -16
  26. package/dist/agent-src/commands/mission/upgrade.md +3 -2
  27. package/dist/agent-src/commands/optimize/agents-dir.md +2 -2
  28. package/dist/agent-src/commands/optimize/deep.md +4 -2
  29. package/dist/agent-src/commands/optimize/rtk.md +4 -26
  30. package/dist/agent-src/commands/pr/create/description-only.md +18 -15
  31. package/dist/agent-src/commands/pr/create.md +42 -34
  32. package/dist/agent-src/commands/pr/merge.md +136 -9
  33. package/dist/agent-src/commands/prepare-for-review.md +13 -11
  34. package/dist/agent-src/commands/project/analyze.md +7 -35
  35. package/dist/agent-src/commands/refine-ticket.md +1 -1
  36. package/dist/agent-src/commands/review/changes.md +14 -19
  37. package/dist/agent-src/commands/roadmap/next.md +10 -1
  38. package/dist/agent-src/commands/roadmap/process-full.md +52 -38
  39. package/dist/agent-src/commands/roadmap/resolve-blockers.md +64 -14
  40. package/dist/agent-src/commands/worktree/create.md +7 -3
  41. package/dist/agent-src/commands/worktree/verify.md +2 -1
  42. package/dist/agent-src/contexts/communication/rules-auto/think-before-action-mechanics.md +5 -3
  43. package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +7 -9
  44. package/dist/agent-src/contexts/contracts/command-suggestion-flow.md +8 -6
  45. package/dist/agent-src/contexts/contracts/frugality-charter.md +8 -5
  46. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +1 -1
  47. package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +0 -1
  48. package/dist/agent-src/contexts/execution/evidence-discipline.md +2 -2
  49. package/dist/agent-src/contexts/execution/non-interactive-contract.md +5 -8
  50. package/dist/agent-src/contexts/execution/rdp-gate.md +4 -4
  51. package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +9 -8
  52. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +67 -52
  53. package/dist/agent-src/contexts/execution/subagent-routing.md +8 -8
  54. package/dist/agent-src/contexts/execution/subagent-steering.md +6 -4
  55. package/dist/agent-src/contexts/execution/terminal-states.md +2 -2
  56. package/dist/agent-src/contexts/execution/toolchain-resolver.md +4 -10
  57. package/dist/agent-src/contexts/subagent-configuration.md +1 -1
  58. package/dist/agent-src/guidelines/agent-infra/active-remediation-mechanics.md +39 -0
  59. package/dist/agent-src/guidelines/agent-infra/context-hygiene-mechanics.md +1 -1
  60. package/dist/agent-src/guidelines/agent-infra/cross-source-consistency-mechanics.md +8 -10
  61. package/dist/agent-src/guidelines/agent-infra/frontier-reasoning-operating-profile.md +3 -2
  62. package/dist/agent-src/guidelines/agent-infra/layered-settings.md +13 -1
  63. package/dist/agent-src/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
  64. package/dist/agent-src/guidelines/agent-infra/self-improvement-pipeline.md +10 -3
  65. package/dist/agent-src/guidelines/agent-infra/size-and-scope.md +36 -0
  66. package/dist/agent-src/guidelines/design-antipatterns.md +1 -1
  67. package/dist/agent-src/guidelines/php/git.md +15 -2
  68. package/dist/agent-src/rules/active-remediation.md +0 -1
  69. package/dist/agent-src/rules/analysis-skill-routing.md +0 -1
  70. package/dist/agent-src/rules/architecture.md +0 -1
  71. package/dist/agent-src/rules/artifact-drafting-protocol.md +0 -1
  72. package/dist/agent-src/rules/artifact-engagement-recording.md +0 -1
  73. package/dist/agent-src/rules/augment-edit-discipline.md +0 -1
  74. package/dist/agent-src/rules/autonomous-execution.md +0 -1
  75. package/dist/agent-src/rules/brand-consistency.md +0 -1
  76. package/dist/agent-src/rules/brand-source-of-truth.md +0 -1
  77. package/dist/agent-src/rules/broken-access-control.md +0 -1
  78. package/dist/agent-src/rules/cli-output-handling.md +0 -1
  79. package/dist/agent-src/rules/code-comment-discipline.md +0 -1
  80. package/dist/agent-src/rules/code-provenance.md +0 -1
  81. package/dist/agent-src/rules/command-suggestion-policy.md +0 -1
  82. package/dist/agent-src/rules/commit-conventions.md +1 -2
  83. package/dist/agent-src/rules/communication-through-line.md +1 -2
  84. package/dist/agent-src/rules/content-quoting-floor.md +1 -2
  85. package/dist/agent-src/rules/context-hygiene.md +5 -5
  86. package/dist/agent-src/rules/copilot-routing.md +1 -2
  87. package/dist/agent-src/rules/council-availability.md +4 -4
  88. package/dist/agent-src/rules/cross-source-consistency.md +4 -6
  89. package/dist/agent-src/rules/decision-revisit-gate.md +2 -3
  90. package/dist/agent-src/rules/delegation-policy.md +2 -3
  91. package/dist/agent-src/rules/design-fidelity.md +0 -1
  92. package/dist/agent-src/rules/design-review-after-ui-write.md +3 -3
  93. package/dist/agent-src/rules/devcontainer-routing.md +1 -2
  94. package/dist/agent-src/rules/doc-screenshot-hygiene.md +0 -1
  95. package/dist/agent-src/rules/docker-commands.md +0 -1
  96. package/dist/agent-src/rules/domain-adoption-policy.md +0 -1
  97. package/dist/agent-src/rules/domain-safety-disclaimer.md +0 -1
  98. package/dist/agent-src/rules/domain-safety-pii.md +0 -1
  99. package/dist/agent-src/rules/domain-safety-retention.md +0 -1
  100. package/dist/agent-src/rules/downstream-changes.md +0 -1
  101. package/dist/agent-src/rules/engineering-safety-floor.md +0 -1
  102. package/dist/agent-src/rules/external-code-graph-interop.md +0 -1
  103. package/dist/agent-src/rules/external-reference-deep-dive.md +0 -1
  104. package/dist/agent-src/rules/fast-path-marker-visibility.md +1 -2
  105. package/dist/agent-src/rules/finance-safety-floor.md +0 -1
  106. package/dist/agent-src/rules/fix-what-you-see.md +6 -32
  107. package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +0 -1
  108. package/dist/agent-src/rules/git-history-discipline.md +1 -2
  109. package/dist/agent-src/rules/guidelines.md +0 -1
  110. package/dist/agent-src/rules/history-discipline.md +0 -1
  111. package/dist/agent-src/rules/icon-consistency.md +0 -1
  112. package/dist/agent-src/rules/image-likeness-and-rights.md +0 -1
  113. package/dist/agent-src/rules/improve-before-implement.md +0 -1
  114. package/dist/agent-src/rules/invite-challenge.md +0 -1
  115. package/dist/agent-src/rules/laravel-routing.md +1 -2
  116. package/dist/agent-src/rules/laravel-translations.md +0 -1
  117. package/dist/agent-src/rules/legal-safety-floor.md +0 -1
  118. package/dist/agent-src/rules/lethal-trifecta-guard.md +0 -1
  119. package/dist/agent-src/rules/linked-projects-onboarding-gate.md +0 -1
  120. package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +0 -1
  121. package/dist/agent-src/rules/markdown-safe-codeblocks.md +0 -1
  122. package/dist/agent-src/rules/media-governance-routing.md +1 -2
  123. package/dist/agent-src/rules/media-sync-ground-truth.md +0 -1
  124. package/dist/agent-src/rules/minimal-safe-diff.md +0 -1
  125. package/dist/agent-src/rules/missing-skill-recovery.md +0 -1
  126. package/dist/agent-src/rules/missing-tool-handling.md +0 -1
  127. package/dist/agent-src/rules/model-recommendation.md +0 -1
  128. package/dist/agent-src/rules/neighbour-precedence.md +64 -0
  129. package/dist/agent-src/rules/no-attribution-footers.md +0 -1
  130. package/dist/agent-src/rules/no-decorative-emojis-in-git-surfaces.md +0 -1
  131. package/dist/agent-src/rules/no-pr-progress-comments.md +0 -1
  132. package/dist/agent-src/rules/no-roadmap-references.md +0 -1
  133. package/dist/agent-src/rules/notes-first-reasoning.md +0 -1
  134. package/dist/agent-src/rules/onboarding-gate.md +0 -1
  135. package/dist/agent-src/rules/output-discipline.md +0 -1
  136. package/dist/agent-src/rules/package-ci-checks.md +0 -1
  137. package/dist/agent-src/rules/persona-governance.md +2 -3
  138. package/dist/agent-src/rules/php-coding.md +0 -1
  139. package/dist/agent-src/rules/prefer-enums-over-literals.md +0 -1
  140. package/dist/agent-src/rules/preservation-guard.md +0 -1
  141. package/dist/agent-src/rules/provider-lifecycle-discipline.md +2 -3
  142. package/dist/agent-src/rules/question-not-instruction.md +0 -1
  143. package/dist/agent-src/rules/reviewer-awareness.md +0 -1
  144. package/dist/agent-src/rules/roadmap-ci-steps-policy.md +0 -1
  145. package/dist/agent-src/rules/roadmap-progress-sync.md +3 -6
  146. package/dist/agent-src/rules/role-mode-adherence.md +0 -1
  147. package/dist/agent-src/rules/rule-type-governance.md +0 -1
  148. package/dist/agent-src/rules/runtime-safety.md +0 -1
  149. package/dist/agent-src/rules/scale-discipline.md +0 -1
  150. package/dist/agent-src/rules/secret-vcs-guard.md +0 -1
  151. package/dist/agent-src/rules/security-sensitive-stop.md +0 -1
  152. package/dist/agent-src/rules/self-repair-loop.md +0 -1
  153. package/dist/agent-src/rules/senior-engineering-discipline.md +0 -1
  154. package/dist/agent-src/rules/session-canary.md +0 -1
  155. package/dist/agent-src/rules/settings-ask-protocol.md +5 -6
  156. package/dist/agent-src/rules/size-enforcement.md +0 -1
  157. package/dist/agent-src/rules/skill-improvement-trigger.md +2 -3
  158. package/dist/agent-src/rules/skill-quality.md +0 -1
  159. package/dist/agent-src/rules/slash-command-routing-policy.md +0 -1
  160. package/dist/agent-src/rules/source-confidentiality.md +0 -1
  161. package/dist/agent-src/rules/source-discovery-gate.md +0 -1
  162. package/dist/agent-src/rules/source-of-truth.md +0 -1
  163. package/dist/agent-src/rules/spreadsheet-source-quality.md +1 -2
  164. package/dist/agent-src/rules/strategy-safety-floor.md +0 -1
  165. package/dist/agent-src/rules/symfony-routing.md +1 -2
  166. package/dist/agent-src/rules/think-before-action.md +0 -1
  167. package/dist/agent-src/rules/token-budget-discipline.md +14 -48
  168. package/dist/agent-src/rules/token-efficiency.md +0 -1
  169. package/dist/agent-src/rules/token-optimizer-maintenance.md +0 -1
  170. package/dist/agent-src/rules/tool-safety.md +0 -1
  171. package/dist/agent-src/rules/ui-audit-gate.md +1 -2
  172. package/dist/agent-src/rules/untrusted-input-defense.md +0 -1
  173. package/dist/agent-src/rules/upstream-proposal.md +0 -1
  174. package/dist/agent-src/rules/user-interaction.md +0 -1
  175. package/dist/agent-src/rules/user-interrupt-priority.md +0 -1
  176. package/dist/agent-src/scripts/gate_budget.ts +47 -23
  177. package/dist/agent-src/scripts/gate_execute.ts +12 -4
  178. package/dist/agent-src/skills/accessibility-auditor/data/aria-patterns.csv +2 -0
  179. package/dist/agent-src/skills/accessibility-auditor/data/manifest.json +3 -3
  180. package/dist/agent-src/skills/ai-council/SKILL.md +7 -4
  181. package/dist/agent-src/skills/ai-council/references/cost-and-redaction.md +21 -11
  182. package/dist/agent-src/skills/ai-council/references/procedure.md +12 -6
  183. package/dist/agent-src/skills/analysis-autonomous-mode/SKILL.md +1 -1
  184. package/dist/agent-src/skills/bug-analyzer/SKILL.md +1 -1
  185. package/dist/agent-src/skills/canvas-design/SKILL.md +4 -2
  186. package/dist/agent-src/skills/command-routing/SKILL.md +3 -4
  187. package/dist/agent-src/skills/conventional-commits-writing/SKILL.md +127 -139
  188. package/dist/agent-src/skills/corpus-grounding/ATTRIBUTION.md +39 -0
  189. package/dist/agent-src/skills/corpus-grounding/SKILL.md +8 -2
  190. package/dist/agent-src/skills/database/data/manifest.json +2 -2
  191. package/dist/agent-src/skills/database/data/query-tuning.csv +13 -13
  192. package/dist/agent-src/skills/design-intelligence/references/integration-mapping.md +13 -10
  193. package/dist/agent-src/skills/design-system-capture/SKILL.md +0 -3
  194. package/dist/agent-src/skills/estimate-ticket/SKILL.md +1 -1
  195. package/dist/agent-src/skills/fe-design/references/design-patterns.md +49 -2
  196. package/dist/agent-src/skills/feature-planning/SKILL.md +1 -1
  197. package/dist/agent-src/skills/frontend-render-security/SKILL.md +9 -0
  198. package/dist/agent-src/skills/git-workflow/SKILL.md +44 -44
  199. package/dist/agent-src/skills/git-workflow/references/branch-update.md +312 -0
  200. package/dist/agent-src/skills/git-workflow/references/commit-subject.md +205 -0
  201. package/dist/agent-src/skills/iconography/SKILL.md +4 -2
  202. package/dist/agent-src/skills/image-provider-routing/SKILL.md +16 -5
  203. package/dist/agent-src/skills/jira-integration/SKILL.md +3 -3
  204. package/dist/agent-src/skills/logo-generation/SKILL.md +12 -8
  205. package/dist/agent-src/skills/merge-conflicts/SKILL.md +10 -4
  206. package/dist/agent-src/skills/po-discovery/SKILL.md +1 -1
  207. package/dist/agent-src/skills/refine-ticket/SKILL.md +4 -4
  208. package/dist/agent-src/skills/roadmap-writing/SKILL.md +2 -2
  209. package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +4 -2
  210. package/dist/agent-src/skills/source-discovery/SKILL.md +1 -1
  211. package/dist/agent-src/skills/svg-authoring/SKILL.md +318 -0
  212. package/dist/agent-src/skills/tailwind-engineer/SKILL.md +3 -1
  213. package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
  214. package/dist/agent-src/skills/using-git-worktrees/SKILL.md +1 -1
  215. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +2 -2
  216. package/dist/agent-src/skills/wireframe/SKILL.md +5 -2
  217. package/dist/agent-src/templates/AGENTS.md +1 -1
  218. package/dist/agent-src/templates/agent-settings.md +46 -129
  219. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +3 -3
  220. package/dist/agent-src/templates/command.md +2 -2
  221. package/dist/agent-src/templates/roadmaps.md +6 -1
  222. package/dist/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +0 -6
  223. package/dist/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +11 -7
  224. package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/decision_trace.ts +3 -2
  225. package/dist/agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.ts +2 -1
  226. package/dist/agent-src/templates/scripts/work_engine/hooks/settings.ts +0 -6
  227. package/dist/agent-src/templates/scripts/work_engine/scoring/decision_engine.ts +9 -12
  228. package/dist/agent-src/templates/scripts/work_engine/scoring/memory_visibility.ts +2 -1
  229. package/dist/agent-src/templates/skill.md +1 -1
  230. package/dist/cli/commands/uiRender.js +201 -4
  231. package/dist/cli/commands/uiRenderAsset.js +1308 -0
  232. package/dist/cli/commands/uiRenderAssetCompare.js +752 -0
  233. package/dist/cli/commands/uiRenderAssetGrid.js +265 -0
  234. package/dist/cli/commands/uiRenderAssetGrounds.js +323 -0
  235. package/dist/cli/commands/uiRenderAssetIsolation.js +85 -0
  236. package/dist/cli/commands/uiRenderAssetTypes.js +145 -0
  237. package/dist/cli/main.js +47 -1
  238. package/dist/cli/registry.js +2 -1
  239. package/dist/cli-delegate/check_update_banner.js +195 -119
  240. package/dist/cli-delegate/{chunk-S4UMZNES.js → chunk-4DBG5K7M.js} +5 -5
  241. package/dist/cli-delegate/{chunk-TRI6DQZ6.js → chunk-5GPULQBE.js} +60 -42
  242. package/dist/cli-delegate/{chunk-JQVYKIZA.js → chunk-6SRJTYJS.js} +33 -177
  243. package/dist/cli-delegate/chunk-6V5FMA3P.js +186 -0
  244. package/dist/cli-delegate/chunk-6YQC2HLF.js +415 -0
  245. package/dist/cli-delegate/{chunk-E4XIZDIB.js → chunk-7HKRE54K.js} +1 -64
  246. package/dist/cli-delegate/{chunk-7HQ52DHU.js → chunk-AL3RZ22D.js} +1 -1
  247. package/dist/cli-delegate/{chunk-DBH4AHDK.js → chunk-ED7KCMLB.js} +9 -11
  248. package/dist/cli-delegate/{chunk-NXEILF2K.js → chunk-F3QDG2GT.js} +481 -72
  249. package/dist/cli-delegate/{chunk-CQWX336L.js → chunk-G5VVIZRC.js} +3 -3
  250. package/dist/cli-delegate/{chunk-JY2I2DXV.js → chunk-H76PHZBI.js} +137 -60
  251. package/dist/cli-delegate/chunk-IAYTIIQW.js +67 -0
  252. package/dist/cli-delegate/{chunk-LIYTLH6O.js → chunk-KXXWJTDO.js} +5 -10
  253. package/dist/cli-delegate/{chunk-T7L2QK3K.js → chunk-LQOCRFWT.js} +1 -1
  254. package/dist/cli-delegate/{chunk-S4YWNRKO.js → chunk-MDPPKQCQ.js} +34 -1
  255. package/dist/cli-delegate/chunk-OAFSJBHH.js +272 -0
  256. package/dist/cli-delegate/{chunk-GKE7ZVFA.js → chunk-PWX7CKMD.js} +1 -1
  257. package/dist/cli-delegate/{chunk-NDJLNC6Q.js → chunk-T6BP34WI.js} +1 -0
  258. package/dist/cli-delegate/{chunk-RQNNW7IF.js → chunk-T7XSJSUQ.js} +433 -632
  259. package/dist/cli-delegate/{chunk-NQ7WT43P.js → chunk-TMWYUOK4.js} +75 -12
  260. package/dist/cli-delegate/{chunk-EEHDXSYD.js → chunk-WQWXGIWB.js} +12 -273
  261. package/dist/cli-delegate/{chunk-QLDHIPWR.js → chunk-XQTPXKFA.js} +1 -1
  262. package/dist/cli-delegate/cmd_analyze_session.js +223 -43
  263. package/dist/cli-delegate/cmd_brand_status.js +3 -2
  264. package/dist/cli-delegate/cmd_conformance.js +489 -238
  265. package/dist/cli-delegate/cmd_converge.js +3 -3
  266. package/dist/cli-delegate/cmd_doctor.js +15 -12
  267. package/dist/cli-delegate/cmd_doctor_neighbours.js +11 -4
  268. package/dist/cli-delegate/cmd_explain.js +43 -19
  269. package/dist/cli-delegate/cmd_export.js +10 -10
  270. package/dist/cli-delegate/cmd_git_convention.js +1851 -0
  271. package/dist/cli-delegate/cmd_handoff.js +40 -21
  272. package/dist/cli-delegate/cmd_mcp_available.js +3 -2
  273. package/dist/cli-delegate/cmd_migrate.js +3 -3
  274. package/dist/cli-delegate/cmd_packs_active.js +4 -3
  275. package/dist/cli-delegate/cmd_prune.js +10 -10
  276. package/dist/cli-delegate/cmd_route_audit.js +7 -7
  277. package/dist/cli-delegate/cmd_route_explain.js +5 -5
  278. package/dist/cli-delegate/cmd_session_recycle.js +9 -7
  279. package/dist/cli-delegate/cmd_settings_check.js +54 -7
  280. package/dist/cli-delegate/cmd_settings_get.js +18 -8
  281. package/dist/cli-delegate/cmd_settings_migrate.js +10 -10
  282. package/dist/cli-delegate/cmd_settings_set.js +1 -1
  283. package/dist/cli-delegate/cmd_sync.js +10 -10
  284. package/dist/cli-delegate/cmd_uninstall.js +10 -10
  285. package/dist/cli-delegate/cmd_update.js +7 -7
  286. package/dist/cli-delegate/cmd_upgrade.js +7 -7
  287. package/dist/cli-delegate/cmd_validate.js +10 -10
  288. package/dist/cli-delegate/cmd_versions.js +5 -5
  289. package/dist/cli-delegate/gate_budget.js +1 -1
  290. package/dist/cli-delegate/gate_execute.js +2 -2
  291. package/dist/cli-delegate/roadmap_gates.js +2 -2
  292. package/dist/discovery/deprecation-report.md +1 -1
  293. package/dist/discovery/discovery-manifest.json +171 -107
  294. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  295. package/dist/discovery/discovery-manifest.summary.md +7 -7
  296. package/dist/discovery/dormancy-report.md +1 -1
  297. package/dist/discovery/orphan-report.md +1 -1
  298. package/dist/discovery/packs.json +41 -22
  299. package/dist/discovery/trust-report.md +3 -3
  300. package/dist/discovery/workspaces.json +16 -11
  301. package/dist/hooks/dispatch.js +2520 -1924
  302. package/dist/hooks/dispatch.sha256 +1 -1
  303. package/dist/hooks/svg_rules.chunk.cjs +1626 -0
  304. package/dist/hooks/svg_rules.chunk.cjs.sha256 +1 -0
  305. package/dist/install/install.mjs +462 -431
  306. package/dist/install/installThinLayer.js +40 -12
  307. package/dist/install/installedRuleLinks.js +105 -19
  308. package/dist/mcp/awesome-mcp-servers.row.md +1 -1
  309. package/dist/mcp/mcp-cloudflare-catalogue.json +2 -2
  310. package/dist/mcp/registry-manifest.json +5 -5
  311. package/dist/mcp/server.json +2 -2
  312. package/dist/mcp/server.mjs +3063 -2160
  313. package/dist/router.json +1 -1
  314. package/dist/scripts/_lib/agent_settings.js +15 -120
  315. package/dist/scripts/_lib/compile_time_toggles.js +12 -21
  316. package/dist/scripts/_lib/git_convention.js +232 -0
  317. package/dist/scripts/_lib/global_deploy_inventory.js +730 -0
  318. package/dist/scripts/_lib/installed_layer.js +344 -18
  319. package/dist/scripts/_lib/package_root.js +68 -0
  320. package/dist/scripts/_lib/rule_law_section.js +1 -1
  321. package/dist/scripts/_lib/scan_scope.js +105 -0
  322. package/dist/scripts/_lib/settings_removed_keys.js +168 -0
  323. package/dist/scripts/_lib/svg_dom.js +284 -0
  324. package/dist/scripts/_lib/svg_geometry.js +477 -0
  325. package/dist/scripts/_lib/svg_motion.js +179 -0
  326. package/dist/scripts/_lib/svg_rules.js +1337 -0
  327. package/dist/scripts/_lib/svg_urls.js +67 -0
  328. package/dist/scripts/_lib/thin_rules.js +80 -3
  329. package/dist/scripts/lint_svg_asset.js +324 -0
  330. package/dist/server/app.js +2 -1
  331. package/dist/server/gitKeysGate.js +105 -0
  332. package/dist/server/routes/settings.js +67 -8
  333. package/dist/server/routes/wizard.js +4 -0
  334. package/dist/server/schemas/settings.js +23 -81
  335. package/dist/shared/skillRanking.js +30 -4
  336. package/dist/ui/assets/{index-Cwq4d0hX.js → index-C3djEJah.js} +2 -2
  337. package/dist/ui/index.html +1 -1
  338. package/docs/MIGRATION.md +72 -1
  339. package/docs/contracts/settings-classes.md +35 -65
  340. package/docs/guidelines/agent-infra/active-remediation-mechanics.md +39 -0
  341. package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +1 -1
  342. package/docs/guidelines/agent-infra/cross-source-consistency-mechanics.md +8 -10
  343. package/docs/guidelines/agent-infra/frontier-reasoning-operating-profile.md +3 -2
  344. package/docs/guidelines/agent-infra/layered-settings.md +13 -1
  345. package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +1 -1
  346. package/docs/guidelines/agent-infra/self-improvement-pipeline.md +10 -3
  347. package/docs/guidelines/agent-infra/size-and-scope.md +36 -0
  348. package/docs/guidelines/design-antipatterns.md +1 -1
  349. package/docs/guidelines/php/git.md +15 -2
  350. package/package.json +4 -3
  351. package/src/agent-src/scripts/gate_budget.ts +47 -23
  352. package/src/agent-src/scripts/gate_execute.ts +12 -4
  353. package/src/agent-src/templates/AGENTS.md +1 -1
  354. package/src/agent-src/templates/scripts/work_engine/_lib/agent_settings.ts +0 -6
  355. package/src/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +11 -7
  356. package/src/agent-src/templates/scripts/work_engine/hooks/builtin/decision_trace.ts +3 -2
  357. package/src/agent-src/templates/scripts/work_engine/hooks/builtin/memory_visibility.ts +2 -1
  358. package/src/agent-src/templates/scripts/work_engine/hooks/settings.ts +0 -6
  359. package/src/agent-src/templates/scripts/work_engine/scoring/decision_engine.ts +9 -12
  360. package/src/agent-src/templates/scripts/work_engine/scoring/memory_visibility.ts +2 -1
  361. package/src/config/agent-settings.template.yml +79 -312
  362. package/src/config/agents-paths.yml +16 -0
  363. package/src/config/assurance-capability-registry.json +7 -3
  364. package/src/config/ci-local-parity.yml +3 -0
  365. package/src/config/continuity-surface.json +3 -3
  366. package/src/config/discovery/packs.yml +17 -1
  367. package/src/config/evaluator-budgets.json +19 -6
  368. package/src/config/gate-coverage.yml +65 -23
  369. package/src/config/gate-violation-baselines.json +56 -16
  370. package/src/config/gitignore-block.txt +19 -0
  371. package/src/config/hook-bundle-budget.json +1 -1
  372. package/src/config/release-gate-locality.yml +2 -1
  373. package/src/config/routing-coverage-seed.json +55 -6
  374. package/src/config/rule-law-ceilings.json +12 -6
  375. package/src/config/rule-obligations.json +833 -0
  376. package/src/install/installThinLayer.ts +76 -10
  377. package/src/install/installedRuleLinks.ts +105 -17
  378. package/src/scripts/_cli/cmd_analyze_session.ts +9 -15
  379. package/src/scripts/_cli/cmd_conformance.ts +13 -2
  380. package/src/scripts/_cli/cmd_doctor.ts +10 -10
  381. package/src/scripts/_cli/cmd_doctor_neighbours.ts +133 -0
  382. package/src/scripts/_cli/cmd_explain.ts +72 -14
  383. package/src/scripts/_cli/cmd_git_convention.ts +637 -0
  384. package/src/scripts/_cli/cmd_settings_check.ts +66 -8
  385. package/src/scripts/_cli/cmd_settings_get.ts +18 -3
  386. package/src/scripts/_cli/doctor_execution.ts +72 -1
  387. package/src/scripts/_dispatch.bash +37 -2
  388. package/src/scripts/_lib/agent_settings.ts +15 -124
  389. package/src/scripts/_lib/blocked_by_marker.ts +1 -1
  390. package/src/scripts/_lib/compile_time_toggles.ts +12 -21
  391. package/src/scripts/_lib/dispatch_import_closure.ts +163 -0
  392. package/src/scripts/_lib/git_base_ref.ts +92 -0
  393. package/src/scripts/_lib/git_convention.ts +291 -0
  394. package/src/scripts/_lib/git_convention_carrier.ts +389 -0
  395. package/src/scripts/_lib/git_convention_grammar.ts +246 -0
  396. package/src/scripts/_lib/git_convention_measure.ts +344 -0
  397. package/src/scripts/_lib/global_deploy_inventory.ts +74 -0
  398. package/src/scripts/_lib/graph_feeder_record.ts +236 -13
  399. package/src/scripts/_lib/installed_layer.ts +448 -23
  400. package/src/scripts/_lib/knowledge_global.ts +14 -1
  401. package/src/scripts/_lib/module_reach.ts +456 -0
  402. package/src/scripts/_lib/neighbour_contradictions.ts +236 -0
  403. package/src/scripts/_lib/neighbour_tool_use.ts +8 -10
  404. package/src/scripts/_lib/ratification_artifact.ts +220 -1
  405. package/src/scripts/_lib/ratification_subject.ts +92 -0
  406. package/src/scripts/_lib/release_findings_ingest.ts +15 -7
  407. package/src/scripts/_lib/release_highlights.ts +5 -0
  408. package/src/scripts/_lib/rule_law_section.ts +1 -1
  409. package/src/scripts/_lib/rule_obligations.ts +205 -0
  410. package/src/scripts/_lib/self_repair.ts +1 -1
  411. package/src/scripts/_lib/settings_removed_keys.ts +173 -0
  412. package/src/scripts/_lib/svg_dom.ts +318 -0
  413. package/src/scripts/_lib/svg_geometry.ts +480 -0
  414. package/src/scripts/_lib/svg_motion.ts +208 -0
  415. package/src/scripts/_lib/svg_rules.ts +1453 -0
  416. package/src/scripts/_lib/svg_urls.ts +72 -0
  417. package/src/scripts/_lib/test_red_state.ts +5 -0
  418. package/src/scripts/_lib/thin_rules.ts +83 -3
  419. package/src/scripts/_lib/touched_file_quality.ts +142 -6
  420. package/src/scripts/_lib/verification_command.ts +59 -0
  421. package/src/scripts/_lib/verify_clause.ts +27 -17
  422. package/src/scripts/_lib/worker_budget.ts +1 -1
  423. package/src/scripts/adr/regenerate_index.ts +16 -1
  424. package/src/scripts/ai_council/config.ts +7 -7
  425. package/src/scripts/ai_council/modification_review.ts +100 -0
  426. package/src/scripts/ai_council/modification_review_questions.ts +90 -0
  427. package/src/scripts/ai_council/orchestrator.ts +5 -5
  428. package/src/scripts/ai_council/spend_gate.ts +18 -7
  429. package/src/scripts/ai_team/config.ts +11 -16
  430. package/src/scripts/audit_user_type_axis.ts +20 -8
  431. package/src/scripts/bench_ab_clone.ts +1 -2
  432. package/src/scripts/bench_concern_spawn_path.ts +129 -0
  433. package/src/scripts/bench_graph_feeder_latency.ts +584 -0
  434. package/src/scripts/check_agent_artifact_location.ts +36 -0
  435. package/src/scripts/check_branch_freshness.ts +147 -24
  436. package/src/scripts/check_enforcement_coverage.ts +130 -0
  437. package/src/scripts/check_evaluator_budgets.ts +4 -0
  438. package/src/scripts/check_finding_dispositions.ts +88 -25
  439. package/src/scripts/check_gate_coverage.ts +4 -3
  440. package/src/scripts/check_gate_reachability.ts +48 -1
  441. package/src/scripts/check_generator_sync.ts +48 -0
  442. package/src/scripts/check_hook_bundle_composition.ts +107 -0
  443. package/src/scripts/check_kernel_edit_ratified.ts +86 -6
  444. package/src/scripts/check_pack_size.ts +1 -1
  445. package/src/scripts/check_release_manifest_content.ts +189 -0
  446. package/src/scripts/check_standing_rule_delivery.ts +96 -0
  447. package/src/scripts/check_suppression_hygiene.ts +2 -5
  448. package/src/scripts/ci_settle.ts +42 -5
  449. package/src/scripts/classify_merge_risk.ts +320 -0
  450. package/src/scripts/closure_scan.ts +91 -1
  451. package/src/scripts/command_suggester/settings.ts +8 -108
  452. package/src/scripts/command_suggester/types.ts +4 -5
  453. package/src/scripts/consumer_matrix.ts +102 -0
  454. package/src/scripts/context_hygiene_hook.ts +13 -23
  455. package/src/scripts/cost/preflight.mjs +12 -1
  456. package/src/scripts/council_cli.ts +7 -7
  457. package/src/scripts/dispatch_r2_reviewer.ts +24 -11
  458. package/src/scripts/explain_run.ts +8 -13
  459. package/src/scripts/generate_git_convention_grammar.ts +127 -0
  460. package/src/scripts/generate_host_cost_table.ts +20 -3
  461. package/src/scripts/handoff_context_hook.ts +86 -37
  462. package/src/scripts/hook_manifest.json +1 -1
  463. package/src/scripts/hook_manifest.yaml +25 -6
  464. package/src/scripts/hooks/block_config_weakening.ts +48 -5
  465. package/src/scripts/hooks/block_plumbing_writes.ts +8 -4
  466. package/src/scripts/hooks/block_speaking_inbox_dir.ts +16 -1
  467. package/src/scripts/hooks/concern_registry.ts +2 -0
  468. package/src/scripts/hooks/delegation_nudge_hook.ts +2 -3
  469. package/src/scripts/hooks/design_pass_hook.ts +157 -3
  470. package/src/scripts/hooks/evidence_independence.ts +12 -4
  471. package/src/scripts/hooks/mcp_usage_observation_hook.ts +121 -0
  472. package/src/scripts/hooks/push_settle_hook.ts +4 -3
  473. package/src/scripts/hooks/rule_inject_hook.ts +44 -3
  474. package/src/scripts/hooks/state_io.ts +8 -4
  475. package/src/scripts/hooks/svg_obligation.ts +497 -0
  476. package/src/scripts/hooks/svg_rules_loader.ts +133 -0
  477. package/src/scripts/hooks/telemetry_usage_hook.ts +7 -46
  478. package/src/scripts/hooks/turn_end_gate_hook.ts +6 -3
  479. package/src/scripts/install-hooks.sh +42 -14
  480. package/src/scripts/install.ts +7 -31
  481. package/src/scripts/lint_blocker_citations.ts +198 -0
  482. package/src/scripts/lint_consolidation_lineage.ts +6 -3
  483. package/src/scripts/lint_design_quality.ts +60 -12
  484. package/src/scripts/lint_evidence_artifacts.ts +9 -0
  485. package/src/scripts/lint_hook_concern_budget.ts +10 -21
  486. package/src/scripts/lint_motion_authority_drift.ts +27 -0
  487. package/src/scripts/lint_pack_boundaries.ts +406 -28
  488. package/src/scripts/lint_roadmap_blockers.ts +282 -29
  489. package/src/scripts/lint_roadmap_complexity.ts +4 -2
  490. package/src/scripts/lint_rule_law_section.ts +151 -21
  491. package/src/scripts/lint_rule_skill_pack_reach.ts +17 -0
  492. package/src/scripts/lint_settings_classes.ts +1 -1
  493. package/src/scripts/lint_svg_asset.ts +365 -0
  494. package/src/scripts/lint_ticked_unmet_criteria.ts +165 -0
  495. package/src/scripts/lint_workflow_security.ts +12 -1
  496. package/src/scripts/measure_skill_ranker_baseline.ts +5 -0
  497. package/src/scripts/model_rule_injection.ts +3 -3
  498. package/src/scripts/onboarding_gate_hook.ts +7 -6
  499. package/src/scripts/print_required_checks.ts +15 -3
  500. package/src/scripts/probe_host_compliance.ts +33 -5
  501. package/src/scripts/probe_turnaround.ts +183 -3
  502. package/src/scripts/ratification_header.ts +77 -0
  503. package/src/scripts/refusal_envelope.ts +138 -0
  504. package/src/scripts/release_publication.ts +29 -3
  505. package/src/scripts/report_dispatch_import_closure.ts +76 -0
  506. package/src/scripts/report_installed_rule_links.ts +118 -1
  507. package/src/scripts/report_module_reach.ts +212 -0
  508. package/src/scripts/report_obligation_mechanism.ts +16 -18
  509. package/src/scripts/report_parked_blockers.ts +222 -0
  510. package/src/scripts/report_required_checks_drift.ts +196 -0
  511. package/src/scripts/report_skill_ranker_confusion.ts +103 -2
  512. package/src/scripts/report_standing_payload_by_host.ts +1 -1
  513. package/src/scripts/routing_doctor.ts +2 -2
  514. package/src/scripts/schemas/agent-settings.schema.json +17 -31
  515. package/src/scripts/schemas/command.schema.json +1 -1
  516. package/src/scripts/schemas/skill.schema.json +1 -1
  517. package/src/scripts/self_review_gate.ts +39 -2
  518. package/src/scripts/skill_tools/score_skill_relevance.ts +28 -19
  519. package/src/scripts/sync_pr_branch.ts +403 -132
  520. package/src/scripts/trigger_eval_grandfather.json +0 -16
  521. package/src/server/schemas/settings.ts +33 -177
  522. package/src/shared/skillRanking.ts +53 -4
  523. package/dist/cli-delegate/chunk-NYX3L2PZ.js +0 -99
  524. package/src/scripts/_lib/config_chain.ts +0 -477
  525. package/src/scripts/_lib/conformance_report.ts +0 -403
  526. package/src/scripts/_lib/eval_discrimination.ts +0 -95
  527. package/src/scripts/_lib/evaluator_promotion.ts +0 -225
  528. package/src/scripts/_lib/file_slicer.ts +0 -117
  529. package/src/scripts/_lib/legacy_boundary_map.ts +0 -228
  530. package/src/scripts/_lib/minimality_tiebreak.ts +0 -168
  531. package/src/scripts/_lib/overbuild_lens_contract.ts +0 -196
  532. package/src/scripts/_lib/role_split.ts +0 -338
@@ -57,13 +57,14 @@ import * as os from 'node:os';
57
57
  import {
58
58
  buildHostLimitRows,
59
59
  loadHostInstructionLimits,
60
+ ownershipLine,
60
61
  readLayer,
61
62
  renderHostLimitRows,
63
+ resolveLayerOwnership,
62
64
  type LayerReading,
63
65
  } from '../scripts/_lib/installed_layer.js';
64
66
  import { GLOBAL_RULE_DIRS, globalRuleLayerPath } from './globalRuleLayers.js';
65
67
  import { manifest_path } from '../scripts/_lib/installed_tools.js';
66
- import { NO_RECORDED_HASHES, readRecordedHashes } from './recordedOwnership.js';
67
68
  import {
68
69
  absoluteBodyLinkPrefix,
69
70
  build_thin,
@@ -271,6 +272,38 @@ export function describeThinInstalledLayer(res: ThinInstalledLayerResult): strin
271
272
  return out;
272
273
  }
273
274
 
275
+ /**
276
+ * What {@link installReceiptBudgetLines} may be told about ownership evidence.
277
+ *
278
+ * Declared ABOVE that function's own doc block on purpose. It first sat between
279
+ * the doc block and the function, which silently re-attached the function's
280
+ * contract — "step 1.4's at install", "global layers only, deliberately",
281
+ * "never throws" — to this interface, and interfaces erase on emit, so the
282
+ * contract disappeared from the shipped JS and from IDE hover on the function.
283
+ */
284
+ export interface InstallReceiptOwnershipOptions {
285
+ /**
286
+ * The installed-tools manifest. `undefined` uses `manifest_path(packageRoot)`;
287
+ * `null` reads none.
288
+ *
289
+ * Overridable so a test can be hermetic. That lock file is gitignored, so
290
+ * it is absent in CI and present on any checkout where a project-scoped
291
+ * install has run — a case reading it implicitly turns green-in-CI,
292
+ * red-on-a-maintainer's-machine, for a reason unrelated to what it tests.
293
+ */
294
+ readonly manifestPath?: string | null | undefined;
295
+ /** `deployed-files.json`. `undefined` reads the user-global default; `null` reads none. */
296
+ readonly inventoryPath?: string | null | undefined;
297
+ /**
298
+ * Anchor → anchor-relative paths this run just wrote.
299
+ *
300
+ * The installer holds exactly this set at the moment it prints the receipt,
301
+ * and `record_deploy` has not run yet, so on a FIRST install it is the only
302
+ * evidence the files are ours.
303
+ */
304
+ readonly thisDeploy?: ReadonlyMap<string, Iterable<string>> | null | undefined;
305
+ }
306
+
274
307
  /**
275
308
  * The install receipt's instruction-budget block — step 1.4's "at install".
276
309
  *
@@ -289,15 +322,47 @@ export function describeThinInstalledLayer(res: ThinInstalledLayerResult): strin
289
322
  * Never throws. A receipt that cannot be measured is silent rather than fatal —
290
323
  * the deploy it describes has already happened correctly.
291
324
  */
292
- export function installReceiptBudgetLines(packageRoot: string, home: string = os.homedir()): string[] {
325
+ export function installReceiptBudgetLines(
326
+ packageRoot: string,
327
+ home: string = os.homedir(),
328
+ opts: InstallReceiptOwnershipOptions = {},
329
+ ): string[] {
293
330
  try {
294
- const recorded = (() => {
295
- try {
296
- return readRecordedHashes(manifest_path(packageRoot), packageRoot);
297
- } catch {
298
- return NO_RECORDED_HASHES;
299
- }
300
- })();
331
+ // ONE RESOLVER, SHARED WITH THE REPORT — step 1.2. This used to read
332
+ // `manifest_path(packageRoot)`, the PACKAGE root's lock, which on a
333
+ // global-only install names a file no global install ever writes; the
334
+ // receipt then printed `0 package-owned` for a layer it had itself just
335
+ // deployed. `resolveLayerOwnership` falls through to the inventory, and
336
+ // `thisDeploy` covers the first install, where the receipt prints
337
+ // before `record_deploy` has written anything.
338
+ const { recorded, sources } = resolveLayerOwnership({
339
+ manifestPath: opts.manifestPath === undefined ? manifest_path(packageRoot) : opts.manifestPath,
340
+ projectRoot: packageRoot,
341
+ // The same home the layers below are read from — the inventory's
342
+ // anchor is tilde-relative, so the two must agree or the receipt
343
+ // measures one install and claims ownership of another.
344
+ home,
345
+ // THE RECEIPT IS THE "ASKING PROCESS" CASE, so it names no home
346
+ // here. It runs inside the install that WROTE the inventory, and
347
+ // that writer resolves the path through `inventory_path()` —
348
+ // honouring `AGENT_CONFIG_DEPLOY_INVENTORY`, which names a FILE
349
+ // rather than a home, and `EVENT4U_CONFIG_HOME`. Passing `home`
350
+ // would take `defaultInventoryPath`'s stated-home branch and read
351
+ // `<home>/.event4u/...`, a file nothing wrote under either
352
+ // override, and the inventory evidence would be silently lost.
353
+ // UNDEFINED IS LEFT UNDEFINED so `resolveLayerOwnership` applies
354
+ // `defaultInventoryPath(home)` — the SAME resolution the report
355
+ // uses. Hardcoding `inventory_path()` here made the two readers
356
+ // step 1.2 exists to reconcile disagree for any home that is not
357
+ // the asking process's: the receipt read one install's inventory
358
+ // and then expanded its tilde-relative anchors against the OTHER
359
+ // home, which is the cross-home misattribution two docstrings in
360
+ // the resolver forbid. `defaultInventoryPath` already returns
361
+ // `inventory_path()` when the stated home IS this process's, which
362
+ // is the case that motivated the hardcode.
363
+ inventoryPath: opts.inventoryPath,
364
+ thisDeploy: opts.thisDeploy,
365
+ });
301
366
  const layers: LayerReading[] = [];
302
367
  for (const host of Object.keys(GLOBAL_RULE_DIRS).sort()) {
303
368
  const dir = globalRuleLayerPath(host, home);
@@ -305,7 +370,8 @@ export function installReceiptBudgetLines(packageRoot: string, home: string = os
305
370
  layers.push(readLayer(host, 'global', dir, recorded));
306
371
  }
307
372
  const rows = buildHostLimitRows(layers, loadHostInstructionLimits());
308
- return rows.length === 0 ? [] : renderHostLimitRows(rows).map((l) => ` ${l}`);
373
+ if (rows.length === 0) return [];
374
+ return [` ${ownershipLine(sources)}`, ...renderHostLimitRows(rows).map((l) => ` ${l}`)];
309
375
  } catch {
310
376
  return [];
311
377
  }
@@ -152,32 +152,90 @@ const EMPTY_COUNTS = (): Record<LinkVerdict, number> => ({
152
152
  });
153
153
 
154
154
  /**
155
- * Audit every link in every rule the plan installs.
155
+ * Every `.md` file under `dir`, as POSIX paths relative to it, sorted.
156
156
  *
157
- * `packageRoot` is the package checkout the installer copies FROM; the rule
158
- * bodies are read from the plan's own rules source, so the audit cannot drift
159
- * from what is shipped.
157
+ * Recursive because skills (`<name>/SKILL.md`), commands (`<cluster>/x.md`) and
158
+ * contexts nest.
160
159
  */
161
- export function auditInstalledRuleLinks(plan: DeployPlan, packageRoot: string): LinkAuditReport {
160
+ function markdownFilesUnder(dir: string): string[] {
161
+ const out: string[] = [];
162
+ const walk = (rel: string): void => {
163
+ for (const e of fs.readdirSync(path.join(dir, rel), { withFileTypes: true })) {
164
+ const child = rel === '' ? e.name : `${rel}/${e.name}`;
165
+ if (e.isDirectory()) walk(child);
166
+ else if (e.name.endsWith('.md')) out.push(child);
167
+ }
168
+ };
169
+ walk('');
170
+ return out.sort();
171
+ }
172
+
173
+ /**
174
+ * Does this link point into a tree no install ever carries — `docs/`, which
175
+ * holds the ADRs?
176
+ *
177
+ * Decided from where the file sits in the PACKAGE (`dist/agent-src/<kind>/…`),
178
+ * not from where the install puts it: an author linking `docs/` meant the
179
+ * repository, whatever the host does. Two shapes count — a target landing under
180
+ * the top-level `docs/`, and a target naming a `docs/` segment or an ADR file
181
+ * that resolves to nothing in the package (an author writing `../docs/x` from
182
+ * a rule meant the repository's `docs/`, not a sibling that does not exist).
183
+ * `guidelines/docs/` is a real projected directory, which is why existence
184
+ * decides the second shape rather than the word alone.
185
+ */
186
+ export function isNonProjectedTarget(packageRoot: string, packageFromDir: string, target: string): boolean {
187
+ const bare = withoutAnchor(target);
188
+ const resolved = path.posix.normalize(path.posix.join(packageFromDir, bare));
189
+ if (resolved === 'docs' || resolved.startsWith('docs/')) return true;
190
+ if (!/(^|\/)(docs\/|ADR-\d)/.test(bare)) return false;
191
+ return resolved.startsWith('..') || !fs.existsSync(path.join(packageRoot, resolved));
192
+ }
193
+
194
+ /** A per-kind audit: the deployable reading, and the non-projected row apart. */
195
+ export type KindLinkReport = LinkAuditReport & { non_projected: LinkAudit[] };
196
+
197
+ /**
198
+ * Audit every link in every file of ONE installed kind.
199
+ *
200
+ * `kindSource` is the package directory the plan copies (`dist/agent-src/skills`).
201
+ * A file nested at `<rel>/x.md` is installed at `<dest>/<rel>/x.md`, so its links
202
+ * resolve from that directory — through the same {@link auditLink} the rule
203
+ * audit uses, because a second resolver would be the drift this count exists to
204
+ * catch.
205
+ *
206
+ * Returns null when the plan does not install the kind at all: "not installed"
207
+ * is a different answer from "installed with zero links".
208
+ */
209
+ export function auditInstalledKindLinks(
210
+ plan: DeployPlan,
211
+ packageRoot: string,
212
+ kindSource: string,
213
+ ): KindLinkReport | null {
214
+ let dest: string | undefined;
215
+ for (const [d, source] of plan) if (source === kindSource) dest = d;
216
+ if (dest === undefined) return null;
217
+
162
218
  const audits: LinkAudit[] = [];
163
- for (const [dest, source] of plan) {
164
- if (!source.endsWith('/rules')) continue;
165
- const dir = path.join(packageRoot, source);
166
- if (!fs.existsSync(dir)) continue;
167
- const files = fs
168
- .readdirSync(dir, { withFileTypes: true })
169
- .filter((e) => !e.isDirectory() && e.name.endsWith('.md'))
170
- .map((e) => e.name)
171
- .sort();
172
- for (const file of files) {
173
- const rule = file.replace(/\.md$/, '');
219
+ const nonProjected: LinkAudit[] = [];
220
+ const dir = path.join(packageRoot, kindSource);
221
+ if (fs.existsSync(dir)) {
222
+ for (const file of markdownFilesUnder(dir)) {
223
+ const relDir = path.posix.dirname(file);
224
+ const installedDir = relDir === '.' ? dest : dest === '' ? relDir : `${dest}/${relDir}`;
225
+ const packageDir = relDir === '.' ? kindSource : `${kindSource}/${relDir}`;
226
+ const id = file.replace(/\.md$/, '');
174
227
  const body = fs.readFileSync(path.join(dir, file), 'utf8');
175
228
  for (const target of relativeLinkTargets(body)) {
176
- audits.push(auditLink(rule, target, dest, plan, packageRoot));
229
+ const audit = auditLink(id, target, installedDir, plan, packageRoot);
230
+ if (isNonProjectedTarget(packageRoot, packageDir, target)) nonProjected.push(audit);
231
+ else audits.push(audit);
177
232
  }
178
233
  }
179
234
  }
235
+ return { ...summarise(audits), non_projected: nonProjected };
236
+ }
180
237
 
238
+ function summarise(audits: LinkAudit[]): LinkAuditReport {
181
239
  const counts = EMPTY_COUNTS();
182
240
  for (const a of audits) counts[a.verdict] += 1;
183
241
 
@@ -196,6 +254,36 @@ export function auditInstalledRuleLinks(plan: DeployPlan, packageRoot: string):
196
254
  return { audits, counts, by_directory };
197
255
  }
198
256
 
257
+ /**
258
+ * Audit every link in every rule the plan installs.
259
+ *
260
+ * `packageRoot` is the package checkout the installer copies FROM; the rule
261
+ * bodies are read from the plan's own rules source, so the audit cannot drift
262
+ * from what is shipped. Non-projected targets stay IN this reading: its
263
+ * recorded figures predate the per-kind split.
264
+ */
265
+ export function auditInstalledRuleLinks(plan: DeployPlan, packageRoot: string): LinkAuditReport {
266
+ const audits: LinkAudit[] = [];
267
+ for (const [dest, source] of plan) {
268
+ if (!source.endsWith('/rules')) continue;
269
+ const dir = path.join(packageRoot, source);
270
+ if (!fs.existsSync(dir)) continue;
271
+ const files = fs
272
+ .readdirSync(dir, { withFileTypes: true })
273
+ .filter((e) => !e.isDirectory() && e.name.endsWith('.md'))
274
+ .map((e) => e.name)
275
+ .sort();
276
+ for (const file of files) {
277
+ const rule = file.replace(/\.md$/, '');
278
+ const body = fs.readFileSync(path.join(dir, file), 'utf8');
279
+ for (const target of relativeLinkTargets(body)) {
280
+ audits.push(auditLink(rule, target, dest, plan, packageRoot));
281
+ }
282
+ }
283
+ }
284
+ return summarise(audits);
285
+ }
286
+
199
287
  /**
200
288
  * Standing-text cost of the rewrite option, in characters.
201
289
  *
@@ -12,10 +12,10 @@
12
12
  * - `changes` — files touched (array of {kind, stack, file, summary}).
13
13
  * - `outcomes` — directive → "success" / "blocked" / … .
14
14
  * - `halts` — array of recorded halts.
15
- * 2. `agents/runtime/state/context-hygiene.json` — fields read:
15
+ * 2. the context-hygiene hook's state file (`STATE_FILE`, imported from
16
+ * `context_hygiene_hook.ts` rather than spelled here — two independent
17
+ * spellings of this path drifted apart before). Fields read:
16
18
  * - `tool_calls` (int)
17
- * - `consecutive_same_tool`(int)
18
- * - `loop_detected` (bool)
19
19
  *
20
20
  * There is NO general token/cost data source in this package (only
21
21
  * video-specific telemetry), so the report deliberately does NOT report
@@ -33,18 +33,16 @@ import process from 'node:process';
33
33
  import { fileURLToPath, pathToFileURL } from 'node:url';
34
34
 
35
35
  import { ProjectRootError, resolve_project_root } from '../_lib/agent_settings.js';
36
+ import { STATE_FILE as HYGIENE_STATE_FILE } from '../context_hygiene_hook.js';
36
37
  import { StateLoadError, load_state } from './explain_last/state_loader.js';
37
38
 
38
39
  type Dict = Record<string, unknown>;
39
40
 
40
41
  const _HERE = fileURLToPath(import.meta.url);
41
42
 
42
- const CONTEXT_HYGIENE_RELATIVE = path.join(
43
- 'agents',
44
- 'runtime',
45
- 'state',
46
- 'context-hygiene.json',
47
- );
43
+ // Imported from the hook rather than spelled here — the hook is the writer,
44
+ // so it is the single source of truth for the path it writes to.
45
+ const CONTEXT_HYGIENE_RELATIVE = HYGIENE_STATE_FILE;
48
46
 
49
47
  /** Python `raise SystemExit(code)` analogue — propagates an explicit code. */
50
48
  class SystemExitError extends Error {
@@ -196,11 +194,7 @@ export function render_report(state: Dict, hygiene: Dict | null): string {
196
194
  lines.push('_Context-hygiene snapshot not available._');
197
195
  } else {
198
196
  const toolCalls = intOrUnknown(hygiene['tool_calls']);
199
- const consecutive = intOrUnknown(hygiene['consecutive_same_tool']);
200
- const loop = hygiene['loop_detected'] === true;
201
197
  lines.push(`- Tool calls: ${toolCalls}`);
202
- lines.push(`- Consecutive same-tool calls: ${consecutive}`);
203
- lines.push(`- Loop detected: ${loop ? 'yes' : 'no'}`);
204
198
  }
205
199
  lines.push('');
206
200
 
@@ -253,8 +247,8 @@ Sources read:
253
247
  · changes — files touched
254
248
  · outcomes — per-directive success / blocked
255
249
  · halts — recorded halts
256
- agents/runtime/state/context-hygiene.json
257
- · tool_calls · consecutive_same_tool · loop_detected
250
+ agents/state/context-hygiene.json
251
+ · tool_calls
258
252
 
259
253
  Token/cost is NOT reported — this package has no per-session token
260
254
  source (only video-specific telemetry).
@@ -42,6 +42,7 @@ import { atomicAppendLine } from '../../install/atomic.js';
42
42
  import { readRecentEntries } from '../../install/txlog.js';
43
43
  import { detectToolPresence } from '../../install/detect.js';
44
44
  import { resolvePackageRoot } from '../_lib/package_root.js';
45
+ import { THIN_ENTRY_MARKER } from '../_lib/thin_rules.js';
45
46
  import { routeTargetPathsPosix } from '../router_target_paths.mjs';
46
47
  import { buildFunnel, render as renderFunnel } from '../report_conformance_funnel.js';
47
48
  import {
@@ -74,8 +75,18 @@ export const CONFORMANCE_CHECK_IDS = [
74
75
  'host-manifest',
75
76
  ] as const;
76
77
 
77
- /** Marker emitted by `project_thin_rules.thin_entry()` — the thin-stub signature. */
78
- export const THIN_STUB_MARKER = 'Routed rule — load the body on trigger-match';
78
+ /**
79
+ * Marker emitted by `project_thin_rules.thin_entry()` — the thin-stub signature.
80
+ *
81
+ * RE-EXPORTED, NEVER RE-SPELLED — step 2.1 of
82
+ * `road-to-a-thinned-layer-measured-in-one-unit`. This was its own literal, a
83
+ * substring of the writer's constant without the blockquote prefix and the full
84
+ * stop, which is exactly the drift `THIN_ENTRY_MARKER`'s own docstring warns
85
+ * about: shorten the writer and this detector keeps matching the old sentence,
86
+ * silently, in the direction where a stub it fails to recognise reads as a
87
+ * complete rule body. The name stays so existing callers are unchanged.
88
+ */
89
+ export const THIN_STUB_MARKER = THIN_ENTRY_MARKER;
79
90
 
80
91
  /**
81
92
  * Rendering symbols for this verb's rows — doctor's table plus `unknown`.
@@ -114,7 +114,7 @@ import {
114
114
  resolve_project_root,
115
115
  type TraceRecord,
116
116
  } from '../_lib/agent_settings.js';
117
- import { executionJson, forgeProtectionJsonFor } from './doctor_execution.js';
117
+ import { executionJson, forgeDepsFor, forgeProtectionJsonFor, type ForgeDeps } from './doctor_execution.js';
118
118
  import { checkOfflineReadiness, trafficEnvironmentJson } from './doctor_network_posture.js';
119
119
  import * as ai_council_clients from '../ai_council/clients.js';
120
120
  import * as ai_council_config from '../ai_council/config.js';
@@ -2945,7 +2945,7 @@ function _run_no_manifest(
2945
2945
  checks.some((c) => c['id'] === opts.check && c['status'] === 'skipped');
2946
2946
 
2947
2947
  if (opts.json) {
2948
- _emit_json(project_root, [], [], [], [], checks, origin);
2948
+ _emit_json(project_root, [], [], [], [], checks, origin, forgeDepsFor(opts));
2949
2949
  } else if (opts.check === null) {
2950
2950
  print(` 📍 project_root: ${project_root} (origin: ${origin})`);
2951
2951
  if (bridge_present) {
@@ -2998,7 +2998,7 @@ function _emit_json(
2998
2998
  foreign: Dict[],
2999
2999
  tag_drift: Dict[],
3000
3000
  checks: Dict[] | null = null,
3001
- origin: string | null = null,
3001
+ origin: string | null = null, forge: ForgeDeps = {},
3002
3002
  ): void {
3003
3003
  const payload: Dict = {
3004
3004
  project_root: String(project_root),
@@ -3009,7 +3009,7 @@ function _emit_json(
3009
3009
  };
3010
3010
  if (origin !== null) payload['project_root_origin'] = origin;
3011
3011
  payload['execution'] = executionJson(() => iter_setting_overrides({ cwd: project_root }));
3012
- payload['forge_protection'] = forgeProtectionJsonFor(String(project_root)); // 3.2 · AC-5
3012
+ payload['forge_protection'] = forgeProtectionJsonFor(String(project_root), forge); // 3.2 · AC-5
3013
3013
  payload['traffic_environment'] = trafficEnvironmentJson(process.env);
3014
3014
  if (checks !== null) {
3015
3015
  payload['checks'] = checks;
@@ -3066,7 +3066,7 @@ interface Options {
3066
3066
  ci: boolean;
3067
3067
  strict: boolean; strict_level: string; // see `_doctor_strict.ts`
3068
3068
  check: string | null;
3069
- trace_root: boolean;
3069
+ trace_root: boolean; no_forge: boolean; online: boolean; // opt-out / opt-in; `forgeDepsFor`
3070
3070
  context: boolean;
3071
3071
  anatomy: boolean;
3072
3072
  repair: string | null;
@@ -3080,14 +3080,14 @@ const PROG = 'agent-config doctor';
3080
3080
  const USAGE =
3081
3081
  `usage: ${PROG} [-h] [--project PROJECT] [--json] [--ci] [--check ID]\n` +
3082
3082
  STRICT_USAGE +
3083
- ' [--trace-root] [--context] [--anatomy]\n' +
3084
- ' [--repair ID]\n';
3083
+ ' [--trace-root] [--context] [--anatomy] [--no-forge]\n' +
3084
+ ' [--online] [--repair ID]\n';
3085
3085
 
3086
3086
  const _STORE_TRUE_FLAGS: Record<string, keyof Options> = {
3087
3087
  '--json': 'json',
3088
3088
  '--ci': 'ci',
3089
3089
  ...STRICT_STORE_TRUE,
3090
- '--trace-root': 'trace_root',
3090
+ '--trace-root': 'trace_root', '--no-forge': 'no_forge', '--offline': 'no_forge', '--online': 'online',
3091
3091
  '--context': 'context',
3092
3092
  '--anatomy': 'anatomy',
3093
3093
  };
@@ -3112,7 +3112,7 @@ function _parse(argv: string[]): Options {
3112
3112
  ci: false,
3113
3113
  ...STRICT_DEFAULTS,
3114
3114
  check: null,
3115
- trace_root: false,
3115
+ trace_root: false, no_forge: false, online: false,
3116
3116
  context: false,
3117
3117
  anatomy: false,
3118
3118
  repair: null,
@@ -3390,7 +3390,7 @@ function main(argv: string[] | null = null): number {
3390
3390
  const fail_check = checks.some((c) => c['status'] === 'fail');
3391
3391
 
3392
3392
  if (opts.json) {
3393
- _emit_json(project_root, missing, modified, foreign, tag_drift, checks, origin);
3393
+ _emit_json(project_root, missing, modified, foreign, tag_drift, checks, origin, forgeDepsFor(opts));
3394
3394
  } else {
3395
3395
  if (opts.check === null) {
3396
3396
  print(` 📍 project_root: ${project_root} (origin: ${origin})`);
@@ -16,8 +16,14 @@
16
16
  * the hook path, and `neighbour-overlap.json`, the cross-root pairs keyed by the
17
17
  * census digest. Nothing outside that directory is touched, and a failed write
18
18
  * is not a failed census.
19
+ *
20
+ * `--contradictions` (step 2.2) writes neither cache. It forms candidate pairs
21
+ * and hands them to ONE council seat, whose question and transcript land under
22
+ * gitignored `agents/runtime/council/`; with no council configured it prints
23
+ * `n/a` and asks nobody.
19
24
  */
20
25
 
26
+ import { spawnSync } from 'node:child_process';
21
27
  import * as fs from 'node:fs';
22
28
  import * as path from 'node:path';
23
29
  import { fileURLToPath, pathToFileURL } from 'node:url';
@@ -32,6 +38,22 @@ import {
32
38
  type NeighbourCensus,
33
39
  } from '../_lib/neighbour_census.js';
34
40
  import { scanNeighbourBody, writeScanCache } from '../_lib/neighbour_scan.js';
41
+ import {
42
+ RANK_NEIGHBOUR_ALWAYS_ON,
43
+ RANK_NEIGHBOUR_SKILL,
44
+ RANK_PROJECT,
45
+ collisionPair,
46
+ extractInstructions,
47
+ modalityPairs,
48
+ parseVerdicts,
49
+ renderReview,
50
+ reviewRows,
51
+ seatPrompt,
52
+ type CandidatePair,
53
+ type InstructionSource,
54
+ type ReviewRow,
55
+ } from '../_lib/neighbour_contradictions.js';
56
+ import { resolveAvailability } from '../council_availability_hook.js';
35
57
  import { resolvePackageRoot } from '../_lib/package_root.js';
36
58
  import {
37
59
  OVERLAP_THRESHOLD,
@@ -144,6 +166,109 @@ export function runCensus(
144
166
  return full;
145
167
  }
146
168
 
169
+ /**
170
+ * Candidate pairs for `--contradictions` (step 2.2), READ-ONLY.
171
+ *
172
+ * Calls `census()` directly rather than `runCensus()`, because the latter
173
+ * writes the scan and overlap caches and this mode promises to change no file.
174
+ * The shape scan still runs, and a refused neighbour body contributes no line.
175
+ */
176
+ export function contradictionCandidates(
177
+ projectRoot: string,
178
+ packageRoot: string,
179
+ homeRoot?: string,
180
+ ): CandidatePair[] {
181
+ const ours = ourSkillNames(packageRoot);
182
+ const c = census(projectRoot, {
183
+ gatedEvents: gatedEvents(packageRoot),
184
+ templatesRoot: path.join(packageRoot, 'src', 'agent-src', 'templates'),
185
+ ourSkillNames: ours,
186
+ packageRoot,
187
+ scan: (p) => scanNeighbourBody(p).kind,
188
+ ...(homeRoot === undefined ? {} : { homeRoot }),
189
+ });
190
+ const sources: InstructionSource[] = [];
191
+ for (const name of ['CLAUDE.md', 'AGENTS.md']) {
192
+ const file = path.join(projectRoot, name);
193
+ if (fs.existsSync(file)) sources.push({ label: name, file, rank: RANK_PROJECT });
194
+ }
195
+ for (const r of c.rule_files) {
196
+ if (scanNeighbourBody(r.source).kind === null) {
197
+ sources.push({ label: r.id, file: r.source, rank: RANK_NEIGHBOUR_ALWAYS_ON });
198
+ }
199
+ }
200
+ for (const s of c.skills) {
201
+ if (s.unscanned === null) sources.push({ label: s.qualified, file: s.source, rank: RANK_NEIGHBOUR_SKILL });
202
+ }
203
+ const pairs = modalityPairs(sources.flatMap((src) => extractInstructions(src)));
204
+ for (const s of c.skills) {
205
+ const name = s.qualified.split(':').slice(1).join(':') || s.qualified;
206
+ if (ours.has(name)) pairs.push(collisionPair(s.qualified, name));
207
+ }
208
+ return pairs;
209
+ }
210
+
211
+ /** One council seat, run through the council CLI; `null` when it cannot answer. */
212
+ export type Seat = (prompt: string) => string | null;
213
+
214
+ function councilSeat(projectRoot: string): Seat {
215
+ return (prompt) => {
216
+ const stamp = new Date().toISOString().replace(/[:.]/gu, '-');
217
+ const q = path.join(projectRoot, 'agents', 'runtime', 'council', 'questions', `neighbour-contradictions-${stamp}.md`);
218
+ const out = path.join(projectRoot, 'agents', 'runtime', 'council', 'responses', `neighbour-contradictions-${stamp}.md`);
219
+ try {
220
+ fs.mkdirSync(path.dirname(q), { recursive: true });
221
+ fs.writeFileSync(q, prompt, 'utf-8');
222
+ const args = ['council', 'run', q, '--single', '--prompt-mode', 'analysis', '--output', out, '--confirm', '--invocation', 'user_explicit'];
223
+ const res = spawnSync('agent-config', args, { cwd: projectRoot, encoding: 'utf-8' });
224
+ if (res.status !== 0) return null;
225
+ const doc = JSON.parse(fs.readFileSync(out, 'utf-8')) as { responses?: { text?: string }[] };
226
+ return doc.responses?.map((r) => r.text ?? '').join('\n') ?? null;
227
+ } catch {
228
+ return null;
229
+ }
230
+ };
231
+ }
232
+
233
+ /**
234
+ * `--contradictions`: a verdict table, or `n/a` when no council is configured.
235
+ *
236
+ * Report-only — it edits nothing and gates nothing. The council transcript the
237
+ * seat writes lands under gitignored `agents/runtime/council/`; no tracked file
238
+ * changes.
239
+ */
240
+ export function runContradictions(
241
+ projectRoot: string,
242
+ packageRoot: string,
243
+ opts: { homeRoot?: string; seat?: Seat; configured?: boolean } = {},
244
+ ): { lines: string[]; rows: ReviewRow[] | null } {
245
+ const configured =
246
+ opts.configured ?? resolveAvailability(projectRoot, process.env)?.configured ?? false;
247
+ const pairs = contradictionCandidates(projectRoot, packageRoot, opts.homeRoot);
248
+ if (!configured) {
249
+ return {
250
+ lines: [` contradictions: n/a — no council configured (${pairs.length} candidate pair(s) formed, none reviewed)`],
251
+ rows: null,
252
+ };
253
+ }
254
+ if (pairs.length === 0) return { lines: renderReview([]), rows: [] };
255
+ let rubric = '';
256
+ for (const rel of [['dist', 'agent-src', 'rules'], ['src', 'rules']]) {
257
+ try {
258
+ rubric = fs.readFileSync(path.join(packageRoot, ...rel, 'neighbour-precedence.md'), 'utf-8');
259
+ break;
260
+ } catch {
261
+ // Try the next layout.
262
+ }
263
+ }
264
+ const answer = (opts.seat ?? councilSeat(projectRoot))(seatPrompt(pairs, rubric));
265
+ if (answer === null) {
266
+ return { lines: [` contradictions: n/a — the council seat did not answer (${pairs.length} candidate pair(s) formed)`], rows: null };
267
+ }
268
+ const rows = reviewRows(pairs, parseVerdicts(answer, pairs.length));
269
+ return { lines: renderReview(rows), rows };
270
+ }
271
+
147
272
  /** The one line the full `doctor` run prints, linking to this verb. */
148
273
  export function summaryLine(c: NeighbourCensus): string {
149
274
  const counts = [
@@ -218,10 +343,12 @@ export function renderText(c: NeighbourCensus): string[] {
218
343
 
219
344
  export function main(argv: readonly string[] = process.argv.slice(2)): number {
220
345
  let json = false;
346
+ let contradictions = false;
221
347
  let root = process.cwd();
222
348
  let home: string | undefined;
223
349
  for (let i = 0; i < argv.length; i += 1) {
224
350
  if (argv[i] === '--json') json = true;
351
+ else if (argv[i] === '--contradictions') contradictions = true;
225
352
  else if (argv[i] === '--project') {
226
353
  root = argv[i + 1] ?? root;
227
354
  i += 1;
@@ -237,6 +364,12 @@ export function main(argv: readonly string[] = process.argv.slice(2)): number {
237
364
  return 2;
238
365
  }
239
366
  }
367
+ if (contradictions) {
368
+ const r = runContradictions(path.resolve(root), resolvePackageRoot(import.meta.url), home === undefined ? {} : { homeRoot: home });
369
+ if (json) process.stdout.write(`${JSON.stringify({ contradictions: r.rows })}\n`);
370
+ else for (const line of r.lines) process.stdout.write(`${line}\n`);
371
+ return 0;
372
+ }
240
373
  const c = runCensus(path.resolve(root), resolvePackageRoot(import.meta.url), home);
241
374
  if (json) {
242
375
  // Compact, not pretty-printed: this is the machine contract, and the