@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,294 @@
1
+ /**
2
+ * The lifecycle AFTER promotion — `road-to-harness-promotion-bridge` steps 7.6
3
+ * and 7.7.
4
+ *
5
+ * ## 7.6 — a promoted artefact is not immortal
6
+ *
7
+ * > *post-promotion re-evaluation with `KEEP / REVISE / MERGE / SPLIT / RETIRE`.
8
+ * > The master's promotion phase ends at the evidence package plus a cooldown,
9
+ * > so nothing reopens a promoted artefact and the lifecycle is manual-only at
10
+ * > exactly the point where growth accumulates.*
11
+ * > verify: **a promoted artefact reaching its review trigger produces one of
12
+ * > the five verdicts, and at least one `RETIRE` path is exercised in a
13
+ * > fixture.**
14
+ *
15
+ * Two halves were already in the tree and one was missing. Four of the five
16
+ * verdicts are E6 curator ops (`_lib/curator_ops.ts`) — `REVISE` is not — and
17
+ * `promoted -> retired` is already the one legal retirement edge
18
+ * (`_lib/candidate_record.ts:210-219`). What did not exist was the REVIEW
19
+ * TRIGGER: nothing decided that a promoted artefact was due, and nothing turned
20
+ * that into a verdict. {@link reviewPromoted} is that.
21
+ *
22
+ * **The verdict set is NOT a subset of `CURATOR_OPS`, and finding that out is
23
+ * part of what this step buys.** E6 argued for seven curator ops on the ground
24
+ * that 7.6 specifies five verdicts a four-op curator could not execute — and the
25
+ * shipped seven still cannot execute one of them, because `REVISE` is not among
26
+ * them. The relationship is pinned by a test in both directions rather than
27
+ * papered over with a mapping nobody chose; see {@link POST_PROMOTION_VERDICTS}.
28
+ *
29
+ * ## 7.7 — best-known-state reference on regression
30
+ *
31
+ * > *Roll back to the recorded best-known state; lineage, not endless append.*
32
+ * > verify: **an injected regression triggers the rollback path in a fixture.**
33
+ *
34
+ * {@link BestKnownState} is the record, {@link planRollback} is the decision.
35
+ * "Lineage, not endless append" is carried in the type: a rollback names the
36
+ * state it returns to and the state it leaves, so the history is a chain rather
37
+ * than a pile of snapshots nobody can order.
38
+ *
39
+ * ## This module promotes nothing
40
+ *
41
+ * It reads promoted artefacts and it can RETIRE one — the only transition it
42
+ * expresses is `promoted -> retired`, which `assertTransition` accepts without
43
+ * an approver because retirement is the direction that shrinks the estate.
44
+ * There is no path here that moves anything INTO `promoted`; that stays behind
45
+ * `_lib/promotion_capability.ts`, and `lint_promotion_paths.ts` is what proves
46
+ * this file did not grow one.
47
+ */
48
+ import { ACCEPTED_STATE, type LifecycleState, assertTransition } from './candidate_record.js';
49
+ import { CURATOR_OPS, type CuratorOp } from './curator_ops.js';
50
+
51
+ /**
52
+ * The five verdicts step 7.6 names, verbatim.
53
+ *
54
+ * **Four of the five are E6 curator ops. `REVISE` is not, and that is a finding
55
+ * rather than a detail.** `_lib/curator_ops.ts:48-56` is `KEEP · ADD · MERGE ·
56
+ * REPLACE · SPLIT · RETIRE · SKIP`, and its own header argues for seven ops on
57
+ * the ground that *"step 7.6 of the same roadmap already specifies the verdict
58
+ * set KEEP / REVISE / MERGE / SPLIT / RETIRE, so a four-op curator would emit
59
+ * verdicts it cannot execute"*. Measured against the shipped set: `REVISE` is
60
+ * still a verdict the curator cannot execute — `REPLACE` is the nearest op and
61
+ * it is not the same thing, since `REPLACE` is 1→1 with a new artefact while
62
+ * `REVISE` edits the one in place and keeps its identity.
63
+ *
64
+ * The list is therefore written out rather than derived, because deriving it
65
+ * would require inventing the mapping the two sets do not have. What IS pinned,
66
+ * by `tests/scripts/promotion_review.test.ts`, is the relationship in both
67
+ * directions: the four shared verdicts really are curator ops, and `REVISE`
68
+ * really is not — so a later change that adds `REVISE` to `CURATOR_OPS`, or
69
+ * drops one of the four, fails a test instead of drifting.
70
+ */
71
+ export const POST_PROMOTION_VERDICTS = ['KEEP', 'REVISE', 'MERGE', 'SPLIT', 'RETIRE'] as const;
72
+
73
+ /** The four verdicts the curator can actually execute today. */
74
+ export const VERDICTS_EXECUTABLE_BY_CURATOR: readonly CuratorOp[] = CURATOR_OPS.filter(
75
+ (op) => (POST_PROMOTION_VERDICTS as readonly string[]).includes(op),
76
+ );
77
+
78
+ export type PostPromotionVerdict = (typeof POST_PROMOTION_VERDICTS)[number];
79
+
80
+ /** Why a promoted artefact came up for review. Absent means it is not due. */
81
+ export const REVIEW_TRIGGERS = [
82
+ 'regression',
83
+ 'usage-floor',
84
+ 'duplicate-detected',
85
+ 'scope-overgrown',
86
+ 'age',
87
+ ] as const;
88
+ export type ReviewTrigger = (typeof REVIEW_TRIGGERS)[number];
89
+
90
+ /** What a review reads. Every field is an observation, not a judgement. */
91
+ export interface PromotedArtefactState {
92
+ readonly id: string;
93
+ readonly lifecycle: LifecycleState;
94
+ /** Measured effect now, in the same units as the promotion evidence's delta. */
95
+ readonly currentDeltaPercent: number;
96
+ /** The delta recorded at promotion. The regression test is `current < promoted`. */
97
+ readonly promotedDeltaPercent: number;
98
+ /** How many times the artefact was actually reached since promotion. */
99
+ readonly invocations: number;
100
+ /** Ids of promoted artefacts whose text this one now duplicates. */
101
+ readonly duplicates: readonly string[];
102
+ /** Distinct responsibilities the artefact has accumulated. */
103
+ readonly responsibilities: number;
104
+ readonly daysSincePromotion: number;
105
+ }
106
+
107
+ export class NotPromotedError extends Error {
108
+ constructor(id: string, lifecycle: LifecycleState) {
109
+ super(
110
+ `'${id}' is '${lifecycle}', not '${ACCEPTED_STATE}' — post-promotion review acts on a ` +
111
+ 'PROMOTED artefact. A candidate that never landed is rejected, not retired, and ' +
112
+ 'reviewing one here would report a lifecycle event that did not happen.',
113
+ );
114
+ this.name = 'NotPromotedError';
115
+ }
116
+ }
117
+
118
+ export interface ReviewOutcome {
119
+ readonly id: string;
120
+ readonly trigger: ReviewTrigger;
121
+ readonly verdict: PostPromotionVerdict;
122
+ readonly reason: string;
123
+ }
124
+
125
+ /** The floors the review reads. Stated defaults; each carries its own revisit-if. */
126
+ export const REVIEW_THRESHOLDS = {
127
+ /** Below this many invocations the artefact is not earning its place. `revisit-if` a
128
+ * legitimately rare artefact is retired for being rare. */
129
+ usageFloor: 1,
130
+ /** Distinct responsibilities above which the artefact should be SPLIT. `revisit-if` a
131
+ * cohesive artefact with several facets is split for having them. */
132
+ responsibilityCeiling: 2,
133
+ /** Days after which an unreviewed artefact is due. `revisit-if` the cadence is noise. */
134
+ ageDays: 180,
135
+ } as const;
136
+
137
+ /**
138
+ * Is this artefact due for review, and why? `null` means not due.
139
+ *
140
+ * Order is precedence: a regression outranks a usage question, which outranks a
141
+ * duplicate, which outranks overgrowth, which outranks mere age. Without a fixed
142
+ * order two triggers firing at once would make the verdict depend on evaluation
143
+ * order, which is how a review becomes irreproducible.
144
+ */
145
+ export function reviewTriggerFor(state: PromotedArtefactState): ReviewTrigger | null {
146
+ if (state.currentDeltaPercent < state.promotedDeltaPercent) return 'regression';
147
+ if (state.invocations < REVIEW_THRESHOLDS.usageFloor) return 'usage-floor';
148
+ if (state.duplicates.length > 0) return 'duplicate-detected';
149
+ if (state.responsibilities > REVIEW_THRESHOLDS.responsibilityCeiling) return 'scope-overgrown';
150
+ if (state.daysSincePromotion >= REVIEW_THRESHOLDS.ageDays) return 'age';
151
+ return null;
152
+ }
153
+
154
+ /**
155
+ * Produce exactly ONE of the five verdicts for a promoted artefact that reached
156
+ * its review trigger.
157
+ *
158
+ * @throws {NotPromotedError} when the artefact is not promoted.
159
+ */
160
+ export function reviewPromoted(state: PromotedArtefactState, trigger: ReviewTrigger): ReviewOutcome {
161
+ if (state.lifecycle !== ACCEPTED_STATE) {
162
+ throw new NotPromotedError(state.id, state.lifecycle);
163
+ }
164
+ const outcome = (verdict: PostPromotionVerdict, reason: string): ReviewOutcome => ({
165
+ id: state.id,
166
+ trigger,
167
+ verdict,
168
+ reason,
169
+ });
170
+ switch (trigger) {
171
+ case 'regression':
172
+ // A measured effect that fell BELOW zero is not worth revising; it is
173
+ // now costing what it was promoted to save.
174
+ return state.currentDeltaPercent <= 0
175
+ ? outcome('RETIRE', `effect fell to ${String(state.currentDeltaPercent)} pp — it no longer earns its place`)
176
+ : outcome(
177
+ 'REVISE',
178
+ `effect fell ${String(state.promotedDeltaPercent)} -> ${String(state.currentDeltaPercent)} pp ` +
179
+ 'but is still positive',
180
+ );
181
+ case 'usage-floor':
182
+ return outcome('RETIRE', `reached ${String(state.invocations)} time(s) since promotion`);
183
+ case 'duplicate-detected':
184
+ return outcome('MERGE', `now duplicates ${state.duplicates.join(', ')}`);
185
+ case 'scope-overgrown':
186
+ return outcome('SPLIT', `carries ${String(state.responsibilities)} distinct responsibilities`);
187
+ case 'age':
188
+ return outcome('KEEP', `${String(state.daysSincePromotion)} days since promotion, effect held`);
189
+ }
190
+ }
191
+
192
+ /**
193
+ * Execute the RETIRE verdict.
194
+ *
195
+ * Routes through `assertTransition`, so the ONE legal retirement edge is the one
196
+ * this takes and a caller cannot retire something that never landed. Returns the
197
+ * next lifecycle state rather than writing anything — nothing in this module
198
+ * touches the filesystem.
199
+ *
200
+ * @throws {LifecycleTransitionError} from `assertTransition`.
201
+ */
202
+ export function retirePromoted(state: PromotedArtefactState): LifecycleState {
203
+ assertTransition(state.lifecycle, 'retired');
204
+ return 'retired';
205
+ }
206
+
207
+ // --- 7.7 — best-known state and rollback ------------------------------------
208
+
209
+ /** A recorded good state, and the state it came from. Lineage, not endless append. */
210
+ export interface BestKnownState {
211
+ readonly artefactId: string;
212
+ /** The revision or bundle identifier this state is recoverable from. */
213
+ readonly reference: string;
214
+ readonly deltaPercent: number;
215
+ /** The best-known state this one replaced. `null` only for the first. */
216
+ readonly supersedes: string | null;
217
+ readonly recordedAt: string;
218
+ }
219
+
220
+ export interface RollbackPlan {
221
+ readonly artefactId: string;
222
+ readonly from: string;
223
+ readonly to: string;
224
+ readonly reason: string;
225
+ /** Oldest first. The chain that makes this a lineage rather than a pile. */
226
+ readonly lineage: readonly string[];
227
+ }
228
+
229
+ export class NoBestKnownStateError extends Error {
230
+ constructor(artefactId: string) {
231
+ super(
232
+ `'${artefactId}' regressed and has no recorded best-known state to return to. A rollback ` +
233
+ 'target is recorded at promotion time, not reconstructed after the regression — by ' +
234
+ 'then the state that worked is exactly what is missing.',
235
+ );
236
+ this.name = 'NoBestKnownStateError';
237
+ }
238
+ }
239
+
240
+ /**
241
+ * Walk the `supersedes` chain, oldest first.
242
+ *
243
+ * Cycle-guarded: a chain that points at itself is a corrupted lineage, and
244
+ * following it forever would hang the caller rather than report the corruption.
245
+ */
246
+ export function lineageOf(head: BestKnownState, all: readonly BestKnownState[]): string[] {
247
+ const byRef = new Map(all.map((s) => [s.reference, s]));
248
+ const chain: string[] = [];
249
+ const seen = new Set<string>();
250
+ let cursor: BestKnownState | undefined = head;
251
+ while (cursor !== undefined && !seen.has(cursor.reference)) {
252
+ seen.add(cursor.reference);
253
+ chain.push(cursor.reference);
254
+ cursor = cursor.supersedes === null ? undefined : byRef.get(cursor.supersedes);
255
+ }
256
+ return chain.reverse();
257
+ }
258
+
259
+ /**
260
+ * Plan a rollback when the current state regressed against the best known one.
261
+ *
262
+ * `null` when there is no regression — the caller does not have to know the
263
+ * comparison, and a rollback that fires on an improvement is worse than none.
264
+ *
265
+ * @throws {NoBestKnownStateError} when a regression has nowhere to return to.
266
+ */
267
+ export function planRollback(
268
+ artefactId: string,
269
+ currentReference: string,
270
+ currentDeltaPercent: number,
271
+ history: readonly BestKnownState[],
272
+ ): RollbackPlan | null {
273
+ const mine = history.filter((s) => s.artefactId === artefactId);
274
+ const best = mine.reduce<BestKnownState | null>(
275
+ (acc, s) => (acc === null || s.deltaPercent > acc.deltaPercent ? s : acc),
276
+ null,
277
+ );
278
+ if (best === null) {
279
+ if (currentDeltaPercent < 0) throw new NoBestKnownStateError(artefactId);
280
+ return null;
281
+ }
282
+ if (currentDeltaPercent >= best.deltaPercent) {
283
+ return null;
284
+ }
285
+ return {
286
+ artefactId,
287
+ from: currentReference,
288
+ to: best.reference,
289
+ reason:
290
+ `regressed ${String(best.deltaPercent)} -> ${String(currentDeltaPercent)} pp against the ` +
291
+ `best-known state '${best.reference}'`,
292
+ lineage: lineageOf(best, mine),
293
+ };
294
+ }
@@ -86,3 +86,95 @@ export function humanAuthoredLead(text: string): string {
86
86
  }
