@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
@@ -47,7 +47,7 @@
47
47
  * or merges one in the same change — or the added file carries an explicit
48
48
  * `estate_offset_exempt:` reason in its frontmatter, which costs a visible line
49
49
  * in the diff of the very commit that claims it. This half is diff-scoped: it
50
- * reads `<base>...HEAD` over `agents/roadmaps/`, so on a branch that adds no
50
+ * reads `<base>...HEAD` over `agents/roadmaps/`, so on a branch that adds no code-comment-allow provenance-comment -- the path is this script's operand, not where the code came from
51
51
  * roadmap it legitimately finds nothing to weigh.
52
52
  *
53
53
  * THE THREE WAYS THE ESTATE MAY LEGITIMATELY GROW
@@ -65,7 +65,7 @@
65
65
  * estate rather than creating it, so it needs no authorisation; what the
66
66
  * allowance does NOT cover is a `later/` file appearing from nowhere.
67
67
  * 3. **Anything else** — `estate_growth_exempt: <reason>` added, in this change,
68
- * to the frontmatter of any roadmap under `agents/roadmaps/`. The canonical
68
+ * to the frontmatter of any roadmap under `agents/roadmaps/`. The canonical code-comment-allow provenance-comment -- the path is this script's operand, not where the code came from
69
69
  * case is a blocker discovered while doing the work: `open_blockers` rises,
70
70
  * nothing was archived, and the reason belongs next to the blocker.
71
71
  *
@@ -117,7 +117,7 @@
117
117
  * which one lied.
118
118
  *
119
119
  * The same function measures the BASE side, over a scratch copy of the base
120
- * ref's `agents/roadmaps/` (`_lib/base_tree.ts`). Re-deriving the floor with a
120
+ * ref's `agents/roadmaps/` (`_lib/base_tree.ts`). Re-deriving the floor with a code-comment-allow provenance-comment -- the path is this script's operand, not where the code came from
121
121
  * second implementation would let the two sides disagree about one tree, which
122
122
  * is the failure this section already argues against, one level up.
123
123
  *
@@ -143,7 +143,7 @@ import { fileURLToPath, pathToFileURL } from 'node:url';
143
143
 
