@event4u/agent-config 14.12.0 → 14.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (466) hide show
  1. package/.augment-plugin/marketplace.json +3 -3
  2. package/.augment-plugin/plugin.json +1 -1
  3. package/.claude-plugin/marketplace.json +1 -1
  4. package/CHANGELOG.md +234 -0
  5. package/CONTRIBUTING.md +38 -0
  6. package/CREDITS.md +135 -0
  7. package/NOTICE +13 -0
  8. package/README.md +8 -6
  9. package/dist/agent-src/commands/analyze/inbox.md +109 -2
  10. package/dist/agent-src/commands/feature/dev.md +7 -2
  11. package/dist/agent-src/commands/ghostwriter/write.md +5 -1
  12. package/dist/agent-src/commands/implement-ticket.md +1 -1
  13. package/dist/agent-src/commands/mission/upgrade.md +1 -1
  14. package/dist/agent-src/commands/orchestrate.md +2 -2
  15. package/dist/agent-src/commands/post-as/me.md +5 -1
  16. package/dist/agent-src/commands/pr/merge.md +19 -6
  17. package/dist/agent-src/commands/roadmap/process-full.md +19 -5
  18. package/dist/agent-src/commands/tdd/red.md +12 -2
  19. package/dist/agent-src/commands/work.md +1 -1
  20. package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +40 -0
  21. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +5 -2
  22. package/dist/agent-src/contexts/execution/autonomy-mechanics.md +21 -0
  23. package/dist/agent-src/contexts/execution/orchestration-telemetry.md +1 -0
  24. package/dist/agent-src/contexts/execution/subagent-response-contract.md +40 -0
  25. package/dist/agent-src/contexts/execution/subagent-steering.md +13 -1
  26. package/dist/agent-src/contexts/execution/terminal-states.md +96 -0
  27. package/dist/agent-src/rules/artifact-drafting-protocol.md +1 -1
  28. package/dist/agent-src/rules/broken-access-control.md +4 -0
  29. package/dist/agent-src/rules/code-provenance.md +4 -0
  30. package/dist/agent-src/rules/design-fidelity.md +1 -1
  31. package/dist/agent-src/rules/domain-safety-pii.md +4 -0
  32. package/dist/agent-src/rules/domain-safety-retention.md +4 -0
  33. package/dist/agent-src/rules/engineering-safety-floor.md +2 -0
  34. package/dist/agent-src/rules/external-code-graph-interop.md +14 -12
  35. package/dist/agent-src/rules/improve-before-implement.md +6 -8
  36. package/dist/agent-src/rules/laravel-routing.md +1 -1
  37. package/dist/agent-src/rules/lethal-trifecta-guard.md +4 -0
  38. package/dist/agent-src/rules/secret-vcs-guard.md +2 -0
  39. package/dist/agent-src/rules/security-sensitive-stop.md +2 -0
  40. package/dist/agent-src/rules/source-confidentiality.md +12 -34
  41. package/dist/agent-src/rules/symfony-routing.md +1 -1
  42. package/dist/agent-src/rules/token-efficiency.md +14 -0
  43. package/dist/agent-src/rules/tool-safety.md +4 -0
  44. package/dist/agent-src/rules/untrusted-input-defense.md +4 -0
  45. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +247 -3
  46. package/dist/agent-src/scripts/guarded_baseline.ts +328 -0
  47. package/dist/agent-src/scripts/roadmap_set_step.ts +253 -0
  48. package/dist/agent-src/scripts/stub_queue.ts +82 -0
  49. package/dist/agent-src/scripts/stubs_due.ts +400 -0
  50. package/dist/agent-src/scripts/ticket_bundles.ts +84 -0
  51. package/dist/agent-src/scripts/update_roadmap_progress.ts +8 -4
  52. package/dist/agent-src/skills/brand-asset-generation/SKILL.md +17 -4
  53. package/dist/agent-src/skills/brand-audit/SKILL.md +33 -0
  54. package/dist/agent-src/skills/code-intelligence/SKILL.md +57 -0
  55. package/dist/agent-src/skills/database/SKILL.md +8 -0
  56. package/dist/agent-src/skills/dependency-upgrade/SKILL.md +27 -0
  57. package/dist/agent-src/skills/design-review/SKILL.md +1 -1
  58. package/dist/agent-src/skills/doc-coauthoring/SKILL.md +1 -1
  59. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +17 -1
  60. package/dist/agent-src/skills/feature-planning/SKILL.md +9 -2
  61. package/dist/agent-src/skills/frontend-render-security/SKILL.md +44 -0
  62. package/dist/agent-src/skills/git-workflow/SKILL.md +1 -1
  63. package/dist/agent-src/skills/js-library-packaging/scripts/check_package_surface.ts +38 -4
  64. package/dist/agent-src/skills/judge-artifact-completeness/rubrics/ticket-quality-score.json +2 -2
  65. package/dist/agent-src/skills/laravel/SKILL.md +35 -0
  66. package/dist/agent-src/skills/laravel-migration/SKILL.md +57 -3
  67. package/dist/agent-src/skills/monorepo-workspace/SKILL.md +26 -0
  68. package/dist/agent-src/skills/playbook-authoring/SKILL.md +28 -1
  69. package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +1 -1
  70. package/dist/agent-src/skills/skill-writing/references/procedure.md +5 -5
  71. package/dist/agent-src/skills/sql-writing/SKILL.md +7 -1
  72. package/dist/agent-src/skills/standards-from-config/SKILL.md +27 -4
  73. package/dist/agent-src/skills/supply-chain-intake/SKILL.md +11 -4
  74. package/dist/agent-src/skills/symfony-workflow/SKILL.md +35 -0
  75. package/dist/agent-src/skills/test-case-discovery/SKILL.md +85 -0
  76. package/dist/agent-src/skills/test-driven-development/SKILL.md +33 -9
  77. package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
  78. package/dist/agent-src/skills/testing-anti-patterns/process-anti-patterns.md +37 -0
  79. package/dist/agent-src/skills/ui-component-architect/SKILL.md +45 -2
  80. package/dist/agent-src/skills/upstream-contribute/SKILL.md +38 -1
  81. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +9 -4
  82. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  83. package/dist/agent-src/templates/roadmaps.md +97 -3
  84. package/dist/agent-src/templates/scripts/check_memory.ts +258 -17
  85. package/dist/agent-src/templates/scripts/check_memory_proposal.ts +9 -3
  86. package/dist/agent-src/templates/scripts/memory_lookup.ts +86 -0
  87. package/dist/agent-src/templates/scripts/memory_signal.ts +44 -0
  88. package/dist/agent-src/templates/scripts/work_engine/directives/backend/implement.ts +90 -0
  89. package/dist/agent-src/templates/scripts/work_engine/directives/backend/index.ts +11 -0
  90. package/dist/agent-src/templates/scripts/work_engine/directives/backend/test.ts +23 -1
  91. package/dist/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +10 -1
  92. package/dist/agent-src/templates/scripts/work_engine/directives/mixed/stitch.ts +5 -1
  93. package/dist/agent-src/templates/scripts/work_engine/stack/runner.ts +102 -14
  94. package/dist/cli/commands/uiAudit.js +124 -5
  95. package/dist/cli/registry.js +2 -0
  96. package/dist/cli-delegate/{chunk-HYWSRNUX.js → chunk-2DK2VJWG.js} +3 -3
  97. package/dist/cli-delegate/{chunk-JCW7ZLHK.js → chunk-4FS4WRXP.js} +5 -0
  98. package/dist/cli-delegate/{chunk-OMIVVCG2.js → chunk-A4QJ6ENT.js} +24 -0
  99. package/dist/cli-delegate/{chunk-JJA2QEWA.js → chunk-AKJGUQNO.js} +466 -285
  100. package/dist/cli-delegate/{chunk-E46KPN6K.js → chunk-BTWUYDGN.js} +424 -363
  101. package/dist/cli-delegate/{chunk-K4FFODTS.js → chunk-ILMUPLGW.js} +1227 -316
  102. package/dist/cli-delegate/{chunk-FF7WAFMR.js → chunk-KPBWFOPZ.js} +5 -1
  103. package/dist/cli-delegate/cmd_adr_effective.js +102 -0
  104. package/dist/cli-delegate/cmd_conformance.js +42 -10
  105. package/dist/cli-delegate/cmd_doctor.js +3 -3
  106. package/dist/cli-delegate/cmd_export.js +3 -2
  107. package/dist/cli-delegate/cmd_fleet.js +2 -2
  108. package/dist/cli-delegate/cmd_handoff.js +1 -1
  109. package/dist/cli-delegate/cmd_preflight.js +2 -2
  110. package/dist/cli-delegate/cmd_prune.js +3 -2
  111. package/dist/cli-delegate/cmd_settings_get.js +1 -1
  112. package/dist/cli-delegate/cmd_settings_migrate.js +3 -2
  113. package/dist/cli-delegate/cmd_settings_set.js +2 -2
  114. package/dist/cli-delegate/cmd_sync.js +3 -2
  115. package/dist/cli-delegate/cmd_uninstall.js +3 -2
  116. package/dist/cli-delegate/cmd_validate.js +3 -2
  117. package/dist/discovery/deprecation-report.md +1 -1
  118. package/dist/discovery/discovery-manifest.json +57 -57
  119. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  120. package/dist/discovery/discovery-manifest.summary.md +1 -1
  121. package/dist/discovery/dormancy-report.md +1 -1
  122. package/dist/discovery/orphan-report.md +1 -1
  123. package/dist/discovery/packs.json +2 -2
  124. package/dist/discovery/trust-report.md +1 -1
  125. package/dist/discovery/workspaces.json +2 -2
  126. package/dist/hooks/dispatch.js +1836 -712
  127. package/dist/install/claudeRuleRewrite.js +254 -0
  128. package/dist/install/detect.js +29 -16
  129. package/dist/install/detect_php_shape.js +159 -0
  130. package/dist/install/install.mjs +634 -428
  131. package/dist/mcp/awesome-mcp-servers.row.md +1 -1
  132. package/dist/mcp/mcp-cloudflare-catalogue.json +1 -1
  133. package/dist/mcp/registry-manifest.json +3 -3
  134. package/dist/mcp/server.json +3 -3
  135. package/dist/mcp/server.mjs +4818 -2645
  136. package/dist/server/schemas/settings.js +3 -0
  137. package/dist/ui/assets/index-D0jaCRPM.js +29 -0
  138. package/dist/ui/index.html +1 -1
  139. package/docs/MIGRATION.md +1 -1
  140. package/docs/THIRD-PARTY-NOTICES.md +25 -0
  141. package/docs/contracts/provider-lifecycle.md +1 -1
  142. package/docs/contracts/settings-classes.md +10 -4
  143. package/docs/guidelines/agent-infra/5w2h-analysis.md +3 -3
  144. package/docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md +1 -0
  145. package/docs/guidelines/agent-infra/artifact-drafting-protocol-mechanics.md +58 -3
  146. package/docs/guidelines/agent-infra/ask-when-uncertain-demos.md +2 -2
  147. package/docs/guidelines/agent-infra/asking-and-brevity-examples.md +3 -3
  148. package/docs/guidelines/agent-infra/break-glass-usage.md +7 -7
  149. package/docs/guidelines/agent-infra/carve-out-predicates.md +3 -3
  150. package/docs/guidelines/agent-infra/comparison-matrix.md +1 -1
  151. package/docs/guidelines/agent-infra/critical-thinking.md +4 -4
  152. package/docs/guidelines/agent-infra/direct-answers-demos.md +2 -2
  153. package/docs/guidelines/agent-infra/domain-eval-anti-pattern.md +1 -1
  154. package/docs/guidelines/agent-infra/engineering-memory-data-format.md +3 -3
  155. package/docs/guidelines/agent-infra/existence-question-verdicts.md +80 -0
  156. package/docs/guidelines/agent-infra/first-principles.md +2 -2
  157. package/docs/guidelines/agent-infra/framework-neutrality-patterns.md +2 -2
  158. package/docs/guidelines/agent-infra/guarded-baseline.md +39 -0
  159. package/docs/guidelines/agent-infra/inversion-thinking.md +5 -5
  160. package/docs/guidelines/agent-infra/language-and-tone-examples.md +1 -1
  161. package/docs/guidelines/agent-infra/layered-settings.md +10 -10
  162. package/docs/guidelines/agent-infra/memory-access.md +1 -1
  163. package/docs/guidelines/agent-infra/mental-models.md +3 -3
  164. package/docs/guidelines/agent-infra/reuse-verdict-mechanics.md +71 -0
  165. package/docs/guidelines/agent-infra/review-routing-data-format.md +7 -7
  166. package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +13 -7
  167. package/docs/guidelines/agent-infra/role-contracts.md +2 -2
  168. package/docs/guidelines/agent-infra/role-mode-router.md +3 -3
  169. package/docs/guidelines/agent-infra/rule-type-governance.md +2 -2
  170. package/docs/guidelines/agent-infra/scqa-framework.md +5 -5
  171. package/docs/guidelines/agent-infra/self-improvement-pipeline.md +6 -6
  172. package/docs/guidelines/agent-infra/simplicity-and-goal-demos.md +2 -2
  173. package/docs/guidelines/agent-infra/six-hats.md +3 -3
  174. package/docs/guidelines/agent-infra/skill-quality-checklist.md +6 -6
  175. package/docs/guidelines/agent-infra/source-confidentiality-mechanics.md +109 -0
  176. package/docs/guidelines/agent-infra/systems-thinking.md +1 -1
  177. package/docs/guidelines/agent-infra/verify-before-complete-demos.md +2 -2
  178. package/docs/guidelines/augment-portability-patterns.md +6 -4
  179. package/docs/guidelines/component-oriented-and-oop-development.md +3 -2
  180. package/docs/guidelines/cross-role-handoff.md +2 -2
  181. package/docs/guidelines/design-fidelity-mechanics.md +1 -1
  182. package/docs/guidelines/docs/readme-size-and-splitting.md +3 -3
  183. package/docs/guidelines/php/database.md +90 -7
  184. package/docs/guidelines/prompt-templates.md +7 -7
  185. package/llms.txt +2 -2
  186. package/package.json +5 -2
  187. package/src/agent-src/scripts/archive_completed_roadmaps.ts +247 -3
  188. package/src/agent-src/scripts/guarded_baseline.ts +328 -0
  189. package/src/agent-src/scripts/roadmap_set_step.ts +253 -0
  190. package/src/agent-src/scripts/stub_queue.ts +82 -0
  191. package/src/agent-src/scripts/stubs_due.ts +400 -0
  192. package/src/agent-src/scripts/ticket_bundles.ts +84 -0
  193. package/src/agent-src/scripts/update_roadmap_progress.ts +8 -4
  194. package/src/agent-src/templates/scripts/check_memory.ts +258 -17
  195. package/src/agent-src/templates/scripts/check_memory_proposal.ts +9 -3
  196. package/src/agent-src/templates/scripts/memory_lookup.ts +86 -0
  197. package/src/agent-src/templates/scripts/memory_signal.ts +44 -0
  198. package/src/agent-src/templates/scripts/work_engine/directives/backend/implement.ts +90 -0
  199. package/src/agent-src/templates/scripts/work_engine/directives/backend/index.ts +11 -0
  200. package/src/agent-src/templates/scripts/work_engine/directives/backend/test.ts +23 -1
  201. package/src/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +10 -1
  202. package/src/agent-src/templates/scripts/work_engine/directives/mixed/stitch.ts +5 -1
  203. package/src/agent-src/templates/scripts/work_engine/stack/runner.ts +102 -14
  204. package/src/config/agent-settings.template.yml +32 -3
  205. package/src/config/assurance-capability-registry.json +21 -9
  206. package/src/config/canonical-terms.yml +119 -0
  207. package/src/config/capability-native-outcome-bars.json +81 -0
  208. package/src/config/ci-local-parity.yml +80 -0
  209. package/src/config/drafting-channels.yml +43 -0
  210. package/src/config/estate-count-budget.json +38 -36
  211. package/src/config/evaluator-budgets.json +14 -14
  212. package/src/config/gate-coverage.yml +579 -63
  213. package/src/config/gate-reachability-exemptions.json +21 -0
  214. package/src/config/gate-violation-baselines.json +37 -19
  215. package/src/config/harness-evolution-budget.json +25 -0
  216. package/src/config/lapsed-beta-baseline.json +96 -0
  217. package/src/config/memory-twin-verdicts.yml +129 -0
  218. package/src/config/metric-registry.yml +124 -0
  219. package/src/config/pack-size-budget.json +16 -15
  220. package/src/config/preamble-payload-budget.json +8 -8
  221. package/src/config/profiles/balanced.ini +27 -0
  222. package/src/config/profiles/full.ini +27 -0
  223. package/src/config/profiles/minimal.ini +27 -0
  224. package/src/config/publish-surface.json +9 -2
  225. package/src/config/routing-coverage-seed.json +16 -2
  226. package/src/config/rule-stub-ceilings.json +126 -112
  227. package/src/config/turnaround-budget.json +66 -0
  228. package/src/install/claudeRuleRewrite.ts +288 -0
  229. package/src/install/detect.ts +60 -17
  230. package/src/install/detect_php_shape.ts +191 -0
  231. package/src/scripts/_cli/cmd_doctor.ts +27 -112
  232. package/src/scripts/_dispatch.bash +27 -0
  233. package/src/scripts/_lib/activation_ladder.ts +211 -0
  234. package/src/scripts/_lib/activation_states.ts +88 -0
  235. package/src/scripts/_lib/adherence_detectors.ts +143 -0
  236. package/src/scripts/_lib/arith_claims.ts +181 -0
  237. package/src/scripts/_lib/arm_ranking.ts +62 -0
  238. package/src/scripts/_lib/asset_delivery_ledger.ts +303 -0
  239. package/src/scripts/_lib/audit_field_provenance.ts +54 -0
  240. package/src/scripts/_lib/auto_dispatch.ts +32 -3
  241. package/src/scripts/_lib/bench_ab_size_claim.ts +98 -4
  242. package/src/scripts/_lib/benchmark_cache_fields.ts +158 -0
  243. package/src/scripts/_lib/candidate_proposer.ts +402 -0
  244. package/src/scripts/_lib/candidate_record.ts +601 -0
  245. package/src/scripts/_lib/capture_rate.ts +319 -0
  246. package/src/scripts/_lib/collector_denominator.ts +771 -0
  247. package/src/scripts/_lib/collector_record.ts +340 -0
  248. package/src/scripts/_lib/collector_store.ts +664 -0
  249. package/src/scripts/_lib/collector_supervision.ts +827 -0
  250. package/src/scripts/_lib/concern_estate.ts +77 -0
  251. package/src/scripts/_lib/config_chain.ts +477 -0
  252. package/src/scripts/_lib/config_cost.ts +209 -0
  253. package/src/scripts/_lib/council_settings_block.ts +6 -0
  254. package/src/scripts/_lib/curator_ops.ts +172 -0
  255. package/src/scripts/_lib/delivery_arm_experiment.ts +266 -0
  256. package/src/scripts/_lib/delivery_criticality.ts +126 -0
  257. package/src/scripts/_lib/doctor_runtime_checks.ts +70 -0
  258. package/src/scripts/_lib/empty_cycles.ts +88 -0
  259. package/src/scripts/_lib/eval_publication.ts +354 -0
  260. package/src/scripts/_lib/evaluation_vector.ts +283 -0
  261. package/src/scripts/_lib/evaluator_promotion.ts +225 -0
  262. package/src/scripts/_lib/evidence_basis.ts +118 -0
  263. package/src/scripts/_lib/exec_evidence.ts +8 -0
  264. package/src/scripts/_lib/experience_card.ts +272 -0
  265. package/src/scripts/_lib/experience_report.ts +151 -0
  266. package/src/scripts/_lib/experiment_freeze.ts +112 -0
  267. package/src/scripts/_lib/generated_by.ts +66 -0
  268. package/src/scripts/_lib/harness_evolution_guards.ts +229 -0
  269. package/src/scripts/_lib/hook_effect_probe.ts +141 -0
  270. package/src/scripts/_lib/host_denominator.ts +687 -0
  271. package/src/scripts/_lib/host_projection_reach.ts +157 -0
  272. package/src/scripts/_lib/ignored_blocker.ts +148 -0
  273. package/src/scripts/_lib/install_reach_checks.ts +495 -0
  274. package/src/scripts/_lib/json_duplicate_keys.ts +150 -0
  275. package/src/scripts/_lib/judge_hygiene.ts +228 -0
  276. package/src/scripts/_lib/legacy_boundary_map.ts +228 -0
  277. package/src/scripts/_lib/loop_guards.ts +299 -0
  278. package/src/scripts/_lib/loss_class.ts +129 -0
  279. package/src/scripts/_lib/machine_wake.ts +51 -0
  280. package/src/scripts/_lib/md_prose_lines.ts +177 -0
  281. package/src/scripts/_lib/minimality_tiebreak.ts +168 -0
  282. package/src/scripts/_lib/one_resolver_invariant.ts +449 -0
  283. package/src/scripts/_lib/orchestration_record.ts +253 -5
  284. package/src/scripts/_lib/outcome_envelope.ts +227 -0
  285. package/src/scripts/_lib/outcome_vocabularies.ts +125 -0
  286. package/src/scripts/_lib/paired_stats.ts +245 -0
  287. package/src/scripts/_lib/paired_verdict.ts +226 -0
  288. package/src/scripts/_lib/prefix_stable_surfaces.ts +123 -0
  289. package/src/scripts/_lib/privacy_class.ts +47 -0
  290. package/src/scripts/_lib/regression_neighbourhood.ts +259 -0
  291. package/src/scripts/_lib/repeated_failure.ts +105 -0
  292. package/src/scripts/_lib/repo_root.ts +111 -0
  293. package/src/scripts/_lib/review_skipped_record.ts +37 -0
  294. package/src/scripts/_lib/role_split.ts +338 -0
  295. package/src/scripts/_lib/runtime_journal.ts +1499 -0
  296. package/src/scripts/_lib/runtime_wiring_checks.ts +430 -0
  297. package/src/scripts/_lib/skill_catalogue.ts +11 -1
  298. package/src/scripts/_lib/source_digest.ts +200 -0
  299. package/src/scripts/_lib/source_redact.ts +260 -0
  300. package/src/scripts/_lib/source_shape.ts +502 -0
  301. package/src/scripts/_lib/source_snapshot_dedup.ts +199 -0
  302. package/src/scripts/_lib/strip_comments.d.mts +8 -0
  303. package/src/scripts/_lib/strip_comments.mjs +65 -0
  304. package/src/scripts/_lib/test_red_state.ts +154 -0
  305. package/src/scripts/_lib/trigger_shift.ts +144 -0
  306. package/src/scripts/_lib/untrusted_content.ts +82 -7
  307. package/src/scripts/adoption_report.ts +1 -1
  308. package/src/scripts/adr/evidence_census.ts +1 -1
  309. package/src/scripts/adr/regenerate_index.ts +26 -2
  310. package/src/scripts/adr_cite_check.ts +164 -1
  311. package/src/scripts/ai_council/blind_review.ts +11 -1
  312. package/src/scripts/ai_council/clients.ts +4 -0
  313. package/src/scripts/ai_council/config.ts +3 -0
  314. package/src/scripts/ai_council/consensus.ts +28 -8
  315. package/src/scripts/ai_council/consensus_round.ts +226 -0
  316. package/src/scripts/ai_council/disagreement_signal.ts +338 -0
  317. package/src/scripts/ai_council/inline_findings.ts +340 -0
  318. package/src/scripts/ai_council/judge_position_bias.ts +197 -0
  319. package/src/scripts/ai_council/orchestrator.ts +16 -203
  320. package/src/scripts/ai_council/orchestrator_results.ts +23 -3
  321. package/src/scripts/ai_council/pricing.ts +106 -0
  322. package/src/scripts/ai_council/prompts.ts +74 -7
  323. package/src/scripts/ai_council/provider_leakage_bench.ts +327 -0
  324. package/src/scripts/ai_council/py_format.ts +14 -3
  325. package/src/scripts/ai_council/recouncil_guard.ts +293 -0
  326. package/src/scripts/ai_council/response_record.ts +50 -0
  327. package/src/scripts/ai_council/topology_bench_manifest.ts +860 -0
  328. package/src/scripts/ai_council/topology_vocabulary.ts +175 -0
  329. package/src/scripts/asset_delivery_ledger.ts +157 -0
  330. package/src/scripts/attest_artifact.ts +193 -0
  331. package/src/scripts/audit_auto_rules.ts +2 -1
  332. package/src/scripts/audit_command_surface.ts +1 -1
  333. package/src/scripts/audit_mcp_tools.ts +2 -2
  334. package/src/scripts/audit_skill_overlap_allowlist.json +6 -1
  335. package/src/scripts/audit_user_type_axis.ts +2 -1
  336. package/src/scripts/bench_ab_clone.ts +215 -10
  337. package/src/scripts/bench_ab_integrity.ts +119 -5
  338. package/src/scripts/bench_ab_v2_stats.ts +40 -213
  339. package/src/scripts/build_archive_index.ts +1 -1
  340. package/src/scripts/build_linear_digest.ts +1 -1
  341. package/src/scripts/build_proof.ts +11 -4
  342. package/src/scripts/build_rule_trigger_matrix.ts +1 -1
  343. package/src/scripts/build_source_digests.ts +157 -0
  344. package/src/scripts/cache_realization_report.ts +103 -0
  345. package/src/scripts/check_adr_frontmatter.ts +126 -0
  346. package/src/scripts/check_benchmark_report_fields.ts +207 -0
  347. package/src/scripts/check_beta_review_markers.ts +235 -6
  348. package/src/scripts/check_bundle_path_leakage.ts +34 -1
  349. package/src/scripts/check_claims.ts +576 -6
  350. package/src/scripts/check_composite_arming.ts +35 -0
  351. package/src/scripts/check_concern_admissions.ts +365 -0
  352. package/src/scripts/check_enforcement_coverage.ts +28 -0
  353. package/src/scripts/check_estate_count.ts +142 -1
  354. package/src/scripts/check_gate_reachability.ts +383 -0
  355. package/src/scripts/check_host_loadability.ts +104 -0
  356. package/src/scripts/check_loss_class_declared.ts +308 -0
  357. package/src/scripts/check_md_language.ts +15 -98
  358. package/src/scripts/check_memory_proposal.ts +18 -11
  359. package/src/scripts/check_no_currency_in_cost_surfaces.ts +225 -0
  360. package/src/scripts/check_no_external_sources.ts +281 -6
  361. package/src/scripts/check_pack_conformance_fixture.ts +11 -1
  362. package/src/scripts/check_pack_size.ts +59 -2
  363. package/src/scripts/check_preamble_payload_budget.ts +114 -3
  364. package/src/scripts/check_prefix_stable_mutation.ts +372 -0
  365. package/src/scripts/check_publish_surface.ts +10 -1
  366. package/src/scripts/check_references.ts +24 -1
  367. package/src/scripts/check_rule_evidence_declaration.ts +316 -0
  368. package/src/scripts/check_rule_projection_integrity.ts +14 -4
  369. package/src/scripts/check_score_contract.ts +26 -3
  370. package/src/scripts/check_static_parity.ts +285 -0
  371. package/src/scripts/check_supervision_claim_atomicity.ts +498 -0
  372. package/src/scripts/check_suppression_hygiene.ts +15 -0
  373. package/src/scripts/ci_settle.ts +39 -2
  374. package/src/scripts/code_graph/build.ts +60 -3
  375. package/src/scripts/code_graph/extract.ts +44 -0
  376. package/src/scripts/code_graph/types.ts +24 -0
  377. package/src/scripts/collector_daemon.ts +714 -0
  378. package/src/scripts/config_cost_report.ts +302 -0
  379. package/src/scripts/consumer_matrix.ts +74 -1
  380. package/src/scripts/cost/budget.mjs +10 -3
  381. package/src/scripts/cost/track.mjs +10 -3
  382. package/src/scripts/council_cli.ts +37 -54
  383. package/src/scripts/dispatch_r2_reviewer.ts +46 -5
  384. package/src/scripts/evolution_lab.ts +980 -0
  385. package/src/scripts/external_sources_denylist.json +5 -18
  386. package/src/scripts/extract_audit_patterns.ts +21 -0
  387. package/src/scripts/fold_intake.ts +12 -1
  388. package/src/scripts/gen_discovery_baseline.ts +1 -1
  389. package/src/scripts/generate_capabilities_index.ts +12 -5
  390. package/src/scripts/generate_capability_matrix.ts +3 -3
  391. package/src/scripts/generate_command_flows.ts +2 -2
  392. package/src/scripts/generate_cookbook.ts +2 -2
  393. package/src/scripts/generate_index.ts +8 -1
  394. package/src/scripts/generate_knowledge_index.ts +2 -1
  395. package/src/scripts/generate_ownership_matrix.ts +2 -1
  396. package/src/scripts/generate_pack_manifests.ts +10 -2
  397. package/src/scripts/generate_role_experiences_catalog.ts +2 -2
  398. package/src/scripts/generate_settings_reference.ts +1 -1
  399. package/src/scripts/git_authorization_hook.ts +22 -1
  400. package/src/scripts/grade_target_readiness.ts +48 -5
  401. package/src/scripts/hook_effect_doctor.ts +261 -0
  402. package/src/scripts/hook_manifest.json +1 -1
  403. package/src/scripts/hook_manifest.yaml +98 -11
  404. package/src/scripts/hooks/block_speaking_inbox_dir.ts +271 -0
  405. package/src/scripts/hooks/block_unauthorized_git.ts +18 -0
  406. package/src/scripts/hooks/concern_registry.ts +4 -0
  407. package/src/scripts/hooks/dispatch_hook.ts +32 -0
  408. package/src/scripts/hooks/journal_record_hook.ts +345 -0
  409. package/src/scripts/hooks/prepush_metadata_sources.sh +110 -0
  410. package/src/scripts/hooks/run_continuation_hook.ts +44 -9
  411. package/src/scripts/hooks/shims/install.sh +61 -0
  412. package/src/scripts/hooks/shims/php +101 -0
  413. package/src/scripts/hooks/suggestion_capture_hook.ts +10 -0
  414. package/src/scripts/hot_context_hook.ts +16 -0
  415. package/src/scripts/install-hooks.sh +20 -5
  416. package/src/scripts/install.ts +17 -35
  417. package/src/scripts/inventory_frontmatter.ts +2 -1
  418. package/src/scripts/lint_adr_sweep_routing.ts +12 -0
  419. package/src/scripts/lint_canonical_terms.ts +604 -0
  420. package/src/scripts/lint_composition_review.ts +619 -0
  421. package/src/scripts/lint_consolidation_lineage.ts +666 -0
  422. package/src/scripts/lint_eval_specs.ts +593 -0
  423. package/src/scripts/lint_hook_manifest.ts +19 -0
  424. package/src/scripts/lint_host_portability.ts +373 -0
  425. package/src/scripts/lint_judge_prompt_expectation.ts +27 -1
  426. package/src/scripts/lint_memory_twin_parity.ts +335 -0
  427. package/src/scripts/lint_metric_consumers.ts +355 -0
  428. package/src/scripts/lint_skill_descriptions.ts +18 -1
  429. package/src/scripts/lint_skill_frontmatter_safety.ts +58 -0
  430. package/src/scripts/lint_skill_link_reach.ts +252 -0
  431. package/src/scripts/lint_skill_trigger_corpus.ts +426 -23
  432. package/src/scripts/lint_ticket_buildable.ts +17 -1
  433. package/src/scripts/mcp_server/consumer_tool_catalog.json +1 -1
  434. package/src/scripts/mcp_server/tool_catalog_source.ts +1 -1
  435. package/src/scripts/measure_docs_dead_links.ts +348 -0
  436. package/src/scripts/measure_host_capture.ts +461 -0
  437. package/src/scripts/migration_status.ts +3 -3
  438. package/src/scripts/model_rule_injection.ts +60 -0
  439. package/src/scripts/orchestration_record.ts +14 -0
  440. package/src/scripts/preamble_byte_census.ts +139 -10
  441. package/src/scripts/prepack-check.mjs +4 -1
  442. package/src/scripts/probe_turnaround.ts +384 -0
  443. package/src/scripts/probe_unblocked_ask.ts +279 -0
  444. package/src/scripts/render_benchmark_md.ts +1 -1
  445. package/src/scripts/rule_activation_census.ts +70 -9
  446. package/src/scripts/rule_backlinks.ts +1 -1
  447. package/src/scripts/run_lifecycle_suite.ts +208 -0
  448. package/src/scripts/run_skill_evals.ts +40 -0
  449. package/src/scripts/schemas/delivery-manifest.schema.json +43 -0
  450. package/src/scripts/schemas/drafting-channels.schema.json +43 -0
  451. package/src/scripts/schemas/evals.schema.json +24 -1
  452. package/src/scripts/schemas/rule.schema.json +52 -1
  453. package/src/scripts/schemas/skill.schema.json +17 -2
  454. package/src/scripts/skill_overlap.ts +7 -1
  455. package/src/scripts/skill_tools/run_block_d_eval.ts +8 -1
  456. package/src/scripts/skill_tools/score_skill_relevance.ts +84 -3
  457. package/src/scripts/skill_tools/suggest_skill_for_task.ts +8 -1
  458. package/src/scripts/skill_usage_report.ts +2 -1
  459. package/src/scripts/stubs_due.ts +211 -0
  460. package/src/scripts/sweep_source_surfaces.ts +678 -0
  461. package/src/scripts/sync_pr_branch.ts +3 -3
  462. package/src/scripts/trigger_eval_grandfather.json +202 -222
  463. package/src/scripts/utilization_report.ts +22 -2
  464. package/src/server/schemas/settings.ts +5 -0
  465. package/src/templates/marketing-copy.yml +1 -1
  466. package/dist/ui/assets/index-Cxgy63kz.js +0 -26
