@event4u/agent-config 9.9.0 → 9.10.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 (384) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +153 -194
  3. package/README.md +1 -1
  4. package/dist/agent-src/commands/agent-status.md +12 -11
  5. package/dist/agent-src/commands/agents/user/accept.md +115 -30
  6. package/dist/agent-src/commands/agents/user/delete.md +147 -0
  7. package/dist/agent-src/commands/agents/user/review.md +65 -28
  8. package/dist/agent-src/commands/agents/user/show.md +82 -29
  9. package/dist/agent-src/commands/agents/user/update.md +2 -2
  10. package/dist/agent-src/commands/agents/user.md +16 -3
  11. package/dist/agent-src/commands/check-current-md.md +0 -10
  12. package/dist/agent-src/commands/condense.md +28 -97
  13. package/dist/agent-src/commands/cost/report.md +7 -0
  14. package/dist/agent-src/commands/fix/portability.md +0 -8
  15. package/dist/agent-src/commands/fix/refs.md +0 -8
  16. package/dist/agent-src/commands/humanize.md +2 -2
  17. package/dist/agent-src/commands/jira-ticket.md +1 -1
  18. package/dist/agent-src/commands/memory/load.md +11 -0
  19. package/dist/agent-src/commands/optimize/skills.md +1 -1
  20. package/dist/agent-src/commands/pr/create.md +4 -4
  21. package/dist/agent-src/commands/profile/show.md +3 -3
  22. package/dist/agent-src/commands/rule-compliance-audit.md +5 -4
  23. package/dist/agent-src/commands/security-audit-config.md +1 -1
  24. package/dist/agent-src/commands/sync/gitignore/fix.md +1 -1
  25. package/dist/agent-src/commands/tdd.md +21 -0
  26. package/dist/agent-src/commands/team/delegate.md +2 -2
  27. package/dist/agent-src/commands/team-knowledge/bootstrap.md +9 -8
  28. package/dist/agent-src/commands/team-knowledge/consolidate.md +8 -7
  29. package/dist/agent-src/commands/team.md +4 -1
  30. package/dist/agent-src/commands/upstream-contribute.md +0 -1
  31. package/dist/agent-src/contexts/authority/commit-mechanics.md +7 -0
  32. package/dist/agent-src/contexts/authority/destructive-mechanics.md +16 -0
  33. package/dist/agent-src/contexts/authority/scope-mechanics.md +61 -0
  34. package/dist/agent-src/contexts/communication/rules-auto/reply-close-mechanics.md +20 -18
  35. package/dist/agent-src/contexts/communication/rules-auto/skill-quality-mechanics.md +1 -1
  36. package/dist/agent-src/contexts/communication/rules-auto/slash-command-routing-policy-mechanics.md +1 -1
  37. package/dist/agent-src/contexts/communication/rules-auto/source-of-truth-mechanics.md +9 -10
  38. package/dist/agent-src/contexts/communication/rules-auto/think-before-action-mechanics.md +1 -1
  39. package/dist/agent-src/contexts/communication/rules-auto/user-interaction-mechanics.md +11 -0
  40. package/dist/agent-src/contexts/contracts/artifact-engagement-flow.md +26 -15
  41. package/dist/agent-src/contexts/contracts/command-suggestion-flow.md +3 -0
  42. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +67 -37
  43. package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +1 -1
  44. package/dist/agent-src/contexts/execution/autonomy-examples.md +1 -1
  45. package/dist/agent-src/contexts/execution/autonomy-mechanics.md +7 -6
  46. package/dist/agent-src/contexts/execution/evidence-discipline.md +92 -77
  47. package/dist/agent-src/contexts/execution/orchestration-benchmark-gate.md +22 -21
  48. package/dist/agent-src/contexts/execution/orchestration-telemetry.md +24 -0
  49. package/dist/agent-src/contexts/execution/project-intelligence.md +122 -103
  50. package/dist/agent-src/contexts/execution/roadmap-execution-contract.md +23 -21
  51. package/dist/agent-src/contexts/execution/subagent-response-contract.md +5 -5
  52. package/dist/agent-src/contexts/execution/subagent-routing.md +11 -0
  53. package/dist/agent-src/contexts/execution/subagent-spawn-contract.md +13 -13
  54. package/dist/agent-src/contexts/execution/subagent-steering.md +36 -34
  55. package/dist/agent-src/contexts/execution/toolchain-resolver.md +1 -1
  56. package/dist/agent-src/contexts/execution/user-memory-channels.md +189 -0
  57. package/dist/agent-src/contexts/execution/verification-mechanics.md +9 -0
  58. package/dist/agent-src/contexts/model-recommendations.md +3 -2
  59. package/dist/agent-src/contexts/subagent-configuration.md +3 -3
  60. package/dist/agent-src/ghostwriter/README.md +2 -2
  61. package/dist/agent-src/packs/README.md +1 -1
  62. package/dist/agent-src/personas/README.md +5 -5
  63. package/dist/agent-src/personas/_template-specialist/persona.md +3 -3
  64. package/dist/agent-src/personas/backend-architect.md +24 -23
  65. package/dist/agent-src/personas/eloquent-tamer.md +30 -30
  66. package/dist/agent-src/personas/frontend-engineer.md +30 -30
  67. package/dist/agent-src/personas/product-owner.md +41 -38
  68. package/dist/agent-src/personas/qa.md +13 -13
  69. package/dist/agent-src/personas/security-engineer.md +22 -22
  70. package/dist/agent-src/presets/README.md +3 -3
  71. package/dist/agent-src/profiles/README.md +3 -3
  72. package/dist/agent-src/rules/active-remediation.md +2 -2
  73. package/dist/agent-src/rules/artifact-engagement-recording.md +4 -4
  74. package/dist/agent-src/rules/ask-when-uncertain.md +0 -4
  75. package/dist/agent-src/rules/augment-edit-discipline.md +1 -1
  76. package/dist/agent-src/rules/broken-access-control.md +4 -4
  77. package/dist/agent-src/rules/code-comment-discipline.md +1 -1
  78. package/dist/agent-src/rules/code-provenance.md +2 -2
  79. package/dist/agent-src/rules/commit-policy.md +4 -9
  80. package/dist/agent-src/rules/communication-through-line.md +5 -5
  81. package/dist/agent-src/rules/decision-revisit-gate.md +1 -1
  82. package/dist/agent-src/rules/doc-screenshot-hygiene.md +1 -1
  83. package/dist/agent-src/rules/domain-adoption-policy.md +1 -1
  84. package/dist/agent-src/rules/domain-safety-pii.md +1 -1
  85. package/dist/agent-src/rules/external-code-graph-interop.md +1 -1
  86. package/dist/agent-src/rules/fast-path-marker-visibility.md +43 -7
  87. package/dist/agent-src/rules/finance-safety-floor.md +1 -1
  88. package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +3 -3
  89. package/dist/agent-src/rules/history-discipline.md +1 -1
  90. package/dist/agent-src/rules/legal-safety-floor.md +1 -1
  91. package/dist/agent-src/rules/lethal-trifecta-guard.md +5 -5
  92. package/dist/agent-src/rules/low-impact-corpus-privacy-floor.md +10 -8
  93. package/dist/agent-src/rules/media-governance-routing.md +13 -13
  94. package/dist/agent-src/rules/media-sync-ground-truth.md +29 -11
  95. package/dist/agent-src/rules/no-cheap-questions.md +7 -7
  96. package/dist/agent-src/rules/no-decorative-emojis-in-git-surfaces.md +29 -18
  97. package/dist/agent-src/rules/non-destructive-by-default.md +5 -23
  98. package/dist/agent-src/rules/onboarding-gate.md +14 -4
  99. package/dist/agent-src/rules/persona-governance.md +2 -2
  100. package/dist/agent-src/rules/prefer-enums-over-literals.md +9 -9
  101. package/dist/agent-src/rules/preservation-guard.md +10 -2
  102. package/dist/agent-src/rules/question-not-instruction.md +1 -1
  103. package/dist/agent-src/rules/roadmap-progress-sync.md +6 -6
  104. package/dist/agent-src/rules/rule-type-governance.md +1 -1
  105. package/dist/agent-src/rules/scale-discipline.md +1 -1
  106. package/dist/agent-src/rules/scope-control.md +1 -1
  107. package/dist/agent-src/rules/secret-vcs-guard.md +1 -1
  108. package/dist/agent-src/rules/security-sensitive-stop.md +17 -11
  109. package/dist/agent-src/rules/senior-engineering-discipline.md +17 -17
  110. package/dist/agent-src/rules/session-canary.md +1 -1
  111. package/dist/agent-src/rules/skill-quality.md +1 -1
  112. package/dist/agent-src/rules/source-confidentiality.md +21 -19
  113. package/dist/agent-src/rules/source-of-truth.md +6 -5
  114. package/dist/agent-src/rules/spreadsheet-source-quality.md +2 -2
  115. package/dist/agent-src/rules/strategy-safety-floor.md +1 -1
  116. package/dist/agent-src/rules/think-before-action.md +5 -5
  117. package/dist/agent-src/rules/token-budget-discipline.md +5 -3
  118. package/dist/agent-src/rules/token-efficiency.md +2 -2
  119. package/dist/agent-src/rules/untrusted-input-defense.md +4 -4
  120. package/dist/agent-src/rules/user-interaction.md +12 -0
  121. package/dist/agent-src/rules/verify-before-complete.md +4 -24
  122. package/dist/agent-src/skills/adversarial-review/SKILL.md +2 -2
  123. package/dist/agent-src/skills/agent-security-review/SKILL.md +52 -45
  124. package/dist/agent-src/skills/agents-md-thin-root/SKILL.md +2 -2
  125. package/dist/agent-src/skills/ai-code-blindspots/SKILL.md +20 -20
  126. package/dist/agent-src/skills/ai-council/SKILL.md +185 -128
  127. package/dist/agent-src/skills/analysis-skill-router/SKILL.md +3 -3
  128. package/dist/agent-src/skills/api-endpoint/SKILL.md +2 -2
  129. package/dist/agent-src/skills/artisan-commands/SKILL.md +2 -2
  130. package/dist/agent-src/skills/async-python-patterns/SKILL.md +8 -7
  131. package/dist/agent-src/skills/authz-review/SKILL.md +16 -15
  132. package/dist/agent-src/skills/aws-infrastructure/SKILL.md +5 -5
  133. package/dist/agent-src/skills/blade-ui/SKILL.md +1 -1
  134. package/dist/agent-src/skills/bug-analyzer/SKILL.md +30 -12
  135. package/dist/agent-src/skills/code-intelligence/SKILL.md +0 -1
  136. package/dist/agent-src/skills/code-intelligence/evals/triggers.json +52 -0
  137. package/dist/agent-src/skills/code-review/SKILL.md +6 -6
  138. package/dist/agent-src/skills/command-routing/SKILL.md +5 -4
  139. package/dist/agent-src/skills/composer-packages/SKILL.md +2 -2
  140. package/dist/agent-src/skills/condense-memory/SKILL.md +43 -41
  141. package/dist/agent-src/skills/context-document/SKILL.md +23 -21
  142. package/dist/agent-src/skills/copilot-config/SKILL.md +6 -1
  143. package/dist/agent-src/skills/decision-record/SKILL.md +20 -18
  144. package/dist/agent-src/skills/design-intelligence/SKILL.md +4 -4
  145. package/dist/agent-src/skills/design-review/SKILL.md +15 -14
  146. package/dist/agent-src/skills/design-system-capture/reference/design-system-json.md +28 -25
  147. package/dist/agent-src/skills/devcontainer/SKILL.md +2 -2
  148. package/dist/agent-src/skills/docker/SKILL.md +1 -1
  149. package/dist/agent-src/skills/docx-authoring/evals/triggers.json +52 -0
  150. package/dist/agent-src/skills/emit-tickets/SKILL.md +2 -2
  151. package/dist/agent-src/skills/error-handling-patterns/SKILL.md +1 -1
  152. package/dist/agent-src/skills/estimate-ticket/SKILL.md +2 -2
  153. package/dist/agent-src/skills/evaluate-llm-feature/SKILL.md +0 -1
  154. package/dist/agent-src/skills/evaluate-llm-feature/evals/triggers.json +52 -0
  155. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +6 -5
  156. package/dist/agent-src/skills/feature-planning/SKILL.md +2 -2
  157. package/dist/agent-src/skills/finishing-a-development-branch/SKILL.md +3 -3
  158. package/dist/agent-src/skills/flux/SKILL.md +1 -1
  159. package/dist/agent-src/skills/frontend-render-security/SKILL.md +13 -13
  160. package/dist/agent-src/skills/git-workflow/SKILL.md +33 -33
  161. package/dist/agent-src/skills/grafana/SKILL.md +5 -0
  162. package/dist/agent-src/skills/humanizer/SKILL.md +83 -66
  163. package/dist/agent-src/skills/humanizer/data/patterns.md +14 -14
  164. package/dist/agent-src/skills/humanizer/references/anti-aiisms.md +4 -4
  165. package/dist/agent-src/skills/judge-artifact-completeness/SKILL.md +82 -37
  166. package/dist/agent-src/skills/judge-bug-hunter/SKILL.md +17 -5
  167. package/dist/agent-src/skills/judge-injection-defense/SKILL.md +63 -25
  168. package/dist/agent-src/skills/judge-security-auditor/SKILL.md +2 -0
  169. package/dist/agent-src/skills/judge-synthesis/SKILL.md +72 -28
  170. package/dist/agent-src/skills/laravel-horizon/SKILL.md +5 -0
  171. package/dist/agent-src/skills/laravel-mail/SKILL.md +5 -4
  172. package/dist/agent-src/skills/laravel-middleware/SKILL.md +5 -4
  173. package/dist/agent-src/skills/laravel-notifications/SKILL.md +10 -9
  174. package/dist/agent-src/skills/laravel-pennant/SKILL.md +1 -1
  175. package/dist/agent-src/skills/laravel-pulse/SKILL.md +9 -8
  176. package/dist/agent-src/skills/laravel-reverb/SKILL.md +6 -5
  177. package/dist/agent-src/skills/laravel-scheduling/SKILL.md +6 -1
  178. package/dist/agent-src/skills/laravel-validation/SKILL.md +12 -0
  179. package/dist/agent-src/skills/launch-readiness/SKILL.md +1 -1
  180. package/dist/agent-src/skills/learning-to-rule-or-skill/SKILL.md +7 -7
  181. package/dist/agent-src/skills/learning-tutor/SKILL.md +44 -43
  182. package/dist/agent-src/skills/learning-tutor/evals/triggers.json +52 -0
  183. package/dist/agent-src/skills/license-compliance-audit/SKILL.md +7 -7
  184. package/dist/agent-src/skills/license-compliance-borrow-check/SKILL.md +3 -3
  185. package/dist/agent-src/skills/license-compliance-credits/SKILL.md +4 -4
  186. package/dist/agent-src/skills/llm-provider-knowledge/SKILL.md +0 -1
  187. package/dist/agent-src/skills/memory-consolidation/SKILL.md +69 -64
  188. package/dist/agent-src/skills/motion-choreographer/SKILL.md +6 -6
  189. package/dist/agent-src/skills/pdf-tools/evals/triggers.json +52 -0
  190. package/dist/agent-src/skills/performance-analysis/SKILL.md +7 -3
  191. package/dist/agent-src/skills/persona-improvement/SKILL.md +0 -2
  192. package/dist/agent-src/skills/persona-improvement/evals/triggers.json +52 -0
  193. package/dist/agent-src/skills/php-coder/SKILL.md +10 -0
  194. package/dist/agent-src/skills/prediction-pool-optimizer/SKILL.md +129 -120
  195. package/dist/agent-src/skills/prediction-pool-optimizer/reference/ev-fixtures.md +36 -35
  196. package/dist/agent-src/skills/prediction-pool-optimizer/reference/odds-and-bonus.md +45 -41
  197. package/dist/agent-src/skills/project-analysis-core/SKILL.md +4 -4
  198. package/dist/agent-src/skills/project-analysis-hypothesis-driven/SKILL.md +3 -3
  199. package/dist/agent-src/skills/project-analysis-react/SKILL.md +1 -1
  200. package/dist/agent-src/skills/project-analysis-symfony/SKILL.md +1 -1
  201. package/dist/agent-src/skills/project-analysis-zend-laminas/SKILL.md +2 -2
  202. package/dist/agent-src/skills/prompt-engineering-patterns/SKILL.md +1 -1
  203. package/dist/agent-src/skills/prompt-validator/SKILL.md +39 -39
  204. package/dist/agent-src/skills/quality-tools/SKILL.md +15 -15
  205. package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +55 -19
  206. package/dist/agent-src/skills/react-shadcn-ui/reference/registry.md +29 -27
  207. package/dist/agent-src/skills/readme-writing-package/SKILL.md +2 -2
  208. package/dist/agent-src/skills/reasoning-orchestrator/SKILL.md +25 -25
  209. package/dist/agent-src/skills/recursive-verification/SKILL.md +6 -5
  210. package/dist/agent-src/skills/refine-prompt/SKILL.md +1 -1
  211. package/dist/agent-src/skills/refine-ticket/SKILL.md +20 -2
  212. package/dist/agent-src/skills/repomix-packer/SKILL.md +1 -1
  213. package/dist/agent-src/skills/requesting-code-review/SKILL.md +2 -2
  214. package/dist/agent-src/skills/roadmap-management/SKILL.md +80 -66
  215. package/dist/agent-src/skills/roadmap-writing/SKILL.md +84 -77
  216. package/dist/agent-src/skills/rule-refactor/SKILL.md +1 -1
  217. package/dist/agent-src/skills/screenshot-hygiene/evals/triggers.json +52 -0
  218. package/dist/agent-src/skills/security-audit/SKILL.md +26 -9
  219. package/dist/agent-src/skills/security-maturity-assessment/SKILL.md +38 -16
  220. package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +14 -11
  221. package/dist/agent-src/skills/skill-writing/SKILL.md +9 -8
  222. package/dist/agent-src/skills/song-to-script/SKILL.md +93 -85
  223. package/dist/agent-src/skills/sql-writing/SKILL.md +2 -2
  224. package/dist/agent-src/skills/stakeholder-tradeoff/SKILL.md +4 -3
  225. package/dist/agent-src/skills/standards-from-config/SKILL.md +61 -43
  226. package/dist/agent-src/skills/subagent-orchestration/SKILL.md +22 -8
  227. package/dist/agent-src/skills/subagent-orchestration/prompts/README.md +28 -2
  228. package/dist/agent-src/skills/supply-chain-intake/SKILL.md +13 -13
  229. package/dist/agent-src/skills/systematic-debugging/SKILL.md +22 -21
  230. package/dist/agent-src/skills/tailwind-engineer/SKILL.md +1 -1
  231. package/dist/agent-src/skills/technical-specification/SKILL.md +5 -0
  232. package/dist/agent-src/skills/terraform/SKILL.md +2 -2
  233. package/dist/agent-src/skills/terragrunt/SKILL.md +8 -8
  234. package/dist/agent-src/skills/testing-anti-patterns/process-anti-patterns.md +1 -1
  235. package/dist/agent-src/skills/threat-modeling/SKILL.md +19 -13
  236. package/dist/agent-src/skills/universal-project-analysis/SKILL.md +1 -1
  237. package/dist/agent-src/skills/upstream-contribute/SKILL.md +0 -1
  238. package/dist/agent-src/skills/using-git-worktrees/SKILL.md +9 -9
  239. package/dist/agent-src/skills/validate-feature-fit/SKILL.md +3 -1
  240. package/dist/agent-src/skills/verify-completion-evidence/SKILL.md +4 -6
  241. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +67 -61
  242. package/dist/agent-src/skills/video-director/SKILL.md +7 -7
  243. package/dist/agent-src/skills/worktree-lifecycle/SKILL.md +3 -3
  244. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  245. package/dist/agent-src/templates/contexts/knowledge-pages.md +47 -45
  246. package/dist/agent-src/templates/contexts/lesson-card.md +2 -2
  247. package/dist/agent-src/templates/contexts/tenant-boundaries.md +2 -2
  248. package/dist/agent-src/templates/contexts.md +1 -1
  249. package/dist/agent-src/templates/features.md +1 -1
  250. package/dist/agent-src/templates/roadmaps.md +125 -116
  251. package/dist/agent-src/templates/rule.md +2 -1
  252. package/dist/agent-src/templates/scripts/pr_risk_review.ts +0 -0
  253. package/dist/agent-src/templates/scripts/telemetry/aggregator.ts +0 -0
  254. package/dist/agent-src/templates/scripts/tier_usage_report.ts +2 -2
  255. package/dist/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +2 -2
  256. package/dist/agent-src/templates/scripts/work_engine/directives/ui/review.ts +1 -1
  257. package/dist/agent-src/user-types/README.md +8 -8
  258. package/dist/agent-src/user-types/galabau-field-crew.md +34 -33
  259. package/dist/agent-src/user-types/metalworking-shop.md +35 -34
  260. package/dist/agent-src/user-types/truck-driver.md +22 -20
  261. package/dist/cli/python/workspace_roles.js +2 -2
  262. package/dist/cli/python/workspace_roles.js.map +1 -1
  263. package/dist/discovery/deprecation-report.md +1 -1
  264. package/dist/discovery/discovery-manifest.json +88 -62
  265. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  266. package/dist/discovery/discovery-manifest.summary.md +3 -3
  267. package/dist/discovery/orphan-report.md +1 -1
  268. package/dist/discovery/packs.json +6 -5
  269. package/dist/discovery/trust-report.md +2 -2
  270. package/dist/discovery/workspaces.json +5 -4
  271. package/dist/hooks/dispatch.js +186 -12
  272. package/dist/install/install.mjs +8 -0
  273. package/dist/mcp/registry-manifest.json +3 -3
  274. package/dist/mcp/server.json +2 -2
  275. package/dist/mcp/server.mjs +1199 -857
  276. package/dist/router.json +1 -1
  277. package/dist/scripts/_lib/compile_time_toggles.js +48 -0
  278. package/dist/scripts/_lib/compile_time_toggles.js.map +1 -0
  279. package/dist/scripts/condense.js +234 -217
  280. package/dist/scripts/condense.js.map +1 -1
  281. package/dist/server/schemas/settings.js +4 -0
  282. package/dist/server/schemas/settings.js.map +1 -1
  283. package/dist/shared/userMd/utils.js +30 -0
  284. package/dist/shared/userMd/utils.js.map +1 -1
  285. package/dist/ui/assets/index-BpSQt5vm.js.map +1 -1
  286. package/docs/guidelines/agent-infra/api-cost-levers.md +56 -5
  287. package/docs/guidelines/agent-infra/simplicity-and-goal-demos.md +93 -33
  288. package/package.json +1 -1
  289. package/src/agent-src/templates/scripts/pr_risk_review.ts +0 -0
  290. package/src/agent-src/templates/scripts/telemetry/aggregator.ts +0 -0
  291. package/src/agent-src/templates/scripts/tier_usage_report.ts +2 -2
  292. package/src/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +2 -2
  293. package/src/agent-src/templates/scripts/work_engine/directives/ui/review.ts +1 -1
  294. package/src/config/agent-settings.template.yml +32 -2
  295. package/src/config/ci-local-parity.yml +142 -0
  296. package/src/config/gate-coverage.yml +127 -0
  297. package/src/config/preamble-payload-budget.json +44 -0
  298. package/src/scripts/_cli/cmd_doctor.ts +78 -2
  299. package/src/scripts/_lib/agent_user_profile.ts +381 -0
  300. package/src/scripts/_lib/agents_overlay.ts +9 -0
  301. package/src/scripts/_lib/anchor_eval.ts +311 -0
  302. package/src/scripts/_lib/cc_transcript.ts +316 -0
  303. package/src/scripts/_lib/compile_time_toggles.ts +79 -0
  304. package/src/scripts/_lib/confusables.ts +101 -0
  305. package/src/scripts/_lib/duplicate_scope_census.ts +77 -0
  306. package/src/scripts/_lib/managed_agents_folder.ts +181 -0
  307. package/src/scripts/_lib/payload_hash_drift.ts +126 -0
  308. package/src/scripts/_lib/preservation_migration.ts +291 -0
  309. package/src/scripts/_lib/retrieval_sanitize.ts +166 -2
  310. package/src/scripts/_lib/scan_scope.ts +115 -0
  311. package/src/scripts/_lib/user_global_memory_audit.ts +187 -0
  312. package/src/scripts/_lib/user_global_observations.ts +830 -0
  313. package/src/scripts/_lib/user_global_revocations.ts +110 -0
  314. package/src/scripts/_lib/user_memory_gate_counters.ts +291 -0
  315. package/src/scripts/ai_council/blind_review.ts +0 -0
  316. package/src/scripts/ai_council/budget_guard.ts +90 -11
  317. package/src/scripts/ai_council/bundler.ts +2 -2
  318. package/src/scripts/ai_council/clients.ts +59 -3
  319. package/src/scripts/ai_council/config.ts +38 -0
  320. package/src/scripts/ai_council/orchestrator.ts +54 -9
  321. package/src/scripts/ai_team/team_dispatch.ts +17 -6
  322. package/src/scripts/anchor_eval_falsify.ts +198 -0
  323. package/src/scripts/anchor_scoring_run.ts +239 -0
  324. package/src/scripts/annotate_discovery.ts +1 -65
  325. package/src/scripts/bench_quality_run.ts +168 -4
  326. package/src/scripts/cache_realization_report.ts +782 -0
  327. package/src/scripts/check_artefact_count_messaging.ts +5 -1
  328. package/src/scripts/check_augment_description_cap.ts +15 -4
  329. package/src/scripts/check_ci_local_parity.ts +317 -0
  330. package/src/scripts/check_condensation.ts +96 -191
  331. package/src/scripts/check_context_paths.ts +38 -9
  332. package/src/scripts/check_gate_coverage.ts +299 -0
  333. package/src/scripts/check_iron_law_prominence.ts +22 -1
  334. package/src/scripts/check_kernel_prefix_stability.ts +0 -0
  335. package/src/scripts/check_no_new_legacy_path.ts +16 -6
  336. package/src/scripts/check_no_roadmap_refs.ts +22 -9
  337. package/src/scripts/check_originality_freshness.ts +167 -0
  338. package/src/scripts/check_preamble_payload_budget.ts +130 -0
  339. package/src/scripts/check_proposal.ts +0 -0
  340. package/src/scripts/check_references.ts +0 -1
  341. package/src/scripts/check_safety_floor_untouched.ts +171 -24
  342. package/src/scripts/check_site_links.ts +62 -3
  343. package/src/scripts/ci_status.ts +0 -0
  344. package/src/scripts/cluster_near_miss_patterns.ts +0 -0
  345. package/src/scripts/code_graph/build.ts +0 -0
  346. package/src/scripts/command_suggester/types.ts +0 -0
  347. package/src/scripts/compile_router.ts +10 -14
  348. package/src/scripts/condense.sh +3 -4
  349. package/src/scripts/condense.ts +247 -228
  350. package/src/scripts/cost/track.mjs +168 -33
  351. package/src/scripts/cost_summary.ts +33 -1
  352. package/src/scripts/council_cli.ts +45 -3
  353. package/src/scripts/discovery_graph.ts +0 -0
  354. package/src/scripts/encoding_corpus.ts +500 -0
  355. package/src/scripts/encoding_corpus_report.ts +216 -0
  356. package/src/scripts/generate_index.ts +19 -2
  357. package/src/scripts/install-hooks.sh +2 -2
  358. package/src/scripts/learning_sidecar.ts +0 -0
  359. package/src/scripts/lint_confusables.ts +10 -72
  360. package/src/scripts/lint_featured_skills.ts +0 -0
  361. package/src/scripts/lint_hidden_unicode.ts +208 -0
  362. package/src/scripts/lint_load_context.ts +17 -5
  363. package/src/scripts/lint_new_skill_gate.ts +9 -3
  364. package/src/scripts/lint_no_python_twin_rationale.ts +17 -2
  365. package/src/scripts/lint_originality.ts +1 -1
  366. package/src/scripts/lint_skill_originality.ts +1 -1
  367. package/src/scripts/lint_ticket_buildable.ts +1 -1
  368. package/src/scripts/mcp_server/tools.ts +4 -4
  369. package/src/scripts/measure_scope_dedup.ts +224 -0
  370. package/src/scripts/memory_lookup.ts +0 -0
  371. package/src/scripts/mine_session.ts +98 -0
  372. package/src/scripts/orchestration_payload_hash_drift.ts +145 -0
  373. package/src/scripts/preamble_byte_census.ts +574 -0
  374. package/src/scripts/probe_skill_registration.ts +2 -2
  375. package/src/scripts/redact_hook_capture.ts +13 -0
  376. package/src/scripts/release.ts +65 -10
  377. package/src/scripts/router_telemetry.ts +1 -1
  378. package/src/scripts/second_brain_retrieval.ts +14 -4
  379. package/src/scripts/skill_linter.ts +5 -0
  380. package/src/scripts/surface-tiers.yml +2 -0
  381. package/src/scripts/validate_pack_yaml.ts +0 -0
  382. package/src/server/schemas/settings.ts +8 -0
  383. package/src/shared/userMd/utils.ts +31 -0
  384. package/dist/agent-src/rules/telegraph-speak.md +0 -87
