@event4u/agent-config 14.12.0 → 14.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (521) hide show
  1. package/.augment-plugin/marketplace.json +3 -3
  2. package/.augment-plugin/plugin.json +1 -1
  3. package/.claude-plugin/marketplace.json +1 -1
  4. package/CHANGELOG.md +118 -155
  5. package/CONTRIBUTING.md +38 -0
  6. package/CREDITS.md +135 -0
  7. package/NOTICE +13 -0
  8. package/README.md +8 -6
  9. package/dist/agent-src/commands/analyze/inbox.md +145 -2
  10. package/dist/agent-src/commands/feature/dev.md +7 -2
  11. package/dist/agent-src/commands/ghostwriter/write.md +5 -1
  12. package/dist/agent-src/commands/implement-ticket.md +1 -1
  13. package/dist/agent-src/commands/mission/upgrade.md +1 -1
  14. package/dist/agent-src/commands/orchestrate.md +2 -2
  15. package/dist/agent-src/commands/post-as/me.md +5 -1
  16. package/dist/agent-src/commands/pr/merge.md +19 -6
  17. package/dist/agent-src/commands/roadmap/process-full.md +19 -5
  18. package/dist/agent-src/commands/tdd/red.md +12 -2
  19. package/dist/agent-src/commands/work.md +1 -1
  20. package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +40 -0
  21. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +5 -2
  22. package/dist/agent-src/contexts/execution/autonomy-mechanics.md +21 -0
  23. package/dist/agent-src/contexts/execution/orchestration-telemetry.md +1 -0
  24. package/dist/agent-src/contexts/execution/subagent-response-contract.md +40 -0
  25. package/dist/agent-src/contexts/execution/subagent-steering.md +13 -1
  26. package/dist/agent-src/contexts/execution/terminal-states.md +96 -0
  27. package/dist/agent-src/rules/artifact-drafting-protocol.md +1 -1
  28. package/dist/agent-src/rules/broken-access-control.md +4 -0
  29. package/dist/agent-src/rules/code-comment-discipline.md +6 -0
  30. package/dist/agent-src/rules/code-provenance.md +4 -0
  31. package/dist/agent-src/rules/design-fidelity.md +1 -1
  32. package/dist/agent-src/rules/domain-safety-pii.md +4 -0
  33. package/dist/agent-src/rules/domain-safety-retention.md +4 -0
  34. package/dist/agent-src/rules/engineering-safety-floor.md +2 -0
  35. package/dist/agent-src/rules/external-code-graph-interop.md +14 -12
  36. package/dist/agent-src/rules/improve-before-implement.md +6 -8
  37. package/dist/agent-src/rules/laravel-routing.md +1 -1
  38. package/dist/agent-src/rules/lethal-trifecta-guard.md +4 -0
  39. package/dist/agent-src/rules/secret-vcs-guard.md +2 -0
  40. package/dist/agent-src/rules/security-sensitive-stop.md +2 -0
  41. package/dist/agent-src/rules/source-confidentiality.md +12 -34
  42. package/dist/agent-src/rules/symfony-routing.md +1 -1
  43. package/dist/agent-src/rules/token-efficiency.md +14 -0
  44. package/dist/agent-src/rules/tool-safety.md +4 -0
  45. package/dist/agent-src/rules/untrusted-input-defense.md +4 -0
  46. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +252 -8
  47. package/dist/agent-src/scripts/guarded_baseline.ts +343 -0
  48. package/dist/agent-src/scripts/roadmap_set_step.ts +253 -0
  49. package/dist/agent-src/scripts/stub_queue.ts +82 -0
  50. package/dist/agent-src/scripts/stubs_due.ts +516 -0
  51. package/dist/agent-src/scripts/ticket_bundles.ts +84 -0
  52. package/dist/agent-src/scripts/update_roadmap_progress.ts +16 -12
  53. package/dist/agent-src/skills/brand-asset-generation/SKILL.md +17 -4
  54. package/dist/agent-src/skills/brand-audit/SKILL.md +33 -0
  55. package/dist/agent-src/skills/code-intelligence/SKILL.md +57 -0
  56. package/dist/agent-src/skills/database/SKILL.md +8 -0
  57. package/dist/agent-src/skills/dependency-upgrade/SKILL.md +27 -0
  58. package/dist/agent-src/skills/design-review/SKILL.md +1 -1
  59. package/dist/agent-src/skills/doc-coauthoring/SKILL.md +1 -1
  60. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +17 -1
  61. package/dist/agent-src/skills/feature-planning/SKILL.md +9 -2
  62. package/dist/agent-src/skills/frontend-render-security/SKILL.md +44 -0
  63. package/dist/agent-src/skills/git-workflow/SKILL.md +1 -1
  64. package/dist/agent-src/skills/js-library-packaging/scripts/check_package_surface.ts +38 -4
  65. package/dist/agent-src/skills/judge-artifact-completeness/rubrics/ticket-quality-score.json +2 -2
  66. package/dist/agent-src/skills/laravel/SKILL.md +35 -0
  67. package/dist/agent-src/skills/laravel-migration/SKILL.md +57 -3
  68. package/dist/agent-src/skills/monorepo-workspace/SKILL.md +26 -0
  69. package/dist/agent-src/skills/playbook-authoring/SKILL.md +28 -1
  70. package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +1 -1
  71. package/dist/agent-src/skills/skill-writing/references/procedure.md +5 -5
  72. package/dist/agent-src/skills/sql-writing/SKILL.md +7 -1
  73. package/dist/agent-src/skills/standards-from-config/SKILL.md +27 -4
  74. package/dist/agent-src/skills/supply-chain-intake/SKILL.md +11 -4
  75. package/dist/agent-src/skills/symfony-workflow/SKILL.md +35 -0
  76. package/dist/agent-src/skills/test-case-discovery/SKILL.md +85 -0
  77. package/dist/agent-src/skills/test-driven-development/SKILL.md +33 -9
  78. package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
  79. package/dist/agent-src/skills/testing-anti-patterns/process-anti-patterns.md +37 -0
  80. package/dist/agent-src/skills/ui-component-architect/SKILL.md +45 -2
  81. package/dist/agent-src/skills/upstream-contribute/SKILL.md +38 -1
  82. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +9 -4
  83. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  84. package/dist/agent-src/templates/roadmaps.md +97 -3
  85. package/dist/agent-src/templates/scripts/check_memory.ts +258 -17
  86. package/dist/agent-src/templates/scripts/check_memory_proposal.ts +9 -3
  87. package/dist/agent-src/templates/scripts/memory_lookup.ts +86 -0
  88. package/dist/agent-src/templates/scripts/memory_signal.ts +44 -0
  89. package/dist/agent-src/templates/scripts/work_engine/directives/backend/implement.ts +90 -0
  90. package/dist/agent-src/templates/scripts/work_engine/directives/backend/index.ts +11 -0
  91. package/dist/agent-src/templates/scripts/work_engine/directives/backend/test.ts +23 -1
  92. package/dist/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +10 -1
  93. package/dist/agent-src/templates/scripts/work_engine/directives/mixed/stitch.ts +5 -1
  94. package/dist/agent-src/templates/scripts/work_engine/stack/runner.ts +102 -14
  95. package/dist/cli/commands/uiAudit.js +124 -5
  96. package/dist/cli/registry.js +2 -0
  97. package/dist/cli-delegate/{chunk-HYWSRNUX.js → chunk-2DK2VJWG.js} +3 -3
  98. package/dist/cli-delegate/{chunk-JCW7ZLHK.js → chunk-4FS4WRXP.js} +5 -0
  99. package/dist/cli-delegate/{chunk-OMIVVCG2.js → chunk-A4QJ6ENT.js} +24 -0
  100. package/dist/cli-delegate/{chunk-JJA2QEWA.js → chunk-AKJGUQNO.js} +466 -285
  101. package/dist/cli-delegate/{chunk-E46KPN6K.js → chunk-BTWUYDGN.js} +424 -363
  102. package/dist/cli-delegate/{chunk-K4FFODTS.js → chunk-ILMUPLGW.js} +1227 -316
  103. package/dist/cli-delegate/{chunk-FF7WAFMR.js → chunk-KPBWFOPZ.js} +5 -1
  104. package/dist/cli-delegate/cmd_adr_effective.js +102 -0
  105. package/dist/cli-delegate/cmd_conformance.js +80 -11
  106. package/dist/cli-delegate/cmd_doctor.js +3 -3
  107. package/dist/cli-delegate/cmd_export.js +3 -2
  108. package/dist/cli-delegate/cmd_fleet.js +2 -2
  109. package/dist/cli-delegate/cmd_handoff.js +1 -1
  110. package/dist/cli-delegate/cmd_preflight.js +2 -2
  111. package/dist/cli-delegate/cmd_prune.js +3 -2
  112. package/dist/cli-delegate/cmd_settings_get.js +1 -1
  113. package/dist/cli-delegate/cmd_settings_migrate.js +3 -2
  114. package/dist/cli-delegate/cmd_settings_set.js +2 -2
  115. package/dist/cli-delegate/cmd_sync.js +3 -2
  116. package/dist/cli-delegate/cmd_uninstall.js +3 -2
  117. package/dist/cli-delegate/cmd_validate.js +3 -2
  118. package/dist/discovery/deprecation-report.md +1 -1
  119. package/dist/discovery/discovery-manifest.json +58 -58
  120. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  121. package/dist/discovery/discovery-manifest.summary.md +1 -1
  122. package/dist/discovery/dormancy-report.md +1 -1
  123. package/dist/discovery/orphan-report.md +1 -1
  124. package/dist/discovery/packs.json +2 -2
  125. package/dist/discovery/trust-report.md +1 -1
  126. package/dist/discovery/workspaces.json +2 -2
  127. package/dist/hooks/dispatch.js +2900 -1049
  128. package/dist/install/claudeRuleRewrite.js +254 -0
  129. package/dist/install/detect.js +29 -16
  130. package/dist/install/detect_php_shape.js +159 -0
  131. package/dist/install/install.mjs +634 -428
  132. package/dist/mcp/awesome-mcp-servers.row.md +1 -1
  133. package/dist/mcp/mcp-cloudflare-catalogue.json +1 -1
  134. package/dist/mcp/registry-manifest.json +3 -3
  135. package/dist/mcp/server.json +3 -3
  136. package/dist/mcp/server.mjs +4895 -2627
  137. package/dist/server/schemas/settings.js +3 -0
  138. package/dist/ui/assets/index-D0jaCRPM.js +29 -0
  139. package/dist/ui/index.html +1 -1
  140. package/docs/MIGRATION.md +1 -1
  141. package/docs/THIRD-PARTY-NOTICES.md +25 -0
  142. package/docs/contracts/provider-lifecycle.md +1 -1
  143. package/docs/contracts/settings-classes.md +10 -4
  144. package/docs/guidelines/agent-infra/5w2h-analysis.md +3 -3
  145. package/docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md +1 -0
  146. package/docs/guidelines/agent-infra/artifact-drafting-protocol-mechanics.md +58 -3
  147. package/docs/guidelines/agent-infra/ask-when-uncertain-demos.md +2 -2
  148. package/docs/guidelines/agent-infra/asking-and-brevity-examples.md +3 -3
  149. package/docs/guidelines/agent-infra/break-glass-usage.md +7 -7
  150. package/docs/guidelines/agent-infra/carve-out-predicates.md +3 -3
  151. package/docs/guidelines/agent-infra/comparison-matrix.md +1 -1
  152. package/docs/guidelines/agent-infra/critical-thinking.md +4 -4
  153. package/docs/guidelines/agent-infra/direct-answers-demos.md +2 -2
  154. package/docs/guidelines/agent-infra/domain-eval-anti-pattern.md +1 -1
  155. package/docs/guidelines/agent-infra/engineering-memory-data-format.md +3 -3
  156. package/docs/guidelines/agent-infra/existence-question-verdicts.md +80 -0
  157. package/docs/guidelines/agent-infra/first-principles.md +2 -2
  158. package/docs/guidelines/agent-infra/framework-neutrality-patterns.md +2 -2
  159. package/docs/guidelines/agent-infra/guarded-baseline.md +39 -0
  160. package/docs/guidelines/agent-infra/inversion-thinking.md +5 -5
  161. package/docs/guidelines/agent-infra/language-and-tone-examples.md +1 -1
  162. package/docs/guidelines/agent-infra/layered-settings.md +10 -10
  163. package/docs/guidelines/agent-infra/memory-access.md +1 -1
  164. package/docs/guidelines/agent-infra/mental-models.md +3 -3
  165. package/docs/guidelines/agent-infra/reuse-verdict-mechanics.md +71 -0
  166. package/docs/guidelines/agent-infra/review-routing-data-format.md +7 -7
  167. package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +13 -7
  168. package/docs/guidelines/agent-infra/role-contracts.md +2 -2
  169. package/docs/guidelines/agent-infra/role-mode-router.md +3 -3
  170. package/docs/guidelines/agent-infra/rule-type-governance.md +2 -2
  171. package/docs/guidelines/agent-infra/scqa-framework.md +5 -5
  172. package/docs/guidelines/agent-infra/self-improvement-pipeline.md +6 -6
  173. package/docs/guidelines/agent-infra/simplicity-and-goal-demos.md +2 -2
  174. package/docs/guidelines/agent-infra/six-hats.md +3 -3
  175. package/docs/guidelines/agent-infra/skill-quality-checklist.md +6 -6
  176. package/docs/guidelines/agent-infra/source-confidentiality-mechanics.md +109 -0
  177. package/docs/guidelines/agent-infra/systems-thinking.md +1 -1
  178. package/docs/guidelines/agent-infra/verify-before-complete-demos.md +2 -2
  179. package/docs/guidelines/augment-portability-patterns.md +6 -4
  180. package/docs/guidelines/code-clarity.md +18 -0
  181. package/docs/guidelines/component-oriented-and-oop-development.md +3 -2
  182. package/docs/guidelines/cross-role-handoff.md +2 -2
  183. package/docs/guidelines/design-fidelity-mechanics.md +1 -1
  184. package/docs/guidelines/docs/readme-size-and-splitting.md +3 -3
  185. package/docs/guidelines/php/database.md +90 -7
  186. package/docs/guidelines/prompt-templates.md +7 -7
  187. package/llms.txt +2 -2
  188. package/package.json +5 -2
  189. package/src/agent-src/scripts/archive_completed_roadmaps.ts +252 -8
  190. package/src/agent-src/scripts/guarded_baseline.ts +343 -0
  191. package/src/agent-src/scripts/roadmap_set_step.ts +253 -0
  192. package/src/agent-src/scripts/stub_queue.ts +82 -0
  193. package/src/agent-src/scripts/stubs_due.ts +516 -0
  194. package/src/agent-src/scripts/ticket_bundles.ts +84 -0
  195. package/src/agent-src/scripts/update_roadmap_progress.ts +16 -12
  196. package/src/agent-src/templates/scripts/check_memory.ts +258 -17
  197. package/src/agent-src/templates/scripts/check_memory_proposal.ts +9 -3
  198. package/src/agent-src/templates/scripts/memory_lookup.ts +86 -0
  199. package/src/agent-src/templates/scripts/memory_signal.ts +44 -0
  200. package/src/agent-src/templates/scripts/work_engine/directives/backend/implement.ts +90 -0
  201. package/src/agent-src/templates/scripts/work_engine/directives/backend/index.ts +11 -0
  202. package/src/agent-src/templates/scripts/work_engine/directives/backend/test.ts +23 -1
  203. package/src/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +10 -1
  204. package/src/agent-src/templates/scripts/work_engine/directives/mixed/stitch.ts +5 -1
  205. package/src/agent-src/templates/scripts/work_engine/stack/runner.ts +102 -14
  206. package/src/config/agent-settings.template.yml +32 -3
  207. package/src/config/assurance-capability-registry.json +21 -9
  208. package/src/config/canonical-terms.yml +119 -0
  209. package/src/config/capability-native-outcome-bars.json +81 -0
  210. package/src/config/ci-local-parity.yml +80 -0
  211. package/src/config/drafting-channels.yml +43 -0
  212. package/src/config/estate-count-budget.json +57 -36
  213. package/src/config/evaluator-budgets.json +14 -14
  214. package/src/config/gate-coverage.yml +729 -63
  215. package/src/config/gate-reachability-exemptions.json +21 -0
  216. package/src/config/gate-violation-baselines.json +42 -19
  217. package/src/config/harness-evolution-budget.json +25 -0
  218. package/src/config/lapsed-beta-baseline.json +96 -0
  219. package/src/config/memory-twin-verdicts.yml +129 -0
  220. package/src/config/metric-registry.yml +124 -0
  221. package/src/config/pack-size-budget.json +16 -15
  222. package/src/config/preamble-payload-budget.json +12 -4
  223. package/src/config/profiles/balanced.ini +27 -0
  224. package/src/config/profiles/full.ini +27 -0
  225. package/src/config/profiles/minimal.ini +27 -0
  226. package/src/config/publish-surface.json +9 -2
  227. package/src/config/routing-coverage-seed.json +16 -2
  228. package/src/config/rule-stub-ceilings.json +133 -112
  229. package/src/config/turnaround-budget.json +66 -0
  230. package/src/install/claudeRuleRewrite.ts +288 -0
  231. package/src/install/detect.ts +60 -17
  232. package/src/install/detect_php_shape.ts +191 -0
  233. package/src/scripts/_cli/cmd_doctor.ts +27 -112
  234. package/src/scripts/_dispatch.bash +23 -0
  235. package/src/scripts/_lib/activation_ladder.ts +255 -0
  236. package/src/scripts/_lib/activation_receipt_producer.ts +341 -0
  237. package/src/scripts/_lib/activation_states.ts +88 -0
  238. package/src/scripts/_lib/adherence_detectors.ts +143 -0
  239. package/src/scripts/_lib/adr_frontmatter.ts +26 -0
  240. package/src/scripts/_lib/arith_claims.ts +181 -0
  241. package/src/scripts/_lib/arm_ranking.ts +62 -0
  242. package/src/scripts/_lib/asset_delivery_ledger.ts +303 -0
  243. package/src/scripts/_lib/audit_field_provenance.ts +54 -0
  244. package/src/scripts/_lib/auto_dispatch.ts +32 -3
  245. package/src/scripts/_lib/bench_ab_size_claim.ts +98 -4
  246. package/src/scripts/_lib/benchmark_cache_fields.ts +158 -0
  247. package/src/scripts/_lib/candidate_pair_delta.ts +349 -0
  248. package/src/scripts/_lib/candidate_proposer.ts +402 -0
  249. package/src/scripts/_lib/candidate_record.ts +601 -0
  250. package/src/scripts/_lib/capture_rate.ts +319 -0
  251. package/src/scripts/_lib/carrier_status.ts +118 -0
  252. package/src/scripts/_lib/cascade_stage_enumeration.ts +92 -0
  253. package/src/scripts/_lib/collector_denominator.ts +771 -0
  254. package/src/scripts/_lib/collector_record.ts +340 -0
  255. package/src/scripts/_lib/collector_store.ts +664 -0
  256. package/src/scripts/_lib/collector_supervision.ts +827 -0
  257. package/src/scripts/_lib/concern_estate.ts +77 -0
  258. package/src/scripts/_lib/config_chain.ts +477 -0
  259. package/src/scripts/_lib/config_cost.ts +209 -0
  260. package/src/scripts/_lib/corpus_manifest.ts +726 -0
  261. package/src/scripts/_lib/council_settings_block.ts +6 -0
  262. package/src/scripts/_lib/curator_ops.ts +172 -0
  263. package/src/scripts/_lib/delivery_arm_experiment.ts +282 -0
  264. package/src/scripts/_lib/delivery_criticality.ts +126 -0
  265. package/src/scripts/_lib/doctor_runtime_checks.ts +70 -0
  266. package/src/scripts/_lib/empty_cycles.ts +88 -0
  267. package/src/scripts/_lib/estate_carrier_cases.ts +72 -0
  268. package/src/scripts/_lib/eval_publication.ts +354 -0
  269. package/src/scripts/_lib/evaluation_cascade.ts +452 -0
  270. package/src/scripts/_lib/evaluation_vector.ts +283 -0
  271. package/src/scripts/_lib/evaluator_promotion.ts +225 -0
  272. package/src/scripts/_lib/evidence_basis.ts +118 -0
  273. package/src/scripts/_lib/evolution_roi.ts +562 -0
  274. package/src/scripts/_lib/exec_evidence.ts +8 -0
  275. package/src/scripts/_lib/experience_card.ts +272 -0
  276. package/src/scripts/_lib/experience_report.ts +151 -0
  277. package/src/scripts/_lib/experiment_freeze.ts +112 -0
  278. package/src/scripts/_lib/generated_by.ts +66 -0
  279. package/src/scripts/_lib/harness_evolution_guards.ts +239 -0
  280. package/src/scripts/_lib/hook_effect_probe.ts +141 -0
  281. package/src/scripts/_lib/host_denominator.ts +687 -0
  282. package/src/scripts/_lib/host_projection_reach.ts +157 -0
  283. package/src/scripts/_lib/ignored_blocker.ts +148 -0
  284. package/src/scripts/_lib/install_reach_checks.ts +495 -0
  285. package/src/scripts/_lib/json_duplicate_keys.ts +150 -0
  286. package/src/scripts/_lib/judge_hygiene.ts +228 -0
  287. package/src/scripts/_lib/legacy_boundary_map.ts +228 -0
  288. package/src/scripts/_lib/lexical_shortlist.ts +215 -0
  289. package/src/scripts/_lib/llm_candidate_proposer.ts +461 -0
  290. package/src/scripts/_lib/llm_proposer_transport.ts +153 -0
  291. package/src/scripts/_lib/loop_guards.ts +299 -0
  292. package/src/scripts/_lib/loss_class.ts +129 -0
  293. package/src/scripts/_lib/machine_wake.ts +51 -0
  294. package/src/scripts/_lib/md_prose_lines.ts +177 -0
  295. package/src/scripts/_lib/minimality_tiebreak.ts +168 -0
  296. package/src/scripts/_lib/one_resolver_invariant.ts +449 -0
  297. package/src/scripts/_lib/orchestration_record.ts +253 -5
  298. package/src/scripts/_lib/outcome_envelope.ts +227 -0
  299. package/src/scripts/_lib/outcome_vocabularies.ts +125 -0
  300. package/src/scripts/_lib/paired_stats.ts +245 -0
  301. package/src/scripts/_lib/paired_verdict.ts +226 -0
  302. package/src/scripts/_lib/pathology_archive.ts +393 -0
  303. package/src/scripts/_lib/prefix_stable_surfaces.ts +123 -0
  304. package/src/scripts/_lib/privacy_class.ts +47 -0
  305. package/src/scripts/_lib/promotion_capability.ts +315 -0
  306. package/src/scripts/_lib/promotion_evidence.ts +414 -0
  307. package/src/scripts/_lib/promotion_review.ts +294 -0
  308. package/src/scripts/_lib/prompt_shape.ts +92 -0
  309. package/src/scripts/_lib/regression_neighbourhood.ts +259 -0
  310. package/src/scripts/_lib/release_highlights.ts +70 -1
  311. package/src/scripts/_lib/release_material.ts +125 -2
  312. package/src/scripts/_lib/repeated_failure.ts +105 -0
  313. package/src/scripts/_lib/repo_root.ts +111 -0
  314. package/src/scripts/_lib/review_skipped_record.ts +37 -0
  315. package/src/scripts/_lib/role_split.ts +338 -0
  316. package/src/scripts/_lib/routing_corpus.ts +307 -0
  317. package/src/scripts/_lib/routing_index_input.ts +104 -0
  318. package/src/scripts/_lib/rule_injection.ts +22 -1
  319. package/src/scripts/_lib/runtime_journal.ts +1499 -0
  320. package/src/scripts/_lib/runtime_wiring_checks.ts +430 -0
  321. package/src/scripts/_lib/semantic_noop.ts +167 -0
  322. package/src/scripts/_lib/skill_catalogue.ts +11 -1
  323. package/src/scripts/_lib/source_digest.ts +200 -0
  324. package/src/scripts/_lib/source_redact.ts +260 -0
  325. package/src/scripts/_lib/source_shape.ts +502 -0
  326. package/src/scripts/_lib/source_snapshot_dedup.ts +199 -0
  327. package/src/scripts/_lib/strip_comments.d.mts +8 -0
  328. package/src/scripts/_lib/strip_comments.mjs +65 -0
  329. package/src/scripts/_lib/test_red_state.ts +154 -0
  330. package/src/scripts/_lib/trigger_shift.ts +144 -0
  331. package/src/scripts/_lib/untrusted_content.ts +82 -7
  332. package/src/scripts/activation_receipt.ts +258 -0
  333. package/src/scripts/adoption_report.ts +1 -1
  334. package/src/scripts/adr/evidence_census.ts +1 -1
  335. package/src/scripts/adr/regenerate_index.ts +26 -2
  336. package/src/scripts/adr_cite_check.ts +164 -1
  337. package/src/scripts/ai_council/blind_review.ts +11 -1
  338. package/src/scripts/ai_council/clients.ts +4 -0
  339. package/src/scripts/ai_council/config.ts +3 -0
  340. package/src/scripts/ai_council/consensus.ts +28 -8
  341. package/src/scripts/ai_council/consensus_round.ts +226 -0
  342. package/src/scripts/ai_council/cross_exam.ts +128 -0
  343. package/src/scripts/ai_council/disagreement_signal.ts +338 -0
  344. package/src/scripts/ai_council/explain_route.ts +157 -0
  345. package/src/scripts/ai_council/information_gain.ts +293 -0
  346. package/src/scripts/ai_council/inline_findings.ts +340 -0
  347. package/src/scripts/ai_council/judge_position_bias.ts +197 -0
  348. package/src/scripts/ai_council/leakage_corpus.ts +385 -0
  349. package/src/scripts/ai_council/leakage_patterns.ts +453 -0
  350. package/src/scripts/ai_council/minority_retention.ts +171 -0
  351. package/src/scripts/ai_council/orchestrator.ts +16 -203
  352. package/src/scripts/ai_council/orchestrator_results.ts +23 -3
  353. package/src/scripts/ai_council/pricing.ts +106 -0
  354. package/src/scripts/ai_council/prompts.ts +74 -7
  355. package/src/scripts/ai_council/provider_leakage_bench.ts +327 -0
  356. package/src/scripts/ai_council/py_format.ts +14 -3
  357. package/src/scripts/ai_council/recouncil_guard.ts +293 -0
  358. package/src/scripts/ai_council/recouncil_savings.ts +299 -0
  359. package/src/scripts/ai_council/replay_route.ts +223 -0
  360. package/src/scripts/ai_council/response_record.ts +50 -0
  361. package/src/scripts/ai_council/reviewer_assignment.ts +279 -0
  362. package/src/scripts/ai_council/routing_training_row.ts +197 -0
  363. package/src/scripts/ai_council/synthesis_strategy.ts +159 -0
  364. package/src/scripts/ai_council/topology_bench_manifest.ts +860 -0
  365. package/src/scripts/ai_council/topology_vocabulary.ts +175 -0
  366. package/src/scripts/asset_delivery_ledger.ts +157 -0
  367. package/src/scripts/attest_artifact.ts +193 -0
  368. package/src/scripts/audit_auto_rules.ts +2 -1
  369. package/src/scripts/audit_command_surface.ts +1 -1
  370. package/src/scripts/audit_mcp_tools.ts +2 -2
  371. package/src/scripts/audit_skill_overlap_allowlist.json +6 -1
  372. package/src/scripts/audit_user_type_axis.ts +2 -1
  373. package/src/scripts/bench_ab_clone.ts +215 -10
  374. package/src/scripts/bench_ab_integrity.ts +119 -5
  375. package/src/scripts/bench_ab_v2_stats.ts +40 -213
  376. package/src/scripts/build_archive_index.ts +1 -1
  377. package/src/scripts/build_linear_digest.ts +1 -1
  378. package/src/scripts/build_proof.ts +11 -4
  379. package/src/scripts/build_rule_trigger_matrix.ts +1 -1
  380. package/src/scripts/build_source_digests.ts +157 -0
  381. package/src/scripts/cache_realization_report.ts +103 -0
  382. package/src/scripts/check_adr_frontmatter.ts +131 -10
  383. package/src/scripts/check_benchmark_report_fields.ts +207 -0
  384. package/src/scripts/check_beta_review_markers.ts +235 -6
  385. package/src/scripts/check_bundle_path_leakage.ts +34 -1
  386. package/src/scripts/check_claims.ts +576 -6
  387. package/src/scripts/check_composite_arming.ts +35 -0
  388. package/src/scripts/check_concern_admissions.ts +365 -0
  389. package/src/scripts/check_enforcement_coverage.ts +28 -0
  390. package/src/scripts/check_estate_count.ts +347 -25
  391. package/src/scripts/check_gate_reachability.ts +383 -0
  392. package/src/scripts/check_host_loadability.ts +104 -0
  393. package/src/scripts/check_loss_class_declared.ts +308 -0
  394. package/src/scripts/check_md_language.ts +15 -98
  395. package/src/scripts/check_memory_proposal.ts +18 -11
  396. package/src/scripts/check_no_currency_in_cost_surfaces.ts +225 -0
  397. package/src/scripts/check_no_external_sources.ts +281 -6
  398. package/src/scripts/check_pack_conformance_fixture.ts +11 -1
  399. package/src/scripts/check_pack_size.ts +59 -2
  400. package/src/scripts/check_preamble_payload_budget.ts +114 -3
  401. package/src/scripts/check_prefix_stable_mutation.ts +372 -0
  402. package/src/scripts/check_publish_surface.ts +10 -1
  403. package/src/scripts/check_references.ts +24 -1
  404. package/src/scripts/check_release_highlights.ts +96 -13
  405. package/src/scripts/check_roadmap_trackable.ts +17 -2
  406. package/src/scripts/check_rule_evidence_declaration.ts +316 -0
  407. package/src/scripts/check_rule_projection_integrity.ts +14 -4
  408. package/src/scripts/check_score_contract.ts +26 -3
  409. package/src/scripts/check_static_parity.ts +285 -0
  410. package/src/scripts/check_supervision_claim_atomicity.ts +498 -0
  411. package/src/scripts/check_suppression_hygiene.ts +15 -0
  412. package/src/scripts/ci_settle.ts +39 -2
  413. package/src/scripts/code_graph/build.ts +60 -3
  414. package/src/scripts/code_graph/extract.ts +44 -0
  415. package/src/scripts/code_graph/types.ts +24 -0
  416. package/src/scripts/collector_daemon.ts +714 -0
  417. package/src/scripts/config_cost_report.ts +302 -0
  418. package/src/scripts/consumer_matrix.ts +74 -1
  419. package/src/scripts/corpus_manifest.ts +235 -0
  420. package/src/scripts/cost/budget.mjs +10 -3
  421. package/src/scripts/cost/track.mjs +10 -3
  422. package/src/scripts/council_cli.ts +37 -54
  423. package/src/scripts/dispatch_r2_reviewer.ts +46 -5
  424. package/src/scripts/evolution_lab.ts +1153 -0
  425. package/src/scripts/external_sources_denylist.json +5 -18
  426. package/src/scripts/extract_audit_patterns.ts +21 -0
  427. package/src/scripts/fold_intake.ts +12 -1
  428. package/src/scripts/gen_discovery_baseline.ts +1 -1
  429. package/src/scripts/generate_capabilities_index.ts +12 -5
  430. package/src/scripts/generate_capability_matrix.ts +3 -3
  431. package/src/scripts/generate_command_flows.ts +2 -2
  432. package/src/scripts/generate_cookbook.ts +2 -2
  433. package/src/scripts/generate_index.ts +8 -1
  434. package/src/scripts/generate_knowledge_index.ts +2 -1
  435. package/src/scripts/generate_ownership_matrix.ts +2 -1
  436. package/src/scripts/generate_pack_manifests.ts +10 -2
  437. package/src/scripts/generate_role_experiences_catalog.ts +2 -2
  438. package/src/scripts/generate_settings_reference.ts +1 -1
  439. package/src/scripts/git_authorization_hook.ts +22 -1
  440. package/src/scripts/grade_target_readiness.ts +48 -5
  441. package/src/scripts/hook_effect_doctor.ts +261 -0
  442. package/src/scripts/hook_manifest.json +1 -1
  443. package/src/scripts/hook_manifest.yaml +125 -16
  444. package/src/scripts/hooks/block_speaking_inbox_dir.ts +271 -0
  445. package/src/scripts/hooks/block_unauthorized_git.ts +18 -0
  446. package/src/scripts/hooks/comment_discipline_hook.ts +146 -0
  447. package/src/scripts/hooks/concern_registry.ts +6 -0
  448. package/src/scripts/hooks/dispatch_hook.ts +32 -0
  449. package/src/scripts/hooks/journal_record_hook.ts +345 -0
  450. package/src/scripts/hooks/prepush_metadata_sources.sh +110 -0
  451. package/src/scripts/hooks/run_continuation_hook.ts +44 -9
  452. package/src/scripts/hooks/shims/install.sh +61 -0
  453. package/src/scripts/hooks/shims/php +101 -0
  454. package/src/scripts/hooks/suggestion_capture_hook.ts +10 -0
  455. package/src/scripts/hooks/turn_end_gate_hook.ts +9 -1
  456. package/src/scripts/hot_context_hook.ts +16 -0
  457. package/src/scripts/install-hooks.sh +20 -5
  458. package/src/scripts/install.ts +17 -35
  459. package/src/scripts/inventory_frontmatter.ts +2 -1
  460. package/src/scripts/language_mirror_hook.ts +14 -2
  461. package/src/scripts/lint_adr_sweep_routing.ts +12 -0
  462. package/src/scripts/lint_canonical_terms.ts +604 -0
  463. package/src/scripts/lint_carrier_integrity.ts +820 -0
  464. package/src/scripts/lint_code_comments.ts +643 -0
  465. package/src/scripts/lint_composition_review.ts +619 -0
  466. package/src/scripts/lint_consolidation_lineage.ts +666 -0
  467. package/src/scripts/lint_eval_specs.ts +593 -0
  468. package/src/scripts/lint_hook_manifest.ts +19 -0
  469. package/src/scripts/lint_host_portability.ts +373 -0
  470. package/src/scripts/lint_judge_prompt_expectation.ts +27 -1
  471. package/src/scripts/lint_memory_twin_parity.ts +335 -0
  472. package/src/scripts/lint_metric_consumers.ts +355 -0
  473. package/src/scripts/lint_plan_risk_register.ts +39 -19
  474. package/src/scripts/lint_promotion_paths.ts +779 -0
  475. package/src/scripts/lint_skill_descriptions.ts +18 -1
  476. package/src/scripts/lint_skill_frontmatter_safety.ts +58 -0
  477. package/src/scripts/lint_skill_link_reach.ts +252 -0
  478. package/src/scripts/lint_skill_trigger_corpus.ts +426 -23
  479. package/src/scripts/lint_ticket_buildable.ts +17 -1
  480. package/src/scripts/llm_propose.ts +256 -0
  481. package/src/scripts/mcp_server/consumer_tool_catalog.json +1 -1
  482. package/src/scripts/mcp_server/tool_catalog_source.ts +1 -1
  483. package/src/scripts/measure_delivery_sets.ts +361 -0
  484. package/src/scripts/measure_docs_dead_links.ts +348 -0
  485. package/src/scripts/measure_host_capture.ts +461 -0
  486. package/src/scripts/measure_routing_signal.ts +307 -0
  487. package/src/scripts/migration_status.ts +3 -3
  488. package/src/scripts/model_rule_injection.ts +76 -0
  489. package/src/scripts/orchestration_record.ts +14 -0
  490. package/src/scripts/preamble_byte_census.ts +139 -10
  491. package/src/scripts/prepack-check.mjs +4 -1
  492. package/src/scripts/probe_council_retention.ts +495 -0
  493. package/src/scripts/probe_turnaround.ts +384 -0
  494. package/src/scripts/probe_unblocked_ask.ts +279 -0
  495. package/src/scripts/release.ts +21 -37
  496. package/src/scripts/release_drill.ts +143 -0
  497. package/src/scripts/release_env.ts +35 -0
  498. package/src/scripts/release_publication.ts +84 -0
  499. package/src/scripts/render_benchmark_md.ts +1 -1
  500. package/src/scripts/rule_activation_census.ts +70 -9
  501. package/src/scripts/rule_backlinks.ts +1 -1
  502. package/src/scripts/run_lifecycle_suite.ts +208 -0
  503. package/src/scripts/run_skill_evals.ts +40 -0
  504. package/src/scripts/schemas/delivery-manifest.schema.json +43 -0
  505. package/src/scripts/schemas/drafting-channels.schema.json +43 -0
  506. package/src/scripts/schemas/evals.schema.json +24 -1
  507. package/src/scripts/schemas/rule.schema.json +52 -1
  508. package/src/scripts/schemas/skill.schema.json +17 -2
  509. package/src/scripts/skill_overlap.ts +7 -1
  510. package/src/scripts/skill_tools/run_block_d_eval.ts +8 -1
  511. package/src/scripts/skill_tools/score_skill_relevance.ts +84 -3
  512. package/src/scripts/skill_tools/suggest_skill_for_task.ts +8 -1
  513. package/src/scripts/skill_usage_report.ts +2 -1
  514. package/src/scripts/stubs_due.ts +211 -0
  515. package/src/scripts/sweep_source_surfaces.ts +678 -0
  516. package/src/scripts/sync_pr_branch.ts +3 -3
  517. package/src/scripts/trigger_eval_grandfather.json +202 -222
  518. package/src/scripts/utilization_report.ts +22 -2
  519. package/src/server/schemas/settings.ts +5 -0
  520. package/src/templates/marketing-copy.yml +1 -1
  521. package/dist/ui/assets/index-Cxgy63kz.js +0 -26