144
144
  import {
145
145
  collect,
146
- is_draft as isDraft,
146
+ is_unscheduled as isUnscheduled,
147
147
  is_roadmap_candidate as isRoadmapCandidate,
148
148
  parse_frontmatter as parseFrontmatter,
149
149
  parse_roadmap as parseRoadmap,
@@ -153,7 +153,10 @@ import { GateLedger } from './_lib/gate_ledger.js';
153
153
  import { resolveBaseRef } from './_lib/ratchet_base_ref.js';
154
154
  import { materialiseSubtree } from './_lib/base_tree.js';
155
155
  import { SKILLS_POSIX, measureSkillEstate } from './_lib/skill_estate.js';
156
+ import { CONCERN_MANIFEST_POSIX, countConcerns } from './_lib/concern_estate.js';
156
157
  import { runGateCli, runSelfTest, type SelfTestCase } from './_lib/gate_self_test.js';
158
+ import { countDeclaredCarriers, declaresCarrier } from './_lib/carrier_status.js';
159
+ import { carrierEstateCases } from './_lib/estate_carrier_cases.js';
157
160
 
158
161
  const GATE = 'check_estate_count';
159
162
  const BUDGET_REL = path.join('src', 'config', 'estate-count-budget.json');
@@ -190,6 +193,23 @@ export interface EstateCounts {
190
193
  * "no tokens" — see `tokensExact`.
191
194
  */
192
195
  skill_description_tokens: number;
196
+ /**
197
+ * Hook concerns declared in `src/scripts/hook_manifest.yaml`.
198
+ *
199
+ * A FIFTH corpus on the same machinery, and the same argument that admitted
200
+ * skills: the floor-from-the-base-ref work is the expensive part and should
201
+ * not be written a third time, and a separate ratchet is a separate place to
202
+ * forget.
203
+ *
204
+ * Read with the SCOPED parser in `_lib/concern_estate.ts`, not the
205
+ * whole-file grep the originating roadmap reproduces its series with. That
206
+ * grep over-counts by exactly 16 at every one of its six pins, because
207
+ * `roles:`, `platforms:` and `native_event_aliases:` sit at the same indent.
208
+ * The growth finding survives the correction — the delta is constant — but
209
+ * the absolute figure does not: the axis stands at 55, not 71, and a floor
210
+ * of 71 is one this gate's own parser could never reproduce.
211
+ */
212
+ concern_count: number;
193
213
  }
194
214
 
195
215
  export type MetricName = keyof EstateCounts;
@@ -200,6 +220,7 @@ export const METRICS: readonly MetricName[] = [
200
220
  'open_blockers',
201
221
  'skill_count',
202
222
  'skill_description_tokens',
223
+ 'concern_count',
203
224
  ];
204
225
 
205
226
  export interface EstateBudget {
@@ -213,6 +234,63 @@ export interface EstateBudget {
213
234
  * number here is how it gets a threshold.
214
235
  */
215
236
  one_in_one_out: { applies_above_active: number | null };
237
+ /**
238
+ * The capped provisional-promotion path — specified, and DECLINED.
239
+ *
240
+ * READ ITS NULLS THE OTHER WAY ROUND FROM THE KEY ABOVE. There `null` means
241
+ * UNCONDITIONAL; here `max_live: null` and `expires_after_days: null` mean
242
+ * NOT REGISTERED, PATH INACTIVE. The two keys sit a few lines apart in one
243
+ * file and their nulls mean opposite things, so a reader who transfers the
244
+ * sibling's semantics reads a declined path as an uncapped one.
245
+ */
246
+ provisional_promotion: ProvisionalPromotion;
247
+ }
248
+
249
+ /**
250
+ * The `provisional_promotion` object as the budget file carries it.
251
+ *
252
+ * `status` is optional so that a file which registered the two integers without
253
+ * restating a status is still readable — the integers are what activate the
254
+ * path, and a declination that dropped its own marker would fall to
255
+ * `unregistered`, which is the safe direction.
256
+ */
257
+ export interface ProvisionalPromotion {
258
+ status?: string;
259
+ max_live: number | null;
260
+ expires_after_days: number | null;
261
+ }
262
+
263
+ /**
264
+ * Three states, and the reason there are three rather than two.
265
+ *
266
+ * The 2026-09-01 council that declined the path attached one obligation to the
267
+ * decline: the checker must distinguish an intentional declination from missing
268
+ * configuration. Two states cannot — `null` would read the same either way, and
269
+ * "nobody has written this yet" would be indistinguishable from "this was
270
+ * specified in full and refused on 2026-09-01".
271
+ */
272
+ export type ProvisionalPromotionState = 'declined' | 'unregistered' | 'registered';
273
+
274
+ /**
275
+ * Classify the path's state. NEVER activates it, in any state.
276
+ *
277
+ * A half-registered object — one integer, one null — throws rather than
278
+ * resolving to either neighbour: a cap with no expiry and an expiry with no cap
279
+ * are different mechanisms, and guessing which half was meant is how a bounded
280
+ * path becomes an unbounded one by omission.
281
+ */
282
+ export function provisionalPromotionState(pp: ProvisionalPromotion): ProvisionalPromotionState {
283
+ const live = pp.max_live;
284
+ const days = pp.expires_after_days;
285
+ if (typeof live === 'number' && typeof days === 'number') return 'registered';
286
+ if ((live === null) !== (days === null)) {
287
+ throw new Error(
288
+ `${BUDGET_REL} "provisional_promotion" is half-registered ` +
289
+ `(max_live=${JSON.stringify(live)}, expires_after_days=${JSON.stringify(days)}). ` +
290
+ 'Both integers activate the path; both null leave it inactive. One of each is neither.',
291
+ );
292
+ }
293
+ return pp.status === 'declined' ? 'declined' : 'unregistered';
216
294
  }
217
295
 
218
296
  /** One gated count that rose above the floor measured at the base ref. */
@@ -286,6 +364,15 @@ export interface EstateVerdict {
286
364
  offsets: OffsetLedger | null;
287
365
  offsetSkipReason: string | null;
288
366
  unpaid: number;
367
+ /**
368
+ * The provisional-promotion path's state, reported and never acted on.
369
+ *
370
+ * Carried in the verdict so a `--json` consumer can tell a declined path
371
+ * from an unwritten one without re-reading the budget file, which is the
372
+ * distinction the 2026-09-01 decline was conditioned on. It contributes
373
+ * nothing to `withinBudget` in any state: reading is not activation.
374
+ */
375
+ provisionalPromotion: ProvisionalPromotionState;
289
376
  withinBudget: boolean;
290
377
  }
291
378
 
@@ -303,6 +390,29 @@ function repoRootFrom(start: string): string {
303
390
  }
304
391
  }
305
392
 
393
+ /** File contents, or `null` when it is absent. Absent is a real state here. */
394
+ function readIfPresent(file: string): string | null {
395
+ try {
396
+ return fs.readFileSync(file, 'utf-8');
397
+ } catch {
398
+ return null;
399
+ }
400
+ }
401
+
402
+ /**
403
+ * Concern count at a git ref, or `null` when the manifest is unreadable there.
404
+ *
405
+ * `null` is NOT zero, and the distinction is the whole reason this returns an
406
+ * option. A missing manifest read as 0 makes the floor 0, which makes the
407
+ * ratchet inert on that path while still printing a green line — "a gate that
408
+ * read nothing has not passed", in this repository's own words. The caller
409
+ * turns `null` into a floor-skip, which this gate already treats as a failure.
410
+ */
411
+ function concernCountAt(repoRoot: string, ref: string): number | null {
412
+ const res = git(['show', `${ref}:${CONCERN_MANIFEST_POSIX}`], repoRoot);
413
+ return res.ok ? countConcerns(res.stdout) : null;
414
+ }
415
+
306
416
  function git(args: readonly string[], cwd: string): { ok: boolean; stdout: string } {
307
417
  const res = spawnSync('git', [...args], { cwd, encoding: 'utf-8', maxBuffer: 32 * 1024 * 1024 });
308
418
  return { ok: res.status === 0, stdout: res.stdout ?? '' };
@@ -328,7 +438,39 @@ function countIn(roadmapRoot: string, sub: string): number {
328
438
  }
329
439
  }
330
440
 
331
- /** Non-draft roadmaps parked in `later/`, parsed for their blockers. */
441
+ /**
442
+ * Top-level roadmaps `collect()` drops for declaring `status: carrier`, added
443
+ * back so that FLIPPING a status is count-neutral.
444
+ *
445
+ * Measured before this: flipping one file to `carrier` moved `active_roadmaps
446
+ * 3 → 2` and the gate printed "estate within its ratchet", because a count
447
+ * below the floor is a drawdown and free. The floor is measured at the base
448
+ * ref, so once such a flip merges the lowered number becomes the next floor —
449
+ * the file cannot be flipped back without paying, and any roadmap can be
450
+ * laundered out of the count by adding one word.
451
+ *
452
+ * A reclassification is not a disposal, so the metric counts the file on both
453
+ * sides. Same argument `open_blockers` makes below for spanning `later/`.
454
+ * Deleting a carrier is still a shrink and still earns no offset
455
+ * (`classifyDiff`); adding one is growth that takes the claim path.
456
+ *
457
+ * This is therefore the one roadmap metric that does NOT equal the dashboard
458
+ * header, stated here rather than left to be tripped over.
459
+ */
460
+ function countActiveCarriers(roadmapRoot: string): number {
461
+ return countDeclaredCarriers(roadmapRoot, isRoadmapCandidate, fs, path.join);
462
+ }
463
+
464
+ /**
465
+ * Roadmaps parked in `later/` whose blockers count, parsed for them.
466
+ *
467
+ * Skips a draft AND a carrier, which is the same pair `collect()` skips on the
468
+ * active side. It used to skip only the draft, so parking a carrier moved its
469
+ * blockers INTO the gated count while the identical file at the top level kept
470
+ * them out — a ratchet verdict that moved on a relocation, for no stated
471
+ * reason. Three of the four status readers learned `carrier` when the status
472
+ * shipped; this is the fourth.
473
+ */
332
474
  function laterRoadmaps(roadmapRoot: string): Array<{ open_blockers: readonly unknown[] }> {
333
475
  const dir = path.join(roadmapRoot, 'later');
334
476
  let names: string[];
@@ -344,7 +486,7 @@ function laterRoadmaps(roadmapRoot: string): Array<{ open_blockers: readonly unk
344
486
  // `collect()` cannot be reused here: it filters through the same
345
487
  // path-based predicate and would reject its own root.
346
488
  const text = fs.readFileSync(abs, 'utf-8');
347
- if (isDraft(parseFrontmatter(text))) continue;
489
+ if (isUnscheduled(parseFrontmatter(text))) continue;
348
490
  const stats = parseRoadmap(abs, dir);
349
491
  if (stats !== null) out.push(stats as unknown as { open_blockers: readonly unknown[] });
350
492
  }
@@ -354,8 +496,11 @@ function laterRoadmaps(roadmapRoot: string): Array<{ open_blockers: readonly unk
354
496
  /**
355
497
  * Count the estate, three ways.
356
498
  *
357
- * `active_roadmaps` comes from `collect()` so it cannot disagree with the
358
- * dashboard. `later_roadmaps` is a directory listing because parked files are
499
+ * `active_roadmaps` is `collect()` PLUS the top-level carriers `collect()`
500
+ * drops, so the parser is shared with the dashboard while a status flip stays
501
+ * count-neutral — see `countActiveCarriers` for why that beats parity here, and
502
+ * for the one number on this gate that the dashboard header does not print.
503
+ * `later_roadmaps` is a directory listing because parked files are
359
504
  * outside that corpus by design — filtered through the same `is_roadmap_candidate`
360
505
  * predicate as the active side, so `later/README.md` is not a roadmap here either.
361
506
  *
@@ -379,7 +524,7 @@ export function countEstate(repoRoot: string): EstateCounts {
379
524
  rows.reduce((n, r) => n + r.open_blockers.length, 0);
380
525
  const skills = measureSkillEstate(repoRoot);
381
526
  return {
382
- active_roadmaps: stats.length,
527
+ active_roadmaps: stats.length + countActiveCarriers(roadmapRoot),
383
528
  later_roadmaps: countIn(roadmapRoot, 'later'),
384
529
  open_blockers: openOf(stats) + openOf(laterRoadmaps(roadmapRoot)),
385
530
  skill_count: skills.skill_count,
@@ -389,6 +534,7 @@ export function countEstate(repoRoot: string): EstateCounts {
389
534
  // against a proxy one — they differ by more than the growth a ratchet
390
535
  // is trying to catch.
391
536
  skill_description_tokens: skills.skill_description_tokens ?? 0,
537
+ concern_count: countConcerns(readIfPresent(path.join(repoRoot, CONCERN_MANIFEST_POSIX)) ?? ''),
392
538
  };
393
539
  }
394
540
 
@@ -397,7 +543,7 @@ export function skillTokensExact(root: string): boolean {
397
543
  return measureSkillEstate(root).skill_description_tokens !== null;
398
544
  }
399
545
 
400
- /** `agents/roadmaps/<name>.md` — the active top level, never a subdirectory. */
546
+ /** `agents/roadmaps/<name>.md` — the active top level. code-comment-allow provenance-comment -- operand, not provenance */
401
547
  function isActiveTopLevel(rel: string): boolean {
402
548
  const norm = rel.split(path.sep).join('/');
403
549
  if (!norm.startsWith('agents/roadmaps/') || !norm.endsWith('.md')) {
@@ -444,6 +590,9 @@ export function exemptionReason(text: string): string | null {
444
590
  return reason === '' ? null : reason;
445
591
  }
446
592
 
593
+ /** Re-export; `_lib/carrier_status.ts` holds the one implementation. */
594
+ export const isCarrierText = declaresCarrier;
595
+
447
596
  /**
448
597
  * Classify the change's effect on the active roadmap tree.
449
598
  *
@@ -452,7 +601,17 @@ export function exemptionReason(text: string): string | null {
452
601
  * `later/road-to-x.md` → `road-to-x.md` is an un-parking and counts as an
453
602
  * addition. A top-level-to-top-level rename is neither.
454
603
  */
455
- export function classifyDiff(nameStatus: string, readFile: (rel: string) => string | null): OffsetLedger {
604
+ export function classifyDiff(
605
+ nameStatus: string,
606
+ readFile: (rel: string) => string | null,
607
+ /**
608
+ * The file's content at the BASE ref, for paths this change removed — a
609
+ * deleted carrier cannot be read from the working tree and its status
610
+ * decides whether the deletion earns an offset. Defaults to null, which
611
+ * reproduces the previous scoring for any caller without a pre-image.
612
+ */
613
+ readBase: (rel: string) => string | null = () => null,
614
+ ): OffsetLedger {
456
615
  const added: string[] = [];
457
616
  const offsets: string[] = [];
458
617
  const exempt: Array<{ file: string; reason: string }> = [];
@@ -465,8 +624,10 @@ export function classifyDiff(nameStatus: string, readFile: (rel: string) => stri
465
624
  const from = cols[1] ?? '';
466
625
  const to = cols[2] ?? '';
467
626
  if (isActiveTopLevel(from) && isDisposed(to)) {
468
- offsets.push(from);
469
- if (isParked(to)) parked.push(to);
627
+ if (!isCarrierText(readBase(from))) {
628
+ offsets.push(from);
629
+ if (isParked(to)) parked.push(to);
630
+ }
470
631
  } else if (isDisposed(from) && isActiveTopLevel(to)) {
471
632
  added.push(to);
472
633
  }
@@ -477,7 +638,10 @@ export function classifyDiff(nameStatus: string, readFile: (rel: string) => stri
477
638
  if (status === 'A') {
478
639
  added.push(file);
479
640
  } else if (status === 'D') {
480
- offsets.push(file);
641
+ // A carrier's removal is never an offset. See `readBase`.
642
+ if (!isCarrierText(readBase(file))) {
643
+ offsets.push(file);
644
+ }
481
645
  }
482
646
  }
483
647
  for (const file of added) {
@@ -544,6 +708,18 @@ export function evaluate(
544
708
  if (budget.one_in_one_out === undefined) {
545
709
  throw new Error(`${BUDGET_REL} carries no "one_in_one_out" object.`);
546
710
  }
711
+ // Same shape, same reason: an absent policy object is a could-not-run, not a
712
+ // pass. Here it also carries a second job — with the key required, "the path
713
+ // was declined on 2026-09-01" and "nobody has configured this" cannot
714
+ // collapse into the same reading, which is the condition the council
715
+ // attached to the decline.
716
+ if (budget.provisional_promotion === undefined) {
717
+ throw new Error(
718
+ `${BUDGET_REL} carries no "provisional_promotion" object. ` +
719
+ 'Absent is misconfiguration, never an inactive path — a declination is recorded, not implied.',
720
+ );
721
+ }
722
+ const provisionalPromotion = provisionalPromotionState(budget.provisional_promotion);
547
723
 
548
724
  const counts = countEstate(repoRoot);
549
725
  const baseRef = opts.baseRef ?? resolveBaseRef(repoRoot);
@@ -554,6 +730,15 @@ export function evaluate(
554
730
  // property, and unlike a number nobody has to remember to update it.
555
731
  let floor: EstateCounts | null = null;
556
732
  let floorSkipReason: string | null = null;
733
+ /**
734
+ * Does the WORKING TREE carry a manifest at all?
735
+ *
736
+ * The base-ref read only matters when it does. A repository with no manifest
737
+ * on either side has no concern axis to ratchet, and failing there would
738
+ * turn every unrelated fixture red — which is how the first version of this
739
+ * clause was caught.
740
+ */
741
+ const headHasManifest = fs.existsSync(path.join(repoRoot, CONCERN_MANIFEST_POSIX));
557
742
  /** Set when the base ref carries no `src/skills` — the skill metrics drop. */
558
743
  let skillFloorSkipReason: string | null = null;
559
744
  /** Set when either side's tokeniser did not resolve — that ONE metric drops. */
@@ -584,7 +769,14 @@ export function evaluate(
584
769
  if (baseSkills.error !== null || baseSkills.files === 0) {
585
770
  // Roadmap floor stands; the skill floor is stated as
586
771
  // unavailable and its metrics are dropped from the compare.
587
- floor = roadmapFloor;
772
+ const cf = concernCountAt(repoRoot, baseRef);
773
+ floor = { ...roadmapFloor, concern_count: cf ?? 0 };
774
+ if (cf === null && headHasManifest) {
775
+ floorSkipReason =
776
+ `could not read ${CONCERN_MANIFEST_POSIX} at ${baseRef} while HEAD ` +
777
+ 'carries one. A floor of 0 would make the concern ratchet inert while ' +
778
+ 'still printing green, so this fails rather than skips.';
779
+ }
588
780
  skillFloorSkipReason =
589
781
  `could not read ${SKILLS_POSIX} at ${baseRef} — ` +
590
782
  `${baseSkills.error ?? 'no files'}`;
@@ -594,7 +786,23 @@ export function evaluate(
594
786
  ...roadmapFloor,
595
787
  skill_count: s.skill_count,
596
788
  skill_description_tokens: s.skill_description_tokens ?? 0,
789
+ // A SINGLE FILE, so `git show` rather than a third
790
+ // `materialiseSubtree` — stated because the roadmap asks
791
+ // which of the two this uses. Materialising a subtree to
792
+ // reach one known path would spend a temp tree and a
793
+ // recursive ls-tree on a `git cat-file` in disguise.
794
+ //
795
+ // `?? 0` never stands for "unreadable": the branch below
796
+ // turns that into a floor-skip, which fails. This
797
+ // coalesce only satisfies the type.
798
+ concern_count: concernCountAt(repoRoot, baseRef) ?? 0,
597
799
  };
800
+ if (concernCountAt(repoRoot, baseRef) === null && headHasManifest) {
801
+ floorSkipReason =
802
+ `could not read ${CONCERN_MANIFEST_POSIX} at ${baseRef} while HEAD ` +
803
+ 'carries one. A floor of 0 would make the concern ratchet inert while ' +
804
+ 'still printing green, so this fails rather than skips.';
805
+ }
598
806
  if (s.skill_description_tokens === null) {
599
807
  skillTokenSkipReason =
600
808
  `the tokeniser did not resolve at ${baseRef}; an exact reading may ` +
@@ -624,13 +832,20 @@ export function evaluate(
624
832
  if (!diff.ok) {
625
833
  offsetSkipReason = `git diff against ${baseRef} failed — one-in-one-out not evaluated`;
626
834
  } else {
627
- offsets = classifyDiff(diff.stdout, (rel) => {
628
- try {
629
- return fs.readFileSync(path.join(repoRoot, rel), 'utf-8');
630
- } catch {
631
- return null;
632
- }
633
- });
835
+ offsets = classifyDiff(
836
+ diff.stdout,
837
+ (rel) => {
838
+ try {
839
+ return fs.readFileSync(path.join(repoRoot, rel), 'utf-8');
840
+ } catch {
841
+ return null;
842
+ }
843
+ },
844
+ (rel) => {
845
+ const show = git(['show', `${baseRef}:${rel}`], repoRoot);
846
+ return show.ok ? show.stdout : null;
847
+ },
848
+ );
634
849
  }
635
850
  const patch = git(
636
851
  ['diff', '--unified=0', '--find-renames', `${baseRef}...HEAD`, '--', ROADMAPS_REL],
@@ -663,6 +878,14 @@ export function evaluate(
663
878
  // claim path — a recorded reason in the diff — or it fails.
664
879
  skill_count: 0,
665
880
  skill_description_tokens: 0,
881
+ // Step 1.2: NO new allowance key. The concern axis joins `skill_count`
882
+ // in taking the claim path or nothing, for the reason the budget file
883
+ // already records for skills — an allowance reopens the gaming path the
884
+ // dimension exists to close. Eight concerns spread across eight events
885
+ // violate the existing per-event cap zero times, which is exactly why a
886
+ // total-growth ratchet was needed and exactly why it must not carry a
887
+ // per-change freebie.
888
+ concern_count: 0,
666
889
  };
667
890
 
668
891
  /** Metrics dropped from the compare, with the reason, never silently. */
@@ -707,6 +930,7 @@ export function evaluate(
707
930
  offsets,
708
931
  offsetSkipReason,
709
932
  unpaid,
933
+ provisionalPromotion,
710
934
  // No floor is a FAILURE, not a skip, and it is the one place this gate
711
935
  // convicts on a missing input. The other halves can report "unproven" and
712
936
  // still leave a meaningful verdict behind; the count half IS the verdict,
@@ -717,7 +941,7 @@ export function evaluate(
717
941
  }
718
942
 
719
943
  /** Floors for `--self-test`, declared here so a truncation is a visible diff. */
720
- const SELF_TEST_MIN_CASES = 12;
944
+ const SELF_TEST_MIN_CASES = 13;
721
945
  const SELF_TEST_MIN_REJECT = 8;
722
946
 
723
947
  /**
@@ -742,11 +966,32 @@ function selfTest(): number {
742
966
  * the baseline with no reason" is not a state a change can reach.
743
967
  */
744
968
  const budgetJson = (): string =>
745
- `${JSON.stringify({ one_in_one_out: { applies_above_active: null } }, null, 4)}\n`;
969
+ `${JSON.stringify(
970
+ {
971
+ one_in_one_out: { applies_above_active: null },
972
+ // Required since the path was specified and declined: the gate
973
+ // refuses a budget that carries no `provisional_promotion`, so a
974
+ // fixture without it exits 2 on every case rather than on the one
975
+ // case testing that refusal.
976
+ provisional_promotion: { status: 'declined', max_live: null, expires_after_days: null },
977
+ },
978
+ null,
979
+ 4,
980
+ )}\n`;
746
981
 
747
982
  const roadmap = (name: string, extra = ''): string =>
748
983
  `# Roadmap: ${name}\n\n## Phase 1\n\n- [ ] **1.1** s\n${extra}`;
749
984
 
985
+ /** A `status: carrier` roadmap — counted as estate, and never an offset. */
986
+ const CARRIER = `---\nstatus: carrier\n---\n# Roadmap: carrier\n\n## Phase 1\n\n- [~] **1.1** s\n`;
987
+
988
+ /**
989
+ * A `status: draft` roadmap — invisible to `collect()`, so adding one cannot
990
+ * move `active_roadmaps`. That is what makes it the fixture for a case that
991
+ * must be decided by the offset scoring and by nothing else.
992
+ */
993
+ const DRAFT = `---\nstatus: draft\n---\n# Roadmap: draft\n\n## Phase 1\n\n- [ ] **1.1** s\n`;
994
+
750
995
  /** An open blocker — no `Status: resolved` prefix, so it counts as open. */
751
996
  const BLOCKER = '\n## Blockers\n\n### Blocker: fixture\n\n- **Status:** open\n';
752
997
 
@@ -808,6 +1053,64 @@ function selfTest(): number {
808
1053
  expect: 'accept',
809
1054
  run: () => fixture({ roadmaps: 3, base: 'main', after: () => undefined }),
810
1055
  },
1056
+ {
1057
+ // The concern axis, both directions. Seeded into the BASE tree so
1058
+ // the floor is a real reading of the fixture's own manifest rather
1059
+ // than this repository's -- the whole point of measuring the floor
1060
+ // from the base ref.
1061
+ name: 'concern count grows above the base-tree floor → reject',
1062
+ expect: 'reject',
1063
+ run: () =>
1064
+ fixture({
1065
+ roadmaps: 3,
1066
+ base: 'main',
1067
+ before: (dir) =>
1068
+ write(dir, CONCERN_MANIFEST_POSIX, 'concerns:\n one:\n severity: advisory\n'),
1069
+ after: (dir) =>
1070
+ write(
1071
+ dir,
1072
+ CONCERN_MANIFEST_POSIX,
1073
+ 'concerns:\n one:\n severity: advisory\n two:\n severity: advisory\n',
1074
+ ),
1075
+ }),
1076
+ },
1077
+ {
1078
+ // AC-3's explicit clause, and it corrects the first implementation
1079
+ // of this metric: an unreadable manifest at the base ref must FAIL,
1080
+ // never read as 0. A floor of 0 makes the ratchet inert on that
1081
+ // path while still printing a green line, which is the shape this
1082
+ // repository calls "a gate that read nothing has not passed".
1083
+ name: 'base ref carries no manifest → reject (a 0 floor is not a floor)',
1084
+ expect: 'reject',
1085
+ run: () =>
1086
+ fixture({
1087
+ roadmaps: 3,
1088
+ base: 'main',
1089
+ after: (dir) =>
1090
+ write(dir, CONCERN_MANIFEST_POSIX, 'concerns:\n one:\n severity: advisory\n'),
1091
+ }),
1092
+ },
1093
+ {
1094
+ // The half that proves the parser is SCOPED rather than a grep: a
1095
+ // top-level map gaining members at the same two-space indent is not
1096
+ // concern growth, and the roadmap's own reproduce command would
1097
+ // have counted it as such.
1098
+ name: 'a non-concern top-level map growing is not concern growth → accept',
1099
+ expect: 'accept',
1100
+ run: () =>
1101
+ fixture({
1102
+ roadmaps: 3,
1103
+ base: 'main',
1104
+ before: (dir) =>
1105
+ write(dir, CONCERN_MANIFEST_POSIX, 'concerns:\n one:\n severity: advisory\nroles:\n dev:\n'),
1106
+ after: (dir) =>
1107
+ write(
1108
+ dir,
1109
+ CONCERN_MANIFEST_POSIX,
1110
+ 'concerns:\n one:\n severity: advisory\nroles:\n dev:\n ops:\n sre:\n',
1111
+ ),
1112
+ }),
1113
+ },
811
1114
  {
812
1115
  // The floor is now exact, so this case no longer depends on anyone
813
1116
  // having typed the right number at the base commit.
@@ -894,6 +1197,14 @@ function selfTest(): number {
894
1197
  after: (dir) => write(dir, 'agents/roadmaps/later/road-to-parked.md', roadmap('P')),
895
1198
  }),
896
1199
  },
1200
+ ...carrierEstateCases({
1201
+ fixture,
1202
+ write,
1203
+ remove: (dir, rel) => fs.rmSync(path.join(dir, rel)),
1204
+ roadmap,
1205
+ CARRIER,
1206
+ DRAFT,
1207
+ }),
897
1208
  {
898
1209
  name: 'a new open blocker with no claim → reject',
899
1210
  expect: 'reject',
@@ -1019,7 +1330,7 @@ export function main(argv: string[] = process.argv.slice(2)): number {
1019
1330
  return 2;
1020
1331
  }
1021
1332
 
1022
- // A ratchet over an empty estate always passes. Move `agents/roadmaps/` and
1333
+ // A ratchet over an empty estate always passes. Move `agents/roadmaps/` and code-comment-allow provenance-comment -- the path is this script's operand, not where the code came from
1023
1334
  // every count is 0, which is trivially under any baseline — exit 2 (could
1024
1335
  // not run), never 1, which would assert the estate actually grew.
1025
1336
  try {
@@ -1096,6 +1407,17 @@ export function main(argv: string[] = process.argv.slice(2)): number {
1096
1407
  } else if (verdict.offsetSkipReason !== null) {
1097
1408
  process.stdout.write(` ⚠️ ${verdict.offsetSkipReason}\n`);
1098
1409
  }
1410
+ // Printed unconditionally so the state is visible without `--json`. It never
1411
+ // changes the exit code — a declined path and a registered one both leave
1412
+ // the ratchet exactly as it was, and the allowance a registered path would
1413
+ // grant is deliberately unwired (the owner registers the numbers; wiring
1414
+ // what they buy is a separate, separately authorised change).
1415
+ process.stdout.write(
1416
+ ` ${'provisional'.padEnd(18)} ${verdict.provisionalPromotion.padStart(5)}` +
1417
+ `${verdict.provisionalPromotion === 'declined' ? ' (specified and declined 2026-09-01 — path inactive by decision)' : ''}` +
1418
+ `${verdict.provisionalPromotion === 'unregistered' ? ' (no numbers registered — path inactive)' : ''}` +
1419
+ `${verdict.provisionalPromotion === 'registered' ? ' (numbers registered by the owner; this gate grants no allowance for them)' : ''}\n`,
1420
+ );
1099
1421
  for (const c of verdict.claims) {
1100
1422
  process.stdout.write(` ↑ growth claimed in ${c.file}: ${c.reason.slice(0, 120)}\n`);
1101
1423
  }