@event4u/agent-config 14.12.0 → 14.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (521) hide show
  1. package/.augment-plugin/marketplace.json +3 -3
  2. package/.augment-plugin/plugin.json +1 -1
  3. package/.claude-plugin/marketplace.json +1 -1
  4. package/CHANGELOG.md +118 -155
  5. package/CONTRIBUTING.md +38 -0
  6. package/CREDITS.md +135 -0
  7. package/NOTICE +13 -0
  8. package/README.md +8 -6
  9. package/dist/agent-src/commands/analyze/inbox.md +145 -2
  10. package/dist/agent-src/commands/feature/dev.md +7 -2
  11. package/dist/agent-src/commands/ghostwriter/write.md +5 -1
  12. package/dist/agent-src/commands/implement-ticket.md +1 -1
  13. package/dist/agent-src/commands/mission/upgrade.md +1 -1
  14. package/dist/agent-src/commands/orchestrate.md +2 -2
  15. package/dist/agent-src/commands/post-as/me.md +5 -1
  16. package/dist/agent-src/commands/pr/merge.md +19 -6
  17. package/dist/agent-src/commands/roadmap/process-full.md +19 -5
  18. package/dist/agent-src/commands/tdd/red.md +12 -2
  19. package/dist/agent-src/commands/work.md +1 -1
  20. package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +40 -0
  21. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +5 -2
  22. package/dist/agent-src/contexts/execution/autonomy-mechanics.md +21 -0
  23. package/dist/agent-src/contexts/execution/orchestration-telemetry.md +1 -0
  24. package/dist/agent-src/contexts/execution/subagent-response-contract.md +40 -0
  25. package/dist/agent-src/contexts/execution/subagent-steering.md +13 -1
  26. package/dist/agent-src/contexts/execution/terminal-states.md +96 -0
  27. package/dist/agent-src/rules/artifact-drafting-protocol.md +1 -1
  28. package/dist/agent-src/rules/broken-access-control.md +4 -0
  29. package/dist/agent-src/rules/code-comment-discipline.md +6 -0
  30. package/dist/agent-src/rules/code-provenance.md +4 -0
  31. package/dist/agent-src/rules/design-fidelity.md +1 -1
  32. package/dist/agent-src/rules/domain-safety-pii.md +4 -0
  33. package/dist/agent-src/rules/domain-safety-retention.md +4 -0
  34. package/dist/agent-src/rules/engineering-safety-floor.md +2 -0
  35. package/dist/agent-src/rules/external-code-graph-interop.md +14 -12
  36. package/dist/agent-src/rules/improve-before-implement.md +6 -8
  37. package/dist/agent-src/rules/laravel-routing.md +1 -1
  38. package/dist/agent-src/rules/lethal-trifecta-guard.md +4 -0
  39. package/dist/agent-src/rules/secret-vcs-guard.md +2 -0
  40. package/dist/agent-src/rules/security-sensitive-stop.md +2 -0
  41. package/dist/agent-src/rules/source-confidentiality.md +12 -34
  42. package/dist/agent-src/rules/symfony-routing.md +1 -1
  43. package/dist/agent-src/rules/token-efficiency.md +14 -0
  44. package/dist/agent-src/rules/tool-safety.md +4 -0
  45. package/dist/agent-src/rules/untrusted-input-defense.md +4 -0
  46. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +252 -8
  47. package/dist/agent-src/scripts/guarded_baseline.ts +343 -0
  48. package/dist/agent-src/scripts/roadmap_set_step.ts +253 -0
  49. package/dist/agent-src/scripts/stub_queue.ts +82 -0
  50. package/dist/agent-src/scripts/stubs_due.ts +516 -0
  51. package/dist/agent-src/scripts/ticket_bundles.ts +84 -0
  52. package/dist/agent-src/scripts/update_roadmap_progress.ts +16 -12
  53. package/dist/agent-src/skills/brand-asset-generation/SKILL.md +17 -4
  54. package/dist/agent-src/skills/brand-audit/SKILL.md +33 -0
  55. package/dist/agent-src/skills/code-intelligence/SKILL.md +57 -0
  56. package/dist/agent-src/skills/database/SKILL.md +8 -0
  57. package/dist/agent-src/skills/dependency-upgrade/SKILL.md +27 -0
  58. package/dist/agent-src/skills/design-review/SKILL.md +1 -1
  59. package/dist/agent-src/skills/doc-coauthoring/SKILL.md +1 -1
  60. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +17 -1
  61. package/dist/agent-src/skills/feature-planning/SKILL.md +9 -2
  62. package/dist/agent-src/skills/frontend-render-security/SKILL.md +44 -0
  63. package/dist/agent-src/skills/git-workflow/SKILL.md +1 -1
  64. package/dist/agent-src/skills/js-library-packaging/scripts/check_package_surface.ts +38 -4
  65. package/dist/agent-src/skills/judge-artifact-completeness/rubrics/ticket-quality-score.json +2 -2
  66. package/dist/agent-src/skills/laravel/SKILL.md +35 -0
  67. package/dist/agent-src/skills/laravel-migration/SKILL.md +57 -3
  68. package/dist/agent-src/skills/monorepo-workspace/SKILL.md +26 -0
  69. package/dist/agent-src/skills/playbook-authoring/SKILL.md +28 -1
  70. package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +1 -1
  71. package/dist/agent-src/skills/skill-writing/references/procedure.md +5 -5
  72. package/dist/agent-src/skills/sql-writing/SKILL.md +7 -1
  73. package/dist/agent-src/skills/standards-from-config/SKILL.md +27 -4
  74. package/dist/agent-src/skills/supply-chain-intake/SKILL.md +11 -4
  75. package/dist/agent-src/skills/symfony-workflow/SKILL.md +35 -0
  76. package/dist/agent-src/skills/test-case-discovery/SKILL.md +85 -0
  77. package/dist/agent-src/skills/test-driven-development/SKILL.md +33 -9
  78. package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
  79. package/dist/agent-src/skills/testing-anti-patterns/process-anti-patterns.md +37 -0
  80. package/dist/agent-src/skills/ui-component-architect/SKILL.md +45 -2
  81. package/dist/agent-src/skills/upstream-contribute/SKILL.md +38 -1
  82. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +9 -4
  83. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  84. package/dist/agent-src/templates/roadmaps.md +97 -3
  85. package/dist/agent-src/templates/scripts/check_memory.ts +258 -17
  86. package/dist/agent-src/templates/scripts/check_memory_proposal.ts +9 -3
  87. package/dist/agent-src/templates/scripts/memory_lookup.ts +86 -0
  88. package/dist/agent-src/templates/scripts/memory_signal.ts +44 -0
  89. package/dist/agent-src/templates/scripts/work_engine/directives/backend/implement.ts +90 -0
  90. package/dist/agent-src/templates/scripts/work_engine/directives/backend/index.ts +11 -0
  91. package/dist/agent-src/templates/scripts/work_engine/directives/backend/test.ts +23 -1
  92. package/dist/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +10 -1
  93. package/dist/agent-src/templates/scripts/work_engine/directives/mixed/stitch.ts +5 -1
  94. package/dist/agent-src/templates/scripts/work_engine/stack/runner.ts +102 -14
  95. package/dist/cli/commands/uiAudit.js +124 -5
  96. package/dist/cli/registry.js +2 -0
  97. package/dist/cli-delegate/{chunk-HYWSRNUX.js → chunk-2DK2VJWG.js} +3 -3
  98. package/dist/cli-delegate/{chunk-JCW7ZLHK.js → chunk-4FS4WRXP.js} +5 -0
  99. package/dist/cli-delegate/{chunk-OMIVVCG2.js → chunk-A4QJ6ENT.js} +24 -0
  100. package/dist/cli-delegate/{chunk-JJA2QEWA.js → chunk-AKJGUQNO.js} +466 -285
  101. package/dist/cli-delegate/{chunk-E46KPN6K.js → chunk-BTWUYDGN.js} +424 -363
  102. package/dist/cli-delegate/{chunk-K4FFODTS.js → chunk-ILMUPLGW.js} +1227 -316
  103. package/dist/cli-delegate/{chunk-FF7WAFMR.js → chunk-KPBWFOPZ.js} +5 -1
  104. package/dist/cli-delegate/cmd_adr_effective.js +102 -0
  105. package/dist/cli-delegate/cmd_conformance.js +80 -11
  106. package/dist/cli-delegate/cmd_doctor.js +3 -3
  107. package/dist/cli-delegate/cmd_export.js +3 -2
  108. package/dist/cli-delegate/cmd_fleet.js +2 -2
  109. package/dist/cli-delegate/cmd_handoff.js +1 -1
  110. package/dist/cli-delegate/cmd_preflight.js +2 -2
  111. package/dist/cli-delegate/cmd_prune.js +3 -2
  112. package/dist/cli-delegate/cmd_settings_get.js +1 -1
  113. package/dist/cli-delegate/cmd_settings_migrate.js +3 -2
  114. package/dist/cli-delegate/cmd_settings_set.js +2 -2
  115. package/dist/cli-delegate/cmd_sync.js +3 -2
  116. package/dist/cli-delegate/cmd_uninstall.js +3 -2
  117. package/dist/cli-delegate/cmd_validate.js +3 -2
  118. package/dist/discovery/deprecation-report.md +1 -1
  119. package/dist/discovery/discovery-manifest.json +58 -58
  120. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  121. package/dist/discovery/discovery-manifest.summary.md +1 -1
  122. package/dist/discovery/dormancy-report.md +1 -1
  123. package/dist/discovery/orphan-report.md +1 -1
  124. package/dist/discovery/packs.json +2 -2
  125. package/dist/discovery/trust-report.md +1 -1
  126. package/dist/discovery/workspaces.json +2 -2
  127. package/dist/hooks/dispatch.js +2900 -1049
  128. package/dist/install/claudeRuleRewrite.js +254 -0
  129. package/dist/install/detect.js +29 -16
  130. package/dist/install/detect_php_shape.js +159 -0
  131. package/dist/install/install.mjs +634 -428
  132. package/dist/mcp/awesome-mcp-servers.row.md +1 -1
  133. package/dist/mcp/mcp-cloudflare-catalogue.json +1 -1
  134. package/dist/mcp/registry-manifest.json +3 -3
  135. package/dist/mcp/server.json +3 -3
  136. package/dist/mcp/server.mjs +4895 -2627
  137. package/dist/server/schemas/settings.js +3 -0
  138. package/dist/ui/assets/index-D0jaCRPM.js +29 -0
  139. package/dist/ui/index.html +1 -1
  140. package/docs/MIGRATION.md +1 -1
  141. package/docs/THIRD-PARTY-NOTICES.md +25 -0
  142. package/docs/contracts/provider-lifecycle.md +1 -1
  143. package/docs/contracts/settings-classes.md +10 -4
  144. package/docs/guidelines/agent-infra/5w2h-analysis.md +3 -3
  145. package/docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md +1 -0
  146. package/docs/guidelines/agent-infra/artifact-drafting-protocol-mechanics.md +58 -3
  147. package/docs/guidelines/agent-infra/ask-when-uncertain-demos.md +2 -2
  148. package/docs/guidelines/agent-infra/asking-and-brevity-examples.md +3 -3
  149. package/docs/guidelines/agent-infra/break-glass-usage.md +7 -7
  150. package/docs/guidelines/agent-infra/carve-out-predicates.md +3 -3
  151. package/docs/guidelines/agent-infra/comparison-matrix.md +1 -1
  152. package/docs/guidelines/agent-infra/critical-thinking.md +4 -4
  153. package/docs/guidelines/agent-infra/direct-answers-demos.md +2 -2
  154. package/docs/guidelines/agent-infra/domain-eval-anti-pattern.md +1 -1
  155. package/docs/guidelines/agent-infra/engineering-memory-data-format.md +3 -3
  156. package/docs/guidelines/agent-infra/existence-question-verdicts.md +80 -0
  157. package/docs/guidelines/agent-infra/first-principles.md +2 -2
  158. package/docs/guidelines/agent-infra/framework-neutrality-patterns.md +2 -2
  159. package/docs/guidelines/agent-infra/guarded-baseline.md +39 -0
  160. package/docs/guidelines/agent-infra/inversion-thinking.md +5 -5
  161. package/docs/guidelines/agent-infra/language-and-tone-examples.md +1 -1
  162. package/docs/guidelines/agent-infra/layered-settings.md +10 -10
  163. package/docs/guidelines/agent-infra/memory-access.md +1 -1
  164. package/docs/guidelines/agent-infra/mental-models.md +3 -3
  165. package/docs/guidelines/agent-infra/reuse-verdict-mechanics.md +71 -0
  166. package/docs/guidelines/agent-infra/review-routing-data-format.md +7 -7
  167. package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +13 -7
  168. package/docs/guidelines/agent-infra/role-contracts.md +2 -2
  169. package/docs/guidelines/agent-infra/role-mode-router.md +3 -3
  170. package/docs/guidelines/agent-infra/rule-type-governance.md +2 -2
  171. package/docs/guidelines/agent-infra/scqa-framework.md +5 -5
  172. package/docs/guidelines/agent-infra/self-improvement-pipeline.md +6 -6
  173. package/docs/guidelines/agent-infra/simplicity-and-goal-demos.md +2 -2
  174. package/docs/guidelines/agent-infra/six-hats.md +3 -3
  175. package/docs/guidelines/agent-infra/skill-quality-checklist.md +6 -6
  176. package/docs/guidelines/agent-infra/source-confidentiality-mechanics.md +109 -0
  177. package/docs/guidelines/agent-infra/systems-thinking.md +1 -1
  178. package/docs/guidelines/agent-infra/verify-before-complete-demos.md +2 -2
  179. package/docs/guidelines/augment-portability-patterns.md +6 -4
  180. package/docs/guidelines/code-clarity.md +18 -0
  181. package/docs/guidelines/component-oriented-and-oop-development.md +3 -2
  182. package/docs/guidelines/cross-role-handoff.md +2 -2
  183. package/docs/guidelines/design-fidelity-mechanics.md +1 -1
  184. package/docs/guidelines/docs/readme-size-and-splitting.md +3 -3
  185. package/docs/guidelines/php/database.md +90 -7
  186. package/docs/guidelines/prompt-templates.md +7 -7
  187. package/llms.txt +2 -2
  188. package/package.json +5 -2
  189. package/src/agent-src/scripts/archive_completed_roadmaps.ts +252 -8
  190. package/src/agent-src/scripts/guarded_baseline.ts +343 -0
  191. package/src/agent-src/scripts/roadmap_set_step.ts +253 -0
  192. package/src/agent-src/scripts/stub_queue.ts +82 -0
  193. package/src/agent-src/scripts/stubs_due.ts +516 -0
  194. package/src/agent-src/scripts/ticket_bundles.ts +84 -0
  195. package/src/agent-src/scripts/update_roadmap_progress.ts +16 -12
  196. package/src/agent-src/templates/scripts/check_memory.ts +258 -17
  197. package/src/agent-src/templates/scripts/check_memory_proposal.ts +9 -3
  198. package/src/agent-src/templates/scripts/memory_lookup.ts +86 -0
  199. package/src/agent-src/templates/scripts/memory_signal.ts +44 -0
  200. package/src/agent-src/templates/scripts/work_engine/directives/backend/implement.ts +90 -0
  201. package/src/agent-src/templates/scripts/work_engine/directives/backend/index.ts +11 -0
  202. package/src/agent-src/templates/scripts/work_engine/directives/backend/test.ts +23 -1
  203. package/src/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +10 -1
  204. package/src/agent-src/templates/scripts/work_engine/directives/mixed/stitch.ts +5 -1
  205. package/src/agent-src/templates/scripts/work_engine/stack/runner.ts +102 -14
  206. package/src/config/agent-settings.template.yml +32 -3
  207. package/src/config/assurance-capability-registry.json +21 -9
  208. package/src/config/canonical-terms.yml +119 -0
  209. package/src/config/capability-native-outcome-bars.json +81 -0
  210. package/src/config/ci-local-parity.yml +80 -0
  211. package/src/config/drafting-channels.yml +43 -0
  212. package/src/config/estate-count-budget.json +57 -36
  213. package/src/config/evaluator-budgets.json +14 -14
  214. package/src/config/gate-coverage.yml +729 -63
  215. package/src/config/gate-reachability-exemptions.json +21 -0
  216. package/src/config/gate-violation-baselines.json +42 -19
  217. package/src/config/harness-evolution-budget.json +25 -0
  218. package/src/config/lapsed-beta-baseline.json +96 -0
  219. package/src/config/memory-twin-verdicts.yml +129 -0
  220. package/src/config/metric-registry.yml +124 -0
  221. package/src/config/pack-size-budget.json +16 -15
  222. package/src/config/preamble-payload-budget.json +12 -4
  223. package/src/config/profiles/balanced.ini +27 -0
  224. package/src/config/profiles/full.ini +27 -0
  225. package/src/config/profiles/minimal.ini +27 -0
  226. package/src/config/publish-surface.json +9 -2
  227. package/src/config/routing-coverage-seed.json +16 -2
  228. package/src/config/rule-stub-ceilings.json +133 -112
  229. package/src/config/turnaround-budget.json +66 -0
  230. package/src/install/claudeRuleRewrite.ts +288 -0
  231. package/src/install/detect.ts +60 -17
  232. package/src/install/detect_php_shape.ts +191 -0
  233. package/src/scripts/_cli/cmd_doctor.ts +27 -112
  234. package/src/scripts/_dispatch.bash +23 -0
  235. package/src/scripts/_lib/activation_ladder.ts +255 -0
  236. package/src/scripts/_lib/activation_receipt_producer.ts +341 -0
  237. package/src/scripts/_lib/activation_states.ts +88 -0
  238. package/src/scripts/_lib/adherence_detectors.ts +143 -0
  239. package/src/scripts/_lib/adr_frontmatter.ts +26 -0
  240. package/src/scripts/_lib/arith_claims.ts +181 -0
  241. package/src/scripts/_lib/arm_ranking.ts +62 -0
  242. package/src/scripts/_lib/asset_delivery_ledger.ts +303 -0
  243. package/src/scripts/_lib/audit_field_provenance.ts +54 -0
  244. package/src/scripts/_lib/auto_dispatch.ts +32 -3
  245. package/src/scripts/_lib/bench_ab_size_claim.ts +98 -4
  246. package/src/scripts/_lib/benchmark_cache_fields.ts +158 -0
  247. package/src/scripts/_lib/candidate_pair_delta.ts +349 -0
  248. package/src/scripts/_lib/candidate_proposer.ts +402 -0
  249. package/src/scripts/_lib/candidate_record.ts +601 -0
  250. package/src/scripts/_lib/capture_rate.ts +319 -0
  251. package/src/scripts/_lib/carrier_status.ts +118 -0
  252. package/src/scripts/_lib/cascade_stage_enumeration.ts +92 -0
  253. package/src/scripts/_lib/collector_denominator.ts +771 -0
  254. package/src/scripts/_lib/collector_record.ts +340 -0
  255. package/src/scripts/_lib/collector_store.ts +664 -0
  256. package/src/scripts/_lib/collector_supervision.ts +827 -0
  257. package/src/scripts/_lib/concern_estate.ts +77 -0
  258. package/src/scripts/_lib/config_chain.ts +477 -0
  259. package/src/scripts/_lib/config_cost.ts +209 -0
  260. package/src/scripts/_lib/corpus_manifest.ts +726 -0
  261. package/src/scripts/_lib/council_settings_block.ts +6 -0
  262. package/src/scripts/_lib/curator_ops.ts +172 -0
  263. package/src/scripts/_lib/delivery_arm_experiment.ts +282 -0
  264. package/src/scripts/_lib/delivery_criticality.ts +126 -0
  265. package/src/scripts/_lib/doctor_runtime_checks.ts +70 -0
  266. package/src/scripts/_lib/empty_cycles.ts +88 -0
  267. package/src/scripts/_lib/estate_carrier_cases.ts +72 -0
  268. package/src/scripts/_lib/eval_publication.ts +354 -0
  269. package/src/scripts/_lib/evaluation_cascade.ts +452 -0
  270. package/src/scripts/_lib/evaluation_vector.ts +283 -0
  271. package/src/scripts/_lib/evaluator_promotion.ts +225 -0
  272. package/src/scripts/_lib/evidence_basis.ts +118 -0
  273. package/src/scripts/_lib/evolution_roi.ts +562 -0
  274. package/src/scripts/_lib/exec_evidence.ts +8 -0
  275. package/src/scripts/_lib/experience_card.ts +272 -0
  276. package/src/scripts/_lib/experience_report.ts +151 -0
  277. package/src/scripts/_lib/experiment_freeze.ts +112 -0
  278. package/src/scripts/_lib/generated_by.ts +66 -0
  279. package/src/scripts/_lib/harness_evolution_guards.ts +239 -0
  280. package/src/scripts/_lib/hook_effect_probe.ts +141 -0
  281. package/src/scripts/_lib/host_denominator.ts +687 -0
  282. package/src/scripts/_lib/host_projection_reach.ts +157 -0
  283. package/src/scripts/_lib/ignored_blocker.ts +148 -0
  284. package/src/scripts/_lib/install_reach_checks.ts +495 -0
  285. package/src/scripts/_lib/json_duplicate_keys.ts +150 -0
  286. package/src/scripts/_lib/judge_hygiene.ts +228 -0
  287. package/src/scripts/_lib/legacy_boundary_map.ts +228 -0
  288. package/src/scripts/_lib/lexical_shortlist.ts +215 -0
  289. package/src/scripts/_lib/llm_candidate_proposer.ts +461 -0
  290. package/src/scripts/_lib/llm_proposer_transport.ts +153 -0
  291. package/src/scripts/_lib/loop_guards.ts +299 -0
  292. package/src/scripts/_lib/loss_class.ts +129 -0
  293. package/src/scripts/_lib/machine_wake.ts +51 -0
  294. package/src/scripts/_lib/md_prose_lines.ts +177 -0
  295. package/src/scripts/_lib/minimality_tiebreak.ts +168 -0
  296. package/src/scripts/_lib/one_resolver_invariant.ts +449 -0
  297. package/src/scripts/_lib/orchestration_record.ts +253 -5
  298. package/src/scripts/_lib/outcome_envelope.ts +227 -0
  299. package/src/scripts/_lib/outcome_vocabularies.ts +125 -0
  300. package/src/scripts/_lib/paired_stats.ts +245 -0
  301. package/src/scripts/_lib/paired_verdict.ts +226 -0
  302. package/src/scripts/_lib/pathology_archive.ts +393 -0
  303. package/src/scripts/_lib/prefix_stable_surfaces.ts +123 -0
  304. package/src/scripts/_lib/privacy_class.ts +47 -0
  305. package/src/scripts/_lib/promotion_capability.ts +315 -0
  306. package/src/scripts/_lib/promotion_evidence.ts +414 -0
  307. package/src/scripts/_lib/promotion_review.ts +294 -0
  308. package/src/scripts/_lib/prompt_shape.ts +92 -0
  309. package/src/scripts/_lib/regression_neighbourhood.ts +259 -0
  310. package/src/scripts/_lib/release_highlights.ts +70 -1
  311. package/src/scripts/_lib/release_material.ts +125 -2
  312. package/src/scripts/_lib/repeated_failure.ts +105 -0
  313. package/src/scripts/_lib/repo_root.ts +111 -0
  314. package/src/scripts/_lib/review_skipped_record.ts +37 -0
  315. package/src/scripts/_lib/role_split.ts +338 -0
  316. package/src/scripts/_lib/routing_corpus.ts +307 -0
  317. package/src/scripts/_lib/routing_index_input.ts +104 -0
  318. package/src/scripts/_lib/rule_injection.ts +22 -1
  319. package/src/scripts/_lib/runtime_journal.ts +1499 -0
  320. package/src/scripts/_lib/runtime_wiring_checks.ts +430 -0
  321. package/src/scripts/_lib/semantic_noop.ts +167 -0
  322. package/src/scripts/_lib/skill_catalogue.ts +11 -1
  323. package/src/scripts/_lib/source_digest.ts +200 -0
  324. package/src/scripts/_lib/source_redact.ts +260 -0
  325. package/src/scripts/_lib/source_shape.ts +502 -0
  326. package/src/scripts/_lib/source_snapshot_dedup.ts +199 -0
  327. package/src/scripts/_lib/strip_comments.d.mts +8 -0
  328. package/src/scripts/_lib/strip_comments.mjs +65 -0
  329. package/src/scripts/_lib/test_red_state.ts +154 -0
  330. package/src/scripts/_lib/trigger_shift.ts +144 -0
  331. package/src/scripts/_lib/untrusted_content.ts +82 -7
  332. package/src/scripts/activation_receipt.ts +258 -0
  333. package/src/scripts/adoption_report.ts +1 -1
  334. package/src/scripts/adr/evidence_census.ts +1 -1
  335. package/src/scripts/adr/regenerate_index.ts +26 -2
  336. package/src/scripts/adr_cite_check.ts +164 -1
  337. package/src/scripts/ai_council/blind_review.ts +11 -1
  338. package/src/scripts/ai_council/clients.ts +4 -0
  339. package/src/scripts/ai_council/config.ts +3 -0
  340. package/src/scripts/ai_council/consensus.ts +28 -8
  341. package/src/scripts/ai_council/consensus_round.ts +226 -0
  342. package/src/scripts/ai_council/cross_exam.ts +128 -0
  343. package/src/scripts/ai_council/disagreement_signal.ts +338 -0
  344. package/src/scripts/ai_council/explain_route.ts +157 -0
  345. package/src/scripts/ai_council/information_gain.ts +293 -0
  346. package/src/scripts/ai_council/inline_findings.ts +340 -0
  347. package/src/scripts/ai_council/judge_position_bias.ts +197 -0
  348. package/src/scripts/ai_council/leakage_corpus.ts +385 -0
  349. package/src/scripts/ai_council/leakage_patterns.ts +453 -0
  350. package/src/scripts/ai_council/minority_retention.ts +171 -0
  351. package/src/scripts/ai_council/orchestrator.ts +16 -203
  352. package/src/scripts/ai_council/orchestrator_results.ts +23 -3
  353. package/src/scripts/ai_council/pricing.ts +106 -0
  354. package/src/scripts/ai_council/prompts.ts +74 -7
  355. package/src/scripts/ai_council/provider_leakage_bench.ts +327 -0
  356. package/src/scripts/ai_council/py_format.ts +14 -3
  357. package/src/scripts/ai_council/recouncil_guard.ts +293 -0
  358. package/src/scripts/ai_council/recouncil_savings.ts +299 -0
  359. package/src/scripts/ai_council/replay_route.ts +223 -0
  360. package/src/scripts/ai_council/response_record.ts +50 -0
  361. package/src/scripts/ai_council/reviewer_assignment.ts +279 -0
  362. package/src/scripts/ai_council/routing_training_row.ts +197 -0
  363. package/src/scripts/ai_council/synthesis_strategy.ts +159 -0
  364. package/src/scripts/ai_council/topology_bench_manifest.ts +860 -0
  365. package/src/scripts/ai_council/topology_vocabulary.ts +175 -0
  366. package/src/scripts/asset_delivery_ledger.ts +157 -0
  367. package/src/scripts/attest_artifact.ts +193 -0
  368. package/src/scripts/audit_auto_rules.ts +2 -1
  369. package/src/scripts/audit_command_surface.ts +1 -1
  370. package/src/scripts/audit_mcp_tools.ts +2 -2
  371. package/src/scripts/audit_skill_overlap_allowlist.json +6 -1
  372. package/src/scripts/audit_user_type_axis.ts +2 -1
  373. package/src/scripts/bench_ab_clone.ts +215 -10
  374. package/src/scripts/bench_ab_integrity.ts +119 -5
  375. package/src/scripts/bench_ab_v2_stats.ts +40 -213
  376. package/src/scripts/build_archive_index.ts +1 -1
  377. package/src/scripts/build_linear_digest.ts +1 -1
  378. package/src/scripts/build_proof.ts +11 -4
  379. package/src/scripts/build_rule_trigger_matrix.ts +1 -1
  380. package/src/scripts/build_source_digests.ts +157 -0
  381. package/src/scripts/cache_realization_report.ts +103 -0
  382. package/src/scripts/check_adr_frontmatter.ts +131 -10
  383. package/src/scripts/check_benchmark_report_fields.ts +207 -0
  384. package/src/scripts/check_beta_review_markers.ts +235 -6
  385. package/src/scripts/check_bundle_path_leakage.ts +34 -1
  386. package/src/scripts/check_claims.ts +576 -6
  387. package/src/scripts/check_composite_arming.ts +35 -0
  388. package/src/scripts/check_concern_admissions.ts +365 -0
  389. package/src/scripts/check_enforcement_coverage.ts +28 -0
  390. package/src/scripts/check_estate_count.ts +347 -25
  391. package/src/scripts/check_gate_reachability.ts +383 -0
  392. package/src/scripts/check_host_loadability.ts +104 -0
  393. package/src/scripts/check_loss_class_declared.ts +308 -0
  394. package/src/scripts/check_md_language.ts +15 -98
  395. package/src/scripts/check_memory_proposal.ts +18 -11
  396. package/src/scripts/check_no_currency_in_cost_surfaces.ts +225 -0
  397. package/src/scripts/check_no_external_sources.ts +281 -6
  398. package/src/scripts/check_pack_conformance_fixture.ts +11 -1
  399. package/src/scripts/check_pack_size.ts +59 -2
  400. package/src/scripts/check_preamble_payload_budget.ts +114 -3
  401. package/src/scripts/check_prefix_stable_mutation.ts +372 -0
  402. package/src/scripts/check_publish_surface.ts +10 -1
  403. package/src/scripts/check_references.ts +24 -1
  404. package/src/scripts/check_release_highlights.ts +96 -13
  405. package/src/scripts/check_roadmap_trackable.ts +17 -2
  406. package/src/scripts/check_rule_evidence_declaration.ts +316 -0
  407. package/src/scripts/check_rule_projection_integrity.ts +14 -4
  408. package/src/scripts/check_score_contract.ts +26 -3
  409. package/src/scripts/check_static_parity.ts +285 -0
  410. package/src/scripts/check_supervision_claim_atomicity.ts +498 -0
  411. package/src/scripts/check_suppression_hygiene.ts +15 -0
  412. package/src/scripts/ci_settle.ts +39 -2
  413. package/src/scripts/code_graph/build.ts +60 -3
  414. package/src/scripts/code_graph/extract.ts +44 -0
  415. package/src/scripts/code_graph/types.ts +24 -0
  416. package/src/scripts/collector_daemon.ts +714 -0
  417. package/src/scripts/config_cost_report.ts +302 -0
  418. package/src/scripts/consumer_matrix.ts +74 -1
  419. package/src/scripts/corpus_manifest.ts +235 -0
  420. package/src/scripts/cost/budget.mjs +10 -3
  421. package/src/scripts/cost/track.mjs +10 -3
  422. package/src/scripts/council_cli.ts +37 -54
  423. package/src/scripts/dispatch_r2_reviewer.ts +46 -5
  424. package/src/scripts/evolution_lab.ts +1153 -0
  425. package/src/scripts/external_sources_denylist.json +5 -18
  426. package/src/scripts/extract_audit_patterns.ts +21 -0
  427. package/src/scripts/fold_intake.ts +12 -1
  428. package/src/scripts/gen_discovery_baseline.ts +1 -1
  429. package/src/scripts/generate_capabilities_index.ts +12 -5
  430. package/src/scripts/generate_capability_matrix.ts +3 -3
  431. package/src/scripts/generate_command_flows.ts +2 -2
  432. package/src/scripts/generate_cookbook.ts +2 -2
  433. package/src/scripts/generate_index.ts +8 -1
  434. package/src/scripts/generate_knowledge_index.ts +2 -1
  435. package/src/scripts/generate_ownership_matrix.ts +2 -1
  436. package/src/scripts/generate_pack_manifests.ts +10 -2
  437. package/src/scripts/generate_role_experiences_catalog.ts +2 -2
  438. package/src/scripts/generate_settings_reference.ts +1 -1
  439. package/src/scripts/git_authorization_hook.ts +22 -1
  440. package/src/scripts/grade_target_readiness.ts +48 -5
  441. package/src/scripts/hook_effect_doctor.ts +261 -0
  442. package/src/scripts/hook_manifest.json +1 -1
  443. package/src/scripts/hook_manifest.yaml +125 -16
  444. package/src/scripts/hooks/block_speaking_inbox_dir.ts +271 -0
  445. package/src/scripts/hooks/block_unauthorized_git.ts +18 -0
  446. package/src/scripts/hooks/comment_discipline_hook.ts +146 -0
  447. package/src/scripts/hooks/concern_registry.ts +6 -0
  448. package/src/scripts/hooks/dispatch_hook.ts +32 -0
  449. package/src/scripts/hooks/journal_record_hook.ts +345 -0
  450. package/src/scripts/hooks/prepush_metadata_sources.sh +110 -0
  451. package/src/scripts/hooks/run_continuation_hook.ts +44 -9
  452. package/src/scripts/hooks/shims/install.sh +61 -0
  453. package/src/scripts/hooks/shims/php +101 -0
  454. package/src/scripts/hooks/suggestion_capture_hook.ts +10 -0
  455. package/src/scripts/hooks/turn_end_gate_hook.ts +9 -1
  456. package/src/scripts/hot_context_hook.ts +16 -0
  457. package/src/scripts/install-hooks.sh +20 -5
  458. package/src/scripts/install.ts +17 -35
  459. package/src/scripts/inventory_frontmatter.ts +2 -1
  460. package/src/scripts/language_mirror_hook.ts +14 -2
  461. package/src/scripts/lint_adr_sweep_routing.ts +12 -0
  462. package/src/scripts/lint_canonical_terms.ts +604 -0
  463. package/src/scripts/lint_carrier_integrity.ts +820 -0
  464. package/src/scripts/lint_code_comments.ts +643 -0
  465. package/src/scripts/lint_composition_review.ts +619 -0
  466. package/src/scripts/lint_consolidation_lineage.ts +666 -0
  467. package/src/scripts/lint_eval_specs.ts +593 -0
  468. package/src/scripts/lint_hook_manifest.ts +19 -0
  469. package/src/scripts/lint_host_portability.ts +373 -0
  470. package/src/scripts/lint_judge_prompt_expectation.ts +27 -1
  471. package/src/scripts/lint_memory_twin_parity.ts +335 -0
  472. package/src/scripts/lint_metric_consumers.ts +355 -0
  473. package/src/scripts/lint_plan_risk_register.ts +39 -19
  474. package/src/scripts/lint_promotion_paths.ts +779 -0
  475. package/src/scripts/lint_skill_descriptions.ts +18 -1
  476. package/src/scripts/lint_skill_frontmatter_safety.ts +58 -0
  477. package/src/scripts/lint_skill_link_reach.ts +252 -0
  478. package/src/scripts/lint_skill_trigger_corpus.ts +426 -23
  479. package/src/scripts/lint_ticket_buildable.ts +17 -1
  480. package/src/scripts/llm_propose.ts +256 -0
  481. package/src/scripts/mcp_server/consumer_tool_catalog.json +1 -1
  482. package/src/scripts/mcp_server/tool_catalog_source.ts +1 -1
  483. package/src/scripts/measure_delivery_sets.ts +361 -0
  484. package/src/scripts/measure_docs_dead_links.ts +348 -0
  485. package/src/scripts/measure_host_capture.ts +461 -0
  486. package/src/scripts/measure_routing_signal.ts +307 -0
  487. package/src/scripts/migration_status.ts +3 -3
  488. package/src/scripts/model_rule_injection.ts +76 -0
  489. package/src/scripts/orchestration_record.ts +14 -0
  490. package/src/scripts/preamble_byte_census.ts +139 -10
  491. package/src/scripts/prepack-check.mjs +4 -1
  492. package/src/scripts/probe_council_retention.ts +495 -0
  493. package/src/scripts/probe_turnaround.ts +384 -0
  494. package/src/scripts/probe_unblocked_ask.ts +279 -0
  495. package/src/scripts/release.ts +21 -37
  496. package/src/scripts/release_drill.ts +143 -0
  497. package/src/scripts/release_env.ts +35 -0
  498. package/src/scripts/release_publication.ts +84 -0
  499. package/src/scripts/render_benchmark_md.ts +1 -1
  500. package/src/scripts/rule_activation_census.ts +70 -9
  501. package/src/scripts/rule_backlinks.ts +1 -1
  502. package/src/scripts/run_lifecycle_suite.ts +208 -0
  503. package/src/scripts/run_skill_evals.ts +40 -0
  504. package/src/scripts/schemas/delivery-manifest.schema.json +43 -0
  505. package/src/scripts/schemas/drafting-channels.schema.json +43 -0
  506. package/src/scripts/schemas/evals.schema.json +24 -1
  507. package/src/scripts/schemas/rule.schema.json +52 -1
  508. package/src/scripts/schemas/skill.schema.json +17 -2
  509. package/src/scripts/skill_overlap.ts +7 -1
  510. package/src/scripts/skill_tools/run_block_d_eval.ts +8 -1
  511. package/src/scripts/skill_tools/score_skill_relevance.ts +84 -3
  512. package/src/scripts/skill_tools/suggest_skill_for_task.ts +8 -1
  513. package/src/scripts/skill_usage_report.ts +2 -1
  514. package/src/scripts/stubs_due.ts +211 -0
  515. package/src/scripts/sweep_source_surfaces.ts +678 -0
  516. package/src/scripts/sync_pr_branch.ts +3 -3
  517. package/src/scripts/trigger_eval_grandfather.json +202 -222
  518. package/src/scripts/utilization_report.ts +22 -2
  519. package/src/server/schemas/settings.ts +5 -0
  520. package/src/templates/marketing-copy.yml +1 -1
  521. package/dist/ui/assets/index-Cxgy63kz.js +0 -26
