@event4u/agent-config 14.12.0 → 14.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (521) hide show
  1. package/.augment-plugin/marketplace.json +3 -3
  2. package/.augment-plugin/plugin.json +1 -1
  3. package/.claude-plugin/marketplace.json +1 -1
  4. package/CHANGELOG.md +118 -155
  5. package/CONTRIBUTING.md +38 -0
  6. package/CREDITS.md +135 -0
  7. package/NOTICE +13 -0
  8. package/README.md +8 -6
  9. package/dist/agent-src/commands/analyze/inbox.md +145 -2
  10. package/dist/agent-src/commands/feature/dev.md +7 -2
  11. package/dist/agent-src/commands/ghostwriter/write.md +5 -1
  12. package/dist/agent-src/commands/implement-ticket.md +1 -1
  13. package/dist/agent-src/commands/mission/upgrade.md +1 -1
  14. package/dist/agent-src/commands/orchestrate.md +2 -2
  15. package/dist/agent-src/commands/post-as/me.md +5 -1
  16. package/dist/agent-src/commands/pr/merge.md +19 -6
  17. package/dist/agent-src/commands/roadmap/process-full.md +19 -5
  18. package/dist/agent-src/commands/tdd/red.md +12 -2
  19. package/dist/agent-src/commands/work.md +1 -1
  20. package/dist/agent-src/contexts/communication/rules-auto/token-efficiency-mechanics.md +40 -0
  21. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +5 -2
  22. package/dist/agent-src/contexts/execution/autonomy-mechanics.md +21 -0
  23. package/dist/agent-src/contexts/execution/orchestration-telemetry.md +1 -0
  24. package/dist/agent-src/contexts/execution/subagent-response-contract.md +40 -0
  25. package/dist/agent-src/contexts/execution/subagent-steering.md +13 -1
  26. package/dist/agent-src/contexts/execution/terminal-states.md +96 -0
  27. package/dist/agent-src/rules/artifact-drafting-protocol.md +1 -1
  28. package/dist/agent-src/rules/broken-access-control.md +4 -0
  29. package/dist/agent-src/rules/code-comment-discipline.md +6 -0
  30. package/dist/agent-src/rules/code-provenance.md +4 -0
  31. package/dist/agent-src/rules/design-fidelity.md +1 -1
  32. package/dist/agent-src/rules/domain-safety-pii.md +4 -0
  33. package/dist/agent-src/rules/domain-safety-retention.md +4 -0
  34. package/dist/agent-src/rules/engineering-safety-floor.md +2 -0
  35. package/dist/agent-src/rules/external-code-graph-interop.md +14 -12
  36. package/dist/agent-src/rules/improve-before-implement.md +6 -8
  37. package/dist/agent-src/rules/laravel-routing.md +1 -1
  38. package/dist/agent-src/rules/lethal-trifecta-guard.md +4 -0
  39. package/dist/agent-src/rules/secret-vcs-guard.md +2 -0
  40. package/dist/agent-src/rules/security-sensitive-stop.md +2 -0
  41. package/dist/agent-src/rules/source-confidentiality.md +12 -34
  42. package/dist/agent-src/rules/symfony-routing.md +1 -1
  43. package/dist/agent-src/rules/token-efficiency.md +14 -0
  44. package/dist/agent-src/rules/tool-safety.md +4 -0
  45. package/dist/agent-src/rules/untrusted-input-defense.md +4 -0
  46. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +252 -8
  47. package/dist/agent-src/scripts/guarded_baseline.ts +343 -0
  48. package/dist/agent-src/scripts/roadmap_set_step.ts +253 -0
  49. package/dist/agent-src/scripts/stub_queue.ts +82 -0
  50. package/dist/agent-src/scripts/stubs_due.ts +516 -0
  51. package/dist/agent-src/scripts/ticket_bundles.ts +84 -0
  52. package/dist/agent-src/scripts/update_roadmap_progress.ts +16 -12
  53. package/dist/agent-src/skills/brand-asset-generation/SKILL.md +17 -4
  54. package/dist/agent-src/skills/brand-audit/SKILL.md +33 -0
  55. package/dist/agent-src/skills/code-intelligence/SKILL.md +57 -0
  56. package/dist/agent-src/skills/database/SKILL.md +8 -0
  57. package/dist/agent-src/skills/dependency-upgrade/SKILL.md +27 -0
  58. package/dist/agent-src/skills/design-review/SKILL.md +1 -1
  59. package/dist/agent-src/skills/doc-coauthoring/SKILL.md +1 -1
  60. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +17 -1
  61. package/dist/agent-src/skills/feature-planning/SKILL.md +9 -2
  62. package/dist/agent-src/skills/frontend-render-security/SKILL.md +44 -0
  63. package/dist/agent-src/skills/git-workflow/SKILL.md +1 -1
  64. package/dist/agent-src/skills/js-library-packaging/scripts/check_package_surface.ts +38 -4
  65. package/dist/agent-src/skills/judge-artifact-completeness/rubrics/ticket-quality-score.json +2 -2
  66. package/dist/agent-src/skills/laravel/SKILL.md +35 -0
  67. package/dist/agent-src/skills/laravel-migration/SKILL.md +57 -3
  68. package/dist/agent-src/skills/monorepo-workspace/SKILL.md +26 -0
  69. package/dist/agent-src/skills/playbook-authoring/SKILL.md +28 -1
  70. package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +1 -1
  71. package/dist/agent-src/skills/skill-writing/references/procedure.md +5 -5
  72. package/dist/agent-src/skills/sql-writing/SKILL.md +7 -1
  73. package/dist/agent-src/skills/standards-from-config/SKILL.md +27 -4
  74. package/dist/agent-src/skills/supply-chain-intake/SKILL.md +11 -4
  75. package/dist/agent-src/skills/symfony-workflow/SKILL.md +35 -0
  76. package/dist/agent-src/skills/test-case-discovery/SKILL.md +85 -0
  77. package/dist/agent-src/skills/test-driven-development/SKILL.md +33 -9
  78. package/dist/agent-src/skills/testing-anti-patterns/SKILL.md +1 -1
  79. package/dist/agent-src/skills/testing-anti-patterns/process-anti-patterns.md +37 -0
  80. package/dist/agent-src/skills/ui-component-architect/SKILL.md +45 -2
  81. package/dist/agent-src/skills/upstream-contribute/SKILL.md +38 -1
  82. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +9 -4
  83. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  84. package/dist/agent-src/templates/roadmaps.md +97 -3
  85. package/dist/agent-src/templates/scripts/check_memory.ts +258 -17
  86. package/dist/agent-src/templates/scripts/check_memory_proposal.ts +9 -3
  87. package/dist/agent-src/templates/scripts/memory_lookup.ts +86 -0
  88. package/dist/agent-src/templates/scripts/memory_signal.ts +44 -0
  89. package/dist/agent-src/templates/scripts/work_engine/directives/backend/implement.ts +90 -0
  90. package/dist/agent-src/templates/scripts/work_engine/directives/backend/index.ts +11 -0
  91. package/dist/agent-src/templates/scripts/work_engine/directives/backend/test.ts +23 -1
  92. package/dist/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +10 -1
  93. package/dist/agent-src/templates/scripts/work_engine/directives/mixed/stitch.ts +5 -1
  94. package/dist/agent-src/templates/scripts/work_engine/stack/runner.ts +102 -14
  95. package/dist/cli/commands/uiAudit.js +124 -5
  96. package/dist/cli/registry.js +2 -0
  97. package/dist/cli-delegate/{chunk-HYWSRNUX.js → chunk-2DK2VJWG.js} +3 -3
  98. package/dist/cli-delegate/{chunk-JCW7ZLHK.js → chunk-4FS4WRXP.js} +5 -0
  99. package/dist/cli-delegate/{chunk-OMIVVCG2.js → chunk-A4QJ6ENT.js} +24 -0
  100. package/dist/cli-delegate/{chunk-JJA2QEWA.js → chunk-AKJGUQNO.js} +466 -285
  101. package/dist/cli-delegate/{chunk-E46KPN6K.js → chunk-BTWUYDGN.js} +424 -363
  102. package/dist/cli-delegate/{chunk-K4FFODTS.js → chunk-ILMUPLGW.js} +1227 -316
  103. package/dist/cli-delegate/{chunk-FF7WAFMR.js → chunk-KPBWFOPZ.js} +5 -1
  104. package/dist/cli-delegate/cmd_adr_effective.js +102 -0
  105. package/dist/cli-delegate/cmd_conformance.js +80 -11
  106. package/dist/cli-delegate/cmd_doctor.js +3 -3
  107. package/dist/cli-delegate/cmd_export.js +3 -2
  108. package/dist/cli-delegate/cmd_fleet.js +2 -2
  109. package/dist/cli-delegate/cmd_handoff.js +1 -1
  110. package/dist/cli-delegate/cmd_preflight.js +2 -2
  111. package/dist/cli-delegate/cmd_prune.js +3 -2
  112. package/dist/cli-delegate/cmd_settings_get.js +1 -1
  113. package/dist/cli-delegate/cmd_settings_migrate.js +3 -2
  114. package/dist/cli-delegate/cmd_settings_set.js +2 -2
  115. package/dist/cli-delegate/cmd_sync.js +3 -2
  116. package/dist/cli-delegate/cmd_uninstall.js +3 -2
  117. package/dist/cli-delegate/cmd_validate.js +3 -2
  118. package/dist/discovery/deprecation-report.md +1 -1
  119. package/dist/discovery/discovery-manifest.json +58 -58
  120. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  121. package/dist/discovery/discovery-manifest.summary.md +1 -1
  122. package/dist/discovery/dormancy-report.md +1 -1
  123. package/dist/discovery/orphan-report.md +1 -1
  124. package/dist/discovery/packs.json +2 -2
  125. package/dist/discovery/trust-report.md +1 -1
  126. package/dist/discovery/workspaces.json +2 -2
  127. package/dist/hooks/dispatch.js +2900 -1049
  128. package/dist/install/claudeRuleRewrite.js +254 -0
  129. package/dist/install/detect.js +29 -16
  130. package/dist/install/detect_php_shape.js +159 -0
  131. package/dist/install/install.mjs +634 -428
  132. package/dist/mcp/awesome-mcp-servers.row.md +1 -1
  133. package/dist/mcp/mcp-cloudflare-catalogue.json +1 -1
  134. package/dist/mcp/registry-manifest.json +3 -3
  135. package/dist/mcp/server.json +3 -3
  136. package/dist/mcp/server.mjs +4895 -2627
  137. package/dist/server/schemas/settings.js +3 -0
  138. package/dist/ui/assets/index-D0jaCRPM.js +29 -0
  139. package/dist/ui/index.html +1 -1
  140. package/docs/MIGRATION.md +1 -1
  141. package/docs/THIRD-PARTY-NOTICES.md +25 -0
  142. package/docs/contracts/provider-lifecycle.md +1 -1
  143. package/docs/contracts/settings-classes.md +10 -4
  144. package/docs/guidelines/agent-infra/5w2h-analysis.md +3 -3
  145. package/docs/guidelines/agent-infra/agent-interaction-and-decision-quality.md +1 -0
  146. package/docs/guidelines/agent-infra/artifact-drafting-protocol-mechanics.md +58 -3
  147. package/docs/guidelines/agent-infra/ask-when-uncertain-demos.md +2 -2
  148. package/docs/guidelines/agent-infra/asking-and-brevity-examples.md +3 -3
  149. package/docs/guidelines/agent-infra/break-glass-usage.md +7 -7
  150. package/docs/guidelines/agent-infra/carve-out-predicates.md +3 -3
  151. package/docs/guidelines/agent-infra/comparison-matrix.md +1 -1
  152. package/docs/guidelines/agent-infra/critical-thinking.md +4 -4
  153. package/docs/guidelines/agent-infra/direct-answers-demos.md +2 -2
  154. package/docs/guidelines/agent-infra/domain-eval-anti-pattern.md +1 -1
  155. package/docs/guidelines/agent-infra/engineering-memory-data-format.md +3 -3
  156. package/docs/guidelines/agent-infra/existence-question-verdicts.md +80 -0
  157. package/docs/guidelines/agent-infra/first-principles.md +2 -2
  158. package/docs/guidelines/agent-infra/framework-neutrality-patterns.md +2 -2
  159. package/docs/guidelines/agent-infra/guarded-baseline.md +39 -0
  160. package/docs/guidelines/agent-infra/inversion-thinking.md +5 -5
  161. package/docs/guidelines/agent-infra/language-and-tone-examples.md +1 -1
  162. package/docs/guidelines/agent-infra/layered-settings.md +10 -10
  163. package/docs/guidelines/agent-infra/memory-access.md +1 -1
  164. package/docs/guidelines/agent-infra/mental-models.md +3 -3
  165. package/docs/guidelines/agent-infra/reuse-verdict-mechanics.md +71 -0
  166. package/docs/guidelines/agent-infra/review-routing-data-format.md +7 -7
  167. package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +13 -7
  168. package/docs/guidelines/agent-infra/role-contracts.md +2 -2
  169. package/docs/guidelines/agent-infra/role-mode-router.md +3 -3
  170. package/docs/guidelines/agent-infra/rule-type-governance.md +2 -2
  171. package/docs/guidelines/agent-infra/scqa-framework.md +5 -5
  172. package/docs/guidelines/agent-infra/self-improvement-pipeline.md +6 -6
  173. package/docs/guidelines/agent-infra/simplicity-and-goal-demos.md +2 -2
  174. package/docs/guidelines/agent-infra/six-hats.md +3 -3
  175. package/docs/guidelines/agent-infra/skill-quality-checklist.md +6 -6
  176. package/docs/guidelines/agent-infra/source-confidentiality-mechanics.md +109 -0
  177. package/docs/guidelines/agent-infra/systems-thinking.md +1 -1
  178. package/docs/guidelines/agent-infra/verify-before-complete-demos.md +2 -2
  179. package/docs/guidelines/augment-portability-patterns.md +6 -4
  180. package/docs/guidelines/code-clarity.md +18 -0
  181. package/docs/guidelines/component-oriented-and-oop-development.md +3 -2
  182. package/docs/guidelines/cross-role-handoff.md +2 -2
  183. package/docs/guidelines/design-fidelity-mechanics.md +1 -1
  184. package/docs/guidelines/docs/readme-size-and-splitting.md +3 -3
  185. package/docs/guidelines/php/database.md +90 -7
  186. package/docs/guidelines/prompt-templates.md +7 -7
  187. package/llms.txt +2 -2
  188. package/package.json +5 -2
  189. package/src/agent-src/scripts/archive_completed_roadmaps.ts +252 -8
  190. package/src/agent-src/scripts/guarded_baseline.ts +343 -0
  191. package/src/agent-src/scripts/roadmap_set_step.ts +253 -0
  192. package/src/agent-src/scripts/stub_queue.ts +82 -0
  193. package/src/agent-src/scripts/stubs_due.ts +516 -0
  194. package/src/agent-src/scripts/ticket_bundles.ts +84 -0
  195. package/src/agent-src/scripts/update_roadmap_progress.ts +16 -12
  196. package/src/agent-src/templates/scripts/check_memory.ts +258 -17
  197. package/src/agent-src/templates/scripts/check_memory_proposal.ts +9 -3
  198. package/src/agent-src/templates/scripts/memory_lookup.ts +86 -0
  199. package/src/agent-src/templates/scripts/memory_signal.ts +44 -0
  200. package/src/agent-src/templates/scripts/work_engine/directives/backend/implement.ts +90 -0
  201. package/src/agent-src/templates/scripts/work_engine/directives/backend/index.ts +11 -0
  202. package/src/agent-src/templates/scripts/work_engine/directives/backend/test.ts +23 -1
  203. package/src/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +10 -1
  204. package/src/agent-src/templates/scripts/work_engine/directives/mixed/stitch.ts +5 -1
  205. package/src/agent-src/templates/scripts/work_engine/stack/runner.ts +102 -14
  206. package/src/config/agent-settings.template.yml +32 -3
  207. package/src/config/assurance-capability-registry.json +21 -9
  208. package/src/config/canonical-terms.yml +119 -0
  209. package/src/config/capability-native-outcome-bars.json +81 -0
  210. package/src/config/ci-local-parity.yml +80 -0
  211. package/src/config/drafting-channels.yml +43 -0
  212. package/src/config/estate-count-budget.json +57 -36
  213. package/src/config/evaluator-budgets.json +14 -14
  214. package/src/config/gate-coverage.yml +729 -63
  215. package/src/config/gate-reachability-exemptions.json +21 -0
  216. package/src/config/gate-violation-baselines.json +42 -19
  217. package/src/config/harness-evolution-budget.json +25 -0
  218. package/src/config/lapsed-beta-baseline.json +96 -0
  219. package/src/config/memory-twin-verdicts.yml +129 -0
  220. package/src/config/metric-registry.yml +124 -0
  221. package/src/config/pack-size-budget.json +16 -15
  222. package/src/config/preamble-payload-budget.json +12 -4
  223. package/src/config/profiles/balanced.ini +27 -0
  224. package/src/config/profiles/full.ini +27 -0
  225. package/src/config/profiles/minimal.ini +27 -0
  226. package/src/config/publish-surface.json +9 -2
  227. package/src/config/routing-coverage-seed.json +16 -2
  228. package/src/config/rule-stub-ceilings.json +133 -112
  229. package/src/config/turnaround-budget.json +66 -0
  230. package/src/install/claudeRuleRewrite.ts +288 -0
  231. package/src/install/detect.ts +60 -17
  232. package/src/install/detect_php_shape.ts +191 -0
  233. package/src/scripts/_cli/cmd_doctor.ts +27 -112
  234. package/src/scripts/_dispatch.bash +23 -0
  235. package/src/scripts/_lib/activation_ladder.ts +255 -0
  236. package/src/scripts/_lib/activation_receipt_producer.ts +341 -0
  237. package/src/scripts/_lib/activation_states.ts +88 -0
  238. package/src/scripts/_lib/adherence_detectors.ts +143 -0
  239. package/src/scripts/_lib/adr_frontmatter.ts +26 -0
  240. package/src/scripts/_lib/arith_claims.ts +181 -0
  241. package/src/scripts/_lib/arm_ranking.ts +62 -0
  242. package/src/scripts/_lib/asset_delivery_ledger.ts +303 -0
  243. package/src/scripts/_lib/audit_field_provenance.ts +54 -0
  244. package/src/scripts/_lib/auto_dispatch.ts +32 -3
  245. package/src/scripts/_lib/bench_ab_size_claim.ts +98 -4
  246. package/src/scripts/_lib/benchmark_cache_fields.ts +158 -0
  247. package/src/scripts/_lib/candidate_pair_delta.ts +349 -0
  248. package/src/scripts/_lib/candidate_proposer.ts +402 -0
  249. package/src/scripts/_lib/candidate_record.ts +601 -0
  250. package/src/scripts/_lib/capture_rate.ts +319 -0
  251. package/src/scripts/_lib/carrier_status.ts +118 -0
  252. package/src/scripts/_lib/cascade_stage_enumeration.ts +92 -0
  253. package/src/scripts/_lib/collector_denominator.ts +771 -0
  254. package/src/scripts/_lib/collector_record.ts +340 -0
  255. package/src/scripts/_lib/collector_store.ts +664 -0
  256. package/src/scripts/_lib/collector_supervision.ts +827 -0
  257. package/src/scripts/_lib/concern_estate.ts +77 -0
  258. package/src/scripts/_lib/config_chain.ts +477 -0
  259. package/src/scripts/_lib/config_cost.ts +209 -0
  260. package/src/scripts/_lib/corpus_manifest.ts +726 -0
  261. package/src/scripts/_lib/council_settings_block.ts +6 -0
  262. package/src/scripts/_lib/curator_ops.ts +172 -0
  263. package/src/scripts/_lib/delivery_arm_experiment.ts +282 -0
  264. package/src/scripts/_lib/delivery_criticality.ts +126 -0
  265. package/src/scripts/_lib/doctor_runtime_checks.ts +70 -0
  266. package/src/scripts/_lib/empty_cycles.ts +88 -0
  267. package/src/scripts/_lib/estate_carrier_cases.ts +72 -0
  268. package/src/scripts/_lib/eval_publication.ts +354 -0
  269. package/src/scripts/_lib/evaluation_cascade.ts +452 -0
  270. package/src/scripts/_lib/evaluation_vector.ts +283 -0
  271. package/src/scripts/_lib/evaluator_promotion.ts +225 -0
  272. package/src/scripts/_lib/evidence_basis.ts +118 -0
  273. package/src/scripts/_lib/evolution_roi.ts +562 -0
  274. package/src/scripts/_lib/exec_evidence.ts +8 -0
  275. package/src/scripts/_lib/experience_card.ts +272 -0
  276. package/src/scripts/_lib/experience_report.ts +151 -0
  277. package/src/scripts/_lib/experiment_freeze.ts +112 -0
  278. package/src/scripts/_lib/generated_by.ts +66 -0
  279. package/src/scripts/_lib/harness_evolution_guards.ts +239 -0
  280. package/src/scripts/_lib/hook_effect_probe.ts +141 -0
  281. package/src/scripts/_lib/host_denominator.ts +687 -0
  282. package/src/scripts/_lib/host_projection_reach.ts +157 -0
  283. package/src/scripts/_lib/ignored_blocker.ts +148 -0
  284. package/src/scripts/_lib/install_reach_checks.ts +495 -0
  285. package/src/scripts/_lib/json_duplicate_keys.ts +150 -0
  286. package/src/scripts/_lib/judge_hygiene.ts +228 -0
  287. package/src/scripts/_lib/legacy_boundary_map.ts +228 -0
  288. package/src/scripts/_lib/lexical_shortlist.ts +215 -0
  289. package/src/scripts/_lib/llm_candidate_proposer.ts +461 -0
  290. package/src/scripts/_lib/llm_proposer_transport.ts +153 -0
  291. package/src/scripts/_lib/loop_guards.ts +299 -0
  292. package/src/scripts/_lib/loss_class.ts +129 -0
  293. package/src/scripts/_lib/machine_wake.ts +51 -0
  294. package/src/scripts/_lib/md_prose_lines.ts +177 -0
  295. package/src/scripts/_lib/minimality_tiebreak.ts +168 -0
  296. package/src/scripts/_lib/one_resolver_invariant.ts +449 -0
  297. package/src/scripts/_lib/orchestration_record.ts +253 -5
  298. package/src/scripts/_lib/outcome_envelope.ts +227 -0
  299. package/src/scripts/_lib/outcome_vocabularies.ts +125 -0
  300. package/src/scripts/_lib/paired_stats.ts +245 -0
  301. package/src/scripts/_lib/paired_verdict.ts +226 -0
  302. package/src/scripts/_lib/pathology_archive.ts +393 -0
  303. package/src/scripts/_lib/prefix_stable_surfaces.ts +123 -0
  304. package/src/scripts/_lib/privacy_class.ts +47 -0
  305. package/src/scripts/_lib/promotion_capability.ts +315 -0
  306. package/src/scripts/_lib/promotion_evidence.ts +414 -0
  307. package/src/scripts/_lib/promotion_review.ts +294 -0
  308. package/src/scripts/_lib/prompt_shape.ts +92 -0
  309. package/src/scripts/_lib/regression_neighbourhood.ts +259 -0
  310. package/src/scripts/_lib/release_highlights.ts +70 -1
  311. package/src/scripts/_lib/release_material.ts +125 -2
  312. package/src/scripts/_lib/repeated_failure.ts +105 -0
  313. package/src/scripts/_lib/repo_root.ts +111 -0
  314. package/src/scripts/_lib/review_skipped_record.ts +37 -0
  315. package/src/scripts/_lib/role_split.ts +338 -0
  316. package/src/scripts/_lib/routing_corpus.ts +307 -0
  317. package/src/scripts/_lib/routing_index_input.ts +104 -0
  318. package/src/scripts/_lib/rule_injection.ts +22 -1
  319. package/src/scripts/_lib/runtime_journal.ts +1499 -0
  320. package/src/scripts/_lib/runtime_wiring_checks.ts +430 -0
  321. package/src/scripts/_lib/semantic_noop.ts +167 -0
  322. package/src/scripts/_lib/skill_catalogue.ts +11 -1
  323. package/src/scripts/_lib/source_digest.ts +200 -0
  324. package/src/scripts/_lib/source_redact.ts +260 -0
  325. package/src/scripts/_lib/source_shape.ts +502 -0
  326. package/src/scripts/_lib/source_snapshot_dedup.ts +199 -0
  327. package/src/scripts/_lib/strip_comments.d.mts +8 -0
  328. package/src/scripts/_lib/strip_comments.mjs +65 -0
  329. package/src/scripts/_lib/test_red_state.ts +154 -0
  330. package/src/scripts/_lib/trigger_shift.ts +144 -0
  331. package/src/scripts/_lib/untrusted_content.ts +82 -7
  332. package/src/scripts/activation_receipt.ts +258 -0
  333. package/src/scripts/adoption_report.ts +1 -1
  334. package/src/scripts/adr/evidence_census.ts +1 -1
  335. package/src/scripts/adr/regenerate_index.ts +26 -2
  336. package/src/scripts/adr_cite_check.ts +164 -1
  337. package/src/scripts/ai_council/blind_review.ts +11 -1
  338. package/src/scripts/ai_council/clients.ts +4 -0
  339. package/src/scripts/ai_council/config.ts +3 -0
  340. package/src/scripts/ai_council/consensus.ts +28 -8
  341. package/src/scripts/ai_council/consensus_round.ts +226 -0
  342. package/src/scripts/ai_council/cross_exam.ts +128 -0
  343. package/src/scripts/ai_council/disagreement_signal.ts +338 -0
  344. package/src/scripts/ai_council/explain_route.ts +157 -0
  345. package/src/scripts/ai_council/information_gain.ts +293 -0
  346. package/src/scripts/ai_council/inline_findings.ts +340 -0
  347. package/src/scripts/ai_council/judge_position_bias.ts +197 -0
  348. package/src/scripts/ai_council/leakage_corpus.ts +385 -0
  349. package/src/scripts/ai_council/leakage_patterns.ts +453 -0
  350. package/src/scripts/ai_council/minority_retention.ts +171 -0
  351. package/src/scripts/ai_council/orchestrator.ts +16 -203
  352. package/src/scripts/ai_council/orchestrator_results.ts +23 -3
  353. package/src/scripts/ai_council/pricing.ts +106 -0
  354. package/src/scripts/ai_council/prompts.ts +74 -7
  355. package/src/scripts/ai_council/provider_leakage_bench.ts +327 -0
  356. package/src/scripts/ai_council/py_format.ts +14 -3
  357. package/src/scripts/ai_council/recouncil_guard.ts +293 -0
  358. package/src/scripts/ai_council/recouncil_savings.ts +299 -0
  359. package/src/scripts/ai_council/replay_route.ts +223 -0
  360. package/src/scripts/ai_council/response_record.ts +50 -0
  361. package/src/scripts/ai_council/reviewer_assignment.ts +279 -0
  362. package/src/scripts/ai_council/routing_training_row.ts +197 -0
  363. package/src/scripts/ai_council/synthesis_strategy.ts +159 -0
  364. package/src/scripts/ai_council/topology_bench_manifest.ts +860 -0
  365. package/src/scripts/ai_council/topology_vocabulary.ts +175 -0
  366. package/src/scripts/asset_delivery_ledger.ts +157 -0
  367. package/src/scripts/attest_artifact.ts +193 -0
  368. package/src/scripts/audit_auto_rules.ts +2 -1
  369. package/src/scripts/audit_command_surface.ts +1 -1
  370. package/src/scripts/audit_mcp_tools.ts +2 -2
  371. package/src/scripts/audit_skill_overlap_allowlist.json +6 -1
  372. package/src/scripts/audit_user_type_axis.ts +2 -1
  373. package/src/scripts/bench_ab_clone.ts +215 -10
  374. package/src/scripts/bench_ab_integrity.ts +119 -5
  375. package/src/scripts/bench_ab_v2_stats.ts +40 -213
  376. package/src/scripts/build_archive_index.ts +1 -1
  377. package/src/scripts/build_linear_digest.ts +1 -1
  378. package/src/scripts/build_proof.ts +11 -4
  379. package/src/scripts/build_rule_trigger_matrix.ts +1 -1
  380. package/src/scripts/build_source_digests.ts +157 -0
  381. package/src/scripts/cache_realization_report.ts +103 -0
  382. package/src/scripts/check_adr_frontmatter.ts +131 -10
  383. package/src/scripts/check_benchmark_report_fields.ts +207 -0
  384. package/src/scripts/check_beta_review_markers.ts +235 -6
  385. package/src/scripts/check_bundle_path_leakage.ts +34 -1
  386. package/src/scripts/check_claims.ts +576 -6
  387. package/src/scripts/check_composite_arming.ts +35 -0
  388. package/src/scripts/check_concern_admissions.ts +365 -0
  389. package/src/scripts/check_enforcement_coverage.ts +28 -0
  390. package/src/scripts/check_estate_count.ts +347 -25
  391. package/src/scripts/check_gate_reachability.ts +383 -0
  392. package/src/scripts/check_host_loadability.ts +104 -0
  393. package/src/scripts/check_loss_class_declared.ts +308 -0
  394. package/src/scripts/check_md_language.ts +15 -98
  395. package/src/scripts/check_memory_proposal.ts +18 -11
  396. package/src/scripts/check_no_currency_in_cost_surfaces.ts +225 -0
  397. package/src/scripts/check_no_external_sources.ts +281 -6
  398. package/src/scripts/check_pack_conformance_fixture.ts +11 -1
  399. package/src/scripts/check_pack_size.ts +59 -2
  400. package/src/scripts/check_preamble_payload_budget.ts +114 -3
  401. package/src/scripts/check_prefix_stable_mutation.ts +372 -0
  402. package/src/scripts/check_publish_surface.ts +10 -1
  403. package/src/scripts/check_references.ts +24 -1
  404. package/src/scripts/check_release_highlights.ts +96 -13
  405. package/src/scripts/check_roadmap_trackable.ts +17 -2
  406. package/src/scripts/check_rule_evidence_declaration.ts +316 -0
  407. package/src/scripts/check_rule_projection_integrity.ts +14 -4
  408. package/src/scripts/check_score_contract.ts +26 -3
  409. package/src/scripts/check_static_parity.ts +285 -0
  410. package/src/scripts/check_supervision_claim_atomicity.ts +498 -0
  411. package/src/scripts/check_suppression_hygiene.ts +15 -0
  412. package/src/scripts/ci_settle.ts +39 -2
  413. package/src/scripts/code_graph/build.ts +60 -3
  414. package/src/scripts/code_graph/extract.ts +44 -0
  415. package/src/scripts/code_graph/types.ts +24 -0
  416. package/src/scripts/collector_daemon.ts +714 -0
  417. package/src/scripts/config_cost_report.ts +302 -0
  418. package/src/scripts/consumer_matrix.ts +74 -1
  419. package/src/scripts/corpus_manifest.ts +235 -0
  420. package/src/scripts/cost/budget.mjs +10 -3
  421. package/src/scripts/cost/track.mjs +10 -3
  422. package/src/scripts/council_cli.ts +37 -54
  423. package/src/scripts/dispatch_r2_reviewer.ts +46 -5
  424. package/src/scripts/evolution_lab.ts +1153 -0
  425. package/src/scripts/external_sources_denylist.json +5 -18
  426. package/src/scripts/extract_audit_patterns.ts +21 -0
  427. package/src/scripts/fold_intake.ts +12 -1
  428. package/src/scripts/gen_discovery_baseline.ts +1 -1
  429. package/src/scripts/generate_capabilities_index.ts +12 -5
  430. package/src/scripts/generate_capability_matrix.ts +3 -3
  431. package/src/scripts/generate_command_flows.ts +2 -2
  432. package/src/scripts/generate_cookbook.ts +2 -2
  433. package/src/scripts/generate_index.ts +8 -1
  434. package/src/scripts/generate_knowledge_index.ts +2 -1
  435. package/src/scripts/generate_ownership_matrix.ts +2 -1
  436. package/src/scripts/generate_pack_manifests.ts +10 -2
  437. package/src/scripts/generate_role_experiences_catalog.ts +2 -2
  438. package/src/scripts/generate_settings_reference.ts +1 -1
  439. package/src/scripts/git_authorization_hook.ts +22 -1
  440. package/src/scripts/grade_target_readiness.ts +48 -5
  441. package/src/scripts/hook_effect_doctor.ts +261 -0
  442. package/src/scripts/hook_manifest.json +1 -1
  443. package/src/scripts/hook_manifest.yaml +125 -16
  444. package/src/scripts/hooks/block_speaking_inbox_dir.ts +271 -0
  445. package/src/scripts/hooks/block_unauthorized_git.ts +18 -0
  446. package/src/scripts/hooks/comment_discipline_hook.ts +146 -0
  447. package/src/scripts/hooks/concern_registry.ts +6 -0
  448. package/src/scripts/hooks/dispatch_hook.ts +32 -0
  449. package/src/scripts/hooks/journal_record_hook.ts +345 -0
  450. package/src/scripts/hooks/prepush_metadata_sources.sh +110 -0
  451. package/src/scripts/hooks/run_continuation_hook.ts +44 -9
  452. package/src/scripts/hooks/shims/install.sh +61 -0
  453. package/src/scripts/hooks/shims/php +101 -0
  454. package/src/scripts/hooks/suggestion_capture_hook.ts +10 -0
  455. package/src/scripts/hooks/turn_end_gate_hook.ts +9 -1
  456. package/src/scripts/hot_context_hook.ts +16 -0
  457. package/src/scripts/install-hooks.sh +20 -5
  458. package/src/scripts/install.ts +17 -35
  459. package/src/scripts/inventory_frontmatter.ts +2 -1
  460. package/src/scripts/language_mirror_hook.ts +14 -2
  461. package/src/scripts/lint_adr_sweep_routing.ts +12 -0
  462. package/src/scripts/lint_canonical_terms.ts +604 -0
  463. package/src/scripts/lint_carrier_integrity.ts +820 -0
  464. package/src/scripts/lint_code_comments.ts +643 -0
  465. package/src/scripts/lint_composition_review.ts +619 -0
  466. package/src/scripts/lint_consolidation_lineage.ts +666 -0
  467. package/src/scripts/lint_eval_specs.ts +593 -0
  468. package/src/scripts/lint_hook_manifest.ts +19 -0
  469. package/src/scripts/lint_host_portability.ts +373 -0
  470. package/src/scripts/lint_judge_prompt_expectation.ts +27 -1
  471. package/src/scripts/lint_memory_twin_parity.ts +335 -0
  472. package/src/scripts/lint_metric_consumers.ts +355 -0
  473. package/src/scripts/lint_plan_risk_register.ts +39 -19
  474. package/src/scripts/lint_promotion_paths.ts +779 -0
  475. package/src/scripts/lint_skill_descriptions.ts +18 -1
  476. package/src/scripts/lint_skill_frontmatter_safety.ts +58 -0
  477. package/src/scripts/lint_skill_link_reach.ts +252 -0
  478. package/src/scripts/lint_skill_trigger_corpus.ts +426 -23
  479. package/src/scripts/lint_ticket_buildable.ts +17 -1
  480. package/src/scripts/llm_propose.ts +256 -0
  481. package/src/scripts/mcp_server/consumer_tool_catalog.json +1 -1
  482. package/src/scripts/mcp_server/tool_catalog_source.ts +1 -1
  483. package/src/scripts/measure_delivery_sets.ts +361 -0
  484. package/src/scripts/measure_docs_dead_links.ts +348 -0
  485. package/src/scripts/measure_host_capture.ts +461 -0
  486. package/src/scripts/measure_routing_signal.ts +307 -0
  487. package/src/scripts/migration_status.ts +3 -3
  488. package/src/scripts/model_rule_injection.ts +76 -0
  489. package/src/scripts/orchestration_record.ts +14 -0
  490. package/src/scripts/preamble_byte_census.ts +139 -10
  491. package/src/scripts/prepack-check.mjs +4 -1
  492. package/src/scripts/probe_council_retention.ts +495 -0
  493. package/src/scripts/probe_turnaround.ts +384 -0
  494. package/src/scripts/probe_unblocked_ask.ts +279 -0
  495. package/src/scripts/release.ts +21 -37
  496. package/src/scripts/release_drill.ts +143 -0
  497. package/src/scripts/release_env.ts +35 -0
  498. package/src/scripts/release_publication.ts +84 -0
  499. package/src/scripts/render_benchmark_md.ts +1 -1
  500. package/src/scripts/rule_activation_census.ts +70 -9
  501. package/src/scripts/rule_backlinks.ts +1 -1
  502. package/src/scripts/run_lifecycle_suite.ts +208 -0
  503. package/src/scripts/run_skill_evals.ts +40 -0
  504. package/src/scripts/schemas/delivery-manifest.schema.json +43 -0
  505. package/src/scripts/schemas/drafting-channels.schema.json +43 -0
  506. package/src/scripts/schemas/evals.schema.json +24 -1
  507. package/src/scripts/schemas/rule.schema.json +52 -1
  508. package/src/scripts/schemas/skill.schema.json +17 -2
  509. package/src/scripts/skill_overlap.ts +7 -1
  510. package/src/scripts/skill_tools/run_block_d_eval.ts +8 -1
  511. package/src/scripts/skill_tools/score_skill_relevance.ts +84 -3
  512. package/src/scripts/skill_tools/suggest_skill_for_task.ts +8 -1
  513. package/src/scripts/skill_usage_report.ts +2 -1
  514. package/src/scripts/stubs_due.ts +211 -0
  515. package/src/scripts/sweep_source_surfaces.ts +678 -0
  516. package/src/scripts/sync_pr_branch.ts +3 -3
  517. package/src/scripts/trigger_eval_grandfather.json +202 -222
  518. package/src/scripts/utilization_report.ts +22 -2
  519. package/src/server/schemas/settings.ts +5 -0
  520. package/src/templates/marketing-copy.yml +1 -1
  521. package/dist/ui/assets/index-Cxgy63kz.js +0 -26
