@event4u/agent-config 9.19.0 → 9.21.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 (234) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +89 -0
  3. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  4. package/dist/cli-delegate/{chunk-XGA2NTU4.js → chunk-3EWYC3YK.js} +40 -0
  5. package/dist/cli-delegate/cmd_handoff.js +1 -1
  6. package/dist/cli-delegate/cmd_memory_get.js +1 -1
  7. package/dist/cli-delegate/cmd_route_audit.js +1 -1
  8. package/dist/discovery/deprecation-report.md +1 -1
  9. package/dist/discovery/discovery-manifest.json +1 -1
  10. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  11. package/dist/discovery/discovery-manifest.summary.md +1 -1
  12. package/dist/discovery/orphan-report.md +1 -1
  13. package/dist/discovery/packs.json +1 -1
  14. package/dist/discovery/trust-report.md +1 -1
  15. package/dist/discovery/workspaces.json +1 -1
  16. package/dist/hooks/dispatch.js +58 -2
  17. package/dist/mcp/registry-manifest.json +2 -2
  18. package/dist/mcp/server.json +2 -2
  19. package/dist/mcp/server.mjs +47 -29
  20. package/package.json +1 -1
  21. package/src/config/gate-coverage.yml +38 -4
  22. package/src/config/gate-violation-baselines.json +3 -8
  23. package/src/scripts/_lib/gate_population.ts +70 -0
  24. package/src/scripts/_lib/roadmap_granularity.ts +157 -0
  25. package/src/scripts/_lib/scan_scope.ts +44 -0
  26. package/src/scripts/_lib/stdin.ts +82 -0
  27. package/src/scripts/audit_adr_coverage.ts +38 -0
  28. package/src/scripts/audit_auto_rules.ts +17 -3
  29. package/src/scripts/audit_command_surface.ts +51 -0
  30. package/src/scripts/audit_initial_context.ts +39 -3
  31. package/src/scripts/audit_mcp_tools.ts +25 -0
  32. package/src/scripts/audit_overlap.ts +24 -1
  33. package/src/scripts/audit_skill_descriptions.ts +19 -0
  34. package/src/scripts/{verify_before_complete_hook.ts → before_complete_hook.ts} +16 -3
  35. package/src/scripts/check_adr_frontmatter.ts +23 -3
  36. package/src/scripts/check_always_budget.ts +24 -0
  37. package/src/scripts/check_artefact_checksums.ts +24 -1
  38. package/src/scripts/check_artefact_count_messaging.ts +20 -0
  39. package/src/scripts/check_augmentignore.ts +22 -15
  40. package/src/scripts/check_backstop_debt.ts +22 -0
  41. package/src/scripts/check_beta_review_markers.ts +22 -1
  42. package/src/scripts/check_bridge_derivation.ts +22 -1
  43. package/src/scripts/check_bundle_path_leakage.ts +26 -0
  44. package/src/scripts/check_ci_strict_superset.ts +21 -3
  45. package/src/scripts/check_claims.ts +22 -0
  46. package/src/scripts/check_cli_registry_budget_sync.ts +33 -4
  47. package/src/scripts/check_cluster_patterns.ts +26 -4
  48. package/src/scripts/check_command_count_messaging.ts +20 -4
  49. package/src/scripts/check_comparison.ts +18 -0
  50. package/src/scripts/check_completion_review.ts +19 -4
  51. package/src/scripts/check_condensed_paths.ts +23 -2
  52. package/src/scripts/check_consumer_scope_flip.ts +21 -2
  53. package/src/scripts/check_council_config_location.ts +20 -0
  54. package/src/scripts/check_council_layout.ts +22 -2
  55. package/src/scripts/check_council_references.ts +23 -1
  56. package/src/scripts/check_dependency_floors.ts +19 -3
  57. package/src/scripts/check_discovery_determinism.ts +26 -0
  58. package/src/scripts/check_enforcement_coverage.ts +20 -0
  59. package/src/scripts/check_evaluator_budgets.ts +23 -0
  60. package/src/scripts/check_finding_dispositions.ts +29 -0
  61. package/src/scripts/check_gate_coverage.ts +63 -22
  62. package/src/scripts/check_gate_paths.ts +30 -5
  63. package/src/scripts/check_generated_artefact_headers.ts +21 -0
  64. package/src/scripts/check_generator_output_coverage.ts +23 -0
  65. package/src/scripts/check_gitignore_freshness.ts +23 -0
  66. package/src/scripts/check_host_loadability.ts +34 -8
  67. package/src/scripts/check_installer_import_purity.ts +22 -8
  68. package/src/scripts/check_kernel_prefix_stability.ts +19 -1
  69. package/src/scripts/check_kernel_rule_bundle.ts +23 -0
  70. package/src/scripts/check_knowledge_cards.ts +13 -0
  71. package/src/scripts/check_knowledge_pages.ts +23 -0
  72. package/src/scripts/check_knowledge_sharing.ts +27 -0
  73. package/src/scripts/check_md_language.ts +24 -0
  74. package/src/scripts/check_media_deps.ts +23 -0
  75. package/src/scripts/check_memory.ts +26 -1
  76. package/src/scripts/check_memory_contradiction.ts +16 -1
  77. package/src/scripts/check_memory_proposal.ts +15 -0
  78. package/src/scripts/check_memory_similarity.ts +16 -0
  79. package/src/scripts/check_module_management_neutral.ts +19 -11
  80. package/src/scripts/check_no_conflict_markers.ts +22 -1
  81. package/src/scripts/check_no_external_sources.ts +26 -1
  82. package/src/scripts/check_no_local_settings_committed.ts +37 -10
  83. package/src/scripts/check_no_new_legacy_path.ts +30 -1
  84. package/src/scripts/check_one_off_location.ts +43 -0
  85. package/src/scripts/check_originality_freshness.ts +25 -1
  86. package/src/scripts/check_overlay_cascade_subdirs.ts +21 -0
  87. package/src/scripts/check_pack_size.ts +22 -0
  88. package/src/scripts/check_preamble_payload_budget.ts +35 -5
  89. package/src/scripts/check_proposal.ts +24 -1
  90. package/src/scripts/check_public_catalog_links.ts +27 -0
  91. package/src/scripts/check_public_links.ts +19 -0
  92. package/src/scripts/check_quality_regression.ts +19 -0
  93. package/src/scripts/check_reach_channels.ts +44 -0
  94. package/src/scripts/check_reach_staleness.ts +27 -0
  95. package/src/scripts/check_release_adjacent_health.ts +28 -0
  96. package/src/scripts/check_release_highlights.ts +34 -0
  97. package/src/scripts/check_release_includes_discovery.ts +25 -6
  98. package/src/scripts/check_release_pr_shape.ts +18 -1
  99. package/src/scripts/check_release_published.ts +21 -0
  100. package/src/scripts/check_release_surface_equality.ts +22 -0
  101. package/src/scripts/check_release_trunk_sync.ts +19 -0
  102. package/src/scripts/check_reply_consistency.ts +22 -0
  103. package/src/scripts/check_review_dispositions.ts +188 -0
  104. package/src/scripts/check_roadmap_trackable.ts +20 -0
  105. package/src/scripts/check_role_doc_links.ts +23 -0
  106. package/src/scripts/check_rule_invariants.ts +14 -0
  107. package/src/scripts/check_secret_leak.ts +47 -0
  108. package/src/scripts/check_skill_gaps.ts +32 -0
  109. package/src/scripts/check_skill_requires.ts +19 -0
  110. package/src/scripts/check_source_pointer_freshness.ts +20 -0
  111. package/src/scripts/check_structural_breaking.ts +29 -2
  112. package/src/scripts/check_surface_tiers.ts +34 -0
  113. package/src/scripts/check_template_pin_drift.ts +23 -1
  114. package/src/scripts/check_test_coverage_diff.ts +17 -1
  115. package/src/scripts/check_token_optimizer_freshness.ts +18 -3
  116. package/src/scripts/check_token_quality_golden.ts +21 -0
  117. package/src/scripts/check_token_regression.ts +25 -0
  118. package/src/scripts/check_tracked_but_ignored.ts +26 -0
  119. package/src/scripts/check_trigger_eval_presence.ts +23 -1
  120. package/src/scripts/check_trigger_evals.ts +36 -0
  121. package/src/scripts/check_trunk_drift.ts +23 -0
  122. package/src/scripts/check_update_banner.ts +24 -0
  123. package/src/scripts/dispatch_r2_reviewer.ts +3 -0
  124. package/src/scripts/gate_scope_classify.ts +513 -0
  125. package/src/scripts/hook_manifest.yaml +1 -1
  126. package/src/scripts/hooks/block_kernel_rule_writes.ts +1 -1
  127. package/src/scripts/hooks/concern_registry.ts +2 -2
  128. package/src/scripts/lint_agent_security.ts +19 -0
  129. package/src/scripts/lint_agent_skill_names.ts +30 -0
  130. package/src/scripts/lint_agents_layout.ts +20 -0
  131. package/src/scripts/lint_agents_md.ts +20 -0
  132. package/src/scripts/lint_archived_skills.ts +24 -3
  133. package/src/scripts/lint_behavioural_eval_freshness.ts +29 -3
  134. package/src/scripts/lint_bench_ab.ts +25 -0
  135. package/src/scripts/lint_bench_corpus.ts +20 -4
  136. package/src/scripts/lint_breaking_changes_index.ts +24 -0
  137. package/src/scripts/lint_budget_ownership.ts +20 -3
  138. package/src/scripts/lint_changelog_rollback.ts +24 -0
  139. package/src/scripts/lint_command_flow_coverage.ts +22 -0
  140. package/src/scripts/lint_command_tiers.ts +29 -5
  141. package/src/scripts/lint_commit_subjects.ts +15 -0
  142. package/src/scripts/lint_confusables.ts +24 -0
  143. package/src/scripts/lint_consumer_internal_refs.ts +24 -0
  144. package/src/scripts/lint_design_quality.ts +22 -0
  145. package/src/scripts/lint_design_slop.ts +23 -0
  146. package/src/scripts/lint_discovery_manifest.ts +23 -0
  147. package/src/scripts/lint_discovery_vocabulary.ts +19 -0
  148. package/src/scripts/lint_documented_commands.ts +23 -0
  149. package/src/scripts/lint_empty_roadmaps.ts +23 -0
  150. package/src/scripts/lint_eval_fixture_citations.ts +19 -0
  151. package/src/scripts/lint_eval_freshness.ts +35 -0
  152. package/src/scripts/lint_examples.ts +18 -3
  153. package/src/scripts/lint_explain_trace.ts +23 -0
  154. package/src/scripts/lint_featured_skills.ts +26 -1
  155. package/src/scripts/lint_flows.ts +19 -0
  156. package/src/scripts/lint_frontmatter_boilerplate.ts +20 -0
  157. package/src/scripts/lint_ghostwriter_source.ts +26 -6
  158. package/src/scripts/lint_glama_drift.ts +24 -0
  159. package/src/scripts/lint_global_paths.ts +24 -0
  160. package/src/scripts/lint_governed_writes.ts +20 -0
  161. package/src/scripts/lint_hidden_unicode.ts +25 -0
  162. package/src/scripts/lint_hook_concern_budget.ts +39 -6
  163. package/src/scripts/lint_hook_manifest.ts +22 -0
  164. package/src/scripts/lint_instruction_smuggling.ts +23 -0
  165. package/src/scripts/lint_knowledge_scale.ts +32 -2
  166. package/src/scripts/lint_legal_pack.ts +31 -0
  167. package/src/scripts/lint_marketplace.ts +26 -0
  168. package/src/scripts/lint_marketplace_install_completeness.ts +23 -0
  169. package/src/scripts/lint_mcp_config_security.ts +24 -0
  170. package/src/scripts/lint_mcp_registry_manifest.ts +22 -1
  171. package/src/scripts/lint_memory_tripwire.ts +35 -0
  172. package/src/scripts/lint_missions.ts +23 -7
  173. package/src/scripts/lint_model_tier_coverage.ts +18 -0
  174. package/src/scripts/lint_namespace_collisions.ts +19 -0
  175. package/src/scripts/lint_no_new_atomic_commands.ts +33 -0
  176. package/src/scripts/lint_no_python_twin_rationale.ts +18 -0
  177. package/src/scripts/lint_one_off_age.ts +38 -2
  178. package/src/scripts/lint_orchestration_dsl.ts +23 -3
  179. package/src/scripts/lint_orchestrator_auto_detect.ts +19 -12
  180. package/src/scripts/lint_originality.ts +22 -4
  181. package/src/scripts/lint_originality_shingles.ts +28 -3
  182. package/src/scripts/lint_output_slop.ts +19 -0
  183. package/src/scripts/lint_override_kernel_guard.ts +30 -0
  184. package/src/scripts/lint_pack_first_win.ts +23 -0
  185. package/src/scripts/lint_pack_risk_class.ts +19 -3
  186. package/src/scripts/lint_persistence.ts +19 -0
  187. package/src/scripts/lint_persona_governance.ts +18 -3
  188. package/src/scripts/lint_positioning.ts +23 -0
  189. package/src/scripts/lint_pre_migration_refs.ts +24 -0
  190. package/src/scripts/lint_profile_overlay_set_only.ts +24 -0
  191. package/src/scripts/lint_provenance.ts +21 -0
  192. package/src/scripts/lint_provenance_vocabulary.ts +24 -1
  193. package/src/scripts/lint_readme_jargon.ts +21 -3
  194. package/src/scripts/lint_readme_serial_comma.ts +21 -3
  195. package/src/scripts/lint_readme_size.ts +21 -3
  196. package/src/scripts/lint_regression.ts +28 -0
  197. package/src/scripts/lint_roadmap_blockers.ts +43 -0
  198. package/src/scripts/lint_roadmap_ci_steps.ts +45 -0
  199. package/src/scripts/lint_roadmap_complexity.ts +47 -0
  200. package/src/scripts/lint_roadmap_later_disposition.ts +23 -0
  201. package/src/scripts/lint_rule_interactions.ts +16 -2
  202. package/src/scripts/lint_rule_tiers.ts +19 -6
  203. package/src/scripts/lint_showcase_sessions.ts +19 -3
  204. package/src/scripts/lint_skill_descriptions.ts +19 -0
  205. package/src/scripts/lint_skill_frontmatter_safety.ts +24 -0
  206. package/src/scripts/lint_skill_originality.ts +18 -3
  207. package/src/scripts/lint_skill_scripts_readonly.ts +20 -0
  208. package/src/scripts/lint_skill_tools.ts +84 -145
  209. package/src/scripts/lint_spawn_payload.ts +27 -1
  210. package/src/scripts/lint_store_boundary.ts +19 -0
  211. package/src/scripts/lint_subagent_determinism.ts +23 -1
  212. package/src/scripts/lint_supported_tools_matrix.ts +18 -0
  213. package/src/scripts/lint_surface_matrix.ts +19 -3
  214. package/src/scripts/lint_ticket_buildable.ts +23 -0
  215. package/src/scripts/lint_topics_yaml.ts +19 -12
  216. package/src/scripts/lint_trigger_precision.ts +27 -0
  217. package/src/scripts/lint_trust_coherence.ts +21 -0
  218. package/src/scripts/lint_ui_stack_bundles.ts +17 -3
  219. package/src/scripts/lint_value_dashboard.ts +19 -3
  220. package/src/scripts/lint_versioned_cache.ts +19 -1
  221. package/src/scripts/lint_workflow_security.ts +22 -14
  222. package/src/scripts/pr_url_reminder_hook.ts +1 -1
  223. package/src/scripts/skill_collision_clusters.ts +37 -3
  224. package/src/scripts/skill_discovery.ts +20 -0
  225. package/src/scripts/skill_eval_coverage.ts +22 -0
  226. package/src/scripts/skill_overlap.ts +32 -6
  227. package/src/scripts/skill_preview.ts +31 -0
  228. package/src/scripts/skill_trigger_eval.ts +18 -0
  229. package/src/scripts/skill_usage_collect.ts +21 -0
  230. package/src/scripts/skill_usage_report.ts +21 -0
  231. package/src/scripts/sweep_dead_scan_roots.ts +11 -3
  232. package/src/scripts/verify_physical_move.ts +24 -0
  233. package/src/scripts/check_bite_sized_granularity.ts +0 -116
  234. package/src/scripts/lint_workspace_boundary.ts +0 -267
