@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
@@ -12,7 +12,7 @@
12
12
  * `archive_completed_roadmaps` can consume it the same way Python does. snake_case
13
13
  * is kept on the public surface.
14
14
  *
15
- * Scans every roadmap under `agents/roadmaps/` (excluding `archive/`, `skipped/`,
15
+ * Scans every roadmap under `agents/roadmaps/` (excluding `archive/`, `skipped/`, code-comment-allow provenance-comment -- the path is this script's operand, not where the code came from
16
16
  * `template.md`, `README.md`, `open-questions*.md`), counts checkbox states per
17
17
  * phase, and writes a dashboard at `agents/roadmaps-progress.md` (outside the
18
18
  * `roadmaps/` folder to keep it clean) with:
@@ -71,6 +71,8 @@ import {
71
71
  type DashboardMode,
72
72
  } from './dashboard_mode.js';
73
73
  import type * as YamlModule from 'yaml';
74
+ import { headerFragment as stubHeaderFragment } from './stubs_due.js';
75
+ import { reportGuardedBaselines } from './guarded_baseline.js'; // third step state; contract lives there
74
76
 
75
77
  const _HERE = fileURLToPath(import.meta.url);
76
78
  const _require = createRequire(import.meta.url);
@@ -94,7 +96,7 @@ const EXCLUDE_DIRS: ReadonlySet<string> = new Set(['archive', 'skipped', 'stubs'
94
96
 
95
97
  // FRONTMATTER_RE = re.compile(r"\A---\n(.*?)\n---\s*\n", re.DOTALL)
96
98
  const FRONTMATTER_RE = /^---\n([\s\S]*?)\n---[ \t\n\r\f\v]*\n/;
97
- const DRAFT_VALUES: ReadonlySet<string> = new Set(['draft']);
99
+ const UNSCHEDULED_VALUES: ReadonlySet<string> = new Set(['draft', 'carrier']);
98
100
 
99
101
  const MERGE_GATED_RE = /merge-gated/i;
100
102
  // PR_NUM_RE = re.compile(r"pr\s*[=#:]?\s*#?\s*(\d+)", re.IGNORECASE)
@@ -287,8 +289,8 @@ function _stripQuotes(s: string): string {
287
289
  return out;
288
290
  }
289
291
 
290
- function is_draft(fm: Record<string, string>): boolean {
291
- return DRAFT_VALUES.has((fm['status'] ?? '').toLowerCase());
292
+ function is_unscheduled(fm: Record<string, string>): boolean {
293
+ return UNSCHEDULED_VALUES.has((fm['status'] ?? '').toLowerCase());
292
294
  }
293
295
 
294
296
  /**
@@ -750,7 +752,7 @@ function collect(roadmap_root: string): RoadmapStats[] {
750
752
  continue;
751
753
  }
752
754
  const text = fs.readFileSync(p, { encoding: 'utf-8' });
753
- if (is_draft(parse_frontmatter(text))) {
755
+ if (is_unscheduled(parse_frontmatter(text))) {
754
756
  continue;
755
757
  }
756
758
  const stats = parse_roadmap(p, roadmap_root);
@@ -818,7 +820,7 @@ function collect_parked(roadmap_root: string): ParkedRoadmap[] {
818
820
  } catch {
819
821
  continue;
820
822
  }
821
- if (is_draft(parse_frontmatter(text))) {
823
+ if (is_unscheduled(parse_frontmatter(text))) {
822
824
  continue;
823
825
  }
824
826
  const cell = resume_cell(text);
@@ -995,6 +997,8 @@ function render(roadmaps: RoadmapStats[], bundles: Bundle[] | null, roadmap_root
995
997
  ? `, **${user_open_blockers}** need you → \`agent-config gates\``
996
998
  : '')
997
999
  : '') +
1000
+ // Two integers, never a row — see `stubs_due.headerFragment`.
1001
+ stubHeaderFragment(path.join(roadmap_root, 'stubs')) +
998
1002
  '\n';
999
1003
  lines.push(
1000
1004
  // Honest provenance (road-to-roadmap-archival-robustness, gap C): name a
@@ -1301,7 +1305,7 @@ function _parseArgs(argv: readonly string[]): Args {
1301
1305
  }
1302
1306
 
1303
1307
  /**
1304
- * When the default cwd carries no `agents/roadmaps/`, fall back to the git
1308
+ * When the default cwd carries no `agents/roadmaps/`, fall back to the git code-comment-allow provenance-comment -- the path is this script's operand, not where the code came from
1305
1309
  * toplevel — hook and IDE invocations often run from a subdirectory, and a
1306
1310
  * cwd-only resolution silently skipped the dashboard there. An explicit
1307
1311
  * `--repo-root` always wins; a cwd that has the directory is used as-is
@@ -1362,8 +1366,8 @@ function main(argv?: readonly string[]): number {
1362
1366
  return 1;
1363
1367
  }
1364
1368
  }
1365
- const roadmaps = collect(roadmap_root);
1366
- const new_text = render(roadmaps, collect_bundles(repo_root), roadmap_root);
1369
+ const roadmaps = collect(roadmap_root), guarded = reportGuardedBaselines(roadmaps, repo_root);
1370
+ const new_text = render(roadmaps, collect_bundles(repo_root), roadmap_root) + guarded.section;
1367
1371
  const complete = unarchived_complete(roadmaps);
1368
1372
  const pending = pending_iron_law_3(roadmaps);
1369
1373
  const gated = merge_gated_pending(roadmaps);
@@ -1395,7 +1399,7 @@ function main(argv?: readonly string[]): number {
1395
1399
  });
1396
1400
  if (r.stderr) process.stderr.write(r.stderr);
1397
1401
  if (r.stdout) process.stdout.write(r.stdout);
1398
- return r.rc;
1402
+ return guarded.problems > 0 ? 1 : r.rc;
1399
1403
  }
1400
1404
  fs.writeFileSync(target, new_text, { encoding: 'utf-8' });
1401
1405
  process.stdout.write(
@@ -1431,7 +1435,7 @@ function main(argv?: readonly string[]): number {
1431
1435
  if (gated.length) {
1432
1436
  _warn_merge_gated();
1433
1437
  }
1434
- return 0;
1438
+ return guarded.problems > 0 ? 1 : 0;
1435
1439
  }
1436
1440
 
1437
1441
  function _isCliEntry(): boolean {
@@ -1475,7 +1479,7 @@ export {
1475
1479
  TITLE_RE,
1476
1480
  FRONTMATTER_RE,
1477
1481
  parse_frontmatter,
1478
- is_draft,
1482
+ is_unscheduled,
1479
1483
  is_roadmap_candidate,
1480
1484
  count_checkboxes,
1481
1485
  parse_blockers,
@@ -1,17 +1,36 @@
1
1
  #!/usr/bin/env tsx
2
+ /*
3
+ * TEMPLATE COPY — reconciled with `src/scripts/check_memory.ts` on 2026-08-26
4
+ * (`road-to-memory-twin-reconciliation` 2.2, verdict `dev-side-correct`).
5
+ *
6
+ * TWO differences remain, and both are `keep-duplicated` for the same
7
+ * STRUCTURAL reason rather than by preference: the installed consumer tree has
8
+ * no `scripts/_lib/`, so a template script may import node built-ins, `yaml`
9
+ * and its own installed siblings — nothing else.
10
+ *
11
+ * - `assertScanned` (`_lib/scan_scope.js`), the dead-scope guard. Not
12
+ * importable here, and its absence is safe in the direction that matters:
13
+ * a consumer with no `agents/memory/` scans zero and passes, which is the
14
+ * correct reading for a project that keeps no memory.
15
+ * - `asOf` (`_lib/as_of.js`), the reproducible-clock pin behind this
16
+ * repository's own `AC_AS_OF` discipline. A consumer has no such pin, so
17
+ * `new Date()` is the right substitute rather than a downgrade.
18
+ *
19
+ * Everything else is identical, INCLUDING the validations this copy used to
20
+ * lack entirely: the `priority` enum, the critical-stale SLA, the one-fact
21
+ * length limit, relative-date discipline, per-type caps, tier-0 inflation, and
22
+ * `status: superseded`.
23
+ */
2
24
  /**
3
25
  * Engineering Memory validator.
4
26
  *
5
- * TypeScript twin of `src/agent-src/templates/scripts/check_memory.py`
6
- * (ADR-200, Phase 1 — consumer-shipped template). Adapted from the dev-side
7
- * `src/scripts/check_memory.ts` twin: the template `.py` is the leaner
8
- * consumer surface — it has NO `--shadow-report`, NO `priority`/date-discipline/
9
- * critical-stale/tier-0-inflation checks. Those are stripped here so this twin
10
- * matches the template `.py` exactly. The CLI contract mirrors the Python
11
- * original EXACTLY — same flags (`--path`, `--format`, `--append-only`,
12
- * `--base`), same exit codes, same stdout/stderr split, byte-identical finding
13
- * messages, same scan scope and ordering. No behaviour changes — latent bugs
14
- * are replicated and flagged in the porting report, not fixed.
27
+ * Ported from the retired Python `src/scripts/check_memory.py` (ADR-200, Phase 4 /
28
+ * Wave 4a). The CLI contract pins the historical contract exactly — same
29
+ * flags (`--path`, `--format`, `--append-only`, `--base`), same exit
30
+ * codes, same stdout/stderr split,
31
+ * byte-identical finding messages, same scan scope and ordering. No
32
+ * behaviour changes — latent bugs are replicated and flagged in the
33
+ * porting report, not fixed.
15
34
  *
16
35
  * Validates YAML files under `agents/memory/<type>/**\/*.yml` against the
17
36
  * schema documented in `guidelines/agent-infra/engineering-memory-data-format`.
@@ -39,7 +58,7 @@
39
58
  * check_memory --append-only # CI: diff vs origin/main
40
59
  * check_memory --append-only --base HEAD~1
41
60
  *
42
- * Note on YAML date typing: the Python original relies on PyYAML's
61
+ * Note on YAML date typing: the retired Python implementation relies on PyYAML's
43
62
  * `safe_load` converting unquoted `YYYY-MM-DD` scalars to `datetime.date`
44
63
  * (and `YYYY-MM-DD HH:MM:SS` to `datetime.datetime`). The `yaml` npm
45
64
  * package parses every scalar to a string, so this twin re-implements
@@ -56,6 +75,7 @@ import process from 'node:process';
56
75
  import { fileURLToPath, pathToFileURL } from 'node:url';
57
76
  import YAML, { parseDocument } from 'yaml';
58
77
 
78
+
59
79
  type Severity = 'error' | 'warning' | 'info';
60
80
 
61
81
  const REQUIRED_KEYS: ReadonlySet<string> = new Set([
@@ -67,14 +87,48 @@ const REQUIRED_KEYS: ReadonlySet<string> = new Set([
67
87
  'last_validated',
68
88
  'review_after_days',
69
89
  ]);
70
- const VALID_STATUS: ReadonlySet<string> = new Set(['active', 'deprecated', 'archived']);
90
+ const VALID_STATUS: ReadonlySet<string> = new Set(['active', 'deprecated', 'archived', 'superseded']);
71
91
  const VALID_CONFIDENCE: ReadonlySet<string> = new Set(['low', 'medium', 'high']);
92
+ // `priority` is optional (default `normal`); enum is the smallest set that
93
+ // solves the tier-0 surfacing use case. See the Phase 2 council brief for why
94
+ // the `high` tier was rejected.
95
+ const VALID_PRIORITY: ReadonlySet<string> = new Set(['critical', 'normal', 'low']);
96
+ // Soft-cap on `priority: critical` entries per memory type. Tier-0 inflation
97
+ // is the failure mode: when too many entries claim "always surface", the
98
+ // slice loses signal. Warn (not fail) when the cap is exceeded so curators
99
+ // notice without being blocked.
100
+ const CRITICAL_WARN_THRESHOLD = 10;
101
+ // Stale-critical guard: a `priority: critical` entry that hasn't been
102
+ // re-validated in this many days emits a warning. Surfaced separately
103
+ // from the generic `stale:` info so reviewers see it before merge.
104
+ const CRITICAL_STALE_DAYS = 90;
72
105
  const KNOWN_TYPES: ReadonlySet<string> = new Set([
73
106
  'domain-invariants',
107
+ 'historical-patterns',
74
108
  'incident-learnings',
109
+ 'ownership',
75
110
  'product-rules',
76
111
  ]);
77
112
 
113
+ // Per-type soft entry cap (size-bounding without a decay engine). Over-cap →
114
+ // warning, never a hard fail: the right answer to bloat is a consolidation pass
115
+ // (prune archived, merge duplicates), not CI failure. See
116
+ // road-to-memory-pipeline-consolidation.md Phase 7.
117
+ const PER_TYPE_CAPS: Readonly<Record<string, number>> = {
118
+ ownership: 50,
119
+ 'domain-invariants': 150,
120
+ 'product-rules': 100,
121
+ 'incident-learnings': 150,
122
+ 'historical-patterns': 150,
123
+ };
124
+ const DEFAULT_TYPE_CAP = 150;
125
+ // One-durable-fact-per-entry: a content field longer than this reads as a
126
+ // transcript / narrative blob, not a single durable fact → warning.
127
+ const ONE_FACT_MAX_CHARS = 600;
128
+ const ONE_FACT_FIELDS = ['rule', 'pattern', 'statement', 'observation', 'body', 'decision', 'note'] as const;
129
+ // Per-type entry tally, populated during validation, consumed by main().
130
+ const _TYPE_COUNTS: Record<string, number> = {};
131
+
78
132
  // Redaction heuristics — plain-regex, deliberately conservative.
79
133
  // False positives are fixed by quoting the line differently; false
80
134
  // negatives are a curator responsibility.
@@ -90,6 +144,15 @@ const REDACTION_PATTERNS: ReadonlyArray<readonly [RegExp, string]> = [
90
144
  [/\b192\.168\.\d{1,3}\.\d{1,3}\b/, 'internal ipv4 range'],
91
145
  ];
92
146
 
147
+ // Date-discipline — relative-date phrases without an ISO YYYY-MM-DD anchor
148
+ // within ±20 chars are rejected. Memory entries that say "yesterday" or
149
+ // "last week" rot the moment the file is re-read on another day; the
150
+ // anchor pins meaning.
151
+ const RELATIVE_DATE_PATTERN =
152
+ /\b(yesterday|today|tomorrow|last\s+(?:week|month|year)|next\s+(?:week|month|year)|this\s+(?:week|month|year))\b/gi;
153
+ const ISO_DATE_PATTERN = /\b\d{4}-\d{2}-\d{2}\b/;
154
+ const DATE_ANCHOR_WINDOW = 20;
155
+
93
156
  // PyYAML timestamp implicit-resolver. A *plain* (unquoted) scalar matching
94
157
  // this is constructed as datetime.date / datetime.datetime — both pass
95
158
  // `isinstance(value, datetime.date)`. Source: yaml/resolver.py.
@@ -246,6 +309,15 @@ function _isInteger(v: unknown): v is number {
246
309
  return typeof v === 'number' && Number.isInteger(v);
247
310
  }
248
311
 
312
+ /** Mirror Python len(str) — code-point count, not UTF-16 unit count. */
313
+ function _pyLen(s: string): number {
314
+ let n = 0;
315
+ for (const _ of s) {
316
+ n += 1;
317
+ }
318
+ return n;
319
+ }
320
+
249
321
  function _memoryType(p: string): string {
250
322
  // Supports `memory/<type>.yml`, `memory/<type>/<hash>.yml`, and
251
323
  // `memory/<type>.example.yml` template filenames.
@@ -270,7 +342,13 @@ function _stem(name: string): string {
270
342
  return base.slice(0, dot);
271
343
  }
272
344
 
273
- function _validateEntry(entry: Entry, p: string, seenIds: Set<string>, findings: Finding[]): void {
345
+ function _validateEntry(
346
+ entry: Entry,
347
+ p: string,
348
+ seenIds: Set<string>,
349
+ findings: Finding[],
350
+ criticalCounts: Record<string, number> | null,
351
+ ): void {
274
352
  const eid = typeof entry['id'] === 'string' ? (entry['id'] as string) : entry['id'] != null ? String(entry['id']) : '';
275
353
  const eidStr = entry['id'] == null ? '' : eid;
276
354
  const present = new Set(Object.keys(entry));
@@ -292,6 +370,22 @@ function _validateEntry(entry: Entry, p: string, seenIds: Set<string>, findings:
292
370
  if (confidence && typeof confidence === 'string' && !VALID_CONFIDENCE.has(confidence)) {
293
371
  findings.push(new Finding(p, 0, 'error', `invalid confidence '${confidence}'`, eidStr));
294
372
  }
373
+ // Priority is optional (defaults to `normal` at read time). When present
374
+ // it MUST be one of the three-tier enum — see VALID_PRIORITY for the
375
+ // rationale on rejecting a fourth `high` tier.
376
+ const priority = entry['priority'];
377
+ if (priority !== undefined && priority !== null && !(typeof priority === 'string' && VALID_PRIORITY.has(priority))) {
378
+ const sortedPri = [...VALID_PRIORITY].sort();
379
+ findings.push(
380
+ new Finding(
381
+ p,
382
+ 0,
383
+ 'error',
384
+ `invalid priority '${_pyStr(priority)}' (expected one of [${sortedPri.map((x) => `'${x}'`).join(', ')}])`,
385
+ eidStr,
386
+ ),
387
+ );
388
+ }
295
389
  const sources = (entry['source'] ?? []) as unknown;
296
390
  if (!Array.isArray(sources) || sources.length < 1) {
297
391
  findings.push(new Finding(p, 0, 'error', 'source must be a list with ≥1 entry', eidStr));
@@ -309,6 +403,71 @@ function _validateEntry(entry: Entry, p: string, seenIds: Set<string>, findings:
309
403
  findings.push(new Finding(p, 0, 'info', `stale: last_validated ${age} days ago (limit ${days})`, eidStr));
310
404
  }
311
405
  }
406
+ // Critical-stale guard: a `priority: critical` entry that has not been
407
+ // re-validated within CRITICAL_STALE_DAYS surfaces as a warning, even
408
+ // when the entry's own `review_after_days` is more lenient. Critical
409
+ // entries surface on every /memory:load — they have a tighter SLA.
410
+ if (priority === 'critical' && entry['status'] === 'active' && lv instanceof PyDate) {
411
+ const critAge = _dateDiffDays(_today(), lv);
412
+ if (critAge > CRITICAL_STALE_DAYS) {
413
+ findings.push(
414
+ new Finding(
415
+ p,
416
+ 0,
417
+ 'warning',
418
+ `critical-stale: last_validated ${critAge} days ago (critical SLA is ${CRITICAL_STALE_DAYS} days)`,
419
+ eidStr,
420
+ ),
421
+ );
422
+ }
423
+ }
424
+ // One-durable-fact-per-entry: reject transcript/narrative blobs. A single
425
+ // content field over ONE_FACT_MAX_CHARS is the bloat signal.
426
+ for (const fld of ONE_FACT_FIELDS) {
427
+ const val = entry[fld];
428
+ if (typeof val === 'string' && _pyLen(val) > ONE_FACT_MAX_CHARS) {
429
+ findings.push(
430
+ new Finding(
431
+ p,
432
+ 0,
433
+ 'warning',
434
+ `one-fact: \`${fld}\` is ${_pyLen(val)} chars (limit ${ONE_FACT_MAX_CHARS}) — split into separate durable facts, not a narrative blob`,
435
+ eidStr,
436
+ ),
437
+ );
438
+ break;
439
+ }
440
+ }
441
+ // Tier-0 inflation tracking — increment per memory type. The aggregate
442
+ // warning is emitted in main() after all files are validated.
443
+ if (criticalCounts !== null && priority === 'critical' && entry['status'] === 'active') {
444
+ const mtype = _memoryType(p);
445
+ criticalCounts[mtype] = (criticalCounts[mtype] ?? 0) + 1;
446
+ }
447
+ // Per-type entry-count tracking — aggregate cap warning in main().
448
+ if (criticalCounts !== null) {
449
+ const mt = _memoryType(p);
450
+ _TYPE_COUNTS[mt] = (_TYPE_COUNTS[mt] ?? 0) + 1;
451
+ }
452
+ }
453
+
454
+ /** Mirror Python's `str(value)` for the priority error message. */
455
+ function _pyStr(value: unknown): string {
456
+ if (value === null) {
457
+ return 'None';
458
+ }
459
+ if (value === true) {
460
+ return 'True';
461
+ }
462
+ if (value === false) {
463
+ return 'False';
464
+ }
465
+ if (value instanceof PyDate) {
466
+ const mm = String(value.month).padStart(2, '0');
467
+ const dd = String(value.day).padStart(2, '0');
468
+ return `${value.year}-${mm}-${dd}`;
469
+ }
470
+ return String(value);
312
471
  }
313
472
 
314
473
  function _checkRedaction(p: string, findings: Finding[]): void {
@@ -328,6 +487,38 @@ function _checkRedaction(p: string, findings: Finding[]): void {
328
487
  });
329
488
  }
330
489
 
490
+ function _checkDateDiscipline(p: string, findings: Finding[]): void {
491
+ // Reject relative-date phrases without an ISO YYYY-MM-DD anchor.
492
+ const text = fs.readFileSync(p, 'utf-8');
493
+ const lines = _splitlines(text);
494
+ lines.forEach((line, idx) => {
495
+ const lineNo = idx + 1;
496
+ const stripped = line.trimStart();
497
+ if (stripped.startsWith('#') || stripped.startsWith('last_validated')) {
498
+ return;
499
+ }
500
+ RELATIVE_DATE_PATTERN.lastIndex = 0;
501
+ let match: RegExpExecArray | null;
502
+ while ((match = RELATIVE_DATE_PATTERN.exec(line)) !== null) {
503
+ const start = Math.max(0, match.index - DATE_ANCHOR_WINDOW);
504
+ const end = Math.min(line.length, match.index + match[0].length + DATE_ANCHOR_WINDOW);
505
+ const windowStr = line.slice(start, end);
506
+ if (ISO_DATE_PATTERN.test(windowStr)) {
507
+ continue;
508
+ }
509
+ const phrase = match[0];
510
+ findings.push(
511
+ new Finding(
512
+ p,
513
+ lineNo,
514
+ 'error',
515
+ `relative date '${phrase}' without an ISO YYYY-MM-DD anchor within ±${DATE_ANCHOR_WINDOW} chars (re-anchor before commit)`,
516
+ ),
517
+ );
518
+ }
519
+ });
520
+ }
521
+
331
522
  /** Mirror Python str.splitlines() for the line-numbering used above. */
332
523
  function _splitlines(text: string): string[] {
333
524
  if (text === '') {
@@ -342,12 +533,17 @@ function _splitlines(text: string): string[] {
342
533
  return lines;
343
534
  }
344
535
 
345
- function _validateFile(p: string, findings: Finding[]): void {
536
+ function _validateFile(
537
+ p: string,
538
+ findings: Finding[],
539
+ criticalCounts: Record<string, number> | null,
540
+ ): void {
346
541
  const mtype = _memoryType(p);
347
542
  if (!KNOWN_TYPES.has(mtype)) {
348
543
  findings.push(new Finding(p, 0, 'warning', `unknown memory type '${mtype}'`));
349
544
  }
350
545
  _checkRedaction(p, findings);
546
+ _checkDateDiscipline(p, findings);
351
547
  let data: unknown;
352
548
  try {
353
549
  data = pyYamlSafeLoad(fs.readFileSync(p, 'utf-8'));
@@ -369,7 +565,7 @@ function _validateFile(p: string, findings: Finding[]): void {
369
565
  if (Array.isArray(entries)) {
370
566
  for (const entry of entries) {
371
567
  if (_isPlainObject(entry)) {
372
- _validateEntry(entry as Entry, p, seenIds, findings);
568
+ _validateEntry(entry as Entry, p, seenIds, findings, criticalCounts);
373
569
  }
374
570
  }
375
571
  }
@@ -549,8 +745,53 @@ function main(): number {
549
745
  }
550
746
  return 0;
551
747
  }
552
- for (const yml of _rglobYmlSorted(root)) {
553
- _validateFile(yml, findings);
748
+ // An ABSENT root stays a pinned exit-0 no-op (the branch above; the memory
749
+ // tree is an optional surface and `task check-memory` short-circuits it).
750
+ // A root that EXISTS but walks to zero `*.yml` is the case nothing covered:
751
+ // entries moved to a subtree this walk does not reach, and the validator
752
+ // reported "0 error(s)" over an empty read. No `allowEmpty` for that half —
753
+ // a present-but-unreadable corpus is blindness, not a clean bill of health.
754
+ // Exit 1 is this gate's only failure code (see `_emit`).
755
+ // No dead-scope guard: `_lib/scan_scope.js` is not installed with the
756
+ // template, and a consumer with no `agents/memory/` legitimately scans zero.
757
+ const ymls = _rglobYmlSorted(root);
758
+
759
+ const criticalCounts: Record<string, number> = {};
760
+ for (const key of Object.keys(_TYPE_COUNTS)) {
761
+ delete _TYPE_COUNTS[key];
762
+ }
763
+ for (const yml of ymls) {
764
+ _validateFile(yml, findings, criticalCounts);
765
+ }
766
+ // Tier-0 inflation warning — soft cap on `priority: critical` per type.
767
+ // Council convergence (Phase 2 B2): warn rather than block, because the
768
+ // right answer to "too many criticals" is curator review, not CI failure.
769
+ for (const [mtype, count] of Object.entries(criticalCounts).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))) {
770
+ if (count > CRITICAL_WARN_THRESHOLD) {
771
+ findings.push(
772
+ new Finding(
773
+ `agents/memory/${mtype}`,
774
+ 0,
775
+ 'warning',
776
+ `tier-0 inflation: ${count} active 'priority: critical' entries (threshold ${CRITICAL_WARN_THRESHOLD}) — review whether all still warrant always-surface treatment`,
777
+ ),
778
+ );
779
+ }
780
+ }
781
+ // Per-type entry-count cap (size-bounding, Phase 7). Warn, never block —
782
+ // over-cap signals a consolidation pass is due (prune archived, merge dups).
783
+ for (const [mtype, count] of Object.entries(_TYPE_COUNTS).sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))) {
784
+ const cap = PER_TYPE_CAPS[mtype] ?? DEFAULT_TYPE_CAP;
785
+ if (count > cap) {
786
+ findings.push(
787
+ new Finding(
788
+ `agents/memory/${mtype}`,
789
+ 0,
790
+ 'warning',
791
+ `entry-cap: ${count} entries (soft cap ${cap}) — run a consolidation pass (prune archived, merge duplicates)`,
792
+ ),
793
+ );
794
+ }
554
795
  }
555
796
  return _emit(findings, args.format);
556
797
  }
@@ -217,6 +217,7 @@ interface ParsedArgs {
217
217
  intake_id: string | null;
218
218
  proposal: string | null;
219
219
  format: 'text' | 'json';
220
+ quiet: boolean;
220
221
  }
221
222
 
222
223
  function _argparse_error(message: string): never {
@@ -228,6 +229,7 @@ function parse_args(argv: readonly string[]): ParsedArgs {
228
229
  let intake_id: string | null = null;
229
230
  let proposal: string | null = null;
230
231
  let format: 'text' | 'json' = 'text';
232
+ let quiet = false;
231
233
  // argparse reports a mutually-exclusive conflict against the SECOND-seen
232
234
  // arg at the point it is parsed (order-sensitive), so check inline rather
233
235
  // than after the loop.
@@ -248,10 +250,12 @@ function parse_args(argv: readonly string[]): ParsedArgs {
248
250
  format = _checkFormat(v);
249
251
  } else if (arg.startsWith('--format=')) {
250
252
  format = _checkFormat(arg.slice('--format='.length));
253
+ } else if (arg === '--quiet') {
254
+ quiet = true;
251
255
  } else if (arg === '-h' || arg === '--help') {
252
256
  process.stdout.write(
253
257
  'usage: check_memory_proposal [-h] (--intake-id INTAKE_ID | --proposal PROPOSAL)\n' +
254
- ' [--format {text,json}]\n',
258
+ ' [--format {text,json}] [--quiet]\n',
255
259
  );
256
260
  process.exit(0);
257
261
  } else {
@@ -261,7 +265,7 @@ function parse_args(argv: readonly string[]): ParsedArgs {
261
265
  if (intake_id === null && proposal === null) {
262
266
  _argparse_error('one of the arguments --intake-id --proposal is required');
263
267
  }
264
- return { intake_id, proposal, format };
268
+ return { intake_id, proposal, format, quiet };
265
269
  }
266
270
 
267
271
  function _need(argv: readonly string[], i: number, flag: string): string {
@@ -322,7 +326,9 @@ function main(argv?: readonly string[]): number {
322
326
  process.stdout.write(` 🔴 ${f}\n`);
323
327
  }
324
328
  } else {
325
- process.stdout.write(`✅ ${source} — gate passed\n`);
329
+ if (!args.quiet) {
330
+ process.stdout.write(`✅ ${source} — gate passed\n`);
331
+ }
326
332
  }
327
333
  }
328
334
  return failures.length > 0 ? 1 : 0;
@@ -246,6 +246,74 @@ function _pad2(v: string): string {
246
246
  * (`agents/memory/<type>.yml` or `<type>/entries.yml` with an `entries:`
247
247
  * list), so consumers can adopt either.
248
248
  */
249
+ const _CURATED_STATUS_EXCLUDE: ReadonlySet<string> = new Set(['deprecated', 'archived', 'superseded']);
250
+
251
+ /** Mirror Python `entry.get("status") in _CURATED_STATUS_EXCLUDE`. */
252
+ function _statusExcluded(entry: Record<string, unknown>): boolean {
253
+ const status = entry['status'];
254
+ return typeof status === 'string' && _CURATED_STATUS_EXCLUDE.has(status);
255
+ }
256
+
257
+
258
+ /*
259
+ * Staleness, ported from `src/scripts/memory_lookup.ts` on 2026-08-26
260
+ * (`road-to-memory-twin-reconciliation` 2.2, verdict `dev-side-correct`).
261
+ *
262
+ * The template previously had NO staleness handling at all — `grep -c stale`
263
+ * returned 0 — so a consumer retrieved curated entries whose own
264
+ * `review_after_days` window had expired, with nothing saying so. `check_memory`
265
+ * required both fields on every entry the whole time; only retrieval ignored
266
+ * them.
267
+ *
268
+ * Portable by construction: Date math and a regex, no `_lib` import.
269
+ */
270
+ function _today(): Date {
271
+ const now = new Date();
272
+ return new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
273
+ }
274
+
275
+ function _parseIsoDate(s: string): Date | null {
276
+ const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(s);
277
+ if (!m) {
278
+ return null;
279
+ }
280
+ const y = Number(m[1]);
281
+ const mo = Number(m[2]);
282
+ const d = Number(m[3]);
283
+ if (mo < 1 || mo > 12 || d < 1 || d > 31) {
284
+ return null;
285
+ }
286
+ const date = new Date(Date.UTC(y, mo - 1, d));
287
+ // Reject overflow (e.g. 2026-02-31 → March), matching fromisoformat's strictness.
288
+ if (date.getUTCFullYear() !== y || date.getUTCMonth() !== mo - 1 || date.getUTCDate() !== d) {
289
+ return null;
290
+ }
291
+ return date;
292
+ }
293
+
294
+ function _pyStrDateLike(lv: unknown): string {
295
+ if (lv instanceof PyTimestamp) {
296
+ return lv.pyStr;
297
+ }
298
+ return _pyStr(lv);
299
+ }
300
+
301
+ function _isStale(entry: Record<string, unknown>, today: Date): boolean {
302
+ const lv = entry['last_validated'];
303
+ const rad = entry['review_after_days'];
304
+ // Python: `not lv or not isinstance(rad, int)`. PyYAML ints land as JS
305
+ // numbers; booleans are int in Python but excluded here as the common path.
306
+ if (!lv || typeof rad !== 'number' || !Number.isInteger(rad)) {
307
+ return false;
308
+ }
309
+ const validated = _parseIsoDate(_pyStrDateLike(lv));
310
+ if (validated === null) {
311
+ return false;
312
+ }
313
+ const days = Math.round((today.getTime() - validated.getTime()) / 86_400_000);
314
+ return days > rad;
315
+ }
316
+
249
317
  function* _iter_curated_entries(mtype: string): Generator<[string, Record<string, unknown>]> {
250
318
  const type_dir = path.join(MEMORY_ROOT, mtype);
251
319
  const single_file = path.join(MEMORY_ROOT, `${mtype}.yml`);
@@ -254,6 +322,9 @@ function* _iter_curated_entries(mtype: string): Generator<[string, Record<string
254
322
  const entries = _isPlainObject(data) ? data['entries'] : null;
255
323
  for (const e of Array.isArray(entries) ? entries : []) {
256
324
  if (_isPlainObject(e)) {
325
+ if (_statusExcluded(e)) {
326
+ continue;
327
+ }
257
328
  yield [single_file, e];
258
329
  }
259
330
  }
@@ -266,11 +337,17 @@ function* _iter_curated_entries(mtype: string): Generator<[string, Record<string
266
337
  if (Array.isArray(entries)) {
267
338
  for (const e of entries) {
268
339
  if (_isPlainObject(e)) {
340
+ if (_statusExcluded(e)) {
341
+ continue;
342
+ }
269
343
  yield [yml, e];
270
344
  }
271
345
  }
272
346
  } else if (_isPlainObject(data) && data['id']) {
273
347
  // Flat, one-entry-per-file layout (content-addressed).
348
+ if (_statusExcluded(data)) {
349
+ continue;
350
+ }
274
351
  yield [yml, data];
275
352
  }
276
353
  }
@@ -454,6 +531,7 @@ function _cross_repo_hits(keys: string[], limit: number): Hit[] {
454
531
  */
455
532
  export function retrieve(types: string[], keys: string[], limit = 5): Hit[] {
456
533
  const repo_hits: Hit[] = [];
534
+ const today = _today();
457
535
  for (const mtype of types) {
458
536
  if (mtype === KNOWLEDGE_TYPE) {
459
537
  for (const [p, entry] of _iter_knowledge_entries()) {
@@ -488,6 +566,14 @@ export function retrieve(types: string[], keys: string[], limit = 5): Hit[] {
488
566
  continue;
489
567
  }
490
568
  for (const [p, entry] of _iter_curated_entries(mtype)) {
569
+ // A curated entry past its own `review_after_days` window is not
570
+ // retrieved. The dev side additionally reports it under `skipped`;
571
+ // this copy has no `retrieve_with_meta`, so it filters silently —
572
+ // the exclusion is the behaviour that matters, the report is the
573
+ // richer surface.
574
+ if (_isStale(entry, today)) {
575
+ continue;
576
+ }
491
577
  repo_hits.push(new Hit(String(entry['id'] ?? ''), mtype, 'curated', String(p), _score(entry, keys), entry));
492
578
  }
493
579
  for (const [p, entry] of _iter_intake_entries(mtype)) {