@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,15 @@ import * as path from 'node:path';
36
36
  import process from 'node:process';
37
37
  import { fileURLToPath, pathToFileURL } from 'node:url';
38
38
 
39
+ // `mcnemar_exact` and `cohens_h` live in `_lib/paired_stats.ts` and are
40
+ // re-exported here, so every existing importer of this module is unchanged.
41
+ // Extracted rather than left in place: this file sits above the 1500-line
42
+ // ceiling `check_source_size_budget` charges, so lines added to it are paid
43
+ // back by extraction rather than by raising a baseline.
44
+ import { cohens_h, mcnemar_exact, _pyRound, _pyRoundNoArg, wilcoxon } from './_lib/paired_stats.js';
45
+
46
+ export { cohens_h, mcnemar_exact, wilcoxon };
47
+
39
48
  import { cost_usd, tier_for_model, type TierRates } from './_lib/bench_ab_activation.js';
40
49
  import { load_pricing } from './_lib/bench_cost.js';
41
50
 
@@ -80,180 +89,10 @@ const COMPARISONS: Array<[string, string, string]> = [
80
89
 
81
90
  // ── CPython math.erf / math.comb ports ────────────────────────────────────
82
91
  //
83
- // CPython's `m_erf` (Modules/mathmodule.c): a Maclaurin series for |x| < 1.5
84
- // and 1 - erfc for larger |x|; `m_erfc` uses a continued-fraction expansion.
85
- // Ported verbatim so `_phi(z)` matches python3 to full double precision.
86
-
87
- const _ERF_SERIES_CUTOFF = 1.5;
88
- const _ERF_SERIES_TERMS = 25;
89
- const _ERFC_CONTFRAC_CUTOFF = 30.0;
90
- const _ERFC_CONTFRAC_TERMS = 50;
91
- const _SQRTPI = 1.772453850905516027298167483341145182798;
92
-
93
- function _m_erf_series(x: number): number {
94
- // erf(x) = 2/sqrt(pi) * x * sum_{k>=0} (-x^2)^k / (k! (2k+1))
95
- let x2 = x * x;
96
- let acc = 0.0;
97
- let fk = _ERF_SERIES_TERMS + 0.5;
98
- for (let i = 0; i < _ERF_SERIES_TERMS; i += 1) {
99
- acc = 2.0 + (x2 * acc) / fk;
100
- fk -= 1.0;
101
- }
102
- return (acc * x * Math.exp(-x2)) / _SQRTPI;
103
- }
104
-
105
- function _m_erfc_contfrac(x: number): number {
106
- if (x >= _ERFC_CONTFRAC_CUTOFF) {
107
- return 0.0;
108
- }
109
- const x2 = x * x;
110
- let a = 0.0;
111
- let da = 0.5;
112
- let p = 1.0;
113
- let p_last = 0.0;
114
- let q = da + x2;
115
- let q_last = 1.0;
116
- for (let i = 0; i < _ERFC_CONTFRAC_TERMS; i += 1) {
117
- a += da;
118
- da += 2.0;
119
- const b = da + x2;
120
- const temp_p = b * p - a * p_last;
121
- p_last = p;
122
- p = temp_p;
123
- const temp_q = b * q - a * q_last;
124
- q_last = q;
125
- q = temp_q;
126
- }
127
- return (((p / q) * x) * Math.exp(-x2)) / _SQRTPI;
128
- }
129
-
130
- function _erf(x: number): number {
131
- if (Number.isNaN(x)) {
132
- return x;
133
- }
134
- const absx = Math.abs(x);
135
- if (absx < _ERF_SERIES_CUTOFF) {
136
- return _m_erf_series(x);
137
- }
138
- const cf = _m_erfc_contfrac(absx);
139
- return x > 0.0 ? 1.0 - cf : cf - 1.0;
140
- }
141
-
142
- /** Python `math.comb(n, k)` — exact non-negative integer (BigInt → Number). */
143
- function _comb(n: number, k: number): number {
144
- if (k < 0 || k > n) {
145
- return 0;
146
- }
147
- let kk = BigInt(Math.min(k, n - k));
148
- if (kk === 0n) {
149
- return 1;
150
- }
151
- const N = BigInt(n);
152
- let result = 1n;
153
- let i = 0n;
154
- while (i < kk) {
155
- result = (result * (N - i)) / (i + 1n);
156
- i += 1n;
157
- }
158
- return Number(result);
159
- }
92
+ // The erf/normal-CDF port and `wilcoxon` live in `_lib/paired_stats.ts`,
93
+ // re-exported above. Same reason as the two functions beside them: this file
94
+ // is over the 1500-line ceiling, so additions are paid back by extraction.
160
95
 
161
- function _phi(z: number): number {
162
- // Standard-normal CDF via erf.
163
- return 0.5 * (1.0 + _erf(z / Math.sqrt(2.0)));
164
- }
165
-
166
- export function mcnemar_exact(b: number, c: number): number {
167
- // Two-sided exact McNemar p-value (binomial on discordant pairs).
168
- const n = b + c;
169
- if (n === 0) {
170
- return 1.0;
171
- }
172
- const k = Math.min(b, c);
173
- let tail = 0;
174
- for (let i = 0; i <= k; i += 1) {
175
- tail += _comb(n, i);
176
- }
177
- tail = tail * 0.5 ** n;
178
- return Math.min(1.0, 2.0 * tail);
179
- }
180
-
181
- export function cohens_h(p1: number, p2: number): number {
182
- return (
183
- 2 * Math.asin(Math.sqrt(Math.max(0, Math.min(1, p1)))) -
184
- 2 * Math.asin(Math.sqrt(Math.max(0, Math.min(1, p2))))
185
- );
186
- }
187
-
188
- interface WilcoxonResult {
189
- n: number;
190
- W_plus: number; // PyFloat-flagged at dump for the rounded case
191
- W_minus: number;
192
- p: number;
193
- rank_biserial: number;
194
- }
195
-
196
- export function wilcoxon(diffs: number[]): WilcoxonResult {
197
- // Wilcoxon signed-rank on paired differences (treatment - baseline).
198
- // Returns W+, W-, normal-approx two-sided p (continuity-corrected), and
199
- // rank-biserial effect size. Zeros are dropped.
200
- const nz = diffs.filter((d) => Math.abs(d) > 1e-9);
201
- const n = nz.length;
202
- if (n === 0) {
203
- return { n: 0, W_plus: 0, W_minus: 0, p: 1.0, rank_biserial: 0.0 };
204
- }
205
- // order = sorted(range(n), key=lambda i: abs(nz[i])) — stable sort.
206
- const order = Array.from({ length: n }, (_, i) => i).sort((x, y) => {
207
- const ax = Math.abs(nz[x] as number);
208
- const ay = Math.abs(nz[y] as number);
209
- return ax < ay ? -1 : ax > ay ? 1 : x - y; // stable on tie
210
- });
211
- const ranks: number[] = new Array(n).fill(0.0);
212
- let i = 0;
213
- while (i < n) {
214
- let j = i;
215
- while (j + 1 < n && Math.abs(nz[order[j + 1] as number] as number) === Math.abs(nz[order[i] as number] as number)) {
216
- j += 1;
217
- }
218
- const avg = (i + 1 + j + 1) / 2.0; // average rank for ties (1-based)
219
- for (let k = i; k <= j; k += 1) {
220
- ranks[order[k] as number] = avg;
221
- }
222
- i = j + 1;
223
- }
224
- let w_plus = 0.0;
225
- let w_minus = 0.0;
226
- for (let idx = 0; idx < n; idx += 1) {
227
- if ((nz[idx] as number) > 0) {
228
- w_plus += ranks[idx] as number;
229
- } else if ((nz[idx] as number) < 0) {
230
- w_minus += ranks[idx] as number;
231
- }
232
- }
233
- const total = w_plus + w_minus;
234
- const rb = total ? (w_plus - w_minus) / total : 0.0;
235
- // Normal approximation (ok-ish for n>=10; for small n it's conservative —
236
- // we surface n so the reader can weight it).
237
- const mean = (n * (n + 1)) / 4.0;
238
- const sd = Math.sqrt((n * (n + 1) * (2 * n + 1)) / 24.0);
239
- const w = Math.min(w_plus, w_minus);
240
- let p: number;
241
- if (sd === 0) {
242
- p = 1.0;
243
- } else {
244
- const z = (w - mean + 0.5) / sd;
245
- p = Math.min(1.0, 2.0 * _phi(z));
246
- }
247
- return {
248
- n,
249
- // W_plus / W_minus are not surfaced in JSON/markdown (compare() drops
250
- // them), so plain numbers suffice; p / rank_biserial are floats.
251
- W_plus: _pyRound(w_plus, 1),
252
- W_minus: _pyRound(w_minus, 1),
253
- p: _pyRound(p, 4),
254
- rank_biserial: _pyRound(rb, 4),
255
- };
256
- }
257
96
 
258
97
  /** Wrap a `round(...)`/float result so it renders `1.0` not `1` (Python float). */
259
98
  function PF(x: number): PyFloat {
@@ -478,6 +317,14 @@ function _paired_median_block(t: number[], b: number[], diffs: number[]): Dict {
478
317
  // Percent change of the medians. A zero baseline has no percent change —
479
318
  // report null rather than Infinity, which would render as a win.
480
319
  const pct = mb === 0 ? null : PF(_pyRound(((mt - mb) / Math.abs(mb)) * 100, 4));
320
+ // Direction counts, ADDITIVE (Phase-3 PREREG amendment v2, 2026-08-26).
321
+ // The significance half of the size verdict now reads these rather than
322
+ // `wilcoxon_p`; every pre-existing key is untouched, so a consumer reading
323
+ // named keys is unaffected. Tie epsilon matches `wilcoxon`'s own 1e-9 zero
324
+ // drop, so "non-tied" means the same thing to both tests — two definitions
325
+ // of a tie in one report is how the numbers start disagreeing.
326
+ const wins = diffs.filter((d) => d < -1e-9).length;
327
+ const losses = diffs.filter((d) => d > 1e-9).length;
481
328
  return {
482
329
  measured: true,
483
330
  n_pairs: diffs.length,
@@ -488,6 +335,13 @@ function _paired_median_block(t: number[], b: number[], diffs: number[]): Dict {
488
335
  wilcoxon_p: PF(wil.p),
489
336
  rank_biserial: PF(wil.rank_biserial),
490
337
  n_nonzero: wil.n,
338
+ // "Win" is DIRECTION-OF-INTEREST, not sign: for added lines and for
339
+ // cognitive complexity a NEGATIVE delta is the improvement. Naming them
340
+ // wins/losses here rather than positive/negative keeps the verdict from
341
+ // having to know which endpoint it is looking at.
342
+ direction_wins: wins,
343
+ direction_losses: losses,
344
+ direction_ties: diffs.length - wins - losses,
491
345
  };
492
346
  }
493
347
 
@@ -733,6 +587,15 @@ function _toContinuous(block: Dict): PairedContinuous {
733
587
  median_delta_pct: block['median_delta_pct'] == null ? null : _pyFloat(block['median_delta_pct']),
734
588
  median_delta: _pyFloat(block['median_delta']),
735
589
  wilcoxon_p: _pyFloat(block['wilcoxon_p']),
590
+ // Optional-absent rather than defaulted to 0: an older report carries
591
+ // no direction counts, and zeroing them would read as "no trial went
592
+ // either way", which is a measurement rather than a missing field.
593
+ ...(block['direction_wins'] === undefined
594
+ ? {}
595
+ : {
596
+ direction_wins: _pyFloat(block['direction_wins']),
597
+ direction_losses: _pyFloat(block['direction_losses']),
598
+ }),
736
599
  };
737
600
  }
738
601
 
@@ -813,7 +676,7 @@ export function to_markdown(analysis: Dict, payload: Dict): string {
813
676
  L.push('# Discipline-Axis Wrapper-Lift Benchmark (v2)');
814
677
  L.push('');
815
678
  L.push(
816
- '> Generated by `scripts/bench_ab_v2_stats.py --markdown`. Source: ' +
679
+ '> Generated by `bench_ab_v2_stats --markdown`. Do not edit. Source: ' +
817
680
  '`internal/bench/reports/ab-v2/`. Re-render with `task bench:ab:v2:diff`.',
818
681
  );
819
682
  L.push('');
@@ -1366,46 +1229,10 @@ function _pyStr(v: unknown): string {
1366
1229
  return String(v);
1367
1230
  }
1368
1231
 
1369
- /** Python `round(x)` (no ndigits) → int, round-half-to-even. */
1370
- function _pyRoundNoArg(x: number): number {
1371
- if (!Number.isFinite(x)) return x;
1372
- const floor = Math.floor(x);
1373
- const frac = x - floor;
1374
- if (frac < 0.5) return floor;
1375
- if (frac > 0.5) return floor + 1;
1376
- return floor % 2 === 0 ? floor : floor + 1;
1377
- }
1232
+ // `_pyRound` / `_pyRoundNoArg` live in `_lib/paired_stats.ts` (imported above):
1233
+ // `wilcoxon` needs them and moved there, and two copies of a float-parity
1234
+ // rounder is how byte-stable output stops being byte-stable.
1378
1235
 
1379
- /** Python `round(x, ndigits)` — round-half-to-even on the exact double. */
1380
- function _pyRound(value: number, ndigits: number): number {
1381
- if (!Number.isFinite(value) || value === 0) {
1382
- return value;
1383
- }
1384
- const neg = value < 0;
1385
- const abs = Math.abs(value);
1386
- const exact = abs.toFixed(40);
1387
- const dot = exact.indexOf('.');
1388
- const intPart = dot === -1 ? exact : exact.slice(0, dot);
1389
- const fracPart = dot === -1 ? '' : exact.slice(dot + 1);
1390
- const keepFrac = fracPart.slice(0, ndigits).padEnd(ndigits, '0');
1391
- const rest = fracPart.slice(ndigits);
1392
- const scaledStr = (intPart + keepFrac).replace(/^0+(?=\d)/, '');
1393
- let scaled = BigInt(scaledStr === '' ? '0' : scaledStr);
1394
- if (rest.length > 0) {
1395
- const firstRest = rest.charCodeAt(0) - 48;
1396
- const hasMore = /[1-9]/.test(rest.slice(1));
1397
- if (firstRest > 5 || (firstRest === 5 && hasMore)) {
1398
- scaled += 1n;
1399
- } else if (firstRest === 5 && !hasMore) {
1400
- if (scaled % 2n === 1n) {
1401
- scaled += 1n;
1402
- }
1403
- }
1404
- }
1405
- const factor = 10 ** ndigits;
1406
- const result = Number(scaled) / factor;
1407
- return neg ? -result : result;
1408
- }
1409
1236
 
1410
1237
  /** `format(x, '.Nf')` — round-half-even on the exact double, fixed N decimals. */
1411
1238
  function _pyFixed(x: number, ndigits: number): string {
@@ -249,7 +249,7 @@ export function renderJson(entries: readonly ArchiveEntry[]): string {
249
249
  return (
250
250
  JSON.stringify(
251
251
  {
252
- generated_by: 'src/scripts/build_archive_index.ts',
252
+ generated_by: 'build_archive_index',
253
253
  source: ARCHIVE_REL,
254
254
  count: entries.length,
255
255
  entries,
@@ -171,7 +171,7 @@ export function render_digest(layer: string, entries: RuleEntry[]): [string, Dig
171
171
  const parts: string[] = [];
172
172
  parts.push(`# event4u/agent-config — Linear AI ${_title(layer)} Digest\n`);
173
173
  parts.push(
174
- '> Auto-generated by `scripts/build_linear_digest.py` from ' +
174
+ '> Generated by `build_linear_digest`. Do not edit. From ' +
175
175
  '`dist/agent-src/rules/` (condensed source) plus the inclusion list ' +
176
176
  'at `docs/contracts/linear-ai-rules-inclusion.md`. Do not edit ' +
177
177
  'this file by hand — re-run `task build-linear-digest` to ' +
@@ -157,7 +157,7 @@ function render(): string {
157
157
  const resolvedNull = entries.filter((e) => e.status === 'resolved-null');
158
158
 
159
159
  const L: string[] = [];
160
- L.push('<!-- GENERATED by src/scripts/build_proof.ts — do NOT hand-edit.');
160
+ L.push('<!-- GENERATED by build_proof — do NOT hand-edit.');
161
161
  L.push(' Drift-checked in CI (`task build-proof-check`). Regenerate with');
162
162
  L.push(' `./scripts-run src/scripts/build_proof` after editing docs/CLAIMS.md. -->');
163
163
  L.push('');
@@ -449,11 +449,18 @@ function render(): string {
449
449
  `${nulls} resolved-null.`,
450
450
  );
451
451
  L.push('');
452
- L.push('| Claim id | Kind | Status | Evidence pointer |');
453
- L.push('|---|---|---|---|');
452
+ // `Measured on` exists because a status alone cannot say that a real
453
+ // measurement describes a build that no longer exists — and an AI
454
+ // council (2026-08-26, 2/2) required the binding to reach every index,
455
+ // not only the detailed entry, since a prose-only qualification drifts
456
+ // from the structured record it qualifies. Empty for every claim that
457
+ // describes the current tree, which is almost all of them.
458
+ L.push('| Claim id | Kind | Status | Measured on | Evidence pointer |');
459
+ L.push('|---|---|---|---|---|');
454
460
  for (const e of ledger) {
455
461
  const ev = e.evidence.length > 0 ? `\`${e.evidence.replace(/\|/g, '\\|')}\`` : '—';
456
- L.push(`| \`${e.id}\` | ${e.kind} | ${e.status} | ${ev} |`);
462
+ const on = e.measured_on.length > 0 ? e.measured_on.replace(/\|/g, '\\|') : '—';
463
+ L.push(`| \`${e.id}\` | ${e.kind} | ${e.status} | ${on} | ${ev} |`);
457
464
  }
458
465
  }
459
466
  L.push('');
@@ -340,7 +340,7 @@ function emit(): number {
340
340
  lines.push('');
341
341
  lines.push('**Source:** Phase 1 of `road-to-rule-hardening.md` (self-check audit) +');
342
342
  lines.push('Phase 1 of `road-to-context-layer-maturity.md` (`load_context:` inventory).');
343
- lines.push('**Generated by:** `src/scripts/build_rule_trigger_matrix.ts` — re-run after rule');
343
+ lines.push('**Generated by:** `build_rule_trigger_matrix` — re-run after rule');
344
344
  lines.push("set changes. Manual classifications live in the script's `CLASSIFICATION`");
345
345
  lines.push('table; size and context-chain columns are derived from the rule files.');
346
346
  lines.push('');
@@ -0,0 +1,157 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * build_source_digests — derive the tracked deny digests from the private
4
+ * master (`road-to-source-silence` Phase 1.1, resolution (c)).
5
+ *
6
+ * ## The shape the council chose
7
+ *
8
+ * Humans edit a readable list; the repository never sees it.
9
+ *
10
+ * src/scripts/external_sources_denylist.private.json ← gitignored MASTER
11
+ * │ { "deny": ["<readable pattern>", …] }
12
+ * ▼ build_source_digests (needs SOURCE_DENY_KEY)
13
+ * src/scripts/external_sources_denylist.json ← tracked, DERIVED
14
+ * { "deny_digests": ["<64 hex>", …] }
15
+ *
16
+ * "Plaintext in the tree" becomes structurally impossible rather than
17
+ * disciplined away: the tracked artefact is derivational, and the readable list
18
+ * exists in exactly one place, which is private.
19
+ *
20
+ * ## STATUS: this ships DORMANT and changes nothing by itself
21
+ *
22
+ * Running it is one quarter of the maintainer's atomic cutover. The other three
23
+ * quarters — provisioning the CI secret, deleting the tracked plaintext `deny`
24
+ * array, and switching CI to strict mode — are NOT in this change and must not
25
+ * be split from each other. `docs/maintainers/source-deny-digests.md` is the
26
+ * recipe. Until then `deny_digests` is empty, the plaintext gate stays in force,
27
+ * and the digest code path does nothing.
28
+ *
29
+ * Modes:
30
+ * (default) write digests into the tracked config from the private master
31
+ * --check verify the tracked digests match the master; exit 1 on drift
32
+ * --stdout print the digest array instead of writing (for inspection)
33
+ *
34
+ * Exit codes: 0 = done / in sync, 1 = drift (--check), 2 = usage or missing
35
+ * input, 3 = no key (`SOURCE_DENY_KEY` unset).
36
+ */
37
+
38
+ import * as fs from 'node:fs';
39
+ import * as path from 'node:path';
40
+ import process from 'node:process';
41
+ import { fileURLToPath, pathToFileURL } from 'node:url';
42
+
43
+ import { digest, DIGEST_RE, EXIT_NO_KEY, KEY_ENV, normalise } from './_lib/source_digest.js';
44
+
45
+ const _HERE = fileURLToPath(import.meta.url);
46
+ const DIR = path.dirname(_HERE);
47
+ export const TRACKED_CONFIG = path.join(DIR, 'external_sources_denylist.json');
48
+ export const PRIVATE_MASTER = path.join(DIR, 'external_sources_denylist.private.json');
49
+
50
+ interface Master {
51
+ deny: string[];
52
+ }
53
+
54
+ /**
55
+ * Digests for a master list, sorted and deduplicated.
56
+ *
57
+ * Sorted so the tracked artefact's diff shows an ADDITION as one line rather
58
+ * than a reshuffle, and so two maintainers with the same master produce the
59
+ * same file. Deduplicated because two spellings of one name fold to one digest
60
+ * — `normalise` is not injective and must not be assumed to be.
61
+ */
62
+ export function digestsFor(deny: readonly string[], key: string): string[] {
63
+ const out = new Set<string>();
64
+ for (const raw of deny) {
65
+ const bare = normalise(raw.replace(/\\b/g, ''));
66
+ if (bare.length < 3) continue;
67
+ out.add(digest(bare, key));
68
+ }
69
+ return [...out].sort();
70
+ }
71
+
72
+ function readMaster(): Master {
73
+ const raw = fs.readFileSync(PRIVATE_MASTER, 'utf-8');
74
+ const parsed = JSON.parse(raw) as Partial<Master>;
75
+ if (!Array.isArray(parsed.deny) || parsed.deny.length === 0) {
76
+ throw new Error('private master has no non-empty `deny` array');
77
+ }
78
+ return { deny: parsed.deny };
79
+ }
80
+
81
+ export function main(argv: readonly string[]): number {
82
+ const check = argv.includes('--check');
83
+ const toStdout = argv.includes('--stdout');
84
+
85
+ const key = process.env[KEY_ENV] ?? '';
86
+ if (key === '') {
87
+ process.stderr.write(
88
+ `❌ ${KEY_ENV} is unset. The digest construction is KEYED on purpose: the candidate\n` +
89
+ ' space is public repository slugs, so an unsalted hash of a slug is a lookup,\n' +
90
+ ' not a secret. Nothing is written without the key.\n',
91
+ );
92
+ return EXIT_NO_KEY;
93
+ }
94
+
95
+ let master: Master;
96
+ try {
97
+ master = readMaster();
98
+ } catch (exc) {
99
+ process.stderr.write(
100
+ `❌ cannot read the private master at ${path.basename(PRIVATE_MASTER)}: ` +
101
+ `${(exc as Error).message}\n` +
102
+ ' It is gitignored by design and must be created by the maintainer — see\n' +
103
+ ' docs/maintainers/source-deny-digests.md.\n',
104
+ );
105
+ return 2;
106
+ }
107
+
108
+ const digests = digestsFor(master.deny, key);
109
+ if (!digests.every((d) => DIGEST_RE.test(d))) {
110
+ process.stderr.write('❌ internal error: a produced digest is not 64 lowercase hex chars\n');
111
+ return 2;
112
+ }
113
+
114
+ if (toStdout) {
115
+ process.stdout.write(JSON.stringify(digests, null, 2) + '\n');
116
+ return 0;
117
+ }
118
+
119
+ const cfg = JSON.parse(fs.readFileSync(TRACKED_CONFIG, 'utf-8')) as Record<string, unknown>;
120
+ const current = Array.isArray(cfg.deny_digests) ? (cfg.deny_digests as string[]) : [];
121
+
122
+ if (check) {
123
+ const same = current.length === digests.length && current.every((d, i) => d === digests[i]);
124
+ if (same) {
125
+ process.stdout.write(`✅ ${String(digests.length)} deny digest(s) in sync with the private master.\n`);
126
+ return 0;
127
+ }
128
+ process.stderr.write(
129
+ `❌ deny_digests drift: tracked ${String(current.length)}, derived ${String(digests.length)}.\n` +
130
+ ' Re-run without --check to regenerate.\n',
131
+ );
132
+ return 1;
133
+ }
134
+
135
+ cfg.deny_digests = digests;
136
+ fs.writeFileSync(TRACKED_CONFIG, JSON.stringify(cfg, null, 2) + '\n', 'utf-8');
137
+ process.stdout.write(`✅ wrote ${String(digests.length)} deny digest(s) to ${path.basename(TRACKED_CONFIG)}.\n`);
138
+ process.stdout.write(
139
+ ' This is ONE QUARTER of the cutover. The CI secret, the deletion of the plaintext\n' +
140
+ ' deny array and the switch to strict mode ship in the SAME change or not at all.\n',
141
+ );
142
+ return 0;
143
+ }
144
+
145
+ function _isCliEntry(): boolean {
146
+ if (process.argv[1] === undefined) return false;
147
+ if (import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href) return true;
148
+ try {
149
+ return fs.realpathSync(fileURLToPath(import.meta.url)) === fs.realpathSync(path.resolve(process.argv[1]));
150
+ } catch {
151
+ return false;
152
+ }
153
+ }
154
+
155
+ if (_isCliEntry()) {
156
+ process.exit(main(process.argv.slice(2)));
157
+ }
@@ -36,6 +36,8 @@ import { homedir } from 'node:os';
36
36
  import * as path from 'node:path';
37
37
  import { fileURLToPath, pathToFileURL } from 'node:url';
38
38
 
39
+ import { buildReport as buildDriftReport } from './orchestration_payload_hash_drift.js';
40
+ import type { PayloadHashDriftReport } from './_lib/payload_hash_drift.js';
39
41
  import {
40
42
  aggregateByBucket,
41
43
  billableInputTokens,
@@ -635,6 +637,7 @@ export interface Options {
635
637
  councilRoot: string;
636
638
  userRulesDir: string;
637
639
  projectRulesDir: string;
640
+ auditDir: string;
638
641
  }
639
642
 
640
643
  function defaultOptions(): Options {
@@ -646,6 +649,7 @@ function defaultOptions(): Options {
646
649
  councilRoot: REPO_ROOT,
647
650
  userRulesDir: path.join(homedir(), '.claude', 'rules'),
648
651
  projectRulesDir: path.join(REPO_ROOT, 'dist', 'agent-src', 'rules'),
652
+ auditDir: path.join(REPO_ROOT, 'agents', 'runtime', 'state', 'audit'),
649
653
  };
650
654
  }
651
655
 
@@ -668,11 +672,82 @@ export function parseArgs(argv: string[]): Options {
668
672
  else if (a.startsWith('--user-rules-dir=')) opts.userRulesDir = a.slice('--user-rules-dir='.length);
669
673
  else if (a === '--project-rules-dir') opts.projectRulesDir = argv[++i] ?? opts.projectRulesDir;
670
674
  else if (a.startsWith('--project-rules-dir=')) opts.projectRulesDir = a.slice('--project-rules-dir='.length);
675
+ else if (a === '--audit-dir') opts.auditDir = argv[++i] ?? opts.auditDir;
676
+ else if (a.startsWith('--audit-dir=')) opts.auditDir = a.slice('--audit-dir='.length);
671
677
  }
672
678
  if (opts.format !== 'text' && opts.format !== 'json') opts.format = 'text';
673
679
  return opts;
674
680
  }
675
681
 
682
+ /**
683
+ * Prefix-stability verdict, carried in the cost report rather than left latent
684
+ * in a separate CLI (`road-to-runtime-context-floors` step 1.3).
685
+ *
686
+ * `_lib/payload_hash_drift` already splits dispatches into a STABLE cohort
687
+ * (repeat occurrences of one payload hash) and an UNSTABLE one (hashes seen
688
+ * once). Nothing read the split, so the one outcome that matters — a stable
689
+ * cohort whose cache-read share is BELOW its unstable cohort, which means the
690
+ * prefix is being rewritten between repeats — was measurable and unreported.
691
+ *
692
+ * `verdict` is deliberately three-valued. `insufficient-data` is not a number
693
+ * and must never be rendered as one: with either cohort empty there is no
694
+ * comparison to make, and printing `0.0%` for "nothing was measured" is the
695
+ * shape that turns a blind report into a believed one.
696
+ */
697
+ export type PrefixStabilityVerdict = 'stable-higher' | 'inverted' | 'insufficient-data';
698
+
699
+ export interface PrefixStabilityResult {
700
+ verdict: PrefixStabilityVerdict;
701
+ /** Why, in one sentence — always populated, including for `insufficient-data`. */
702
+ reason: string;
703
+ stable_cohort: { n: number; read_share: number | null };
704
+ unstable_cohort: { n: number; read_share: number | null };
705
+ lines_with_data: number;
706
+ }
707
+
708
+ export function computePrefixStability(drift: PayloadHashDriftReport): PrefixStabilityResult {
709
+ const stable = { n: drift.stable_cohort.n, read_share: drift.stable_cohort.hit_rate };
710
+ const unstable = { n: drift.unstable_cohort.n, read_share: drift.unstable_cohort.hit_rate };
711
+
712
+ if (stable.read_share === null || unstable.read_share === null) {
713
+ const empty = [stable.read_share === null ? 'stable' : null, unstable.read_share === null ? 'unstable' : null]
714
+ .filter((x) => x !== null)
715
+ .join(' and ');
716
+ const plural = empty.includes(' and ') ? 'cohorts are' : 'cohort is';
717
+ return {
718
+ verdict: 'insufficient-data',
719
+ reason:
720
+ `the ${empty} ${plural} empty (${drift.lines_with_data} audit line(s) carry both ` +
721
+ 'payload_hash and cache_hit) — no comparison exists, and a share is not reported for one',
722
+ stable_cohort: stable,
723
+ unstable_cohort: unstable,
724
+ lines_with_data: drift.lines_with_data,
725
+ };
726
+ }
727
+ if (stable.read_share < unstable.read_share) {
728
+ return {
729
+ verdict: 'inverted',
730
+ reason:
731
+ `repeat dispatches of the same payload shape hit the cache LESS often ` +
732
+ `(${(stable.read_share * 100).toFixed(1)}%) than one-off shapes ` +
733
+ `(${(unstable.read_share * 100).toFixed(1)}%) — a prefix-stable surface is being ` +
734
+ 'rewritten between repeats',
735
+ stable_cohort: stable,
736
+ unstable_cohort: unstable,
737
+ lines_with_data: drift.lines_with_data,
738
+ };
739
+ }
740
+ return {
741
+ verdict: 'stable-higher',
742
+ reason:
743
+ `repeat dispatches hit the cache at ${(stable.read_share * 100).toFixed(1)}% against ` +
744
+ `${(unstable.read_share * 100).toFixed(1)}% for one-off shapes, which is the expected ordering`,
745
+ stable_cohort: stable,
746
+ unstable_cohort: unstable,
747
+ lines_with_data: drift.lines_with_data,
748
+ };
749
+ }
750
+
676
751
  export interface Report {
677
752
  schema: 'cache-realization-report/v1';
678
753
  host_version: string;
@@ -688,6 +763,7 @@ export interface Report {
688
763
  duplicate_scope: DuplicateScopeResult;
689
764
  council_mispricing: CouncilMispricingResult;
690
765
  worktree_fragmentation: WorktreeFragmentationResult;
766
+ prefix_stability: PrefixStabilityResult;
691
767
  claims: Claim[];
692
768
  }
693
769
 
@@ -709,6 +785,22 @@ export function buildReport(opts: Options): Report {
709
785
  const worktreePaths = listGitWorktrees(opts.repoRoot);
710
786
  const worktreeFragmentation = computeWorktreeFragmentation(opts.root, worktreePaths, opts.maxAgeDays);
711
787
 
788
+ // A missing or unreadable audit directory is a real, expected state — the
789
+ // two fields are lean-init extensions and no caller wires them yet — so it
790
+ // resolves to `insufficient-data` with a reason, never to a fabricated share.
791
+ let prefixStability: PrefixStabilityResult;
792
+ try {
793
+ prefixStability = computePrefixStability(buildDriftReport(opts.auditDir));
794
+ } catch (err) {
795
+ prefixStability = {
796
+ verdict: 'insufficient-data',
797
+ reason: `the audit ledger at ${opts.auditDir} could not be read: ${(err as Error).message}`,
798
+ stable_cohort: { n: 0, read_share: null },
799
+ unstable_cohort: { n: 0, read_share: null },
800
+ lines_with_data: 0,
801
+ };
802
+ }
803
+
712
804
  const claims = buildClaims({ subagentColdStart, duplicateScope, councilMispricing, worktreeFragmentation });
713
805
 
714
806
  return {
@@ -729,6 +821,7 @@ export function buildReport(opts: Options): Report {
729
821
  duplicate_scope: duplicateScope,
730
822
  council_mispricing: councilMispricing,
731
823
  worktree_fragmentation: worktreeFragmentation,
824
+ prefix_stability: prefixStability,
732
825
  claims,
733
826
  };
734
827
  }
@@ -748,6 +841,16 @@ export function renderText(r: Report): string {
748
841
  out.push(` dedup: ${r.deduped_count}/${r.total_seen} unique records kept (dedup_ratio ${pct(r.dedup_ratio)})`);
749
842
  out.push('');
750
843
 
844
+ const ps = r.prefix_stability;
845
+ const share = (v: number | null): string => (v === null ? 'insufficient data' : pct(v));
846
+ const mark = ps.verdict === 'inverted' ? '⚠️ ' : '';
847
+ out.push('Prefix stability (payload_hash × cache_hit):');
848
+ out.push(` ${mark}verdict: ${ps.verdict}`);
849
+ out.push(` stable cohort: n=${ps.stable_cohort.n} read_share=${share(ps.stable_cohort.read_share)}`);
850
+ out.push(` unstable cohort: n=${ps.unstable_cohort.n} read_share=${share(ps.unstable_cohort.read_share)}`);
851
+ out.push(` ${ps.reason}`);
852
+ out.push('');
853
+
751
854
  out.push('By bucket:');
752
855
  for (const bucket of ['main', 'subagent'] as const) {
753
856
  const b = r.buckets[bucket];