@@ -0,0 +1,453 @@
1
+ /**
2
+ * The version-pinned pattern list for the provider-recognition leakage bench's
3
+ * PATTERN-STRIPPED arm.
4
+ *
5
+ * `road-to-inbox-harvest-2026-08-e-council-topology-evidence`,
6
+ * `blocker: leakage-bench-needs-assembler-and-design-forks`, todo item 3.
7
+ *
8
+ * ── Why this file exists as its own change ──────────────────────────────────
9
+ * The AI council settled the anonymisation protocol on 2026-08-31 (Option C,
10
+ * two arms, 2/2 convergent) and its condition 1 requires the pattern list to be
11
+ * "pre-registered and version-pinned" before the stripped arm runs.
12
+ * `internal/bench/council-provider-leakage/PREREG-anonymisation-and-sampling.md`
13
+ * § Fork 3 DEFERRED the list on an explicit ground: writing it in the same
14
+ * change that settled the protocol "would put an unreviewed floor into the
15
+ * pre-registration under cover of the council's verdict". This module is that
16
+ * separate change. It carries the list, its replacement semantics, and the
17
+ * span-level transformation log condition 2 requires — and nothing else.
18
+ *
19
+ * ── What this module does NOT do ────────────────────────────────────────────
20
+ * It does NOT anonymise in any strong sense, and the label is load-bearing:
21
+ * condition 6 of the verdict says the second arm is called `pattern-stripped`
22
+ * and NEVER `identifier-free`. Regexes miss identifiers. `ARM_LABEL` is the
23
+ * only name this module will answer to, and `FORBIDDEN_ARM_LABELS` names the
24
+ * ones a caller may not substitute; a test asserts neither appears in the
25
+ * rendered output of anything here.
26
+ *
27
+ * It does NOT dispatch, prompt, score, or write. No `main()`, no transport, no
28
+ * filesystem access.
29
+ *
30
+ * ── The residue this design cannot remove, stated here rather than discovered ─
31
+ * Replacement is family-INVARIANT: every rule writes the same placeholder
32
+ * whatever family matched, so the placeholder text itself cannot tell a rater
33
+ * which provider wrote the body. What it cannot make invariant is the COUNT and
34
+ * the POSITION of the placeholders. A family that self-identifies four times
35
+ * and one that never does are distinguishable by `[REDACTED-…]` density alone,
36
+ * and that density is created by the stripping rather than removed by it.
37
+ *
38
+ * This is not a defect to fix here — suppressing it would mean equalising the
39
+ * marker count across families, which is a second transformation with its own
40
+ * distortion. It is a bound on what the arm may claim, and it belongs beside
41
+ * the claim limit both council seats insisted on: the RAW − STRIPPED delta
42
+ * estimates the effect of THESE registered transformations, never "label
43
+ * leakage" in general.
44
+ *
45
+ * ── Freeze semantics ────────────────────────────────────────────────────────
46
+ * Condition 1 makes the list a floor ONCE AN ARM HAS RUN; it does not forbid
47
+ * authoring it. No arm has run at the commit that lands this file
48
+ * (`collectGuesses` and `scoreRecognition` still have zero production callers),
49
+ * so the list is pinned-and-amendable today and frozen the moment the first
50
+ * rater call is made. `PATTERN_LIST_DIGEST` exists so that transition is
51
+ * observable: a test asserts the live list hashes to the recorded digest, so
52
+ * any edit — before or after the freeze — is a loud diff rather than a silent
53
+ * one.
54
+ */
55
+ import * as crypto from 'node:crypto';
56
+
57
+ /** The version id of this list. Bump on ANY change to `LEAKAGE_PATTERNS`. */
58
+ export const LEAKAGE_PATTERN_LIST_VERSION = 'leakage-patterns-v1-2026-08-31';
59
+
60
+ /**
61
+ * The only name the stripped arm may carry. Verdict condition 6: regexes miss
62
+ * identifiers, so a name promising their absence would overstate the result.
63
+ */
64
+ export const ARM_LABEL = 'pattern-stripped';
65
+
66
+ /** Names condition 6 forbids for the stripped arm. Asserted, not documented. */
67
+ export const FORBIDDEN_ARM_LABELS: readonly string[] = [
68
+ 'identifier-free',
69
+ 'anonymised',
70
+ 'anonymized',
71
+ 'de-identified',
72
+ 'deidentified',
73
+ ];
74
+
75
+ /**
76
+ * What a rule targets. The four categories are the verdict's own enumeration —
77
+ * "provider names, vendor names, model ids and first-person
78
+ * self-identification" — and the union is closed so a fifth cannot be added
79
+ * without a version bump.
80
+ */
81
+ export type PatternCategory =
82
+ | 'provider-name'
83
+ | 'vendor-name'
84
+ | 'model-id'
85
+ | 'first-person-self-identification';
86
+
87
+ /**
88
+ * The placeholder written in place of a match. ONE token per category, and the
89
+ * SAME token whatever family matched — see the residue note in the header.
90
+ */
91
+ export const CATEGORY_PLACEHOLDER: Readonly<Record<PatternCategory, string>> = {
92
+ 'provider-name': '[REDACTED-PROVIDER]',
93
+ 'vendor-name': '[REDACTED-VENDOR]',
94
+ 'model-id': '[REDACTED-MODEL]',
95
+ 'first-person-self-identification': '[REDACTED-SELF-ID]',
96
+ };
97
+
98
+ /**
99
+ * How likely this rule is to remove material that is NOT an identifier.
100
+ * Recorded per rule because the council's claim limit turns on exactly this:
101
+ * a rule that also removes stylistic material changes what the delta estimates.
102
+ */
103
+ export type FalsePositiveRisk = 'low' | 'moderate';
104
+
105
+ export interface PatternRule {
106
+ /** Stable id. Appears in the transformation log; never renumbered. */
107
+ readonly id: string;
108
+ readonly category: PatternCategory;
109
+ /** Why this token identifies a family. One clause, checkable by a reader. */
110
+ readonly rationale: string;
111
+ readonly falsePositiveRisk: FalsePositiveRisk;
112
+ /** Source of the pattern. Recompiled per call so lastIndex never leaks. */
113
+ readonly source: string;
114
+ /** Flags. Always contains `g` and `i`; asserted by a test. */
115
+ readonly flags: string;
116
+ }
117
+
118
+ /**
119
+ * The list.
120
+ *
121
+ * ── Two admission rules, applied to every candidate ─────────────────────────
122
+ * (1) A bare token that is also ordinary English is EXCLUDED, and excluded
123
+ * deliberately rather than forgotten: `meta`, `grok`, `bard`, `gemini` (a
124
+ * zodiac sign and a common noun in other registers) and `mistral` (a wind)
125
+ * all appear in prose that has nothing to do with a vendor. Stripping them
126
+ * unconditionally would delete ordinary sentences, and the deletions would
127
+ * not be family-uniform, so the arm would measure the regex rather than the
128
+ * style. Each is admitted ONLY inside an identifying context — a vendor
129
+ * possessive, a model-id shape, or a self-identification frame.
130
+ * (2) A token whose only role is to name a vendor or a model is admitted bare.
131
+ * `anthropic`, `openai`, `claude`, `chatgpt` and `codex` carry no ordinary
132
+ * English sense in this corpus's register.
133
+ *
134
+ * ── Order is part of the pinned artefact ───────────────────────────────────
135
+ * Three tiers, longest frame first, and the reason is span attribution rather
136
+ * than aesthetics: `applyLeakagePatterns` resolves overlap by FIRST-CLAIM-WINS
137
+ * in declaration order, so whichever tier is declared first decides both what
138
+ * is removed and which category the audit log attributes it to.
139
+ *
140
+ * 1. self-identification frames — "I am Claude", "trained by Anthropic".
141
+ * Declared first so the whole frame is one `[REDACTED-SELF-ID]` span. Put
142
+ * last, `product-claude` would claim `Claude` on its own, leaving a
143
+ * dangling "I am " and logging a `provider-name` removal where the thing
144
+ * actually removed was a self-identification.
145
+ * 2. model ids — `claude-sonnet-4-5`, `gpt-4o`. Ahead of the bare vendor
146
+ * tokens they contain, so the id is consumed whole rather than leaving
147
+ * `[REDACTED-PROVIDER]-sonnet-4-5` behind.
148
+ * 3. bare vendor and product tokens — the residue neither tier above framed.
149
+ *
150
+ * A test pins each tier boundary by asserting the span's `patternId`, not only
151
+ * the output text: two orderings can produce the same string and disagree about
152
+ * what the log says was removed, and the log is what condition 2 asks for.
153
+ */
154
+ export const LEAKAGE_PATTERNS: readonly PatternRule[] = [
155
+ // ── first-person self-identification, FIRST: longest frames ────────────
156
+ {
157
+ id: 'selfid-i-am-assistant',
158
+ category: 'first-person-self-identification',
159
+ rationale: 'Direct self-naming: "I am Claude", "I\u0027m ChatGPT", "This is Gemini".',
160
+ falsePositiveRisk: 'low',
161
+ source: '\\b(?:I\\s+am|I\u0027m|this\\s+is)\\s+(?:an?\\s+)?(?:claude|chatgpt|gpt(?:[\\w.-]*[\\w])?|gemini|llama|codex|grok|mistral)\\b',
162
+ flags: 'gi',
163
+ },
164
+ {
165
+ id: 'selfid-trained-by',
166
+ category: 'first-person-self-identification',
167
+ rationale: 'Attribution frames: "trained by X", "developed by X", "made by X", "created by X".',
168
+ falsePositiveRisk: 'low',
169
+ source: '\\b(?:trained|developed|built|made|created)\\s+by\\s+(?:anthropic|open\\s?ai|google|meta|mistral|deepseek|xai|cohere)\\b',
170
+ flags: 'gi',
171
+ },
172
+ {
173
+ id: 'selfid-as-an-ai-by',
174
+ category: 'first-person-self-identification',
175
+ rationale: 'The "As an AI assistant developed by …" frame, including the truncated "As an AI model from …".',
176
+ falsePositiveRisk: 'low',
177
+ source: '\\bas\\s+an?\\s+(?:AI|language)\\s+(?:model|assistant)\\s+(?:developed|created|trained|made)?\\s*(?:by|from)\\s+[A-Z][\\w.\\s]{0,20}?(?=[,.;:]|\\s+I\\b)',
178
+ flags: 'g',
179
+ },
180
+ {
181
+ id: 'selfid-my-training',
182
+ category: 'first-person-self-identification',
183
+ rationale: 'First-person model-self talk that names the house: "my training data at Anthropic".',
184
+ falsePositiveRisk: 'moderate',
185
+ source: '\\bmy\\s+(?:training|creators?|developers?|makers?)\\b(?:[^.\\n]{0,40}?\\b(?:anthropic|open\\s?ai|google|meta)\\b)',
186
+ flags: 'gi',
187
+ },
188
+ // ── model ids, second: they contain the bare vendor tokens below ───────
189
+ {
190
+ id: 'model-claude-family',
191
+ category: 'model-id',
192
+ rationale: 'Anthropic model ids: claude-<line>-<version>, incl. dotted and bare line names.',
193
+ falsePositiveRisk: 'low',
194
+ source: 'claude[-\\s](?:sonnet|opus|haiku|instant)(?:[-\\s.\\d]*\\d)?',
195
+ flags: 'gi',
196
+ },
197
+ {
198
+ id: 'model-gpt-family',
199
+ category: 'model-id',
200
+ rationale: 'OpenAI model ids: gpt-4, gpt-4o, gpt-5, and the o-series reasoning ids.',
201
+ falsePositiveRisk: 'low',
202
+ source: '\\bgpt[-\\s]?[0-9](?:[\\w.-]*[\\w])?|\\bo[1-9]\\b(?=[-\\s](?:mini|preview|pro))',
203
+ flags: 'gi',
204
+ },
205
+ {
206
+ id: 'model-codex-family',
207
+ category: 'model-id',
208
+ rationale: 'The codex-* seat ids this repository configures for the openai member.',
209
+ falsePositiveRisk: 'low',
210
+ source: '\\bcodex(?:[-\\s][\\w.]+)?',
211
+ flags: 'gi',
212
+ },
213
+ {
214
+ id: 'model-gemini-family',
215
+ category: 'model-id',
216
+ rationale: 'Google model ids in id shape only — a bare "gemini" is excluded by admission rule 1.',
217
+ falsePositiveRisk: 'low',
218
+ source: '\\bgemini[-\\s][\\d](?:[\\w.-]*[\\w])?|\\bgemini[-\\s](?:pro|flash|ultra|nano)\\b',
219
+ flags: 'gi',
220
+ },
221
+ {
222
+ id: 'model-open-weight-family',
223
+ category: 'model-id',
224
+ rationale: 'Open-weight ids that name their house: llama-N, mixtral-*, deepseek-*, qwen-*.',
225
+ falsePositiveRisk: 'low',
226
+ source: '\\b(?:llama|mixtral|mistral|deepseek|qwen|grok)[-\\s]?[\\d](?:[\\w.-]*[\\w])?',
227
+ flags: 'gi',
228
+ },
229
+ // ── vendor and product names admitted bare (admission rule 2) ───────────
230
+ {
231
+ id: 'vendor-anthropic',
232
+ category: 'vendor-name',
233
+ rationale: 'Company name; no ordinary-English sense.',
234
+ falsePositiveRisk: 'low',
235
+ source: '\\banthropic(?:\u0027s)?\\b',
236
+ flags: 'gi',
237
+ },
238
+ {
239
+ id: 'vendor-openai',
240
+ category: 'vendor-name',
241
+ rationale: 'Company name, hyphenated and spaced spellings included.',
242
+ falsePositiveRisk: 'low',
243
+ source: '\\bopen[-\\s]?ai(?:\u0027s)?\\b',
244
+ flags: 'gi',
245
+ },
246
+ {
247
+ id: 'vendor-possessive-ambiguous',
248
+ category: 'vendor-name',
249
+ rationale: 'Ambiguous tokens admitted ONLY in a vendor possessive/attributive frame (admission rule 1).',
250
+ falsePositiveRisk: 'moderate',
251
+ source: '\\b(?:google|meta|mistral\\s+ai|deepseek|xai|x\\.ai|cohere)(?:\u0027s)?(?=\\s+(?:model|models|api|team|research|assistant|policy|guidelines|training))',
252
+ flags: 'gi',
253
+ },
254
+ {
255
+ id: 'product-claude',
256
+ category: 'provider-name',
257
+ rationale: 'Assistant product name; the single strongest bare identifier in this corpus.',
258
+ falsePositiveRisk: 'low',
259
+ source: '\\bclaude(?:\u0027s)?\\b',
260
+ flags: 'gi',
261
+ },
262
+ {
263
+ id: 'product-chatgpt',
264
+ category: 'provider-name',
265
+ rationale: 'Assistant product name; no ordinary-English sense.',
266
+ falsePositiveRisk: 'low',
267
+ source: '\\bchat[-\\s]?gpt(?:\u0027s)?\\b',
268
+ flags: 'gi',
269
+ },
270
+ {
271
+ id: 'product-bare-gpt',
272
+ category: 'provider-name',
273
+ rationale: 'Bare "GPT" outside a model id; kept separate so its removals are countable on their own.',
274
+ falsePositiveRisk: 'moderate',
275
+ source: '\\bgpt\\b',
276
+ flags: 'gi',
277
+ },
278
+ ];
279
+
280
+ /**
281
+ * One removal, with enough information to audit it after the fact. Offsets
282
+ * index the ORIGINAL text, so `original.slice(start, end) === matched` — the
283
+ * property a span-level log has to have to be checkable, and a test asserts it.
284
+ */
285
+ export interface TransformationSpan {
286
+ readonly patternId: string;
287
+ readonly category: PatternCategory;
288
+ /** Inclusive start offset in the ORIGINAL text. */
289
+ readonly start: number;
290
+ /** Exclusive end offset in the ORIGINAL text. */
291
+ readonly end: number;
292
+ readonly matched: string;
293
+ readonly replacement: string;
294
+ }
295
+
296
+ export interface StripResult {
297
+ /** The transformed body. Never labelled `identifier-free` — see `ARM_LABEL`. */
298
+ readonly text: string;
299
+ /**
300
+ * Every removal, ascending by `start` and NON-OVERLAPPING. Empty means the
301
+ * body carried no registered identifier — which is a RESULT, not a failure.
302
+ */
303
+ readonly spans: readonly TransformationSpan[];
304
+ /** Echoed so a persisted log is self-describing without its writer. */
305
+ readonly patternListVersion: string;
306
+ }
307
+
308
+ /** Ascending, non-overlapping claim over the original text. */
309
+ interface Claim {
310
+ readonly start: number;
311
+ readonly end: number;
312
+ readonly rule: PatternRule;
313
+ }
314
+
315
+ /**
316
+ * Apply the pinned list to one body.
317
+ *
318
+ * Rules are applied in declaration order and a later rule may not claim a
319
+ * region an earlier rule already claimed — which is how `claude-sonnet-4-5`
320
+ * survives as ONE model-id span instead of being cut into a vendor token plus
321
+ * debris. Overlap is resolved by first-claim-wins rather than by longest-match,
322
+ * because the declaration order is itself part of the pinned list and a
323
+ * length heuristic would make the outcome depend on the input.
324
+ */
325
+ export function applyLeakagePatterns(original: string): StripResult {
326
+ const claims: Claim[] = [];
327
+
328
+ for (const rule of LEAKAGE_PATTERNS) {
329
+ // Recompiled per rule per call so a shared `g` regex cannot carry
330
+ // `lastIndex` across calls.
331
+ //
332
+ // HONEST GAP, recorded because the sabotage run showed it: hoisting
333
+ // this into a module-level cache does NOT turn any test red. The loop
334
+ // below always runs to `exec` returning null, which resets `lastIndex`
335
+ // to 0 on the way out, so today a cached regex is indistinguishable
336
+ // from a fresh one. The recompile is defensive against a future early
337
+ // exit from this loop, and it is UNPROVEN rather than proven.
338
+ const re = new RegExp(rule.source, rule.flags);
339
+ let match: RegExpExecArray | null = re.exec(original);
340
+ while (match !== null) {
341
+ const start = match.index;
342
+ const end = start + match[0].length;
343
+ if (match[0].length === 0) {
344
+ re.lastIndex += 1;
345
+ match = re.exec(original);
346
+ continue;
347
+ }
348
+ const overlaps = claims.some((c) => start < c.end && c.start < end);
349
+ if (!overlaps) claims.push({ start, end, rule });
350
+ match = re.exec(original);
351
+ }
352
+ }
353
+
354
+ claims.sort((a, b) => (a.start === b.start ? a.end - b.end : a.start - b.start));
355
+
356
+ const spans: TransformationSpan[] = [];
357
+ let out = '';
358
+ let cursor = 0;
359
+ for (const claim of claims) {
360
+ const replacement = CATEGORY_PLACEHOLDER[claim.rule.category];
361
+ out += original.slice(cursor, claim.start) + replacement;
362
+ spans.push({
363
+ patternId: claim.rule.id,
364
+ category: claim.rule.category,
365
+ start: claim.start,
366
+ end: claim.end,
367
+ matched: original.slice(claim.start, claim.end),
368
+ replacement,
369
+ });
370
+ cursor = claim.end;
371
+ }
372
+ out += original.slice(cursor);
373
+
374
+ return { text: out, spans, patternListVersion: LEAKAGE_PATTERN_LIST_VERSION };
375
+ }
376
+
377
+ /** One item's transformation log — what condition 2 asks be retained. */
378
+ export interface ItemTransformationLog {
379
+ readonly itemId: string;
380
+ readonly spans: readonly TransformationSpan[];
381
+ }
382
+
383
+ /**
384
+ * Build an `AssembleOptions.anonymise` seam that ALSO records a span log.
385
+ *
386
+ * The seam's type is `(text: string) => string` and cannot return a log, so the
387
+ * log is accumulated into the array the caller owns. Ordering is the assembler's
388
+ * item order; ids are attached by `attachLogIds` because the seam is called
389
+ * before the item id exists. Keeping the two steps apart is deliberate: a seam
390
+ * that invented an id would make the log's ids disagree with the corpus's.
391
+ */
392
+ export function makeRecordingAnonymiser(sink: TransformationSpan[][]): (text: string) => string {
393
+ return (text: string): string => {
394
+ const result = applyLeakagePatterns(text);
395
+ sink.push([...result.spans]);
396
+ return result.text;
397
+ };
398
+ }
399
+
400
+ /** Zip a recorded span sink onto the ids the assembler produced, in order. */
401
+ export function attachLogIds(
402
+ sink: readonly (readonly TransformationSpan[])[],
403
+ itemIds: readonly string[],
404
+ ): readonly ItemTransformationLog[] {
405
+ if (sink.length !== itemIds.length) {
406
+ throw new Error(
407
+ `transformation log length ${sink.length} does not match item count ${itemIds.length}; ` +
408
+ 'the log cannot be attributed and must not be published',
409
+ );
410
+ }
411
+ return itemIds.map((itemId, i) => ({ itemId, spans: [...(sink[i] ?? [])] }));
412
+ }
413
+
414
+ /**
415
+ * Canonical serialisation of the list — the input to `PATTERN_LIST_DIGEST`.
416
+ * Every field a rule carries is included, so a rationale edit is as visible as
417
+ * a regex edit: the freeze condition 1 states is about the registered artefact,
418
+ * not only about its matching behaviour.
419
+ */
420
+ export function canonicalPatternListSource(): string {
421
+ return JSON.stringify(
422
+ {
423
+ version: LEAKAGE_PATTERN_LIST_VERSION,
424
+ armLabel: ARM_LABEL,
425
+ placeholders: CATEGORY_PLACEHOLDER,
426
+ rules: LEAKAGE_PATTERNS.map((r) => ({
427
+ id: r.id,
428
+ category: r.category,
429
+ rationale: r.rationale,
430
+ falsePositiveRisk: r.falsePositiveRisk,
431
+ source: r.source,
432
+ flags: r.flags,
433
+ })),
434
+ },
435
+ null,
436
+ 0,
437
+ );
438
+ }
439
+
440
+ /** sha256 of `canonicalPatternListSource()`. */
441
+ export function patternListDigest(): string {
442
+ return crypto.createHash('sha256').update(canonicalPatternListSource(), 'utf8').digest('hex');
443
+ }
444
+
445
+ /**
446
+ * The recorded digest of the pinned list.
447
+ *
448
+ * A test asserts `patternListDigest() === PATTERN_LIST_DIGEST`, so editing a
449
+ * rule without editing this constant is a RED test rather than a quiet change.
450
+ * That is the whole enforcement of condition 1 available before a run exists:
451
+ * it cannot stop an edit, and it makes one impossible to make silently.
452
+ */
453
+ export const PATTERN_LIST_DIGEST = '10045caaec23a1bd7053a629f9e8043cb6a3066b44e349ceba6890b058976da6';
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Majority laundering — the permanent fixture gate for step 5.3.
3
+ *
4
+ * `road-to-inbox-harvest-2026-08-e-council-topology-evidence` step 5.3:
5
+ * *"seed one correct minority against several plausible-but-wrong majority
6
+ * answers; the synthesizer must justify accepting or rejecting the minority"*,
7
+ * verified by *"the fixture is permanent, and a synthesizer that silently drops
8
+ * the minority fails it"*.
9
+ *
10
+ * ## What this decides, and what it deliberately does not
11
+ *
12
+ * It decides the SHAPE of the disposition, not its correctness. Three questions,
13
+ * all answerable from text:
14
+ *
15
+ * 1. Does the synthesis NAME the minority position (an anchor phrase)?
16
+ * 2. Does it state a DISPOSITION — accept or reject?
17
+ * 3. Does it attach a REASON to that disposition?
18
+ *
19
+ * Accepting and rejecting are BOTH passes. The failure 5.3 names is the silent
20
+ * drop: the majority answer reported as the verdict with the minority never
21
+ * appearing, so a reader cannot tell whether it was weighed or never seen.
22
+ *
23
+ * It does NOT decide whether the synthesizer reached the right verdict. That
24
+ * needs the benchmark, which is gated behind `blocker: phase-2-benchmark-cost`,
25
+ * and pretending otherwise here would be the overstatement this file's own
26
+ * § Prevented items exists to catch. A synthesis that rejects the correct
27
+ * minority with a stated reason PASSES this gate and is wrong — which is the
28
+ * honest scope, said out loud rather than implied.
29
+ *
30
+ * Pure, offline, no model call: the "synthesizers" its tests exercise are
31
+ * scripted strings.
32
+ */
33
+ import * as fs from 'node:fs';
34
+
35
+ /** The minority half of a laundering fixture. */
36
+ export interface MinorityPosition {
37
+ readonly member: string;
38
+ readonly answer: string;
39
+ /** Distinctive phrases; naming none of them is not engaging with the minority. */
40
+ readonly anchors: readonly string[];
41
+ }
42
+
43
+ /** One plausible-but-wrong majority answer. */
44
+ export interface MajorityPosition {
45
+ readonly member: string;
46
+ readonly answer: string;
47
+ readonly why_wrong: string;
48
+ }
49
+
50
+ export interface LaunderingFixture {
51
+ readonly id: string;
52
+ readonly permanent: boolean;
53
+ readonly question: string;
54
+ /** Which side is correct. `'minority'` is the whole point of the fixture. */
55
+ readonly ground_truth: 'minority' | 'majority';
56
+ readonly minority: MinorityPosition;
57
+ readonly majority: readonly MajorityPosition[];
58
+ }
59
+
60
+ /** Why a synthesis failed. Empty means it stated a disposition with a reason. */
61
+ export type RetentionFailure =
62
+ /** No anchor appears — the minority is not in the text at all. */
63
+ | 'minority-silently-dropped'
64
+ /** The minority is named but neither accepted nor rejected. */
65
+ | 'no-disposition'
66
+ /** A disposition is stated with nothing attached to it. */
67
+ | 'unjustified-disposition';
68
+
69
+ export interface RetentionVerdict {
70
+ readonly passed: boolean;
71
+ readonly failures: readonly RetentionFailure[];
72
+ /** Anchors actually found, for the failure message. */
73
+ readonly anchorsFound: readonly string[];
74
+ /** `'accept' | 'reject' | null` — what the text says was done with the minority. */
75
+ readonly disposition: 'accept' | 'reject' | null;
76
+ }
77
+
78
+ /**
79
+ * Disposition vocabulary.
80
+ *
81
+ * Deliberately small and explicit rather than a general parser: a wide matcher
82
+ * would pass a synthesis that merely uses the word "however", which is the
83
+ * hedge a laundering synthesis produces most often.
84
+ */
85
+ const ACCEPT_RE =
86
+ /\b(accept(?:ed|ing|s)?|adopt(?:ed|ing|s)?|the minority is correct|minority is right|side with the minority|upheld)\b/i;
87
+ const REJECT_RE =
88
+ /\b(reject(?:ed|ing|s)?|set aside|discount(?:ed|ing|s)?|overrul(?:e|ed|ing)|not persuasive|declin(?:e|ed|ing) to adopt|dismiss(?:ed|ing|es)?)\b/i;
89
+
90
+ /**
91
+ * Justification markers. A disposition with no reason attached is the second
92
+ * failure mode 5.3 implies but does not spell out: *"justify accepting or
93
+ * rejecting"* is two obligations, and a bare "the minority is rejected" clears
94
+ * only the first.
95
+ */
96
+ const REASON_RE = /\b(because|since|on the grounds that|the reason is|as it|reasoning:|rationale:|given that)\b/i;
97
+
98
+ /** Tolerant containment: `eager load` matches `eager loading`, case-insensitively. */
99
+ export function anchorPresent(text: string, anchor: string): boolean {
100
+ const words = anchor
101
+ .trim()
102
+ .split(/\s+/)
103
+ .map((w) => w.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
104
+ // `\w*` after each word absorbs an inflection; `\s+` between them tolerates
105
+ // whatever whitespace the renderer emitted.
106
+ return new RegExp(`\\b${words.join('\\w*\\s+')}\\w*`, 'i').test(text);
107
+ }
108
+
109
+ /** Audit one synthesis against one fixture. */
110
+ export function auditMinorityRetention(synthesis: string, fixture: LaunderingFixture): RetentionVerdict {
111
+ const anchorsFound = fixture.minority.anchors.filter((a) => anchorPresent(synthesis, a));
112
+ const failures: RetentionFailure[] = [];
113
+
114
+ if (anchorsFound.length === 0) {
115
+ // Nothing further is decidable: with the minority absent there is no
116
+ // disposition to grade, and reporting three failures for one defect
117
+ // would put noise in a message whose value is that it is short.
118
+ return {
119
+ passed: false,
120
+ failures: ['minority-silently-dropped'],
121
+ anchorsFound,
122
+ disposition: null,
123
+ };
124
+ }
125
+
126
+ const accepted = ACCEPT_RE.test(synthesis);
127
+ const rejected = REJECT_RE.test(synthesis);
128
+ const disposition: 'accept' | 'reject' | null = accepted ? 'accept' : rejected ? 'reject' : null;
129
+
130
+ if (disposition === null) failures.push('no-disposition');
131
+ else if (!REASON_RE.test(synthesis)) failures.push('unjustified-disposition');
132
+
133
+ return { passed: failures.length === 0, failures, anchorsFound, disposition };
134
+ }
135
+
136
+ /** Human-readable failure text. */
137
+ export function renderRetentionVerdict(v: RetentionVerdict, fixture: LaunderingFixture): string {
138
+ if (v.passed) {
139
+ return (
140
+ `synthesis PASSES ${fixture.id}: minority (${fixture.minority.member}) ` +
141
+ `${v.disposition === null ? 'addressed' : v.disposition + 'ed'} with a stated reason ` +
142
+ `[anchors: ${v.anchorsFound.join(', ')}]\n`
143
+ );
144
+ }
145
+ const why: Record<RetentionFailure, string> = {
146
+ 'minority-silently-dropped':
147
+ `no anchor of the minority position appears (${fixture.minority.anchors.join(' | ')}) — ` +
148
+ 'the majority answer was reported as the verdict and the minority never appears',
149
+ 'no-disposition': 'the minority is named but neither accepted nor rejected',
150
+ 'unjustified-disposition': 'a disposition is stated with no reason attached to it',
151
+ };
152
+ return (
153
+ `synthesis FAILS ${fixture.id}:\n` +
154
+ v.failures.map((f) => ` - ${f}: ${why[f]}\n`).join('') +
155
+ ` ground truth: the ${fixture.ground_truth} is correct\n`
156
+ );
157
+ }
158
+
159
+ /** Load and validate the frozen fixture. Throws on a fixture that is not permanent. */
160
+ export function loadLaunderingFixture(absPath: string): LaunderingFixture {
161
+ const raw = JSON.parse(fs.readFileSync(absPath, 'utf8')) as Record<string, unknown>;
162
+ if (raw['permanent'] !== true) {
163
+ throw new Error(
164
+ `${absPath}: step 5.3 requires a PERMANENT fixture; this file does not declare permanent: true`,
165
+ );
166
+ }
167
+ if (raw['ground_truth'] !== 'minority' && raw['ground_truth'] !== 'majority') {
168
+ throw new Error(`${absPath}: ground_truth must be "minority" or "majority"`);
169
+ }
170
+ return raw as unknown as LaunderingFixture;
171
+ }