@event4u/agent-config 14.12.0 → 14.14.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 (521) 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 +118 -155
  5. package/CONTRIBUTING.md +38 -0
  6. package/CREDITS.md +135 -0
  7. package/NOTICE +13 -0
  8. package/README.md +8 -6
  9. package/dist/agent-src/commands/analyze/inbox.md +145 -2
  10. package/dist/agent-src/commands/feature/dev.md +7 -2
  11. package/dist/agent-src/commands/ghostwriter/write.md +5 -1
  12. package/dist/agent-src/commands/implement-ticket.md +1 -1
  13. package/dist/agent-src/commands/mission/upgrade.md +1 -1
  14. package/dist/agent-src/commands/orchestrate.md +2 -2
  15. package/dist/agent-src/commands/post-as/me.md +5 -1
  16. package/dist/agent-src/commands/pr/merge.md +19 -6
  17. package/dist/agent-src/commands/roadmap/process-full.md +19 -5
  18. package/dist/agent-src/commands/tdd/red.md +12 -2
  19. package/dist/agent-src/commands/work.md +1 -1
  20. package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +40 -0
  21. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +5 -2
  22. package/dist/agent-src/contexts/execution/autonomy-mechanics.md +21 -0
  23. package/dist/agent-src/contexts/execution/orchestration-telemetry.md +1 -0
  24. package/dist/agent-src/contexts/execution/subagent-response-contract.md +40 -0
  25. package/dist/agent-src/contexts/execution/subagent-steering.md +13 -1
  26. package/dist/agent-src/contexts/execution/terminal-states.md +96 -0
  27. package/dist/agent-src/rules/artifact-drafting-protocol.md +1 -1
  28. package/dist/agent-src/rules/broken-access-control.md +4 -0
  29. package/dist/agent-src/rules/code-comment-discipline.md +6 -0
  30. package/dist/agent-src/rules/code-provenance.md +4 -0
  31. package/dist/agent-src/rules/design-fidelity.md +1 -1
  32. package/dist/agent-src/rules/domain-safety-pii.md +4 -0
  33. package/dist/agent-src/rules/domain-safety-retention.md +4 -0
  34. package/dist/agent-src/rules/engineering-safety-floor.md +2 -0
  35. package/dist/agent-src/rules/external-code-graph-interop.md +14 -12
  36. package/dist/agent-src/rules/improve-before-implement.md +6 -8
  37. package/dist/agent-src/rules/laravel-routing.md +1 -1
  38. package/dist/agent-src/rules/lethal-trifecta-guard.md +4 -0
  39. package/dist/agent-src/rules/secret-vcs-guard.md +2 -0
  40. package/dist/agent-src/rules/security-sensitive-stop.md +2 -0
  41. package/dist/agent-src/rules/source-confidentiality.md +12 -34
  42. package/dist/agent-src/rules/symfony-routing.md +1 -1
  43. package/dist/agent-src/rules/token-efficiency.md +14 -0
  44. package/dist/agent-src/rules/tool-safety.md +4 -0
  45. package/dist/agent-src/rules/untrusted-input-defense.md +4 -0
  46. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +252 -8
  47. package/dist/agent-src/scripts/guarded_baseline.ts +343 -0
  48. package/dist/agent-src/scripts/roadmap_set_step.ts +253 -0
  49. package/dist/agent-src/scripts/stub_queue.ts +82 -0
  50. package/dist/agent-src/scripts/stubs_due.ts +516 -0
  51. package/dist/agent-src/scripts/ticket_bundles.ts +84 -0
  52. package/dist/agent-src/scripts/update_roadmap_progress.ts +16 -12
  53. package/dist/agent-src/skills/brand-asset-generation/SKILL.md +17 -4
  54. package/dist/agent-src/skills/brand-audit/SKILL.md +33 -0
  55. package/dist/agent-src/skills/code-intelligence/SKILL.md +57 -0
  56. package/dist/agent-src/skills/database/SKILL.md +8 -0
  57. package/dist/agent-src/skills/dependency-upgrade/SKILL.md +27 -0
  58. package/dist/agent-src/skills/design-review/SKILL.md +1 -1
  59. package/dist/agent-src/skills/doc-coauthoring/SKILL.md +1 -1
  60. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +17 -1
  61. package/dist/agent-src/skills/feature-planning/SKILL.md +9 -2
  62. package/dist/agent-src/skills/frontend-render-security/SKILL.md +44 -0
  63. package/dist/agent-src/skills/git-workflow/SKILL.md +1 -1
  64. package/dist/agent-src/skills/js-library-packaging/scripts/check_package_surface.ts +38 -4
  65. package/dist/agent-src/skills/judge-artifact-completeness/rubrics/ticket-quality-score.json +2 -2
  66. package/dist/agent-src/skills/laravel/SKILL.md +35 -0
  67. package/dist/agent-src/skills/laravel-migration/SKILL.md +57 -3
  68. package/dist/agent-src/skills/monorepo-workspace/SKILL.md +26 -0
  69. package/dist/agent-src/skills/playbook-authoring/SKILL.md +28 -1
  70. package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +1 -1
  71. package/dist/agent-src/skills/skill-writing/references/procedure.md +5 -5
  72. package/dist/agent-src/skills/sql-writing/SKILL.md +7 -1
  73. package/dist/agent-src/skills/standards-from-config/SKILL.md +27 -4
  74. package/dist/agent-src/skills/supply-chain-intake/SKILL.md +11 -4
  75. package/dist/agent-src/skills/symfony-workflow/SKILL.md +35 -0
  76. package/dist/agent-src/skills/test-case-discovery/SKILL.md +85 -0
  77. package/dist/agent-src/skills/test-driven-development/SKILL.md +33 -9
  78. package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
  79. package/dist/agent-src/skills/testing-anti-patterns/process-anti-patterns.md +37 -0
  80. package/dist/agent-src/skills/ui-component-architect/SKILL.md +45 -2
  81. package/dist/agent-src/skills/upstream-contribute/SKILL.md +38 -1
  82. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +9 -4
  83. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  84. package/dist/agent-src/templates/roadmaps.md +97 -3
  85. package/dist/agent-src/templates/scripts/check_memory.ts +258 -17
  86. package/dist/agent-src/templates/scripts/check_memory_proposal.ts +9 -3
  87. package/dist/agent-src/templates/scripts/memory_lookup.ts +86 -0
  88. package/dist/agent-src/templates/scripts/memory_signal.ts +44 -0
  89. package/dist/agent-src/templates/scripts/work_engine/directives/backend/implement.ts +90 -0
  90. package/dist/agent-src/templates/scripts/work_engine/directives/backend/index.ts +11 -0
  91. package/dist/agent-src/templates/scripts/work_engine/directives/backend/test.ts +23 -1
  92. package/dist/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +10 -1
  93. package/dist/agent-src/templates/scripts/work_engine/directives/mixed/stitch.ts +5 -1
  94. package/dist/agent-src/templates/scripts/work_engine/stack/runner.ts +102 -14
  95. package/dist/cli/commands/uiAudit.js +124 -5
  96. package/dist/cli/registry.js +2 -0
  97. package/dist/cli-delegate/{chunk-HYWSRNUX.js → chunk-2DK2VJWG.js} +3 -3
  98. package/dist/cli-delegate/{chunk-JCW7ZLHK.js → chunk-4FS4WRXP.js} +5 -0
  99. package/dist/cli-delegate/{chunk-OMIVVCG2.js → chunk-A4QJ6ENT.js} +24 -0
  100. package/dist/cli-delegate/{chunk-JJA2QEWA.js → chunk-AKJGUQNO.js} +466 -285
  101. package/dist/cli-delegate/{chunk-E46KPN6K.js → chunk-BTWUYDGN.js} +424 -363
  102. package/dist/cli-delegate/{chunk-K4FFODTS.js → chunk-ILMUPLGW.js} +1227 -316
  103. package/dist/cli-delegate/{chunk-FF7WAFMR.js → chunk-KPBWFOPZ.js} +5 -1
  104. package/dist/cli-delegate/cmd_adr_effective.js +102 -0
  105. package/dist/cli-delegate/cmd_conformance.js +80 -11
  106. package/dist/cli-delegate/cmd_doctor.js +3 -3
  107. package/dist/cli-delegate/cmd_export.js +3 -2
  108. package/dist/cli-delegate/cmd_fleet.js +2 -2
  109. package/dist/cli-delegate/cmd_handoff.js +1 -1
  110. package/dist/cli-delegate/cmd_preflight.js +2 -2
  111. package/dist/cli-delegate/cmd_prune.js +3 -2
  112. package/dist/cli-delegate/cmd_settings_get.js +1 -1
  113. package/dist/cli-delegate/cmd_settings_migrate.js +3 -2
  114. package/dist/cli-delegate/cmd_settings_set.js +2 -2
  115. package/dist/cli-delegate/cmd_sync.js +3 -2
  116. package/dist/cli-delegate/cmd_uninstall.js +3 -2
  117. package/dist/cli-delegate/cmd_validate.js +3 -2
  118. package/dist/discovery/deprecation-report.md +1 -1
  119. package/dist/discovery/discovery-manifest.json +58 -58
  120. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  121. package/dist/discovery/discovery-manifest.summary.md +1 -1
  122. package/dist/discovery/dormancy-report.md +1 -1
  123. package/dist/discovery/orphan-report.md +1 -1
  124. package/dist/discovery/packs.json +2 -2
  125. package/dist/discovery/trust-report.md +1 -1
  126. package/dist/discovery/workspaces.json +2 -2
  127. package/dist/hooks/dispatch.js +2900 -1049
  128. package/dist/install/claudeRuleRewrite.js +254 -0
  129. package/dist/install/detect.js +29 -16
  130. package/dist/install/detect_php_shape.js +159 -0
  131. package/dist/install/install.mjs +634 -428
  132. package/dist/mcp/awesome-mcp-servers.row.md +1 -1
  133. package/dist/mcp/mcp-cloudflare-catalogue.json +1 -1
  134. package/dist/mcp/registry-manifest.json +3 -3
  135. package/dist/mcp/server.json +3 -3
  136. package/dist/mcp/server.mjs +4895 -2627
  137. package/dist/server/schemas/settings.js +3 -0
  138. package/dist/ui/assets/index-D0jaCRPM.js +29 -0
  139. package/dist/ui/index.html +1 -1
  140. package/docs/MIGRATION.md +1 -1
  141. package/docs/THIRD-PARTY-NOTICES.md +25 -0
  142. package/docs/contracts/provider-lifecycle.md +1 -1
  143. package/docs/contracts/settings-classes.md +10 -4
  144. package/docs/guidelines/agent-infra/5w2h-analysis.md +3 -3
  145. package/docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md +1 -0
  146. package/docs/guidelines/agent-infra/artifact-drafting-protocol-mechanics.md +58 -3
  147. package/docs/guidelines/agent-infra/ask-when-uncertain-demos.md +2 -2
  148. package/docs/guidelines/agent-infra/asking-and-brevity-examples.md +3 -3
  149. package/docs/guidelines/agent-infra/break-glass-usage.md +7 -7
  150. package/docs/guidelines/agent-infra/carve-out-predicates.md +3 -3
  151. package/docs/guidelines/agent-infra/comparison-matrix.md +1 -1
  152. package/docs/guidelines/agent-infra/critical-thinking.md +4 -4
  153. package/docs/guidelines/agent-infra/direct-answers-demos.md +2 -2
  154. package/docs/guidelines/agent-infra/domain-eval-anti-pattern.md +1 -1
  155. package/docs/guidelines/agent-infra/engineering-memory-data-format.md +3 -3
  156. package/docs/guidelines/agent-infra/existence-question-verdicts.md +80 -0
  157. package/docs/guidelines/agent-infra/first-principles.md +2 -2
  158. package/docs/guidelines/agent-infra/framework-neutrality-patterns.md +2 -2
  159. package/docs/guidelines/agent-infra/guarded-baseline.md +39 -0
  160. package/docs/guidelines/agent-infra/inversion-thinking.md +5 -5
  161. package/docs/guidelines/agent-infra/language-and-tone-examples.md +1 -1
  162. package/docs/guidelines/agent-infra/layered-settings.md +10 -10
  163. package/docs/guidelines/agent-infra/memory-access.md +1 -1
  164. package/docs/guidelines/agent-infra/mental-models.md +3 -3
  165. package/docs/guidelines/agent-infra/reuse-verdict-mechanics.md +71 -0
  166. package/docs/guidelines/agent-infra/review-routing-data-format.md +7 -7
  167. package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +13 -7
  168. package/docs/guidelines/agent-infra/role-contracts.md +2 -2
  169. package/docs/guidelines/agent-infra/role-mode-router.md +3 -3
  170. package/docs/guidelines/agent-infra/rule-type-governance.md +2 -2
  171. package/docs/guidelines/agent-infra/scqa-framework.md +5 -5
  172. package/docs/guidelines/agent-infra/self-improvement-pipeline.md +6 -6
  173. package/docs/guidelines/agent-infra/simplicity-and-goal-demos.md +2 -2
  174. package/docs/guidelines/agent-infra/six-hats.md +3 -3
  175. package/docs/guidelines/agent-infra/skill-quality-checklist.md +6 -6
  176. package/docs/guidelines/agent-infra/source-confidentiality-mechanics.md +109 -0
  177. package/docs/guidelines/agent-infra/systems-thinking.md +1 -1
  178. package/docs/guidelines/agent-infra/verify-before-complete-demos.md +2 -2
  179. package/docs/guidelines/augment-portability-patterns.md +6 -4
  180. package/docs/guidelines/code-clarity.md +18 -0
  181. package/docs/guidelines/component-oriented-and-oop-development.md +3 -2
  182. package/docs/guidelines/cross-role-handoff.md +2 -2
  183. package/docs/guidelines/design-fidelity-mechanics.md +1 -1
  184. package/docs/guidelines/docs/readme-size-and-splitting.md +3 -3
  185. package/docs/guidelines/php/database.md +90 -7
  186. package/docs/guidelines/prompt-templates.md +7 -7
  187. package/llms.txt +2 -2
  188. package/package.json +5 -2
  189. package/src/agent-src/scripts/archive_completed_roadmaps.ts +252 -8
  190. package/src/agent-src/scripts/guarded_baseline.ts +343 -0
  191. package/src/agent-src/scripts/roadmap_set_step.ts +253 -0
  192. package/src/agent-src/scripts/stub_queue.ts +82 -0
  193. package/src/agent-src/scripts/stubs_due.ts +516 -0
  194. package/src/agent-src/scripts/ticket_bundles.ts +84 -0
  195. package/src/agent-src/scripts/update_roadmap_progress.ts +16 -12
  196. package/src/agent-src/templates/scripts/check_memory.ts +258 -17
  197. package/src/agent-src/templates/scripts/check_memory_proposal.ts +9 -3
  198. package/src/agent-src/templates/scripts/memory_lookup.ts +86 -0
  199. package/src/agent-src/templates/scripts/memory_signal.ts +44 -0
  200. package/src/agent-src/templates/scripts/work_engine/directives/backend/implement.ts +90 -0
  201. package/src/agent-src/templates/scripts/work_engine/directives/backend/index.ts +11 -0
  202. package/src/agent-src/templates/scripts/work_engine/directives/backend/test.ts +23 -1
  203. package/src/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +10 -1
  204. package/src/agent-src/templates/scripts/work_engine/directives/mixed/stitch.ts +5 -1
  205. package/src/agent-src/templates/scripts/work_engine/stack/runner.ts +102 -14
  206. package/src/config/agent-settings.template.yml +32 -3
  207. package/src/config/assurance-capability-registry.json +21 -9
  208. package/src/config/canonical-terms.yml +119 -0
  209. package/src/config/capability-native-outcome-bars.json +81 -0
  210. package/src/config/ci-local-parity.yml +80 -0
  211. package/src/config/drafting-channels.yml +43 -0
  212. package/src/config/estate-count-budget.json +57 -36
  213. package/src/config/evaluator-budgets.json +14 -14
  214. package/src/config/gate-coverage.yml +729 -63
  215. package/src/config/gate-reachability-exemptions.json +21 -0
  216. package/src/config/gate-violation-baselines.json +42 -19
  217. package/src/config/harness-evolution-budget.json +25 -0
  218. package/src/config/lapsed-beta-baseline.json +96 -0
  219. package/src/config/memory-twin-verdicts.yml +129 -0
  220. package/src/config/metric-registry.yml +124 -0
  221. package/src/config/pack-size-budget.json +16 -15
  222. package/src/config/preamble-payload-budget.json +12 -4
  223. package/src/config/profiles/balanced.ini +27 -0
  224. package/src/config/profiles/full.ini +27 -0
  225. package/src/config/profiles/minimal.ini +27 -0
  226. package/src/config/publish-surface.json +9 -2
  227. package/src/config/routing-coverage-seed.json +16 -2
  228. package/src/config/rule-stub-ceilings.json +133 -112
  229. package/src/config/turnaround-budget.json +66 -0
  230. package/src/install/claudeRuleRewrite.ts +288 -0
  231. package/src/install/detect.ts +60 -17
  232. package/src/install/detect_php_shape.ts +191 -0
  233. package/src/scripts/_cli/cmd_doctor.ts +27 -112
  234. package/src/scripts/_dispatch.bash +23 -0
  235. package/src/scripts/_lib/activation_ladder.ts +255 -0
  236. package/src/scripts/_lib/activation_receipt_producer.ts +341 -0
  237. package/src/scripts/_lib/activation_states.ts +88 -0
  238. package/src/scripts/_lib/adherence_detectors.ts +143 -0
  239. package/src/scripts/_lib/adr_frontmatter.ts +26 -0
  240. package/src/scripts/_lib/arith_claims.ts +181 -0
  241. package/src/scripts/_lib/arm_ranking.ts +62 -0
  242. package/src/scripts/_lib/asset_delivery_ledger.ts +303 -0
  243. package/src/scripts/_lib/audit_field_provenance.ts +54 -0
  244. package/src/scripts/_lib/auto_dispatch.ts +32 -3
  245. package/src/scripts/_lib/bench_ab_size_claim.ts +98 -4
  246. package/src/scripts/_lib/benchmark_cache_fields.ts +158 -0
  247. package/src/scripts/_lib/candidate_pair_delta.ts +349 -0
  248. package/src/scripts/_lib/candidate_proposer.ts +402 -0
  249. package/src/scripts/_lib/candidate_record.ts +601 -0
  250. package/src/scripts/_lib/capture_rate.ts +319 -0
  251. package/src/scripts/_lib/carrier_status.ts +118 -0
  252. package/src/scripts/_lib/cascade_stage_enumeration.ts +92 -0
  253. package/src/scripts/_lib/collector_denominator.ts +771 -0
  254. package/src/scripts/_lib/collector_record.ts +340 -0
  255. package/src/scripts/_lib/collector_store.ts +664 -0
  256. package/src/scripts/_lib/collector_supervision.ts +827 -0
  257. package/src/scripts/_lib/concern_estate.ts +77 -0
  258. package/src/scripts/_lib/config_chain.ts +477 -0
  259. package/src/scripts/_lib/config_cost.ts +209 -0
  260. package/src/scripts/_lib/corpus_manifest.ts +726 -0
  261. package/src/scripts/_lib/council_settings_block.ts +6 -0
  262. package/src/scripts/_lib/curator_ops.ts +172 -0
  263. package/src/scripts/_lib/delivery_arm_experiment.ts +282 -0
  264. package/src/scripts/_lib/delivery_criticality.ts +126 -0
  265. package/src/scripts/_lib/doctor_runtime_checks.ts +70 -0
  266. package/src/scripts/_lib/empty_cycles.ts +88 -0
  267. package/src/scripts/_lib/estate_carrier_cases.ts +72 -0
  268. package/src/scripts/_lib/eval_publication.ts +354 -0
  269. package/src/scripts/_lib/evaluation_cascade.ts +452 -0
  270. package/src/scripts/_lib/evaluation_vector.ts +283 -0
  271. package/src/scripts/_lib/evaluator_promotion.ts +225 -0
  272. package/src/scripts/_lib/evidence_basis.ts +118 -0
  273. package/src/scripts/_lib/evolution_roi.ts +562 -0
  274. package/src/scripts/_lib/exec_evidence.ts +8 -0
  275. package/src/scripts/_lib/experience_card.ts +272 -0
  276. package/src/scripts/_lib/experience_report.ts +151 -0
  277. package/src/scripts/_lib/experiment_freeze.ts +112 -0
  278. package/src/scripts/_lib/generated_by.ts +66 -0
  279. package/src/scripts/_lib/harness_evolution_guards.ts +239 -0
  280. package/src/scripts/_lib/hook_effect_probe.ts +141 -0
  281. package/src/scripts/_lib/host_denominator.ts +687 -0
  282. package/src/scripts/_lib/host_projection_reach.ts +157 -0
  283. package/src/scripts/_lib/ignored_blocker.ts +148 -0
  284. package/src/scripts/_lib/install_reach_checks.ts +495 -0
  285. package/src/scripts/_lib/json_duplicate_keys.ts +150 -0
  286. package/src/scripts/_lib/judge_hygiene.ts +228 -0
  287. package/src/scripts/_lib/legacy_boundary_map.ts +228 -0
  288. package/src/scripts/_lib/lexical_shortlist.ts +215 -0
  289. package/src/scripts/_lib/llm_candidate_proposer.ts +461 -0
  290. package/src/scripts/_lib/llm_proposer_transport.ts +153 -0
  291. package/src/scripts/_lib/loop_guards.ts +299 -0
  292. package/src/scripts/_lib/loss_class.ts +129 -0
  293. package/src/scripts/_lib/machine_wake.ts +51 -0
  294. package/src/scripts/_lib/md_prose_lines.ts +177 -0
  295. package/src/scripts/_lib/minimality_tiebreak.ts +168 -0
  296. package/src/scripts/_lib/one_resolver_invariant.ts +449 -0
  297. package/src/scripts/_lib/orchestration_record.ts +253 -5
  298. package/src/scripts/_lib/outcome_envelope.ts +227 -0
  299. package/src/scripts/_lib/outcome_vocabularies.ts +125 -0
  300. package/src/scripts/_lib/paired_stats.ts +245 -0
  301. package/src/scripts/_lib/paired_verdict.ts +226 -0
  302. package/src/scripts/_lib/pathology_archive.ts +393 -0
  303. package/src/scripts/_lib/prefix_stable_surfaces.ts +123 -0
  304. package/src/scripts/_lib/privacy_class.ts +47 -0
  305. package/src/scripts/_lib/promotion_capability.ts +315 -0
  306. package/src/scripts/_lib/promotion_evidence.ts +414 -0
  307. package/src/scripts/_lib/promotion_review.ts +294 -0
  308. package/src/scripts/_lib/prompt_shape.ts +92 -0
  309. package/src/scripts/_lib/regression_neighbourhood.ts +259 -0
  310. package/src/scripts/_lib/release_highlights.ts +70 -1
  311. package/src/scripts/_lib/release_material.ts +125 -2
  312. package/src/scripts/_lib/repeated_failure.ts +105 -0
  313. package/src/scripts/_lib/repo_root.ts +111 -0
  314. package/src/scripts/_lib/review_skipped_record.ts +37 -0
  315. package/src/scripts/_lib/role_split.ts +338 -0
  316. package/src/scripts/_lib/routing_corpus.ts +307 -0
  317. package/src/scripts/_lib/routing_index_input.ts +104 -0
  318. package/src/scripts/_lib/rule_injection.ts +22 -1
  319. package/src/scripts/_lib/runtime_journal.ts +1499 -0
  320. package/src/scripts/_lib/runtime_wiring_checks.ts +430 -0
  321. package/src/scripts/_lib/semantic_noop.ts +167 -0
  322. package/src/scripts/_lib/skill_catalogue.ts +11 -1
  323. package/src/scripts/_lib/source_digest.ts +200 -0
  324. package/src/scripts/_lib/source_redact.ts +260 -0
  325. package/src/scripts/_lib/source_shape.ts +502 -0
  326. package/src/scripts/_lib/source_snapshot_dedup.ts +199 -0
  327. package/src/scripts/_lib/strip_comments.d.mts +8 -0
  328. package/src/scripts/_lib/strip_comments.mjs +65 -0
  329. package/src/scripts/_lib/test_red_state.ts +154 -0
  330. package/src/scripts/_lib/trigger_shift.ts +144 -0
  331. package/src/scripts/_lib/untrusted_content.ts +82 -7
  332. package/src/scripts/activation_receipt.ts +258 -0
  333. package/src/scripts/adoption_report.ts +1 -1
  334. package/src/scripts/adr/evidence_census.ts +1 -1
  335. package/src/scripts/adr/regenerate_index.ts +26 -2
  336. package/src/scripts/adr_cite_check.ts +164 -1
  337. package/src/scripts/ai_council/blind_review.ts +11 -1
  338. package/src/scripts/ai_council/clients.ts +4 -0
  339. package/src/scripts/ai_council/config.ts +3 -0
  340. package/src/scripts/ai_council/consensus.ts +28 -8
  341. package/src/scripts/ai_council/consensus_round.ts +226 -0
  342. package/src/scripts/ai_council/cross_exam.ts +128 -0
  343. package/src/scripts/ai_council/disagreement_signal.ts +338 -0
  344. package/src/scripts/ai_council/explain_route.ts +157 -0
  345. package/src/scripts/ai_council/information_gain.ts +293 -0
  346. package/src/scripts/ai_council/inline_findings.ts +340 -0
  347. package/src/scripts/ai_council/judge_position_bias.ts +197 -0
  348. package/src/scripts/ai_council/leakage_corpus.ts +385 -0
  349. package/src/scripts/ai_council/leakage_patterns.ts +453 -0
  350. package/src/scripts/ai_council/minority_retention.ts +171 -0
  351. package/src/scripts/ai_council/orchestrator.ts +16 -203
  352. package/src/scripts/ai_council/orchestrator_results.ts +23 -3
  353. package/src/scripts/ai_council/pricing.ts +106 -0
  354. package/src/scripts/ai_council/prompts.ts +74 -7
  355. package/src/scripts/ai_council/provider_leakage_bench.ts +327 -0
  356. package/src/scripts/ai_council/py_format.ts +14 -3
  357. package/src/scripts/ai_council/recouncil_guard.ts +293 -0
  358. package/src/scripts/ai_council/recouncil_savings.ts +299 -0
  359. package/src/scripts/ai_council/replay_route.ts +223 -0
  360. package/src/scripts/ai_council/response_record.ts +50 -0
  361. package/src/scripts/ai_council/reviewer_assignment.ts +279 -0
  362. package/src/scripts/ai_council/routing_training_row.ts +197 -0
  363. package/src/scripts/ai_council/synthesis_strategy.ts +159 -0
  364. package/src/scripts/ai_council/topology_bench_manifest.ts +860 -0
  365. package/src/scripts/ai_council/topology_vocabulary.ts +175 -0
  366. package/src/scripts/asset_delivery_ledger.ts +157 -0
  367. package/src/scripts/attest_artifact.ts +193 -0
  368. package/src/scripts/audit_auto_rules.ts +2 -1
  369. package/src/scripts/audit_command_surface.ts +1 -1
  370. package/src/scripts/audit_mcp_tools.ts +2 -2
  371. package/src/scripts/audit_skill_overlap_allowlist.json +6 -1
  372. package/src/scripts/audit_user_type_axis.ts +2 -1
  373. package/src/scripts/bench_ab_clone.ts +215 -10
  374. package/src/scripts/bench_ab_integrity.ts +119 -5
  375. package/src/scripts/bench_ab_v2_stats.ts +40 -213
  376. package/src/scripts/build_archive_index.ts +1 -1
  377. package/src/scripts/build_linear_digest.ts +1 -1
  378. package/src/scripts/build_proof.ts +11 -4
  379. package/src/scripts/build_rule_trigger_matrix.ts +1 -1
  380. package/src/scripts/build_source_digests.ts +157 -0
  381. package/src/scripts/cache_realization_report.ts +103 -0
  382. package/src/scripts/check_adr_frontmatter.ts +131 -10
  383. package/src/scripts/check_benchmark_report_fields.ts +207 -0
  384. package/src/scripts/check_beta_review_markers.ts +235 -6
  385. package/src/scripts/check_bundle_path_leakage.ts +34 -1
  386. package/src/scripts/check_claims.ts +576 -6
  387. package/src/scripts/check_composite_arming.ts +35 -0
  388. package/src/scripts/check_concern_admissions.ts +365 -0
  389. package/src/scripts/check_enforcement_coverage.ts +28 -0
  390. package/src/scripts/check_estate_count.ts +347 -25
  391. package/src/scripts/check_gate_reachability.ts +383 -0
  392. package/src/scripts/check_host_loadability.ts +104 -0
  393. package/src/scripts/check_loss_class_declared.ts +308 -0
  394. package/src/scripts/check_md_language.ts +15 -98
  395. package/src/scripts/check_memory_proposal.ts +18 -11
  396. package/src/scripts/check_no_currency_in_cost_surfaces.ts +225 -0
  397. package/src/scripts/check_no_external_sources.ts +281 -6
  398. package/src/scripts/check_pack_conformance_fixture.ts +11 -1
  399. package/src/scripts/check_pack_size.ts +59 -2
  400. package/src/scripts/check_preamble_payload_budget.ts +114 -3
  401. package/src/scripts/check_prefix_stable_mutation.ts +372 -0
  402. package/src/scripts/check_publish_surface.ts +10 -1
  403. package/src/scripts/check_references.ts +24 -1
  404. package/src/scripts/check_release_highlights.ts +96 -13
  405. package/src/scripts/check_roadmap_trackable.ts +17 -2
  406. package/src/scripts/check_rule_evidence_declaration.ts +316 -0
  407. package/src/scripts/check_rule_projection_integrity.ts +14 -4
  408. package/src/scripts/check_score_contract.ts +26 -3
  409. package/src/scripts/check_static_parity.ts +285 -0
  410. package/src/scripts/check_supervision_claim_atomicity.ts +498 -0
  411. package/src/scripts/check_suppression_hygiene.ts +15 -0
  412. package/src/scripts/ci_settle.ts +39 -2
  413. package/src/scripts/code_graph/build.ts +60 -3
  414. package/src/scripts/code_graph/extract.ts +44 -0
  415. package/src/scripts/code_graph/types.ts +24 -0
  416. package/src/scripts/collector_daemon.ts +714 -0
  417. package/src/scripts/config_cost_report.ts +302 -0
  418. package/src/scripts/consumer_matrix.ts +74 -1
  419. package/src/scripts/corpus_manifest.ts +235 -0
  420. package/src/scripts/cost/budget.mjs +10 -3
  421. package/src/scripts/cost/track.mjs +10 -3
  422. package/src/scripts/council_cli.ts +37 -54
  423. package/src/scripts/dispatch_r2_reviewer.ts +46 -5
  424. package/src/scripts/evolution_lab.ts +1153 -0
  425. package/src/scripts/external_sources_denylist.json +5 -18
  426. package/src/scripts/extract_audit_patterns.ts +21 -0
  427. package/src/scripts/fold_intake.ts +12 -1
  428. package/src/scripts/gen_discovery_baseline.ts +1 -1
  429. package/src/scripts/generate_capabilities_index.ts +12 -5
  430. package/src/scripts/generate_capability_matrix.ts +3 -3
  431. package/src/scripts/generate_command_flows.ts +2 -2
  432. package/src/scripts/generate_cookbook.ts +2 -2
  433. package/src/scripts/generate_index.ts +8 -1
  434. package/src/scripts/generate_knowledge_index.ts +2 -1
  435. package/src/scripts/generate_ownership_matrix.ts +2 -1
  436. package/src/scripts/generate_pack_manifests.ts +10 -2
  437. package/src/scripts/generate_role_experiences_catalog.ts +2 -2
  438. package/src/scripts/generate_settings_reference.ts +1 -1
  439. package/src/scripts/git_authorization_hook.ts +22 -1
  440. package/src/scripts/grade_target_readiness.ts +48 -5
  441. package/src/scripts/hook_effect_doctor.ts +261 -0
  442. package/src/scripts/hook_manifest.json +1 -1
  443. package/src/scripts/hook_manifest.yaml +125 -16
  444. package/src/scripts/hooks/block_speaking_inbox_dir.ts +271 -0
  445. package/src/scripts/hooks/block_unauthorized_git.ts +18 -0
  446. package/src/scripts/hooks/comment_discipline_hook.ts +146 -0
  447. package/src/scripts/hooks/concern_registry.ts +6 -0
  448. package/src/scripts/hooks/dispatch_hook.ts +32 -0
  449. package/src/scripts/hooks/journal_record_hook.ts +345 -0
  450. package/src/scripts/hooks/prepush_metadata_sources.sh +110 -0
  451. package/src/scripts/hooks/run_continuation_hook.ts +44 -9
  452. package/src/scripts/hooks/shims/install.sh +61 -0
  453. package/src/scripts/hooks/shims/php +101 -0
  454. package/src/scripts/hooks/suggestion_capture_hook.ts +10 -0
  455. package/src/scripts/hooks/turn_end_gate_hook.ts +9 -1
  456. package/src/scripts/hot_context_hook.ts +16 -0
  457. package/src/scripts/install-hooks.sh +20 -5
  458. package/src/scripts/install.ts +17 -35
  459. package/src/scripts/inventory_frontmatter.ts +2 -1
  460. package/src/scripts/language_mirror_hook.ts +14 -2
  461. package/src/scripts/lint_adr_sweep_routing.ts +12 -0
  462. package/src/scripts/lint_canonical_terms.ts +604 -0
  463. package/src/scripts/lint_carrier_integrity.ts +820 -0
  464. package/src/scripts/lint_code_comments.ts +643 -0
  465. package/src/scripts/lint_composition_review.ts +619 -0
  466. package/src/scripts/lint_consolidation_lineage.ts +666 -0
  467. package/src/scripts/lint_eval_specs.ts +593 -0
  468. package/src/scripts/lint_hook_manifest.ts +19 -0
  469. package/src/scripts/lint_host_portability.ts +373 -0
  470. package/src/scripts/lint_judge_prompt_expectation.ts +27 -1
  471. package/src/scripts/lint_memory_twin_parity.ts +335 -0
  472. package/src/scripts/lint_metric_consumers.ts +355 -0
  473. package/src/scripts/lint_plan_risk_register.ts +39 -19
  474. package/src/scripts/lint_promotion_paths.ts +779 -0
  475. package/src/scripts/lint_skill_descriptions.ts +18 -1
  476. package/src/scripts/lint_skill_frontmatter_safety.ts +58 -0
  477. package/src/scripts/lint_skill_link_reach.ts +252 -0
  478. package/src/scripts/lint_skill_trigger_corpus.ts +426 -23
  479. package/src/scripts/lint_ticket_buildable.ts +17 -1
  480. package/src/scripts/llm_propose.ts +256 -0
  481. package/src/scripts/mcp_server/consumer_tool_catalog.json +1 -1
  482. package/src/scripts/mcp_server/tool_catalog_source.ts +1 -1
  483. package/src/scripts/measure_delivery_sets.ts +361 -0
  484. package/src/scripts/measure_docs_dead_links.ts +348 -0
  485. package/src/scripts/measure_host_capture.ts +461 -0
  486. package/src/scripts/measure_routing_signal.ts +307 -0
  487. package/src/scripts/migration_status.ts +3 -3
  488. package/src/scripts/model_rule_injection.ts +76 -0
  489. package/src/scripts/orchestration_record.ts +14 -0
  490. package/src/scripts/preamble_byte_census.ts +139 -10
  491. package/src/scripts/prepack-check.mjs +4 -1
  492. package/src/scripts/probe_council_retention.ts +495 -0
  493. package/src/scripts/probe_turnaround.ts +384 -0
  494. package/src/scripts/probe_unblocked_ask.ts +279 -0
  495. package/src/scripts/release.ts +21 -37
  496. package/src/scripts/release_drill.ts +143 -0
  497. package/src/scripts/release_env.ts +35 -0
  498. package/src/scripts/release_publication.ts +84 -0
  499. package/src/scripts/render_benchmark_md.ts +1 -1
  500. package/src/scripts/rule_activation_census.ts +70 -9
  501. package/src/scripts/rule_backlinks.ts +1 -1
  502. package/src/scripts/run_lifecycle_suite.ts +208 -0
  503. package/src/scripts/run_skill_evals.ts +40 -0
  504. package/src/scripts/schemas/delivery-manifest.schema.json +43 -0
  505. package/src/scripts/schemas/drafting-channels.schema.json +43 -0
  506. package/src/scripts/schemas/evals.schema.json +24 -1
  507. package/src/scripts/schemas/rule.schema.json +52 -1
  508. package/src/scripts/schemas/skill.schema.json +17 -2
  509. package/src/scripts/skill_overlap.ts +7 -1
  510. package/src/scripts/skill_tools/run_block_d_eval.ts +8 -1
  511. package/src/scripts/skill_tools/score_skill_relevance.ts +84 -3
  512. package/src/scripts/skill_tools/suggest_skill_for_task.ts +8 -1
  513. package/src/scripts/skill_usage_report.ts +2 -1
  514. package/src/scripts/stubs_due.ts +211 -0
  515. package/src/scripts/sweep_source_surfaces.ts +678 -0
  516. package/src/scripts/sync_pr_branch.ts +3 -3
  517. package/src/scripts/trigger_eval_grandfather.json +202 -222
  518. package/src/scripts/utilization_report.ts +22 -2
  519. package/src/server/schemas/settings.ts +5 -0
  520. package/src/templates/marketing-copy.yml +1 -1
  521. package/dist/ui/assets/index-Cxgy63kz.js +0 -26