@@ -0,0 +1,516 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Read-only query: which roadmap stubs are overdue for a read, and which
4
+ * decisions are sitting on the owner.
5
+ *
6
+ * WHY THIS EXISTS, AND WHY IT LANDS BEFORE THE DATES DO.
7
+ * `agents/roadmaps/stubs/` holds 77 files that are, by construction, not active
8
+ * work — the directory listing IS the inventory (the index tables were deleted
9
+ * on 2026-08-21 and `check_no_stub_inventory_table` keeps them deleted). Giving
10
+ * each stub a `review_by:` date without giving anyone a way to READ those dates
11
+ * would be strictly worse than adding nothing: the repository would carry a
12
+ * field certifying attention it does not pay, and a stale date reads as
13
+ * evidence. An AI council (2026-08-26, 2/2) made the ordering a rule — the
14
+ * reader lands first, the backfill second. This is the reader.
15
+ *
16
+ * WHAT IT IS NOT. It is not a gate: it always exits 0, because "three stubs are
17
+ * overdue" is a state of the world, not a defect in a diff. It is not an
18
+ * inventory table: it prints to stdout on demand and writes nothing, least of
19
+ * all into `agents/roadmaps/stubs/`, so the guard that deleted the tables stays
20
+ * green and un-weakened. `agent-config roadmap:progress` consumes only its two
21
+ * COUNTS for the dashboard header — two integers, no rows, nothing to grow an
22
+ * index back from.
23
+ *
24
+ * THE TWO SHAPES HAVE DIFFERENT CLOCKS, and the cadence follows the shape, not
25
+ * the file. A drain-run transfer is capability-gated: an environment can appear
26
+ * at any moment, so it is re-probed every 30 days. An org-mode stub is
27
+ * demand-gated: customer recruitment and audit funding move slowly, so its
28
+ * demand question is re-asked every 120 days. Both numbers, and the reason 120
29
+ * was taken over 180, are recorded in `agents/roadmaps/stubs/README.md`
30
+ * § Frontmatter contract.
31
+ *
32
+ * OWNER DECISIONS are counted from two deterministic markers, because "the text
33
+ * routes a decision to the owner" needs to be readable by a script and not only
34
+ * by a person: an `## Unresolved decision` heading, and an open `### blocker:`
35
+ * whose owner is the maintainer. A stub can carry both.
36
+ *
37
+ * CLI contract: always exit 0.
38
+ * ./scripts-run src/scripts/stubs_due
39
+ * ./scripts-run src/scripts/stubs_due --json
40
+ * ./scripts-run src/scripts/stubs_due --counts # the two integers only
41
+ * ./scripts-run src/scripts/stubs_due --today 2026-12-01 # pin "now"
42
+ */
43
+ import * as fs from 'node:fs';
44
+ import * as path from 'node:path';
45
+ import { fileURLToPath, pathToFileURL } from 'node:url';
46
+
47
+ const STUB_DIR = path.join('agents', 'roadmaps', 'stubs');
48
+
49
+ /** Cadence in days, per stub shape. Source of truth: the README section above. */
50
+ export const CADENCE_DAYS = { transfer: 30, orgmode: 120 } as const;
51
+
52
+ /** The marker that identifies a drain-run transfer in a stub body. */
53
+ const TRANSFER_MARKER = 'drain-run transfer';
54
+
55
+ const _HERE = path.resolve(fileURLToPath(import.meta.url));
56
+
57
+ export type StubShape = 'transfer' | 'orgmode';
58
+
59
+ export interface StubRecord {
60
+ file: string;
61
+ shape: StubShape;
62
+ review_by: string | null;
63
+ reviewed_at: string | null;
64
+ probe_none: boolean;
65
+ has_probe_heading: boolean;
66
+ owner_decisions: number;
67
+ overdue: boolean;
68
+ days_overdue: number | null;
69
+ /** Frontmatter `design_validated:` — a citation, or null when absent. */
70
+ design_validated: string | null;
71
+ /** Frontmatter `capability_gap:` — `none` means the stub declares no gap. */
72
+ capability_gap: string | null;
73
+ /** Frontmatter `blocker_class:` — `estate` | `budget` | `product`. */
74
+ blocker_class: string | null;
75
+ /** Frontmatter `blocker_opened:` — ISO date the hold began, or null. */
76
+ blocker_opened: string | null;
77
+ /** Releases published since `blocker_opened`, or null when it is absent. */
78
+ releases_since_blocked: number | null;
79
+ /** All three membership conditions hold. See {@link BLOCKED_QUICKWIN_FIELDS}. */
80
+ blocked_quickwin: boolean;
81
+ }
82
+
83
+ /**
84
+ * The three frontmatter keys that decide fourth-bucket membership.
85
+ *
86
+ * Read as SCALARS, never as substrings of the body. A substring match over
87
+ * prose is what put a validated fix and a waiting preference into one bucket
88
+ * in the first place; doing it with three substrings instead of one would be
89
+ * worse, not better. A stub missing any of the three is not a member and falls
90
+ * through to the OWNER bucket exactly as before — absence is never a member.
91
+ */
92
+ export const BLOCKED_QUICKWIN_FIELDS = ['design_validated', 'capability_gap', 'blocker_class'] as const;
93
+
94
+ /** Blocker classes that make a stub a BLOCKED QUICK-WIN rather than a product wait. */
95
+ export const QUICKWIN_BLOCKER_CLASSES = ['estate', 'budget'] as const;
96
+
97
+ /**
98
+ * All three conditions, read from frontmatter only.
99
+ *
100
+ * A recorded design validation, an explicit `capability_gap: none`, and an open
101
+ * blocker that is an estate or budget decision rather than a product one.
102
+ */
103
+ export function is_blocked_quickwin(
104
+ design_validated: string | null,
105
+ capability_gap: string | null,
106
+ blocker_class: string | null,
107
+ ): boolean {
108
+ if (design_validated === null || design_validated === '') return false;
109
+ if (capability_gap !== 'none') return false;
110
+ return (QUICKWIN_BLOCKER_CLASSES as readonly string[]).includes(blocker_class ?? '');
111
+ }
112
+
113
+ function _isDir(p: string): boolean {
114
+ try {
115
+ return fs.statSync(p).isDirectory();
116
+ } catch {
117
+ return false;
118
+ }
119
+ }
120
+
121
+ /** Walk up from CWD until a dir containing `agents/roadmaps/stubs` is found. */
122
+ export function repo_root(start?: string): string {
123
+ let cur = start ?? process.cwd();
124
+ const chain = [cur];
125
+ for (;;) {
126
+ const parent = path.dirname(cur);
127
+ if (parent === cur) break;
128
+ chain.push(parent);
129
+ cur = parent;
130
+ }
131
+ for (const candidate of chain) {
132
+ if (_isDir(path.join(candidate, STUB_DIR))) {
133
+ return candidate;
134
+ }
135
+ }
136
+ return start ?? process.cwd();
137
+ }
138
+
139
+ /**
140
+ * The frontmatter block, as raw lines. Returns [] when the file does not open
141
+ * with `---` — a stub without frontmatter simply has no fields, which the
142
+ * caller reports rather than crashing on.
143
+ */
144
+ function _frontmatter(text: string): string[] {
145
+ const lines = text.split('\n');
146
+ if (lines[0]?.trim() !== '---') {
147
+ return [];
148
+ }
149
+ const out: string[] = [];
150
+ for (const line of lines.slice(1)) {
151
+ if (line.trim() === '---') {
152
+ return out;
153
+ }
154
+ out.push(line);
155
+ }
156
+ return [];
157
+ }
158
+
159
+ function _scalar(front: string[], key: string): string | null {
160
+ const prefix = `${key}:`;
161
+ for (const line of front) {
162
+ if (line.startsWith(prefix)) {
163
+ return line.slice(prefix.length).trim().replace(/^["']|["']$/g, '');
164
+ }
165
+ }
166
+ return null;
167
+ }
168
+
169
+ /**
170
+ * Owner-routed decisions in one stub body. Two markers, unioned:
171
+ * - an `## Unresolved decision …` heading — the shape
172
+ * `road-to-owner-authority-decisions.md` already uses;
173
+ * - an open `### blocker:` whose Owner line names the maintainer.
174
+ * Counting the union rather than one of them is deliberate: a stub can carry
175
+ * both, and either alone would under-report.
176
+ */
177
+ export function count_owner_decisions(text: string): number {
178
+ const lines = text.split('\n');
179
+ let n = 0;
180
+ for (const line of lines) {
181
+ if (/^#{2,4}\s+Unresolved decision\b/.test(line)) {
182
+ n += 1;
183
+ }
184
+ }
185
+ // Open maintainer-owned blockers. Scan each `### blocker:` section for the
186
+ // two field lines; a blocker missing either is not counted, because an
187
+ // unstated owner is not an owner decision.
188
+ let inBlocker = false;
189
+ let ownerIsMaintainer = false;
190
+ let statusOpen = false;
191
+ const flush = (): void => {
192
+ if (inBlocker && ownerIsMaintainer && statusOpen) {
193
+ n += 1;
194
+ }
195
+ inBlocker = false;
196
+ ownerIsMaintainer = false;
197
+ statusOpen = false;
198
+ };
199
+ for (const line of lines) {
200
+ if (/^#{2,4}\s+(blocker:|b-)/.test(line.trim()) || /^#{2,4}\s+\S+ — /.test(line)) {
201
+ if (/blocker:/.test(line) || /^#{2,4}\s+b-/.test(line.trim())) {
202
+ flush();
203
+ inBlocker = true;
204
+ continue;
205
+ }
206
+ }
207
+ if (!inBlocker) continue;
208
+ if (/^#{1,4}\s/.test(line)) {
209
+ flush();
210
+ continue;
211
+ }
212
+ if (/^-\s+\*\*Owner:\*\*\s*maintainer\b/i.test(line)) ownerIsMaintainer = true;
213
+ if (/^-\s+\*\*Status:\*\*\s*open\b/i.test(line)) statusOpen = true;
214
+ }
215
+ flush();
216
+ return n;
217
+ }
218
+
219
+ /** ISO date (UTC) N days after `from`. */
220
+ function _addDays(from: Date, days: number): string {
221
+ const d = new Date(from.getTime() + days * 86_400_000);
222
+ return d.toISOString().slice(0, 10);
223
+ }
224
+
225
+ function _parseIso(s: string): Date | null {
226
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(s)) return null;
227
+ const d = new Date(`${s}T00:00:00Z`);
228
+ return Number.isNaN(d.getTime()) ? null : d;
229
+ }
230
+
231
+ /** Read every stub and classify it. `today` is injectable so tests are stable. */
232
+ export function scan(root: string, today: string): StubRecord[] {
233
+ return scan_dir(path.join(root, STUB_DIR), today, release_dates(root));
234
+ }
235
+
236
+ /**
237
+ * Changelog files that carry released sections, newest era first.
238
+ *
239
+ * BOTH are read, and that is the whole point of the pair. The era split moved
240
+ * older releases into the archive, so a count taken over the current file alone
241
+ * silently reports zero for anything before the split — measured: 14.11.0 lives
242
+ * only in the archive, and grepping `CHANGELOG.md` for it returns nothing.
243
+ */
244
+ export const CHANGELOG_ERAS = ['CHANGELOG.md', 'docs/archive/CHANGELOG-pre-14.12.0.md'] as const;
245
+
246
+ /** `## [x.y.z](…) (YYYY-MM-DD)` — a released section heading with its date. */
247
+ const RELEASE_HEADING = /^## \[\d+\.\d+\.\d+\][^\n]*\((\d{4}-\d{2}-\d{2})\)\s*$/gm;
248
+
249
+ /** Every released section's date across both eras, unsorted. */
250
+ export function release_dates(root: string): string[] {
251
+ const out: string[] = [];
252
+ for (const rel of CHANGELOG_ERAS) {
253
+ let text: string;
254
+ try {
255
+ text = fs.readFileSync(path.join(root, rel), 'utf8');
256
+ } catch {
257
+ continue;
258
+ }
259
+ for (const m of text.matchAll(RELEASE_HEADING)) {
260
+ if (m[1] !== undefined) out.push(m[1]);
261
+ }
262
+ }
263
+ return out;
264
+ }
265
+
266
+ /**
267
+ * Releases published strictly AFTER the day the hold began.
268
+ *
269
+ * Strictly after, because a release cut on the same day cannot have carried a
270
+ * fix the hold was blocking — counting it would inflate the figure the
271
+ * council's falsifier is read against.
272
+ */
273
+ export function releases_since(opened: string, dates: readonly string[]): number {
274
+ return dates.filter((d) => d > opened).length;
275
+ }
276
+
277
+ /**
278
+ * Same, but addressed by the stub DIRECTORY rather than the repo root.
279
+ * `update_roadmap_progress` already holds `agents/roadmaps` and would otherwise
280
+ * have to walk back up two levels to hand this function a root it would
281
+ * immediately re-join — a fragile round trip past exactly the directory both
282
+ * callers care about.
283
+ */
284
+ export function scan_dir(
285
+ base: string,
286
+ today: string,
287
+ releaseDates: readonly string[] = [],
288
+ ): StubRecord[] {
289
+ if (!_isDir(base)) return [];
290
+ const now = _parseIso(today);
291
+ const out: StubRecord[] = [];
292
+ let names: string[];
293
+ try {
294
+ names = fs
295
+ .readdirSync(base)
296
+ .filter((n) => n.endsWith('.md') && n !== 'README.md')
297
+ .sort();
298
+ } catch {
299
+ return [];
300
+ }
301
+ for (const name of names) {
302
+ let text: string;
303
+ try {
304
+ text = fs.readFileSync(path.join(base, name), 'utf8');
305
+ } catch {
306
+ continue;
307
+ }
308
+ const front = _frontmatter(text);
309
+ const review_by = _scalar(front, 'review_by');
310
+ const reviewed_at = _scalar(front, 'reviewed_at');
311
+ const probeVal = _scalar(front, 'probe');
312
+ const design_validated = _scalar(front, 'design_validated');
313
+ const capability_gap = _scalar(front, 'capability_gap');
314
+ const blocker_class = _scalar(front, 'blocker_class');
315
+ const blocker_opened = _scalar(front, 'blocker_opened');
316
+ const shape: StubShape = text.includes(TRANSFER_MARKER) ? 'transfer' : 'orgmode';
317
+ let overdue = false;
318
+ let days_overdue: number | null = null;
319
+ if (review_by !== null && now !== null) {
320
+ const due = _parseIso(review_by);
321
+ if (due !== null && due.getTime() < now.getTime()) {
322
+ overdue = true;
323
+ days_overdue = Math.round((now.getTime() - due.getTime()) / 86_400_000);
324
+ }
325
+ }
326
+ out.push({
327
+ file: `${STUB_DIR}/${name}`,
328
+ shape,
329
+ review_by,
330
+ reviewed_at,
331
+ probe_none: probeVal === 'none',
332
+ has_probe_heading: /^#{1,4} *(Probe|Promotion)/m.test(text),
333
+ owner_decisions: count_owner_decisions(text),
334
+ overdue,
335
+ days_overdue,
336
+ design_validated,
337
+ capability_gap,
338
+ blocker_class,
339
+ blocker_opened,
340
+ releases_since_blocked:
341
+ blocker_opened === null ? null : releases_since(blocker_opened, releaseDates),
342
+ blocked_quickwin: is_blocked_quickwin(design_validated, capability_gap, blocker_class),
343
+ });
344
+ }
345
+ return out;
346
+ }
347
+
348
+ export interface Counts {
349
+ overdue: number;
350
+ owner_decisions: number;
351
+ missing_review_by: number;
352
+ /** ADDITIVE 2026-09-01. Existing keys are unchanged in name, type and meaning. */
353
+ blocked_quickwin: number;
354
+ total: number;
355
+ }
356
+
357
+ export function counts(records: StubRecord[]): Counts {
358
+ return {
359
+ overdue: records.filter((r) => r.overdue).length,
360
+ owner_decisions: records.reduce((s, r) => s + r.owner_decisions, 0),
361
+ missing_review_by: records.filter((r) => r.review_by === null).length,
362
+ blocked_quickwin: records.filter((r) => r.blocked_quickwin).length,
363
+ total: records.length,
364
+ };
365
+ }
366
+
367
+ /** Suggested `review_by:` for a stub of this shape, dated from `from`. */
368
+ export function due_date(shape: StubShape, from: string): string {
369
+ const d = _parseIso(from) ?? new Date();
370
+ return _addDays(d, CADENCE_DAYS[shape]);
371
+ }
372
+
373
+ export function main(argv: readonly string[] = process.argv.slice(2)): number {
374
+ const asJson = argv.includes('--json');
375
+ const countsOnly = argv.includes('--counts');
376
+ const todayIdx = argv.indexOf('--today');
377
+ const today =
378
+ todayIdx >= 0 && argv[todayIdx + 1] !== undefined
379
+ ? (argv[todayIdx + 1] as string)
380
+ : new Date().toISOString().slice(0, 10);
381
+
382
+ const root = repo_root();
383
+ const records = scan(root, today);
384
+ const c = counts(records);
385
+
386
+ if (countsOnly) {
387
+ process.stdout.write(`${c.overdue} ${c.owner_decisions}\n`);
388
+ return 0;
389
+ }
390
+ if (asJson) {
391
+ process.stdout.write(`${JSON.stringify({ today, counts: c, stubs: records }, null, 2)}\n`);
392
+ return 0;
393
+ }
394
+
395
+ process.stdout.write(`stubs:due · ${today} · ${c.total} stub(s) under ${STUB_DIR}/\n\n`);
396
+
397
+ const overdue = records.filter((r) => r.overdue).sort((a, b) => (b.days_overdue ?? 0) - (a.days_overdue ?? 0));
398
+ if (overdue.length === 0) {
399
+ process.stdout.write(' ✅ no stub is past its review date.\n');
400
+ } else {
401
+ process.stdout.write(` ⚠️ ${overdue.length} overdue:\n`);
402
+ for (const r of overdue) {
403
+ process.stdout.write(
404
+ ` ${r.file} (${r.shape}, due ${r.review_by}, ${r.days_overdue}d late)\n`,
405
+ );
406
+ }
407
+ }
408
+
409
+ if (c.missing_review_by > 0) {
410
+ process.stdout.write(
411
+ `\n ⚠️ ${c.missing_review_by} stub(s) carry no \`review_by:\` — see ` +
412
+ `${STUB_DIR}/README.md § Frontmatter contract:\n`,
413
+ );
414
+ for (const r of records.filter((x) => x.review_by === null)) {
415
+ process.stdout.write(
416
+ ` ${r.file} (${r.shape}, suggested ${due_date(r.shape, today)})\n`,
417
+ );
418
+ }
419
+ }
420
+
421
+ const withDecisions = records.filter((r) => r.owner_decisions > 0);
422
+ process.stdout.write(`\n ${c.owner_decisions} decision(s) routed to the owner`);
423
+ if (withDecisions.length === 0) {
424
+ process.stdout.write('.\n');
425
+ } else {
426
+ process.stdout.write(':\n');
427
+ for (const r of withDecisions) {
428
+ process.stdout.write(` ${r.file} (${r.owner_decisions})\n`);
429
+ }
430
+ }
431
+
432
+ const quickwins = records.filter((r) => r.blocked_quickwin);
433
+ if (quickwins.length > 0) {
434
+ process.stdout.write(
435
+ `\n 🔓 ${quickwins.length} BLOCKED QUICK-WIN(S) — design validated, no capability gap,\n` +
436
+ ' held by an estate or budget decision rather than a product one:\n',
437
+ );
438
+ for (const r of quickwins) {
439
+ const since =
440
+ r.releases_since_blocked === null
441
+ ? 'no `blocker_opened:`'
442
+ : `${String(r.releases_since_blocked)} release(s) since ${r.blocker_opened}`;
443
+ process.stdout.write(` ${r.file} (${r.blocker_class}, ${since})\n`);
444
+ }
445
+ }
446
+
447
+ const noProbe = records.filter((r) => !r.probe_none && !r.has_probe_heading);
448
+ if (noProbe.length > 0) {
449
+ process.stdout.write(
450
+ `\n ⚠️ ${noProbe.length} stub(s) name no promoting probe and do not say ` +
451
+ '`probe: none`:\n',
452
+ );
453
+ for (const r of noProbe) {
454
+ process.stdout.write(` ${r.file}\n`);
455
+ }
456
+ }
457
+
458
+ process.stdout.write('\n Read-only. This command writes nothing.\n');
459
+ return 0;
460
+ }
461
+
462
+ function _isCliEntry(): boolean {
463
+ if (process.argv[1] === undefined) {
464
+ return false;
465
+ }
466
+ const argvUrl = pathToFileURL(path.resolve(process.argv[1])).href;
467
+ if (import.meta.url === argvUrl) {
468
+ return true;
469
+ }
470
+ try {
471
+ const here = fs.realpathSync(fileURLToPath(import.meta.url));
472
+ const argv = fs.realpathSync(path.resolve(process.argv[1]));
473
+ return here === argv;
474
+ } catch {
475
+ return false;
476
+ }
477
+ }
478
+
479
+ if (_isCliEntry() || process.argv[1] === _HERE) {
480
+ process.exitCode = main();
481
+ }
482
+
483
+ /**
484
+ * The dashboard header fragment: two integers and a pointer, or `''` when both
485
+ * are zero.
486
+ *
487
+ * Lives here rather than in `update_roadmap_progress` deliberately. That file
488
+ * sits on the wrong side of the 1,500-line source-size ratchet, so every line
489
+ * added to it is charged; this one is 365 lines and is charged nothing. The
490
+ * generator gets a one-line call, and the rule that a count is not an inventory
491
+ * — no row, no per-stub link, nothing for the deleted index tables to grow back
492
+ * from — is enforced in one place instead of two.
493
+ *
494
+ * Failure-tolerant by construction: a tree with no `agents/roadmaps/stubs/`
495
+ * yields `''` rather than throwing. This runs in consumer installs that carry no
496
+ * stub directory at all, so a throwing read here would break their dashboard.
497
+ */
498
+ export function headerFragment(stubsDir: string, today?: string): string {
499
+ let overdue = 0;
500
+ let decisions = 0;
501
+ try {
502
+ const c = counts(scan_dir(stubsDir, today ?? new Date().toISOString().slice(0, 10)));
503
+ overdue = c.overdue;
504
+ decisions = c.owner_decisions;
505
+ } catch {
506
+ return '';
507
+ }
508
+ if (overdue === 0 && decisions === 0) {
509
+ return '';
510
+ }
511
+ return (
512
+ ` · **${overdue}** overdue stub${overdue !== 1 ? 's' : ''}` +
513
+ `, **${decisions}** owner decision${decisions !== 1 ? 's' : ''}` +
514
+ ' → `agent-config stubs:due`'
515
+ );
516
+ }
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Ticket bundles, read from `agents/tickets/_registry.yml` for the dashboard.
3
+ *
4
+ * Extracted from `update_roadmap_progress.ts` and imported back, so behaviour is
5
+ * unchanged. The move is mechanical: that file sits above the 1500-line ceiling
6
+ * `check_source_size_budget` charges, and a run that adds lines there pays for
7
+ * them by extraction rather than by raising a baseline.
8
+ */
9
+ import { createRequire } from 'node:module';
10
+ import * as fs from 'node:fs';
11
+ import * as path from 'node:path';
12
+
13
+ import type * as YamlModule from 'yaml';
14
+
15
+ const _require = createRequire(import.meta.url);
16
+
17
+ /** Local copy: the parent keeps its own, and one tiny predicate is cheaper than
18
+ * an export cycle between two scripts in the same directory. */
19
+ function _isDir(p: string): boolean {
20
+ try {
21
+ return fs.statSync(p).isDirectory();
22
+ } catch {
23
+ return false;
24
+ }
25
+ }
26
+
27
+ export interface Bundle {
28
+ slug: string;
29
+ tickets: number;
30
+ status: string;
31
+ roadmap: string;
32
+ }
33
+
34
+ export function collect_bundles(repo_root: string): Bundle[] {
35
+ const reg = path.join(repo_root, 'agents', 'tickets', '_registry.yml');
36
+ if (!fs.existsSync(reg)) {
37
+ return [];
38
+ }
39
+ let YAML: typeof YamlModule;
40
+ try {
41
+ YAML = _require('yaml') as typeof YamlModule;
42
+ } catch {
43
+ return [];
44
+ }
45
+ let data: unknown;
46
+ try {
47
+ // yaml.safe_load(...) or {} — PyYAML 1.1 semantics; graceful on malformed.
48
+ data = YAML.parse(fs.readFileSync(reg, { encoding: 'utf-8' }), { version: '1.1' }) ?? {};
49
+ } catch {
50
+ return [];
51
+ }
52
+ const out: Bundle[] = [];
53
+ const bundles =
54
+ data && typeof data === 'object' && !Array.isArray(data)
55
+ ? ((data as Record<string, unknown>)['bundles'] ?? null)
56
+ : null;
57
+ const bundleMap =
58
+ bundles && typeof bundles === 'object' && !Array.isArray(bundles)
59
+ ? (bundles as Record<string, unknown>)
60
+ : {};
61
+ for (const slug of Object.keys(bundleMap).sort()) {
62
+ const metaRaw = bundleMap[slug];
63
+ const meta =
64
+ metaRaw && typeof metaRaw === 'object' && !Array.isArray(metaRaw)
65
+ ? (metaRaw as Record<string, unknown>)
66
+ : {};
67
+ const bdir = path.join(repo_root, 'agents', 'tickets', slug);
68
+ let n = 0;
69
+ if (_isDir(bdir)) {
70
+ try {
71
+ n = fs.readdirSync(bdir).filter((f) => f.startsWith('T-') && f.endsWith('.md')).length;
72
+ } catch {
73
+ n = 0;
74
+ }
75
+ }
76
+ out.push({
77
+ slug,
78
+ tickets: n,
79
+ status: (meta['status'] as string) ?? '?',
80
+ roadmap: (meta['source_roadmap'] as string) ?? '',
81
+ });
82
+ }
83
+ return out;
84
+ }