@@ -0,0 +1,175 @@
1
+ /**
2
+ * The council-rung topology vocabulary, closed at seven names.
3
+ *
4
+ * `road-to-inbox-harvest-2026-08-e-council-topology-evidence` step 7.1 asks
5
+ * for a vocabulary that "admits no eighth member without a schema change" and
6
+ * in which `team` / `user_required` are "not representable". Those are two
7
+ * different claims and they need two different mechanisms, so this module
8
+ * carries both.
9
+ *
10
+ * ## Where this sits — and what it deliberately is NOT
11
+ *
12
+ * It is **not** a resolver. `src/scripts/_lib/judgment_ladder.ts` is the ONE
13
+ * task-side resolver, and `src/scripts/_lib/one_resolver_invariant.ts` fails
14
+ * the build on a second one. This module exports a NAME SET and two
15
+ * predicates; it classifies nothing, reads no request, and takes no routing
16
+ * decision. It also lives under `ai_council/`, which the one-resolver scan
17
+ * treats as council-internal and skips by construction — the topology
18
+ * refinement hangs off the council rung *after* the ladder has already
19
+ * resolved to it, exactly as the roadmap's goal diagram draws it.
20
+ *
21
+ * The selector that will eventually CONSUME this vocabulary is step 7.2 and is
22
+ * not built here. Shipping the vocabulary first is deliberate: it is the half
23
+ * that can be closed without pre-empting the selector's design.
24
+ *
25
+ * ## Claim 1 — no eighth member without a source change that fails a gate
26
+ *
27
+ * {@link COUNCIL_TOPOLOGIES} is a frozen `as const` tuple, so its `length` is
28
+ * the literal `7` and {@link CouncilTopology} is a closed union. Appending an
29
+ * eighth entry turns the length into `8`, and {@link VocabularyIsClosed}'s
30
+ * first assertion then fails `npm run typecheck` — a CI gate. The same edit
31
+ * also fails {@link auditCouncilTopologyVocabulary}, which is the runtime half
32
+ * for the compiled `dist/` path where types no longer exist.
33
+ *
34
+ * ## Claim 2 — `team` and `user_required` are not representable
35
+ *
36
+ * Omitting two strings from a list is the weak form: nothing stops the next
37
+ * author adding them. The strong form binds the exclusion to the vocabularies
38
+ * that actually own those names, via TYPE-ONLY imports that are erased at
39
+ * compile time and couple nothing at runtime:
40
+ *
41
+ * - `team` is a `LadderVerdict` — rung 3, `judgment_ladder.ts:45`. The ladder
42
+ * owns it.
43
+ * - `user_required` is an `ImpactClass` — `necessity.ts:550`, and it sits in
44
+ * `LOCKED_IMPACT_CLASSES` (`necessity.ts:557-560`), the set structurally
45
+ * locked to `user` routing. The Hard Floor owns it.
46
+ *
47
+ * {@link VocabularyIsClosed} asserts that NO `LadderVerdict` and NO
48
+ * `ImpactClass` is a `CouncilTopology` — which is stronger than naming two
49
+ * strings, because it also excludes `script`, `subagent`, `council`, `ask`,
50
+ * `in-session`, `high_impact` and the rest. It further asserts that the two
51
+ * names in {@link RESERVED_BY_OTHER_LAYERS} really ARE members of those
52
+ * foreign vocabularies, so a rename on the ladder or in the necessity gate
53
+ * reds this file rather than silently orphaning the exclusion.
54
+ *
55
+ * ## Why not a JSON schema, and why not the config contract
56
+ *
57
+ * `src/scripts/schemas/` carries no council schema at all — `.ai-council.yml`
58
+ * is validated by the hand-rolled loader in `ai_council/config.ts`, so there
59
+ * is no enum surface there to extend. And this vocabulary is deliberately
60
+ * absent from `docs/contracts/ai-council-config.md`: that document describes
61
+ * what a USER may configure, while step 12.4 requires consumer surfaces to
62
+ * request capabilities and never topology names. Documenting it as config
63
+ * would invite exactly the coupling 12.4 forbids.
64
+ */
65
+ import type { LadderVerdict } from '../_lib/judgment_ladder.js';
66
+
67
+ import type { ImpactClass } from './necessity.js';
68
+
69
+ /**
70
+ * The closed topology vocabulary, verbatim from the roadmap's goal diagram
71
+ * (`road-to-inbox-harvest-2026-08-e-council-topology-evidence.md:62-68`).
72
+ * Order is the diagram's order and carries no precedence.
73
+ */
74
+ export const COUNCIL_TOPOLOGIES = Object.freeze([
75
+ 'single_external',
76
+ 'dual_independent',
77
+ 'advisor_diversity',
78
+ 'peer_review',
79
+ 'judge_synthesis',
80
+ 'targeted_cross_exam',
81
+ 'full_debate',
82
+ ] as const);
83
+
84
+ /** The closed union. There is no widening escape hatch on purpose. */
85
+ export type CouncilTopology = (typeof COUNCIL_TOPOLOGIES)[number];
86
+
87
+ /** Declared arity. Changing the tuple without changing this reds the type layer. */
88
+ export const COUNCIL_TOPOLOGY_ARITY = 7;
89
+
90
+ /**
91
+ * Names owned by other layers, restated here so the runtime half can reject
92
+ * them without importing a value across the layer boundary. The type layer
93
+ * below pins each one to its real owning vocabulary.
94
+ */
95
+ export const RESERVED_BY_OTHER_LAYERS = Object.freeze(['team', 'user_required'] as const);
96
+
97
+ /** A name this vocabulary must never admit. */
98
+ export type ReservedElsewhere = (typeof RESERVED_BY_OTHER_LAYERS)[number];
99
+
100
+ /** Fails to instantiate unless `T` is exactly `true`. */
101
+ type Assert<T extends true> = T;
102
+
103
+ /**
104
+ * The compile-time half of both claims. Every member must stay `true`; each
105
+ * one is a distinct way the vocabulary could be opened, and `npm run
106
+ * typecheck` is the gate that runs them.
107
+ *
108
+ * 1. arity is exactly {@link COUNCIL_TOPOLOGY_ARITY} — an eighth member reds it
109
+ * 2. no ladder verdict is a topology — `team` included, by construction
110
+ * 3. no impact class is a topology — `user_required` included, by construction
111
+ * 4. both reserved names are real members of those foreign vocabularies, so a
112
+ * rename upstream cannot orphan the exclusion into a dead string
113
+ * 5. neither reserved name is representable as a topology
114
+ *
115
+ * The `[X] extends [never]` tuple form is deliberate: it suppresses
116
+ * distribution, so an empty `Extract` reads as the single type `never` rather
117
+ * than as an empty union of branches.
118
+ */
119
+ export type VocabularyIsClosed = [
120
+ Assert<(typeof COUNCIL_TOPOLOGIES)['length'] extends typeof COUNCIL_TOPOLOGY_ARITY ? true : false>,
121
+ Assert<[Extract<CouncilTopology, LadderVerdict>] extends [never] ? true : false>,
122
+ Assert<[Extract<CouncilTopology, ImpactClass>] extends [never] ? true : false>,
123
+ Assert<ReservedElsewhere extends LadderVerdict | ImpactClass ? true : false>,
124
+ Assert<[Extract<CouncilTopology, ReservedElsewhere>] extends [never] ? true : false>,
125
+ ];
126
+
127
+ /** Is this value one of the seven? `team` and `user_required` are not. */
128
+ export function isCouncilTopology(value: unknown): value is CouncilTopology {
129
+ return typeof value === 'string' && (COUNCIL_TOPOLOGIES as readonly string[]).includes(value);
130
+ }
131
+
132
+ /**
133
+ * The runtime half, and the reason it takes arguments rather than reading the
134
+ * constants directly: a guard that can only ever be handed the correct input
135
+ * has unknown sensitivity. Callers in `dist/` pass the shipped constants; the
136
+ * test passes mutations and asserts each one is caught.
137
+ *
138
+ * @returns one string per problem found; empty means the vocabulary is closed.
139
+ */
140
+ export function auditCouncilTopologyVocabulary(
141
+ topologies: readonly string[] = COUNCIL_TOPOLOGIES,
142
+ reserved: readonly string[] = RESERVED_BY_OTHER_LAYERS,
143
+ ): string[] {
144
+ const problems: string[] = [];
145
+ if (topologies.length !== COUNCIL_TOPOLOGY_ARITY) {
146
+ problems.push(
147
+ `arity: expected exactly ${COUNCIL_TOPOLOGY_ARITY} topologies, found ${topologies.length}. ` +
148
+ 'The vocabulary is closed; an eighth member is a schema change, not an append.',
149
+ );
150
+ }
151
+ if (new Set(topologies).size !== topologies.length) {
152
+ problems.push('duplicate: the vocabulary contains a repeated name.');
153
+ }
154
+ for (const name of reserved) {
155
+ if (topologies.includes(name)) {
156
+ problems.push(
157
+ `reserved: \`${name}\` is owned by another layer (the judgment ladder for ` +
158
+ '`team`, the locked impact classes for `user_required`) and is not ' +
159
+ 'representable as a council topology.',
160
+ );
161
+ }
162
+ }
163
+ return problems;
164
+ }
165
+
166
+ /**
167
+ * Module-load guard. Types are erased in `dist/`, so without this the runtime
168
+ * artefact carries no version of claim 1 or claim 2 at all. It can only fire
169
+ * on a source edit that also reds `npm run typecheck`, which is the point:
170
+ * two independent layers, not one restated twice.
171
+ */
172
+ const _shippedProblems = auditCouncilTopologyVocabulary();
173
+ if (_shippedProblems.length > 0) {
174
+ throw new Error(`council topology vocabulary is not closed:\n ${_shippedProblems.join('\n ')}`);
175
+ }
@@ -0,0 +1,157 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * Per-asset delivery ledger — which assets produce the standing payload
4
+ * (`road-to-delivered-cost-truth` step 2.1).
5
+ *
6
+ * `check_preamble_payload_budget` measures three BUCKET totals and refuses
7
+ * growth. It cannot say which asset inside a bucket produces the cost, so a
8
+ * reduction effort has a number (35,692 tokens over a published milestone) and
9
+ * no target. This command ranks the assets behind that number.
10
+ *
11
+ * Class A per ADR-124: in-process, per-invocation, no socket, no daemon, no
12
+ * network, no writes outside a stdout/JSON report.
13
+ *
14
+ * Usage:
15
+ * ./scripts-run src/scripts/asset_delivery_ledger [--format text|json]
16
+ * [--top <n>] [--root <path>]
17
+ */
18
+ import * as path from 'node:path';
19
+
20
+ import {
21
+ buildLedger,
22
+ reconcile,
23
+ RECONCILE_MARGIN,
24
+ type AssetRow,
25
+ type LedgerVerdict,
26
+ type Reconciliation,
27
+ } from './_lib/asset_delivery_ledger.js';
28
+ import { measureDeterministicPayload } from './check_preamble_payload_budget.js';
29
+ import { prefixStableDirRoots } from './_lib/prefix_stable_surfaces.js';
30
+
31
+ const HERE = path.dirname(new URL(import.meta.url).pathname);
32
+ const REPO_ROOT = path.resolve(HERE, '..', '..');
33
+
34
+ export interface Options {
35
+ format: 'text' | 'json';
36
+ top: number;
37
+ root: string;
38
+ }
39
+
40
+ export function parseArgs(argv: string[]): Options {
41
+ const opts: Options = { format: 'text', top: 20, root: REPO_ROOT };
42
+ for (let i = 0; i < argv.length; i++) {
43
+ const a = argv[i];
44
+ if (a === undefined) continue;
45
+ if (a === '--format') opts.format = (argv[++i] as Options['format']) ?? opts.format;
46
+ else if (a.startsWith('--format=')) opts.format = a.slice('--format='.length) as Options['format'];
47
+ else if (a === '--top') opts.top = Number(argv[++i]) || opts.top;
48
+ else if (a.startsWith('--top=')) opts.top = Number(a.slice('--top='.length)) || opts.top;
49
+ else if (a === '--root') opts.root = path.resolve(argv[++i] ?? opts.root);
50
+ else if (a.startsWith('--root=')) opts.root = path.resolve(a.slice('--root='.length));
51
+ }
52
+ if (opts.format !== 'text' && opts.format !== 'json') opts.format = 'text';
53
+ return opts;
54
+ }
55
+
56
+ export interface Report {
57
+ schema: 'asset-delivery-ledger/v1';
58
+ ledger: LedgerVerdict;
59
+ reconciliation: Reconciliation[];
60
+ reconcile_margin: number;
61
+ }
62
+
63
+ export function buildReport(root: string): Report {
64
+ // Roots come from the prefix-stable registry, the same module the payload
65
+ // gate resolves its census roots from. A third statement of the same
66
+ // boundary is the drift shape this repository already pays for.
67
+ const [rulesRel, skillsRel] = prefixStableDirRoots();
68
+ const ledger = buildLedger(
69
+ path.join(root, rulesRel ?? 'dist/agent-src/rules'),
70
+ path.join(root, skillsRel ?? 'dist/agent-src/skills'),
71
+ root,
72
+ );
73
+ return {
74
+ schema: 'asset-delivery-ledger/v1',
75
+ ledger,
76
+ reconciliation: reconcile(ledger, measureDeterministicPayload(root)),
77
+ reconcile_margin: RECONCILE_MARGIN,
78
+ };
79
+ }
80
+
81
+ function pct(v: number): string {
82
+ return `${(v * 100).toFixed(1)}%`;
83
+ }
84
+
85
+ export function renderText(r: Report, top: number): string {
86
+ const out: string[] = [];
87
+ const l = r.ledger;
88
+ out.push('Per-asset delivery ledger — what every spawn pays for');
89
+ out.push(
90
+ ` measurement: ${l.exact_throughout ? 'exact BPE throughout' : 'MIXED — some rows fall back to the chars/4 proxy'}`,
91
+ );
92
+ out.push(` total: ${l.total_tokens} tok across ${l.rows.length} asset(s)`);
93
+ out.push(
94
+ ` by kind: rules ${l.by_kind.rule.tokens} tok (${l.by_kind.rule.count}) · ` +
95
+ `skill catalogue lines ${l.by_kind['skill-catalogue-line'].tokens} tok (${l.by_kind['skill-catalogue-line'].count})`,
96
+ );
97
+ out.push('');
98
+ out.push(`Top ${Math.min(top, l.rows.length)} by delivered tokens:`);
99
+ out.push(` ${'tokens'.padStart(7)} ${'share'.padStart(6)} ${'method'.padEnd(6)} asset`);
100
+ for (const row of l.rows.slice(0, top)) {
101
+ out.push(
102
+ ` ${String(row.tokens).padStart(7)} ${pct(row.share).padStart(6)} ${row.method.padEnd(6)} ${row.name} (${row.kind})`,
103
+ );
104
+ }
105
+ out.push('');
106
+ out.push('Reconciliation against the payload gate\'s own bucket totals:');
107
+ if (r.reconciliation.length === 0) {
108
+ out.push(' no bucket to reconcile against — the payload census measured nothing');
109
+ }
110
+ for (const rec of r.reconciliation) {
111
+ const mark = rec.within_margin ? '✅' : '❌';
112
+ out.push(
113
+ ` ${mark} ${rec.bucket}: ledger ${rec.ledger_proxy_tokens} tok vs bucket ${rec.bucket_tokens} tok ` +
114
+ `(drift ${pct(rec.drift)}, margin ${pct(r.reconcile_margin)}) · both chars/4` +
115
+ `\n exact BPE for the same assets: ${rec.ledger_exact_tokens} tok` +
116
+ ` (${pct(1 - rec.ledger_exact_tokens / Math.max(rec.ledger_proxy_tokens, 1))} below the proxy)`,
117
+ );
118
+ }
119
+ out.push('');
120
+ out.push(' Reconciled like-for-like: both sides are chars/4, so what remains is real');
121
+ out.push(' disagreement rather than a method gap. The exact BPE figure is shown beside each');
122
+ out.push(' bucket because the gap is the interesting part — chars/4 overestimates short');
123
+ out.push(' structured lines far more than it does prose, which is why the skill catalogue');
124
+ out.push(' and the rule bodies diverge from the proxy by very different amounts.');
125
+ return out.join('\n') + '\n';
126
+ }
127
+
128
+ export function main(argv: string[] = process.argv.slice(2)): number {
129
+ const opts = parseArgs(argv);
130
+ let report: Report;
131
+ try {
132
+ report = buildReport(opts.root);
133
+ } catch (err) {
134
+ process.stderr.write(`❌ asset_delivery_ledger: ${(err as Error).message}\n`);
135
+ return 2;
136
+ }
137
+
138
+ if (report.ledger.rows.length === 0) {
139
+ process.stderr.write(
140
+ '❌ asset_delivery_ledger: no asset measured. The standing rule and skill trees are\n' +
141
+ ' generated (`task sync && task generate-tools`); a checkout that has not run them\n' +
142
+ ' has nothing to rank. This is a stated reason, not an empty ledger reported as zero.\n',
143
+ );
144
+ return 2;
145
+ }
146
+
147
+ process.stdout.write(
148
+ opts.format === 'json' ? JSON.stringify(report, null, 2) + '\n' : renderText(report, opts.top),
149
+ );
150
+ return report.reconciliation.every((r) => r.within_margin) ? 0 : 1;
151
+ }
152
+
153
+ if (process.argv[1] !== undefined && import.meta.url === `file://${process.argv[1]}`) {
154
+ process.exit(main());
155
+ }
156
+
157
+ export type { AssetRow };
@@ -0,0 +1,193 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * Content attestation for any artifact a hook would INJECT.
4
+ *
5
+ * `road-to-skill-ecosystem-runtime-enforcement` Phase 5, Steps 6-7, and the
6
+ * ordering in that step is the argument: attestation is the **precondition** for
7
+ * auto-injection, not a follow-up to it.
8
+ *
9
+ * ── The threat, concretely ──────────────────────────────────────────────────
10
+ * A hook that reads a tracked file and injects its contents into the model's
11
+ * context turns that file into a **standing injection amplifier**. Whoever can
12
+ * write the file can write the agent's instructions, on every session, without
13
+ * a review — which is `untrusted-input-defense`'s found-instructions case
14
+ * arriving through a file the repository itself vouches for. The file being
15
+ * tracked is not the control: a tracked file changes in a pull request, and a
16
+ * pull request that changes an injected file is indistinguishable in the diff
17
+ * from one that changes documentation.
18
+ *
19
+ * ── The contract ────────────────────────────────────────────────────────────
20
+ * An injectable artifact carries a sidecar `<file>.attest.json` holding the
21
+ * sha256 of its bytes and the date the attestation was recorded. Before
22
+ * injecting, a caller asks {@link verifyArtifact}:
23
+ *
24
+ * - hash matches → `ok`, inject.
25
+ * - hash differs → `mismatch`, REFUSE. The content changed since a human
26
+ * vouched for it; re-attesting is a deliberate act with a diff.
27
+ * - no sidecar → `unattested`, REFUSE. **Not "allow because nothing said
28
+ * no"** — that default makes the whole mechanism opt-out, and the file an
29
+ * attacker adds is exactly the one with no sidecar.
30
+ * - file missing → `absent`, REFUSE.
31
+ *
32
+ * ── What this does NOT claim ────────────────────────────────────────────────
33
+ * The sidecar is committed beside the artifact, so an attacker who can write
34
+ * both can write a consistent pair. This is NOT a cryptographic signature and
35
+ * does not pretend to be one. What it buys is that the change becomes VISIBLE:
36
+ * a diff that touches an injected file must also touch its attestation, and a
37
+ * hash line changing in a review is a question, where a prose change in the same
38
+ * file is not. Making a change reviewable is the honest claim; making it
39
+ * impossible would need a key this repository does not have.
40
+ *
41
+ * Exit codes: 0 verified · 1 refused (mismatch / unattested / absent) · 2 usage.
42
+ *
43
+ * Usage:
44
+ * ./scripts-run src/scripts/attest_artifact --record <file>
45
+ * ./scripts-run src/scripts/attest_artifact --verify <file>
46
+ * ./scripts-run src/scripts/attest_artifact --verify <file> --json
47
+ */
48
+ import * as crypto from 'node:crypto';
49
+ import * as fs from 'node:fs';
50
+ import * as path from 'node:path';
51
+ import process from 'node:process';
52
+ import { fileURLToPath, pathToFileURL } from 'node:url';
53
+
54
+ const _HERE = fileURLToPath(import.meta.url);
55
+
56
+ /** Sidecar suffix. Beside the artifact, so a move takes the attestation with it. */
57
+ export const ATTEST_SUFFIX = '.attest.json';
58
+
59
+ export type AttestStatus = 'ok' | 'mismatch' | 'unattested' | 'absent';
60
+
61
+ export interface Attestation {
62
+ schema_version: 1;
63
+ /** sha256 of the artifact's bytes, hex. */
64
+ sha256: string;
65
+ /** `YYYY-MM-DD` the attestation was recorded. */
66
+ recorded_at: string;
67
+ /** Bytes at record time — a cheap second signal that costs nothing to store. */
68
+ bytes: number;
69
+ }
70
+
71
+ export interface Verdict {
72
+ status: AttestStatus;
73
+ /** True only for `ok`. Every other status refuses. */
74
+ inject: boolean;
75
+ detail: string;
76
+ expected?: string;
77
+ actual?: string;
78
+ }
79
+
80
+ export function sidecarPath(artifact: string): string {
81
+ return `${artifact}${ATTEST_SUFFIX}`;
82
+ }
83
+
84
+ export function hashFile(artifact: string): string {
85
+ return crypto.createHash('sha256').update(fs.readFileSync(artifact)).digest('hex');
86
+ }
87
+
88
+ /**
89
+ * Verify an artifact against its sidecar.
90
+ *
91
+ * Every non-`ok` status sets `inject: false`. That is the whole safety property
92
+ * and it is expressed as data rather than left to each caller's `if`: a caller
93
+ * that reads `verdict.inject` cannot accidentally treat `unattested` as
94
+ * permissive, which is the mistake an `status === 'mismatch'` check invites.
95
+ */
96
+ export function verifyArtifact(artifact: string, today?: string): Verdict {
97
+ void today;
98
+ if (!fs.existsSync(artifact)) {
99
+ return { status: 'absent', inject: false, detail: `${artifact} does not exist` };
100
+ }
101
+ const side = sidecarPath(artifact);
102
+ if (!fs.existsSync(side)) {
103
+ return {
104
+ status: 'unattested',
105
+ inject: false,
106
+ detail:
107
+ `${artifact} has no ${ATTEST_SUFFIX} sidecar — REFUSED. An unattested artifact is ` +
108
+ 'not "allowed because nothing said no": that default makes attestation opt-out, and ' +
109
+ 'the file an attacker adds is precisely the one with no sidecar.',
110
+ };
111
+ }
112
+ let att: Partial<Attestation>;
113
+ try {
114
+ att = JSON.parse(fs.readFileSync(side, 'utf8')) as Partial<Attestation>;
115
+ } catch (e) {
116
+ return {
117
+ status: 'unattested',
118
+ inject: false,
119
+ detail: `${side} does not parse (${e instanceof Error ? e.message : String(e)}) — treated as absent`,
120
+ };
121
+ }
122
+ const actual = hashFile(artifact);
123
+ if (typeof att.sha256 !== 'string' || att.sha256 === '') {
124
+ return { status: 'unattested', inject: false, detail: `${side} carries no sha256`, actual };
125
+ }
126
+ if (att.sha256 !== actual) {
127
+ return {
128
+ status: 'mismatch',
129
+ inject: false,
130
+ detail:
131
+ `${artifact} changed since it was attested — REFUSED. Re-attest deliberately ` +
132
+ `(--record) so the new hash lands in a diff a reviewer sees.`,
133
+ expected: att.sha256,
134
+ actual,
135
+ };
136
+ }
137
+ return { status: 'ok', inject: true, detail: `${artifact} matches its attestation`, expected: att.sha256, actual };
138
+ }
139
+
140
+ /** Record (or re-record) an attestation. Deliberate, and it lands in a diff. */
141
+ export function recordAttestation(artifact: string, today = new Date().toISOString().slice(0, 10)): Attestation {
142
+ const att: Attestation = {
143
+ schema_version: 1,
144
+ sha256: hashFile(artifact),
145
+ recorded_at: today,
146
+ bytes: fs.statSync(artifact).size,
147
+ };
148
+ fs.writeFileSync(sidecarPath(artifact), `${JSON.stringify(att, null, 2)}\n`, 'utf8');
149
+ return att;
150
+ }
151
+
152
+ export function main(argv: string[] = process.argv.slice(2)): number {
153
+ const usage =
154
+ 'usage: attest_artifact (--record | --verify) <file> [--json]\n' +
155
+ ' --verify exits 1 on mismatch, unattested or absent. Refusal is the default.\n';
156
+ if (argv.includes('-h') || argv.includes('--help')) {
157
+ process.stdout.write(usage);
158
+ return 0;
159
+ }
160
+ const asJson = argv.includes('--json');
161
+ const record = argv.includes('--record');
162
+ const verify = argv.includes('--verify');
163
+ const file = argv.find((a) => !a.startsWith('--'));
164
+ if (record === verify || file === undefined) {
165
+ process.stderr.write(`attest_artifact: error: exactly one of --record / --verify plus a file\n${usage}`);
166
+ return 2;
167
+ }
168
+ const target = path.resolve(file);
169
+ if (record) {
170
+ if (!fs.existsSync(target)) {
171
+ process.stderr.write(`attest_artifact: ${file} does not exist\n`);
172
+ return 2;
173
+ }
174
+ const att = recordAttestation(target);
175
+ process.stdout.write(`✅ attested ${file} — sha256 ${att.sha256.slice(0, 16)}… (${String(att.bytes)} bytes)\n`);
176
+ return 0;
177
+ }
178
+ const v = verifyArtifact(target);
179
+ if (asJson) {
180
+ process.stdout.write(`${JSON.stringify(v, null, 2)}\n`);
181
+ } else if (v.inject) {
182
+ process.stdout.write(`✅ ${v.detail}\n`);
183
+ } else {
184
+ process.stderr.write(`❌ [${v.status}] ${v.detail}\n`);
185
+ }
186
+ return v.inject ? 0 : 1;
187
+ }
188
+
189
+ /* c8 ignore start */
190
+ if (process.argv[1] !== undefined && pathToFileURL(path.resolve(process.argv[1])).href === pathToFileURL(_HERE).href) {
191
+ process.exit(main());
192
+ }
193
+ /* c8 ignore stop */
@@ -29,6 +29,7 @@ import { parse as parseYaml } from 'yaml';
29
29
 
