@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
@@ -43,7 +43,9 @@ import {
43
43
  AGENTIC_MODES,
44
44
  DISCOVERY_STATES,
45
45
  EVIDENCE_STRENGTHS,
46
+ PROTECTED_DIMENSIONS,
46
47
  PROVENANCE_KINDS,
48
+ REOPEN_POLICIES,
47
49
  evidenceOf,
48
50
  provenanceOf,
49
51
  readAdrFrontmatter,
@@ -60,6 +62,20 @@ const ADR_DIR = path.join(REPO_ROOT, 'docs', 'decisions');
60
62
  */
61
63
  export const REVIEW_TRIGGER_SINCE = '2026-07-25';
62
64
 
65
+ /**
66
+ * Staging date for the `## Not reopened` obligation on a scoped supersession
67
+ * (road-to-runtime-governance-flip step 1.4). Same shape and same reason as
68
+ * `REVIEW_TRIGGER_SINCE`: a new structural requirement is an error on records
69
+ * written after it and a warning on records written before, so the gate does
70
+ * not retroactively red the corpus it is being added to.
71
+ *
72
+ * Two records predate it and warn: `ADR-124` (2026-07-23) and `ADR-209`
73
+ * (2026-08-03). Both carry a real `supersedes_scope` and neither states its
74
+ * remainder in a section — measured, not assumed, and left visible as a warning
75
+ * rather than silenced with a baseline file.
76
+ */
77
+ export const SCOPED_SUPERSESSION_SINCE = '2026-08-27';
78
+
63
79
  /** Fields every ADR must carry — the shape that already exists in practice. */
64
80
  const REQUIRED = ['adr', 'status', 'date', 'decision'] as const;
65
81
 
@@ -73,16 +89,9 @@ const REQUIRED = ['adr', 'status', 'date', 'decision'] as const;
73
89
  * the same words. This validator therefore checks the VALUE when present and
74
90
  * never requires the KEY.
75
91
  */
76
- const ALLOWED_REOPEN_POLICY = new Set(['directional', 'owner', 'unclassified']);
77
-
78
- const ALLOWED_PROTECTED_DIMENSIONS = new Set([
79
- 'purpose',
80
- 'security_floor',
81
- 'privacy_floor',
82
- 'external_commitment',
83
- 'governance',
84
- 'none',
85
- ]);
92
+ const ALLOWED_REOPEN_POLICY = new Set<string>(REOPEN_POLICIES);
93
+
94
+ const ALLOWED_PROTECTED_DIMENSIONS = new Set<string>(PROTECTED_DIMENSIONS);
86
95
 
87
96
  /** Split an inline `[a, b]` list or a folded multi-value string into members. */
88
97
  export function split_dimensions(raw: string): string[] {
@@ -150,6 +159,12 @@ export function check_reopen_authority(
150
159
  }
151
160
 
152
161
  const ALLOWED_STATUS = new Set([
162
+ // `challenged` — accepted, and under active question. It names NO successor
163
+ // and SUSPENDS NOTHING: an ADR at `challenged` still binds until something
164
+ // replaces it. Without that clause the status becomes a way to stop obeying
165
+ // a decision without reopening it, which is the failure mode
166
+ // road-to-decision-conformance 1.2 exists to prevent.
167
+ 'challenged',
153
168
  'accepted',
154
169
  'proposed',
155
170
  'superseded',
@@ -258,6 +273,7 @@ export function check_one(rel: string, text: string): AdrFinding[] {
258
273
  }
259
274
  check_reopen_authority(rel, fm, findings);
260
275
  check_amendment_shape(rel, fm, findings);
276
+ check_scoped_supersession(rel, fm, text, findings);
261
277
  const parsed = readAdrFrontmatter(text);
262
278
  if (parsed !== null) check_descriptive_axes(rel, parsed, findings);
263
279
  return findings;
@@ -546,6 +562,111 @@ export function check_amendment_shape(
546
562
  }
547
563
  }
548
564
 
565
+ /**
566
+ * Validate a SCOPED supersession — the `supersedes_scope` / `superseded_scope`
567
+ * pair documented at `docs/contracts/adr-layout.md:59-60, 105-117`.
568
+ *
569
+ * Two invariants, both decidable from one file, both taken from that contract's
570
+ * own text rather than invented here:
571
+ *
572
+ * 1. **A scope with no refs is not a supersession.** The contract says so
573
+ * literally — "A scope with no refs is not a supersession and renders as
574
+ * `—`" — and `regenerate_index.ts` → `supersessionCell` silently drops the
575
+ * scope in that case, so the author's intent disappears with no signal.
576
+ * 2. **A scoped supersession names what it did NOT reopen.** Narrowing a
577
+ * prohibition to one row is precisely when a reader needs the boundary
578
+ * stated, and a `## Not reopened` section is where this corpus states it.
579
+ * Without the section, "supersedes ADR-NNN, partially" is an assertion with
580
+ * no stated remainder, and the remainder is the whole content of a partial
581
+ * supersession.
582
+ *
583
+ * **What this deliberately does NOT check**, because it is not observable: it
584
+ * cannot require a scope wherever partial supersession was *intended*. Intent
585
+ * is not in the file. A whole-document supersession that should have been
586
+ * scoped passes this check, and closing that gap needs stable section
587
+ * identifiers rather than prose scopes — recorded as the known limit rather
588
+ * than implied away.
589
+ *
590
+ * road-to-runtime-governance-flip step 1.4, which asked for exactly one thing:
591
+ * make the required section enforceable, or drop the word "required".
592
+ */
593
+ /**
594
+ * Is there a `## Not reopened` section WITH content under it?
595
+ *
596
+ * Two corrections a neutral review made to the first version, both real:
597
+ *
598
+ * 1. **The level is exactly `##`.** The first pattern was `#{2,3}`, so a `###`
599
+ * subsection satisfied a contract and a diagnostic that both say `##`. A gate
600
+ * accepting a shape its own message forbids teaches the message is decorative.
601
+ * 2. **The section must say something.** Matching the heading alone let an empty
602
+ * section pass while the error text promises one "naming what the narrowing
603
+ * leaves standing". A heading with nothing under it is the absence the check
604
+ * exists to catch, wearing the right title.
605
+ *
606
+ * "Content" is deliberately weak — one non-blank, non-heading line. No gate can
607
+ * judge whether the prose is true, and pretending otherwise would be the
608
+ * masquerade the sibling gate's docstring warns about.
609
+ */
610
+ export function hasNotReopenedSection(text: string): boolean {
611
+ const lines = text.split('\n');
612
+ const start = lines.findIndex((l) => /^##\s+Not reopened\s*$/i.test(l));
613
+ if (start === -1) return false;
614
+ for (const line of lines.slice(start + 1)) {
615
+ if (/^#{1,6}\s/.test(line)) break;
616
+ if (line.trim() !== '') return true;
617
+ }
618
+ return false;
619
+ }
620
+
621
+ export function check_scoped_supersession(
622
+ rel: string,
623
+ fm: Record<string, string>,
624
+ text: string,
625
+ findings: AdrFinding[],
626
+ ): void {
627
+ const placeholder = (v: string | undefined): boolean =>
628
+ v === undefined || v.trim() === '' || v.trim() === '—' || v.trim() === '-';
629
+
630
+ for (const [scopeKey, refKey] of [
631
+ ['supersedes_scope', 'supersedes'],
632
+ ['superseded_scope', 'superseded_by'],
633
+ ] as const) {
634
+ if (placeholder(fm[scopeKey])) continue;
635
+ if (placeholder(fm[refKey])) {
636
+ findings.push({
637
+ file: rel,
638
+ level: 'error',
639
+ message:
640
+ `\`${scopeKey}\` is set but \`${refKey}\` names no ADR. A scope with no refs ` +
641
+ 'is not a supersession (adr-layout § Frontmatter) — the index renders it as ' +
642
+ '`—` and the scope text is lost. Name the record, or drop the scope.',
643
+ });
644
+ }
645
+ }
646
+
647
+ // The "Not reopened" obligation is on the record that PERFORMS the scoped
648
+ // supersession, never on the one that receives it: the successor is what
649
+ // has to state the remainder.
650
+ if (placeholder(fm['supersedes_scope'])) return;
651
+ if (!hasNotReopenedSection(text)) {
652
+ // A well-formed ISO date, or no grandfathering. A malformed `date:`
653
+ // sorts unpredictably against the staging constant, and the safe
654
+ // direction for an unreadable date is the error, not the warning.
655
+ const date = fm['date'] ?? '';
656
+ const wellFormed = /^\d{4}-\d{2}-\d{2}$/.test(date);
657
+ const staged = wellFormed && date < SCOPED_SUPERSESSION_SINCE;
658
+ findings.push({
659
+ file: rel,
660
+ level: staged ? 'warn' : 'error',
661
+ message:
662
+ 'a scoped supersession (`supersedes_scope`) must carry a `## Not reopened` ' +
663
+ 'section naming what the narrowing leaves standing. Partially superseding a ' +
664
+ 'record without stating the remainder reads as a general relaxation, which is ' +
665
+ 'the reading a safety floor cannot survive.',
666
+ });
667
+ }
668
+ }
669
+
549
670
  /**
550
671
  * Corpus-level check: every `amends:` has its reciprocal `amended_by:` and vice
551
672
  * versa. Its absence for the `supersedes:` / `superseded_by:` pair is exactly
@@ -0,0 +1,207 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * A benchmark or cost report that omits a required cache field fails, naming the
4
+ * field (`road-to-runtime-context-floors` step 4.1).
5
+ *
6
+ * `cache.read_write_ratio` and `cache.stable_prefix_share` are REQUIRED. A report
7
+ * that cannot compute one emits `{ unavailable: "<reason>" }`; it does not omit
8
+ * the key and it does not emit a zero. A blank reads as "no cache activity" and a
9
+ * zero reads as "the worst possible ratio" — both are claims, and neither is the
10
+ * claim "this was not measured".
11
+ *
12
+ * Contract: `docs/contracts/benchmark-report-schema.md` § The `cache` block.
13
+ *
14
+ * Exit codes: 0 every scanned report carries both fields · 1 a report is missing
15
+ * or malformed · 2 misuse / unreadable input.
16
+ *
17
+ * Usage:
18
+ * ./scripts-run src/scripts/check_benchmark_report_fields [--dir <path>] [--quiet]
19
+ * ./scripts-run src/scripts/check_benchmark_report_fields --self-test
20
+ */
21
+ import * as fs from 'node:fs';
22
+ import * as os from 'node:os';
23
+ import * as path from 'node:path';
24
+
25
+ import { describeProblem, validateCacheBlock, validateProvenanceBlock } from './_lib/benchmark_cache_fields.js';
26
+ import { GateLedger } from './_lib/gate_ledger.js';
27
+ import { runGateCli, runSelfTest, type SelfTestCase } from './_lib/gate_self_test.js';
28
+ import { DeadScopeError, reportScanned } from './_lib/scan_scope.js';
29
+
30
+ const HERE = path.dirname(new URL(import.meta.url).pathname);
31
+ const REPO_ROOT = path.resolve(HERE, '..', '..');
32
+ const DEFAULT_DIR = path.join(REPO_ROOT, 'internal', 'bench', 'reports');
33
+
34
+ export interface ReportFinding {
35
+ file: string;
36
+ message: string;
37
+ }
38
+
39
+ export interface FieldVerdict {
40
+ scanned: number;
41
+ findings: ReportFinding[];
42
+ }
43
+
44
+ /** Only files that ANNOUNCE themselves as benchmark reports are in the corpus. */
45
+ function isBenchmarkReport(doc: unknown): boolean {
46
+ const d = doc as { schema_version?: unknown; selection?: unknown; corpus?: unknown } | null;
47
+ if (d === null || typeof d !== 'object') return false;
48
+ return d.schema_version !== undefined && (d.selection !== undefined || d.corpus !== undefined);
49
+ }
50
+
51
+ export function evaluate(dir: string = DEFAULT_DIR, ledger?: GateLedger): FieldVerdict {
52
+ const findings: ReportFinding[] = [];
53
+ let scanned = 0;
54
+ if (!fs.existsSync(dir)) return { scanned, findings };
55
+
56
+ const names = fs.readdirSync(dir).sort();
57
+ ledger?.plan(names);
58
+
59
+ for (const name of names) {
60
+ if (!name.endsWith('.json')) {
61
+ ledger?.outOfScope(name, 'not_applicable_kind');
62
+ continue;
63
+ }
64
+ const file = path.join(dir, name);
65
+ let doc: unknown;
66
+ try {
67
+ doc = JSON.parse(fs.readFileSync(file, 'utf-8'));
68
+ } catch {
69
+ // Not our corpus; a malformed JSON is another gate's finding.
70
+ ledger?.skip(name, 'binary_content');
71
+ continue;
72
+ }
73
+ if (!isBenchmarkReport(doc)) {
74
+ ledger?.outOfScope(name, 'not_applicable_kind');
75
+ continue;
76
+ }
77
+ scanned += 1;
78
+ const problems = [...validateCacheBlock(doc), ...validateProvenanceBlock(doc)];
79
+ for (const p of problems) {
80
+ findings.push({ file: path.relative(REPO_ROOT, file), message: describeProblem(p) });
81
+ }
82
+ if (problems.length > 0) ledger?.fail(name, `${String(problems.length)} missing or malformed required field(s)`);
83
+ else ledger?.complete(name);
84
+ }
85
+ return { scanned, findings };
86
+ }
87
+
88
+ // ---------------------------------------------------------------- self-test
89
+
90
+ const BASE = { schema_version: 1, corpus: { id: 'x' }, selection: { top_k: 3 } };
91
+
92
+ const GOOD_CACHE = { read_write_ratio: 2, stable_prefix_share: 0.5 };
93
+
94
+ /** A provenance block that passes, so a cache-field case tests only cache fields. */
95
+ const GOOD_PROVENANCE = {
96
+ host_binary_hash: 'sha256:deadbeef',
97
+ harness_commit: 'abc1234',
98
+ harness_dirty: false,
99
+ reproducibility: 'task bench-run --corpus x at the commit above',
100
+ };
101
+
102
+ function plant(dir: string, cache: unknown, provenance: unknown = GOOD_PROVENANCE): void {
103
+ const doc: Record<string, unknown> = { ...BASE };
104
+ if (cache !== undefined) doc['cache'] = cache;
105
+ if (provenance !== undefined) doc['provenance'] = provenance;
106
+ fs.writeFileSync(path.join(dir, 'report.json'), JSON.stringify(doc));
107
+ }
108
+
109
+ function selfTestCases(): SelfTestCase[] {
110
+ const mk = (name: string, expect: 'reject' | 'accept', cache: unknown, provenance?: unknown): SelfTestCase => ({
111
+ name,
112
+ expect,
113
+ run: () => {
114
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'brf-'));
115
+ try {
116
+ plant(dir, cache, provenance === undefined ? GOOD_PROVENANCE : provenance);
117
+ return runGateCli(REPO_ROOT, 'src/scripts/check_benchmark_report_fields.ts', ['--dir', dir, '--quiet'], REPO_ROOT);
118
+ } finally {
119
+ fs.rmSync(dir, { recursive: true, force: true });
120
+ }
121
+ },
122
+ });
123
+ return [
124
+ mk('no cache block at all → reject', 'reject', undefined),
125
+ mk('read_write_ratio missing → reject', 'reject', { stable_prefix_share: 0.5 }),
126
+ mk('stable_prefix_share missing → reject', 'reject', { read_write_ratio: 2 }),
127
+ mk('both present as numbers → accept', 'accept', { read_write_ratio: 2, stable_prefix_share: 0.5 }),
128
+ mk('unavailable WITH a reason → accept', 'accept', {
129
+ read_write_ratio: { unavailable: 'no cache_creation tokens in window' },
130
+ stable_prefix_share: 0.5,
131
+ }),
132
+ mk('unavailable with a BLANK reason → reject', 'reject', {
133
+ read_write_ratio: { unavailable: ' ' },
134
+ stable_prefix_share: 0.5,
135
+ }),
136
+ mk('a share above 1 → reject', 'reject', { read_write_ratio: 2, stable_prefix_share: 1.5 }),
137
+ // Provenance half (step 4.2) — the four reproducibility fields.
138
+ mk('no provenance block at all → reject', 'reject', GOOD_CACHE, null),
139
+ mk('harness_commit missing → reject', 'reject', GOOD_CACHE, { ...GOOD_PROVENANCE, harness_commit: undefined }),
140
+ mk('reproducibility is an empty string → reject', 'reject', GOOD_CACHE, { ...GOOD_PROVENANCE, reproducibility: ' ' }),
141
+ mk('harness_dirty as a string → reject', 'reject', GOOD_CACHE, { ...GOOD_PROVENANCE, harness_dirty: 'no' }),
142
+ // `false` is the GOOD case for a dirty flag, and a truthiness check
143
+ // would silently reject it. Pinned so it cannot regress.
144
+ mk('harness_dirty: false → accept', 'accept', GOOD_CACHE, { ...GOOD_PROVENANCE, harness_dirty: false }),
145
+ mk('harness_dirty: true → accept — a fact, not a failure', 'accept', GOOD_CACHE, { ...GOOD_PROVENANCE, harness_dirty: true }),
146
+ mk('a field unavailable WITH a reason → accept', 'accept', GOOD_CACHE, {
147
+ ...GOOD_PROVENANCE,
148
+ host_binary_hash: { unavailable: 'the host binary is not on PATH in this runner' },
149
+ }),
150
+ ];
151
+ }
152
+
153
+ // ---------------------------------------------------------------------- CLI
154
+
155
+ export function main(argv: string[] = process.argv.slice(2)): number {
156
+ if (argv.includes('--self-test')) {
157
+ return runSelfTest({ gate: 'check_benchmark_report_fields', cases: selfTestCases(), minCases: 12, minRejectCases: 8 });
158
+ }
159
+ const quiet = argv.includes('--quiet');
160
+ const di = argv.indexOf('--dir');
161
+ const dirArg = di !== -1 ? argv[di + 1] : undefined;
162
+ const dir = dirArg !== undefined ? path.resolve(dirArg) : DEFAULT_DIR;
163
+
164
+ const ledger = new GateLedger('check_benchmark_report_fields');
165
+ let v: FieldVerdict;
166
+ try {
167
+ v = evaluate(dir, ledger);
168
+ } catch (err) {
169
+ process.stderr.write(`❌ check_benchmark_report_fields: ${(err as Error).message}\n`);
170
+ return 2;
171
+ }
172
+
173
+ try {
174
+ reportScanned({
175
+ gate: 'check_benchmark_report_fields',
176
+ scanned: v.scanned,
177
+ units: 'benchmark report(s)',
178
+ roots: [path.relative(REPO_ROOT, dir)],
179
+ // A tree with no committed benchmark report is a real state: reports
180
+ // are run artefacts, not source. The gate exists to fail the day one
181
+ // is committed without the block, not to demand one exist.
182
+ allowEmpty: 'OPTIONAL_INPUT: benchmark reports are run artefacts; a checkout may legitimately carry none',
183
+ });
184
+ } catch (err) {
185
+ if (err instanceof DeadScopeError) {
186
+ process.stderr.write(`❌ check_benchmark_report_fields: ${err.message}\n`);
187
+ return 2;
188
+ }
189
+ throw err;
190
+ }
191
+
192
+ ledger.report();
193
+
194
+ if (v.findings.length > 0) {
195
+ for (const f of v.findings) process.stderr.write(`❌ ${f.file}: ${f.message}\n`);
196
+ process.stderr.write(`\n Contract: docs/contracts/benchmark-report-schema.md § The \`cache\` block.\n`);
197
+ return 1;
198
+ }
199
+ if (!quiet) process.stdout.write(`✅ every benchmark report carries its required cache and provenance fields (${String(v.scanned)} report(s)).\n`);
200
+ return 0;
201
+ }
202
+
203
+ if (process.env['GATE_SELF_TEST_CHILD'] !== '1' || process.argv.includes('--dir')) {
204
+ if (process.argv[1] !== undefined && import.meta.url === `file://${process.argv[1]}`) {
205
+ process.exit(main());
206
+ }
207
+ }