@event4u/agent-config 12.1.0 → 13.0.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 (105) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +151 -0
  3. package/README.md +1 -1
  4. package/dist/agent-src/commands/cost/report.md +23 -0
  5. package/dist/agent-src/contexts/execution/subagent-routing.md +148 -33
  6. package/dist/agent-src/contexts/subagent-configuration.md +69 -7
  7. package/dist/agent-src/rules/autonomous-execution.md +1 -1
  8. package/dist/agent-src/rules/design-fidelity.md +1 -1
  9. package/dist/agent-src/rules/design-review-after-ui-write.md +10 -5
  10. package/dist/agent-src/rules/evaluator-independence.md +27 -5
  11. package/dist/agent-src/rules/git-history-discipline.md +5 -1
  12. package/dist/agent-src/rules/missing-skill-recovery.md +89 -0
  13. package/dist/agent-src/rules/ui-audit-gate.md +9 -4
  14. package/dist/agent-src/scripts/archive_completed_roadmaps.ts +33 -0
  15. package/dist/agent-src/scripts/update_roadmap_progress.ts +17 -2
  16. package/dist/agent-src/skills/authz-review/SKILL.md +4 -0
  17. package/dist/agent-src/skills/design-system-capture/SKILL.md +4 -0
  18. package/dist/agent-src/skills/design-system-capture/references/snapshot-preference-order.md +77 -0
  19. package/dist/agent-src/skills/merge-conflicts/SKILL.md +4 -0
  20. package/dist/agent-src/skills/prompt-optimizer/SKILL.md +17 -1
  21. package/dist/agent-src/skills/roadmap-writing/SKILL.md +4 -4
  22. package/dist/agent-src/skills/systematic-debugging/SKILL.md +4 -0
  23. package/dist/agent-src/skills/threat-modeling/SKILL.md +3 -0
  24. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  25. package/dist/cli-delegate/{chunk-O52B4F5S.js → chunk-3B72LSZL.js} +1 -1
  26. package/dist/cli-delegate/{chunk-55WZN5VF.js → chunk-EVTY7ISR.js} +2 -2
  27. package/dist/cli-delegate/{chunk-K34QTSD5.js → chunk-N7FEST6D.js} +17 -17
  28. package/dist/cli-delegate/{chunk-LKZ5DOYW.js → chunk-XURJ4AQC.js} +11 -3
  29. package/dist/cli-delegate/cmd_conformance.js +2 -2
  30. package/dist/cli-delegate/cmd_doctor.js +2 -2
  31. package/dist/cli-delegate/cmd_export.js +2 -2
  32. package/dist/cli-delegate/cmd_handoff.js +1 -1
  33. package/dist/cli-delegate/cmd_prune.js +2 -2
  34. package/dist/cli-delegate/cmd_settings_migrate.js +2 -2
  35. package/dist/cli-delegate/cmd_settings_set.js +1 -1
  36. package/dist/cli-delegate/cmd_sync.js +2 -2
  37. package/dist/cli-delegate/cmd_uninstall.js +2 -2
  38. package/dist/cli-delegate/cmd_validate.js +2 -2
  39. package/dist/discovery/deprecation-report.md +1 -1
  40. package/dist/discovery/discovery-manifest.json +43 -22
  41. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  42. package/dist/discovery/discovery-manifest.summary.md +3 -3
  43. package/dist/discovery/dormancy-report.md +1 -1
  44. package/dist/discovery/orphan-report.md +1 -1
  45. package/dist/discovery/packs.json +6 -5
  46. package/dist/discovery/trust-report.md +2 -2
  47. package/dist/discovery/workspaces.json +5 -4
  48. package/dist/hooks/dispatch.js +936 -346
  49. package/dist/install/install.mjs +12 -4
  50. package/dist/mcp/registry-manifest.json +3 -3
  51. package/dist/mcp/server.json +2 -2
  52. package/dist/mcp/server.mjs +1192 -160
  53. package/dist/router.json +1 -1
  54. package/dist/server/schemas/settings.js +2 -2
  55. package/dist/server/schemas/settings.js.map +1 -1
  56. package/docs/guidelines/design-fidelity-mechanics.md +21 -0
  57. package/docs/guidelines/design-handover-extraction.md +87 -0
  58. package/docs/guidelines/prompt-templates.md +24 -1
  59. package/package.json +1 -1
  60. package/src/agent-src/scripts/archive_completed_roadmaps.ts +33 -0
  61. package/src/agent-src/scripts/update_roadmap_progress.ts +17 -2
  62. package/src/config/evaluator-budgets.json +5 -4
  63. package/src/config/gate-coverage.yml +33 -11
  64. package/src/config/gate-violation-baselines.json +9 -3
  65. package/src/config/hook-token-budget.json +8 -1
  66. package/src/scripts/_lib/bench_ab_complexity.ts +439 -0
  67. package/src/scripts/_lib/bench_ab_safety_tier.ts +142 -0
  68. package/src/scripts/_lib/bench_ab_scoring_v2.ts +28 -3
  69. package/src/scripts/_lib/bench_ab_search_adherence.ts +423 -0
  70. package/src/scripts/_lib/bench_ab_size_claim.ts +206 -0
  71. package/src/scripts/_lib/bench_ab_workspace.ts +111 -0
  72. package/src/scripts/_lib/skill_catalogue.ts +258 -5
  73. package/src/scripts/_lib/tier_budget_routing.ts +31 -331
  74. package/src/scripts/ai_council/clients.ts +21 -21
  75. package/src/scripts/bench_ab_v2_complexity.ts +252 -0
  76. package/src/scripts/bench_ab_v2_run.ts +3 -42
  77. package/src/scripts/bench_ab_v2_safety.ts +296 -0
  78. package/src/scripts/bench_ab_v2_search.ts +343 -0
  79. package/src/scripts/bench_ab_v2_stats.ts +191 -0
  80. package/src/scripts/build_archive_index.ts +383 -0
  81. package/src/scripts/capture_skill_catalogue.ts +107 -2
  82. package/src/scripts/check_source_size_budget.ts +428 -0
  83. package/src/scripts/check_suppression_hygiene.ts +5 -1
  84. package/src/scripts/cost/backfill_rates.mjs +298 -0
  85. package/src/scripts/cost/budget.mjs +12 -32
  86. package/src/scripts/cost_summary.ts +25 -0
  87. package/src/scripts/external_sources_denylist.json +1 -0
  88. package/src/scripts/hook_manifest.yaml +28 -2
  89. package/src/scripts/hooks/concern_registry.ts +2 -0
  90. package/src/scripts/hooks/skill_route_hook.ts +226 -0
  91. package/src/scripts/hooks/ui_route_nudge_hook.ts +6 -3
  92. package/src/scripts/lint_design_antipattern_parity.ts +40 -6
  93. package/src/scripts/lint_harvest_provenance.ts +35 -1
  94. package/src/scripts/lint_rule_skill_pack_reach.ts +43 -0
  95. package/src/scripts/lint_skill_router_head.ts +21 -0
  96. package/src/scripts/mcp_server/consumer_tool_catalog.json +26 -3
  97. package/src/scripts/mcp_server/tool_catalog_source.ts +6 -24
  98. package/src/scripts/mcp_server/tools.ts +87 -0
  99. package/src/scripts/release.ts +5 -5
  100. package/src/scripts/routing_doctor.ts +50 -13
  101. package/src/scripts/schemas/command.schema.json +1 -1
  102. package/src/scripts/schemas/skill.schema.json +18 -1
  103. package/src/scripts/trigger_coverage.ts +224 -3
  104. package/src/server/schemas/settings.ts +2 -2
  105. package/src/config/budget-routing.json +0 -7
