@event4u/agent-config 14.12.0 → 14.13.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 (466) 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 +234 -0
  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 +109 -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-provenance.md +4 -0
  30. package/dist/agent-src/rules/design-fidelity.md +1 -1
  31. package/dist/agent-src/rules/domain-safety-pii.md +4 -0
  32. package/dist/agent-src/rules/domain-safety-retention.md +4 -0
  33. package/dist/agent-src/rules/engineering-safety-floor.md +2 -0
  34. package/dist/agent-src/rules/external-code-graph-interop.md +14 -12
  35. package/dist/agent-src/rules/improve-before-implement.md +6 -8
  36. package/dist/agent-src/rules/laravel-routing.md +1 -1
  37. package/dist/agent-src/rules/lethal-trifecta-guard.md +4 -0
  38. package/dist/agent-src/rules/secret-vcs-guard.md +2 -0
  39. package/dist/agent-src/rules/security-sensitive-stop.md +2 -0
  40. package/dist/agent-src/rules/source-confidentiality.md +12 -34
  41. package/dist/agent-src/rules/symfony-routing.md +1 -1
  42. package/dist/agent-src/rules/token-efficiency.md +14 -0
  43. package/dist/agent-src/rules/tool-safety.md +4 -0
  44. package/dist/agent-src/rules/untrusted-input-defense.md +4 -0
  45. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +247 -3
  46. package/dist/agent-src/scripts/guarded_baseline.ts +328 -0
  47. package/dist/agent-src/scripts/roadmap_set_step.ts +253 -0
  48. package/dist/agent-src/scripts/stub_queue.ts +82 -0
  49. package/dist/agent-src/scripts/stubs_due.ts +400 -0
  50. package/dist/agent-src/scripts/ticket_bundles.ts +84 -0
  51. package/dist/agent-src/scripts/update_roadmap_progress.ts +8 -4
  52. package/dist/agent-src/skills/brand-asset-generation/SKILL.md +17 -4
  53. package/dist/agent-src/skills/brand-audit/SKILL.md +33 -0
  54. package/dist/agent-src/skills/code-intelligence/SKILL.md +57 -0
  55. package/dist/agent-src/skills/database/SKILL.md +8 -0
  56. package/dist/agent-src/skills/dependency-upgrade/SKILL.md +27 -0
  57. package/dist/agent-src/skills/design-review/SKILL.md +1 -1
  58. package/dist/agent-src/skills/doc-coauthoring/SKILL.md +1 -1
  59. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +17 -1
  60. package/dist/agent-src/skills/feature-planning/SKILL.md +9 -2
  61. package/dist/agent-src/skills/frontend-render-security/SKILL.md +44 -0
  62. package/dist/agent-src/skills/git-workflow/SKILL.md +1 -1
  63. package/dist/agent-src/skills/js-library-packaging/scripts/check_package_surface.ts +38 -4
  64. package/dist/agent-src/skills/judge-artifact-completeness/rubrics/ticket-quality-score.json +2 -2
  65. package/dist/agent-src/skills/laravel/SKILL.md +35 -0
  66. package/dist/agent-src/skills/laravel-migration/SKILL.md +57 -3
  67. package/dist/agent-src/skills/monorepo-workspace/SKILL.md +26 -0
  68. package/dist/agent-src/skills/playbook-authoring/SKILL.md +28 -1
  69. package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +1 -1
  70. package/dist/agent-src/skills/skill-writing/references/procedure.md +5 -5
  71. package/dist/agent-src/skills/sql-writing/SKILL.md +7 -1
  72. package/dist/agent-src/skills/standards-from-config/SKILL.md +27 -4
  73. package/dist/agent-src/skills/supply-chain-intake/SKILL.md +11 -4
  74. package/dist/agent-src/skills/symfony-workflow/SKILL.md +35 -0
  75. package/dist/agent-src/skills/test-case-discovery/SKILL.md +85 -0
  76. package/dist/agent-src/skills/test-driven-development/SKILL.md +33 -9
  77. package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
  78. package/dist/agent-src/skills/testing-anti-patterns/process-anti-patterns.md +37 -0
  79. package/dist/agent-src/skills/ui-component-architect/SKILL.md +45 -2
  80. package/dist/agent-src/skills/upstream-contribute/SKILL.md +38 -1
  81. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +9 -4
  82. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  83. package/dist/agent-src/templates/roadmaps.md +97 -3
  84. package/dist/agent-src/templates/scripts/check_memory.ts +258 -17
  85. package/dist/agent-src/templates/scripts/check_memory_proposal.ts +9 -3
  86. package/dist/agent-src/templates/scripts/memory_lookup.ts +86 -0
  87. package/dist/agent-src/templates/scripts/memory_signal.ts +44 -0
  88. package/dist/agent-src/templates/scripts/work_engine/directives/backend/implement.ts +90 -0
  89. package/dist/agent-src/templates/scripts/work_engine/directives/backend/index.ts +11 -0
  90. package/dist/agent-src/templates/scripts/work_engine/directives/backend/test.ts +23 -1
  91. package/dist/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +10 -1
  92. package/dist/agent-src/templates/scripts/work_engine/directives/mixed/stitch.ts +5 -1
  93. package/dist/agent-src/templates/scripts/work_engine/stack/runner.ts +102 -14
  94. package/dist/cli/commands/uiAudit.js +124 -5
  95. package/dist/cli/registry.js +2 -0
  96. package/dist/cli-delegate/{chunk-HYWSRNUX.js → chunk-2DK2VJWG.js} +3 -3
  97. package/dist/cli-delegate/{chunk-JCW7ZLHK.js → chunk-4FS4WRXP.js} +5 -0
  98. package/dist/cli-delegate/{chunk-OMIVVCG2.js → chunk-A4QJ6ENT.js} +24 -0
  99. package/dist/cli-delegate/{chunk-JJA2QEWA.js → chunk-AKJGUQNO.js} +466 -285
  100. package/dist/cli-delegate/{chunk-E46KPN6K.js → chunk-BTWUYDGN.js} +424 -363
  101. package/dist/cli-delegate/{chunk-K4FFODTS.js → chunk-ILMUPLGW.js} +1227 -316
  102. package/dist/cli-delegate/{chunk-FF7WAFMR.js → chunk-KPBWFOPZ.js} +5 -1
  103. package/dist/cli-delegate/cmd_adr_effective.js +102 -0
  104. package/dist/cli-delegate/cmd_conformance.js +42 -10
  105. package/dist/cli-delegate/cmd_doctor.js +3 -3
  106. package/dist/cli-delegate/cmd_export.js +3 -2
  107. package/dist/cli-delegate/cmd_fleet.js +2 -2
  108. package/dist/cli-delegate/cmd_handoff.js +1 -1
  109. package/dist/cli-delegate/cmd_preflight.js +2 -2
  110. package/dist/cli-delegate/cmd_prune.js +3 -2
  111. package/dist/cli-delegate/cmd_settings_get.js +1 -1
  112. package/dist/cli-delegate/cmd_settings_migrate.js +3 -2
  113. package/dist/cli-delegate/cmd_settings_set.js +2 -2
  114. package/dist/cli-delegate/cmd_sync.js +3 -2
  115. package/dist/cli-delegate/cmd_uninstall.js +3 -2
  116. package/dist/cli-delegate/cmd_validate.js +3 -2
  117. package/dist/discovery/deprecation-report.md +1 -1
  118. package/dist/discovery/discovery-manifest.json +57 -57
  119. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  120. package/dist/discovery/discovery-manifest.summary.md +1 -1
  121. package/dist/discovery/dormancy-report.md +1 -1
  122. package/dist/discovery/orphan-report.md +1 -1
  123. package/dist/discovery/packs.json +2 -2
  124. package/dist/discovery/trust-report.md +1 -1
  125. package/dist/discovery/workspaces.json +2 -2
  126. package/dist/hooks/dispatch.js +1836 -712
  127. package/dist/install/claudeRuleRewrite.js +254 -0
  128. package/dist/install/detect.js +29 -16
  129. package/dist/install/detect_php_shape.js +159 -0
  130. package/dist/install/install.mjs +634 -428
  131. package/dist/mcp/awesome-mcp-servers.row.md +1 -1
  132. package/dist/mcp/mcp-cloudflare-catalogue.json +1 -1
  133. package/dist/mcp/registry-manifest.json +3 -3
  134. package/dist/mcp/server.json +3 -3
  135. package/dist/mcp/server.mjs +4818 -2645
  136. package/dist/server/schemas/settings.js +3 -0
  137. package/dist/ui/assets/index-D0jaCRPM.js +29 -0
  138. package/dist/ui/index.html +1 -1
  139. package/docs/MIGRATION.md +1 -1
  140. package/docs/THIRD-PARTY-NOTICES.md +25 -0
  141. package/docs/contracts/provider-lifecycle.md +1 -1
  142. package/docs/contracts/settings-classes.md +10 -4
  143. package/docs/guidelines/agent-infra/5w2h-analysis.md +3 -3
  144. package/docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md +1 -0
  145. package/docs/guidelines/agent-infra/artifact-drafting-protocol-mechanics.md +58 -3
  146. package/docs/guidelines/agent-infra/ask-when-uncertain-demos.md +2 -2
  147. package/docs/guidelines/agent-infra/asking-and-brevity-examples.md +3 -3
  148. package/docs/guidelines/agent-infra/break-glass-usage.md +7 -7
  149. package/docs/guidelines/agent-infra/carve-out-predicates.md +3 -3
  150. package/docs/guidelines/agent-infra/comparison-matrix.md +1 -1
  151. package/docs/guidelines/agent-infra/critical-thinking.md +4 -4
  152. package/docs/guidelines/agent-infra/direct-answers-demos.md +2 -2
  153. package/docs/guidelines/agent-infra/domain-eval-anti-pattern.md +1 -1
  154. package/docs/guidelines/agent-infra/engineering-memory-data-format.md +3 -3
  155. package/docs/guidelines/agent-infra/existence-question-verdicts.md +80 -0
  156. package/docs/guidelines/agent-infra/first-principles.md +2 -2
  157. package/docs/guidelines/agent-infra/framework-neutrality-patterns.md +2 -2
  158. package/docs/guidelines/agent-infra/guarded-baseline.md +39 -0
  159. package/docs/guidelines/agent-infra/inversion-thinking.md +5 -5
  160. package/docs/guidelines/agent-infra/language-and-tone-examples.md +1 -1
  161. package/docs/guidelines/agent-infra/layered-settings.md +10 -10
  162. package/docs/guidelines/agent-infra/memory-access.md +1 -1
  163. package/docs/guidelines/agent-infra/mental-models.md +3 -3
  164. package/docs/guidelines/agent-infra/reuse-verdict-mechanics.md +71 -0
  165. package/docs/guidelines/agent-infra/review-routing-data-format.md +7 -7
  166. package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +13 -7
  167. package/docs/guidelines/agent-infra/role-contracts.md +2 -2
  168. package/docs/guidelines/agent-infra/role-mode-router.md +3 -3
  169. package/docs/guidelines/agent-infra/rule-type-governance.md +2 -2
  170. package/docs/guidelines/agent-infra/scqa-framework.md +5 -5
  171. package/docs/guidelines/agent-infra/self-improvement-pipeline.md +6 -6
  172. package/docs/guidelines/agent-infra/simplicity-and-goal-demos.md +2 -2
  173. package/docs/guidelines/agent-infra/six-hats.md +3 -3
  174. package/docs/guidelines/agent-infra/skill-quality-checklist.md +6 -6
  175. package/docs/guidelines/agent-infra/source-confidentiality-mechanics.md +109 -0
  176. package/docs/guidelines/agent-infra/systems-thinking.md +1 -1
  177. package/docs/guidelines/agent-infra/verify-before-complete-demos.md +2 -2
  178. package/docs/guidelines/augment-portability-patterns.md +6 -4
  179. package/docs/guidelines/component-oriented-and-oop-development.md +3 -2
  180. package/docs/guidelines/cross-role-handoff.md +2 -2
  181. package/docs/guidelines/design-fidelity-mechanics.md +1 -1
  182. package/docs/guidelines/docs/readme-size-and-splitting.md +3 -3
  183. package/docs/guidelines/php/database.md +90 -7
  184. package/docs/guidelines/prompt-templates.md +7 -7
  185. package/llms.txt +2 -2
  186. package/package.json +5 -2
  187. package/src/agent-src/scripts/archive_completed_roadmaps.ts +247 -3
  188. package/src/agent-src/scripts/guarded_baseline.ts +328 -0
  189. package/src/agent-src/scripts/roadmap_set_step.ts +253 -0
  190. package/src/agent-src/scripts/stub_queue.ts +82 -0
  191. package/src/agent-src/scripts/stubs_due.ts +400 -0
  192. package/src/agent-src/scripts/ticket_bundles.ts +84 -0
  193. package/src/agent-src/scripts/update_roadmap_progress.ts +8 -4
  194. package/src/agent-src/templates/scripts/check_memory.ts +258 -17
  195. package/src/agent-src/templates/scripts/check_memory_proposal.ts +9 -3
  196. package/src/agent-src/templates/scripts/memory_lookup.ts +86 -0
  197. package/src/agent-src/templates/scripts/memory_signal.ts +44 -0
  198. package/src/agent-src/templates/scripts/work_engine/directives/backend/implement.ts +90 -0
  199. package/src/agent-src/templates/scripts/work_engine/directives/backend/index.ts +11 -0
  200. package/src/agent-src/templates/scripts/work_engine/directives/backend/test.ts +23 -1
  201. package/src/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +10 -1
  202. package/src/agent-src/templates/scripts/work_engine/directives/mixed/stitch.ts +5 -1
  203. package/src/agent-src/templates/scripts/work_engine/stack/runner.ts +102 -14
  204. package/src/config/agent-settings.template.yml +32 -3
  205. package/src/config/assurance-capability-registry.json +21 -9
  206. package/src/config/canonical-terms.yml +119 -0
  207. package/src/config/capability-native-outcome-bars.json +81 -0
  208. package/src/config/ci-local-parity.yml +80 -0
  209. package/src/config/drafting-channels.yml +43 -0
  210. package/src/config/estate-count-budget.json +38 -36
  211. package/src/config/evaluator-budgets.json +14 -14
  212. package/src/config/gate-coverage.yml +579 -63
  213. package/src/config/gate-reachability-exemptions.json +21 -0
  214. package/src/config/gate-violation-baselines.json +37 -19
  215. package/src/config/harness-evolution-budget.json +25 -0
  216. package/src/config/lapsed-beta-baseline.json +96 -0
  217. package/src/config/memory-twin-verdicts.yml +129 -0
  218. package/src/config/metric-registry.yml +124 -0
  219. package/src/config/pack-size-budget.json +16 -15
  220. package/src/config/preamble-payload-budget.json +8 -8
  221. package/src/config/profiles/balanced.ini +27 -0
  222. package/src/config/profiles/full.ini +27 -0
  223. package/src/config/profiles/minimal.ini +27 -0
  224. package/src/config/publish-surface.json +9 -2
  225. package/src/config/routing-coverage-seed.json +16 -2
  226. package/src/config/rule-stub-ceilings.json +126 -112
  227. package/src/config/turnaround-budget.json +66 -0
  228. package/src/install/claudeRuleRewrite.ts +288 -0
  229. package/src/install/detect.ts +60 -17
  230. package/src/install/detect_php_shape.ts +191 -0
  231. package/src/scripts/_cli/cmd_doctor.ts +27 -112
  232. package/src/scripts/_dispatch.bash +27 -0
  233. package/src/scripts/_lib/activation_ladder.ts +211 -0
  234. package/src/scripts/_lib/activation_states.ts +88 -0
  235. package/src/scripts/_lib/adherence_detectors.ts +143 -0
  236. package/src/scripts/_lib/arith_claims.ts +181 -0
  237. package/src/scripts/_lib/arm_ranking.ts +62 -0
  238. package/src/scripts/_lib/asset_delivery_ledger.ts +303 -0
  239. package/src/scripts/_lib/audit_field_provenance.ts +54 -0
  240. package/src/scripts/_lib/auto_dispatch.ts +32 -3
  241. package/src/scripts/_lib/bench_ab_size_claim.ts +98 -4
  242. package/src/scripts/_lib/benchmark_cache_fields.ts +158 -0
  243. package/src/scripts/_lib/candidate_proposer.ts +402 -0
  244. package/src/scripts/_lib/candidate_record.ts +601 -0
  245. package/src/scripts/_lib/capture_rate.ts +319 -0
  246. package/src/scripts/_lib/collector_denominator.ts +771 -0
  247. package/src/scripts/_lib/collector_record.ts +340 -0
  248. package/src/scripts/_lib/collector_store.ts +664 -0
  249. package/src/scripts/_lib/collector_supervision.ts +827 -0
  250. package/src/scripts/_lib/concern_estate.ts +77 -0
  251. package/src/scripts/_lib/config_chain.ts +477 -0
  252. package/src/scripts/_lib/config_cost.ts +209 -0
  253. package/src/scripts/_lib/council_settings_block.ts +6 -0
  254. package/src/scripts/_lib/curator_ops.ts +172 -0
  255. package/src/scripts/_lib/delivery_arm_experiment.ts +266 -0
  256. package/src/scripts/_lib/delivery_criticality.ts +126 -0
  257. package/src/scripts/_lib/doctor_runtime_checks.ts +70 -0
  258. package/src/scripts/_lib/empty_cycles.ts +88 -0
  259. package/src/scripts/_lib/eval_publication.ts +354 -0
  260. package/src/scripts/_lib/evaluation_vector.ts +283 -0
  261. package/src/scripts/_lib/evaluator_promotion.ts +225 -0
  262. package/src/scripts/_lib/evidence_basis.ts +118 -0
  263. package/src/scripts/_lib/exec_evidence.ts +8 -0
  264. package/src/scripts/_lib/experience_card.ts +272 -0
  265. package/src/scripts/_lib/experience_report.ts +151 -0
  266. package/src/scripts/_lib/experiment_freeze.ts +112 -0
  267. package/src/scripts/_lib/generated_by.ts +66 -0
  268. package/src/scripts/_lib/harness_evolution_guards.ts +229 -0
  269. package/src/scripts/_lib/hook_effect_probe.ts +141 -0
  270. package/src/scripts/_lib/host_denominator.ts +687 -0
  271. package/src/scripts/_lib/host_projection_reach.ts +157 -0
  272. package/src/scripts/_lib/ignored_blocker.ts +148 -0
  273. package/src/scripts/_lib/install_reach_checks.ts +495 -0
  274. package/src/scripts/_lib/json_duplicate_keys.ts +150 -0
  275. package/src/scripts/_lib/judge_hygiene.ts +228 -0
  276. package/src/scripts/_lib/legacy_boundary_map.ts +228 -0
  277. package/src/scripts/_lib/loop_guards.ts +299 -0
  278. package/src/scripts/_lib/loss_class.ts +129 -0
  279. package/src/scripts/_lib/machine_wake.ts +51 -0
  280. package/src/scripts/_lib/md_prose_lines.ts +177 -0
  281. package/src/scripts/_lib/minimality_tiebreak.ts +168 -0
  282. package/src/scripts/_lib/one_resolver_invariant.ts +449 -0
  283. package/src/scripts/_lib/orchestration_record.ts +253 -5
  284. package/src/scripts/_lib/outcome_envelope.ts +227 -0
  285. package/src/scripts/_lib/outcome_vocabularies.ts +125 -0
  286. package/src/scripts/_lib/paired_stats.ts +245 -0
  287. package/src/scripts/_lib/paired_verdict.ts +226 -0
  288. package/src/scripts/_lib/prefix_stable_surfaces.ts +123 -0
  289. package/src/scripts/_lib/privacy_class.ts +47 -0
  290. package/src/scripts/_lib/regression_neighbourhood.ts +259 -0
  291. package/src/scripts/_lib/repeated_failure.ts +105 -0
  292. package/src/scripts/_lib/repo_root.ts +111 -0
  293. package/src/scripts/_lib/review_skipped_record.ts +37 -0
  294. package/src/scripts/_lib/role_split.ts +338 -0
  295. package/src/scripts/_lib/runtime_journal.ts +1499 -0
  296. package/src/scripts/_lib/runtime_wiring_checks.ts +430 -0
  297. package/src/scripts/_lib/skill_catalogue.ts +11 -1
  298. package/src/scripts/_lib/source_digest.ts +200 -0
  299. package/src/scripts/_lib/source_redact.ts +260 -0
  300. package/src/scripts/_lib/source_shape.ts +502 -0
  301. package/src/scripts/_lib/source_snapshot_dedup.ts +199 -0
  302. package/src/scripts/_lib/strip_comments.d.mts +8 -0
  303. package/src/scripts/_lib/strip_comments.mjs +65 -0
  304. package/src/scripts/_lib/test_red_state.ts +154 -0
  305. package/src/scripts/_lib/trigger_shift.ts +144 -0
  306. package/src/scripts/_lib/untrusted_content.ts +82 -7
  307. package/src/scripts/adoption_report.ts +1 -1
  308. package/src/scripts/adr/evidence_census.ts +1 -1
  309. package/src/scripts/adr/regenerate_index.ts +26 -2
  310. package/src/scripts/adr_cite_check.ts +164 -1
  311. package/src/scripts/ai_council/blind_review.ts +11 -1
  312. package/src/scripts/ai_council/clients.ts +4 -0
  313. package/src/scripts/ai_council/config.ts +3 -0
  314. package/src/scripts/ai_council/consensus.ts +28 -8
  315. package/src/scripts/ai_council/consensus_round.ts +226 -0
  316. package/src/scripts/ai_council/disagreement_signal.ts +338 -0
  317. package/src/scripts/ai_council/inline_findings.ts +340 -0
  318. package/src/scripts/ai_council/judge_position_bias.ts +197 -0
  319. package/src/scripts/ai_council/orchestrator.ts +16 -203
  320. package/src/scripts/ai_council/orchestrator_results.ts +23 -3
  321. package/src/scripts/ai_council/pricing.ts +106 -0
  322. package/src/scripts/ai_council/prompts.ts +74 -7
  323. package/src/scripts/ai_council/provider_leakage_bench.ts +327 -0
  324. package/src/scripts/ai_council/py_format.ts +14 -3
  325. package/src/scripts/ai_council/recouncil_guard.ts +293 -0
  326. package/src/scripts/ai_council/response_record.ts +50 -0
  327. package/src/scripts/ai_council/topology_bench_manifest.ts +860 -0
  328. package/src/scripts/ai_council/topology_vocabulary.ts +175 -0
  329. package/src/scripts/asset_delivery_ledger.ts +157 -0
  330. package/src/scripts/attest_artifact.ts +193 -0
  331. package/src/scripts/audit_auto_rules.ts +2 -1
  332. package/src/scripts/audit_command_surface.ts +1 -1
  333. package/src/scripts/audit_mcp_tools.ts +2 -2
  334. package/src/scripts/audit_skill_overlap_allowlist.json +6 -1
  335. package/src/scripts/audit_user_type_axis.ts +2 -1
  336. package/src/scripts/bench_ab_clone.ts +215 -10
  337. package/src/scripts/bench_ab_integrity.ts +119 -5
  338. package/src/scripts/bench_ab_v2_stats.ts +40 -213
  339. package/src/scripts/build_archive_index.ts +1 -1
  340. package/src/scripts/build_linear_digest.ts +1 -1
  341. package/src/scripts/build_proof.ts +11 -4
  342. package/src/scripts/build_rule_trigger_matrix.ts +1 -1
  343. package/src/scripts/build_source_digests.ts +157 -0
  344. package/src/scripts/cache_realization_report.ts +103 -0
  345. package/src/scripts/check_adr_frontmatter.ts +126 -0
  346. package/src/scripts/check_benchmark_report_fields.ts +207 -0
  347. package/src/scripts/check_beta_review_markers.ts +235 -6
  348. package/src/scripts/check_bundle_path_leakage.ts +34 -1
  349. package/src/scripts/check_claims.ts +576 -6
  350. package/src/scripts/check_composite_arming.ts +35 -0
  351. package/src/scripts/check_concern_admissions.ts +365 -0
  352. package/src/scripts/check_enforcement_coverage.ts +28 -0
  353. package/src/scripts/check_estate_count.ts +142 -1
  354. package/src/scripts/check_gate_reachability.ts +383 -0
  355. package/src/scripts/check_host_loadability.ts +104 -0
  356. package/src/scripts/check_loss_class_declared.ts +308 -0
  357. package/src/scripts/check_md_language.ts +15 -98
  358. package/src/scripts/check_memory_proposal.ts +18 -11
  359. package/src/scripts/check_no_currency_in_cost_surfaces.ts +225 -0
  360. package/src/scripts/check_no_external_sources.ts +281 -6
  361. package/src/scripts/check_pack_conformance_fixture.ts +11 -1
  362. package/src/scripts/check_pack_size.ts +59 -2
  363. package/src/scripts/check_preamble_payload_budget.ts +114 -3
  364. package/src/scripts/check_prefix_stable_mutation.ts +372 -0
  365. package/src/scripts/check_publish_surface.ts +10 -1
  366. package/src/scripts/check_references.ts +24 -1
  367. package/src/scripts/check_rule_evidence_declaration.ts +316 -0
  368. package/src/scripts/check_rule_projection_integrity.ts +14 -4
  369. package/src/scripts/check_score_contract.ts +26 -3
  370. package/src/scripts/check_static_parity.ts +285 -0
  371. package/src/scripts/check_supervision_claim_atomicity.ts +498 -0
  372. package/src/scripts/check_suppression_hygiene.ts +15 -0
  373. package/src/scripts/ci_settle.ts +39 -2
  374. package/src/scripts/code_graph/build.ts +60 -3
  375. package/src/scripts/code_graph/extract.ts +44 -0
  376. package/src/scripts/code_graph/types.ts +24 -0
  377. package/src/scripts/collector_daemon.ts +714 -0
  378. package/src/scripts/config_cost_report.ts +302 -0
  379. package/src/scripts/consumer_matrix.ts +74 -1
  380. package/src/scripts/cost/budget.mjs +10 -3
  381. package/src/scripts/cost/track.mjs +10 -3
  382. package/src/scripts/council_cli.ts +37 -54
  383. package/src/scripts/dispatch_r2_reviewer.ts +46 -5
  384. package/src/scripts/evolution_lab.ts +980 -0
  385. package/src/scripts/external_sources_denylist.json +5 -18
  386. package/src/scripts/extract_audit_patterns.ts +21 -0
  387. package/src/scripts/fold_intake.ts +12 -1
  388. package/src/scripts/gen_discovery_baseline.ts +1 -1
  389. package/src/scripts/generate_capabilities_index.ts +12 -5
  390. package/src/scripts/generate_capability_matrix.ts +3 -3
  391. package/src/scripts/generate_command_flows.ts +2 -2
  392. package/src/scripts/generate_cookbook.ts +2 -2
  393. package/src/scripts/generate_index.ts +8 -1
  394. package/src/scripts/generate_knowledge_index.ts +2 -1
  395. package/src/scripts/generate_ownership_matrix.ts +2 -1
  396. package/src/scripts/generate_pack_manifests.ts +10 -2
  397. package/src/scripts/generate_role_experiences_catalog.ts +2 -2
  398. package/src/scripts/generate_settings_reference.ts +1 -1
  399. package/src/scripts/git_authorization_hook.ts +22 -1
  400. package/src/scripts/grade_target_readiness.ts +48 -5
  401. package/src/scripts/hook_effect_doctor.ts +261 -0
  402. package/src/scripts/hook_manifest.json +1 -1
  403. package/src/scripts/hook_manifest.yaml +98 -11
  404. package/src/scripts/hooks/block_speaking_inbox_dir.ts +271 -0
  405. package/src/scripts/hooks/block_unauthorized_git.ts +18 -0
  406. package/src/scripts/hooks/concern_registry.ts +4 -0
  407. package/src/scripts/hooks/dispatch_hook.ts +32 -0
  408. package/src/scripts/hooks/journal_record_hook.ts +345 -0
  409. package/src/scripts/hooks/prepush_metadata_sources.sh +110 -0
  410. package/src/scripts/hooks/run_continuation_hook.ts +44 -9
  411. package/src/scripts/hooks/shims/install.sh +61 -0
  412. package/src/scripts/hooks/shims/php +101 -0
  413. package/src/scripts/hooks/suggestion_capture_hook.ts +10 -0
  414. package/src/scripts/hot_context_hook.ts +16 -0
  415. package/src/scripts/install-hooks.sh +20 -5
  416. package/src/scripts/install.ts +17 -35
  417. package/src/scripts/inventory_frontmatter.ts +2 -1
  418. package/src/scripts/lint_adr_sweep_routing.ts +12 -0
  419. package/src/scripts/lint_canonical_terms.ts +604 -0
  420. package/src/scripts/lint_composition_review.ts +619 -0
  421. package/src/scripts/lint_consolidation_lineage.ts +666 -0
  422. package/src/scripts/lint_eval_specs.ts +593 -0
  423. package/src/scripts/lint_hook_manifest.ts +19 -0
  424. package/src/scripts/lint_host_portability.ts +373 -0
  425. package/src/scripts/lint_judge_prompt_expectation.ts +27 -1
  426. package/src/scripts/lint_memory_twin_parity.ts +335 -0
  427. package/src/scripts/lint_metric_consumers.ts +355 -0
  428. package/src/scripts/lint_skill_descriptions.ts +18 -1
  429. package/src/scripts/lint_skill_frontmatter_safety.ts +58 -0
  430. package/src/scripts/lint_skill_link_reach.ts +252 -0
  431. package/src/scripts/lint_skill_trigger_corpus.ts +426 -23
  432. package/src/scripts/lint_ticket_buildable.ts +17 -1
  433. package/src/scripts/mcp_server/consumer_tool_catalog.json +1 -1
  434. package/src/scripts/mcp_server/tool_catalog_source.ts +1 -1
  435. package/src/scripts/measure_docs_dead_links.ts +348 -0
  436. package/src/scripts/measure_host_capture.ts +461 -0
  437. package/src/scripts/migration_status.ts +3 -3
  438. package/src/scripts/model_rule_injection.ts +60 -0
  439. package/src/scripts/orchestration_record.ts +14 -0
  440. package/src/scripts/preamble_byte_census.ts +139 -10
  441. package/src/scripts/prepack-check.mjs +4 -1
  442. package/src/scripts/probe_turnaround.ts +384 -0
  443. package/src/scripts/probe_unblocked_ask.ts +279 -0
  444. package/src/scripts/render_benchmark_md.ts +1 -1
  445. package/src/scripts/rule_activation_census.ts +70 -9
  446. package/src/scripts/rule_backlinks.ts +1 -1
  447. package/src/scripts/run_lifecycle_suite.ts +208 -0
  448. package/src/scripts/run_skill_evals.ts +40 -0
  449. package/src/scripts/schemas/delivery-manifest.schema.json +43 -0
  450. package/src/scripts/schemas/drafting-channels.schema.json +43 -0
  451. package/src/scripts/schemas/evals.schema.json +24 -1
  452. package/src/scripts/schemas/rule.schema.json +52 -1
  453. package/src/scripts/schemas/skill.schema.json +17 -2
  454. package/src/scripts/skill_overlap.ts +7 -1
  455. package/src/scripts/skill_tools/run_block_d_eval.ts +8 -1
  456. package/src/scripts/skill_tools/score_skill_relevance.ts +84 -3
  457. package/src/scripts/skill_tools/suggest_skill_for_task.ts +8 -1
  458. package/src/scripts/skill_usage_report.ts +2 -1
  459. package/src/scripts/stubs_due.ts +211 -0
  460. package/src/scripts/sweep_source_surfaces.ts +678 -0
  461. package/src/scripts/sync_pr_branch.ts +3 -3
  462. package/src/scripts/trigger_eval_grandfather.json +202 -222
  463. package/src/scripts/utilization_report.ts +22 -2
  464. package/src/server/schemas/settings.ts +5 -0
  465. package/src/templates/marketing-copy.yml +1 -1
  466. package/dist/ui/assets/index-Cxgy63kz.js +0 -26