@@ -6,7 +6,7 @@
6
6
  },
7
7
  "metadata": {
8
8
  "description": "Bootstrap shim for the event4u agent-config suite. This plugin ships ONLY the dispatcher hooks plus one install-pointer skill — ALL content (skills, rules, commands) is installed via `npx -y @event4u/agent-config init`, which writes the file projection AND registers the same hooks in ~/.claude/settings.json. DEPRECATED as a content channel; kept so the marketplace listing stays discoverable and existing installs keep working hooks.",
9
- "version": "9.19.0",
9
+ "version": "9.21.0",
10
10
  "keywords": [
11
11
  "agent-config",
12
12
  "skills",
package/CHANGELOG.md CHANGED
@@ -294,6 +294,95 @@ Entry-shape contract: [`docs/contracts/CHANGELOG-conventions.md`](docs/contracts
294
294
  > that forces a new era split (`# Era: 9.19.x`, etc.) — see
295
295
  > [`docs/contracts/CHANGELOG-conventions.md § Era splits`](docs/contracts/CHANGELOG-conventions.md).
296
296
 
297
+ ## [9.21.0](https://github.com/event4u-app/agent-config/compare/9.20.0...9.21.0) (2026-08-05)
298
+
299
+ ### Release highlights
300
+
301
+ <!-- Curated head: fill before merge, keep it under 10 lines, and leave `_none_` where it is genuinely the answer. The generated log below is unchanged. -->
302
+ - **Behaviour changes:** _none_
303
+ - **Default changes + migration:** _none_
304
+ - **Security and correctness:** _none_
305
+ - **Honest nulls:** _none_
306
+ - **Known limitations:** _none_
307
+
308
+ ### Features
309
+
310
+ * **gates:** take the unhardened-gate count to 0 and delete the ratchet entry ([e31690c](https://github.com/event4u-app/agent-config/commit/e31690c7330bb90ed813cc25ead2268da2971ea1))
311
+ * **gates:** repoint lint_skill_tools at the .ts corpus and harden it ([694a729](https://github.com/event4u-app/agent-config/commit/694a729359e674953881a996af6079123e91a98d))
312
+ * **gates:** fold bite-sized granularity into lint_roadmap_complexity ([08d9075](https://github.com/event4u-app/agent-config/commit/08d9075c978a6a76a250a74fe6377ad3b2c2d8a2))
313
+ * **gates:** assert the scan scope of the last 57 gates — 61 → 4 ([5244b21](https://github.com/event4u-app/agent-config/commit/5244b21ea664db73a3a07c8ce717a2b43c4ba157))
314
+ * **gates:** assert the scan scope of 54 more gates — 115 → 61 ([835fd54](https://github.com/event4u-app/agent-config/commit/835fd545649287574c9d74e3280302ca429b8d20))
315
+ * **gates:** assert the scan scope of 48 tree-walking gates ([9cc51a2](https://github.com/event4u-app/agent-config/commit/9cc51a20c8d3d3c9f133d0bb8a94a322b90ee235))
316
+ * **gates:** assert the scan scope of 28 more corpus gates ([f4e79e4](https://github.com/event4u-app/agent-config/commit/f4e79e4a8f7c90e27353693f42d27c1a70bbdac4))
317
+ * **gates:** classify the corpusless gates by what they read ([c7a851b](https://github.com/event4u-app/agent-config/commit/c7a851becd7a77ff85c7c443c59ca45b91bc7ef3))
318
+ * **gates:** assert the scan scope of five corpus gates ([7433f72](https://github.com/event4u-app/agent-config/commit/7433f72482c639bf88d01e58e093d7c57a608960))
319
+ * **gates:** derive the conversion work-list instead of reading 189 gates ([b845e4d](https://github.com/event4u-app/agent-config/commit/b845e4df66e90b1d43a42f9fa55bb41457b4a1b5))
320
+ * **scan-scope:** pair the scope assertion with the published count ([b8b2840](https://github.com/event4u-app/agent-config/commit/b8b2840d17466f0be5047fbaa98ed67751a93a70))
321
+
322
+ ### Bug Fixes
323
+
324
+ * **gates:** read piped stdin whole — a gate that only broke on big diffs ([0e3e9cd](https://github.com/event4u-app/agent-config/commit/0e3e9cd4ca91c01c00d8c611a96db72b936952d8))
325
+ * **gates:** clear the two preflight blockers the repairs introduced ([2683395](https://github.com/event4u-app/agent-config/commit/268339595ca2dd34b14a1a63abd6362fde7868fb))
326
+ * **gates:** repair two dead scan roots the widened population revealed ([5b41c55](https://github.com/event4u-app/agent-config/commit/5b41c556bc245c4eb9da7506b4de449a3cde07b0))
327
+ * **gates:** one definition of "a gate", and an honest denominator ([9f65efe](https://github.com/event4u-app/agent-config/commit/9f65efea7882d4c79f2e5f4c8fcefb0b521bcdde))
328
+ * **gate-coverage:** an unenforced `scanned:` line hardens nothing ([2873c91](https://github.com/event4u-app/agent-config/commit/2873c919d0245ca76a18f2315c768b9a9cb1e1ca))
329
+
330
+ ### Documentation
331
+
332
+ * **roadmap:** close and archive road-to-gate-hardening-adoption ([d1497c5](https://github.com/event4u-app/agent-config/commit/d1497c5fc12f5475b683f27b42953cf2f448def8))
333
+ * **roadmap:** file the four-gate blocker where the dashboard reads it ([7e0c8e9](https://github.com/event4u-app/agent-config/commit/7e0c8e9e369c29a7574c99f1ec453835e1ae44e9))
334
+ * **roadmap:** close Phase 1 — the mechanically-safe conversions ([877859a](https://github.com/event4u-app/agent-config/commit/877859ac99e70a79630b201a025a474df156fe55))
335
+ * **roadmap:** record the assert-first conversion contract ([613d478](https://github.com/event4u-app/agent-config/commit/613d47878252edfe8c5d225d73c1bed3fe6fb753))
336
+
337
+ ### Refactoring
338
+
339
+ * **gates:** re-home the ADR-095 workspace boundary to ESLint ([2bc2483](https://github.com/event4u-app/agent-config/commit/2bc24833149cff33573a84c9dfbc973b5b3b5fe3))
340
+ * **hooks:** rename verify_before_complete_hook off the gate prefix ([f57d969](https://github.com/event4u-app/agent-config/commit/f57d969c6c54e591060054f217a12d816d121116))
341
+
342
+ ### Chores
343
+
344
+ * **tests:** drop a dead helper the lint scope only now reaches ([9b49d24](https://github.com/event4u-app/agent-config/commit/9b49d240140c9b6af28969c752f4757bf5580d98))
345
+
346
+ Tests: 11034 (+39 since 9.20.0)
347
+
348
+ ## [9.20.0](https://github.com/event4u-app/agent-config/compare/9.19.0...9.20.0) (2026-08-04)
349
+
350
+ ### Release highlights
351
+
352
+ <!-- Curated head: fill before merge, keep it under 10 lines, and leave `_none_` where it is genuinely the answer. The generated log below is unchanged. -->
353
+ - **Behaviour changes:** _none_
354
+ - **Default changes + migration:** _auto-derived, rewrite before merge:_ commits naming a default, migration or migrate in 14dc053, bb362a0.
355
+ - **Security and correctness:** _none_
356
+ - **Honest nulls:** _auto-derived, rewrite before merge:_ commits carrying an honest-null marker in ba77e6a.
357
+ - **Known limitations:** _none_
358
+
359
+ ### Features
360
+
361
+ * **gates:** read the archived round records nothing was reading ([89eea71](https://github.com/event4u-app/agent-config/commit/89eea712b89048a032dfccf8a3bdd41f565adacc))
362
+
363
+ ### Bug Fixes
364
+
365
+ * **gates:** stop the remediation text pointing at the closed hole ([2dc9e0d](https://github.com/event4u-app/agent-config/commit/2dc9e0d91262864237e50268d8ea54dcce761a62))
366
+ * **gates:** rows are live wherever they appear — close the fence fail-open ([ba77e6a](https://github.com/event4u-app/agent-config/commit/ba77e6a6f4cc5c31b9de4741ee30ccc41e126df7))
367
+
368
+ ### Documentation
369
+
370
+ * **evidence:** close the blind-pass dispositions and correct a claim I made ([0398238](https://github.com/event4u-app/agent-config/commit/0398238d99f7451712e710204c86ab41f964de50))
371
+ * **contracts:** 2.7 is enforced now, and says what it still does not check ([d0b3650](https://github.com/event4u-app/agent-config/commit/d0b365035dc314183dcb0e353a09e3e2c5420284))
372
+ * **roadmap:** pin-then-migrate ordering; drop the index for a round-record check ([bb362a0](https://github.com/event4u-app/agent-config/commit/bb362a0b64a5e16a156d238c1acadded44f229aa))
373
+ * **roadmap:** record the council verdict on the fence grammar ([3e0deff](https://github.com/event4u-app/agent-config/commit/3e0deff6256050aa23fe952707ab88bf7bc9647e))
374
+ * **review:** give the blind-pass findings terminal statuses and a carrier ([667b81e](https://github.com/event4u-app/agent-config/commit/667b81e9fa44d892095a7b057a6407196aa429bf))
375
+
376
+ ### Tests
377
+
378
+ * **gates:** pin every fence arrangement before the grammar migration ([14dc053](https://github.com/event4u-app/agent-config/commit/14dc053d51ac1e932ce4deeb50ffb2e07737bd84))
379
+
380
+ ### CI
381
+
382
+ * **gates:** wire check_review_dispositions with a trippable floor ([9b03190](https://github.com/event4u-app/agent-config/commit/9b0319032494345fdcaad40ae79dbe3ea95f6fc8))
383
+
384
+ Tests: 10995 (+23 since 9.19.0)
385
+
297
386
  ## [9.19.0](https://github.com/event4u-app/agent-config/compare/9.18.1...9.19.0) (2026-08-04)
298
387
 
299
388
  ### Release highlights
@@ -39,7 +39,7 @@ schema_version: 1
39
39
  # CI guard: a release bump of `package.json` must update this value
40
40
  # in lockstep — see scripts/check_template_pin_drift.ts (road-to-
41
41
  # portable-runtime-and-update-check P3.3).
42
- agent_config_version: "9.19.0"
42
+ agent_config_version: "9.21.0"
43
43
 
44
44
  # --- Project identity ---
45
45
  project:
@@ -457,6 +457,29 @@ function _pyJsonScalarAscii(value) {
457
457
  return _pyJsonScalar(value);
458
458
  }
459
459
 
460
+ // src/scripts/_lib/scan_scope.ts
461
+ var DeadScopeError = class extends Error {
462
+ gate;
463
+ constructor(gate, message) {
464
+ super(message);
465
+ this.name = "DeadScopeError";
466
+ this.gate = gate;
467
+ }
468
+ };
469
+ function assertScanned(opts) {
470
+ if (opts.scanned > 0) {
471
+ return;
472
+ }
473
+ if (opts.allowEmpty !== void 0 && opts.allowEmpty.trim() !== "") {
474
+ return;
475
+ }
476
+ const roots = opts.roots.length > 0 ? opts.roots.join(", ") : "(no root declared)";
477
+ throw new DeadScopeError(
478
+ opts.gate,
479
+ `${opts.gate}: scanned 0 ${opts.units} under ${roots} \u2014 the scan scope is dead or the root moved. A gate that read nothing has not passed. Repoint the root (prefer the shared resolver in _lib/agent_src.ts), or declare a justified \`allowEmpty\` reason if an empty corpus is genuinely expected.`
480
+ );
481
+ }
482
+
460
483
  // src/scripts/lint_hidden_unicode.ts
461
484
  var CHECK = "hidden-unicode";
462
485
  var _BIDI = /* @__PURE__ */ new Set([
@@ -872,7 +895,9 @@ function main(argv = null) {
872
895
  const args = parse_args(argv ?? process.argv.slice(2));
873
896
  const findings = [];
874
897
  const flagged = /* @__PURE__ */ new Set();
898
+ let corpusFiles = 0;
875
899
  for (const sf of iter_corpus()) {
900
+ corpusFiles += 1;
876
901
  const hits = _scan(sf);
877
902
  for (const h of hits) {
878
903
  findings.push(h);
@@ -881,6 +906,21 @@ function main(argv = null) {
881
906
  flagged.add(sf.path);
882
907
  }
883
908
  }
909
+ try {
910
+ assertScanned({
911
+ gate: "lint_hidden_unicode",
912
+ scanned: corpusFiles,
913
+ units: "corpus file(s)",
914
+ roots: DEFAULT_SCAN_ROOTS
915
+ });
916
+ } catch (exc) {
917
+ if (exc instanceof DeadScopeError) {
918
+ process.stderr.write(`\u274C ${exc.message}
919
+ `);
920
+ return 1;
921
+ }
922
+ throw exc;
923
+ }
884
924
  const sourceFiles = _eligibleSourceFiles();
885
925
  for (const h of _scanSourceControlBytes(sourceFiles)) {
886
926
  findings.push(h);
@@ -6,7 +6,7 @@ import {
6
6
  readHookStdin,
7
7
  read_entries
8
8
  } from "./chunk-AIIUU73N.js";
9
- import "./chunk-XGA2NTU4.js";
9
+ import "./chunk-3EWYC3YK.js";
10
10
  import {
11
11
  _RAW_KEY_PREFIXES,
12
12
  hardenedSpawnEnv
@@ -2,7 +2,7 @@
2
2
  import { createRequire as __acCreateRequire } from 'node:module'; const require = globalThis.require ?? __acCreateRequire(import.meta.url);
3
3
  import {
4
4
  memory_get_v1
5
- } from "./chunk-XGA2NTU4.js";
5
+ } from "./chunk-3EWYC3YK.js";
6
6
  import "./chunk-OY53J6II.js";
7
7
  import "./chunk-J55WI3RR.js";
8
8
 
@@ -6,7 +6,7 @@ import {
6
6
  import {
7
7
  read_entries
8
8
  } from "./chunk-AIIUU73N.js";
9
- import "./chunk-XGA2NTU4.js";
9
+ import "./chunk-3EWYC3YK.js";
10
10
  import {
11
11
  load_agent_settings
12
12
  } from "./chunk-HJ6DAJHR.js";
@@ -1,6 +1,6 @@
1
1
  # Discovery — Deprecation Report
2
2
 
3
- - Generated: `2026-08-04T16:08:00Z`
3
+ - Generated: `2026-08-05T03:10:28Z`
4
4
  - Deprecated artefacts: **0**
5
5
 
6
6
  _None. Tree is clean._
@@ -14402,7 +14402,7 @@
14402
14402
  "reason": "scaffold template for ticket-bundle tickets (ADR-101); carries no runtime frontmatter — emit-tickets fills it in per ticket"
14403
14403
  }
14404
14404
  ],
14405
- "generated_at": "2026-08-04T16:08:00Z",
14405
+ "generated_at": "2026-08-05T03:10:28Z",
14406
14406
  "packs": [
14407
14407
  {
14408
14408
  "artefact_count": 117,
@@ -1 +1 @@
1
- 771e350a2329d84c1a47378ed09ebeed75e5ada993d722cfc079b3f5befec595 discovery-manifest.json
1
+ 4b795a51a6574b400b90053e476daf9aac787dd71aa03ca8be86ad3f2913ea3e discovery-manifest.json
@@ -1,6 +1,6 @@
1
1
  # Discovery Manifest — Summary
2
2
 
3
- - Generated: `2026-08-04T16:08:00Z`
3
+ - Generated: `2026-08-05T03:10:28Z`
4
4
  - Scanner: `c24312e116f8`
5
5
  - Artefacts: **594**
6
6
  - Unassigned: **0**
@@ -1,6 +1,6 @@
1
1
  # Discovery — Orphan Report
2
2
 
3
- - Generated: `2026-08-04T16:08:00Z`
3
+ - Generated: `2026-08-05T03:10:28Z`
4
4
  - Orphan artefacts: **0**
5
5
 
6
6
  > An orphan is an artefact whose declared pack has no other members.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "checksum": "sha256:d766f7f17140ce6b648e68821c9403c0bf478609a1ea925e85501c5994002a05",
3
- "generated_at": "2026-08-04T16:08:00Z",
3
+ "generated_at": "2026-08-05T03:10:28Z",
4
4
  "packs": [
5
5
  {
6
6
  "always_on": false,
@@ -1,6 +1,6 @@
1
1
  # Discovery — Trust Report
2
2
 
3
- - Generated: `2026-08-04T16:08:00Z`
3
+ - Generated: `2026-08-05T03:10:28Z`
4
4
  - Workspaces tracked: **10**
5
5
  - Human-review-required artefacts: **3**
6
6
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "checksum": "sha256:d766f7f17140ce6b648e68821c9403c0bf478609a1ea925e85501c5994002a05",
3
- "generated_at": "2026-08-04T16:08:00Z",
3
+ "generated_at": "2026-08-05T03:10:28Z",
4
4
  "scanner_version": "c24312e116f8",
5
5
  "workspaces": [
6
6
  {
@@ -8170,6 +8170,29 @@ function _pyJsonScalarAscii(value) {
8170
8170
  return _pyJsonScalar(value);
8171
8171
  }
8172
8172
 
8173
+ // src/scripts/_lib/scan_scope.ts
8174
+ var DeadScopeError = class extends Error {
8175
+ gate;
8176
+ constructor(gate, message) {
8177
+ super(message);
8178
+ this.name = "DeadScopeError";
8179
+ this.gate = gate;
8180
+ }
8181
+ };
8182
+ function assertScanned(opts) {
8183
+ if (opts.scanned > 0) {
8184
+ return;
8185
+ }
8186
+ if (opts.allowEmpty !== void 0 && opts.allowEmpty.trim() !== "") {
8187
+ return;
8188
+ }
8189
+ const roots = opts.roots.length > 0 ? opts.roots.join(", ") : "(no root declared)";
8190
+ throw new DeadScopeError(
8191
+ opts.gate,
8192
+ `${opts.gate}: scanned 0 ${opts.units} under ${roots} \u2014 the scan scope is dead or the root moved. A gate that read nothing has not passed. Repoint the root (prefer the shared resolver in _lib/agent_src.ts), or declare a justified \`allowEmpty\` reason if an empty corpus is genuinely expected.`
8193
+ );
8194
+ }
8195
+
8173
8196
  // src/scripts/lint_hidden_unicode.ts
8174
8197
  var CHECK = "hidden-unicode";
8175
8198
  var _BIDI = /* @__PURE__ */ new Set([
@@ -8585,7 +8608,9 @@ function main(argv = null) {
8585
8608
  const args = parse_args(argv ?? process.argv.slice(2));
8586
8609
  const findings = [];
8587
8610
  const flagged = /* @__PURE__ */ new Set();
8611
+ let corpusFiles = 0;
8588
8612
  for (const sf of iter_corpus()) {
8613
+ corpusFiles += 1;
8589
8614
  const hits = _scan(sf);
8590
8615
  for (const h of hits) {
8591
8616
  findings.push(h);
@@ -8594,6 +8619,21 @@ function main(argv = null) {
8594
8619
  flagged.add(sf.path);
8595
8620
  }
8596
8621
  }
8622
+ try {
8623
+ assertScanned({
8624
+ gate: "lint_hidden_unicode",
8625
+ scanned: corpusFiles,
8626
+ units: "corpus file(s)",
8627
+ roots: DEFAULT_SCAN_ROOTS
8628
+ });
8629
+ } catch (exc) {
8630
+ if (exc instanceof DeadScopeError) {
8631
+ process.stderr.write(`\u274C ${exc.message}
8632
+ `);
8633
+ return 1;
8634
+ }
8635
+ throw exc;
8636
+ }
8597
8637
  const sourceFiles = _eligibleSourceFiles();
8598
8638
  for (const h of _scanSourceControlBytes(sourceFiles)) {
8599
8639
  findings.push(h);
@@ -14983,7 +15023,7 @@ if (isCliEntry3) {
14983
15023
  process.exit(main11(process.argv.slice(2)));
14984
15024
  }
14985
15025
 
14986
- // src/scripts/verify_before_complete_hook.ts
15026
+ // src/scripts/before_complete_hook.ts
14987
15027
  import fs19 from "node:fs";
14988
15028
  import path18 from "node:path";
14989
15029
  import { fileURLToPath as fileURLToPath13, pathToFileURL as pathToFileURL9 } from "node:url";
@@ -19005,6 +19045,22 @@ function main27() {
19005
19045
  for (const f of walkDir(scanDir, /\.(html|htm|css|scss|sass|less|vue|svelte|astro|jsx|tsx|md|mdx)$/i)) {
19006
19046
  if (!ignoreGlobs.some((g) => f.includes(g.replace("**", "")))) files.push(f);
19007
19047
  }
19048
+ try {
19049
+ assertScanned({
19050
+ gate: "lint_design_slop",
19051
+ scanned: files.length,
19052
+ units: "design source file(s)",
19053
+ // Absolute: --dir may point outside the cwd (or outside any repo).
19054
+ roots: [scanDir]
19055
+ });
19056
+ } catch (exc) {
19057
+ if (exc instanceof DeadScopeError) {
19058
+ process.stderr.write(`\u274C ${exc.message}
19059
+ `);
19060
+ process.exit(1);
19061
+ }
19062
+ throw exc;
19063
+ }
19008
19064
  const findings = [];
19009
19065
  for (const fp of files) {
19010
19066
  const rel = path37.relative(process.cwd(), fp);
@@ -19461,7 +19517,7 @@ var CONCERN_REGISTRY = {
19461
19517
  "src/scripts/roadmap_progress_hook.ts": main9,
19462
19518
  "src/scripts/onboarding_gate_hook.ts": main10,
19463
19519
  "src/scripts/context_hygiene_hook.ts": main11,
19464
- "src/scripts/verify_before_complete_hook.ts": main12,
19520
+ "src/scripts/before_complete_hook.ts": main12,
19465
19521
  "src/scripts/minimal_safe_diff_hook.ts": main13,
19466
19522
  "src/scripts/injection_scan_hook.ts": main14,
19467
19523
  "src/scripts/memory_learn_hook.ts": main15,
@@ -3,13 +3,13 @@
3
3
  "artefact_count": 594,
4
4
  "scanner_version": "c24312e116f8"
5
5
  },
6
- "generated_at": "2026-08-04",
6
+ "generated_at": "2026-08-05",
7
7
  "package": {
8
8
  "description": "Governed skills, rules and commands for AI coding tools (Claude Code, Cursor, Windsurf, Copilot) \u2014 every claim machine-checked, including \"zero runtime daemon\".",
9
9
  "homepage": "https://event4u-app.github.io/agent-config",
10
10
  "name": "@event4u/agent-config",
11
11
  "repository": "https://github.com/event4u-app/agent-config",
12
- "version": "9.19.0"
12
+ "version": "9.21.0"
13
13
  },
14
14
  "registries": [
15
15
  {
@@ -9,12 +9,12 @@
9
9
  "transport": {
10
10
  "type": "stdio"
11
11
  },
12
- "version": "9.19.0"
12
+ "version": "9.21.0"
13
13
  }
14
14
  ],
15
15
  "repository": {
16
16
  "source": "github",
17
17
  "url": "https://github.com/event4u-app/agent-config"
18
18
  },
19
- "version": "9.19.0"
19
+ "version": "9.21.0"
20
20
  }
@@ -9362,6 +9362,35 @@ var init_security_lint = __esm({
9362
9362
  }
9363
9363
  });
9364
9364
 
9365
+ // src/scripts/_lib/scan_scope.ts
9366
+ function assertScanned(opts) {
9367
+ if (opts.scanned > 0) {
9368
+ return;
9369
+ }
9370
+ if (opts.allowEmpty !== void 0 && opts.allowEmpty.trim() !== "") {
9371
+ return;
9372
+ }
9373
+ const roots = opts.roots.length > 0 ? opts.roots.join(", ") : "(no root declared)";
9374
+ throw new DeadScopeError(
9375
+ opts.gate,
9376
+ `${opts.gate}: scanned 0 ${opts.units} under ${roots} \u2014 the scan scope is dead or the root moved. A gate that read nothing has not passed. Repoint the root (prefer the shared resolver in _lib/agent_src.ts), or declare a justified \`allowEmpty\` reason if an empty corpus is genuinely expected.`
9377
+ );
9378
+ }
9379
+ var DeadScopeError;
9380
+ var init_scan_scope = __esm({
9381
+ "src/scripts/_lib/scan_scope.ts"() {
9382
+ "use strict";
9383
+ DeadScopeError = class extends Error {
9384
+ gate;
9385
+ constructor(gate, message) {
9386
+ super(message);
9387
+ this.name = "DeadScopeError";
9388
+ this.gate = gate;
9389
+ }
9390
+ };
9391
+ }
9392
+ });
9393
+
9365
9394
  // src/scripts/lint_hidden_unicode.ts
9366
9395
  import * as fs7 from "node:fs";
9367
9396
  import * as path7 from "node:path";
@@ -9549,7 +9578,9 @@ function main(argv = null) {
9549
9578
  const args = parse_args(argv ?? process.argv.slice(2));
9550
9579
  const findings = [];
9551
9580
  const flagged = /* @__PURE__ */ new Set();
9581
+ let corpusFiles = 0;
9552
9582
  for (const sf of iter_corpus()) {
9583
+ corpusFiles += 1;
9553
9584
  const hits = _scan(sf);
9554
9585
  for (const h of hits) {
9555
9586
  findings.push(h);
@@ -9558,6 +9589,21 @@ function main(argv = null) {
9558
9589
  flagged.add(sf.path);
9559
9590
  }
9560
9591
  }
9592
+ try {
9593
+ assertScanned({
9594
+ gate: "lint_hidden_unicode",
9595
+ scanned: corpusFiles,
9596
+ units: "corpus file(s)",
9597
+ roots: DEFAULT_SCAN_ROOTS
9598
+ });
9599
+ } catch (exc) {
9600
+ if (exc instanceof DeadScopeError) {
9601
+ process.stderr.write(`\u274C ${exc.message}
9602
+ `);
9603
+ return 1;
9604
+ }
9605
+ throw exc;
9606
+ }
9561
9607
  const sourceFiles = _eligibleSourceFiles();
9562
9608
  for (const h of _scanSourceControlBytes(sourceFiles)) {
9563
9609
  findings.push(h);
@@ -9608,6 +9654,7 @@ var init_lint_hidden_unicode = __esm({
9608
9654
  "src/scripts/lint_hidden_unicode.ts"() {
9609
9655
  "use strict";
9610
9656
  init_security_lint();
9657
+ init_scan_scope();
9611
9658
  CHECK = "hidden-unicode";
9612
9659
  _BIDI = /* @__PURE__ */ new Set([
9613
9660
  8234,
@@ -14000,35 +14047,6 @@ var init_release_scope = __esm({
14000
14047
  }
14001
14048
  });
14002
14049
 
14003
- // src/scripts/_lib/scan_scope.ts
14004
- function assertScanned(opts) {
14005
- if (opts.scanned > 0) {
14006
- return;
14007
- }
14008
- if (opts.allowEmpty !== void 0 && opts.allowEmpty.trim() !== "") {
14009
- return;
14010
- }
14011
- const roots = opts.roots.length > 0 ? opts.roots.join(", ") : "(no root declared)";
14012
- throw new DeadScopeError(
14013
- opts.gate,
14014
- `${opts.gate}: scanned 0 ${opts.units} under ${roots} \u2014 the scan scope is dead or the root moved. A gate that read nothing has not passed. Repoint the root (prefer the shared resolver in _lib/agent_src.ts), or declare a justified \`allowEmpty\` reason if an empty corpus is genuinely expected.`
14015
- );
14016
- }
14017
- var DeadScopeError;
14018
- var init_scan_scope = __esm({
14019
- "src/scripts/_lib/scan_scope.ts"() {
14020
- "use strict";
14021
- DeadScopeError = class extends Error {
14022
- gate;
14023
- constructor(gate, message) {
14024
- super(message);
14025
- this.name = "DeadScopeError";
14026
- this.gate = gate;
14027
- }
14028
- };
14029
- }
14030
- });
14031
-
14032
14050
  // src/scripts/skill_linter.ts
14033
14051
  var skill_linter_exports = {};
14034
14052
  __export(skill_linter_exports, {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@event4u/agent-config",
3
3
  "mcpName": "io.github.event4u-app/agent-config",
4
- "version": "9.19.0",
4
+ "version": "9.21.0",
5
5
  "description": "Governed skills, rules and commands for AI coding tools (Claude Code, Cursor, Windsurf, Copilot) — every claim machine-checked, including \"zero runtime daemon\".",
6
6
  "license": "MIT",
7
7
  "private": false,
@@ -72,10 +72,15 @@
72
72
  #
73
73
  # What remains is NOT one line per gate. For the ~201 the count would have to be
74
74
  # INVENTED (what is this gate's unit?) rather than published, and that judgement
75
- # is per-gate. It is tracked as a vulnerability ratchet — `gate-hardening:
76
- # unhardened-scan-scope` in src/config/gate-violation-baselines.json, which fails
77
- # on a RISE and targets 0 — and charter-owned by
78
- # `agents/roadmaps/road-to-gate-hardening-adoption.md`.
75
+ # is per-gate. It was tracked as a vulnerability ratchet — `gate-hardening:
76
+ # unhardened-scan-scope` in src/config/gate-violation-baselines.json, which
77
+ # failed on a RISE and targeted 0 — under the road-to-gate-hardening-adoption
78
+ # charter. That charter closed 2026-08-05: the count reached 0 and the baseline
79
+ # entry was DELETED rather than zeroed, so `checkRatchet` now returns
80
+ # `unbaselined` with `ok = (actual === 0)`. Zero is mandatory, not a floor — any
81
+ # new gate written without a scope assertion reds immediately, and
82
+ # `tests/scripts/check_gate_coverage.test.ts` pins both the empty population and
83
+ # the entry's continued absence.
79
84
  #
80
85
  # `tests/scripts/check_gate_coverage.test.ts` fails the build the moment a gate
81
86
  # starts emitting the line without being registered here, so the list cannot
@@ -365,6 +370,22 @@ gates:
365
370
  stays registered so the guard reports this gate rather than skipping it
366
371
  silently.
367
372
 
373
+ - id: check_review_dispositions
374
+ argv: []
375
+ min_scanned: 7
376
+ corpus: "archived round records — `*-review.md` under agents/evidence/reviews/, excluding live `*.findings.md` (9 at baseline)"
377
+ status: enforced
378
+ note: >
379
+ Contract § 2.7. Unlike the R2 entry above, this floor is genuinely
380
+ trippable: the corpus is 9 frozen records and archived records are not
381
+ deleted, so a drop to 7 means the reviews root moved or the naming
382
+ convention drifted — not that the work went clean. That is precisely the
383
+ case rule 3 exists for. The gate reads the FROZEN records because R2
384
+ selects only artefacts in the CURRENT review scope, so a superseded round
385
+ renamed out of the `*.findings.md` glob is read by nothing at all — two
386
+ findings sat recorded as `open` in this repo's own corpus for a day
387
+ through exactly that gap.
388
+
368
389
  # ---------------------------------------------------------------------------
369
390
  # The five below close the gap this header named: they already called
370
391
  # `_lib/scan_scope.assertScanned` with a real count and only had to PRINT it.
@@ -425,3 +446,16 @@ gates:
425
446
  note: >
426
447
  Emits on stderr, not stdout: `--format json` owns this gate's stdout and a
427
448
  count written there would corrupt the payload. The guard reads both streams.
449
+
450
+ - id: check_cli_registry_budget_sync
451
+ argv: []
452
+ min_scanned: 3
453
+ corpus: "the three named inputs it cross-checks — src/cli/registry.ts, src/config/evaluator-budgets.json, internal/bench/reports/evaluator-measurements.json"
454
+ status: enforced
455
+ note: >
456
+ Registered because its count became REAL, not to pad the manifest. The
457
+ gate always printed a hardcoded `scanned: 3`; hardening derived it from
458
+ the watch list that actually resolved, which is what makes a floor of 3
459
+ meaningful — it now falls when one of the three inputs is renamed away.
460
+ `argv: []` is the CI-identical invocation: both `taskfiles/ci-fast.yml`
461
+ and `.github/workflows/tests.yml` call it bare.
@@ -1,15 +1,10 @@
1
1
  {
2
2
  "$comment": "Violation ratchet for gates whose dead scan root was repaired. A repair REVEALS pre-existing debt; it does not create it. Each entry records the count revealed at repair time — the gate fails only when its count RISES. Lowering a count is a normal commit; raising one is a defect. Entries expire: a baseline that has not dropped within 56 days of `landed` (or of `reaffirmed.date`) fails its gate, because a number that never moves is suppression with extra steps. Mechanism + rationale: src/scripts/_lib/gate_baseline.ts. Decision: AI council 2026-08-02, roadmap road-to-gates-that-can-fail blocker `dead-gate-finding-triage`.",
3
3
  "gates": {
4
- "gate-hardening:unhardened-scan-scope": {
5
- "count": 189,
6
- "landed": "2026-08-04",
7
- "note": "Gate scripts under src/scripts (population 223, the lint_/check_/audit_ prefix set) that neither route through _lib/scan_scope nor emit the machine-readable 'scanned:' line — the gates that can still report success over a moved or empty root without saying so. This is a VULNERABILITY count, not a coverage percentage: it measures how much of the original defect class is still reachable, it RISES whenever a new gate is written without a scope assertion, and its target is 0. That direction is the whole point — an adoption-reach metric ('hardened gates must increase') can never regress and would be threshold-lowering wearing a ratchet's clothes (AI council 2026-08-04, anthropic/claude-sonnet-4-5 + openai/gpt-4o, convergent on scope decomposition plus this discriminator). Clearing it is the charter of road-to-gate-hardening-adoption; the 56-day non-stagnation clause applies unchanged, so a number that never drops fails this gate rather than hardening into configuration. NEW ENTRY, not a raised threshold: this records newly-measured pre-existing exposure at first measurement — nothing was loosened."
8
- },
9
4
  "check_no_new_legacy_path:hardcoded-scan-roots": {
10
- "count": 51,
11
- "landed": "2026-08-02",
12
- "note": "Lines under src/scripts/**/*.{ts,mts,mjs} that pass the retired `.agent-src.uncondensed` directory into `path.join(...)` — a filesystem path CONSTRUCTED against the tree ADR-051 abandoned, which is the exact shape of all 14 dead gates. Deliberately narrow so the number is signal, not noise: 236 raw mentions under src/scripts → 147 string-literal lines → 67 path-constructing lines when the pass was written, after exempting src/scripts/_lib/agent_src.ts (the shared resolver, whose job IS owning the constant — gates that route through it survived the move). Detectors holding the literal as data to match, strip, or print are not counted, and no prose, docs, tests or fixtures are read: that full-tree shape was measured at 44 files / 213 hits and rejected as the wrong lint (see the note in check_no_new_legacy_path.ts::find_offenders). Recorded at 58 rather than 67 because Phase 1's scan-root repairs were landing on this branch while the pass was being written and had already removed 9 — a baseline above the truth silently permits new violations. This count goes to ZERO as the remaining repairs land; every repair is a lowering commit. Lowered 56→51 by the road-to-renewal-foundation Phase 1 dead-root sweep (check_always_budget, check_portability, check_references, lint_framework_leakage, lint_agents_md)."
5
+ "count": 49,
6
+ "landed": "2026-08-04",
7
+ "note": "Lines under src/scripts/**/*.{ts,mts,mjs} that pass the retired `.agent-src.uncondensed` directory into `path.join(...)` — a filesystem path CONSTRUCTED against the tree ADR-051 abandoned, which is the exact shape of all 14 dead gates. Deliberately narrow so the number is signal, not noise: 236 raw mentions under src/scripts → 147 string-literal lines → 67 path-constructing lines when the pass was written, after exempting src/scripts/_lib/agent_src.ts (the shared resolver, whose job IS owning the constant — gates that route through it survived the move). Detectors holding the literal as data to match, strip, or print are not counted, and no prose, docs, tests or fixtures are read: that full-tree shape was measured at 44 files / 213 hits and rejected as the wrong lint (see the note in check_no_new_legacy_path.ts::find_offenders). Recorded at 58 rather than 67 because Phase 1's scan-root repairs were landing on this branch while the pass was being written and had already removed 9 — a baseline above the truth silently permits new violations. This count goes to ZERO as the remaining repairs land; every repair is a lowering commit. Lowered 56→51 by the road-to-renewal-foundation Phase 1 dead-root sweep (check_always_budget, check_portability, check_references, lint_framework_leakage, lint_agents_md). Lowered 51→49 by the gate-hardening adoption PR: skill_collision_clusters and skill_overlap were repointed at the live skills tree via the shared resolver — two gates that had been reading the retired container and scoring 0 of 288 skills."
13
8
  },
14
9
  "audit_user_type_axis": {
15
10
  "count": 1,