@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,283 @@
1
+ /**
2
+ * The evaluation gate's record type: a metric VECTOR, never a weighted total.
3
+ *
4
+ * `road-to-governed-harness-evolution` Phase 4, steps 4.2 and 4.3.
5
+ *
6
+ * > *4.2 Report a metric vector, never a weighted total. Include an
7
+ * > `artifact-count delta` row — that is where the sprawl concern belongs,
8
+ * > inside the gate where it can prevent something.*
9
+ * > verify: **no code path computes a single scalar score.**
10
+ *
11
+ * > *4.3 Make the verdict hierarchy explicit. `paired_verdict` per metric
12
+ * > decides; `underpowered` is not a pass; a Pareto frontier may only order
13
+ * > candidates that are already non-dominated and never promotes.*
14
+ * > verify: **a fixture where the frontier prefers a candidate whose
15
+ * > `paired_verdict` is `underpowered` produces no promotion.**
16
+ *
17
+ * ## Why a scalar is the defect and not merely a simplification
18
+ *
19
+ * A weighted total is a claim that the metrics are commensurable and that the
20
+ * author knew the exchange rate. Neither is established here. Worse, the
21
+ * collapse is lossy in exactly the direction that matters: a candidate that
22
+ * regresses one metric and wins three can outscore one that wins all four, and
23
+ * the report shows one number where the disagreement was. The vector keeps the
24
+ * disagreement visible and forces {@link promotionVerdict} to state which row
25
+ * refused.
26
+ *
27
+ * So the shape carries the guarantee rather than a comment asking for it:
28
+ * {@link MetricVector} has no total field, no weight field, and nothing in this
29
+ * module takes a vector and returns a number.
30
+ * `tests/scripts/evaluation_vector.test.ts` scans every file in `src/scripts`
31
+ * that mentions `MetricVector` for that construct set, in both polarities.
32
+ *
33
+ * ## The artifact-count row is inside the gate, not beside it
34
+ *
35
+ * Sprawl reported next to a gate is a note; sprawl reported inside it can
36
+ * refuse. {@link buildVector} REFUSES a vector that omits the
37
+ * {@link ARTIFACT_COUNT_METRIC} row, so a candidate cannot reach
38
+ * {@link promotionVerdict} without its artifact delta having been measured, and
39
+ * {@link promotionVerdict} blocks on a delta above its ceiling.
40
+ *
41
+ * The default ceiling is **0** — a candidate may not grow the artifact count
42
+ * unless the caller says so. That is a conservative default rather than a
43
+ * measured one, and it is stated as such: a curator `ADD` is a legitimate
44
+ * positive delta, and the caller that knows it is an `ADD` passes the ceiling
45
+ * it means.
46
+ *
47
+ * ## Two row kinds, because two things are being measured
48
+ *
49
+ * A paired row carries a {@link PairedVerdict} — direction decided by the exact
50
+ * sign test, with `underpowered` deliberately not a kind of pass. A counted row
51
+ * carries an integer delta read off the candidate, with no trials behind it.
52
+ * Forcing the artifact delta through a paired verdict would invent trials that
53
+ * do not exist; giving a metric row a bare number would let a caller put an
54
+ * outcome there without evidence. Both shapes exist so neither lie is available.
55
+ */
56
+ import type { PairedVerdict, PairedVerdictKind } from './paired_verdict.js';
57
+
58
+ /** Which direction is better for a row. Read by {@link dominates}. */
59
+ export type MetricDirection = 'higher-better' | 'lower-better';
60
+
61
+ /** The counted row every vector must carry. Step 4.2 names it. */
62
+ export const ARTIFACT_COUNT_METRIC = 'artifact-count-delta';
63
+
64
+ export interface PairedRow {
65
+ kind: 'paired';
66
+ metric: string;
67
+ direction: MetricDirection;
68
+ verdict: PairedVerdict;
69
+ }
70
+
71
+ export interface CountedRow {
72
+ kind: 'counted';
73
+ metric: string;
74
+ direction: MetricDirection;
75
+ /** Signed delta against the baseline. No trials, no verdict, no inference. */
76
+ delta: number;
77
+ }
78
+
79
+ export type MetricRow = PairedRow | CountedRow;
80
+
81
+ /**
82
+ * The evaluation record for one candidate.
83
+ *
84
+ * Deliberately absent: any field that would hold a summary number. Adding one
85
+ * is the failure this type exists to prevent, and the scanner test names it.
86
+ */
87
+ export interface MetricVector {
88
+ candidate_id: string;
89
+ rows: readonly MetricRow[];
90
+ }
91
+
92
+ export class VectorShapeError extends Error {
93
+ constructor(message: string) {
94
+ super(message);
95
+ this.name = 'VectorShapeError';
96
+ }
97
+ }
98
+
99
+ /**
100
+ * Build a vector, refusing the three shapes that would make the gate lie:
101
+ * no rows at all, a duplicate metric name, or a missing artifact-count row.
102
+ */
103
+ export function buildVector(candidate_id: string, rows: readonly MetricRow[]): MetricVector {
104
+ if (rows.length === 0) {
105
+ throw new VectorShapeError(`${candidate_id}: a vector with no rows measures nothing`);
106
+ }
107
+ const seen = new Set<string>();
108
+ for (const r of rows) {
109
+ if (seen.has(r.metric)) {
110
+ throw new VectorShapeError(`${candidate_id}: duplicate metric row '${r.metric}'`);
111
+ }
112
+ seen.add(r.metric);
113
+ }
114
+ if (!seen.has(ARTIFACT_COUNT_METRIC)) {
115
+ throw new VectorShapeError(
116
+ `${candidate_id}: missing the '${ARTIFACT_COUNT_METRIC}' row — the sprawl ` +
117
+ 'measurement belongs inside the gate, so a vector without it cannot be evaluated',
118
+ );
119
+ }
120
+ return { candidate_id, rows: [...rows] };
121
+ }
122
+
123
+ /** The artifact-count row, or `null` on a vector that never went through {@link buildVector}. */
124
+ export function artifactCountRow(v: MetricVector): CountedRow | null {
125
+ for (const r of v.rows) {
126
+ if (r.metric === ARTIFACT_COUNT_METRIC && r.kind === 'counted') {
127
+ return r;
128
+ }
129
+ }
130
+ return null;
131
+ }
132
+
133
+ /**
134
+ * Row-level ordering: `-1` when `a` is worse, `1` when better, `0` when the two
135
+ * carry no ordering against each other.
136
+ *
137
+ * A paired row orders by VERDICT KIND, never by magnitude — `magnitude_mean`
138
+ * exists for triage and decides nothing (`paired_verdict.ts` header). An
139
+ * `underpowered` row is incomparable with everything including itself: it is
140
+ * not a worse pass, it is an absence of evidence, so it can neither win a row
141
+ * nor lose one.
142
+ */
143
+ /**
144
+ * Paired-verdict ordering. `underpowered` is `null` — incomparable in both
145
+ * directions, because an absent measurement is not a worse pass.
146
+ */
147
+ const VERDICT_RANK: Record<PairedVerdictKind, number | null> = {
148
+ pass: 2,
149
+ 'no-change': 1,
150
+ regression: 0,
151
+ underpowered: null,
152
+ };
153
+
154
+ export function compareRow(a: MetricRow, b: MetricRow): -1 | 0 | 1 {
155
+ if (a.metric !== b.metric) {
156
+ throw new VectorShapeError(`cannot compare '${a.metric}' against '${b.metric}'`);
157
+ }
158
+ if (a.kind === 'counted' && b.kind === 'counted') {
159
+ if (a.delta === b.delta) return 0;
160
+ const aBetter = a.direction === 'higher-better' ? a.delta > b.delta : a.delta < b.delta;
161
+ return aBetter ? 1 : -1;
162
+ }
163
+ if (a.kind === 'paired' && b.kind === 'paired') {
164
+ const ra = VERDICT_RANK[a.verdict.kind];
165
+ const rb = VERDICT_RANK[b.verdict.kind];
166
+ if (ra === null || rb === null) return 0;
167
+ if (ra === rb) return 0;
168
+ return ra > rb ? 1 : -1;
169
+ }
170
+ return 0;
171
+ }
172
+
173
+ /**
174
+ * Pareto domination: `a` dominates `b` when no row is worse and at least one is
175
+ * better. Vectors must carry the same metric names — comparing different metric
176
+ * sets is a shape error, not a tie.
177
+ */
178
+ export function dominates(a: MetricVector, b: MetricVector): boolean {
179
+ const bRows = new Map(b.rows.map((r) => [r.metric, r]));
180
+ if (a.rows.length !== b.rows.length) {
181
+ throw new VectorShapeError(
182
+ `${a.candidate_id} and ${b.candidate_id} carry different metric sets`,
183
+ );
184
+ }
185
+ let strictlyBetter = false;
186
+ for (const ar of a.rows) {
187
+ const br = bRows.get(ar.metric);
188
+ if (br === undefined) {
189
+ throw new VectorShapeError(
190
+ `${a.candidate_id} and ${b.candidate_id} carry different metric sets`,
191
+ );
192
+ }
193
+ const c = compareRow(ar, br);
194
+ if (c < 0) return false;
195
+ if (c > 0) strictlyBetter = true;
196
+ }
197
+ return strictlyBetter;
198
+ }
199
+
200
+ /**
201
+ * The non-dominated set, in input order.
202
+ *
203
+ * ORDERING ONLY. This function promotes nothing and is not consulted by
204
+ * {@link promotionVerdict}; step 4.3's verify clause is precisely that a
205
+ * frontier preference cannot become a promotion. Membership here means "no
206
+ * other candidate beat this one on every row", which is a statement about the
207
+ * comparison set and not about whether the evidence concluded.
208
+ */
209
+ export function paretoFrontier(vectors: readonly MetricVector[]): MetricVector[] {
210
+ return vectors.filter((v) => !vectors.some((o) => o !== v && dominates(o, v)));
211
+ }
212
+
213
+ export interface PromotionOptions {
214
+ /** Largest artifact-count delta this candidate class may carry. Default 0. */
215
+ artifactDeltaCeiling?: number;
216
+ }
217
+
218
+ export interface PromotionVerdict {
219
+ promote: boolean;
220
+ /** Every row that refused, by metric name. Empty iff `promote` is true. */
221
+ blocking: readonly string[];
222
+ /** One sentence a report can print verbatim. */
223
+ reason: string;
224
+ }
225
+
226
+ /**
227
+ * The ONLY promoter in this module, and the whole hierarchy in one place.
228
+ *
229
+ * Refuses on, in this order: a regression on any paired row; an `underpowered`
230
+ * paired row (not a pass — the remedy is more trials, not a promotion); an
231
+ * artifact-count delta above the ceiling; a vector with no paired row at all;
232
+ * and a vector where every paired row concluded `no-change`. The last is the
233
+ * one worth stating: `no-change` is a real verdict and it says the candidate
234
+ * did not help, so a vector of them is a decided absence of improvement rather
235
+ * than a clean sheet.
236
+ */
237
+ export function promotionVerdict(v: MetricVector, opts: PromotionOptions = {}): PromotionVerdict {
238
+ const ceiling = opts.artifactDeltaCeiling ?? 0;
239
+ const blocking: string[] = [];
240
+ const notes: string[] = [];
241
+ let pairedRows = 0;
242
+ let passRows = 0;
243
+
244
+ for (const r of v.rows) {
245
+ if (r.kind === 'paired') {
246
+ pairedRows += 1;
247
+ if (r.verdict.kind === 'pass') passRows += 1;
248
+ if (r.verdict.kind === 'regression') {
249
+ blocking.push(r.metric);
250
+ notes.push(`${r.metric} regressed`);
251
+ } else if (r.verdict.kind === 'underpowered') {
252
+ blocking.push(r.metric);
253
+ notes.push(`${r.metric} is underpowered, which is not a pass`);
254
+ }
255
+ } else if (r.metric === ARTIFACT_COUNT_METRIC && r.delta > ceiling) {
256
+ blocking.push(r.metric);
257
+ notes.push(`artifact-count delta ${String(r.delta)} exceeds ceiling ${String(ceiling)}`);
258
+ }
259
+ }
260
+
261
+ if (pairedRows === 0) {
262
+ blocking.push('<no-paired-row>');
263
+ notes.push('no paired verdict in the vector, so no metric concluded');
264
+ } else if (passRows === 0 && blocking.length === 0) {
265
+ blocking.push('<no-pass-row>');
266
+ notes.push('every paired row concluded no-change, so nothing improved');
267
+ }
268
+
269
+ if (blocking.length > 0) {
270
+ return {
271
+ promote: false,
272
+ blocking,
273
+ reason: `${v.candidate_id} is not promotable: ${notes.join('; ')}`,
274
+ };
275
+ }
276
+ return {
277
+ promote: true,
278
+ blocking: [],
279
+ reason:
280
+ `${v.candidate_id} carries ${String(pairedRows)} paired row(s), ${String(passRows)} of them a pass, ` +
281
+ `none regressed or underpowered, artifact delta within ceiling ${String(ceiling)}`,
282
+ };
283
+ }
@@ -0,0 +1,225 @@
1
+ /**
2
+ * Evaluator promotion — a new evaluator earns its seat by cross-grading, or it
3
+ * does not get one.
4
+ *
5
+ * `road-to-governed-harness-evolution` Phase 4, step 4.7.
6
+ *
7
+ * > *Reuse the discrimination and hygiene machinery. `eval_publication`'s
8
+ * > `PlantedItem` for plants, `judge_hygiene` for order-swap. Add the
9
+ * > evaluator-promotion procedure the master omitted: an old and a new
10
+ * > evaluator must cross-grade frozen candidate sets, and evaluator promotion
11
+ * > itself requires discrimination plants.*
12
+ * > verify: **a planted candidate the control arm also satisfies is reported as
13
+ * > a discrimination deficit, not as a win; an evaluator change with no
14
+ * > cross-grade is refused.**
15
+ *
16
+ * ## Reuse, not reimplementation
17
+ *
18
+ * Risk 1 on this roadmap is a parallel rebuild of machinery that already
19
+ * exists, committed four times by the source proposals. So nothing here scores
20
+ * a plant, classifies an assertion, or decides a paired verdict:
21
+ * {@link reportPlants} delegates to `eval_publication.discriminationDeficit`
22
+ * and {@link assertEvaluatorPromotable} delegates to
23
+ * `judge_hygiene.auditAssertions`. What this module adds is the one thing
24
+ * neither has: the REFUSAL that turns an evaluator swap into a gated event.
25
+ *
26
+ * ## Why a satisfied plant can be a deficit rather than a win
27
+ *
28
+ * A plant exists to be recoverable only via the behaviour under test. If the
29
+ * control arm also satisfies it, then the item measured general competence and
30
+ * the treatment's success over it is not evidence about the treatment — the two
31
+ * arms scored the same for different-looking reasons. Counting it as a win is
32
+ * the exact inflation `eval_publication`'s header describes, so
33
+ * {@link reportPlants} moves it into `discrimination_deficits` and, critically,
34
+ * strips its `requires_artifact_behaviour` flag before handing the set to
35
+ * `discriminationDeficit` — otherwise a fixture set whose every discriminating
36
+ * plant turned out to be non-discriminating in practice would still pass the
37
+ * pre-run check on its declared intent.
38
+ *
39
+ * ## Order-swap is carried as a declared property, and refused when absent
40
+ *
41
+ * `judge_hygiene`'s header records that blinding and the order-swap are already
42
+ * met upstream by `check_quality_regression.evaluatePair`, which judges every
43
+ * pair in both orders and resolves a flip to `inconsistent`. This module does
44
+ * not re-implement that; it requires the cross-grade to DECLARE that it ran
45
+ * that way ({@link CrossGrade.order_swapped}) and refuses the promotion when it
46
+ * did not. That is an honest boundary: the property is asserted by the caller
47
+ * and checked here, not observed here.
48
+ */
49
+ import { discriminationDeficit, type PlantedItem } from './eval_publication.js';
50
+ import { auditAssertions, type AssertionObservation } from './judge_hygiene.js';
51
+
52
+ /** One plant, and what each arm actually did with it. */
53
+ export interface PlantOutcome {
54
+ item: PlantedItem;
55
+ treatment_satisfied: boolean;
56
+ control_satisfied: boolean;
57
+ }
58
+
59
+ export interface DiscriminationDeficitFinding {
60
+ id: string;
61
+ reason: string;
62
+ }
63
+
64
+ export interface PlantReport {
65
+ /** Plants the treatment satisfied and the control did not. The measurement. */
66
+ wins: readonly string[];
67
+ /** Plants the control also satisfied. Never wins, whatever the treatment did. */
68
+ discrimination_deficits: readonly DiscriminationDeficitFinding[];
69
+ /**
70
+ * The set-level verdict from `eval_publication.discriminationDeficit`, run
71
+ * over the EFFECTIVE set (observed, not declared). Non-null means the set
72
+ * cannot adjudicate at all.
73
+ */
74
+ set_deficit: string | null;
75
+ }
76
+
77
+ /** Classify every plant outcome. See the header for why a shared satisfaction is a deficit. */
78
+ export function reportPlants(outcomes: readonly PlantOutcome[]): PlantReport {
79
+ const wins: string[] = [];
80
+ const deficits: DiscriminationDeficitFinding[] = [];
81
+ const effective: PlantedItem[] = [];
82
+
83
+ for (const o of outcomes) {
84
+ if (o.control_satisfied) {
85
+ deficits.push({
86
+ id: o.item.id,
87
+ reason:
88
+ `the control arm also satisfied '${o.item.id}', so it measures general ` +
89
+ 'competence rather than the behaviour under test — a discrimination deficit, not a win',
90
+ });
91
+ effective.push({ id: o.item.id, requires_artifact_behaviour: false });
92
+ continue;
93
+ }
94
+ effective.push({ id: o.item.id, requires_artifact_behaviour: o.item.requires_artifact_behaviour });
95
+ if (o.treatment_satisfied && o.item.requires_artifact_behaviour) {
96
+ wins.push(o.item.id);
97
+ }
98
+ }
99
+
100
+ return {
101
+ wins,
102
+ discrimination_deficits: deficits,
103
+ set_deficit: discriminationDeficit(effective),
104
+ };
105
+ }
106
+
107
+ /** The frozen candidate set both evaluators must grade. Frozen means: named and enumerated. */
108
+ export interface FrozenCandidateSet {
109
+ id: string;
110
+ candidate_ids: readonly string[];
111
+ }
112
+
113
+ export interface CrossGrade {
114
+ from_evaluator: string;
115
+ to_evaluator: string;
116
+ /** Must equal the change's frozen set id — a cross-grade of some other set proves nothing. */
117
+ frozen_set_id: string;
118
+ /** Candidate ids the OLD evaluator graded. */
119
+ graded_by_from: readonly string[];
120
+ /** Candidate ids the NEW evaluator graded. */
121
+ graded_by_to: readonly string[];
122
+ /**
123
+ * Declared by the caller: every pair was judged in both orders upstream
124
+ * (`check_quality_regression.evaluatePair`). See the header — asserted, not
125
+ * observed here.
126
+ */
127
+ order_swapped: boolean;
128
+ /** Rubric assertions used by the grading, audited via `judge_hygiene`. */
129
+ assertions: readonly AssertionObservation[];
130
+ }
131
+
132
+ export interface EvaluatorChange {
133
+ from: string;
134
+ to: string;
135
+ frozen_set: FrozenCandidateSet;
136
+ /** `null` is the case step 4.7 names: an evaluator change with no cross-grade. */
137
+ cross_grade: CrossGrade | null;
138
+ /** Discrimination plants. Evaluator promotion requires them, per step 4.7. */
139
+ plants: readonly PlantOutcome[];
140
+ }
141
+
142
+ export class EvaluatorPromotionRefused extends Error {
143
+ readonly reasons: readonly string[];
144
+ constructor(reasons: readonly string[]) {
145
+ super(`evaluator promotion refused: ${reasons.join('; ')}`);
146
+ this.name = 'EvaluatorPromotionRefused';
147
+ this.reasons = reasons;
148
+ }
149
+ }
150
+
151
+ function missing(required: readonly string[], graded: readonly string[]): string[] {
152
+ const seen = new Set(graded);
153
+ return required.filter((id) => !seen.has(id));
154
+ }
155
+
156
+ /**
157
+ * Throw {@link EvaluatorPromotionRefused} unless every condition holds.
158
+ *
159
+ * Fail-closed by construction: the function has no permissive path and no
160
+ * option object that could relax one. A caller who wants to promote an
161
+ * evaluator without a cross-grade has to delete this call, which is visible in
162
+ * a diff, rather than pass a flag, which is not.
163
+ */
164
+ export function assertEvaluatorPromotable(change: EvaluatorChange): void {
165
+ const reasons: string[] = [];
166
+ const cg = change.cross_grade;
167
+
168
+ if (cg === null) {
169
+ reasons.push(
170
+ `no cross-grade between '${change.from}' and '${change.to}' — an evaluator change ` +
171
+ 'without one has no evidence that the two agree on anything',
172
+ );
173
+ } else {
174
+ if (cg.frozen_set_id !== change.frozen_set.id) {
175
+ reasons.push(
176
+ `the cross-grade names frozen set '${cg.frozen_set_id}' but the change is over ` +
177
+ `'${change.frozen_set.id}'`,
178
+ );
179
+ }
180
+ if (cg.from_evaluator !== change.from || cg.to_evaluator !== change.to) {
181
+ reasons.push(
182
+ `the cross-grade is between '${cg.from_evaluator}' and '${cg.to_evaluator}', ` +
183
+ `not between '${change.from}' and '${change.to}'`,
184
+ );
185
+ }
186
+ const missFrom = missing(change.frozen_set.candidate_ids, cg.graded_by_from);
187
+ const missTo = missing(change.frozen_set.candidate_ids, cg.graded_by_to);
188
+ if (missFrom.length > 0) {
189
+ reasons.push(`'${change.from}' did not grade: ${missFrom.join(', ')}`);
190
+ }
191
+ if (missTo.length > 0) {
192
+ reasons.push(`'${change.to}' did not grade: ${missTo.join(', ')}`);
193
+ }
194
+ if (!cg.order_swapped) {
195
+ reasons.push('the cross-grade did not declare the order-swap, so a position bias is unexcluded');
196
+ }
197
+ const audit = auditAssertions(cg.assertions);
198
+ const alwaysPass = audit.findings.filter((f) => f.verdict === 'non-discriminating-always-pass');
199
+ if (alwaysPass.length > 0) {
200
+ reasons.push(
201
+ `${String(alwaysPass.length)} assertion(s) pass in both arms and narrow nothing: ` +
202
+ alwaysPass.map((f) => f.id).join(', '),
203
+ );
204
+ }
205
+ }
206
+
207
+ if (change.plants.length === 0) {
208
+ reasons.push('evaluator promotion requires discrimination plants and this change carries none');
209
+ } else {
210
+ const report = reportPlants(change.plants);
211
+ if (report.set_deficit !== null) {
212
+ reasons.push(`plants cannot discriminate: ${report.set_deficit}`);
213
+ }
214
+ if (report.discrimination_deficits.length > 0) {
215
+ reasons.push(
216
+ `${String(report.discrimination_deficits.length)} plant(s) were also satisfied by the control arm: ` +
217
+ report.discrimination_deficits.map((d) => d.id).join(', '),
218
+ );
219
+ }
220
+ }
221
+
222
+ if (reasons.length > 0) {
223
+ throw new EvaluatorPromotionRefused(reasons);
224
+ }
225
+ }
@@ -0,0 +1,118 @@
1
+ /**
2
+ * One evidence-basis vocabulary (`road-to-delivered-cost-truth` step 4.1).
3
+ *
4
+ * Every number this suite reports rests on something, and until now the tree
5
+ * said what on at least three incompatible partial scales:
6
+ *
7
+ * `_lib/orchestration_record.ts` `'measured' | 'estimated'`
8
+ * `preamble_byte_census.ts` `'measured_local_file' | 'residual'`
9
+ * `_lib/value_ladder.ts` `'measured' | 'estimated' | 'vendor-claim' | 'pending' | 'available'`
10
+ *
11
+ * They overlap, disagree on naming for the same idea, and none of them can
12
+ * express "a model judged this" — which several surfaces in this tree do report.
13
+ * This module is the reconciliation, and it is deliberately NOT a fourth
14
+ * vocabulary sitting beside the three: the migration of the first two ships in
15
+ * the same change, and the third is documented as an unmigrated variant with the
16
+ * reason, rather than left looking like an oversight.
17
+ *
18
+ * WHAT EACH VALUE RESTS ON — one sentence, which is the whole contract:
19
+ *
20
+ * measured an instrument in this repository produced it from real input
21
+ * estimated derived by arithmetic from measured values, not itself observed
22
+ * inferred concluded from structure or convention, with no measurement behind it
23
+ * provider-reported a third party stated it and we recorded it unverified
24
+ * model-judged a language model's assessment, reproducible only in distribution
25
+ * unknown nothing establishes it, and that is the honest answer
26
+ *
27
+ * `unknown` is a first-class value, not a failure code. A surface that cannot
28
+ * establish a basis says `unknown`; it does not pick the nearest optimistic one.
29
+ */
30
+
31
+ export const EVIDENCE_BASES = [
32
+ 'measured',
33
+ 'estimated',
34
+ 'inferred',
35
+ 'provider-reported',
36
+ 'model-judged',
37
+ 'unknown',
38
+ ] as const;
39
+ export type EvidenceBasis = (typeof EVIDENCE_BASES)[number];
40
+
41
+ /** What each value rests on. Printed verbatim by surfaces that explain themselves. */
42
+ export const EVIDENCE_BASIS_MEANING: Record<EvidenceBasis, string> = {
43
+ measured: 'an instrument in this repository produced it from real input',
44
+ estimated: 'derived by arithmetic from measured values, not itself observed',
45
+ inferred: 'concluded from structure or convention, with no measurement behind it',
46
+ 'provider-reported': 'a third party stated it and we recorded it unverified',
47
+ 'model-judged': "a language model's assessment, reproducible only in distribution",
48
+ unknown: 'nothing establishes it, and that is the honest answer',
49
+ };
50
+
51
+ export function isEvidenceBasis(v: unknown): v is EvidenceBasis {
52
+ return typeof v === 'string' && (EVIDENCE_BASES as readonly string[]).includes(v);
53
+ }
54
+
55
+ /**
56
+ * Ordering by how much a reader may lean on the value.
57
+ *
58
+ * Used for reporting, never for arithmetic: two figures on different bases do
59
+ * not become comparable by being ranked, and nothing here should be read as
60
+ * licence to average them.
61
+ */
62
+ export const EVIDENCE_BASIS_STRENGTH: Record<EvidenceBasis, number> = {
63
+ measured: 5,
64
+ estimated: 4,
65
+ 'provider-reported': 3,
66
+ inferred: 2,
67
+ 'model-judged': 1,
68
+ unknown: 0,
69
+ };
70
+
71
+ /** The weakest basis in a set — what a derived figure may honestly claim. */
72
+ export function weakestBasis(bases: readonly EvidenceBasis[]): EvidenceBasis {
73
+ if (bases.length === 0) return 'unknown';
74
+ return bases.reduce((a, b) => (EVIDENCE_BASIS_STRENGTH[b] < EVIDENCE_BASIS_STRENGTH[a] ? b : a));
75
+ }
76
+
77
+ // ---------------------------------------------------------------------------
78
+ // Basis TAGS — a basis plus, where the basis is `estimated`, its method
79
+ // ---------------------------------------------------------------------------
80
+
81
+ /**
82
+ * `estimated` on its own is not a basis, it is a category.
83
+ *
84
+ * Two figures both marked `estimated` can differ by an order of magnitude in
85
+ * how much they should be trusted — one derived by arithmetic from measured
86
+ * inputs, one from a response-length heuristic — and a report that renders them
87
+ * identically has told the reader nothing they can act on. So wherever a figure
88
+ * is estimated, the METHOD travels with it.
89
+ *
90
+ * Every other basis is self-describing and takes no suffix: `measured` names
91
+ * the instrument by existing, `unknown` has no method by definition, and
92
+ * `model-judged` and `provider-reported` name their source in the value itself.
93
+ *
94
+ * road-to-experience-loop-broadening step 6.2.
95
+ */
96
+ export type BasisTag = Exclude<EvidenceBasis, 'estimated'> | `estimated:${string}`;
97
+
98
+ /**
99
+ * A bare `estimated` is REJECTED, and that is the whole point of the type.
100
+ * `estimated:` with nothing after it is rejected too — an empty method is the
101
+ * same omission wearing a colon.
102
+ */
103
+ export function isBasisTag(v: unknown): v is BasisTag {
104
+ if (typeof v !== 'string') return false;
105
+ if (v === 'estimated') return false;
106
+ if (v.startsWith('estimated:')) return v.slice('estimated:'.length).trim().length > 0;
107
+ return isEvidenceBasis(v);
108
+ }
109
+
110
+ /** The basis half of a tag, for grouping and for rendering the meaning table. */
111
+ export function basisOf(tag: BasisTag): EvidenceBasis {
112
+ return tag.startsWith('estimated:') ? 'estimated' : (tag as EvidenceBasis);
113
+ }
114
+
115
+ /** The method half, or `null` for every non-estimated basis. */
116
+ export function methodOf(tag: BasisTag): string | null {
117
+ return tag.startsWith('estimated:') ? tag.slice('estimated:'.length) : null;
118
+ }
@@ -60,6 +60,14 @@ export const ALLOWLIST_PREFIXES: readonly (readonly string[])[] = [
60
60
  // report exists. Read-only, deterministic, model-free, and already run in
61
61
  // CI (`rule-backstops.yml`) for its own reasons.
62
62
  ['check_enforcement_denominator'],
63
+ // road-to-source-silence Phase 5.3. The source-confidentiality gate's exit
64
+ // code IS the verdict for `claim:plaintext-source-attribution`: 0 means zero
65
+ // deny-pattern matches in tracked content AND in every tracked path, plus the
66
+ // attribution-shape block count at or below its ratchet baseline. An
67
+ // existence-check pointer would have gone stale the first time somebody added
68
+ // a name. Read-only, deterministic, model-free, and already run in CI for its
69
+ // own reasons — the same class as its neighbours here.
70
+ ['check_no_external_sources'],
63
71
  ['check_token_regression'],
64
72
  ['lint_agent_security'],
65
73
  ['measure_lexical_ranking'],