30
30
  import { artefact_roots } from './_lib/agent_src.js';
31
31
  import { assertScanned, DeadScopeError } from './_lib/scan_scope.js';
32
+ import { generatedBy } from './_lib/generated_by.js';
32
33
 
33
34
  const _HERE = fileURLToPath(import.meta.url);
34
35
  // src/scripts/audit_auto_rules.py → parent.parent.parent == repo root.
@@ -270,7 +271,7 @@ export function render_markdown(rules: RuleEntry[]): string {
270
271
  `<!-- analyzed: ${dateStr} | commit: ${commitShort} | files: ${rules.length} -->`,
271
272
  '# Auto-Rule Audit',
272
273
  '',
273
- 'Generated by `scripts/audit_auto_rules.py` for Phase 5 of',
274
+ generatedBy('audit_auto_rules', 'For Phase 5 of'),
274
275
  '`agents/roadmaps/archive/road-to-augment-limit-fit.md`. Re-run after',
275
276
  'any rule add/merge/deprecate to refresh the baseline.',
276
277
  '',
@@ -548,7 +548,7 @@ export function render_md(commands: Command[], pairs: OverlapPair[]): string {
548
548
  const lines: string[] = [
549
549
  '# Command-Surface Inventory',
550
550
  '',
551
- '> Generated by `scripts/audit_command_surface.py`. ' +
551
+ '> Generated by `audit_command_surface`. Do not edit. ' +
552
552
  'Source: `.agent-src.uncondensed/commands/`.',
553
553
  '',
554
554
  '## Summary',
@@ -25,7 +25,7 @@ import { assertWatchlistResolves, DeadScopeError } from './_lib/scan_scope.js';
25
25
 
26
26
  const _HERE = fileURLToPath(import.meta.url);
27
27
 
28
- // src/scripts/audit_mcp_tools.ts → parent.parent.parent of the .py file = repo root.
28
+ // audit_mcp_tools → parent.parent.parent of the .py file = repo root.
29
29
  export const ROOT = path.resolve(path.dirname(_HERE), '..', '..');
30
30
  export const CATALOG = path.join(ROOT, 'src/scripts/mcp_server/consumer_tool_catalog.json');
31
31
  export const TOOLS_TS = path.join(ROOT, 'src/scripts/mcp_server/tools.ts');
@@ -145,7 +145,7 @@ function _render(catalog: Catalog, handlers: Map<string, number>, cat_lines: Map
145
145
  lines.push('');
146
146
  lines.push('# MCP tool inventory');
147
147
  lines.push('');
148
- lines.push('> Generated by [`src/scripts/audit_mcp_tools.ts`](../../src/scripts/audit_mcp_tools.ts)');
148
+ lines.push('> Generated by [`audit_mcp_tools`](../../audit_mcp_tools)');
149
149
  lines.push('> from the source-of-truth catalog');
150
150
  lines.push('> [`src/scripts/mcp_server/consumer_tool_catalog.json`](../../src/scripts/mcp_server/consumer_tool_catalog.json).');
151
151
  lines.push('> Do **not** hand-edit; rerun `./scripts-run src/scripts/audit_mcp_tools --write`.');
@@ -1,4 +1,9 @@
1
1
  {
2
2
  "_comment": "Reviewed same-pack overlaps at or above the canonical 0.70 threshold. Each entry needs a real reason — a pair is here because a human read both skills and decided the overlap is structural, not because the gate was noisy. Capped at 20 by audit_skill_overlap.ts: crossing the cap means the threshold is wrong, not that the corpus needs a twenty-first exception. Empty is the healthy state.",
3
- "entries": []
3
+ "entries": [
4
+ {
5
+ "pair": "test-driven-development::testing-anti-patterns",
6
+ "reason": "Structural vocabulary overlap from a shared testing domain (test, assertion, mock, fixture, red, green), not duplicated responsibility. The two are architecturally distinct: test-driven-development is the PROCEDURE — four mode contracts with diff-checked Forbidden columns, mode inference on resume, the delete-and-restart law; testing-anti-patterns is the DIAGNOSTIC CATALOGUE — tautological assertions, hardcoded expectations, over-mocking, test-data realism. They answer different questions at different call sites. Measured 2026-08-26 with the audit's own collect()+_cosine(): the pair sat at 0.7000 before this change and 0.7120 after, so it was already at the cap and any body edit to either skill re-trips the gate. Migrating 11 lines of rationale into a non-SKILL.md companion was tried and measured (0.7056) and REJECTED: it still failed, and it removes guidance from the file the agent actually loads, which optimises for the detector rather than the reader. Merging was rejected — a procedure and a failure catalogue have distinct invocation needs. Invalidation trigger: reassess if either skill's scope materially changes, or if substantive guidance becomes duplicated between them rather than merely sharing vocabulary. Council 2026-08-26, 2/2 convergent (anthropic/claude-sonnet-4-5, openai/codex-default), agents/evidence/council/tdd-overlap-disposition.md."
7
+ }
8
+ ]
4
9
  }
@@ -35,6 +35,7 @@ import { fileURLToPath, pathToFileURL } from 'node:url';
35
35
  import { SRC_SKILLS } from './_lib/agent_src.js';
36
36
  import { checkRatchet } from './_lib/gate_baseline.js';
37
37
  import { DeadScopeError, assertScanned } from './_lib/scan_scope.js';
38
+ import { generatedBy } from './_lib/generated_by.js';
38
39
 
39
40
  const _HERE = fileURLToPath(import.meta.url);
40
41
 
@@ -198,7 +199,7 @@ export function _render_report(
198
199
  const lines: string[] = [
199
200
  '# User-type axis — frontmatter coverage audit',
200
201
  '',
201
- 'Generated by `scripts/audit_user_type_axis.py` (step-9 Phase 4).',
202
+ generatedBy('audit_user_type_axis', '(step-9 Phase 4.)'),
202
203
  '',
203
204
  `- Declared user-types (\`user-types/*.yml\`): **${declared.size}**`,
204
205
  `- Distinct frontmatter values across skills: **${byValue.size}**`,