@@ -0,0 +1,245 @@
1
+ /**
2
+ * Paired binary statistics — the exact test and its effect size.
3
+ *
4
+ * Extracted from `bench_ab_v2_stats.ts` and re-exported there, so every existing
5
+ * importer is unchanged. The move is not cosmetic: that file sits above the
6
+ * 1500-line ceiling `check_source_size_budget` charges, so lines added to it are
7
+ * paid back by extraction rather than by raising a baseline.
8
+ *
9
+ * `mcnemar_exact` is the shape `_lib/paired_verdict.ts` generalises — a binomial
10
+ * over DISCORDANT pairs only, which is the whole point: a concordant pair
11
+ * carries no information about direction and must not dilute the count. This one
12
+ * is two-sided (its callers ask whether the arms differ); `paired_verdict`'s is
13
+ * one-sided (it asks whether the treatment is better). They are kept apart for
14
+ * that reason rather than merged into a flag.
15
+ */
16
+
17
+ /** Exact binomial coefficient via BigInt, so a large n cannot drift. */
18
+ function comb(n: number, k: number): number {
19
+ if (k < 0 || k > n) return 0;
20
+ let num = 1n;
21
+ let den = 1n;
22
+ const kk = BigInt(Math.min(k, n - k));
23
+ for (let i = 0n; i < kk; i += 1n) {
24
+ num *= BigInt(n) - i;
25
+ den *= i + 1n;
26
+ }
27
+ return Number(num / den);
28
+ }
29
+
30
+ export function mcnemar_exact(b: number, c: number): number {
31
+ // Two-sided exact McNemar p-value (binomial on discordant pairs).
32
+ const n = b + c;
33
+ if (n === 0) {
34
+ return 1.0;
35
+ }
36
+ const k = Math.min(b, c);
37
+ let tail = 0;
38
+ for (let i = 0; i <= k; i += 1) {
39
+ tail += comb(n, i);
40
+ }
41
+ tail = tail * 0.5 ** n;
42
+ return Math.min(1.0, 2.0 * tail);
43
+ }
44
+
45
+ export function cohens_h(p1: number, p2: number): number {
46
+ return (
47
+ 2 * Math.asin(Math.sqrt(Math.max(0, Math.min(1, p1)))) -
48
+ 2 * Math.asin(Math.sqrt(Math.max(0, Math.min(1, p2))))
49
+ );
50
+ }
51
+
52
+ /** Python `round(x)` (no ndigits) → int, round-half-to-even. */
53
+ export function _pyRoundNoArg(x: number): number {
54
+ if (!Number.isFinite(x)) return x;
55
+ const floor = Math.floor(x);
56
+ const frac = x - floor;
57
+ if (frac < 0.5) return floor;
58
+ if (frac > 0.5) return floor + 1;
59
+ return floor % 2 === 0 ? floor : floor + 1;
60
+ }
61
+
62
+ /** Python `round(x, ndigits)` — round-half-to-even on the exact double. */
63
+ export function _pyRound(value: number, ndigits: number): number {
64
+ if (!Number.isFinite(value) || value === 0) {
65
+ return value;
66
+ }
67
+ const neg = value < 0;
68
+ const abs = Math.abs(value);
69
+ const exact = abs.toFixed(40);
70
+ const dot = exact.indexOf('.');
71
+ const intPart = dot === -1 ? exact : exact.slice(0, dot);
72
+ const fracPart = dot === -1 ? '' : exact.slice(dot + 1);
73
+ const keepFrac = fracPart.slice(0, ndigits).padEnd(ndigits, '0');
74
+ const rest = fracPart.slice(ndigits);
75
+ const scaledStr = (intPart + keepFrac).replace(/^0+(?=\d)/, '');
76
+ let scaled = BigInt(scaledStr === '' ? '0' : scaledStr);
77
+ if (rest.length > 0) {
78
+ const firstRest = rest.charCodeAt(0) - 48;
79
+ const hasMore = /[1-9]/.test(rest.slice(1));
80
+ if (firstRest > 5 || (firstRest === 5 && hasMore)) {
81
+ scaled += 1n;
82
+ } else if (firstRest === 5 && !hasMore) {
83
+ if (scaled % 2n === 1n) {
84
+ scaled += 1n;
85
+ }
86
+ }
87
+ }
88
+ const factor = 10 ** ndigits;
89
+ const result = Number(scaled) / factor;
90
+ return neg ? -result : result;
91
+ }
92
+
93
+ // CPython's `m_erf` (Modules/mathmodule.c): a Maclaurin series for |x| < 1.5
94
+ // and 1 - erfc for larger |x|; `m_erfc` uses a continued-fraction expansion.
95
+ // Ported verbatim so `_phi(z)` matches python3 to full double precision.
96
+
97
+ const _ERF_SERIES_CUTOFF = 1.5;
98
+ const _ERF_SERIES_TERMS = 25;
99
+ const _ERFC_CONTFRAC_CUTOFF = 30.0;
100
+ const _ERFC_CONTFRAC_TERMS = 50;
101
+ const _SQRTPI = 1.772453850905516027298167483341145182798;
102
+
103
+ function _m_erf_series(x: number): number {
104
+ // erf(x) = 2/sqrt(pi) * x * sum_{k>=0} (-x^2)^k / (k! (2k+1))
105
+ let x2 = x * x;
106
+ let acc = 0.0;
107
+ let fk = _ERF_SERIES_TERMS + 0.5;
108
+ for (let i = 0; i < _ERF_SERIES_TERMS; i += 1) {
109
+ acc = 2.0 + (x2 * acc) / fk;
110
+ fk -= 1.0;
111
+ }
112
+ return (acc * x * Math.exp(-x2)) / _SQRTPI;
113
+ }
114
+
115
+ function _m_erfc_contfrac(x: number): number {
116
+ if (x >= _ERFC_CONTFRAC_CUTOFF) {
117
+ return 0.0;
118
+ }
119
+ const x2 = x * x;
120
+ let a = 0.0;
121
+ let da = 0.5;
122
+ let p = 1.0;
123
+ let p_last = 0.0;
124
+ let q = da + x2;
125
+ let q_last = 1.0;
126
+ for (let i = 0; i < _ERFC_CONTFRAC_TERMS; i += 1) {
127
+ a += da;
128
+ da += 2.0;
129
+ const b = da + x2;
130
+ const temp_p = b * p - a * p_last;
131
+ p_last = p;
132
+ p = temp_p;
133
+ const temp_q = b * q - a * q_last;
134
+ q_last = q;
135
+ q = temp_q;
136
+ }
137
+ return (((p / q) * x) * Math.exp(-x2)) / _SQRTPI;
138
+ }
139
+
140
+ function _erf(x: number): number {
141
+ if (Number.isNaN(x)) {
142
+ return x;
143
+ }
144
+ const absx = Math.abs(x);
145
+ if (absx < _ERF_SERIES_CUTOFF) {
146
+ return _m_erf_series(x);
147
+ }
148
+ const cf = _m_erfc_contfrac(absx);
149
+ return x > 0.0 ? 1.0 - cf : cf - 1.0;
150
+ }
151
+
152
+ /** Python `math.comb(n, k)` — exact non-negative integer (BigInt → Number). */
153
+ function _comb(n: number, k: number): number {
154
+ if (k < 0 || k > n) {
155
+ return 0;
156
+ }
157
+ let kk = BigInt(Math.min(k, n - k));
158
+ if (kk === 0n) {
159
+ return 1;
160
+ }
161
+ const N = BigInt(n);
162
+ let result = 1n;
163
+ let i = 0n;
164
+ while (i < kk) {
165
+ result = (result * (N - i)) / (i + 1n);
166
+ i += 1n;
167
+ }
168
+ return Number(result);
169
+ }
170
+
171
+ function _phi(z: number): number {
172
+ // Standard-normal CDF via erf.
173
+ return 0.5 * (1.0 + _erf(z / Math.sqrt(2.0)));
174
+ }
175
+
176
+
177
+ interface WilcoxonResult {
178
+ n: number;
179
+ W_plus: number; // PyFloat-flagged at dump for the rounded case
180
+ W_minus: number;
181
+ p: number;
182
+ rank_biserial: number;
183
+ }
184
+
185
+ export function wilcoxon(diffs: number[]): WilcoxonResult {
186
+ // Wilcoxon signed-rank on paired differences (treatment - baseline).
187
+ // Returns W+, W-, normal-approx two-sided p (continuity-corrected), and
188
+ // rank-biserial effect size. Zeros are dropped.
189
+ const nz = diffs.filter((d) => Math.abs(d) > 1e-9);
190
+ const n = nz.length;
191
+ if (n === 0) {
192
+ return { n: 0, W_plus: 0, W_minus: 0, p: 1.0, rank_biserial: 0.0 };
193
+ }
194
+ // order = sorted(range(n), key=lambda i: abs(nz[i])) — stable sort.
195
+ const order = Array.from({ length: n }, (_, i) => i).sort((x, y) => {
196
+ const ax = Math.abs(nz[x] as number);
197
+ const ay = Math.abs(nz[y] as number);
198
+ return ax < ay ? -1 : ax > ay ? 1 : x - y; // stable on tie
199
+ });
200
+ const ranks: number[] = new Array(n).fill(0.0);
201
+ let i = 0;
202
+ while (i < n) {
203
+ let j = i;
204
+ while (j + 1 < n && Math.abs(nz[order[j + 1] as number] as number) === Math.abs(nz[order[i] as number] as number)) {
205
+ j += 1;
206
+ }
207
+ const avg = (i + 1 + j + 1) / 2.0; // average rank for ties (1-based)
208
+ for (let k = i; k <= j; k += 1) {
209
+ ranks[order[k] as number] = avg;
210
+ }
211
+ i = j + 1;
212
+ }
213
+ let w_plus = 0.0;
214
+ let w_minus = 0.0;
215
+ for (let idx = 0; idx < n; idx += 1) {
216
+ if ((nz[idx] as number) > 0) {
217
+ w_plus += ranks[idx] as number;
218
+ } else if ((nz[idx] as number) < 0) {
219
+ w_minus += ranks[idx] as number;
220
+ }
221
+ }
222
+ const total = w_plus + w_minus;
223
+ const rb = total ? (w_plus - w_minus) / total : 0.0;
224
+ // Normal approximation (ok-ish for n>=10; for small n it's conservative —
225
+ // we surface n so the reader can weight it).
226
+ const mean = (n * (n + 1)) / 4.0;
227
+ const sd = Math.sqrt((n * (n + 1) * (2 * n + 1)) / 24.0);
228
+ const w = Math.min(w_plus, w_minus);
229
+ let p: number;
230
+ if (sd === 0) {
231
+ p = 1.0;
232
+ } else {
233
+ const z = (w - mean + 0.5) / sd;
234
+ p = Math.min(1.0, 2.0 * _phi(z));
235
+ }
236
+ return {
237
+ n,
238
+ // W_plus / W_minus are not surfaced in JSON/markdown (compare() drops
239
+ // them), so plain numbers suffice; p / rank_biserial are floats.
240
+ W_plus: _pyRound(w_plus, 1),
241
+ W_minus: _pyRound(w_minus, 1),
242
+ p: _pyRound(p, 4),
243
+ rank_biserial: _pyRound(rb, 4),
244
+ };
245
+ }
@@ -0,0 +1,226 @@
1
+ /**
2
+ * Paired verdicts decided by DIRECTION, never by magnitude.
3
+ *
4
+ * `road-to-skill-ecosystem-eval-integrity` Phase 2. The defect this replaces was
5
+ * proved by exhaustive comparison rather than argued: weighting a paired
6
+ * confidence interval by per-trial magnitude disagrees with the exact test on
7
+ * twelve records up to ten trials, and it is the PERMISSIVE side in every one of
8
+ * them. The visible symptom is the opposite of what "permissive" suggests, which
9
+ * is why it went unnoticed — an artifact that won every trial still failed five
10
+ * consecutive runs, because a handful of large opposite-direction deltas
11
+ * outweighed a clean sweep of small ones.
12
+ *
13
+ * The fix is not a better interval. It is to stop asking the question magnitude
14
+ * answers. A paired comparison asks *did this help more often than it hurt*, and
15
+ * the exact test for that reads the DISCORDANT trials only: a pair where both
16
+ * arms tie carries no information about direction and must not dilute the count.
17
+ *
18
+ * ── What magnitude is still for ─────────────────────────────────────────────
19
+ * Triage, and nothing else. {@link PairedVerdict.magnitude_mean} is retained and
20
+ * reported so a human can see whether a directional win is worth anything, and
21
+ * every renderer that prints it must say it decides nothing. A number in a
22
+ * report with no stated role gets read as a criterion by the next person.
23
+ */
24
+
25
+ /** The four outcomes. `underpowered` is deliberately not a kind of pass. */
26
+ export type PairedVerdictKind = 'pass' | 'regression' | 'no-change' | 'underpowered';
27
+
28
+ export interface PairedVerdict {
29
+ kind: PairedVerdictKind;
30
+ /** Trials where the arms differed. Concordant pairs are excluded by design. */
31
+ discordant: number;
32
+ /** Discordant trials favouring the treatment. */
33
+ wins: number;
34
+ /** Discordant trials favouring the control. */
35
+ losses: number;
36
+ /** One-sided exact p in the observed direction. */
37
+ p: number;
38
+ /** Mean signed delta over ALL trials. Triage only — decides nothing. */
39
+ magnitude_mean: number | null;
40
+ /** True when `discordant` sits exactly on the derived floor. */
41
+ at_floor: boolean;
42
+ /** Why this verdict, in one sentence a report can print verbatim. */
43
+ reason: string;
44
+ }
45
+
46
+ /**
47
+ * Significance level. 0.05 is the convention every sibling gate in this tree
48
+ * already applies (`bench_ab_size_claim.ALPHA`), and changing it here would make
49
+ * two verdicts in one report answer to different bars.
50
+ */
51
+ export const ALPHA = 0.05;
52
+
53
+ /**
54
+ * Minimum discordant trials, DERIVED from the test rather than chosen.
55
+ *
56
+ * The one-sided exact sign test over `n` discordant trials has a smallest
57
+ * attainable p of `0.5 ** n` — the probability of a perfect sweep. A pass at
58
+ * `ALPHA` is therefore arithmetically impossible until `0.5 ** n <= ALPHA`:
59
+ *
60
+ * n=1 → 0.5 n=2 → 0.25 n=3 → 0.125
61
+ * n=4 → 0.0625 n=5 → 0.03125 ← first n that can clear 0.05
62
+ *
63
+ * So the floor is **5**, and it is a fact about the test, not a preference. A
64
+ * specification with fewer discordant trials cannot pass however good the
65
+ * artifact is, which is why {@link decidePairedVerdict} returns `underpowered`
66
+ * there instead of `no-change`: the two look identical in a table and have
67
+ * opposite remedies — one says run more trials, the other says stop.
68
+ *
69
+ * Recomputed by {@link deriveMinDiscordant} rather than hardcoded, so a future
70
+ * change to ALPHA moves the floor with it instead of leaving a stale constant.
71
+ */
72
+ export function deriveMinDiscordant(alpha: number = ALPHA): number {
73
+ let n = 1;
74
+ while (0.5 ** n > alpha && n < 64) n += 1;
75
+ return n;
76
+ }
77
+
78
+ export const MIN_DISCORDANT = deriveMinDiscordant();
79
+
80
+ /** Binomial coefficient, exact via BigInt so large n cannot drift. */
81
+ function comb(n: number, k: number): number {
82
+ if (k < 0 || k > n) return 0;
83
+ let num = 1n;
84
+ let den = 1n;
85
+ const kk = BigInt(Math.min(k, n - k));
86
+ for (let i = 0n; i < kk; i += 1n) {
87
+ num *= BigInt(n) - i;
88
+ den *= i + 1n;
89
+ }
90
+ return Number(num / den);
91
+ }
92
+
93
+ /**
94
+ * One-sided exact sign test over discordant trials.
95
+ *
96
+ * `P(X >= wins)` under a fair coin on `discordant` trials — the probability of
97
+ * seeing at least this many wins if direction were noise. One-sided because the
98
+ * question a verdict asks is directional: *is the treatment better*, not *do the
99
+ * arms differ*. A two-sided p answers the second and is twice as hard to clear
100
+ * for the first, which is a bar nobody chose.
101
+ */
102
+ export function exactOneSidedP(wins: number, discordant: number): number {
103
+ if (discordant <= 0) return 1;
104
+ let tail = 0;
105
+ for (let i = wins; i <= discordant; i += 1) tail += comb(discordant, i);
106
+ return Math.min(1, tail * 0.5 ** discordant);
107
+ }
108
+
109
+ export interface PairedInput {
110
+ /** One signed delta per trial. Positive favours the treatment. */
111
+ deltas: readonly number[];
112
+ /** Deltas within this of zero are ties and are excluded as concordant. */
113
+ tieEpsilon?: number;
114
+ alpha?: number;
115
+ }
116
+
117
+ /**
118
+ * Decide a paired comparison from direction alone.
119
+ *
120
+ * Ties are dropped BEFORE anything is counted, which is the half a
121
+ * magnitude-weighted interval gets wrong: a tie has zero magnitude, so it
122
+ * contributes nothing to the mean while still inflating `n` and narrowing the
123
+ * interval. Dropping it makes the sample honest about how much evidence there
124
+ * actually is.
125
+ */
126
+ export function decidePairedVerdict(input: PairedInput): PairedVerdict {
127
+ const alpha = input.alpha ?? ALPHA;
128
+ const eps = input.tieEpsilon ?? 0;
129
+ const floor = deriveMinDiscordant(alpha);
130
+ const wins = input.deltas.filter((d) => d > eps).length;
131
+ const losses = input.deltas.filter((d) => d < -eps).length;
132
+ const discordant = wins + losses;
133
+ const magnitude_mean =
134
+ input.deltas.length === 0
135
+ ? null
136
+ : input.deltas.reduce((a, b) => a + b, 0) / input.deltas.length;
137
+ const at_floor = discordant === floor;
138
+
139
+ if (discordant < floor) {
140
+ return {
141
+ kind: 'underpowered',
142
+ discordant,
143
+ wins,
144
+ losses,
145
+ p: 1,
146
+ magnitude_mean,
147
+ at_floor: false,
148
+ reason:
149
+ `${String(discordant)} discordant trial(s) is below the derived floor of ` +
150
+ `${String(floor)}: the smallest attainable one-sided p is ${(0.5 ** discordant).toFixed(4)}, ` +
151
+ `so no result here can clear ${String(alpha)}. This is NOT a null result — it is an ` +
152
+ 'absent measurement, and it belongs in no pass-rate denominator.',
153
+ };
154
+ }
155
+
156
+ const favoured = wins >= losses ? wins : losses;
157
+ const p = exactOneSidedP(favoured, discordant);
158
+ if (p > alpha) {
159
+ return {
160
+ kind: 'no-change',
161
+ discordant,
162
+ wins,
163
+ losses,
164
+ p,
165
+ magnitude_mean,
166
+ at_floor,
167
+ reason:
168
+ `${String(wins)}/${String(discordant)} discordant trials favour the treatment ` +
169
+ `(one-sided exact p=${p.toFixed(4)}); the direction is not distinguishable from noise at ${String(alpha)}.`,
170
+ };
171
+ }
172
+ return {
173
+ kind: wins >= losses ? 'pass' : 'regression',
174
+ discordant,
175
+ wins,
176
+ losses,
177
+ p,
178
+ magnitude_mean,
179
+ at_floor,
180
+ reason:
181
+ `${String(wins)}/${String(discordant)} discordant trials favour the ` +
182
+ `${wins >= losses ? 'treatment' : 'control'} (one-sided exact p=${p.toFixed(4)}).`,
183
+ };
184
+ }
185
+
186
+ /**
187
+ * The warning a specification earns by sitting EXACTLY on the derived floor.
188
+ *
189
+ * At the floor, `0.5 ** n` equals or barely clears alpha, so a pass requires a
190
+ * PERFECT sweep — one trial going the other way makes the result arithmetically
191
+ * unreachable before the run starts. That is a specification defect rather than
192
+ * a result, and it is invisible in the output: the run simply fails. Observed as
193
+ * five specifications raised to exactly the floor all failing, four of them
194
+ * decided before the run began.
195
+ *
196
+ * Returns `null` when there is nothing to warn about, so a caller can print it
197
+ * unconditionally.
198
+ */
199
+ export function floorWarning(v: PairedVerdict, alpha: number = ALPHA): string | null {
200
+ if (!v.at_floor) return null;
201
+ return (
202
+ `specification sits exactly on the derived discordant floor (${String(v.discordant)}): ` +
203
+ `a pass needs every trial to agree, because one dissent moves p to ` +
204
+ `${exactOneSidedP(v.discordant - 1, v.discordant).toFixed(4)} against a bar of ${String(alpha)}. ` +
205
+ 'Raise the trial count rather than the expectation.'
206
+ );
207
+ }
208
+
209
+ /**
210
+ * Pass rate over a set of verdicts, with `underpowered` excluded.
211
+ *
212
+ * Exported as the ONLY sanctioned way to compute one, because the exclusion is
213
+ * the whole point and an inline `filter(v => v.kind === 'pass').length / all.length`
214
+ * silently reinstates the defect. Returns `null` when nothing is decidable —
215
+ * a rate over an empty denominator is a fabricated number, not a zero.
216
+ */
217
+ export function passRate(verdicts: readonly PairedVerdict[]): { rate: number; decided: number; excluded: number } | null {
218
+ const decidable = verdicts.filter((v) => v.kind !== 'underpowered');
219
+ const excluded = verdicts.length - decidable.length;
220
+ if (decidable.length === 0) return null;
221
+ return {
222
+ rate: decidable.filter((v) => v.kind === 'pass').length / decidable.length,
223
+ decided: decidable.length,
224
+ excluded,
225
+ };
226
+ }
@@ -0,0 +1,123 @@
1
+ /**
2
+ * The canonical prefix-stable surface set — one list, loaded by every gate
3
+ * that needs it, restated by none.
4
+ *
5
+ * WHAT A PREFIX-STABLE SURFACE IS
6
+ * -------------------------------
7
+ * Bytes that sit in the cached prompt prefix of every dispatch. Rewriting them
8
+ * mid-session invalidates the cache for the remainder of that session, so the
9
+ * next call pays the cache-WRITE rate over the whole prefix instead of the
10
+ * cache-READ rate. That is the cost this list exists to bound; it is not a
11
+ * correctness claim about the content.
12
+ *
13
+ * WHY THE LIST LIVES HERE AND NOT IN A GATE
14
+ * -----------------------------------------
15
+ * `check_preamble_payload_budget` measured these three buckets first and stated
16
+ * their roots twice inside its own file — once to drive the census, once as the
17
+ * `roots:` argument to the dead-scope guard. A second gate restating them a
18
+ * third time is the recorded drift shape this repository already pays for
19
+ * elsewhere: two lists describing one boundary diverge, and each gate then
20
+ * guards a set the other no longer measures. So the roots move here and both
21
+ * gates import them.
22
+ *
23
+ * SCOPE — decided, with the reopen condition recorded
24
+ * ---------------------------------------------------
25
+ * Council 2026-08-28 (2/2 convergent, anthropic + openai, 2 rounds) resolved
26
+ * `road-to-runtime-context-floors`'s `which-surfaces-are-prefix-stable` blocker
27
+ * as option (c): the declared set is the three buckets the payload budget
28
+ * already measures, and the widening to "every surface a hook can write that
29
+ * reaches standing context" is recorded as an explicit reopen condition rather
30
+ * than enumerated now. Enumerating carriers that do not exist would be
31
+ * enumerating a plan.
32
+ *
33
+ * REOPEN — see `docs/contracts/prefix-stable-surfaces.md` § Reopen condition.
34
+ * A change that lands a hook or resident-process carrier able to write standing
35
+ * context outside these three roots must add it here in the same change.
36
+ */
37
+
38
+ export interface PrefixStableSurface {
39
+ /** Stable identifier; the mutation gate names it in its findings. */
40
+ id: string;
41
+ /** Repo-relative root. A directory root covers everything beneath it. */
42
+ root: string;
43
+ kind: 'dir' | 'file';
44
+ /** Human-readable bucket name, as the payload budget reports it. */
45
+ bucket: string;
46
+ /** Why these bytes are in the cached prefix. */
47
+ why: string;
48
+ }
49
+
50
+ /**
51
+ * The declared set. Order is the order the payload budget reports its buckets,
52
+ * so a reader comparing the two outputs sees the same sequence.
53
+ */
54
+ export const PREFIX_STABLE_SURFACES: readonly PrefixStableSurface[] = [
55
+ {
56
+ id: 'project-scope-rules',
57
+ root: 'dist/agent-src/rules',
58
+ kind: 'dir',
59
+ bucket: 'project-scope rules',
60
+ why: 'Every always-loaded rule body is re-written into the preamble on every spawn.',
61
+ },
62
+ {
63
+ id: 'preloaded-skills-catalog',
64
+ root: 'dist/agent-src/skills',
65
+ kind: 'dir',
66
+ bucket: 'preloaded skills catalog',
67
+ why: 'Skill names and descriptions are catalogued into the preamble on every spawn.',
68
+ },
69
+ {
70
+ id: 'project-claude-md',
71
+ root: 'CLAUDE.md',
72
+ kind: 'file',
73
+ bucket: 'CLAUDE.md hierarchy (project only)',
74
+ why: 'The project half of the CLAUDE.md hierarchy is injected ahead of the first user turn.',
75
+ },
76
+ {
77
+ id: 'project-claude-local-md',
78
+ root: 'CLAUDE.local.md',
79
+ kind: 'file',
80
+ bucket: 'CLAUDE.md hierarchy (project only)',
81
+ why: 'The gitignored project-local override is injected on the same path as CLAUDE.md.',
82
+ },
83
+ ] as const;
84
+
85
+ /**
86
+ * The re-arm events. A rebuilt prefix is expected and paid for once at each of
87
+ * these boundaries, so a write declared against one is not a mid-session
88
+ * mutation. Anything not listed here fires mid-session.
89
+ */
90
+ export const RE_ARM_EVENTS: readonly string[] = ['session_start', 'pre_compact'] as const;
91
+
92
+ /** Roots only, in declaration order — the shape `assertScanned` wants. */
93
+ export function prefixStableRoots(): string[] {
94
+ return PREFIX_STABLE_SURFACES.map((s) => s.root);
95
+ }
96
+
97
+ /** Directory roots only — the shape the payload census walks. */
98
+ export function prefixStableDirRoots(): string[] {
99
+ return PREFIX_STABLE_SURFACES.filter((s) => s.kind === 'dir').map((s) => s.root);
100
+ }
101
+
102
+ function normalise(p: string): string {
103
+ return p.replace(/\\/g, '/').replace(/^\.\//, '').replace(/\/+$/, '');
104
+ }
105
+
106
+ /**
107
+ * Does `target` (a repo-relative path, or a path literal lifted out of source)
108
+ * resolve inside a declared surface? Returns the surface, or `null`.
109
+ *
110
+ * Deliberately substring-free: a literal must match a root exactly, or sit
111
+ * beneath a directory root at a path separator. `dist/agent-src/rules-backup`
112
+ * is NOT inside `dist/agent-src/rules`.
113
+ */
114
+ export function surfaceFor(target: string): PrefixStableSurface | null {
115
+ const t = normalise(target);
116
+ if (t === '') return null;
117
+ for (const s of PREFIX_STABLE_SURFACES) {
118
+ const root = normalise(s.root);
119
+ if (t === root) return s;
120
+ if (s.kind === 'dir' && t.startsWith(root + '/')) return s;
121
+ }
122
+ return null;
123
+ }
@@ -0,0 +1,47 @@
1
+ /**
2
+ * The privacy class an audit-log-v1 line declares about ITSELF.
3
+ *
4
+ * `docs/contracts/audit-log-v1.md` states a privacy floor in prose and, until
5
+ * 2026-08-30, named a test file that exists in no tree — so the floor was
6
+ * asserted and not enforced. Two things close that gap, and they are different
7
+ * mechanisms rather than one restated twice:
8
+ *
9
+ * 1. A COMPILE-TIME guard (`NoFreeForm`, applied to each producer's input type)
10
+ * makes a field that *could* hold a body a build error. That is what stops
11
+ * the leak.
12
+ * 2. This enum makes each line SAY what it carries. That is what lets a reader
13
+ * decide whether a stream is safe to aggregate, export, or ship without
14
+ * re-deriving the answer from the producer's source.
15
+ *
16
+ * The first without the second leaves every consumer inferring the class; the
17
+ * second without the first is a label with nothing behind it.
18
+ *
19
+ * One module rather than a literal per producer, per step 9.1's rule that an
20
+ * enum family appearing in more than one place gets exactly one definition —
21
+ * the duplicate-enum failure that gave this tree two outcome vocabularies.
22
+ */
23
+
24
+ /**
25
+ * Ordered from least to most permissive. A reader may treat a lower class as
26
+ * satisfying any assertion made about a higher one; the reverse is never true.
27
+ */
28
+ export const PRIVACY_CLASSES = [
29
+ /**
30
+ * Counts, enums, timestamps and opaque ids the package itself minted. No
31
+ * artefact names at all. The strictest class a line can declare.
32
+ */
33
+ 'counts-only',
34
+ /**
35
+ * Everything `counts-only` allows, plus STABLE ARTEFACT IDS the package
36
+ * governs — rule ids, skill ids, task-class ids. Still no bodies, no paths,
37
+ * no user content, and no third-party identifiers. This is what both
38
+ * shipped producers emit, because both carry `rules_applied`.
39
+ */
40
+ 'ids-only',
41
+ ] as const;
42
+
43
+ export type PrivacyClass = (typeof PRIVACY_CLASSES)[number];
44
+
45
+ export function isPrivacyClass(v: unknown): v is PrivacyClass {
46
+ return typeof v === 'string' && (PRIVACY_CLASSES as readonly string[]).includes(v);
47
+ }