@@ -36,6 +36,7 @@
36
36
  * CI=true ./scripts-run src/scripts/check_claims # re-runs exec: claims
37
37
  */
38
38
  import * as fs from 'node:fs';
39
+ import * as os from 'node:os';
39
40
  import * as path from 'node:path';
40
41
  import { fileURLToPath, pathToFileURL } from 'node:url';
41
42
  import {
@@ -44,7 +45,13 @@ import {
44
45
  parse_exec_pointer,
45
46
  run_exec_evidence,
46
47
  } from './_lib/exec_evidence.js';
47
- import { assertScanned, DeadScopeError } from './_lib/scan_scope.js';
48
+ import { checkRatchet } from './_lib/gate_baseline.js';
49
+ import { runGateCli, runSelfTest, type SelfTestCase } from './_lib/gate_self_test.js';
50
+ import {
51
+ assertWatchlistResolves,
52
+ DeadScopeError,
53
+ reportScanned,
54
+ } from './_lib/scan_scope.js';
48
55
 
49
56
  const _FILE = fileURLToPath(import.meta.url);
50
57
  const _HERE = path.dirname(_FILE);
@@ -69,6 +76,61 @@ const URL_DATED = /^https?:\/\/\S+\s*\(\d{4}-\d{2}-\d{2}\)\s*$/;
69
76
  * are structurally witnessed (pointer columns + their own linters). */
70
77
  const WITNESS_SURFACES = ['README.md', 'CAPABILITIES.yaml'];
71
78
 
79
+ /**
80
+ * The publish-surface set — and the RULE that decides membership.
81
+ *
82
+ * `SURFACE_ROOTS` above is where the package looks for claim MARKERS; this is
83
+ * where the package's own words are RENDERED BY SOMEBODY ELSE. The two are not
84
+ * the same set and conflating them is what let a retired claim keep shipping:
85
+ * `package.json.description` and `.github/about.yml` carried the withdrawn
86
+ * `no-runtime-daemon` wording for weeks while `check_claims` read neither.
87
+ *
88
+ * THE RULE, stated once so a channel that does not appear below is still
89
+ * answerable: a file belongs to this set when a distribution channel the
90
+ * package publishes to renders its content to a reader who never opens the
91
+ * repository. Three consequences, each of which decides a real case:
92
+ *
93
+ * 1. SOURCE, not derived artefact. `dist/mcp/server.json` and
94
+ * `dist/mcp/registry-manifest.json` are published, and they are BUILT from
95
+ * `package.json` + `README.md`. Scanning the source covers them and
96
+ * scanning the artefact would not — a fresh checkout has no `dist/`, so a
97
+ * gate reading it dies on a missing file rather than on the property.
98
+ * 2. RENDERED, not merely shipped. `docs/**` ships inside the npm tarball but
99
+ * no channel renders it as the package's pitch; it is documentation a
100
+ * reader reaches after choosing the package. `README.md` is rendered by
101
+ * both the npm page and the GitHub repo page, so it is in.
102
+ * 3. THE PITCH FIELD, not the whole file. A JSON/YAML publish surface is
103
+ * scanned whole rather than per-key on purpose: a retired phrasing is
104
+ * equally wrong in `keywords`, in a nested plugin `description`, or in a
105
+ * comment, and a per-key list is the snapshot-of-today this rule exists to
106
+ * replace.
107
+ *
108
+ * Applying the rule to a channel not listed: a registry page whose copy is
109
+ * pasted by hand is IN and needs a file here holding that copy; a generated
110
+ * badge is OUT because its text derives from a source already in the set.
111
+ */
112
+ const PUBLISH_SURFACES = [
113
+ 'README.md',
114
+ 'package.json',
115
+ '.github/about.yml',
116
+ '.github/topics.yml',
117
+ '.claude-plugin/marketplace.json',
118
+ ];
119
+
120
+ /** The sentinel `retires_phrasings` value for a claim that never left the ledger. */
121
+ const NEVER_PUBLISHED = 'never-published';
122
+
123
+ /** A phrasing shorter than this matches too much prose to be a safe needle. */
124
+ const MIN_PHRASING_CHARS = 12;
125
+
126
+ /** Split a `retires_phrasings` value into its literal phrasings. */
127
+ export function parse_retired_phrasings(raw: string): string[] {
128
+ return raw
129
+ .split('|')
130
+ .map((x) => x.trim())
131
+ .filter((x) => x !== '');
132
+ }
133
+
72
134
  /**
73
135
  * Shapes that read as a measured capability figure.
74
136
  *
@@ -103,7 +165,48 @@ const RATIO = /\b\d+(?:\.\d+)?\s*(?:%|[x×](?![A-Za-z0-9]))/;
103
165
  // The optional `<word>-` allows a qualified unit: `13,881 GPT-tokens` is the
104
166
  // same claim shape as `13,881 tokens` and was missed without it.
105
167
  const MAGNITUDE = /\b\d[\d,._]*\s*(?:[A-Za-z]+-)?(?:tokens?|ms|USD|KB|MB|GB|chars?)\b/i;
106
- const SELF_COUNT = /\b\d+\+?\s+(?:host agents?|hosts|supported (?:agents?|hosts))\b/i;
168
+ /**
169
+ * The nouns this package counts ITSELF in. Widened 2026-08-26
170
+ * (road-to-published-number-truth 2.1) from the three host-reach nouns to the
171
+ * package's own artifact vocabulary, because the host-reach miss was an
172
+ * instance and the artifact counts are the population: the badge block alone
173
+ * publishes six of them, and until this widening `is_quantified_claim` returned
174
+ * false for every one.
175
+ *
176
+ * Extended rather than given a sibling pattern on purpose — the sweep, the
177
+ * surfaces and the `unverified` allow path all already exist, and a second gate
178
+ * would trip three ratchets to reach the same lines.
179
+ */
180
+ const SELF_COUNT_NOUNS =
181
+ 'host agents?|hosts|supported (?:agents?|hosts)|' +
182
+ 'skills?|commands?|rules?|guidelines?|personas?|advisors?|' +
183
+ 'packs?|profiles?|ADRs?|contexts?|scripts?';
184
+
185
+ /**
186
+ * Prose shape: `299 skills`, `7+ host agents`, `13,881 tokens`, and — the shape
187
+ * that shipped wrong twice — a QUALIFIED noun, `112 Python scripts`. The
188
+ * optional `<word> ` before the noun is what makes the qualified form match; a
189
+ * pattern anchored directly on the noun read straight past it.
190
+ */
191
+ const SELF_COUNT_PROSE = new RegExp(
192
+ String.raw`\b\d[\d,]*\+?\s+(?:[A-Za-z][A-Za-z.+-]*\s+)?(?:` + SELF_COUNT_NOUNS + String.raw`)\b`,
193
+ 'i',
194
+ );
195
+
196
+ /**
197
+ * Badge-URL shape: `badge/Skills-299`. This is how six of this package's own
198
+ * counts are published, and it carries no whitespace at all, so no prose
199
+ * pattern can see it. `Personas-29` is the live instance that motivated it.
200
+ */
201
+ const SELF_COUNT_BADGE = new RegExp(
202
+ String.raw`badge/(?:` + SELF_COUNT_NOUNS + String.raw`)-\d[\d,]*\b`,
203
+ 'i',
204
+ );
205
+
206
+ const SELF_COUNT = new RegExp(
207
+ `(?:${SELF_COUNT_PROSE.source})|(?:${SELF_COUNT_BADGE.source})`,
208
+ 'i',
209
+ );
107
210
 
108
211
  /** True when a line carries any figure shape that must bind to a claim. */
109
212
  export function is_quantified_claim(line: string): boolean {
@@ -136,6 +239,89 @@ export interface LedgerEntry {
136
239
  * ledger exists to make impossible.
137
240
  */
138
241
  superseded_by: string;
242
+ /**
243
+ * REQUIRED on a `withdrawn` entry: the decision record that retired the
244
+ * claim. Empty everywhere else.
245
+ *
246
+ * `road-to-runtime-governance-flip` Phase 2, on an AI council ruling
247
+ * (2026-08-27, 4/4 across two rounds). `withdrawn` is the ledger's third
248
+ * closure — a claim that was true and asserted, and that the package decided
249
+ * to stop having. The status alone does not say WHOSE decision, and a
250
+ * withdrawal nobody can trace to a record is an unexplained deletion wearing
251
+ * a status. Requiring the pointer is what keeps the fourth status from
252
+ * becoming the dumping ground both council rounds warned about.
253
+ */
254
+ retired_by: string;
255
+ /**
256
+ * Optional: the build a quantitative measurement describes, when that is not
257
+ * the current one.
258
+ *
259
+ * `road-to-inbox-harvest-2026-08-f-code-graph-evidence-refresh` 3.2, on an
260
+ * AI council ruling (2026-08-26, 2/2). `claim:code-graph-retrieval-null` is
261
+ * a real measurement of a build that no longer exists: its figures date from
262
+ * 2026-07-28 and the extractor defect they blame was repaired on 2026-08-22.
263
+ *
264
+ * The council rejected both obvious statuses. `resolved-null` would say the
265
+ * retrieval question was ANSWERED null on the current build, which is
266
+ * exactly what nobody has measured; `superseded_by` expects replacement
267
+ * EVIDENCE, and a repair commit is the wrong semantic object for it. What
268
+ * was required instead was structured scoping — and that it reach every
269
+ * index and summary rather than only the detailed entry, because a prose-only
270
+ * qualification drifts from the structured record it qualifies.
271
+ *
272
+ * So this field is printed in `docs/proof.md`'s ledger table, not merely
273
+ * parsed.
274
+ */
275
+ measured_on: string;
276
+ /**
277
+ * Optional: the inferences this claim's data does NOT license.
278
+ *
279
+ * `road-to-skill-ecosystem-eval-integrity` Phase 5 Step 5. A measured number
280
+ * travels further than its measurement, and the sentence that stops it is
281
+ * one nobody writes unless a field asks for it. A `quant` claim backed by a
282
+ * benchmark supports exactly what the benchmark measured, on the population
283
+ * it ran over — and a reader with only the headline has no way to know which
284
+ * neighbouring reading it does not support.
285
+ *
286
+ * Optional rather than required, with a shrink-only ratchet on `backed`
287
+ * quant entries that lack it. Making it required would fail the build on
288
+ * every existing entry at once, which is the shape this repository's own
289
+ * records call a gate that could only block.
290
+ */
291
+ non_inference: string;
292
+ /**
293
+ * Optional, CLOSED entries only: the literal phrasings this claim was
294
+ * PUBLISHED under, `|`-separated — or the sentinel
295
+ * `never-published — <reason>` when it never appeared outside the ledger.
296
+ *
297
+ * `road-to-retired-claims-stay-retired` Phase 1. Retiring a claim was a
298
+ * bookkeeping act with no reach: `check_claims` validated a `withdrawn`
299
+ * row's own shape and `lint_positioning` validated three surfaces agreeing
300
+ * with each other, and neither read the other's input. A row could go
301
+ * `withdrawn` while its exact wording stayed on the npm page.
302
+ *
303
+ * The list lives ON THE ROW rather than in a sibling deny-list file, so
304
+ * retiring a claim and forbidding its wording are one edit. A second file
305
+ * is the one nobody updates.
306
+ *
307
+ * Populated from HISTORY, never from imagination — `MIN_PHRASING_CHARS` and
308
+ * the read-it-from-git discipline in docs/CLAIMS.md are both aimed at the
309
+ * same failure: a list of plausible paraphrases becomes a gate that fires
310
+ * on legitimate prose and is muted within a release.
311
+ */
312
+ retires_phrasings: string;
313
+ /**
314
+ * Whether the `- retires_phrasings:` LINE exists at all, independent of
315
+ * whether it carries a value.
316
+ *
317
+ * The two states are different findings and the string alone cannot tell
318
+ * them apart: an ABSENT field is a row nobody has got to yet (the coverage
319
+ * ratchet's business), while a PRESENT-BUT-EMPTY one is an author who
320
+ * answered the question with silence — the same distinction `non_inference`
321
+ * draws with its 20-character floor, and the reason that field's check is
322
+ * separate from its ratchet.
323
+ */
324
+ retires_phrasings_present: boolean;
139
325
  }
140
326
 
141
327
  interface Args {
@@ -147,6 +333,10 @@ function parse_args(argv: string[]): Args {
147
333
  for (const a of argv) {
148
334
  if (a === '--quiet') {
149
335
  out.quiet = true;
336
+ } else if (a === '--self-test') {
337
+ // Handled in main() before parse_args is reached; accepted here so
338
+ // a stray ordering never turns the flag into a usage error.
339
+ continue;
150
340
  } else if (a === '-h' || a === '--help') {
151
341
  process.stdout.write('usage: check_claims [--quiet]\n');
152
342
  throw new ExitCode(0);
@@ -177,6 +367,11 @@ function load_ledger(): Map<string, LedgerEntry> {
177
367
  status: cur.status ?? '',
178
368
  last_verified: cur.last_verified ?? '',
179
369
  superseded_by: cur.superseded_by ?? '',
370
+ retired_by: cur.retired_by ?? '',
371
+ measured_on: cur.measured_on ?? '',
372
+ non_inference: cur.non_inference ?? '',
373
+ retires_phrasings: cur.retires_phrasings ?? '',
374
+ retires_phrasings_present: cur.retires_phrasings_present ?? false,
180
375
  });
181
376
  }
182
377
  cur = {};
@@ -189,10 +384,19 @@ function load_ledger(): Map<string, LedgerEntry> {
189
384
  continue;
190
385
  }
191
386
  if (!cur.id) continue;
192
- const field = line.match(/^-\s+(claim|kind|evidence|status|last_verified|superseded_by):\s*(.*)$/);
387
+ // Keeping both sides of the merge is right for the FIELD LIST and wrong
388
+ // for the call: `String.match` takes one pattern, so two lines here
389
+ // would have silently ignored the second and dropped whichever field
390
+ // came from the other branch. One union, both fields.
391
+ const field = line.match(
392
+ /^-\s+(claim|kind|evidence|status|last_verified|superseded_by|retired_by|measured_on|non_inference|retires_phrasings):\s*(.*)$/,
393
+ );
193
394
  if (field) {
194
395
  const key = field[1] as keyof LedgerEntry;
195
396
  (cur as Record<string, string>)[key] = (field[2] ?? '').trim();
397
+ if (key === 'retires_phrasings') {
398
+ (cur as Record<string, unknown>)['retires_phrasings_present'] = true;
399
+ }
196
400
  }
197
401
  }
198
402
  flush();
@@ -289,6 +493,7 @@ interface Finding {
289
493
  }
290
494
 
291
495
  function main(argv: string[] = process.argv.slice(2)): number {
496
+ if (argv.includes('--self-test')) return selfTest();
292
497
  const args = parse_args(argv);
293
498
  const ledger = load_ledger();
294
499
  // The ledger is the corpus both passes depend on: markers resolve against
@@ -299,7 +504,7 @@ function main(argv: string[] = process.argv.slice(2)): number {
299
504
  // Marker count is deliberately not the unit: a surface tree with zero
300
505
  // markers is a legitimate state, an absent ledger never is.
301
506
  try {
302
- assertScanned({
507
+ reportScanned({
303
508
  gate: 'check_claims',
304
509
  scanned: ledger.size,
305
510
  units: 'ledger entry(s)',
@@ -344,13 +549,19 @@ function main(argv: string[] = process.argv.slice(2)): number {
344
549
  // reader arriving at a `resolved-null` learns the question was reopened
345
550
  // by a different mechanism — a dangling id would send them nowhere, and
346
551
  // the field on a live entry would claim a closure that never happened.
552
+ //
553
+ // `withdrawn` joins `resolved-null` as a closure that may carry a
554
+ // successor (road-to-runtime-governance-flip Phase 2). The two are
555
+ // different closures — one is "we measured and the threshold was missed",
556
+ // the other is "we decided to stop having the property" — but both are
557
+ // closed, and both leave a reader who needs the forward link.
347
558
  for (const entry of ledger.values()) {
348
559
  if (!entry.superseded_by) continue;
349
- if (entry.status !== 'resolved-null') {
560
+ if (entry.status !== 'resolved-null' && entry.status !== 'withdrawn') {
350
561
  findings.push({
351
562
  id: entry.id,
352
563
  file: LEDGER_REL,
353
- reason: `superseded_by is only meaningful on a resolved-null entry (status: ${entry.status || 'missing'})`,
564
+ reason: `superseded_by is only meaningful on a closed entry — resolved-null or withdrawn (status: ${entry.status || 'missing'})`,
354
565
  });
355
566
  continue;
356
567
  }
@@ -369,6 +580,154 @@ function main(argv: string[] = process.argv.slice(2)): number {
369
580
  }
370
581
  }
371
582
 
583
+ // 2c. A withdrawal names the decision that retired it. Without the pointer
584
+ // `withdrawn` says only "this closed for a reason that was not a
585
+ // measurement", which is the half of the statement a reader can already
586
+ // infer from the absence of `resolved-null`.
587
+ for (const entry of ledger.values()) {
588
+ if (entry.status !== 'withdrawn') continue;
589
+ if (!entry.retired_by) {
590
+ findings.push({
591
+ id: entry.id,
592
+ file: LEDGER_REL,
593
+ reason: 'status is withdrawn but no `retired_by` names the decision that retired it',
594
+ });
595
+ }
596
+ }
597
+ for (const entry of ledger.values()) {
598
+ if (entry.retired_by && entry.status !== 'withdrawn') {
599
+ findings.push({
600
+ id: entry.id,
601
+ file: LEDGER_REL,
602
+ reason: `retired_by is only meaningful on a withdrawn entry (status: ${entry.status || 'missing'})`,
603
+ });
604
+ }
605
+ }
606
+
607
+ // 2d. `retires_phrasings` — shape. A retirement that names no wording
608
+ // forbids no wording, and a wording too short to be specific forbids
609
+ // half the tree. Both are findings at any count; the COVERAGE question
610
+ // (is every closed row populated?) is a ratchet further down, because
611
+ // that is the number that can only shrink.
612
+ for (const entry of ledger.values()) {
613
+ const raw = entry.retires_phrasings;
614
+ if (!entry.retires_phrasings_present) continue;
615
+ if (entry.status !== 'resolved-null' && entry.status !== 'withdrawn') {
616
+ findings.push({
617
+ id: entry.id,
618
+ file: LEDGER_REL,
619
+ reason: `retires_phrasings is only meaningful on a closed entry — resolved-null or withdrawn (status: ${entry.status || 'missing'})`,
620
+ });
621
+ continue;
622
+ }
623
+ if (raw.startsWith(NEVER_PUBLISHED)) {
624
+ // The sentinel is a claim about history, so it carries its reason.
625
+ // `never-published` alone is indistinguishable from "nobody looked".
626
+ const reason = raw.slice(NEVER_PUBLISHED.length).replace(/^[\s\u2014-]+/, '').trim();
627
+ if (reason.length < 20) {
628
+ findings.push({
629
+ id: entry.id,
630
+ file: LEDGER_REL,
631
+ reason:
632
+ 'retires_phrasings says never-published but states no reason — the sentinel ' +
633
+ 'asserts that history was read and came back empty, and an unreasoned one is ' +
634
+ 'indistinguishable from nobody having looked',
635
+ });
636
+ }
637
+ continue;
638
+ }
639
+ const phrasings = parse_retired_phrasings(raw);
640
+ if (phrasings.length === 0) {
641
+ findings.push({
642
+ id: entry.id,
643
+ file: LEDGER_REL,
644
+ reason: 'retires_phrasings is present but empty — a retirement that names no wording forbids none',
645
+ });
646
+ continue;
647
+ }
648
+ for (const ph of phrasings) {
649
+ if (ph.length < MIN_PHRASING_CHARS) {
650
+ findings.push({
651
+ id: entry.id,
652
+ file: LEDGER_REL,
653
+ reason: `retires_phrasings carries "${ph}" (${ph.length} chars) — under ${MIN_PHRASING_CHARS} it is a needle that matches ordinary prose, which is how this gate gets muted`,
654
+ });
655
+ }
656
+ }
657
+ }
658
+
659
+ // 2e. THE REACH. A retired phrasing may not appear on a publish surface.
660
+ // This is the half the ledger never had: `check_claims` read the row's
661
+ // own shape, `lint_positioning` read three surfaces against each other,
662
+ // and nothing read the row against the surfaces. The live instance was
663
+ // the withdrawn `no-runtime-daemon` wording still shipping in
664
+ // `package.json.description` and `.github/about.yml`.
665
+ //
666
+ // Match is case-insensitive substring over the raw file, per rule (3)
667
+ // at PUBLISH_SURFACES: a retired phrasing is equally wrong in a
668
+ // keyword, a nested description, or a comment.
669
+ //
670
+ // THE SCAN ROOT IS ASSERTED, and asserted CONDITIONALLY. A watch-list
671
+ // guard whose paths all vanish reports clean forever — the
672
+ // `check_safety_floor_untouched` shape, which announced "4 rules
673
+ // guarded" while guarding none. `assertWatchlistResolves` is that
674
+ // assertion. It runs only when there is at least one needle to look
675
+ // for, because a ledger carrying no retired phrasings has nothing to
676
+ // watch, and a phantom watchlist over an empty needle set is a false
677
+ // alarm rather than a caught defect (it is also every fixture tree).
678
+ //
679
+ // A needle under MIN_PHRASING_CHARS is already a finding above and is
680
+ // excluded here rather than searched: reporting it twice, once as a
681
+ // bad needle and once as a phantom watchlist, buries the actionable
682
+ // message under the derived one.
683
+ const usableNeedles = new Map<string, string[]>();
684
+ for (const e of ledger.values()) {
685
+ if (e.status !== 'resolved-null' && e.status !== 'withdrawn') continue;
686
+ if (e.retires_phrasings === '' || e.retires_phrasings.startsWith(NEVER_PUBLISHED)) continue;
687
+ const usable = parse_retired_phrasings(e.retires_phrasings).filter(
688
+ (ph) => ph.length >= MIN_PHRASING_CHARS,
689
+ );
690
+ if (usable.length > 0) usableNeedles.set(e.id, usable);
691
+ }
692
+ let liveSurfaces: string[] = [];
693
+ if (usableNeedles.size > 0) {
694
+ try {
695
+ liveSurfaces = assertWatchlistResolves({
696
+ gate: 'check_claims:publish-surfaces',
697
+ candidates: PUBLISH_SURFACES,
698
+ repoRoot: REPO,
699
+ });
700
+ } catch (exc) {
701
+ if (!(exc instanceof DeadScopeError)) throw exc;
702
+ // A FINDING, not an early return. Returning here would suppress
703
+ // every finding already collected, and the dead-root message would
704
+ // arrive alone — hiding the shape errors that are usually the
705
+ // reason somebody is reading this output.
706
+ findings.push({
707
+ id: 'publish-surfaces',
708
+ file: LEDGER_REL,
709
+ reason: exc.message,
710
+ });
711
+ }
712
+ }
713
+ for (const entry of ledger.values()) {
714
+ const phrasings = usableNeedles.get(entry.id);
715
+ if (phrasings === undefined) continue;
716
+ for (const rel of liveSurfaces) {
717
+ const abs = path.join(REPO, rel);
718
+ const body = fs.readFileSync(abs, 'utf8').toLowerCase();
719
+ for (const ph of phrasings) {
720
+ if (body.includes(ph.toLowerCase())) {
721
+ findings.push({
722
+ id: entry.id,
723
+ file: rel,
724
+ reason: `publishes the retired phrasing "${ph}" — claim:${entry.id} is ${entry.status}, so this wording may no longer ship`,
725
+ });
726
+ }
727
+ }
728
+ }
729
+ }
730
+
372
731
  // 3. Witness sweep (road-to-opt-subagent-harvest P1.2): a QUANTIFIED
373
732
  // capability claim on a marketing-class surface must be witnessed — a
374
733
  // `<!-- claim:ID -->` marker on the same line, or an explicit
@@ -486,6 +845,98 @@ function main(argv: string[] = process.argv.slice(2)): number {
486
845
  }
487
846
  }
488
847
 
848
+ // 5. Non-inference ratchet (road-to-skill-ecosystem-eval-integrity 5.5).
849
+ //
850
+ // A measured number travels further than its measurement. `non_inference`
851
+ // is the sentence that stops it, and it is a sentence nobody writes unless
852
+ // something asks. Scoped to `backed` + `quant`, which is exactly the class
853
+ // that gets quoted out of context: a qualitative claim carries its own
854
+ // hedge in the prose, a quantitative one carries a figure.
855
+ //
856
+ // A RATCHET rather than a requirement, deliberately: 42 backed quant
857
+ // entries lack the field today, and failing the build on all of them at
858
+ // once produces a gate that can only block — the shape this repository's
859
+ // own records name as the reason a gate gets suppressed. Every NEW backed
860
+ // quant claim must carry it; the inherited 42 come along as they are
861
+ // touched. A present-but-empty field is a finding at any count, because
862
+ // that is an author answering the question with silence.
863
+ const missingNonInference = [...ledger.values()].filter(
864
+ (e) => e.status === 'backed' && e.kind === 'quant' && e.non_inference === '',
865
+ );
866
+ const emptyNonInference = [...ledger.values()].filter(
867
+ (e) => e.non_inference !== '' && e.non_inference.trim().length < 20,
868
+ );
869
+ for (const e of emptyNonInference) {
870
+ findings.push({
871
+ id: e.id,
872
+ file: LEDGER_REL,
873
+ reason:
874
+ 'non_inference is present but says almost nothing — the field exists to enumerate ' +
875
+ 'what the data does NOT license, and a placeholder is worse than an absent field ' +
876
+ 'because it reads as answered',
877
+ });
878
+ }
879
+ // The ratchet is a property of a repository that RECORDS baselines. A tree
880
+ // with no baselines file at all is a fixture, not a repository silencing a
881
+ // gate, and the two are distinguishable: a MISSING FILE skips, while a
882
+ // present file with no entry still fails — which is the anti-silencing
883
+ // property, since deleting one entry from a tracked file is the cheap way
884
+ // to make this go away and it must not work.
885
+ const baselinesPath = path.join(REPO, 'src', 'config', 'gate-violation-baselines.json');
886
+ const nonInferenceVerdict = fs.existsSync(baselinesPath)
887
+ ? checkRatchet({
888
+ gate: 'check_claims:non-inference',
889
+ actual: missingNonInference.length,
890
+ repoRoot: REPO,
891
+ })
892
+ : { ok: true, message: '' };
893
+ if (!nonInferenceVerdict.ok) {
894
+ findings.push({
895
+ id: 'non-inference',
896
+ file: LEDGER_REL,
897
+ reason: nonInferenceVerdict.message,
898
+ });
899
+ }
900
+
901
+ // 6. Retired-phrasings COVERAGE ratchet (road-to-retired-claims-stay-retired
902
+ // Phase 1.2). Every closed entry names what its retirement forbids; the
903
+ // field stays optional at the SCHEMA level so a fixture and a
904
+ // mid-authoring row still parse, and this is where absence becomes a
905
+ // finding.
906
+ //
907
+ // DELIBERATELY UNBASELINED, unlike the `non_inference` ratchet above.
908
+ // All eight closed rows were populated in the change that introduced the
909
+ // field, so there is no inherited debt to carry — and `checkRatchet`
910
+ // with no recorded entry returns `ok: actual === 0`
911
+ // (src/scripts/_lib/gate_baseline.ts:288-301), which is exactly the
912
+ // hard-zero this needs. Recording a baseline of 0 would be worse than
913
+ // recording none: a 0 can never DROP, so the 56-day anti-fossilization
914
+ // clause (STALE_AFTER_DAYS, :41) would fail the gate two months from now
915
+ // for a count that was correct the whole time.
916
+ const closedWithoutPhrasings = [...ledger.values()].filter(
917
+ (e) =>
918
+ (e.status === 'resolved-null' || e.status === 'withdrawn') &&
919
+ !e.retires_phrasings_present,
920
+ );
921
+ const phrasingsVerdict = fs.existsSync(baselinesPath)
922
+ ? checkRatchet({
923
+ gate: 'check_claims:retired-phrasings',
924
+ actual: closedWithoutPhrasings.length,
925
+ repoRoot: REPO,
926
+ })
927
+ : { ok: true, message: '' };
928
+ if (!phrasingsVerdict.ok) {
929
+ findings.push({
930
+ id: 'retired-phrasings',
931
+ file: LEDGER_REL,
932
+ reason:
933
+ `${phrasingsVerdict.message}` +
934
+ (closedWithoutPhrasings.length > 0
935
+ ? ` — closed without the field: ${closedWithoutPhrasings.map((e) => e.id).join(', ')}`
936
+ : ''),
937
+ });
938
+ }
939
+
489
940
  if (findings.length > 0) {
490
941
  process.stderr.write(`❌ check_claims: ${findings.length} unbacked/dangling claim(s):\n`);
491
942
  for (const f of findings) {
@@ -526,6 +977,125 @@ function _isCliEntry(): boolean {
526
977
  return false;
527
978
  }
528
979
  }
980
+ /**
981
+ * `--self-test` — the gate proving its own rejections still fire.
982
+ *
983
+ * Required by the `gate-self-test:registered-non-adopters` ratchet once this
984
+ * gate joined `src/config/gate-coverage.yml`, and worth having on its own
985
+ * terms: `check_claims` resolves `REPO` from its own file location rather than
986
+ * from `cwd`, so the only way to point it at a fixture is to COPY it into one.
987
+ * That is what the harness below does, and it is why `runGateCli` is handed a
988
+ * path that walks back out of the repository — `path.join(REPO, relative)`
989
+ * resolves into the temporary tree while `tsx` is still found under the real
990
+ * `node_modules`.
991
+ *
992
+ * Four of the five cases are the retired-phrasings reach added by
993
+ * road-to-retired-claims-stay-retired; the fixture in the rejecting one carries
994
+ * the LITERAL historical string that shipped on two publish surfaces while
995
+ * `claim:no-runtime-daemon` was already `withdrawn`.
996
+ */
997
+ function selfTest(): number {
998
+ const roots: string[] = [];
999
+ // FOUR, not three: this gate imports `gate_self_test.ts` for the harness
1000
+ // it is running right now, and a missing fourth lib fails as a module
1001
+ // resolution error in EVERY case at once — which reads as the detection
1002
+ // having broken rather than the fixture being incomplete.
1003
+ const libs = ['exec_evidence.ts', 'scan_scope.ts', 'gate_baseline.ts', 'gate_self_test.ts'];
1004
+
1005
+ const fixture = (files: Record<string, string>): number => {
1006
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'check-claims-selftest-'));
1007
+ roots.push(dir);
1008
+ fs.mkdirSync(path.join(dir, 'src', 'scripts', '_lib'), { recursive: true });
1009
+ fs.copyFileSync(_FILE, path.join(dir, 'src', 'scripts', 'check_claims.ts'));
1010
+ for (const lib of libs) {
1011
+ fs.copyFileSync(
1012
+ path.join(REPO, 'src', 'scripts', '_lib', lib),
1013
+ path.join(dir, 'src', 'scripts', '_lib', lib),
1014
+ );
1015
+ }
1016
+ fs.mkdirSync(path.join(dir, 'docs'), { recursive: true });
1017
+ fs.writeFileSync(path.join(dir, 'docs', 'evidence.md'), 'Contains the ANCHOR string.\n');
1018
+ for (const [rel, body] of Object.entries(files)) {
1019
+ const abs = path.join(dir, rel);
1020
+ fs.mkdirSync(path.dirname(abs), { recursive: true });
1021
+ fs.writeFileSync(abs, body);
1022
+ }
1023
+ const rel = path.relative(REPO, path.join(dir, 'src', 'scripts', 'check_claims.ts'));
1024
+ return runGateCli(REPO, rel, [], dir);
1025
+ };
1026
+
1027
+ const closed = (phrasings: string | null): string =>
1028
+ [
1029
+ '# Claims Ledger',
1030
+ '',
1031
+ '### claim: no-runtime-daemon',
1032
+ '- claim: Compiled into host agents with zero runtime daemon.',
1033
+ '- kind: qual',
1034
+ '- evidence: docs/evidence.md#ANCHOR',
1035
+ '- status: withdrawn',
1036
+ '- last_verified: 2026-07-04',
1037
+ '- retired_by: ADR-249',
1038
+ ...(phrasings === null ? [] : [`- retires_phrasings: ${phrasings}`]),
1039
+ '',
1040
+ ].join('\n');
1041
+
1042
+ const CLEAN_README = '# Agent Config\n\nGoverned skills, rules and commands.\n';
1043
+
1044
+ const cases: SelfTestCase[] = [
1045
+ {
1046
+ name: 'a retired phrasing absent from every publish surface → accept',
1047
+ expect: 'accept',
1048
+ run: () =>
1049
+ fixture({
1050
+ 'docs/CLAIMS.md': closed('zero runtime daemon'),
1051
+ 'README.md': CLEAN_README,
1052
+ }),
1053
+ },
1054
+ {
1055
+ name: 'the LITERAL historical string in package.json.description → reject',
1056
+ expect: 'reject',
1057
+ run: () =>
1058
+ fixture({
1059
+ 'docs/CLAIMS.md': closed('zero runtime daemon'),
1060
+ 'package.json':
1061
+ '{\n "description": "every claim machine-checked, including \\"zero runtime daemon\\"."\n}\n',
1062
+ }),
1063
+ },
1064
+ {
1065
+ name: 'a present-but-empty retires_phrasings → reject',
1066
+ expect: 'reject',
1067
+ run: () => fixture({ 'docs/CLAIMS.md': closed(''), 'README.md': CLEAN_README }),
1068
+ },
1069
+ {
1070
+ name: 'a needle too short to be specific → reject',
1071
+ expect: 'reject',
1072
+ run: () => fixture({ 'docs/CLAIMS.md': closed('daemon'), 'README.md': CLEAN_README }),
1073
+ },
1074
+ {
1075
+ name: 'the never-published sentinel with a stated reason → accept',
1076
+ expect: 'accept',
1077
+ run: () =>
1078
+ fixture({
1079
+ 'docs/CLAIMS.md': closed(
1080
+ 'never-published — verified by `git log -S` over every publish surface: zero commits.',
1081
+ ),
1082
+ 'README.md': `${CLEAN_README}\nIt mentions zero runtime daemon freely.\n`,
1083
+ }),
1084
+ },
1085
+ ];
1086
+
1087
+ try {
1088
+ return runSelfTest({
1089
+ gate: 'check_claims',
1090
+ cases,
1091
+ minCases: 5,
1092
+ minRejectCases: 3,
1093
+ });
1094
+ } finally {
1095
+ for (const d of roots) fs.rmSync(d, { recursive: true, force: true });
1096
+ }
1097
+ }
1098
+
529
1099
  if (_isCliEntry()) {
530
1100
  try {
531
1101
  process.exit(main());