87
87
  return kept.join("\n");
88
88
  }
89
+
90
+ /** A line that is nothing but an opening tag, with the tag name captured. */
91
+ const REGION_OPEN = /^\s*<([A-Za-z][\w-]*)>\s*$/;
92
+
93
+ /**
94
+ * The host's own framing of an injected region — the sentence it writes ABOUT
95
+ * the block, not a sentence the user typed.
96
+ *
97
+ * Named literally, for the same reason `isSyntheticPrompt` names wrapper tags:
98
+ * this is host furniture, and furniture is identified by what it says about
99
+ * itself. It is deliberately NOT a language rule — the clauses describe the
100
+ * region's provenance and its data status, and a user who types one is quoting
101
+ * the host, which is exactly the case that should be dropped too.
102
+ */
103
+ const REGION_NOTE =
104
+ /\b(content (above|below) is from|treat (it|this|that|the (content|text|above|following)) as data)\b/i;
105
+
106
+ /**
107
+ * Remove host-injected wrapper regions — `<launch-selected-element>` and
108
+ * friends — leaving the text the human actually typed around them.
109
+ *
110
+ * MEASURED, from a 14.13.0 field report (2026-09-01) reproduced against this
111
+ * source. `DOCUMENT_HEAD` matches a bare `<tag>` line, and Claude Code PREPENDS
112
+ * exactly that when the user picks a DOM element in the browser pane. So
113
+ * `humanAuthoredLead` broke at line zero and returned `""` for every such
114
+ * prompt — the lead-first isolation was not degraded, it was OFF — and the
115
+ * whole-text fallback then scored ~4 KB of class-heavy markup plus the host's
116
+ * own advisory line. Four consecutive German turns pinned English, and the
117
+ * turn-end gate refused each one.
118
+ *
119
+ * Two things had to move, and both are visible in the reproduction:
120
+ *
121
+ * 1. A bare `<tag>` line that HAS a matching close is the START of a region
122
+ * to skip, never the end of the human lead. That is this function.
123
+ * 2. It runs BEFORE `instructionText`. The block's indented lines arm that
124
+ * filter's paste-state machine, and where no blank line separates the
125
+ * block from the user's sentence, the sentence itself was deleted — the
126
+ * German markers did not merely lose the count, they reached zero.
127
+ *
128
+ * Conservative by construction, in three ways. An UNBALANCED bare tag is left
129
+ * in place, so a pasted document opening with one still terminates the lead
130
+ * exactly as before. A prompt with no balanced region is returned untouched,
131
+ * so nothing outside this shape reclassifies. And the framing sentence is
132
+ * dropped LINE BY LINE against `REGION_NOTE` rather than as a paragraph: in the
133
+ * reported shape the advisory and the user's sentence share one unbroken run,
134
+ * so dropping the run would have taken the sentence with it.
135
+ *
136
+ * Not `isSyntheticPrompt`: that answers "is this whole turn machine-written",
137
+ * and these turns are not — a human sentence follows the block. The wrapper is
138
+ * removed; the turn is kept.
139
+ *
140
+ * Nested same-name regions resolve to the FIRST matching close tag. Host
141
+ * wrappers do not nest by name, and stopping early keeps more human text than
142
+ * scanning past the wrong close would.
143
+ */
144
+ export function stripInjectedRegions(text: string): string {
145
+ const lines = text.split("\n");
146
+ const kept: string[] = [];
147
+ for (let i = 0; i < lines.length; i++) {
148
+ const line = lines[i] ?? "";
149
+ const open = REGION_OPEN.exec(line);
150
+ if (open === null) {
151
+ kept.push(line);
152
+ continue;
153
+ }
154
+ // The tag name comes from `[A-Za-z][\w-]*`, so it carries no regex
155
+ // metacharacter and needs no escaping.
156
+ const close = new RegExp(`^\\s*</${open[1] ?? ""}>\\s*$`);
157
+ let end = -1;
158
+ for (let j = i + 1; j < lines.length; j++) {
159
+ if (close.test(lines[j] ?? "")) {
160
+ end = j;
161
+ break;
162
+ }
163
+ }
164
+ if (end === -1) {
165
+ kept.push(line);
166
+ continue;
167
+ }
168
+ if (kept.length > 0 && REGION_NOTE.test(kept[kept.length - 1] ?? "")) {
169
+ kept.pop();
170
+ }
171
+ i = end;
172
+ while (i + 1 < lines.length && (lines[i + 1] ?? "").trim() !== "") {
173
+ if (!REGION_NOTE.test(lines[i + 1] ?? "")) {
174
+ break;
175
+ }
176
+ i++;
177
+ }
178
+ }
179
+ return kept.join("\n");
180
+ }
@@ -0,0 +1,259 @@
1
+ /**
2
+ * Regression selection from the affected neighbourhood.
3
+ *
4
+ * `road-to-governed-harness-evolution` Phase 4, step 4.6.
5
+ *
6
+ * > *Use the code graph to choose which regressions to run for a given
7
+ * > candidate. The master adopted the attack "local improvement, global
8
+ * > regression" as a risk with no mechanism behind it. This is distinct from
9
+ * > the killed curriculum generator — it selects existing regressions, it does
10
+ * > not author tasks.*
11
+ * > verify: **a candidate touching one surface runs the regressions its
12
+ * > neighbourhood names, and a fixture proves a neighbour regression is
13
+ * > caught.**
14
+ *
15
+ * ## Which graph, and why it is not the one the step names
16
+ *
17
+ * The step says "the code graph". This tree has two graph surfaces and only one
18
+ * of them resolves here, so the substitution is STATED rather than hidden.
19
+ *
20
+ * · `agent-config code-graph` — the native code-graph engine (ADR-124). It
21
+ * ships `hooks.code_graph.enabled: false`
22
+ * (`src/config/agent-settings.template.yml:1373-1374`), and
23
+ * `agent-config code-graph detect` in this checkout answers
24
+ * `no code-graph source detected`. There is no index to select against.
25
+ * · `src/scripts/discovery_graph.ts` — this suite's OWN artefact relation
26
+ * graph, five typed edges extracted from the discovery manifest's
27
+ * structured fields, with an `affected` BFS already implemented and
28
+ * answering. That is the surface this module builds on.
29
+ *
30
+ * The substitution changes what a "neighbourhood" means, and the difference is
31
+ * worth naming: the native engine would neighbour a candidate by SYMBOL
32
+ * relations, while `discovery_graph` neighbours it by ARTEFACT relations
33
+ * (`supersedes`, `routes_to`, `references_adr`, pack and workspace membership).
34
+ * For this roadmap's candidates — rules, skills, guidelines — the artefact
35
+ * graph is the one that carries the coupling a rewrite can break. For a
36
+ * candidate that edits a `.ts` symbol, it is the weaker surface, and this
37
+ * module says so through {@link selectionVerdict}: a touched surface absent
38
+ * from the graph is REFUSED, never silently neighboured with the empty set.
39
+ *
40
+ * ## Why an unresolved surface refuses instead of selecting nothing
41
+ *
42
+ * A selector whose neighbourhood lookup fails and then runs zero regressions
43
+ * reports a clean sheet, which is indistinguishable from a candidate that
44
+ * genuinely touches nothing coupled. That is exactly the "local improvement,
45
+ * global regression" hole the step exists to close, arriving through the
46
+ * selector rather than around it. So an unresolved touched surface is a
47
+ * refusal reason, and there is no option flag that relaxes it.
48
+ *
49
+ * ## Selects, never authors — carried by object identity (K9)
50
+ *
51
+ * K9 killed the curriculum generator. This module has no code path that
52
+ * constructs a {@link RegressionSpec}: every selected entry is an element of
53
+ * the registry the caller supplied, returned by reference, so
54
+ * `registry.includes(selected.spec)` holds by identity for every selection.
55
+ * A test asserts that identity rather than an id match, because an id match
56
+ * would also be satisfied by a synthesized spec carrying a copied id.
57
+ */
58
+ import { affected, isSyntheticNode, type Graph } from '../discovery_graph.js';
59
+
60
+ /**
61
+ * An EXISTING regression, as the registry holds it. `guards` names the artefact
62
+ * ids whose breakage this regression would detect.
63
+ *
64
+ * Nothing in this module builds one of these. It is the caller's registry entry,
65
+ * passed through by reference.
66
+ */
67
+ export interface RegressionSpec {
68
+ id: string;
69
+ guards: readonly string[];
70
+ }
71
+
72
+ /** A candidate under evaluation, reduced to the surfaces it touches. */
73
+ export interface Candidate {
74
+ id: string;
75
+ /** Artefact ids the candidate's diff touches. */
76
+ touches: readonly string[];
77
+ }
78
+
79
+ /** Why a node is in the neighbourhood: the candidate touched it, or a relation reached it. */
80
+ export type NeighbourReason = 'touched' | 'neighbour';
81
+
82
+ export interface NeighbourhoodNode {
83
+ node: string;
84
+ reason: NeighbourReason;
85
+ /** Hop distance from the nearest touched surface. `0` for a touched surface. */
86
+ depth: number;
87
+ /** The relation that reached it, or `''` for a touched surface. */
88
+ via: string;
89
+ /** True for `pack:` / `workspace:` container nodes the graph invents. */
90
+ synthetic: boolean;
91
+ }
92
+
93
+ export interface Selection {
94
+ spec: RegressionSpec;
95
+ /** The neighbourhood nodes this regression guards, sorted. */
96
+ matched: readonly string[];
97
+ /** `touched` when it guards a surface the candidate edited, else `neighbour`. */
98
+ reason: NeighbourReason;
99
+ }
100
+
101
+ export interface NeighbourhoodReport {
102
+ candidate_id: string;
103
+ neighbourhood: readonly NeighbourhoodNode[];
104
+ /** Touched surfaces that are not nodes in the graph. A refusal reason, not a warning. */
105
+ unresolved: readonly string[];
106
+ selected: readonly Selection[];
107
+ /** Registry entries whose guards intersect nothing in the neighbourhood. */
108
+ skipped: readonly string[];
109
+ /**
110
+ * Literal 0. This module selects from a registry; a non-zero value here
111
+ * would mean it authored a task, which is K9.
112
+ */
113
+ authored: 0;
114
+ }
115
+
116
+ /**
117
+ * Hops walked out from each touched surface.
118
+ *
119
+ * A STATED default, not a measured optimum. Two is the smallest depth that
120
+ * reaches a `routes_to` target AND that target's own container membership, so a
121
+ * rule edit neighbours the skill it routes to and the pack that skill sits in.
122
+ * `revisit-if` a run selects a regression nobody can explain from the diff, or
123
+ * a real breakage lands outside the two-hop set.
124
+ */
125
+ export const DEFAULT_NEIGHBOURHOOD_DEPTH = 2;
126
+
127
+ /**
128
+ * The neighbourhood of a candidate: every touched surface, plus everything the
129
+ * relation graph reaches from it within `depth` hops.
130
+ *
131
+ * Deterministic — nodes are emitted at their shallowest depth and sorted by
132
+ * `(depth, node)`, so two runs over the same graph produce byte-identical
133
+ * reports.
134
+ */
135
+ export function neighbourhood(
136
+ graph: Graph,
137
+ candidate: Candidate,
138
+ depth: number = DEFAULT_NEIGHBOURHOOD_DEPTH,
139
+ ): NeighbourhoodNode[] {
140
+ const best = new Map<string, NeighbourhoodNode>();
141
+ for (const t of candidate.touches) {
142
+ best.set(t, { node: t, reason: 'touched', depth: 0, via: '', synthetic: isSyntheticNode(t) });
143
+ }
144
+ for (const t of candidate.touches) {
145
+ for (const hit of affected(graph, t, depth)) {
146
+ const prior = best.get(hit.node);
147
+ if (prior !== undefined && prior.depth <= hit.depth) continue;
148
+ best.set(hit.node, {
149
+ node: hit.node,
150
+ reason: 'neighbour',
151
+ depth: hit.depth,
152
+ via: hit.via,
153
+ synthetic: isSyntheticNode(hit.node),
154
+ });
155
+ }
156
+ }
157
+ return [...best.values()].sort((a, b) => a.depth - b.depth || a.node.localeCompare(b.node));
158
+ }
159
+
160
+ /** Touched surfaces the graph does not know about. */
161
+ export function unresolvedSurfaces(graph: Graph, candidate: Candidate): string[] {
162
+ const known = new Set(graph.nodes);
163
+ return candidate.touches.filter((t) => !known.has(t)).sort((a, b) => a.localeCompare(b));
164
+ }
165
+
166
+ /**
167
+ * Select the registry entries whose guards intersect the candidate's
168
+ * neighbourhood.
169
+ *
170
+ * The returned `spec` values are the caller's registry objects, by reference.
171
+ */
172
+ export function selectRegressions(
173
+ graph: Graph,
174
+ candidate: Candidate,
175
+ registry: readonly RegressionSpec[],
176
+ depth: number = DEFAULT_NEIGHBOURHOOD_DEPTH,
177
+ ): NeighbourhoodReport {
178
+ const hood = neighbourhood(graph, candidate, depth);
179
+ const reasonOf = new Map<string, NeighbourReason>(hood.map((n) => [n.node, n.reason]));
180
+ const selected: Selection[] = [];
181
+ const skipped: string[] = [];
182
+ for (const spec of registry) {
183
+ const matched = spec.guards.filter((g) => reasonOf.has(g)).sort((a, b) => a.localeCompare(b));
184
+ if (matched.length === 0) {
185
+ skipped.push(spec.id);
186
+ continue;
187
+ }
188
+ const reason: NeighbourReason = matched.some((m) => reasonOf.get(m) === 'touched')
189
+ ? 'touched'
190
+ : 'neighbour';
191
+ selected.push({ spec, matched, reason });
192
+ }
193
+ return {
194
+ candidate_id: candidate.id,
195
+ neighbourhood: hood,
196
+ unresolved: unresolvedSurfaces(graph, candidate),
197
+ selected: selected.sort((a, b) => a.spec.id.localeCompare(b.spec.id)),
198
+ skipped: skipped.sort((a, b) => a.localeCompare(b)),
199
+ authored: 0,
200
+ };
201
+ }
202
+
203
+ /**
204
+ * `null` when the selection may be trusted, otherwise every reason it may not.
205
+ *
206
+ * Fail-closed by construction: no option object relaxes a reason, so a caller
207
+ * who wants to proceed on an unresolved surface has to delete this call — which
208
+ * is visible in a diff — rather than pass a flag, which is not.
209
+ */
210
+ export function selectionVerdict(report: NeighbourhoodReport): readonly string[] | null {
211
+ const reasons: string[] = [];
212
+ if (report.unresolved.length > 0) {
213
+ reasons.push(
214
+ `touched surfaces absent from the relation graph: ${report.unresolved.join(', ')} — ` +
215
+ 'their neighbourhood is unknown, and an unknown neighbourhood is not an empty one',
216
+ );
217
+ }
218
+ if (report.neighbourhood.length === 0) {
219
+ reasons.push('empty neighbourhood — the candidate touches nothing the graph knows');
220
+ }
221
+ return reasons.length === 0 ? null : reasons;
222
+ }
223
+
224
+ /** One regression's observed result on a candidate. */
225
+ export interface RegressionOutcome {
226
+ regression_id: string;
227
+ passed: boolean;
228
+ }
229
+
230
+ export interface CatchReport {
231
+ /** Selected regressions that FAILED — the breakages this selection caught. */
232
+ caught: readonly string[];
233
+ /**
234
+ * Regressions that failed but were never selected, so their failure was
235
+ * never observed. Present so a miss is countable rather than invisible.
236
+ */
237
+ missed: readonly string[];
238
+ }
239
+
240
+ /**
241
+ * Split observed regression outcomes by whether the selection actually ran them.
242
+ *
243
+ * `outcomes` is the full registry's result — what WOULD have been observed had
244
+ * everything run. `caught` is the part the neighbourhood selection reached;
245
+ * `missed` is the part it did not. A selector that narrows too far shows up
246
+ * here as a non-empty `missed`, which is what makes the fixture in
247
+ * `tests/scripts/regression_neighbourhood.test.ts` falsifiable.
248
+ */
249
+ export function catchReport(
250
+ report: NeighbourhoodReport,
251
+ outcomes: readonly RegressionOutcome[],
252
+ ): CatchReport {
253
+ const ran = new Set(report.selected.map((s) => s.spec.id));
254
+ const failed = outcomes.filter((o) => !o.passed).map((o) => o.regression_id);
255
+ return {
256
+ caught: failed.filter((id) => ran.has(id)).sort((a, b) => a.localeCompare(b)),
257
+ missed: failed.filter((id) => !ran.has(id)).sort((a, b) => a.localeCompare(b)),
258
+ };
259
+ }