@@ -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": "12.1.0",
9
+ "version": "13.0.0",
10
10
  "keywords": [
11
11
  "agent-config",
12
12
  "skills",
package/CHANGELOG.md CHANGED
@@ -357,6 +357,157 @@ Entry-shape contract: [`docs/contracts/CHANGELOG-conventions.md`](docs/contracts
357
357
  > that forces a new era split (`# Era: 12.1.x`, etc.) — see
358
358
  > [`docs/contracts/CHANGELOG-conventions.md § Era splits`](docs/contracts/CHANGELOG-conventions.md).
359
359
 
360
+ ## [13.0.0](https://github.com/event4u-app/agent-config/compare/12.1.0...13.0.0) (2026-08-17)
361
+
362
+ ### Release highlights
363
+
364
+ <!-- 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. -->
365
+ - **Behaviour changes:** _auto-derived, rewrite before merge:_ rule/schema diffs, breaking commits or removed public surface in 395912e, 357fa52, f224177, 43d4e1b, 0cb9e5d, 3573525 +2 more.
366
+ - **Default changes + migration:** _none_
367
+ - **Security and correctness:** _auto-derived, rewrite before merge:_ security-scoped commits or fixes to executable surface in 184a3f1, 64e48f1, 498f174, e3ce6a5, 532c29b, d36c665 +15 more.
368
+ - **Honest nulls:** _auto-derived, rewrite before merge:_ commits recording a null, waived or falsified result in e8e6447.
369
+ - **Known limitations:** _none_
370
+
371
+ ### BREAKING CHANGES
372
+
373
+ * **council:** archive the budget-routing decision layer and permit lifecycle ([43d4e1b](https://github.com/event4u-app/agent-config/commit/43d4e1b2a83c25611e8d90c3ed28b5de13f09e29))
374
+
375
+ ### Features
376
+
377
+ * **bench:** report T5 as its own verdict in the stats layer ([538708f](https://github.com/event4u-app/agent-config/commit/538708fd063a33cc8c5fb05943335b1637a97966))
378
+ * **bench:** score T5 search adherence at the pre-registered k=2 ([5d5575e](https://github.com/event4u-app/agent-config/commit/5d5575e49c91ff5eb3bdf01e0c90542f496a9372))
379
+ * **bench:** preserve each trial's transcript beside its clone ([f487622](https://github.com/event4u-app/agent-config/commit/f487622a06ad7c2237cd2060d0135c967be65a63))
380
+ * **bench:** score T4 offline against the preserved workspaces ([ee770eb](https://github.com/event4u-app/agent-config/commit/ee770ebc129c2464a8d3f585b05131b1b1a103d5))
381
+ * **bench:** add the T4 safety tier to the v2 corpus ([6bb7561](https://github.com/event4u-app/agent-config/commit/6bb7561436ac569712c5cebfba73099998cbb37f))
382
+ * **cost:** re-price rate_missing ledger rows against the observed shape ([50b3c5d](https://github.com/event4u-app/agent-config/commit/50b3c5d2c9511ff517d7a3d2dfa189d4da45be1f))
383
+ * **bench:** offline re-scorer retro-fits the size pair onto finished sweeps ([0fd111e](https://github.com/event4u-app/agent-config/commit/0fd111ebf0b9075002e1a8d462da70fa20fe473d))
384
+ * **bench:** refuse a size win on golfing or a safety regression ([ae52635](https://github.com/event4u-app/agent-config/commit/ae52635b227e9a43e37c41edad9580fda62e91d5))
385
+ * **bench:** cognitive complexity per changed function (delta #11) ([5e6f177](https://github.com/event4u-app/agent-config/commit/5e6f177731c12be4f57efbaccf2584718cdb6201))
386
+ * **design-fidelity:** URL / live-page handover extracts into files first ([0cb9e5d](https://github.com/event4u-app/agent-config/commit/0cb9e5d8e8db5ced9b236e29f061233dbff47fc4))
387
+ * **gates:** adopt per-target completeness ledgers in four more gates ([6fc4458](https://github.com/event4u-app/agent-config/commit/6fc445804ca845778e6521a1ddec8964ed072435))
388
+ * **contracts:** declare the eight rule pairs the audit left arbitrated by nobody ([0499a0f](https://github.com/event4u-app/agent-config/commit/0499a0fe411e045c8562b94b95e2089379e4a4d1))
389
+ * **prompt-optimizer:** de-inflate a prompt before polishing it ([8e22d2b](https://github.com/event4u-app/agent-config/commit/8e22d2b4667b59232a0aa2b26de4882da27f6c74))
390
+ * **ci:** keep the archive index from going stale in the PR that stales it ([89ad466](https://github.com/event4u-app/agent-config/commit/89ad466950d818b56348bd5f49819bd0000d8ebf))
391
+ * **scripts:** index the roadmap archive, deterministically ([725e4b3](https://github.com/event4u-app/agent-config/commit/725e4b376fd5b58ef47d82da777aaa30313ee76d))
392
+ * **gates:** ratchet the excess lines over a 1,500-line source ceiling ([7e051f9](https://github.com/event4u-app/agent-config/commit/7e051f94af00b1652eabeca0064b28ef760c75db))
393
+ * **mcp:** recover what the host dropped — real ranker tool + a route to it ([866bd98](https://github.com/event4u-app/agent-config/commit/866bd9861b42db575da1869790290cf4062eadfd))
394
+ * **skills:** give skill triggers a schema, a validator, and a first tranche ([1bf6a9a](https://github.com/event4u-app/agent-config/commit/1bf6a9ab9d15909fcbd6e6dbe7f5d7e925cca18a))
395
+ * **hooks:** bind the deterministic skill ranker to user_prompt_submit ([0da18b4](https://github.com/event4u-app/agent-config/commit/0da18b48956b2374e64e88bf3159e88581403178))
396
+ * **catalogue:** report projected skill counts per projection mode ([8a6d7df](https://github.com/event4u-app/agent-config/commit/8a6d7df4ff15213a54c01f52895f5cebace78ab9))
397
+ * **routing:** bound inherit at high, cap the judge ladder, floor the split ([7863ebc](https://github.com/event4u-app/agent-config/commit/7863ebca390cfd353dabc46bebb505fabacfa435))
398
+
399
+ ### Bug Fixes
400
+
401
+ * **release:** keep release.ts off the source-size ratchet ([184a3f1](https://github.com/event4u-app/agent-config/commit/184a3f107ba24467eaf363bbfac7d02fd80152ef))
402
+ * **release:** recognise the stale-lease push rejection as a moved ref ([64e48f1](https://github.com/event4u-app/agent-config/commit/64e48f1894a6dcbbc8292207215e0145bf9bd9d5))
403
+ * **bench:** drop the own-orphans the extraction left in the runner ([498f174](https://github.com/event4u-app/agent-config/commit/498f174359e18e59f9ea98cd329ccaca329a9fbf))
404
+ * **roadmaps:** resolve the dangling risk anchor in road-to-context-fidelity ([19b653a](https://github.com/event4u-app/agent-config/commit/19b653a016f683f733ff23e4f9a2122a15dff08f))
405
+ * **bench:** pay back the source-size ratchet by extraction ([e3ce6a5](https://github.com/event4u-app/agent-config/commit/e3ce6a5539c0e47fb439e5c43a14dca40b47b923))
406
+ * **bench:** repair the nine findings the completion review raised ([532c29b](https://github.com/event4u-app/agent-config/commit/532c29b722a6b80da06c338d033100ef9894b327))
407
+ * **schemas:** the requires_confirmation descriptions carried the same claim ([395912e](https://github.com/event4u-app/agent-config/commit/395912ed6c8ec313c3a3d8c4547768f7d711d938))
408
+ * **rules:** stop certifying two hosts that never deny, and name four gap hosts ([357fa52](https://github.com/event4u-app/agent-config/commit/357fa52c740f93a26022a352dfb6a45bdac9d583))
409
+ * **contracts:** model the fourth host state — bound, and ignored ([2a30650](https://github.com/event4u-app/agent-config/commit/2a3065070281fcb3185939b182f41423a4adeb46))
410
+ * **hooks:** correct the same claim in the ui-route-nudge header ([d36c665](https://github.com/event4u-app/agent-config/commit/d36c665b5b5d6918d0200710d3df489b10084782))
411
+ * **rules:** correct the pre_tool_use coverage reason, not the count ([f224177](https://github.com/event4u-app/agent-config/commit/f224177f523b15585149fbe3524fa5ac915bebbb))
412
+ * **roadmaps:** make the feasibility-screen inputs true again ([e8e6447](https://github.com/event4u-app/agent-config/commit/e8e64471659bddd7510861d70e0bbe250a7d9ad3))
413
+ * **build:** rebuild the install bundle without the worktree symlink ([441c2d8](https://github.com/event4u-app/agent-config/commit/441c2d8edf4ed6836a483cb4c3ab15da75c0cfb1))
414
+ * **cost:** repair all seven completion-review findings ([f296b41](https://github.com/event4u-app/agent-config/commit/f296b41e477fa7c3a34bde0e03ddb7b558422d42))
415
+ * **council,roadmap:** apply the R2 fix pass on the archival ([e11b9e1](https://github.com/event4u-app/agent-config/commit/e11b9e18c2ab37d400fd2ec7c799099b6928848d))
416
+ * **ci:** green the source-size ratchet and the reference check ([b0de33a](https://github.com/event4u-app/agent-config/commit/b0de33a29a2ab4c2476545c3b44ee2ce8b91de87))
417
+ * **bench:** repair the ten completion-review findings ([4eee75f](https://github.com/event4u-app/agent-config/commit/4eee75f9c959b0c9710e37229bc41ce36640965c))
418
+ * **roadmap,council:** apply the R2 fix pass ([8d49432](https://github.com/event4u-app/agent-config/commit/8d49432a615fd5f3f67f9ef9be1f0885912739fd))
419
+ * **roadmap:** record both (b) votes, and correct three claims the last PR left stale ([4da97c5](https://github.com/event4u-app/agent-config/commit/4da97c5804f8eaf3c5f333f31e471ecc27d89356))
420
+ * **council:** correct a comment that claimed the spawn inherits the caller cwd ([f3c1509](https://github.com/event4u-app/agent-config/commit/f3c1509d1f51eb5973184313618222517a062bd7))
421
+ * **docs:** regenerate proof.md after the claims edit ([722c123](https://github.com/event4u-app/agent-config/commit/722c123a1bbdc10034aef606e14d3b48aeae9d63))
422
+ * **roadmap:** picktier-wire-or-archive is gated on infrastructure, not judgement ([4ad4701](https://github.com/event4u-app/agent-config/commit/4ad4701cb6a882bab2581c23e8c9608b13459b46))
423
+ * **claims:** the budget-routing entry described a binding that was deleted ([6712475](https://github.com/event4u-app/agent-config/commit/671247590b2a0be54f46d0d59dbb4568ea5c1798))
424
+ * **gates:** drop a bootstrap flag whose window has closed ([cfc27b4](https://github.com/event4u-app/agent-config/commit/cfc27b4303cf2cdc6c0c64b338473e7b1356f511))
425
+ * **roadmap:** stop the disposition note from naming the token it scrubbed ([e2b0858](https://github.com/event4u-app/agent-config/commit/e2b0858a45589ea887ba020030b43805fa9ba54f))
426
+ * **roadmaps:** make six held blockers decidable, and lower the ratchet to match ([9aff993](https://github.com/event4u-app/agent-config/commit/9aff993d64698754c4253f30ef98a913a7325c3b))
427
+ * **gates:** exclude declarations and tests, emit real JSON, stop swallowing reads ([09c7a84](https://github.com/event4u-app/agent-config/commit/09c7a84d680437a17a3d24fb665f236a9827e8b3))
428
+ * **roadmap:** terminate a blocker field on ANY labelled bullet, not eight names ([8216fab](https://github.com/event4u-app/agent-config/commit/8216fab38bea09dc5d3051cd454dac26ab359235))
429
+ * **ci:** pin skill-route in the worker-drop set ([179fc09](https://github.com/event4u-app/agent-config/commit/179fc09e9f8734b335aac5dc222ef243da76cef9))
430
+ * **ci:** re-point the trigger census and rebuild the install bundle ([ec7b34b](https://github.com/event4u-app/agent-config/commit/ec7b34b37649a238dca949c98bf4458c4ebca69e))
431
+ * **review:** close all 13 R2 findings ([3573525](https://github.com/event4u-app/agent-config/commit/35735256cbefccea79455a61c323cd37685920c3))
432
+ * **routing:** address all 7 R2 review findings ([aa57107](https://github.com/event4u-app/agent-config/commit/aa571070882084f8653a7cff13a0c930d7690bcf))
433
+ * **routing-doctor:** report cool-down state as unavailable, not as false ([4fed9ec](https://github.com/event4u-app/agent-config/commit/4fed9ec7b91777e198d2596d58c2868246072ac9))
434
+
435
+ ### Documentation
436
+
437
+ * **evidence:** re-bind the review after the own-orphan cleanup ([575258b](https://github.com/event4u-app/agent-config/commit/575258b6867db4670f7bbe0c0b50bb4dee664b7a))
438
+ * **roadmaps:** add road-to-release-review-p0 and regenerate the dashboard ([7ac1bfb](https://github.com/event4u-app/agent-config/commit/7ac1bfba699b53f29e151570789f29801c6b20c1))
439
+ * **roadmaps:** add road-to-metric-loop-and-review-integrity ([2bec54e](https://github.com/event4u-app/agent-config/commit/2bec54e62ddc5f4dd14d63bb749f2e1a3309d473))
440
+ * **roadmaps:** add road-to-org-telemetry ([5a8f5fd](https://github.com/event4u-app/agent-config/commit/5a8f5fdd838fb0b5c83b24fedb0b6d8f8657da71))
441
+ * **roadmaps:** add road-to-context-fidelity ([ca373a6](https://github.com/event4u-app/agent-config/commit/ca373a667f972aace506597d75667f66dba0ab70))
442
+ * **roadmaps:** add road-to-user-out-of-the-loop ([53166c7](https://github.com/event4u-app/agent-config/commit/53166c720e1c0e0c31e54a5741ac4a742f34abd6))
443
+ * **evidence:** re-bind the review after the CI repair ([71457e0](https://github.com/event4u-app/agent-config/commit/71457e0bb1fcb9ebf5eed1783f3ee87c2dde1d05))
444
+ * **evidence:** close the nine findings and re-bind the review scope ([f54a02f](https://github.com/event4u-app/agent-config/commit/f54a02f4c71aae43a24815d021e30a81ed890e71))
445
+ * **evidence:** record the R2 completion review before fixing anything ([02e7b69](https://github.com/event4u-app/agent-config/commit/02e7b697c2c3240fe1944e5625fd3bbf28f0fd4c))
446
+ * **bench:** discharge PREREG precondition 3 and close step 3.4 ([06b8e2d](https://github.com/event4u-app/agent-config/commit/06b8e2d9e68444a7f66d1218664dcaa30a4240b0))
447
+ * **evidence:** re-bind the findings after the six fixes ([81d611d](https://github.com/event4u-app/agent-config/commit/81d611d2716a0947aa74978d42300591e7410939))
448
+ * **evidence:** record the R2 findings before the fixes ([18e62fa](https://github.com/event4u-app/agent-config/commit/18e62fa49e9aa2b53f1da2c8892d7d5eddf54f78))
449
+ * **contracts:** tabulate which hosts carry pre_tool_use ([36211a9](https://github.com/event4u-app/agent-config/commit/36211a9652cabff813fc9851080a0497c14fbc7d))
450
+ * **evidence:** declare the completion-review skip for the corrections ([75c8d89](https://github.com/event4u-app/agent-config/commit/75c8d898b9187b491f16f3d756c5668d3f80194c))
451
+ * **evidence:** re-bind the completion review after the main merge ([3ce343d](https://github.com/event4u-app/agent-config/commit/3ce343dac8101e1e8d37a689296ce63820811b94))
452
+ * **evidence:** re-bind the findings after the bundle rebuild ([35a178d](https://github.com/event4u-app/agent-config/commit/35a178d6e3ef7aca8f3c4c1da0c7775918491d37))
453
+ * **evidence:** record the fix commit on each repaired finding row ([7cfc6ff](https://github.com/event4u-app/agent-config/commit/7cfc6ff2bdf274612f7ae0444229b5d6dbc6bb2c))
454
+ * **evidence:** re-bind the completion review after the seven repairs ([b043aef](https://github.com/event4u-app/agent-config/commit/b043aef11a1eb9f02f1fd4ae8cd11be0ed6a78cc))
455
+ * **evidence:** re-bind the R2 findings and record the dispositions ([80252df](https://github.com/event4u-app/agent-config/commit/80252df5e61ee215627da4a072b235126cfd336a))
456
+ * **evidence:** completion review for the ledger-truth backfill, rows open ([f1dfe04](https://github.com/event4u-app/agent-config/commit/f1dfe0404e8e70745c4df67cbe26c669a0d67c19))
457
+ * **evidence:** record the R2 findings on the archival before fixing ([f840dbc](https://github.com/event4u-app/agent-config/commit/f840dbc1ae0eca2a1e651277ca2f1e5c25821690))
458
+ * **cost:** document the re-pricing pass in the cost report command ([d7021a5](https://github.com/event4u-app/agent-config/commit/d7021a57e299e83c5763943ffe5385a915789e3c))
459
+ * **roadmap:** close ledger-truth 2.5, resolve its blocker, archive the roadmap ([8d6c8a2](https://github.com/event4u-app/agent-config/commit/8d6c8a2a6b43da0549965c4ace23e9ae7085147b))
460
+ * **evidence:** record the observed rate_missing row, and why it waited three days ([d56147c](https://github.com/event4u-app/agent-config/commit/d56147c6869c35b29be061d791cf79767a1eff64))
461
+ * **roadmap:** close 4.1 on the converged verdict ([01da09c](https://github.com/event4u-app/agent-config/commit/01da09ce167ef38af10bbe43b62e3c56c3d4f0ab))
462
+ * **evidence:** re-bind the completion review after the CI repairs ([218b6eb](https://github.com/event4u-app/agent-config/commit/218b6eb8f5b202f9ff013673a387a86aba9fd01d))
463
+ * **evidence:** re-bind the completion review, all ten rows fixed ([17a8ad0](https://github.com/event4u-app/agent-config/commit/17a8ad09c673150561ebdb72340d8e99fd382b20))
464
+ * **evidence:** completion review for the Phase-3 metric pair, rows open ([df12c39](https://github.com/event4u-app/agent-config/commit/df12c39e18630757fd34da19dbea79a17a2809b0))
465
+ * **evidence:** record the R2 findings before the fix pass ([1aae520](https://github.com/event4u-app/agent-config/commit/1aae5201e9e7b74238cf095ed026e33cf5fcd0a8))
466
+ * **roadmap:** record delta #11 and repoint five stale blocked-by annotations ([d6f5d59](https://github.com/event4u-app/agent-config/commit/d6f5d5929596ce813a4920bc78dfc95525adba0d))
467
+ * **evidence:** re-bind the completion-review skip after the main merge ([7594467](https://github.com/event4u-app/agent-config/commit/7594467ce4e38391537329c4d92696fbdf7f747b))
468
+ * **evidence:** declare the docs-only skip for this completion ([7041aae](https://github.com/event4u-app/agent-config/commit/7041aae477d9b1b051796236440a6b99263496b2))
469
+ * **evidence:** re-declare the skip after the forward-merge and index regen ([f2ffe38](https://github.com/event4u-app/agent-config/commit/f2ffe38e83d12da0a1255436f1596c33ad5b7328))
470
+ * **evidence:** re-declare the docs-only skip at the post-split scope ([90409ae](https://github.com/event4u-app/agent-config/commit/90409ae8c915a70d0d64d466bbdebff3560a036c))
471
+ * **roadmap:** close source-first Phase 4 Steps 1-2, correct a stale blocker claim ([314e3ea](https://github.com/event4u-app/agent-config/commit/314e3eaf9157ce87003c5ca5447118b756bf7e28))
472
+ * **roadmap:** close F4.1 with the re-adjudication, and correct a header that was false ([0b96569](https://github.com/event4u-app/agent-config/commit/0b9656992832fe4f7a3f87e109af26c474c0c011))
473
+ * **roadmap:** close and archive the prompt-deinflation roadmap ([a14f7be](https://github.com/event4u-app/agent-config/commit/a14f7be15d165df34bca2d3167084cb9dd84d4d7))
474
+ * **roadmap:** publish the saving reading, route the authoring surface, archive ([ee3d0ef](https://github.com/event4u-app/agent-config/commit/ee3d0efcfd851e9b45017e433961b4450bbbe4df))
475
+ * **review:** re-bind the completion review after the fix pass ([8941d59](https://github.com/event4u-app/agent-config/commit/8941d599f5351b167c93da8ecc97fd32bc10328b))
476
+ * **review:** record the R2 completion-review findings for this branch ([1e4c3a2](https://github.com/event4u-app/agent-config/commit/1e4c3a27025166026b575aee4d6ebf162c633b32))
477
+ * **review:** re-bind the findings after the originality refresh ([620613f](https://github.com/event4u-app/agent-config/commit/620613f3ba21b72f2aff1f38cc4658fe58c8ee9e))
478
+ * **review:** re-bind the findings after the worker-drop pin ([a326d59](https://github.com/event4u-app/agent-config/commit/a326d59f0234dc366b3e53ee9a3a6bbb531a5fea))
479
+ * **roadmap:** close R3 and R4, make both residual blockers decidable ([358c91d](https://github.com/event4u-app/agent-config/commit/358c91db0bd44aa0c65c9f8aad000f7e2c98f3ac))
480
+ * **skills:** record the snapshot preference order for design-system capture ([bcbb0ca](https://github.com/event4u-app/agent-config/commit/bcbb0ca8f3b81e59368fab31e07fd8963b39e0c8))
481
+ * **review:** re-bind the findings after the CI-fix commit ([cfe225c](https://github.com/event4u-app/agent-config/commit/cfe225cde464f5d67a0458b94ef3f9673c5f8155))
482
+ * **review:** re-bind the findings after the main merge ([24b0916](https://github.com/event4u-app/agent-config/commit/24b0916629169c61d053592bd24694289feccb64))
483
+ * **review:** re-bind the findings to the post-fix scope, 13/13 fixed ([871a96c](https://github.com/event4u-app/agent-config/commit/871a96c675f4de2693b6b97a520c19ff6bb9181d))
484
+ * **review:** record the R2 completion review — 13 findings ([113b9ed](https://github.com/event4u-app/agent-config/commit/113b9edfc76ec796fa4ceea6dc36ea56c6818a0e))
485
+ * **review:** re-bind the R2 findings after the fix pass ([80c994e](https://github.com/event4u-app/agent-config/commit/80c994e8c0ed491374c6bb77010a9ff845159dae))
486
+ * **review:** R2 completion review for feat-top-band-model-economy ([2f25030](https://github.com/event4u-app/agent-config/commit/2f250301491a4d3c305be148159b7803ed4ff511))
487
+ * **roadmap:** close runtime-skill-routing, 14 of 14 ([793a75e](https://github.com/event4u-app/agent-config/commit/793a75ea4af9c7ecfba08a31c3de4c1b2940b0b6))
488
+ * **roadmap:** close Phase 3 and 4.2, open the pickTier decision as a blocker ([1c078db](https://github.com/event4u-app/agent-config/commit/1c078dbbdfcd65074434707fa8cb61fee53fe05b))
489
+ * **evidence:** publish the downshift-versus-cache reading ([3a27719](https://github.com/event4u-app/agent-config/commit/3a27719964ada44c7d2744a3aa928e258f997047))
490
+
491
+ ### Refactoring
492
+
493
+ * **design-fidelity:** split the handover section out under the depth ceiling ([ee113c3](https://github.com/event4u-app/agent-config/commit/ee113c3c65d86e44bae34314f22a1eaaeabb8639))
494
+
495
+ ### Chores
496
+
497
+ * **roadmap:** regenerate dashboard after merging main ([308faf8](https://github.com/event4u-app/agent-config/commit/308faf8e960c2f9a94a345809c12e2e1698a3902))
498
+ * **evaluator:** record the 19 -> 20 mcp_public_tool_count move ([5a8a77f](https://github.com/event4u-app/agent-config/commit/5a8a77fca840e5dc4d5c35abcf9c3cb27e78b684))
499
+ * **roadmap:** regenerate the dashboard for the ledger-truth archival ([daa3d0d](https://github.com/event4u-app/agent-config/commit/daa3d0d0b633d7aba27126b7512aa9f7be520790))
500
+ * **roadmap:** regenerate the dashboard after the main merge ([8b40272](https://github.com/event4u-app/agent-config/commit/8b402725818fed47424b788de20ef9de516233a5))
501
+ * **roadmap:** regenerate the dashboard after merging main ([9d2ff18](https://github.com/event4u-app/agent-config/commit/9d2ff180612fcfec1531fe6ed7a118b0c1dbde63))
502
+ * **index:** regenerate the artefact index for the new guideline ([ce19de0](https://github.com/event4u-app/agent-config/commit/ce19de0baf25ed9982f9cdce97dc2f92a4d104fd))
503
+ * **provenance:** record the prompt-optimizer non-entry and ratchet the source ([be9b9e2](https://github.com/event4u-app/agent-config/commit/be9b9e2f68394a2cbcac2101049f0470d5a39d02))
504
+ * **reports:** refresh the originality audit for the grown corpus ([43054b8](https://github.com/event4u-app/agent-config/commit/43054b8e663d771e29dd102a41bbc639dfe194a7))
505
+ * **roadmaps:** archive the completed scheduled-deprecation roadmap ([f74cabe](https://github.com/event4u-app/agent-config/commit/f74cabe009a14e7410c70cd06a481c42be304808))
506
+ * **docs:** routed-rule count 110 -> 111 for missing-skill-recovery ([6b8a9a6](https://github.com/event4u-app/agent-config/commit/6b8a9a6726a3234a20a435bf71be9ebb942ffe70))
507
+ * **roadmaps:** archive two completed roadmaps ([5cbe55d](https://github.com/event4u-app/agent-config/commit/5cbe55d6d78d340d25752505784e945aedee15df))
508
+
509
+ Tests: 14173 (+181 since 12.1.0)
510
+
360
511
  ## [12.1.0](https://github.com/event4u-app/agent-config/compare/12.0.0...12.1.0) (2026-08-16)
361
512
 
362
513
  ### Release highlights
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  [![Smoke](https://github.com/event4u-app/agent-config/actions/workflows/smoke.yml/badge.svg)](https://github.com/event4u-app/agent-config/actions/workflows/smoke.yml) [![Public install smoke (3 OS × 2 Node)](https://github.com/event4u-app/agent-config/actions/workflows/smoke-public-install.yml/badge.svg)](https://github.com/event4u-app/agent-config/actions/workflows/smoke-public-install.yml) [![npm](https://img.shields.io/npm/v/@event4u/agent-config?style=flat-square&label=npm&color=orange)](https://www.npmjs.com/package/@event4u/agent-config) [![agent-config MCP server](https://glama.ai/mcp/servers/event4u-app/agent-config/badges/score.svg)](https://glama.ai/mcp/servers/event4u-app/agent-config) [![MCP Toplist](https://mcptoplist.com/badge/glama%2Fevent4u-app%2Fagent-config.svg)](https://mcptoplist.com/server/glama%2Fevent4u-app%2Fagent-config)
6
6
 
7
- [![Skills](https://img.shields.io/badge/Skills-289-orange?style=flat-square)](dist/agent-src/skills/) [![Rules](https://img.shields.io/badge/Rules-116-orange?style=flat-square)](dist/agent-src/rules/) [![Commands](https://img.shields.io/badge/Commands-200-orange?style=flat-square)](dist/agent-src/commands/) [![Guidelines](https://img.shields.io/badge/Guidelines-105-orange?style=flat-square)](docs/guidelines/) [![Personas](https://img.shields.io/badge/Personas-29-orange?style=flat-square)](dist/agent-src/personas/) [![Advisors](https://img.shields.io/badge/Advisors-5-orange?style=flat-square)](dist/agent-src/personas/advisors/)
7
+ [![Skills](https://img.shields.io/badge/Skills-289-orange?style=flat-square)](dist/agent-src/skills/) [![Rules](https://img.shields.io/badge/Rules-117-orange?style=flat-square)](dist/agent-src/rules/) [![Commands](https://img.shields.io/badge/Commands-200-orange?style=flat-square)](dist/agent-src/commands/) [![Guidelines](https://img.shields.io/badge/Guidelines-106-orange?style=flat-square)](docs/guidelines/) [![Personas](https://img.shields.io/badge/Personas-29-orange?style=flat-square)](dist/agent-src/personas/) [![Advisors](https://img.shields.io/badge/Advisors-5-orange?style=flat-square)](dist/agent-src/personas/advisors/)
8
8
 
9
9
  **Try it in 30 seconds** — drop one read-only subagent into any repo and watch it gate "done": `@production-validator check this branch is actually done`. No wizard, no lock-in, nothing else installed — the [30-second wedge ↓](#quickstart) is the whole first step. Start at the proof, not the catalog: **[event4u-app.github.io/agent-config/proof/](https://event4u-app.github.io/agent-config/proof/)**.
10
10
 
@@ -46,6 +46,28 @@ treated as pre-dedup.
46
46
  If `track.mjs` exits 2 with `no Claude Code project dir`, the user is not in
47
47
  a Claude Code session — surface that and stop.
48
48
 
49
+ If the run warns `rate_missing`, the session contained a model with no price
50
+ tier: those messages were costed at **$0** and the total is understated, not
51
+ cheap. Token counts are kept, so the row can be re-priced later — see step 1b.
52
+
53
+ ### 1b. Re-price an unpriced row (only when `rate_missing` fired)
54
+
55
+ ```bash
56
+ node scripts/cost/backfill_rates.mjs --rates rates.json # dry run
57
+ node scripts/cost/backfill_rates.mjs --rates rates.json --apply # write
58
+ ```
59
+
60
+ `rates.json` maps each unpriced model id to a **tier alias** (`"opus"`) or an
61
+ explicit per-1M table (`input`, `output`, `cache_write_5m`, `cache_write_1h`,
62
+ `cache_read`). The rate is the operator's to supply: the pass never guesses a
63
+ price for an id the tracker did not recognise, and rejects an unknown alias or
64
+ a missing key by name rather than defaulting one.
65
+
66
+ Dry run is the default. Ask the user for the rate — **never invent one** — and
67
+ surface both limits the pass reports: cache writes price at the 5m rate (the
68
+ row does not retain the 5m/1h split), and `byBucket` costs are not repaired
69
+ (the row carries no per-bucket-per-model tokens).
70
+
49
71
  ### 2. Check the budget
50
72
 
51
73
  ```bash
@@ -186,6 +208,7 @@ and there is no `agents/runtime/state/audit/` directory.
186
208
  (different scope: in-flight estimate, not historical actuals).
187
209
  - [`scripts/cost/track.mjs`](../../../scripts/cost/track.mjs) — tracker source.
188
210
  - [`scripts/cost/budget.mjs`](../../../scripts/cost/budget.mjs) — budget source.
211
+ - [`scripts/cost/backfill_rates.mjs`](../../../scripts/cost/backfill_rates.mjs) — re-pricing pass for `rate_missing` rows.
189
212
 
190
213
  ## Attribution
191
214
 
@@ -8,8 +8,10 @@ provider's model or billing rule.
8
8
 
9
9
  ## Inputs
10
10
 
11
- - The sub-task's declared `model_tier` (`lite | medium | high | inherit`,
12
- per [`model-recommendations`](../model-recommendations.md)).
11
+ - The sub-task's declared `model_tier` (`lite | medium | high | frontier |
12
+ inherit`, per [`model-recommendations`](../model-recommendations.md)).
13
+ `frontier` (ADR-232) is declarable and opt-in; it is never the resolution of
14
+ `inherit` — see the top-band invariant below.
13
15
  - `subagents.downshift`, `subagents.quota_arbitrage`, `subagents.model_map`
14
16
  (see [`auto-orchestration-activation`](auto-orchestration-activation.md)).
15
17
  - The host-capability manifest's `separate_quota_pool`
@@ -27,43 +29,154 @@ THE SAME MINUS THE QUOTA WIN.
27
29
  1. **Downshift off** (`downshift: false`) → every sub-task runs on the session
28
30
  tier. No routing change.
29
31
  2. **Downshift on** → a sub-task runs on its declared tier; an `inherit` task
30
- runs on the session tier. The tier resolves to a model alias via
31
- `model_map`; an empty entry means "use the tier's runtime default" — never a
32
- baked-in provider model name.
32
+ runs on the session tier, **bounded by the top-band invariant below**. The
33
+ tier resolves to a model alias via `model_map`; an empty entry means "use
34
+ the tier's runtime default" — never a baked-in provider model name.
33
35
  3. **Quota arbitrage** → prefer the **separate** quota pool for the sub-task
34
36
  **only when** `subagents.quota_arbitrage == true` **and**
35
37
  `manifest.separate_quota_pool == true`. Otherwise the shared pool is used and
36
38
  the tier/model choice is unchanged. This is the only place the
37
39
  "Sonnet-has-its-own-allowance" idea lives, and it lives as a runtime-detected
38
40
  flag, never as portable prose.
39
- 4. **Budget routing** (design:
40
- [`budget-routing` contract](../../../../docs/contracts/budget-routing.md)) →
41
- AFTER the tier resolves per 1–3, the budget relation via `pickTier`
42
- (`src/scripts/_lib/tier_budget_routing.ts`) would apply: cheapest
43
- classifier-adequate tier WITH available budget; that tier exhausted or
44
- cooling → next tier up with budget; all unavailable → session model +
45
- surfaced one-line notice. Work is never blocked to save money. Before
46
- the dispatch is created, acquire the atomic reserve
47
- (`acquireBudgetPermit`; check state via `node src/scripts/cost/budget.mjs
48
- tier <t>`); a 429/quota error trips `tripCooldown` for that tier and
49
- falls back per the relation — never a retry loop.
50
- `subagents.budget_routing` was removed as a settings key (always-on
51
- orchestration, road-to-always-on-orchestration Phase 1: no per-layer
52
- on/off switch survives) — `pickTier` has NO production caller today, so
53
- this point documents the DESIGNED relation, not a currently wired one;
54
- wiring it is a later phase of that roadmap (council-side
55
- `cli_call_budget`/`cost_budget` are the caps that replace the settings
56
- gate). Every budget-routed dispatch, once wired, would emit one
57
- `orchestration_record` line (tier + provenance-tagged token delta) so
58
- realized savings are measured, not asserted.
41
+ 4. **Budget routing — ARCHIVED 2026-08-16, there is no fourth step.** This
42
+ position used to describe a budget relation applied after the tier resolves
43
+ per 1–3: cheapest classifier-adequate tier WITH available budget, an atomic
44
+ pre-dispatch reserve, a cool-down on quota errors. None of it exists any
45
+ more. A converged AI-council verdict (anthropic + openai, 2 of 2) archived
46
+ `pickTier` and the permit lifecycle, because the `routing_switch` they
47
+ required lost its only source when `subagents.budget_routing` was deliberately
48
+ deleted by always-on orchestration — so wiring meant inventing a replacement
49
+ for a removed category — and because `session_tier` sits non-null in 0 of 327
50
+ records, leaving the saving unmeasurable in principle. Migration record and
51
+ the union revisit-if:
52
+ [`budget-routing` contract](../../../../docs/contracts/budget-routing.md).
53
+ **Tier resolution therefore ends at step 3.** What survives of the module is
54
+ `TIER_ORDER` and `readCooldowns`, read by `routing:doctor` as a diagnostic —
55
+ monitoring, not routing, and note that nothing writes the cool-down file any
56
+ more, which is why the doctor reports that state as *unavailable, no
57
+ producer* rather than as a measured "not cooling".
58
+
59
+ ### The top-band invariant (binding)
60
+
61
+ ```
62
+ UNDER A TOP-BAND SESSION, `inherit` RESOLVES TO AT MOST `high`.
63
+ A SLICE THAT GENUINELY NEEDS THE SESSION'S OWN BAND DECLARES IT.
64
+ ONE TOP-BAND CONTEXT PER TASK — THE ORCHESTRATOR'S. NEVER A SECOND BY DEFAULT.
65
+ ```
66
+
67
+ Read as one line: an undeclared slice under a top-band session runs at most
68
+ `high`, never the session's own band.
69
+
70
+ `inherit` means *model-agnostic*, not *whatever the session happens to cost*.
71
+ Left unbounded it is the one declaration that silently buys the most expensive
72
+ band available, for exactly the slices whose authors judged the model choice
73
+ not to matter — the weakest possible reason to spend the most.
74
+
75
+ **The clamp is `high`, not the top mapped tier, and the distinction is not
76
+ cosmetic.** ADR-232 added `frontier` to the tier→model map, so the top *mapped*
77
+ rung is now `frontier`; clamping there would clamp nothing. The bound is the
78
+ top **generally-recommended** band, which is what
79
+ [`model-recommendations`](../model-recommendations.md) already states from the
80
+ other side — its `frontier` row reads *"Never the resolution of `inherit`"*.
81
+ This clause is that same rule written where the resolution actually happens.
82
+
83
+ Consequences, stated so the cost stays visible rather than removed:
84
+
85
+ - A slice that needs `frontier` **declares `model_tier: frontier`** — a value
86
+ § Inputs above lists as declarable, precisely so this escape hatch is legal
87
+ rather than instructed-but-forbidden. The declaration is the whole point:
88
+ the spend becomes an authored decision with a name on it instead of a
89
+ default nobody chose.
90
+ - The clamp changes only the **undeclared** case. Every explicit
91
+ `model_tier:` is honoured verbatim, upward included.
92
+ - A session running *below* `high` is untouched — `inherit` still resolves to
93
+ the session tier. "At most" is a ceiling, never a floor, and this clause
94
+ never promotes a slice.
95
+ - A **declared `frontier` implementer** keeps its band, and its judge is
96
+ governed by [`subagent-configuration`](../subagent-configuration.md)
97
+ § The judge cap — which handles that case explicitly rather than leaving
98
+ the reviewer weaker than the author.
99
+
100
+ **Honest scope.** This is a policy clause in a context file, so it binds the
101
+ agent that reads it and nothing else; no gate re-derives an `inherit`
102
+ resolution at dispatch time. `enforced_by: none`, deliberately — the same
103
+ boundary the safety-floor rules state for their own obligations.
104
+
105
+ ### The non-escalation floor (binding)
106
+
107
+ ```
108
+ A SLICE WHOSE DISPATCH OVERHEAD EXCEEDS THE SAVING FROM DOWNSHIFTING
109
+ STAYS IN-SESSION. SPLITTING WORK WHOSE OVERHEAD EATS ITS OWN SAVING
110
+ IS THE ANTI-GOAL, NOT THE MECHANISM WORKING.
111
+ ```
112
+
113
+ Every dispatch pays a fixed cost the in-session path does not: the slice's
114
+ prompt is re-sent to a fresh context, the return is read back, and the
115
+ orchestrator verifies it. Below some slice size that overhead exceeds
116
+ whatever the cheaper tier saved, and the delegation is a net loss dressed as
117
+ an optimisation.
118
+
119
+ **The floor is a rule, not a number — and the reason is measured, not
120
+ assumed.** The step that authored this clause expected the same-band spawn
121
+ distribution to supply the number. It cannot, and the corpus says so
122
+ precisely. Over the full 327-record `orchestration` corpus (2026-07 plus
123
+ 2026-08):
124
+
125
+ | Field the saving model needs | Non-null records |
126
+ |---|---:|
127
+ | `dispatch_tokens` | 40 |
128
+ | `tier_chosen` | 1 |
129
+ | `session_tier` | **0** |
130
+
131
+ The three must co-occur on one dispatch to model a reduction, so the usable
132
+ intersection is **zero**. This is not a small sample — it is an empty one, and
133
+ `orchestration_savings_report.ts` already prints exactly that conclusion
134
+ (`MODELED cost reduction: n/a (needs dispatch_tokens + session_tier +
135
+ tier_chosen on a dispatch)`). `token_delta` does not rescue it: the hook
136
+ writes it as a constant `0` with provenance `estimated`, deliberately, because
137
+ no in-session counterfactual exists on disk to difference against.
138
+
139
+ So the floor binds as a judgement with a named direction rather than a
140
+ threshold:
141
+
142
+ - **Default to in-session** when the slice is small enough that stating it
143
+ costs about as much as doing it — a single-file edit, one grep, one
144
+ question with a known answer.
145
+ - **Delegate** when the slice carries its own reading (a file set to sweep, an
146
+ independent verification, a search whose output you do not want in context)
147
+ — there the returned conclusion is the saving, and it is not in tokens.
148
+ - **Never delegate to hit a target.** A dispatch count is not an outcome.
149
+
150
+ *Revisit-if:* a single dispatch record carries `dispatch_tokens`,
151
+ `session_tier` and `tier_chosen` together. At that point the floor is
152
+ computable and this clause should be replaced by the number, not amended
153
+ toward it. Filling `session_tier` is the blocking gap — it exists in the
154
+ schema and on the manual `orchestration_record` CLI path (`--session-tier`),
155
+ and the hook that produced all 327 records never sets it.
59
156
 
60
157
  **Cache trade-off (road-to-cache-economy Phase 4).** A tier downshift changes
61
- the sub-task's model, and the prompt cache is keyed by `(model, prefix)` — so
62
- a downshifted leg forfeits its model-scoped cache reads AND splits a cohort's
63
- shared prefix into two caches (downshifted legs vs. session-tier legs). The
64
- per-call model saving and the forfeited cache-read saving pull in opposite
65
- directions; which wins is a measured question, not a default this policy
66
- resolves — see
158
+ the sub-task's model, and the prompt cache is keyed by `(model, prefix)`. The
159
+ concern was that a downshifted leg forfeits its model-scoped cache reads AND
160
+ splits a cohort's shared prefix into two caches (downshifted legs vs.
161
+ session-tier legs).
162
+
163
+ **Measured 2026-08-16 —
164
+ [`downshift-vs-cache.md`](../../../../agents/evidence/analysis/downshift-vs-cache.md),
165
+ 611 subagent legs / 16,612 calls.** The first half does not hold: a subagent
166
+ leg's **first call realizes 2.8 % cache read**, so it starts cold and does not
167
+ inherit the session's cache — a downshift forfeits a cache the leg never had.
168
+ The cache is not lost, it is created on the other model and then read for the
169
+ rest of the leg (median 18 calls per leg, ~96.9 % read share). The second half
170
+ is **not measured** — nothing sizes cohort prefix sharing — but it is bounded
171
+ above: prefix splitting is a write-side cost, and writes are **3.1 %** of
172
+ subagent billable input against a 96.9 % read surface. Even attributing every
173
+ write to splitting, the two sit about an order of magnitude apart, in favour of
174
+ the downshift, so the direction does not depend on the unmeasured fraction.
175
+
176
+ This resolves the direction; it does not license downshifting as a target. The
177
+ cold start is paid per leg regardless of tier, which is precisely what the
178
+ non-escalation floor above bounds. Analogous downgrade/cache coupling on the
179
+ council side: see
67
180
  [`docs/contracts/ai-council-config.md`](../../../../docs/contracts/ai-council-config.md)
68
181
  § `model_downgrade` for the analogous downgrade/cache coupling this suite
69
182
  already ships on the council side.
@@ -80,8 +193,10 @@ rule, or context asserts "model X is free".
80
193
  [`src/scripts/_lib/subagent_routing.ts`](../../../../src/scripts/_lib/subagent_routing.ts)
81
194
  (`resolveSubagentRouting`), covered by
82
195
  [`tests/scripts/_lib_subagent_routing.test.ts`](../../../../tests/scripts/_lib_subagent_routing.test.ts).
83
- Budget layer: [`src/scripts/_lib/tier_budget_routing.ts`](../../../../src/scripts/_lib/tier_budget_routing.ts)
84
- (`pickTier`, `acquireBudgetPermit`, cool-downs), covered by
196
+ Tier vocabulary + cool-down state:
197
+ [`src/scripts/_lib/tier_budget_routing.ts`](../../../../src/scripts/_lib/tier_budget_routing.ts)
198
+ (`TIER_ORDER`, `readCooldowns` — the budget decision layer that used to live
199
+ there is archived, see step 4), covered by
85
200
  [`tests/scripts/tier_budget_routing.test.ts`](../../../../tests/scripts/tier_budget_routing.test.ts);
86
201
  live state: `agent-config routing:doctor` (orchestration section).
87
202
 
@@ -15,21 +15,83 @@ Loaded by the `subagent-orchestration` skill and the `/do-and-judge`,
15
15
  ## Model tier ladder
16
16
 
17
17
  The "one tier up" fallback walks this ladder. Session model is the
18
- starting point; judge picks the tier above.
18
+ starting point; judge picks the tier above. The ladder is written in
19
+ **bands**, not vendor models — the package keeps exactly one tier→model
20
+ mapping and it lives in
21
+ [`model-recommendations`](model-recommendations.md) (ADR-035 § 3). A
22
+ second per-vendor ladder here would be the two-clocks drift ADR-232 was
23
+ careful not to create.
19
24
 
20
25
  ```
21
- haiku → sonnet → opus
26
+ lite → medium → high
22
27
  ```
23
28
 
24
- If the session runs on **opus**, judge stays on opus (no higher tier
25
- available). If the session runs on **sonnet**, judge defaults to opus.
26
- If the session runs on **haiku**, judge defaults to sonnet.
29
+ If the session runs at **`high`**, judge stays at `high`. If the session
30
+ runs at **`medium`**, judge defaults to `high`. If the session runs at
31
+ **`lite`**, judge defaults to `medium`.
32
+
33
+ ### The judge cap (binding)
34
+
35
+ ```
36
+ THE ONE-TIER-UP ESCALATION STOPS AT `high` — IT NEVER CLIMBS INTO `frontier`.
37
+ A JUDGE IS NEVER BELOW ITS OWN IMPLEMENTER: A DECLARED `frontier`
38
+ IMPLEMENTER KEEPS A `frontier` JUDGE.
39
+ A SATURATED LADDER ESCALATES CROSS-VENDOR VIA THE COUNCIL —
40
+ NEVER INTO A SECOND SAME-VENDOR TOP-BAND AGENT.
41
+ ```
42
+
43
+ Two clauses that are easy to collapse into one and must not be. The cap
44
+ binds the **escalation**, not the floor:
45
+
46
+ | Implementer band | Judge band | Why |
47
+ |---|---|---|
48
+ | `lite` | `medium` | one tier up |
49
+ | `medium` | `high` | one tier up |
50
+ | `high` | `high` | escalation capped — never climbs into `frontier` |
51
+ | `frontier` | **`frontier`** | the floor wins: a judge is never below its author |
52
+
53
+ `frontier` (ADR-232) sits above `high` in the vocabulary, so a naive
54
+ "one tier up" would resolve a `high` implementer's judge to `frontier`
55
+ and buy the most expensive band available for every verification pass.
56
+ The cap forecloses that — `frontier` is opt-in by declaration only.
57
+
58
+ **But the cap must not invert the ladder it protects.** Reading it as a
59
+ flat ceiling would give a declared `frontier` implementer a `high`
60
+ judge, i.e. a reviewer strictly *weaker* than the author — worse than
61
+ the same-band case the one-tier-up rule exists to avoid, and a direct
62
+ contradiction of "never downshifts its judge below what the verify
63
+ contract requires" below. So `frontier` reaches the judge only where
64
+ the implementer already declared it, never by escalation from `high`.
65
+
66
+ **What to do when the ladder saturates.** At `high` and at `frontier`
67
+ the judge is same-band — the reviewer is no stronger than the author,
68
+ which is the condition the one-tier-up rule existed to avoid. The
69
+ answer is *different vendor*, not *bigger model*:
70
+
71
+ - Route the saturation case through
72
+ [`ai-council`](../skills/ai-council/SKILL.md), which polls models
73
+ outside the host session (Anthropic + OpenAI) and is therefore
74
+ genuinely independent of the implementer's framing.
75
+ - This is the escalation **instead of** a second top-band context, not
76
+ in addition to one. Two same-vendor top-band agents on one task cost
77
+ twice and correlate their blind spots; a second vendor costs less and
78
+ disagrees for real reasons.
79
+ - Cost boundary unchanged: the council is a network call and is
80
+ therefore never automatic. It is what the saturation case escalates
81
+ *to* when a second opinion is wanted, not a step every `high` task
82
+ takes ([`ai-council`](../skills/ai-council/SKILL.md) § Do NOT use).
83
+
84
+ **Honest scope.** This is policy prose in a context file — it binds the
85
+ agent that reads it and no gate re-derives a judge tier at dispatch
86
+ time. `enforced_by: none`, stated rather than implied.
27
87
 
28
88
  **Downshift never touches the judge.** When cost-aware routing runs an
29
89
  implementer on a downshifted tier (per the category → tier defaults in
30
90
  [`model-recommendations § Subagent Category → Tier Defaults`](model-recommendations.md)),
31
- the judge still resolves one tier above the IMPLEMENTER's resolved tier —
32
- so a `lite` implementer gets at least a `medium` judge. Downshifting an
91
+ the judge still resolves one tier above the IMPLEMENTER's resolved tier,
92
+ **with the escalation capped at `high` per the judge cap above** — so a
93
+ `lite` implementer gets at least a `medium` judge, and no *downshifted*
94
+ implementer escalates its judge into `frontier`. Downshifting an
33
95
  implementer never downshifts its judge below what the verify contract
34
96
  requires, and a judge is never `lite`.
35
97
 
@@ -67,7 +67,7 @@ ALLOWLIST > 20 ENTRIES IN ONE SESSION = THE LINTER IS WRONG.
67
67
  STOP. PROPOSE LINTER REDESIGN OR REMOVAL. DO NOT EXPAND THE ALLOWLIST FURTHER.
68
68
  ```
69
69
 
70
- Crossing 20 entries counts as the 3rd validation-target failure — fix the tool shape, not the list. Enforced at tool-call time by the `block-config-weakening` PreToolUse guard (`src/scripts/hooks/block_config_weakening.ts`) **on the three hosts that have a `pre_tool_use` slot at all** — augment, claude, cowork: it counts allowlist entries added per session, warns from 5, and blocks past 20. On cursor, cline, windsurf, gemini and copilot the guard has nowhere to bind, so there the cap is model-carried and "enforced at tool-call time" is not a claim this rule can make. Run `agent-config hooks:status` to see which slots are bound on the host you are actually on — the sibling rules `git-history-discipline` and `evaluator-independence` qualify the identical slot, and an unqualified claim here would read as a guarantee the manifest does not give. Baselines and budget thresholds warn only — a rising count there may be a legitimate ratchet reset, which the edit alone cannot distinguish. Verify with the narrowest tool that proves the target green (a single `curl` / Playwright spec for HTTP/UI, the test runner with a `--filter`, an `xdebug` step-through) — never a meta-pipeline as per-iteration probe. Failed-attempt detail, suppression-sweep equivalents, probe-efficiency detail, and adaptive effort & stop (RDP): [`autonomy-mechanics § Validation-loop budget`](../contexts/execution/autonomy-mechanics.md).
70
+ Crossing 20 entries counts as the 3rd validation-target failure — fix the tool shape, not the list. Enforced at tool-call time by the `block-config-weakening` PreToolUse guard (`src/scripts/hooks/block_config_weakening.ts`) **on `claude`, the one host that both binds `pre_tool_use` and honours a deny**: it counts allowlist entries added per session, warns from 5, and blocks past 20. It is *bound* on augment and cowork as well, and ignored there — `host_semantics.ts` verifies claude alone, and both trampolines discard dispatcher output and `exit 0` unconditionally. Everywhere else the cap is model-carried and "enforced at tool-call time" is not a claim this rule can make. **Corrected 2026-08-17 in both directions:** this sentence used to certify augment, claude and cowork as the enforcing set (an over-claim of two hosts) and to explain the rest with "the guard has nowhere to bind" (false for cursor, cline and gemini, whose native pre-tool events `native_event_aliases` already maps onto `pre_tool_use` — unbound, not unbindable; only windsurf and copilot have no pre-tool surface). The four states are tabulated once in [`hook-architecture-v1 § Which hosts carry pre_tool_use`](../docs/contracts/hook-architecture-v1.md). Run `agent-config hooks:status` to see which slots are bound on the host you are actually on — the sibling rules `git-history-discipline` and `evaluator-independence` qualify the identical slot, and an unqualified claim here would read as a guarantee the manifest does not give. Baselines and budget thresholds warn only — a rising count there may be a legitimate ratchet reset, which the edit alone cannot distinguish. Verify with the narrowest tool that proves the target green (a single `curl` / Playwright spec for HTTP/UI, the test runner with a `--filter`, an `xdebug` step-through) — never a meta-pipeline as per-iteration probe. Failed-attempt detail, suppression-sweep equivalents, probe-efficiency detail, and adaptive effort & stop (RDP): [`autonomy-mechanics § Validation-loop budget`](../contexts/execution/autonomy-mechanics.md).
71
71
 
72
72
  Body migrated to `contexts/execution/autonomy-mechanics.md` (per P4 of `road-to-kernel-and-router.md`) — opt-in detection summary, task-scope shapes table, N=3 mechanics, allowlist-antipattern detail, probe efficiency, adaptive effort (RDP).
73
73
  Trigger-set above activates this routing on demand, independent of the discipline profile (ADR-110).
@@ -171,7 +171,7 @@ introduced. The row that would have caught it is
171
171
  and it exists only because a review asked for it after the trigger had already
172
172
  shipped. Write that row first next time; it is the cheap half.
173
173
 
174
- Body migrated to [`guideline:design-fidelity-mechanics`](../docs/guidelines/design-fidelity-mechanics.md) (per P4 of `road-to-kernel-and-router.md`) — surgical visual edits (targeted-edit vs redesign-trigger discipline, stable anchors), asset & imagery discipline (owned-asset path, third-party delivery is self-hosted by default, real-imagery-as-proof, iconography floor, no unrequested filler), deviation-surfacing shape, failure-mode catalog, `daf-*` fixtures.
174
+ Body migrated to [`guideline:design-fidelity-mechanics`](../docs/guidelines/design-fidelity-mechanics.md) (per P4 of `road-to-kernel-and-router.md`) — URL / live-page handover (extraction into the `design-system.json` contract before the first UI write, the retrieval order, the lock boundary), surgical visual edits (targeted-edit vs redesign-trigger discipline, stable anchors), asset & imagery discipline (owned-asset path, third-party delivery is self-hosted by default, real-imagery-as-proof, iconography floor, no unrequested filler), deviation-surfacing shape, failure-mode catalog, `daf-*` fixtures.
175
175
  Trigger-set above activates this routing on demand, independent of the discipline profile (ADR-110).
176
176
 
177
177
  ## See also
@@ -114,11 +114,16 @@ still have no runtime consumer. A test — not a code path — keeps the two fro
114
114
  drifting: `ui_rule_triggers.test.ts` asserts every `file_pattern` declared here
115
115
  is accepted by that predicate.
116
116
 
117
- Warn-only, capped at two nudges per session, default-OFF, bound only on hosts
118
- carrying a `pre_tool_use` slot. A nudge that can be ignored is not enforcement,
119
- so `enforced_by:` stays `none` — it moves the day a mechanism can refuse, not
120
- the day a reminder appears. `agent-config hooks:status` answers whether the
121
- concern is bound on the host you are actually on.
117
+ Warn-only, capped at two nudges per session, default-OFF, and bound only in the
118
+ three `platforms:` rows that carry a `pre_tool_use` key — augment, claude,
119
+ cowork (**clarified 2026-08-17**: "hosts carrying a slot" read as a host
120
+ property and is a manifest one; three further hosts alias a native pre-tool
121
+ event with no binding, and only claude honours a deny — see
122
+ [`hook-architecture-v1 § Which hosts carry pre_tool_use`](../docs/contracts/hook-architecture-v1.md)).
123
+ The verdict is unchanged either way: a nudge that can be ignored is not
124
+ enforcement, so `enforced_by:` stays `none` — it moves the day a mechanism can
125
+ refuse, not the day a reminder appears. `agent-config hooks:status` answers
126
+ whether the concern is bound on the host you are actually on.
122
127
 
123
128
  What that leaves, and it is the useful part: the write side now has a named
124
129
  obligation and a route to the skill that discharges it, where before it had