@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,272 @@
1
+ /**
2
+ * Experience cards — the `kind: experience` variant of the knowledge card.
3
+ *
4
+ * **Where these live, and why it was a decision.** AI council 2026-08-30,
5
+ * anthropic + openai, 2/2 convergent: they live in `agents/knowledge/`
6
+ * alongside external-source cards, as a STRICT TAGGED UNION on a required
7
+ * `kind` field — never as one schema with conditional fields.
8
+ *
9
+ * The distinction the council insisted on is the whole design. Making the
10
+ * external card's checks (authoritative pointer, pointer resolution,
11
+ * git-ancestry across `source_version`s) *optional* would hide two contracts
12
+ * inside one nominal schema, which is the union-of-what-producers-send failure
13
+ * this repository refuses elsewhere. Making them **variant invariants** — they
14
+ * apply, in full, to `kind: external` and are not part of the `experience`
15
+ * variant at all — keeps one contract per variant and one directory.
16
+ *
17
+ * The reusable boundary the council left behind, recorded so the next proposal
18
+ * is measured against it rather than re-argued: *a new store is justified only
19
+ * when its records cannot share the existing carrier's identity, discovery path
20
+ * and consumer lifecycle — not merely because they have different provenance or
21
+ * validation rules.* Experience cards share all three, so they are a variant.
22
+ */
23
+
24
+ /**
25
+ * How a card's statement was arrived at.
26
+ *
27
+ * The split is load-bearing rather than descriptive: `observed` and `derived`
28
+ * are FACTUAL — something happened, or follows from something that happened —
29
+ * while `inferred` and `hypothesized` are GENERATIVE. Only the factual pair may
30
+ * act as a hard filter; the generative pair may at most reduce ranking weight.
31
+ * Letting a hypothesis filter is how a guess becomes a rule without anyone
32
+ * deciding it should.
33
+ */
34
+ export const EPISTEMIC_TYPES = ['observed', 'derived', 'inferred', 'hypothesized'] as const;
35
+ export type EpistemicType = (typeof EPISTEMIC_TYPES)[number];
36
+
37
+ /** Only a factual statement may exclude a candidate outright. */
38
+ export function mayHardFilter(t: EpistemicType): boolean {
39
+ return t === 'observed' || t === 'derived';
40
+ }
41
+
42
+ /**
43
+ * The promotion ladder. A card starts at `session` and climbs one rung at a
44
+ * time; `repo` is the last rung reachable on the evidence that produced it.
45
+ */
46
+ export const CARD_SCOPES = ['session', 'repo', 'workspace', 'organization', 'global'] as const;
47
+ export type CardScope = (typeof CARD_SCOPES)[number];
48
+
49
+ /** Where the evidence for a promotion came from. */
50
+ export const EVIDENCE_POOLS = ['development', 'held-out', 'independent'] as const;
51
+ export type EvidencePool = (typeof EVIDENCE_POOLS)[number];
52
+
53
+ /**
54
+ * A card is admissible only from the mining gate or an explicit seed. Never
55
+ * invented, and never pre-seeded as a family of plausible-looking entries.
56
+ */
57
+ export interface CardProvenance {
58
+ /**
59
+ * A pattern id from `extract_audit_patterns`, which mints a pattern only at
60
+ * count >= 2 across INDEPENDENT `work_id`s. One run repeating itself is not
61
+ * a pattern.
62
+ */
63
+ pattern_ref?: string;
64
+ /** An explicit `### SEED —` block a human wrote. */
65
+ seed_ref?: string;
66
+ }
67
+
68
+ export interface ExperienceCard {
69
+ kind: 'experience';
70
+ id: string;
71
+ scope: CardScope;
72
+ /** When this card applies. Id-shaped tokens, never prose. */
73
+ trigger_context: string[];
74
+ /** What to do. One compact statement. */
75
+ strategy: string;
76
+ /**
77
+ * What would show this card is wrong. REQUIRED, and the field that makes a
78
+ * card a claim rather than an opinion: a card with no falsifier can never
79
+ * be retired on evidence, only on taste.
80
+ */
81
+ falsifier: string;
82
+ confidence: 'low' | 'medium' | 'high';
83
+ /** Card ids this one contradicts. Recorded, never silently resolved. */
84
+ contradictions: string[];
85
+ /** Card ids this one replaces. */
86
+ supersedes: string[];
87
+ /**
88
+ * ISO date after which this card must be re-checked. REQUIRED: an
89
+ * unexpiring empirical claim outlives the conditions that produced it and
90
+ * nobody notices, because nothing ever asks.
91
+ */
92
+ expiry: string;
93
+ epistemic_type: EpistemicType;
94
+ provenance: CardProvenance;
95
+ /** Cases where the strategy failed. Narrows the card; never widens it. */
96
+ anti_patterns: string[];
97
+ }
98
+
99
+ export class CardContractError extends Error {}
100
+
101
+ /** Admissible iff it carries a mining-gate pattern or a human seed. */
102
+ export function isAdmissible(p: CardProvenance): boolean {
103
+ return (
104
+ (typeof p.pattern_ref === 'string' && p.pattern_ref.trim().length > 0) ||
105
+ (typeof p.seed_ref === 'string' && p.seed_ref.trim().length > 0)
106
+ );
107
+ }
108
+
109
+ /** Fields whose absence makes a card inadmissible, in the order a linter reports them. */
110
+ export const REQUIRED_CARD_FIELDS = [
111
+ 'id',
112
+ 'scope',
113
+ 'trigger_context',
114
+ 'strategy',
115
+ 'falsifier',
116
+ 'confidence',
117
+ 'contradictions',
118
+ 'supersedes',
119
+ 'expiry',
120
+ 'epistemic_type',
121
+ ] as const;
122
+
123
+ export interface CardFailure {
124
+ /** What went wrong, id-shaped. */
125
+ anti_pattern: string;
126
+ /**
127
+ * Present only when the failure is being used to argue the card applies
128
+ * MORE widely. That is the move this type exists to refuse.
129
+ */
130
+ widen_scope_to?: CardScope;
131
+ }
132
+
133
+ /**
134
+ * Fold a failure into a card.
135
+ *
136
+ * **A failure narrows; it never widens.** The temptation is real and specific:
137
+ * a card fails in a neighbouring context, and the natural-sounding repair is
138
+ * "so the card is really about the broader case". That reasoning turns every
139
+ * piece of disconfirming evidence into an expansion, which is the exact inverse
140
+ * of what evidence is for. A failure adds an anti-pattern and nothing else.
141
+ */
142
+ export function applyFailure(card: ExperienceCard, failure: CardFailure): ExperienceCard {
143
+ if (failure.widen_scope_to !== undefined) {
144
+ throw new CardContractError(
145
+ `a failure may not widen scope (${card.scope} -> ${failure.widen_scope_to}). ` +
146
+ 'A failure adds an anti-pattern; it never extends applicability. ' +
147
+ 'Widening on disconfirming evidence is the inverse of what evidence is for.',
148
+ );
149
+ }
150
+ return { ...card, anti_patterns: [...card.anti_patterns, failure.anti_pattern] };
151
+ }
152
+
153
+ export interface PromotionEvidence {
154
+ pool: EvidencePool;
155
+ }
156
+
157
+ /**
158
+ * Promote one rung.
159
+ *
160
+ * Two refusals, and they answer the two ways a card gets over-promoted:
161
+ *
162
+ * 1. **One level at a time.** A two-level raise skips the rung where the card
163
+ * would have been checked against a wider population.
164
+ * 2. **Past `repo` needs evidence the card did not produce.** The runs that
165
+ * minted a card cannot also demonstrate it transfers — that is the same data
166
+ * answering its own question. Above `repo`, the evidence must be held-out or
167
+ * independent.
168
+ */
169
+ export function promote(
170
+ card: ExperienceCard,
171
+ target: CardScope,
172
+ evidence: PromotionEvidence,
173
+ ): ExperienceCard {
174
+ const from = CARD_SCOPES.indexOf(card.scope);
175
+ const to = CARD_SCOPES.indexOf(target);
176
+ if (to - from !== 1) {
177
+ throw new CardContractError(
178
+ `promotion moves exactly one rung: ${card.scope} -> ${target} is ${to - from}. ` +
179
+ 'A skipped rung is a population the card was never checked against.',
180
+ );
181
+ }
182
+ if (to > CARD_SCOPES.indexOf('repo') && evidence.pool === 'development') {
183
+ throw new CardContractError(
184
+ `raising past repo scope needs held-out or independent evidence; got '${evidence.pool}'. ` +
185
+ 'The runs that produced a card cannot also show it transfers.',
186
+ );
187
+ }
188
+ return { ...card, scope: target };
189
+ }
190
+
191
+ // ---------------------------------------------------------------------------
192
+ // Admission and duplicate checks — the linter's pure core
193
+ // ---------------------------------------------------------------------------
194
+
195
+ import { jaccardSimilarity } from './text_similarity.js';
196
+
197
+ export interface CardViolation {
198
+ card_id: string;
199
+ code:
200
+ | 'not-admissible'
201
+ | 'missing-field'
202
+ | 'unknown-epistemic-type'
203
+ | 'unknown-scope'
204
+ | 'duplicates-rule';
205
+ detail: string;
206
+ }
207
+
208
+ /**
209
+ * Everything a card must satisfy to be admissible, in one pass.
210
+ *
211
+ * `rules` is a map of live rule id -> its text. Passed IN rather than read
212
+ * here: this stays pure so the duplicate threshold can be tested against
213
+ * synthetic text instead of against whatever the rule corpus happens to say
214
+ * today.
215
+ */
216
+ export function checkCard(
217
+ card: Partial<ExperienceCard> & { id?: string },
218
+ rules: ReadonlyMap<string, string> = new Map(),
219
+ duplicateThreshold = DUPLICATE_THRESHOLD,
220
+ ): CardViolation[] {
221
+ const id = card.id ?? '<unnamed>';
222
+ const out: CardViolation[] = [];
223
+
224
+ for (const f of REQUIRED_CARD_FIELDS) {
225
+ const v = (card as Record<string, unknown>)[f];
226
+ const empty =
227
+ v === undefined ||
228
+ v === null ||
229
+ (typeof v === 'string' && v.trim().length === 0) ||
230
+ (Array.isArray(v) && f === 'trigger_context' && v.length === 0);
231
+ if (empty) out.push({ card_id: id, code: 'missing-field', detail: f });
232
+ }
233
+
234
+ if (card.epistemic_type !== undefined && !(EPISTEMIC_TYPES as readonly string[]).includes(card.epistemic_type)) {
235
+ out.push({ card_id: id, code: 'unknown-epistemic-type', detail: String(card.epistemic_type) });
236
+ }
237
+ if (card.scope !== undefined && !(CARD_SCOPES as readonly string[]).includes(card.scope)) {
238
+ out.push({ card_id: id, code: 'unknown-scope', detail: String(card.scope) });
239
+ }
240
+ if (card.provenance === undefined || !isAdmissible(card.provenance)) {
241
+ out.push({
242
+ card_id: id,
243
+ code: 'not-admissible',
244
+ detail: 'needs a pattern_ref from the mining gate or an explicit seed_ref — never invented',
245
+ });
246
+ }
247
+
248
+ // A card is not a rule: empirical, scoped and probabilistic versus
249
+ // normative. One that restates a live rule adds no knowledge and creates a
250
+ // second place the same instruction can drift.
251
+ const text = `${card.strategy ?? ''} ${(card.trigger_context ?? []).join(' ')}`.trim();
252
+ if (text.length > 0) {
253
+ for (const [ruleId, ruleText] of rules) {
254
+ if (jaccardSimilarity(text, ruleText) >= duplicateThreshold) {
255
+ out.push({
256
+ card_id: id,
257
+ code: 'duplicates-rule',
258
+ detail: `restates the live rule '${ruleId}' — a card is not a rule`,
259
+ });
260
+ }
261
+ }
262
+ }
263
+ return out;
264
+ }
265
+
266
+ /**
267
+ * Similarity at or above which a card is treated as restating a rule.
268
+ *
269
+ * Stated as a named constant rather than inlined so it is one number a reviewer
270
+ * can argue with, and so the tests exercise the same value the linter uses.
271
+ */
272
+ export const DUPLICATE_THRESHOLD = 0.6;
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Per-asset effectiveness, aggregated over the audit stream. READ ONLY.
3
+ *
4
+ * The one rule that shapes every type here: **a missing signal counts as
5
+ * `unknown`, never as success.** An asset that appears in the stream and whose
6
+ * outcome cannot be classified contributes to `unknown` and to nothing else. It
7
+ * does not enter a win-rate numerator, and it does not enter the denominator
8
+ * either — because a rate computed over "everything we saw" silently answers a
9
+ * different question from a rate computed over "everything we could classify",
10
+ * and only the second one is about the asset.
11
+ *
12
+ * `win_rate` is therefore `null` — not `0` — when nothing classifiable was seen.
13
+ * Zero is a measurement meaning "it never worked"; null means "we do not know",
14
+ * and rendering the second as the first is the fabrication this module exists to
15
+ * prevent. A reader seeing `0.0` will act; a reader seeing `—` will ask.
16
+ *
17
+ * Nothing in any selection or routing path may import this module. That is step
18
+ * 6.3's constraint and it is checked by a test, not by convention.
19
+ */
20
+
21
+ import { type BasisTag } from './evidence_basis.js';
22
+
23
+ /** What kind of asset a row is about. */
24
+ export type AssetKind = 'rule' | 'skill';
25
+
26
+ export interface AssetRow {
27
+ kind: AssetKind;
28
+ id: string;
29
+ /** Outcomes classified as helpful. */
30
+ helpful: number;
31
+ /** Classified, and neither helpful nor harmful. */
32
+ neutral: number;
33
+ /** Classified as harmful. */
34
+ harmful: number;
35
+ /**
36
+ * Appearances that could not be classified. Its OWN share, reported
37
+ * alongside the rest and never folded into any of them.
38
+ */
39
+ unknown: number;
40
+ /** Consecutive most-recent helpful outcomes. */
41
+ streak: number;
42
+ /**
43
+ * `helpful / (helpful + neutral + harmful)`, or `null` when that
44
+ * denominator is zero. Never `0` in the no-data case.
45
+ */
46
+ win_rate: number | null;
47
+ /** How `win_rate` was arrived at. Every derived figure states its basis. */
48
+ win_rate_basis: BasisTag;
49
+ }
50
+
51
+ /** The audit-line shape this module reads. Deliberately narrow. */
52
+ export interface AuditLineView {
53
+ outcome?: unknown;
54
+ rules_applied?: unknown;
55
+ skills_applied?: unknown;
56
+ }
57
+
58
+ /** Outcomes that count as helpful, and the ones that count against. */
59
+ const HELPFUL = new Set(['success']);
60
+ const HARMFUL = new Set(['error']);
61
+ const NEUTRAL = new Set(['skipped', 'blocked']);
62
+
63
+ interface Tally {
64
+ helpful: number;
65
+ neutral: number;
66
+ harmful: number;
67
+ unknown: number;
68
+ /** Most-recent-first classification history, for the streak. */
69
+ recent: ('helpful' | 'other' | 'unknown')[];
70
+ }
71
+
72
+ function emptyTally(): Tally {
73
+ return { helpful: 0, neutral: 0, harmful: 0, unknown: 0, recent: [] };
74
+ }
75
+
76
+ function classifyOutcome(outcome: unknown): 'helpful' | 'neutral' | 'harmful' | 'unknown' {
77
+ if (typeof outcome !== 'string') return 'unknown';
78
+ if (HELPFUL.has(outcome)) return 'helpful';
79
+ if (HARMFUL.has(outcome)) return 'harmful';
80
+ if (NEUTRAL.has(outcome)) return 'neutral';
81
+ return 'unknown';
82
+ }
83
+
84
+ function idsOf(v: unknown): string[] {
85
+ return Array.isArray(v) ? v.filter((x): x is string => typeof x === 'string') : [];
86
+ }
87
+
88
+ /**
89
+ * Aggregate.
90
+ *
91
+ * The `skills_applied` half deserves a note, because it is where the
92
+ * absent-vs-empty distinction stops being philosophical. A line that OMITS
93
+ * `skills_applied` recorded nothing about skills, so it contributes no skill
94
+ * row at all — it is not evidence that no skill was applied. A line carrying
95
+ * `[]` recorded that none was applied, which is also no row, but for the
96
+ * opposite reason. Neither may invent an `unknown` against a skill nobody
97
+ * named; `unknown` is counted against an asset the line DID name and whose
98
+ * outcome could not be classified.
99
+ */
100
+ export function aggregate(lines: readonly AuditLineView[]): AssetRow[] {
101
+ const tallies = new Map<string, { kind: AssetKind; id: string; t: Tally }>();
102
+
103
+ const bump = (kind: AssetKind, id: string, cls: ReturnType<typeof classifyOutcome>): void => {
104
+ const key = `${kind}:${id}`;
105
+ let entry = tallies.get(key);
106
+ if (entry === undefined) {
107
+ entry = { kind, id, t: emptyTally() };
108
+ tallies.set(key, entry);
109
+ }
110
+ entry.t[cls] += 1;
111
+ entry.t.recent.unshift(cls === 'helpful' ? 'helpful' : cls === 'unknown' ? 'unknown' : 'other');
112
+ };
113
+
114
+ for (const line of lines) {
115
+ const cls = classifyOutcome(line.outcome);
116
+ for (const id of idsOf(line.rules_applied)) bump('rule', id, cls);
117
+ for (const id of idsOf(line.skills_applied)) bump('skill', id, cls);
118
+ }
119
+
120
+ const rows: AssetRow[] = [];
121
+ for (const { kind, id, t } of tallies.values()) {
122
+ const classified = t.helpful + t.neutral + t.harmful;
123
+ // `null`, by construction, whenever nothing was classifiable. The
124
+ // ternary is the whole contract of this module.
125
+ const win_rate = classified === 0 ? null : t.helpful / classified;
126
+
127
+ let streak = 0;
128
+ for (const r of t.recent) {
129
+ if (r !== 'helpful') break;
130
+ streak += 1;
131
+ }
132
+
133
+ rows.push({
134
+ kind,
135
+ id,
136
+ helpful: t.helpful,
137
+ neutral: t.neutral,
138
+ harmful: t.harmful,
139
+ unknown: t.unknown,
140
+ streak,
141
+ win_rate,
142
+ // Not `measured`: the ratio is arithmetic over counted outcomes,
143
+ // never itself observed. The method travels with it so a reader can
144
+ // tell this apart from a figure derived some other way.
145
+ win_rate_basis: 'estimated:ratio-of-classified-audit-outcomes',
146
+ });
147
+ }
148
+
149
+ rows.sort((a, b) => (a.kind === b.kind ? a.id.localeCompare(b.id) : a.kind.localeCompare(b.kind)));
150
+ return rows;
151
+ }
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Freeze the five things a comparison must not change while it runs.
3
+ *
4
+ * A comparison whose evaluator, corpus, task definition, baseline or protected
5
+ * fixtures move mid-run has not compared two arms — it has compared two
6
+ * different experiments and reported the difference as an effect. The failure
7
+ * is silent by construction: every individual reading looks fine, and the
8
+ * corruption lives in the relationship between them.
9
+ *
10
+ * The design decision worth stating: `assertUnchanged` **throws**, and does not
11
+ * return a verdict. A verdict is a value a caller can log and step past, and a
12
+ * caller mid-comparison has every incentive to step past it — the run is already
13
+ * expensive and the drift usually looks small. An abort is the only shape that
14
+ * cannot be quietly absorbed, and "aborts the comparison rather than continuing
15
+ * it" is what the step asks for in those words.
16
+ *
17
+ * road-to-experience-loop-broadening step 9.5.
18
+ */
19
+
20
+ import * as crypto from 'node:crypto';
21
+
22
+ /**
23
+ * The five frozen elements.
24
+ *
25
+ * Every field is REQUIRED. An optional element is one a caller can omit and
26
+ * thereby freeze nothing, which is the failure mode a freeze exists to stop —
27
+ * so the type refuses a partial spec rather than hashing whatever it was given.
28
+ */
29
+ export interface ExperimentSpec {
30
+ /** Identity of the evaluator: its id and version, never its output. */
31
+ evaluator: string;
32
+ /** Content hash or pinned id of the corpus partition. */
33
+ corpus: string;
34
+ /** The task definition the arms are scored against. */
35
+ task: string;
36
+ /** The baseline arm's identity. */
37
+ baseline: string;
38
+ /** Protected fixtures, order-insensitive. */
39
+ fixtures: readonly string[];
40
+ }
41
+
42
+ /** The five element names, so a caller can report WHICH one moved. */
43
+ export const FROZEN_ELEMENTS = ['evaluator', 'corpus', 'task', 'baseline', 'fixtures'] as const;
44
+ export type FrozenElement = (typeof FROZEN_ELEMENTS)[number];
45
+
46
+ export class ExperimentDriftError extends Error {
47
+ constructor(
48
+ readonly changed: FrozenElement[],
49
+ readonly frozen: string,
50
+ readonly actual: string,
51
+ ) {
52
+ super(
53
+ `experiment drift: ${changed.join(', ')} changed mid-run. ` +
54
+ `Frozen ${frozen}, now ${actual}. The comparison is aborted rather than continued — ` +
55
+ 'a run whose frozen set moved did not compare two arms, it compared two experiments.',
56
+ );
57
+ this.name = 'ExperimentDriftError';
58
+ }
59
+ }
60
+
61
+ function canonical(spec: ExperimentSpec): string {
62
+ // Fixtures are sorted: their ORDER is a property of how the caller happened
63
+ // to enumerate a directory, not of the experiment, and a freeze that broke
64
+ // on reordering would be abandoned the first time it fired spuriously.
65
+ return JSON.stringify({
66
+ evaluator: spec.evaluator,
67
+ corpus: spec.corpus,
68
+ task: spec.task,
69
+ baseline: spec.baseline,
70
+ fixtures: [...spec.fixtures].sort(),
71
+ });
72
+ }
73
+
74
+ /** The frozen digest. Record it with the run; it is what `assertUnchanged` compares against. */
75
+ export function freeze(spec: ExperimentSpec): string {
76
+ return crypto.createHash('sha256').update(canonical(spec), 'utf-8').digest('hex').slice(0, 32);
77
+ }
78
+
79
+ /** Which of the five differ. Exported so a caller can report the cause without re-deriving it. */
80
+ export function changedElements(a: ExperimentSpec, b: ExperimentSpec): FrozenElement[] {
81
+ const out: FrozenElement[] = [];
82
+ if (a.evaluator !== b.evaluator) out.push('evaluator');
83
+ if (a.corpus !== b.corpus) out.push('corpus');
84
+ if (a.task !== b.task) out.push('task');
85
+ if (a.baseline !== b.baseline) out.push('baseline');
86
+ if (JSON.stringify([...a.fixtures].sort()) !== JSON.stringify([...b.fixtures].sort())) {
87
+ out.push('fixtures');
88
+ }
89
+ return out;
90
+ }
91
+
92
+ /**
93
+ * Abort if the set moved.
94
+ *
95
+ * Takes the ORIGINAL spec as well as its digest so the error can name which
96
+ * element changed. A digest alone would abort correctly and tell the operator
97
+ * nothing about what to fix, and an abort nobody can act on gets suppressed.
98
+ */
99
+ export function assertUnchanged(frozen: string, original: ExperimentSpec, now: ExperimentSpec): void {
100
+ const actual = freeze(now);
101
+ if (actual === frozen) return;
102
+ const changed = changedElements(original, now);
103
+ throw new ExperimentDriftError(
104
+ // A digest mismatch with no field difference means the ORIGINAL spec and
105
+ // the frozen digest disagree — the caller passed a spec that never
106
+ // produced that hash. That is a worse bug than drift, so it is named
107
+ // rather than reported as an empty change list.
108
+ changed.length > 0 ? changed : (['evaluator'] as FrozenElement[]),
109
+ frozen,
110
+ actual,
111
+ );
112
+ }
@@ -0,0 +1,66 @@
1
+ /**
2
+ * The attribution line a generated artifact carries.
3
+ *
4
+ * `road-to-consumer-repo-reality` Phase 1, step 1.4: "A generated file that
5
+ * names the script that wrote it becomes a lie the moment that script moves.
6
+ * Emit a stable, resolvable reference instead."
7
+ *
8
+ * IT ALREADY HAPPENED, which is why this module exists rather than a style
9
+ * note. Measured 2026-08-26 across `src/`, ten generated artifacts named their
10
+ * generator by literal path and **six of those paths did not resolve**:
11
+ *
12
+ * scripts/audit_user_type_axis.py scripts/adoption_report.py
13
+ * scripts/skill_overlap.py scripts/gen_discovery_baseline.py
14
+ * scripts/generate_ownership_matrix.py
15
+ * scripts/generate_pack_manifests.ts
16
+ *
17
+ * The first five were retired by the py2ts migration (ADR-200) and the sixth by
18
+ * the `scripts/` → `src/scripts/` move. Each artifact kept telling its reader to
19
+ * go look at a file that is not there — the same over-reporting failure Phase 1
20
+ * measures in consumer root instruction files, produced by this package's own
21
+ * generators.
22
+ *
23
+ * THE STABLE REFERENCE IS THE COMMAND, NOT THE PATH. A path is an
24
+ * implementation detail that a refactor moves; the command a human runs to
25
+ * regenerate is the thing that stays true, and it is also the only half of the
26
+ * attribution a reader can act on. Where no command exists, the generator's
27
+ * MODULE NAME is used — stable under a directory move, and greppable.
28
+ */
29
+
30
+ /**
31
+ * `Generated by <ref>. Do not edit.` — with `ref` a command or a module name,
32
+ * never a path.
33
+ *
34
+ * @param ref the regeneration command (`agent-config sync`, `task sync`) or
35
+ * the generator's module name (`regenerate_index`). A value
36
+ * containing a path separator is a bug this function refuses
37
+ * rather than emits, because emitting it is exactly the defect.
38
+ * @param detail optional trailing clause, e.g. a source description. No
39
+ * timestamp: a regenerated timestamp makes every run a diff.
40
+ */
41
+ export function generatedBy(ref: string, detail?: string): string {
42
+ if (ref.includes('/') || ref.includes('\\')) {
43
+ throw new Error(
44
+ `generatedBy: "${ref}" contains a path separator. The attribution must be a command or a ` +
45
+ 'module name — a literal path becomes wrong the moment the file moves, which is the ' +
46
+ 'defect this helper exists to prevent (road-to-consumer-repo-reality 1.4).',
47
+ );
48
+ }
49
+ const tail = detail === undefined || detail.trim() === '' ? '' : ` ${detail.trim()}`;
50
+ return `Generated by \`${ref}\`. Do not edit.${tail}`;
51
+ }
52
+
53
+ /** The same line as a markdown blockquote, the shape most emitters use. */
54
+ export function generatedByQuote(ref: string, detail?: string): string {
55
+ return `> ${generatedBy(ref, detail)}`;
56
+ }
57
+
58
+ /** The same line as an italic footer, for artifacts that use one. */
59
+ export function generatedByItalic(ref: string, detail?: string): string {
60
+ return `_${generatedBy(ref, detail)}_`;
61
+ }
62
+
63
+ /** The same line as a `#` comment, for YAML and INI-shaped output. */
64
+ export function generatedByComment(ref: string, detail?: string): string {
65
+ return `# ${generatedBy(ref, detail)}`;
66
+ }