@@ -0,0 +1,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
+ }
@@ -0,0 +1,105 @@
1
+ /**
2
+ * The repeated-failure rate — computed over the AMENDED view, by construction.
3
+ *
4
+ * This is the roadmap's single pre-registered core metric, and the reason it
5
+ * needed the amendment path first is arithmetic rather than aesthetic. A repeat
6
+ * is precisely the signal that surfaces AFTER an episode's terminal record is
7
+ * written: rework lands, a regression is found, a review comes back. A rate
8
+ * computed over unamended rows therefore undercounts the exact thing it exists
9
+ * to measure, and undercounts it in the flattering direction.
10
+ *
11
+ * The guarantee here is structural, not documentary: this module's input type
12
+ * is {@link EpisodeReconstruction}, which is the folded projection. It has no
13
+ * overload taking raw `JournalEvent[]`, so a caller CANNOT accidentally compute
14
+ * the rate over unamended rows — there is nothing to pass.
15
+ */
16
+
17
+ import type { BasisTag } from './evidence_basis.js';
18
+ import type { EpisodeReconstruction } from './runtime_journal.js';
19
+ import { RUN_TERMINAL_STATES, type RunTerminalState } from './outcome_vocabularies.js';
20
+
21
+ /**
22
+ * Terminal states that count as a failure for this metric.
23
+ *
24
+ * `clean-no-op` is deliberately NOT a failure: an episode that correctly
25
+ * determined there was nothing to do succeeded at the thing it was asked. And
26
+ * `approval-required` is not one either — it is the safety floor working, and
27
+ * counting a floor doing its job as a failure would make the metric fall every
28
+ * time governance fires.
29
+ */
30
+ export const FAILURE_TERMINALS: ReadonlySet<RunTerminalState> = new Set([
31
+ 'blocked',
32
+ 'exhausted',
33
+ 'stagnated',
34
+ ]);
35
+
36
+ /** States that count as a success for the metric. */
37
+ export const SUCCESS_TERMINALS: ReadonlySet<RunTerminalState> = new Set([
38
+ 'success',
39
+ 'clean-no-op',
40
+ ]);
41
+
42
+ // Every terminal state is classified or deliberately excluded -- silence about
43
+ // one is how a metric quietly changes meaning when the vocabulary grows.
44
+ const CLASSIFIED = new Set<string>([...FAILURE_TERMINALS, ...SUCCESS_TERMINALS, 'approval-required']);
45
+ const _unclassified = RUN_TERMINAL_STATES.filter((t) => !CLASSIFIED.has(t));
46
+ if (_unclassified.length > 0) {
47
+ throw new Error(
48
+ `repeated_failure: terminal state(s) ${_unclassified.join(', ')} are neither a failure, ` +
49
+ 'a success, nor explicitly excluded. Classify them or the rate silently changes meaning.',
50
+ );
51
+ }
52
+
53
+ export interface RepeatedFailureRate {
54
+ /** Episodes whose EFFECTIVE terminal state is a failure. */
55
+ failed: number;
56
+ /** Episodes with any classifiable effective terminal state. */
57
+ classified: number;
58
+ /** Episodes whose terminal state is absent or excluded. Its own share. */
59
+ unknown: number;
60
+ /** `failed / classified`, or `null` when nothing was classifiable. */
61
+ rate: number | null;
62
+ /** How many of the counted episodes carried at least one amendment. */
63
+ amended_episodes: number;
64
+ basis: BasisTag;
65
+ }
66
+
67
+ /**
68
+ * Compute the rate.
69
+ *
70
+ * `rate` is `null`, never `0`, when nothing classifiable was seen — the same
71
+ * rule the per-asset report follows, for the same reason: zero is a measurement
72
+ * and null is an absence, and a reader acts on the first while asking about the
73
+ * second.
74
+ */
75
+ export function repeatedFailureRate(
76
+ episodes: readonly EpisodeReconstruction[],
77
+ ): RepeatedFailureRate {
78
+ let failed = 0;
79
+ let classified = 0;
80
+ let unknown = 0;
81
+ let amended_episodes = 0;
82
+
83
+ for (const ep of episodes) {
84
+ if (ep.amendment_count > 0) amended_episodes += 1;
85
+
86
+ // `ep.terminal_state` is already the AMENDED verdict: reconstructEpisode
87
+ // drops superseded rows and takes the LAST effective terminal state.
88
+ const t = ep.terminal_state;
89
+ if (t === null || !CLASSIFIED.has(t) || t === 'approval-required') {
90
+ unknown += 1;
91
+ continue;
92
+ }
93
+ classified += 1;
94
+ if (FAILURE_TERMINALS.has(t)) failed += 1;
95
+ }
96
+
97
+ return {
98
+ failed,
99
+ classified,
100
+ unknown,
101
+ rate: classified === 0 ? null : failed / classified,
102
+ amended_episodes,
103
+ basis: 'estimated:ratio-over-amended-episode-terminals',
104
+ };
105
+ }
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Repository-root resolution that REFUSES rather than guesses.
3
+ *
4
+ * `road-to-skill-ecosystem-runtime-enforcement` Phase 2 Step 6. The trap class
5
+ * this closes is small to describe and has cost multiple sessions:
6
+ *
7
+ * 1. **An inherited `GIT_DIR`.** A git hook exports `GIT_DIR` (often `.git`,
8
+ * relative) into every child process. A gate that resolves its root with
9
+ * `git rev-parse --show-toplevel` then answers for whatever repository the
10
+ * inherited variable points at — which inside a worktree hook is the parent
11
+ * checkout, not the tree being committed. The gate runs, reads the wrong
12
+ * files, and passes.
13
+ * 2. **A path walked one directory too far.** `path.resolve(__dirname, '..',
14
+ * '..')` is correct until a file moves, and then it silently addresses a
15
+ * parent directory that also exists. Nothing fails; the scan is simply
16
+ * empty, which several gates report as a clean pass.
17
+ *
18
+ * Both are the same failure in the end: a resolver that always SUCCEEDS. So the
19
+ * contract here is the opposite — a root is returned only when the directory
20
+ * carries a **sentinel** proving it is the repository, and otherwise the call
21
+ * throws. A caller that cannot locate its own repository should stop, not scan
22
+ * an arbitrary directory.
23
+ *
24
+ * The sentinel is `package.json` carrying this package's `name`, not a bare
25
+ * `package.json`: every node_modules entry and every sibling project has one of
26
+ * those, and a resolver that accepts any of them has not narrowed anything.
27
+ */
28
+ import * as fs from 'node:fs';
29
+ import * as path from 'node:path';
30
+
31
+ /** The package name that identifies THIS repository. */
32
+ export const SENTINEL_PACKAGE_NAME = '@event4u/agent-config';
33
+
34
+ /** Raised when no directory on the walk carries the sentinel. */
35
+ export class RepoRootUnresolvedError extends Error {
36
+ readonly startedAt: string;
37
+
38
+ constructor(startedAt: string, message: string) {
39
+ super(message);
40
+ this.name = 'RepoRootUnresolvedError';
41
+ this.startedAt = startedAt;
42
+ }
43
+ }
44
+
45
+ /**
46
+ * True when `dir` is this repository's root.
47
+ *
48
+ * Reads `package.json` and compares `name`. A parse failure is `false`, never a
49
+ * throw: a malformed `package.json` somewhere up the walk must not stop the walk
50
+ * from reaching a valid root above it.
51
+ */
52
+ export function hasSentinel(dir: string): boolean {
53
+ try {
54
+ const raw = fs.readFileSync(path.join(dir, 'package.json'), 'utf8');
55
+ return (JSON.parse(raw) as { name?: unknown }).name === SENTINEL_PACKAGE_NAME;
56
+ } catch {
57
+ return false;
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Walk upward from `from` and return the first directory carrying the sentinel.
63
+ *
64
+ * @throws {RepoRootUnresolvedError} when the walk reaches the filesystem root
65
+ * without finding one. Deliberately not a `null` return: an optional type
66
+ * invites `?? process.cwd()`, which is the guess this module exists to prevent.
67
+ */
68
+ export function resolveRepoRoot(from: string = process.cwd()): string {
69
+ let dir = path.resolve(from);
70
+ const seen: string[] = [];
71
+ for (;;) {
72
+ seen.push(dir);
73
+ if (hasSentinel(dir)) return dir;
74
+ const parent = path.dirname(dir);
75
+ if (parent === dir) break;
76
+ dir = parent;
77
+ }
78
+ throw new RepoRootUnresolvedError(
79
+ path.resolve(from),
80
+ `no repository root above ${path.resolve(from)} — no directory on the walk carries a ` +
81
+ `package.json named "${SENTINEL_PACKAGE_NAME}". Checked ${String(seen.length)} directory(ies). ` +
82
+ 'This is a refusal, not a fallback: resolving to the working directory here is how a gate ' +
83
+ 'ends up scanning an arbitrary tree and reporting a clean pass over it.',
84
+ );
85
+ }
86
+
87
+ /**
88
+ * The environment variables that override git's own discovery.
89
+ *
90
+ * `GIT_DIR` is the one that has actually bitten; the other three are listed
91
+ * because they fail the same way and a reader checking for one should see all
92
+ * four rather than believe the list is complete at one entry.
93
+ */
94
+ export const GIT_DISCOVERY_OVERRIDES = [
95
+ 'GIT_DIR',
96
+ 'GIT_WORK_TREE',
97
+ 'GIT_INDEX_FILE',
98
+ 'GIT_COMMON_DIR',
99
+ ] as const;
100
+
101
+ /** Any git discovery override present in `env`, with its value. */
102
+ export function inheritedGitOverrides(
103
+ env: NodeJS.ProcessEnv = process.env,
104
+ ): { name: string; value: string }[] {
105
+ const out: { name: string; value: string }[] = [];
106
+ for (const name of GIT_DISCOVERY_OVERRIDES) {
107
+ const value = env[name];
108
+ if (typeof value === 'string' && value !== '') out.push({ name, value });
109
+ }
110
+ return out;
111
+ }
@@ -34,6 +34,17 @@
34
34
  */
35
35
  export type MutationMeasure = 'exact' | 'capped_approximation';
36
36
 
37
+ import type { NoFreeForm } from './runtime_journal.js';
38
+ import { type PrivacyClass } from './privacy_class.js';
39
+
40
+ type Assert<T extends true> = T;
41
+
42
+ /**
43
+ * What THIS producer's lines carry: counts (`diff_lines`), enums, and the
44
+ * `rules_applied` id array. `ids-only`, same as the orchestration producer.
45
+ */
46
+ const PRODUCER_PRIVACY_CLASS: PrivacyClass = 'ids-only';
47
+
37
48
  export interface ReviewSkippedInput {
38
49
  /** Non-doc tracked-file mutation size that triggered the nudge (count only). */
39
50
  diff_lines: number;
@@ -92,6 +103,15 @@ export function buildReviewSkippedLine(input: ReviewSkippedInput): BuiltReviewSk
92
103
  memory: { asks: 0, hits: 0 },
93
104
  verify: { claims: 0, first_try_passes: 0 },
94
105
  rules_applied: ['delegation-policy'],
106
+ // MANDATORY on every audit line, same as the orchestration producer.
107
+ privacy_class: PRODUCER_PRIVACY_CLASS,
108
+ // `skills_applied` is OMITTED here, deliberately and not by oversight.
109
+ // audit-log-v1 distinguishes an absent key ("not recorded") from `[]`
110
+ // ("recorded, none applied"), and this writer observes a review that
111
+ // did not happen -- it has no skill observation to offer in either
112
+ // direction. Emitting `[]` would assert "no skills applied" on evidence
113
+ // this producer never gathered, which is the exact fabrication the
114
+ // absent/empty split exists to make impossible.
95
115
  persona: null,
96
116
  input_kind: 'prompt',
97
117
  type: 'note',
@@ -100,3 +120,20 @@ export function buildReviewSkippedLine(input: ReviewSkippedInput): BuiltReviewSk
100
120
 
101
121
  return { line, errors: [] };
102
122
  }
123
+
124
+ /**
125
+ * The SECOND producer's half of the compile-time privacy floor.
126
+ *
127
+ * `docs/contracts/audit-log-v1.md` states that the floor holds by construction
128
+ * "on two paths"; guarding only the first would leave that sentence half true
129
+ * while reading as fully true. Same mechanism as
130
+ * `orchestration_record.ts`: a free-form key on the input type makes this
131
+ * `Assert<false>` and stops the build.
132
+ *
133
+ * The negative direction is fixtured there rather than duplicated here — one
134
+ * proof that `NoFreeForm` still rejects is enough for both call sites, since
135
+ * they share the type.
136
+ */
137
+ type _ReviewSkippedInputCarriesNoFreeFormField = Assert<
138
+ [NoFreeForm<ReviewSkippedInput>] extends [never] ? false : true
139
+ >;