@@ -0,0 +1,130 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * Ratchet gate for the per-spawn preamble payload (road-to-cache-economy
4
+ * Phase 3, unblocked by C-3 measuring 38.0% against a 15% bar).
5
+ *
6
+ * WHY A RATCHET AND NOT THE ROADMAP'S LITERAL NUMBERS
7
+ * ---------------------------------------------------
8
+ * The roadmap's candidate ceiling (median 40k / p95 50k) is anchored to an
9
+ * upstream ~37k cold start. This package's own deterministic in-repo payload is
10
+ * ~102.8k tokens, so a hard 40k gate would be red the day it lands — and a gate
11
+ * that is always red trains the reader to ignore it, which is precisely the
12
+ * failure the gates-that-can-fail work exists to prevent. So this fails on
13
+ * GROWTH: the number can only walk down, and the 40k/50k target stays recorded
14
+ * in the budget file as the destination.
15
+ *
16
+ * Only deterministic, in-repo buckets are gated. User-scope rules depend on what
17
+ * the developer happens to have installed globally, and the tool-definition
18
+ * bucket has no local source at all — the census reports that one as an explicit
19
+ * residual rather than pretending to measure it.
20
+ *
21
+ * Exit codes: 0 within budget · 1 over budget · 2 misuse / unreadable budget.
22
+ */
23
+ import * as fs from 'node:fs';
24
+ import * as path from 'node:path';
25
+
26
+ import { censusClaudeMdHierarchy, censusRuleDir, censusSkillsCatalog } from './preamble_byte_census.js';
27
+
28
+ const HERE = path.dirname(new URL(import.meta.url).pathname);
29
+ const REPO_ROOT = path.resolve(HERE, '..', '..');
30
+ const BUDGET_FILE = path.join(REPO_ROOT, 'src', 'config', 'preamble-payload-budget.json');
31
+
32
+ interface Budget {
33
+ baseline_tokens: number;
34
+ headroom_pct: number;
35
+ target_tokens: { median: number; p95: number };
36
+ }
37
+
38
+ export interface BudgetVerdict {
39
+ measured: number;
40
+ baseline: number;
41
+ ceiling: number;
42
+ withinBudget: boolean;
43
+ buckets: Array<{ name: string; tokens: number }>;
44
+ }
45
+
46
+ function tokens(chars: number): number {
47
+ return Math.round(chars / 4);
48
+ }
49
+
50
+ export function readBudget(file: string = BUDGET_FILE): Budget {
51
+ const raw = JSON.parse(fs.readFileSync(file, 'utf-8')) as Record<string, unknown>;
52
+ const baseline = Number(raw['baseline_tokens']);
53
+ const headroom = Number(raw['headroom_pct']);
54
+ if (!Number.isFinite(baseline) || !Number.isFinite(headroom)) {
55
+ throw new Error(`${file}: baseline_tokens and headroom_pct must both be numbers`);
56
+ }
57
+ const target = (raw['target_tokens'] ?? {}) as Record<string, unknown>;
58
+ return {
59
+ baseline_tokens: baseline,
60
+ headroom_pct: headroom,
61
+ target_tokens: { median: Number(target['median']), p95: Number(target['p95']) },
62
+ };
63
+ }
64
+
65
+ /** Measure only what the repo tree determines — no `~`, no transcripts, no network. */
66
+ export function measureDeterministicPayload(
67
+ repoRoot: string = REPO_ROOT,
68
+ ): Array<{ name: string; tokens: number }> {
69
+ const projectRules = censusRuleDir(path.join(repoRoot, 'dist', 'agent-src', 'rules'));
70
+ const skills = censusSkillsCatalog(path.join(repoRoot, 'dist', 'agent-src', 'skills'));
71
+ // Only the PROJECT half of the CLAUDE.md hierarchy is deterministic — the
72
+ // user file and its @-imports live on whatever machine runs this.
73
+ const claudeMd = censusClaudeMdHierarchy(repoRoot, path.join(repoRoot, '.no-such-home'));
74
+ const projectClaudeMdChars =
75
+ claudeMd.project_claude_md_chars + claudeMd.project_claude_local_md_chars;
76
+ return [
77
+ { name: 'project-scope rules', tokens: tokens(projectRules.chars) },
78
+ { name: 'preloaded skills catalog', tokens: tokens(skills.chars) },
79
+ { name: 'CLAUDE.md hierarchy (project only)', tokens: tokens(projectClaudeMdChars) },
80
+ ];
81
+ }
82
+
83
+ export function evaluate(repoRoot?: string, budgetFile?: string): BudgetVerdict {
84
+ const budget = readBudget(budgetFile);
85
+ const buckets = measureDeterministicPayload(repoRoot);
86
+ const measured = buckets.reduce((sum, b) => sum + b.tokens, 0);
87
+ const ceiling = Math.round(budget.baseline_tokens * (1 + budget.headroom_pct / 100));
88
+ return { measured, baseline: budget.baseline_tokens, ceiling, withinBudget: measured <= ceiling, buckets };
89
+ }
90
+
91
+ export function main(argv: string[] = process.argv.slice(2)): number {
92
+ const json = argv.includes('--format=json') || argv.includes('--json');
93
+ let verdict: BudgetVerdict;
94
+ try {
95
+ verdict = evaluate();
96
+ } catch (err) {
97
+ process.stderr.write(`❌ preamble-payload budget: ${(err as Error).message}\n`);
98
+ return 2;
99
+ }
100
+
101
+ if (json) {
102
+ process.stdout.write(JSON.stringify(verdict, null, 2) + '\n');
103
+ return verdict.withinBudget ? 0 : 1;
104
+ }
105
+
106
+ for (const b of verdict.buckets) {
107
+ process.stdout.write(` ${b.name.padEnd(38)} ${String(b.tokens).padStart(8)} tok\n`);
108
+ }
109
+ const delta = verdict.measured - verdict.baseline;
110
+ const sign = delta >= 0 ? '+' : '';
111
+ process.stdout.write(
112
+ ` ${'measured total'.padEnd(38)} ${String(verdict.measured).padStart(8)} tok ` +
113
+ `(baseline ${verdict.baseline}, ${sign}${delta}; ceiling ${verdict.ceiling})\n`,
114
+ );
115
+ if (!verdict.withinBudget) {
116
+ process.stderr.write(
117
+ `❌ per-spawn preamble payload grew past the ratchet: ${verdict.measured} > ${verdict.ceiling} tok.\n` +
118
+ ` Every rule and skill description here is re-written on EVERY subagent spawn, so growth\n` +
119
+ ` is paid per spawn, not once. Either shrink the addition, or raise baseline_tokens in\n` +
120
+ ` src/config/preamble-payload-budget.json with the reason in the same commit.\n`,
121
+ );
122
+ return 1;
123
+ }
124
+ process.stdout.write('✅ per-spawn preamble payload within the ratchet.\n');
125
+ return 0;
126
+ }
127
+
128
+ if (process.argv[1] !== undefined && import.meta.url === `file://${process.argv[1]}`) {
129
+ process.exit(main());
130
+ }
Binary file
@@ -179,7 +179,6 @@ const EXAMPLE_PATH_PATTERNS: RegExp[] = [
179
179
  /skills\/[\w-]+\.md/, // short skill refs in examples (not SKILL.md path)
180
180
  /skills\/[\w-]+\/SKILL\.md/, // example skill paths in commands
181
181
  /\{/, // template placeholders like {module}
182
- /\.condensation-hashes\.json/, // JSON file, not .md
183
182
  /-foo\.(md|json|yml|yaml)$/, // `-foo.<ext>` placeholder examples
184
183
  /-bar\.(md|json|yml|yaml)$/, // `-bar.<ext>` placeholder examples
185
184
  // ── docs/+src/ illustrative example paths (Phase-0 step 7a) ──
@@ -9,24 +9,62 @@
9
9
  * messages, the same git plumbing and the same `origin/main` → `main`
10
10
  * fallback. Historical quirks are preserved deliberately — tests and downstream consumers pin the exact behaviour.
11
11
  *
12
- * Per Q3=A locked decision (council Round 3, 2026-05-03), the four
13
- * safety-floor always-rules are out of scope for Phase 2A slimming:
12
+ * The four safety-floor always-rules it guards:
14
13
  * - non-destructive-by-default
15
14
  * - commit-policy
16
15
  * - scope-control
17
16
  * - verify-before-complete
18
17
  *
19
- * Exit codes: 0 = clean (or skipped — see `--skip-if-no-baseline`),
20
- * 1 = safety-floor file modified, 3 = internal error.
18
+ * NARROWED 2026-07-31 (ADR-203). The Q3=A decision (council Round 3,
19
+ * 2026-05-03) put these rules out of scope for Phase-2A slimming, and the guard
20
+ * implemented that as "no edits at all". That over-shot: it also blocked
21
+ * preservation-conforming P4 migrations, which move lookup material into a
22
+ * declared `load_context:` target without losing anything — and since the two
23
+ * kernel rules over their budget caps are guarded files, the pairing had no
24
+ * legal state at all.
25
+ *
26
+ * The lock now blocks SUBSTANTIVE changes and exempts proven migrations. Proven
27
+ * is the load-bearing word: `_lib/preservation_migration.ts` CHECKS that every
28
+ * paragraph, list item and fenced block survives — in the rule (telegraph
29
+ * condensation allowed) or verbatim in a declared context — with Iron Law
30
+ * headings holding their level and Iron Law fences byte-exact. No label, no
31
+ * commit-message attestation, no honour system: unprovable ⇒ substantive ⇒
32
+ * blocked.
33
+ *
34
+ * Exit codes: 0 = clean, skipped, or verified migration,
35
+ * 1 = substantive safety-floor change, 3 = internal error.
21
36
  */
22
37
  import { spawnSync } from 'node:child_process';
23
38
  import * as path from 'node:path';
24
39
  import * as fs from 'node:fs';
25
40
  import { fileURLToPath, pathToFileURL } from 'node:url';
26
41
 
42
+ import { assertWatchlistResolves } from './_lib/scan_scope.js';
43
+ import {
44
+ load_context_targets,
45
+ verify_migration,
46
+ type Finding,
47
+ } from './_lib/preservation_migration.js';
48
+
27
49
  const _HERE = fileURLToPath(import.meta.url);
28
50
  const REPO_ROOT = path.resolve(path.dirname(_HERE), '..', '..');
29
- const RULES_DIR_REL = '.agent-src.uncondensed/rules';
51
+ /**
52
+ * Root the four floor rules live under (ADR-051).
53
+ *
54
+ * Until 2026-07-29 this named the retired source container, so the guard
55
+ * compared diffs against paths absent from every commit and reported
56
+ * `✅ Safety-floor untouched (4 rules guarded)` no matter what was edited.
57
+ * `assertWatchlistResolves` below now makes that state a loud failure instead
58
+ * of a clean bill of health.
59
+ *
60
+ * A first pass also kept the legacy path "in case a pre-ADR-051 baseline names
61
+ * it". That was speculative — CI always diffs against current `main` — and it
62
+ * tripped `check_no_new_legacy_path`, which is right: the source of truth is
63
+ * `src/`, and a dead path kept alive for an unmeasured scenario is how the
64
+ * original defect survived.
65
+ */
66
+ const RULES_DIR_REL = 'src/rules';
67
+ const RULES_DIRS_REL = [RULES_DIR_REL] as const;
30
68
  const SAFETY_FLOOR = [
31
69
  'non-destructive-by-default.md',
32
70
  'commit-policy.md',
@@ -34,6 +72,17 @@ const SAFETY_FLOOR = [
34
72
  'verify-before-complete.md',
35
73
  ] as const;
36
74
 
75
+ /** Every repo-relative path this guard watches, across all known roots. */
76
+ function _floor_candidates(): string[] {
77
+ return RULES_DIRS_REL.flatMap((dir) => SAFETY_FLOOR.map((name) => `${dir}/${name}`));
78
+ }
79
+
80
+ /** Which of `changed` are guarded floor files. Pure — the gate's whole decision. */
81
+ function _breaches(changed: readonly string[]): string[] {
82
+ const floorPaths = new Set(_floor_candidates());
83
+ return changed.filter((p) => floorPaths.has(p)).sort();
84
+ }
85
+
37
86
  function _run_git(args: string[]): [number, string] {
38
87
  const proc = spawnSync('git', args, {
39
88
  cwd: REPO_ROOT,
@@ -43,13 +92,26 @@ function _run_git(args: string[]): [number, string] {
43
92
  return [code, (proc.stdout ?? '') + (proc.stderr ?? '')];
44
93
  }
45
94
 
95
+ /** File content at `ref`, or null when the path does not exist there. */
96
+ function _git_show(ref: string, path: string): string | null {
97
+ const [code, out] = _run_git(["show", `${ref}:${path}`]);
98
+ return code === 0 ? out : null;
99
+ }
100
+
46
101
  function _baseline_exists(ref: string): boolean {
47
102
  const [code] = _run_git(['rev-parse', '--verify', '--quiet', ref]);
48
103
  return code === 0;
49
104
  }
50
105
 
51
- function _changed_files(baseline: string): string[] {
52
- const [code, output] = _run_git(['diff', '--name-only', `${baseline}...HEAD`]);
106
+ /**
107
+ * Files changed between `baseline` and `head`.
108
+ *
109
+ * `head` is parameterised (default `HEAD`) so the guard is verifiable against a
110
+ * real historical range — without it the only way to exercise a breach was to
111
+ * manufacture a commit, which is why this gate shipped untested for months.
112
+ */
113
+ function _changed_files(baseline: string, head = 'HEAD'): string[] {
114
+ const [code, output] = _run_git(['diff', '--name-only', `${baseline}...${head}`]);
53
115
  if (code !== 0) {
54
116
  throw new Error(`git diff failed: ${output}`);
55
117
  }
@@ -61,11 +123,12 @@ function _changed_files(baseline: string): string[] {
61
123
 
62
124
  interface ParsedArgs {
63
125
  baseline: string;
126
+ head: string;
64
127
  skip_if_no_baseline: boolean;
65
128
  }
66
129
 
67
130
  function parse_args(argv: readonly string[]): ParsedArgs {
68
- const args: ParsedArgs = { baseline: 'origin/main', skip_if_no_baseline: false };
131
+ const args: ParsedArgs = { baseline: 'origin/main', head: 'HEAD', skip_if_no_baseline: false };
69
132
  for (let i = 0; i < argv.length; i++) {
70
133
  const arg = argv[i]!;
71
134
  if (arg === '--baseline') {
@@ -79,11 +142,22 @@ function parse_args(argv: readonly string[]): ParsedArgs {
79
142
  args.baseline = v;
80
143
  } else if (arg.startsWith('--baseline=')) {
81
144
  args.baseline = arg.slice('--baseline='.length);
145
+ } else if (arg === '--head') {
146
+ const v = argv[++i];
147
+ if (v === undefined) {
148
+ process.stderr.write(
149
+ 'check_safety_floor_untouched: error: argument --head: expected one argument\n',
150
+ );
151
+ process.exit(2);
152
+ }
153
+ args.head = v;
154
+ } else if (arg.startsWith('--head=')) {
155
+ args.head = arg.slice('--head='.length);
82
156
  } else if (arg === '--skip-if-no-baseline') {
83
157
  args.skip_if_no_baseline = true;
84
158
  } else if (arg === '-h' || arg === '--help') {
85
159
  process.stdout.write(
86
- 'usage: check_safety_floor_untouched [-h] [--baseline BASELINE] [--skip-if-no-baseline]\n',
160
+ 'usage: check_safety_floor_untouched [-h] [--baseline BASELINE] [--head HEAD] [--skip-if-no-baseline]\n',
87
161
  );
88
162
  process.exit(0);
89
163
  } else {
@@ -118,34 +192,97 @@ function main(): number {
118
192
 
119
193
  let changed: string[];
120
194
  try {
121
- changed = _changed_files(args.baseline);
195
+ changed = _changed_files(args.baseline, args.head);
122
196
  } catch (exc) {
123
197
  const msg = exc instanceof Error ? exc.message : String(exc);
124
198
  process.stderr.write(`❌ ${msg}\n`);
125
199
  return 3;
126
200
  }
127
201
 
128
- const floorPaths = new Set(SAFETY_FLOOR.map((name) => `${RULES_DIR_REL}/${name}`));
129
- const breaches = changed.filter((p) => floorPaths.has(p)).sort();
202
+ // Scope assertion BEFORE the comparison: if none of the guarded paths exist
203
+ // on disk, this guard cannot fire and must say so loudly rather than
204
+ // reporting a clean floor it never looked at.
205
+ let guarded: string[];
206
+ try {
207
+ guarded = assertWatchlistResolves({
208
+ gate: 'check_safety_floor_untouched',
209
+ candidates: _floor_candidates(),
210
+ repoRoot: REPO_ROOT,
211
+ });
212
+ } catch (exc) {
213
+ const msg = exc instanceof Error ? exc.message : String(exc);
214
+ process.stderr.write(`❌ ${msg}\n`);
215
+ return 3;
216
+ }
217
+
218
+ const breaches = _breaches(changed);
130
219
 
131
220
  if (breaches.length) {
132
- process.stderr.write(
133
- '❌ Safety-floor rule(s) modified — Phase 2A is not allowed to ' +
134
- 'touch these (Q3=A locked decision):\n',
135
- );
221
+ // ADR-203: the lock narrowed from "no edits" to "no SUBSTANTIVE edits".
222
+ // A preservation-conforming P4 migration is exempt — but only when the
223
+ // guard can PROVE it is one. Anything unprovable is substantive.
224
+ const blocked: Array<[string, Finding[]]> = [];
136
225
  for (const p of breaches) {
137
- process.stderr.write(` ${p}\n`);
226
+ const base = _git_show(args.baseline, p);
227
+ const head = _git_show(args.head, p);
228
+ if (base === null || head === null) {
229
+ blocked.push([p, [{ code: 'passage-lost', detail: 'file added or deleted — not a migration' }]]);
230
+ continue;
231
+ }
232
+ const headContexts = new Map<string, string>();
233
+ const baseContexts = new Map<string, string>();
234
+ for (const rel of load_context_targets(head)) {
235
+ const target = `src/agent-src/${rel}`;
236
+ const h = _git_show(args.head, target);
237
+ if (h !== null) headContexts.set(target, h);
238
+ const b = _git_show(args.baseline, target);
239
+ baseContexts.set(target, b ?? '');
240
+ }
241
+ const findings = verify_migration({
242
+ base_rule: base,
243
+ head_rule: head,
244
+ head_contexts: headContexts,
245
+ base_contexts: baseContexts,
246
+ });
247
+ if (findings.length) blocked.push([p, findings]);
138
248
  }
139
- process.stderr.write(
140
- '\n Lift via the two-gate rollback documented in ' +
141
- 'agents/roadmaps/road-to-structural-optimization.md ' +
142
- '§ Phase 2A Abort/rollback.\n',
249
+
250
+ if (blocked.length) {
251
+ process.stderr.write(
252
+ '❌ Substantive change to safety-floor rule(s) — blocked (ADR-203 ' +
253
+ 'narrowed the Q3=A lock; only PROVEN preservation-conforming P4 ' +
254
+ 'migrations are exempt):\n',
255
+ );
256
+ for (const [p, findings] of blocked) {
257
+ process.stderr.write(`\n ${p}\n`);
258
+ for (const f of findings) {
259
+ process.stderr.write(` · [${f.code}] ${f.detail}\n`);
260
+ }
261
+ }
262
+ process.stderr.write(
263
+ '\n A migration must leave every paragraph, list item and fenced block\n' +
264
+ ' either in the rule (telegraph condensation is fine) or verbatim in a\n' +
265
+ ' declared load_context: target. Iron Law headings keep their level and\n' +
266
+ ' Iron Law fences stay byte-exact. Unprovable ⇒ substantive ⇒ blocked.\n',
267
+ );
268
+ return 1;
269
+ }
270
+
271
+ process.stdout.write(
272
+ `✅ Safety-floor edit(s) verified as preservation-conforming P4 migration ` +
273
+ `(${breaches.length} rule file(s); every passage accounted for):\n`,
143
274
  );
144
- return 1;
275
+ for (const p of breaches) {
276
+ process.stdout.write(` ${p}\n`);
277
+ }
278
+ return 0;
145
279
  }
146
280
 
281
+ // Report the RESOLVED count, not the declared one — the old message printed
282
+ // `SAFETY_FLOOR.length` unconditionally, so it claimed 4 guarded rules while
283
+ // guarding zero.
147
284
  process.stdout.write(
148
- `✅ Safety-floor untouched (${SAFETY_FLOOR.length} rules guarded ` +
285
+ `✅ Safety-floor untouched (${guarded.length} rule file(s) guarded ` +
149
286
  `vs. ${args.baseline}).\n`,
150
287
  );
151
288
  return 0;
@@ -177,4 +314,14 @@ if (_isCliEntry() || process.argv[1] === _HERE) {
177
314
  process.exit(main());
178
315
  }
179
316
 
180
- export { REPO_ROOT, RULES_DIR_REL, SAFETY_FLOOR, _baseline_exists, _changed_files, main };
317
+ export {
318
+ REPO_ROOT,
319
+ RULES_DIR_REL,
320
+ RULES_DIRS_REL,
321
+ SAFETY_FLOOR,
322
+ _baseline_exists,
323
+ _breaches,
324
+ _changed_files,
325
+ _floor_candidates,
326
+ main,
327
+ };
@@ -10,8 +10,9 @@
10
10
  * (`http(s):`, `mailto:`, `data:`, protocol-relative `//`) links and pure `#`
11
11
  * anchors are skipped — this gate owns *internal* integrity only.
12
12
  *
13
- * Read-only. Exit 0 clean / 1 on any broken internal link, 2 if the site has not
14
- * been built yet (run `cd site && npm run build` first).
13
+ * Read-only. Exit 0 clean / 1 on any broken internal link, 2 if the build is
14
+ * missing OR stale (run `cd site && npm run build` first). Staleness matters as much
15
+ * as absence: a green verdict over an old partial build is a gate that cannot fail.
15
16
  *
16
17
  * Usage:
17
18
  * ./scripts-run src/scripts/check_site_links # scan site/dist
@@ -117,19 +118,77 @@ export function main(argv: string[] = process.argv.slice(2)): number {
117
118
  process.stderr.write(`❌ site not built: ${distDir} is missing. Run \`cd site && npm ci && npm run build\` first.\n`);
118
119
  return 2;
119
120
  }
121
+ // A missing dist was already an exit-2; a STALE one was not, so the checker
122
+ // reported green over an old partial build (measured: 6 pages against 25 content
123
+ // sources, every source newer than the build). Green over a build that does not
124
+ // contain the pages being checked is worse than red — it is a gate that cannot
125
+ // fail. Same silent-green class as the per-pack matrix removed alongside this.
126
+ const stale = _stalenessVerdict(distDir);
127
+ if (stale !== null) {
128
+ process.stderr.write(`❌ site build is stale: ${stale}. Run \`cd site && npm ci && npm run build\` first.\n`);
129
+ return 2;
130
+ }
120
131
  const broken = findBrokenLinks(distDir, base);
121
132
  if (broken.length > 0) {
122
133
  process.stdout.write(`❌ ${broken.length} broken internal link(s) in the built site:\n`);
123
134
  for (const b of broken) process.stdout.write(` - ${b.page}: ${b.link}\n`);
135
+ process.stderr.write(`scanned: ${_walkHtml(distDir).length}\n`);
124
136
  return 1;
125
137
  }
138
+ const pages = _walkHtml(distDir).length;
139
+ // Machine-readable count for check_gate_coverage — emitted regardless of
140
+ // --quiet, and on every exit path above too, so a gate with real findings
141
+ // still reports what it inspected (the emission bug found on #1047).
142
+ process.stderr.write(`scanned: ${pages}\n`);
126
143
  if (!quiet) {
127
- const pages = _walkHtml(distDir).length;
128
144
  process.stdout.write(`✅ site links: ${pages} page(s), no broken internal links (base ${base}).\n`);
129
145
  }
130
146
  return 0;
131
147
  }
132
148
 
149
+ /**
150
+ * Why the built site cannot be trusted, or `null` when it looks current.
151
+ *
152
+ * Two independent signals, because they catch different failures:
153
+ * - a content source newer than every built page → the build predates an edit;
154
+ * - materially fewer pages than content sources → the build is partial.
155
+ *
156
+ * Both are cheap `stat` walks. Exported for the test.
157
+ */
158
+ export function _stalenessVerdict(distDir: string, contentDir?: string): string | null {
159
+ const content = contentDir ?? path.join(REPO, 'site', 'src', 'content');
160
+ if (!fs.existsSync(content)) {
161
+ return null; // nothing to compare against — not this checker's verdict to make
162
+ }
163
+ const sources = _walkFiles(content).filter((f) => f.endsWith('.md') || f.endsWith('.mdx'));
164
+ if (sources.length === 0) {
165
+ return null;
166
+ }
167
+ const pages = _walkHtml(distDir);
168
+ if (pages.length === 0) {
169
+ return 'the build contains no HTML pages';
170
+ }
171
+ const newestPage = Math.max(...pages.map((p) => fs.statSync(p).mtimeMs));
172
+ const newer = sources.filter((s) => fs.statSync(s).mtimeMs > newestPage);
173
+ if (newer.length > 0) {
174
+ return `${newer.length} of ${sources.length} content source(s) are newer than the newest built page`;
175
+ }
176
+ if (pages.length < sources.length) {
177
+ return `only ${pages.length} page(s) built for ${sources.length} content source(s)`;
178
+ }
179
+ return null;
180
+ }
181
+
182
+ function _walkFiles(dir: string): string[] {
183
+ const out: string[] = [];
184
+ for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
185
+ const full = path.join(dir, e.name);
186
+ if (e.isDirectory()) out.push(..._walkFiles(full));
187
+ else if (e.isFile()) out.push(full);
188
+ }
189
+ return out;
190
+ }
191
+
133
192
  function _isCliEntry(): boolean {
134
193
  if (process.argv[1] === undefined) {
135
194
  return false;
Binary file
Binary file
@@ -50,16 +50,14 @@ const SETTINGS_PATH = project_settings_path(ROOT);
50
50
  // workspace-independent by definition.
51
51
  export const SCHEMA_VERSION = 2;
52
52
 
53
- // Compile-time rule toggles. Maps rule-id → settings predicate.
54
- // Rule omitted from router.json when predicate returns False.
55
- const COMPILE_TIME_TOGGLES: Record<string, (s: JsonObject) => boolean> = {
56
- 'telegraph-speak': (s: JsonObject): boolean => {
57
- const tg = (s['telegraph'] as JsonObject | undefined) ?? {};
58
- const enabled = tg['enabled'] === undefined ? true : tg['enabled'];
59
- const speak = tg['speak'] === undefined ? true : tg['speak'];
60
- return Boolean(enabled) && Boolean(speak);
61
- },
62
- };
53
+ // Compile-time rule toggles — the definition moved to
54
+ // `_lib/compile_time_toggles.ts` on 2026-07-29 so the PROJECTOR honours it too.
55
+ // Router membership alone was never zero-cost: a disabled rule kept shipping as a
56
+ // file, and the host reads the file (docs/adrs/telegraph/0002 § part 1).
57
+ // Re-exported here because tests and downstream consumers pin this name.
58
+ import { COMPILE_TIME_TOGGLES, rule_is_compile_enabled } from './_lib/compile_time_toggles.js';
59
+
60
+ export { COMPILE_TIME_TOGGLES };
63
61
 
64
62
  // Maps legacy tier values to the router-canonical names. See
65
63
  // docs/contracts/rule-router.md § Backward compatibility.
@@ -204,10 +202,8 @@ function _collect(): JsonObject {
204
202
  continue;
205
203
  }
206
204
  const rule_id = _stem(p);
207
- if (rule_id in COMPILE_TIME_TOGGLES) {
208
- if (!(COMPILE_TIME_TOGGLES[rule_id] as (s: JsonObject) => boolean)(settings)) {
209
- continue;
210
- }
205
+ if (!rule_is_compile_enabled(rule_id, settings)) {
206
+ continue;
211
207
  }
212
208
  const rule_type = String(fm['type'] ?? 'auto');
213
209
  // Manual rules are reference-only (ADR-004) — no router emission.
@@ -4,12 +4,11 @@
4
4
  # Usage:
5
5
  # ./scripts/condense.sh # sync non-.md files + cleanup
6
6
  # ./scripts/condense.sh --list # list ALL .md files
7
- # ./scripts/condense.sh --changed # list .md files changed since last condensation
7
+ # ./scripts/condense.sh --changed # list .md files whose projection is out of date
8
8
  # ./scripts/condense.sh --check # check if dirs are in sync
9
- # ./scripts/condense.sh --mark-done <path> # mark file as condensed
10
- # ./scripts/condense.sh --mark-all-done # mark all files as condensed
11
9
  #
12
- # .md condensation is done by the Augment agent interactively.
10
+ # .md files are projected verbatim with the path rewriter applied — --sync
11
+ # writes them; there is no separate condensation step.
13
12
 
14
13
  set -euo pipefail
15
14