@event4u/agent-config 9.31.0 → 9.33.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.
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +146 -0
- package/dist/agent-src/commands/review/routing.md +3 -4
- package/dist/agent-src/contexts/communication/rules-auto/reply-close-mechanics.md +65 -0
- package/dist/agent-src/contexts/execution/host-capability-manifest.md +32 -1
- package/dist/agent-src/contexts/execution/orchestration-telemetry.md +3 -0
- package/dist/agent-src/rules/delegation-policy.md +17 -1
- package/dist/agent-src/scripts/roadmap_gates.ts +107 -3
- package/dist/agent-src/skills/docker/SKILL.md +11 -0
- package/dist/agent-src/skills/laravel/SKILL.md +11 -0
- package/dist/agent-src/skills/review-routing/SKILL.md +23 -6
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/scripts/ownership-map.example.yml +1 -1
- package/dist/agent-src/templates/scripts/work_engine/delivery_state.ts +6 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +332 -0
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/refine.ts +106 -1
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/test.ts +50 -15
- package/dist/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +49 -15
- package/dist/agent-src/templates/scripts/work_engine/state.ts +74 -0
- package/dist/agent-src/templates/scripts/work_engine/state_io.ts +6 -0
- package/dist/cli/registry.js +4 -4
- package/dist/cli/registry.js.map +1 -1
- package/dist/cli-delegate/chunk-2WELHO3P.js +582 -0
- package/dist/cli-delegate/chunk-HTIU3W56.js +66 -0
- package/dist/cli-delegate/{chunk-ITIQSGOQ.js → chunk-MA4GFWDY.js} +7 -4
- package/dist/cli-delegate/{chunk-2WCLVDWC.js → chunk-PMQ6Z3T3.js} +1642 -165
- package/dist/cli-delegate/chunk-PZWRPRWP.js +38 -0
- package/dist/cli-delegate/{chunk-PFBV6XRT.js → chunk-Q26HT4QT.js} +1 -63
- package/dist/cli-delegate/{chunk-LVRYBKTI.js → chunk-YPAWXXXR.js} +158 -0
- package/dist/cli-delegate/cmd_conformance.js +308 -227
- package/dist/cli-delegate/cmd_doctor.js +4 -2
- package/dist/cli-delegate/cmd_export.js +1 -1
- package/dist/cli-delegate/cmd_handoff.js +160 -58
- package/dist/cli-delegate/cmd_prune.js +1 -1
- package/dist/cli-delegate/cmd_session_recycle.js +30 -5
- package/dist/cli-delegate/cmd_settings_get.js +4 -2
- package/dist/cli-delegate/cmd_settings_migrate.js +1 -1
- package/dist/cli-delegate/cmd_settings_set.js +5 -3
- package/dist/cli-delegate/cmd_sync.js +1 -1
- package/dist/cli-delegate/cmd_uninstall.js +1 -1
- package/dist/cli-delegate/cmd_validate.js +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +8 -8
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +1 -1
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +2 -2
- package/dist/discovery/trust-report.md +1 -1
- package/dist/discovery/workspaces.json +2 -2
- package/dist/hooks/dispatch.js +1136 -690
- package/dist/install/install.mjs +7 -4
- package/dist/mcp/registry-manifest.json +2 -2
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +3688 -1159
- package/package.json +1 -1
- package/src/agent-src/scripts/roadmap_gates.ts +107 -3
- package/src/agent-src/templates/scripts/ownership-map.example.yml +1 -1
- package/src/agent-src/templates/scripts/work_engine/delivery_state.ts +6 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +332 -0
- package/src/agent-src/templates/scripts/work_engine/directives/backend/refine.ts +106 -1
- package/src/agent-src/templates/scripts/work_engine/directives/backend/test.ts +50 -15
- package/src/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +49 -15
- package/src/agent-src/templates/scripts/work_engine/state.ts +74 -0
- package/src/agent-src/templates/scripts/work_engine/state_io.ts +6 -0
- package/src/config/cost-parity-budget.json +167 -0
- package/src/config/gate-coverage.yml +44 -5
- package/src/config/quorum-attendance-budget.json +39 -0
- package/src/scripts/_cli/cmd_doctor.ts +69 -1
- package/src/scripts/_cli/cmd_session_recycle.ts +44 -3
- package/src/scripts/_cli/handoff_generate.ts +36 -1
- package/src/scripts/_cli/handoff_sessions.ts +140 -9
- package/src/scripts/_dispatch.bash +5 -3
- package/src/scripts/_lib/carrier_divergence.ts +98 -27
- package/src/scripts/_lib/envelope_grounding.ts +206 -0
- package/src/scripts/_lib/host_capability.ts +79 -0
- package/src/scripts/_lib/orchestration_record.ts +45 -0
- package/src/scripts/_lib/session_eol.ts +85 -0
- package/src/scripts/_lib/subagent_capsule.ts +256 -1
- package/src/scripts/ai_council/clients.ts +31 -0
- package/src/scripts/ai_council/events_log.ts +128 -6
- package/src/scripts/ai_council/orchestrator.ts +12 -3
- package/src/scripts/ai_council/pricing.ts +48 -1
- package/src/scripts/ai_council/quorum.ts +20 -0
- package/src/scripts/ai_council/session.ts +11 -0
- package/src/scripts/ask_transport.ts +20 -1
- package/src/scripts/cache_realization_report.ts +38 -0
- package/src/scripts/check_release_highlights.ts +7 -1
- package/src/scripts/check_secret_leak.test.ts +43 -0
- package/src/scripts/check_secret_leak.ts +12 -0
- package/src/scripts/conformance_scan.ts +105 -0
- package/src/scripts/cost/track.mjs +39 -0
- package/src/scripts/cost_summary.ts +104 -1
- package/src/scripts/council_cli.ts +131 -13
- package/src/scripts/dispatch_economy_report.ts +5 -2
- package/src/scripts/handoff_context_hook.ts +66 -18
- package/src/scripts/hooks/session_eol_hook.ts +12 -12
- package/src/scripts/install.ts +20 -6
- package/src/scripts/lint_budget_ownership.ts +81 -0
- package/src/scripts/lint_skill_frontmatter_safety.ts +55 -1
- package/src/scripts/lint_workflow_paths.ts +384 -0
- package/src/scripts/preamble_byte_census.ts +9 -1
- package/src/scripts/report_carrier_divergence.ts +104 -29
- package/src/scripts/report_conformance_funnel.ts +51 -4
- package/src/scripts/routing_doctor.ts +25 -2
- package/src/scripts/schemas/dod.schema.json +45 -0
- package/src/scripts/schemas/subagent.schema.json +3 -2
- package/dist/cli-delegate/chunk-RVGBH4XK.js +0 -142
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "Bootstrap shim for the event4u agent-config suite. This plugin ships ONLY the dispatcher hooks plus one install-pointer skill — ALL content (skills, rules, commands) is installed via `npx -y @event4u/agent-config init`, which writes the file projection AND registers the same hooks in ~/.claude/settings.json. DEPRECATED as a content channel; kept so the marketplace listing stays discoverable and existing installs keep working hooks.",
|
|
9
|
-
"version": "9.
|
|
9
|
+
"version": "9.33.0",
|
|
10
10
|
"keywords": [
|
|
11
11
|
"agent-config",
|
|
12
12
|
"skills",
|
package/CHANGELOG.md
CHANGED
|
@@ -321,6 +321,152 @@ Entry-shape contract: [`docs/contracts/CHANGELOG-conventions.md`](docs/contracts
|
|
|
321
321
|
> that forces a new era split (`# Era: 9.32.x`, etc.) — see
|
|
322
322
|
> [`docs/contracts/CHANGELOG-conventions.md § Era splits`](docs/contracts/CHANGELOG-conventions.md).
|
|
323
323
|
|
|
324
|
+
## [9.33.0](https://github.com/event4u-app/agent-config/compare/9.32.0...9.33.0) (2026-08-11)
|
|
325
|
+
|
|
326
|
+
### Release highlights
|
|
327
|
+
|
|
328
|
+
<!-- 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. -->
|
|
329
|
+
- **Behaviour changes:** _auto-derived, rewrite before merge:_ rule/schema diffs, breaking commits or removed public surface in e625e69, 9ec8042.
|
|
330
|
+
- **Default changes + migration:** _auto-derived, rewrite before merge:_ commits naming a default, migration or migrate in 2588c5b.
|
|
331
|
+
- **Security and correctness:** _auto-derived, rewrite before merge:_ security-scoped commits in b17d1f3.
|
|
332
|
+
- **Honest nulls:** _auto-derived, rewrite before merge:_ commits carrying an honest-null marker in 9e999d6, b86a4a9.
|
|
333
|
+
- **Known limitations:** _none_
|
|
334
|
+
|
|
335
|
+
### Features
|
|
336
|
+
|
|
337
|
+
* **gates:** add --reply, the reply-close projection over open blockers ([dd88d21](https://github.com/event4u-app/agent-config/commit/dd88d2116dcc73a1351e292047c0b22a8f84fdd7))
|
|
338
|
+
* **funnel:** the missing Opportunity stage ([ca5aabd](https://github.com/event4u-app/agent-config/commit/ca5aabd834db73755f2a6eba8efa5dc2edd2bb1b))
|
|
339
|
+
* **recycle:** --verify validates without writing, plus an envelope mutation suite ([a9ad7d8](https://github.com/event4u-app/agent-config/commit/a9ad7d88ea214f2eb9dd12e406f93e9cbfb7bc17))
|
|
340
|
+
* **conformance:** --why <id> traces one conformance check ([807a85c](https://github.com/event4u-app/agent-config/commit/807a85caed1a7b79499f1071d4202ed17142b6e2))
|
|
341
|
+
* **doctor:** --anatomy renders the injection anatomy from existing measurements ([6ed0aac](https://github.com/event4u-app/agent-config/commit/6ed0aac994ef14b42d5e65bd86a5c4734648cceb))
|
|
342
|
+
* **cost-summary:** report what caching bought, when spend happened, and where input went ([3dbc570](https://github.com/event4u-app/agent-config/commit/3dbc57082506a00a51dca76fdb06610e720a754d))
|
|
343
|
+
* **cost-ledger:** record the model that actually answered, not the one asked for ([8b79067](https://github.com/event4u-app/agent-config/commit/8b790671bb780629fd30a06a47dacf957da93c3d))
|
|
344
|
+
* **council:** mark a solo-concluded pass in the rendered quorum line ([b6a90ab](https://github.com/event4u-app/agent-config/commit/b6a90ab405a2d0a5bdee655f8fa34f45b3ae4d74))
|
|
345
|
+
* **ci:** resolve workflow path filters against the tree, and repair 20 dead ones ([77f200f](https://github.com/event4u-app/agent-config/commit/77f200f0885d5ac6b28c9d5b98d737665d847954))
|
|
346
|
+
* **council:** make a solo-concluded quorum distinguishable in the event log ([5addcd0](https://github.com/event4u-app/agent-config/commit/5addcd0a9bee200ec2fbc529a6365254c397e68f))
|
|
347
|
+
* **budget:** register the three attendance metrics before any data exists ([b6bf44d](https://github.com/event4u-app/agent-config/commit/b6bf44dd799c2854e7caa576ca3cd2d29889f560))
|
|
348
|
+
* **council:** make a solo-concluded pass visible in the event log ([ec8ede6](https://github.com/event4u-app/agent-config/commit/ec8ede6ec50b8aa5e9daecfcc35c26486ad1bb14))
|
|
349
|
+
* **budget:** the cost-parity target table, with a gate that refuses an untraceable number ([b86a4a9](https://github.com/event4u-app/agent-config/commit/b86a4a9d4efc2ab1dff74ba56724b07061850b8e))
|
|
350
|
+
|
|
351
|
+
### Bug Fixes
|
|
352
|
+
|
|
353
|
+
* **cost-ledger:** repair the seven findings from the R2 completion review ([4204a99](https://github.com/event4u-app/agent-config/commit/4204a99a118ab8e8ed04fb3674821b69c0616f1a))
|
|
354
|
+
* **changelog:** curate the shipped v9.32.0 head, record the cadence decision ([27616e6](https://github.com/event4u-app/agent-config/commit/27616e6046424b12d5b203399dbd3435fb535c48))
|
|
355
|
+
* **install:** record the .vscode bridge merge, surface trampoline removal failures ([c1f15c1](https://github.com/event4u-app/agent-config/commit/c1f15c18f1da0d6e079a2bc4e16f311af6b1ccba))
|
|
356
|
+
* **pricing:** stop pricing a dated model alias at nothing, and stop hiding it ([3fbcc52](https://github.com/event4u-app/agent-config/commit/3fbcc52c436bbdc063aa1476b9a3dc281b38180e))
|
|
357
|
+
* **wedge:** regenerate the production-validator projection after the pragma ([8ab3012](https://github.com/event4u-app/agent-config/commit/8ab3012ab40a54d228d11fadfd0ba072a0fa08fa))
|
|
358
|
+
* **security-lint:** the bare-shell detector had never read a subagent ([b17d1f3](https://github.com/event4u-app/agent-config/commit/b17d1f33653438ab6489c64f33dce403a4f8d2c1))
|
|
359
|
+
* **test:** drop the last v1 label the schema bump left behind ([6f53010](https://github.com/event4u-app/agent-config/commit/6f530100a3b2af7cc4b43b7e58fcb2862df9a48a))
|
|
360
|
+
* **council:** measure the dispatch shape, and stop dividing entries by clients ([d716386](https://github.com/event4u-app/agent-config/commit/d7163864715e15d879ce6af1c1f6db028832d824))
|
|
361
|
+
* **council:** make the attendance metrics able to answer their own questions ([8f92902](https://github.com/event4u-app/agent-config/commit/8f929020301bfdb50e6d788a71e1050f9ff58d43))
|
|
362
|
+
* **ci:** describe the retired tree without naming its dead path ([bd2e726](https://github.com/event4u-app/agent-config/commit/bd2e726883aecf5106522fa7324c1d11aa3a0473))
|
|
363
|
+
* **roadmap:** re-date the index risk review after the substantial rewrite ([6f71cb4](https://github.com/event4u-app/agent-config/commit/6f71cb4f23cfbf2eb344be4a070281e45b2c1fdf))
|
|
364
|
+
* **schema:** let a subagent express the scoped tool grant tool-safety asks for ([9ec8042](https://github.com/event4u-app/agent-config/commit/9ec8042d2c73162931c0d7900826934fdaafccfa))
|
|
365
|
+
* **review-routing:** give the role vocabulary a home that exists ([ec4d392](https://github.com/event4u-app/agent-config/commit/ec4d392faf4feaaf5fbf0694bc028b6e54d0fe2c))
|
|
366
|
+
* **skills:** re-home two sections the rule migration dropped ([2588c5b](https://github.com/event4u-app/agent-config/commit/2588c5be9f82bab41ebedcddd0ad4302dbfc245a))
|
|
367
|
+
* **review:** name the skip artefact so the gate can discover it ([b693b61](https://github.com/event4u-app/agent-config/commit/b693b61e94e5ded5463c22124acb20a1ca776d00))
|
|
368
|
+
* **roadmap:** correct three false premises in the gate-integrity kernel blocker ([2e6c07e](https://github.com/event4u-app/agent-config/commit/2e6c07e66eec04ddf8afb8e233340c2e628141fa))
|
|
369
|
+
* **roadmap:** stop two sub-headings from parsing as phantom phases ([05ed949](https://github.com/event4u-app/agent-config/commit/05ed9493b153c19253fcad3c98a939d76dd09f31))
|
|
370
|
+
|
|
371
|
+
### Documentation
|
|
372
|
+
|
|
373
|
+
* **adr:** ADR-222 — blocker handover is delivered, not remembered ([961ac12](https://github.com/event4u-app/agent-config/commit/961ac12705db642f54119f39dfef9ac5cbea870c))
|
|
374
|
+
* **reply-close:** state the blocker handover as part of the one summary ([ec761e0](https://github.com/event4u-app/agent-config/commit/ec761e04b13e05ea671ba906bfbfd05999e25563))
|
|
375
|
+
* **review:** re-bind the completion review to the repaired scope ([0a585db](https://github.com/event4u-app/agent-config/commit/0a585db2279c83bbf09a1b3afd18852833795c89))
|
|
376
|
+
* **roadmap:** release-surface integrity, 11 of 12 steps closed ([70cec30](https://github.com/event4u-app/agent-config/commit/70cec30255f61de1aeaa39551e008992c63f606c))
|
|
377
|
+
* **context:** Continuation Protocol v1 decided, the runtime graph deferred ([3bafcc0](https://github.com/event4u-app/agent-config/commit/3bafcc075c6db2bcaf9a9725ee87fdb190bd7a73))
|
|
378
|
+
* **contracts:** the model ceiling escalates, never silently degrades ([e625e69](https://github.com/event4u-app/agent-config/commit/e625e696fb4f2d90110f8678dd86e208ec0f4729))
|
|
379
|
+
* **cli:** name the three new flags in the registry synopses and dispatcher help ([1f43731](https://github.com/event4u-app/agent-config/commit/1f4373195ca2d477d06e1fcaa467df2120d8043b))
|
|
380
|
+
* **context:** give the corrected carrier-divergence figure a stable surface ([4812f9d](https://github.com/event4u-app/agent-config/commit/4812f9de9d6bd96b6109776001191a8fbb95feb9))
|
|
381
|
+
* **proof:** re-render after the surgical-uninstall claim moved to exec evidence ([5e489ee](https://github.com/event4u-app/agent-config/commit/5e489ee7b58428f79fc211d07fda754c76efda0e))
|
|
382
|
+
* **review:** record the R2 completion-review findings before any fix ([2954d66](https://github.com/event4u-app/agent-config/commit/2954d663fa26980113331653c31d3dc3ef88c649))
|
|
383
|
+
* **roadmap:** restore install-lifecycle 2.3 to open-and-blocked ([4b61e7f](https://github.com/event4u-app/agent-config/commit/4b61e7f4ba61c560bd3a836368ebb73864e0d285))
|
|
384
|
+
* **roadmap:** land the org-pack reopening brief, close install-lifecycle Phase 2 ([b172d28](https://github.com/event4u-app/agent-config/commit/b172d28ed0a8f2f112a3b0fb43c4e5fe9c54edd6))
|
|
385
|
+
* **roadmap:** close install-lifecycle Phase 1, cancel 1.2 on a failed premise ([920910b](https://github.com/event4u-app/agent-config/commit/920910bc2d6acf978ebe70f5fdb844420b2002c4))
|
|
386
|
+
* **install-layout:** correct the untracked-surfaces list and the vscode pointer shape ([26982c6](https://github.com/event4u-app/agent-config/commit/26982c62eafd452f4c2cf6cd929a7a74dd68dbc6))
|
|
387
|
+
* **roadmap:** record the unapplied Phase 1 implementation and its two open calls ([25fc56d](https://github.com/event4u-app/agent-config/commit/25fc56da7356e446f13bbb1da866a4ddc70091d1))
|
|
388
|
+
* **roadmap:** carry the re-homing the merge commit described but did not contain ([a7a469f](https://github.com/event4u-app/agent-config/commit/a7a469f87592580fab38a1180e17d2320e861337))
|
|
389
|
+
* **roadmap:** council dispositions and four cited corrections ([10c25c4](https://github.com/event4u-app/agent-config/commit/10c25c4753212c2c4b93e972707b3090e06cb431))
|
|
390
|
+
* **review:** re-bind round 2 — six fixed, one accepted as debt ([7b451cb](https://github.com/event4u-app/agent-config/commit/7b451cb75f65b787f4c5ebf3903b49e90382c98a))
|
|
391
|
+
* **review:** record round 2 — the fixes introduced two of their own ([4a0504c](https://github.com/event4u-app/agent-config/commit/4a0504cfcf302b00a3f9773ba89eb284f2b7f573))
|
|
392
|
+
* **review:** re-bind the findings to what the fixes actually did ([baba417](https://github.com/event4u-app/agent-config/commit/baba417297bbb6db0d0d250785e3c049f7e33fd7))
|
|
393
|
+
* **review:** record the completion review before any fix lands ([7dc1f1f](https://github.com/event4u-app/agent-config/commit/7dc1f1f4ea511bcd30a67ac416937511c6420721))
|
|
394
|
+
* **roadmap:** split the 2026-08-10 harvest into eight executable roadmaps ([72a1078](https://github.com/event4u-app/agent-config/commit/72a10788336fc54cff25833ae1568328765f4011))
|
|
395
|
+
* **roadmap:** close Phase 1 and steps 3.2 / 3.5 / 3.8, and re-frame 3.6 ([dc12894](https://github.com/event4u-app/agent-config/commit/dc128947b844d0afb147b9e413c12c1dadbc7346))
|
|
396
|
+
* **roadmap:** close Phase 1 — the quorum-attendance defect ([12e0bc1](https://github.com/event4u-app/agent-config/commit/12e0bc14f7813691c8708d25b6eb23c8bcf4f116))
|
|
397
|
+
* **review:** declare the no-code-surface skip for this completion ([3771eaf](https://github.com/event4u-app/agent-config/commit/3771eafda510306cf238539f3c910481f7e36b1a))
|
|
398
|
+
* **ledger:** record that the three dangling pointers were repaired ([03cf5f8](https://github.com/event4u-app/agent-config/commit/03cf5f8699dce20224479a58a6ece39509deb6a0))
|
|
399
|
+
* **roadmap:** triage the 2026-08-10 inbox batch ([9e999d6](https://github.com/event4u-app/agent-config/commit/9e999d64eb3b34612bcbe7d8d4e91bad56c7cc54))
|
|
400
|
+
* **roadmap:** correct two roadmap claims the tree contradicts ([e1f271e](https://github.com/event4u-app/agent-config/commit/e1f271e6bbe50f9ebaf9814ce47b83bc4111d871))
|
|
401
|
+
* **roadmap:** add the risk register the telemetry record made due ([82268d7](https://github.com/event4u-app/agent-config/commit/82268d7e4e417e688bfb453d9c75f0ded1b0991e))
|
|
402
|
+
* **roadmap:** record the measured telemetry state on both orchestration blockers ([10a2790](https://github.com/event4u-app/agent-config/commit/10a2790e19b245280dd5764cdbfcb873ff586be7))
|
|
403
|
+
* **roadmap:** close and archive the cost-parity program — 23 steps, 6 criteria, every claim re-verified ([af57abf](https://github.com/event4u-app/agent-config/commit/af57abf96ae30234de73446f965d93eba45423f7))
|
|
404
|
+
* **decision:** give the router-is-unused finding an owner before someone acts on it ([bf70104](https://github.com/event4u-app/agent-config/commit/bf701040cf44e873b4fb1eb115a599ed39f7190f))
|
|
405
|
+
* **cost-parity:** one ledger for the family's order, and the per-host table the diet actually needs ([fa188ee](https://github.com/event4u-app/agent-config/commit/fa188ee44ecddf4898abf8feea3c4a12155b1f29))
|
|
406
|
+
|
|
407
|
+
### Tests
|
|
408
|
+
|
|
409
|
+
* **subagent:** assert the tool-grant behaviour, not which keyword rejected it ([59ee093](https://github.com/event4u-app/agent-config/commit/59ee0938eac9289a7f711600eb3bf45500ded1d4))
|
|
410
|
+
* **workspace-inbox:** re-record the inline snapshot that embeds the docker skill ([f395d79](https://github.com/event4u-app/agent-config/commit/f395d79dec3d7e5e39cded83871d384f1008594e))
|
|
411
|
+
* **pricing:** cross-check the two cache-rate tables that nothing compared ([e623e0c](https://github.com/event4u-app/agent-config/commit/e623e0c8fe285dd5ff8e824ac58b7a7cf2d222b0))
|
|
412
|
+
|
|
413
|
+
### Build
|
|
414
|
+
|
|
415
|
+
* **install:** refresh dist/install/install.mjs for the vscode bridge and trampoline warning ([440b046](https://github.com/event4u-app/agent-config/commit/440b046fb75448bfbe6cf854f0084ae19fd9c8f4))
|
|
416
|
+
|
|
417
|
+
Tests: 12935 (+117 since 9.32.0)
|
|
418
|
+
|
|
419
|
+
## [9.32.0](https://github.com/event4u-app/agent-config/compare/9.31.0...9.32.0) (2026-08-10)
|
|
420
|
+
|
|
421
|
+
### Release highlights
|
|
422
|
+
|
|
423
|
+
<!-- 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. -->
|
|
424
|
+
- **Behaviour changes:** the work-engine's two red-check lanes now run a bounded self-fix loop before halting to `BLOCKED` — at most three attempts per validation target, stopped early when a verdict signature repeats (1f01490, wired in 10c8f7e). e05de77 edits a rule file only and changes no behaviour.
|
|
425
|
+
- **Default changes + migration:** _none_
|
|
426
|
+
- **Security and correctness:** _none_
|
|
427
|
+
- **Honest nulls:** _none_
|
|
428
|
+
- **Known limitations:** _none_
|
|
429
|
+
|
|
430
|
+
### Features
|
|
431
|
+
|
|
432
|
+
* **work-engine:** route both red-check lanes through the self-fix loop ([10c8f7e](https://github.com/event4u-app/agent-config/commit/10c8f7eafbf21fc03a5f301163c941a20df4a885))
|
|
433
|
+
* **work-engine:** bounded self-fix loop primitive + executable dod schema ([1f01490](https://github.com/event4u-app/agent-config/commit/1f0149035c1a27729b729dab1dedd861ccdf9812))
|
|
434
|
+
* **envelope:** drift anchor, scripted grounding, verbatim error strings ([6c9187e](https://github.com/event4u-app/agent-config/commit/6c9187e30f41c87553764759096a3f7f4d19a126))
|
|
435
|
+
* **envelope:** successor tailoring, mandatory failed_approaches, data-never-instruction boundary ([b03beac](https://github.com/event4u-app/agent-config/commit/b03beac1ad1325253c89a63eac9abc9f051269d3))
|
|
436
|
+
* **orchestration:** report per-field provenance for host capabilities ([f4958de](https://github.com/event4u-app/agent-config/commit/f4958decf4a70b445a38747bff768ab449877d52))
|
|
437
|
+
|
|
438
|
+
### Bug Fixes
|
|
439
|
+
|
|
440
|
+
* **gates:** stop the R2 review-input copy from laundering fixture secrets ([c63d350](https://github.com/event4u-app/agent-config/commit/c63d3502013e7bc261096d02e2c102a52e2f1ec7))
|
|
441
|
+
* **golden:** teach the replay the delegated bad-verdict surface, re-lock baselines ([1ff480c](https://github.com/event4u-app/agent-config/commit/1ff480c6adeb88af32198a19d41838e2f9f5dcc0))
|
|
442
|
+
* **envelope:** close the eight R2 review findings ([b0d153c](https://github.com/event4u-app/agent-config/commit/b0d153cb3084dac2a20093b73d28a3ce3c12324c))
|
|
443
|
+
* **tests:** type the self-fix state helpers against the wire types ([60d2724](https://github.com/event4u-app/agent-config/commit/60d272419b07b5abea1ce6ffa430faf127fcde4a))
|
|
444
|
+
* **handoff:** stop offering the caller its own empty session ([b72f772](https://github.com/event4u-app/agent-config/commit/b72f772a03207aa4feeded3acd5b68823e3fd79c))
|
|
445
|
+
* **tests:** narrow regex captures in the capability parity block ([6f27615](https://github.com/event4u-app/agent-config/commit/6f276154b83781404d6551113c6d43e5cf040423))
|
|
446
|
+
* **carrier:** a paths: disagreement is a delivery defect, not inert metadata ([318fb81](https://github.com/event4u-app/agent-config/commit/318fb818eb543f27fc4c3b138ce762dc8c9e9640))
|
|
447
|
+
|
|
448
|
+
### Documentation
|
|
449
|
+
|
|
450
|
+
* **review:** re-bind the findings artefact to the post-fix scope ([7a9bbbb](https://github.com/event4u-app/agent-config/commit/7a9bbbb2d7f4f04786771914bf7b3b68aba23e10))
|
|
451
|
+
* **review:** record the R2 completion-review findings before fixing them ([27322e8](https://github.com/event4u-app/agent-config/commit/27322e876c76f96d6a67131f9e96a1759290a8f5))
|
|
452
|
+
* **roadmap:** P2.2 build half shipped, its threshold unevaluated with a blocker ([1e478fd](https://github.com/event4u-app/agent-config/commit/1e478fdc317fdf12df001c1b98ef264df54a3742))
|
|
453
|
+
* **contracts:** the flow contract documents the self-fix loop and the dod slot ([0ebaaba](https://github.com/event4u-app/agent-config/commit/0ebaabae9e12c75446efefc5be6f6b33b9d0435f))
|
|
454
|
+
* **roadmap:** capability-answerability Phase 1 closed, blocker narrowed to one question ([c37af04](https://github.com/event4u-app/agent-config/commit/c37af045ecbf62b31e6878befdc88d763498d7a9))
|
|
455
|
+
* **rules:** delegation-policy names the capability provenance check ([e05de77](https://github.com/event4u-app/agent-config/commit/e05de771d74e8284e2e64e91e33be66b1bd15e23))
|
|
456
|
+
* **contracts:** the host-capability contract documents six fields, not five ([566b984](https://github.com/event4u-app/agent-config/commit/566b984681d1a1a5ef76643fa6f90f297c284e81))
|
|
457
|
+
|
|
458
|
+
### Tests
|
|
459
|
+
|
|
460
|
+
* **work-engine:** pin the loop contract and update the changed halt shapes ([eb88aa6](https://github.com/event4u-app/agent-config/commit/eb88aa695121a01c0c1e10de9804f1df3424c334))
|
|
461
|
+
|
|
462
|
+
### Other
|
|
463
|
+
|
|
464
|
+
* **carrier:** re-bind to the post-merge scope — the fixed point ([884104c](https://github.com/event4u-app/agent-config/commit/884104c15d8257579a320932c671b489d96e7b06))
|
|
465
|
+
* **carrier:** re-bind the R2 round to the shipping content, all 6 terminal ([9bbfbc3](https://github.com/event4u-app/agent-config/commit/9bbfbc35388f54c77fdae27315025843a6ea79f5))
|
|
466
|
+
* **carrier:** R2 completion review round 1 — 6 findings, all open ([75be940](https://github.com/event4u-app/agent-config/commit/75be940f4f9bcbf71e1f1248467637fc51c6b63b))
|
|
467
|
+
|
|
468
|
+
Tests: 12818 (+89 since 9.31.0)
|
|
469
|
+
|
|
324
470
|
## [9.31.0](https://github.com/event4u-app/agent-config/compare/9.30.0...9.31.0) (2026-08-10)
|
|
325
471
|
|
|
326
472
|
### Release highlights
|
|
@@ -59,9 +59,8 @@ changed-file list. The skill:
|
|
|
59
59
|
4. Computes overall severity (`high` wins).
|
|
60
60
|
5. Returns the structured block.
|
|
61
61
|
|
|
62
|
-
If neither data file exists, the skill returns the generic fallback
|
|
63
|
-
|
|
64
|
-
valid output — do not invent owners.
|
|
62
|
+
If neither data file exists, the skill returns the generic fallback from
|
|
63
|
+
its own common role vocabulary. That is valid output — do not invent owners.
|
|
65
64
|
|
|
66
65
|
### 3. Present the result
|
|
67
66
|
|
|
@@ -121,7 +120,7 @@ After the block, ask:
|
|
|
121
120
|
## See also
|
|
122
121
|
|
|
123
122
|
- [`review-routing`](../../skills/review-routing/SKILL.md) — the resolver
|
|
124
|
-
- [`reviewer-awareness`](../../rules/reviewer-awareness.md) —
|
|
123
|
+
- [`reviewer-awareness`](../../rules/reviewer-awareness.md) — the rule that routes here: paths and risk over seniority, primary + secondary on medium/high
|
|
125
124
|
- [`review-routing-data-format`](../../../docs/guidelines/agent-infra/review-routing-data-format.md)
|
|
126
125
|
— YAML schemas
|
|
127
126
|
- [`create-pr-description`](../../skills/create-pr:description-only/SKILL.md) —
|
|
@@ -23,6 +23,53 @@ hunts for it. One PR → one URL line.
|
|
|
23
23
|
- Only when a PR was actually created/updated **this turn**. No PR → no link line.
|
|
24
24
|
- The raw URL (not a masked markdown link) so it is unmistakable and clickable.
|
|
25
25
|
|
|
26
|
+
## Blocker handover — when the reply leaves work stuck
|
|
27
|
+
|
|
28
|
+
A work reply that stops because something is waiting on the **user** closes
|
|
29
|
+
with the blocker, in the same one summary, above the PR-URL line. Not a second
|
|
30
|
+
summary — this is what "what remains" looks like when what remains is not yours
|
|
31
|
+
to do.
|
|
32
|
+
|
|
33
|
+
`agent-config gates --reply` renders it. Call it, paste what it returns, and
|
|
34
|
+
mirror the labels into the user's language. It prints **nothing** when nothing
|
|
35
|
+
is owned by the user, so it is safe to call unconditionally: the "no blocker →
|
|
36
|
+
no block" rule is a property of the command, not a judgement you have to make.
|
|
37
|
+
|
|
38
|
+
Three obligations the command cannot carry for you:
|
|
39
|
+
|
|
40
|
+
- **The options ARE the blocker decision — never a choice of substitute work.**
|
|
41
|
+
This is the measured failure, not a hypothetical one: a session that ended
|
|
42
|
+
every reply with well-formed numbered options still left its real blockers
|
|
43
|
+
unresolved for nine rounds, because each option block asked *"which work
|
|
44
|
+
should I do while your decision sits there"* (option 3 was reliably "nothing
|
|
45
|
+
more autonomously"). The user answered every one of them with a digit and
|
|
46
|
+
decided nothing. Offering the agent's next task is not a handover.
|
|
47
|
+
- **The action travels, not a pointer to it.** "The three readings are in the
|
|
48
|
+
roadmap" is not a decidable option — the user cannot answer without reading
|
|
49
|
+
first. Where a real choice exists, write the alternatives out, one line each
|
|
50
|
+
for what speaks for them, then the single recommendation line
|
|
51
|
+
([`user-interaction`](../../../rules/user-interaction.md)).
|
|
52
|
+
- **Owner ≠ agent.** If you could clear it with a tool or a command, it is not
|
|
53
|
+
a blocker, it is unfinished work — do it now. A blocker whose owner is the
|
|
54
|
+
agent, announced instead of executed, is the promissory close that
|
|
55
|
+
[`verify-before-complete`](../../../rules/verify-before-complete.md) forbids.
|
|
56
|
+
|
|
57
|
+
## Why the blocker handover is not a trailing checklist
|
|
58
|
+
|
|
59
|
+
[`mandated-lines`](../../execution/mandated-lines.md) bans the end-of-reply
|
|
60
|
+
checklist, and this shape has to answer that ban rather than sit beside it.
|
|
61
|
+
|
|
62
|
+
- **It fires only when owed.** Nothing waiting on the user ⇒ nothing emitted,
|
|
63
|
+
enforced by the renderer. It never appears as evidence that blockers were
|
|
64
|
+
checked for — which is exactly the ceremony the ban targets.
|
|
65
|
+
- **The end of the reply IS the decision point here.** The turn stops because
|
|
66
|
+
the decision is the user's. A line emitted where the decision lands is the
|
|
67
|
+
rule's own criterion, not an exception to it.
|
|
68
|
+
- **One blocker in full, the rest as a count.** The blocking one is written
|
|
69
|
+
out; everything else is `N other decisions also wait on you` plus the
|
|
70
|
+
command. A roster is the failure mode — "twelve decisions across two
|
|
71
|
+
documents, ~850 lines" produced no decision at all.
|
|
72
|
+
|
|
26
73
|
## Why it does not collide with sibling rules
|
|
27
74
|
|
|
28
75
|
- **`language-and-tone`** last-line rule: a raw URL is language-neutral, so it
|
|
@@ -34,6 +81,15 @@ hunts for it. One PR → one URL line.
|
|
|
34
81
|
last among interactive elements; the PR URL sits below it as the final line and
|
|
35
82
|
is not an "open question," so it does not trip the no-trailing-open-question
|
|
36
83
|
rule.
|
|
84
|
+
- **`ask-when-uncertain`** (one question per turn): reporting N blockers is
|
|
85
|
+
**zero** questions — it is a report. What the turn may carry is at most ONE
|
|
86
|
+
numbered-options block, for the one blocking decision, with one recommendation
|
|
87
|
+
line. Per-blocker questions are the violation that rule names.
|
|
88
|
+
- **`no-cheap-questions`** IL4: the handover ends on `Done when:` — a decidable
|
|
89
|
+
signal, not "shall I continue once you've sorted this out?".
|
|
90
|
+
- **`scope-control`** post-artifact hard stop: the steps address the **user**.
|
|
91
|
+
A handover that routes a slash-command back to the agent ("Blocker X — shall I
|
|
92
|
+
start Phase 1?") is the execution menu that rule forbids, wearing a new label.
|
|
37
93
|
|
|
38
94
|
## Failure modes
|
|
39
95
|
|
|
@@ -43,3 +99,12 @@ hunts for it. One PR → one URL line.
|
|
|
43
99
|
scroll/search.
|
|
44
100
|
- Masking the URL behind link text so it is not obviously the PR.
|
|
45
101
|
- Adding a PR-link line when no PR was created this turn.
|
|
102
|
+
- Closing on a blocker while offering the agent's next task instead of the
|
|
103
|
+
decision the blocker actually needs.
|
|
104
|
+
- Handing over options as a count ("four options, see the template") or as a
|
|
105
|
+
file reference — the user cannot answer either without reading first.
|
|
106
|
+
- Listing every open blocker flat, leaving the user to work out which one is
|
|
107
|
+
the one holding the chain.
|
|
108
|
+
- Reporting the same blocker again, turn after turn, with no resolution path —
|
|
109
|
+
a repeat with nothing moved is itself the finding, and belongs in the reply
|
|
110
|
+
as such.
|
|
@@ -16,7 +16,8 @@ A single JSON object, `schema_version: 1`:
|
|
|
16
16
|
"parallel_spawn": false,
|
|
17
17
|
"status_polling": false,
|
|
18
18
|
"separate_quota_pool": false,
|
|
19
|
-
"agent_teams": false
|
|
19
|
+
"agent_teams": false,
|
|
20
|
+
"worker_respawn": false
|
|
20
21
|
}
|
|
21
22
|
```
|
|
22
23
|
|
|
@@ -64,11 +65,41 @@ to in-session execution rather than attempting an unsupported primitive.
|
|
|
64
65
|
| `status_polling` | bool | Monitoring running subagents (progress / completion checks). `false` → fire-and-collect only, no mid-run polling. |
|
|
65
66
|
| `separate_quota_pool` | bool | Quota-arbitrage bonus (Phase 2) — subagents draw from a distinct quota pool than the session. `false` → assume shared quota. |
|
|
66
67
|
| `agent_teams` | bool | Claude Code's experimental multi-instance Agent Teams primitive (`CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS`). `false` → the [judgment ladder](auto-dispatch-classification.md#judgment-ladder-phase-2--road-to-always-on-orchestration)'s rung 3 (team) degrades to parallel subagents, recorded as `degraded_from: 3`. |
|
|
68
|
+
| `worker_respawn` | bool | The host can kill a running worker and spawn a fresh one that continues the SAME task mid-flight. `false` on every host today, deliberately — set `true` only once OBSERVED, never by inference from spawning and killing existing separately. `false` → degrade to stop-loss behaviour, loudly. |
|
|
67
69
|
|
|
68
70
|
A field being `true` is a **precondition**, not a mandate: `parallel_spawn:
|
|
69
71
|
true` permits concurrency but the dispatch cap still applies (see
|
|
70
72
|
`subagents.max_parallel` in subagent-configuration.md).
|
|
71
73
|
|
|
74
|
+
## Provenance — "probe" is a misnomer for five of the six fields
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
NEVER READ A false FIELD AS "THIS HOST CANNOT DO IT".
|
|
78
|
+
A REGISTRY ROW IS A COMMITTED OBSERVATION, NOT A LIVE CHECK.
|
|
79
|
+
A default FIELD MEANS NOBODY ANSWERED — RENDERED AS false BECAUSE THAT IS THE
|
|
80
|
+
SAFE DEGRADATION, NOT BECAUSE ANYTHING WAS MEASURED.
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
The six booleans look alike and are not. `HOST_CAPABILITY_REGISTRY` holds
|
|
84
|
+
exactly one row today, so on every other host **all six** fields are the safe
|
|
85
|
+
default — and `agent_teams` is the only field any live check touches. The name
|
|
86
|
+
`probeHostCapabilities` says "detected" about values that were mostly asserted
|
|
87
|
+
at authoring time.
|
|
88
|
+
|
|
89
|
+
`describeHostCapabilities(hostId)` returns the same manifest plus a
|
|
90
|
+
`sources` map naming, per field, which of the three answered:
|
|
91
|
+
|
|
92
|
+
| Source | Means | Re-checked at run time |
|
|
93
|
+
|---|---|---|
|
|
94
|
+
| `registry` | this repo observed the capability on this host once and committed it to the table | no |
|
|
95
|
+
| `live-probe` | established in THIS process, from the environment | yes |
|
|
96
|
+
| `default` | nothing answered; `SAFE_DEFAULT` applied | n/a |
|
|
97
|
+
|
|
98
|
+
`agent-config routing:doctor [--platform <host>]` prints it. Read the
|
|
99
|
+
provenance before treating a `false` as a host limitation: on an unrecognized
|
|
100
|
+
host every field is `default`, which is an absence of knowledge and not a
|
|
101
|
+
measurement.
|
|
102
|
+
|
|
72
103
|
## Related
|
|
73
104
|
|
|
74
105
|
- [`subagent-configuration`](../subagent-configuration.md) — the `subagents.*`
|
|
@@ -68,6 +68,9 @@ v1 forward-compat rule on unknown fields).
|
|
|
68
68
|
| `rules_used` | int \| null | **Lean-init extension (L6 demand signal).** Rules the worker actually applied/cited. Validation: never exceeds `rules_carried`. `null` = not measured. Counts only. |
|
|
69
69
|
| `work_tokens` | int \| null | **Dispatch-economy extension.** Tokens the worker consumed AFTER init — the delta from first worker turn to envelope close. With `init_tokens`, yields the `dispatch_floor` ratio (`src/config/dispatch-economy-metrics.json`). Sourced from the transcript ledger (`_lib/cc_transcript.ts` `billable_input` semantics) by the report/backfill, never model-estimated without the tag below. `null` = not measured. |
|
|
70
70
|
| `floor_provenance` | enum \| null | **Dispatch-economy extension.** Provenance of the `init_tokens`/`work_tokens` pair: `measured` (transcript ledger) · `estimated`. Auto-defaults to `estimated` when either field is present untagged — mirrors `token_delta_provenance`. `null` = neither field present. |
|
|
71
|
+
| `model_requested` | string \| null | **Served-model-truth extension (`inbox-harvest-2026-08-b-ledger-truth` Phase 1).** The model id that was ASKED for — the id `tier_chosen`, `tier_source`, `session_tier` and the downshift cost-% are all derived from. `null` = not recorded. Id only, never free-form. |
|
|
72
|
+
| `model_served` | string \| null | **Served-model-truth extension.** The model id the provider reported ANSWERING with. `''`/`null` when the transport reports none (every CLI client) — absent is the honest value, not a defect. Attribution only: never route or tier on it. |
|
|
73
|
+
| `model_divergent` | bool \| null | **Served-model-truth extension.** DERIVED, never supplied: `true` when both ids are present and differ (an alias or provider substitution — every tier-derived figure on this line attributes to a model that never ran), `false` when both are present and match. `null` when either is absent, because a comparison that never happened must not read as "checked, and they matched". |
|
|
71
74
|
| `return_channel_chars` | int \| null | **Dispatch-economy extension (Phase 6.3).** Serialized chars of the tool result returned into the orchestrator context (sync completions, hook-derived count — content never enters the record). Detector for "isolation win refunded through the return channel"; committed cap: `MAX_ENVELOPE_CHARS` (12,000) via `return_channel` in `dispatch-economy-metrics.json`. `null` = async ack. |
|
|
72
75
|
|
|
73
76
|
These routing + cost fields are additive and optional — a line without them is
|
|
@@ -66,6 +66,12 @@ primitive → run in-session (clean no-op).
|
|
|
66
66
|
2. **Tier-size** each slice (`lite|medium|high`) per the classification context —
|
|
67
67
|
never the orchestrator's own session tier (the cost win is the per-call
|
|
68
68
|
downsize; see [`subagent-routing`](../contexts/execution/subagent-routing.md)).
|
|
69
|
+
Where `subagents.model_ceiling` caps the tier and the slice does not fit under
|
|
70
|
+
it, the worker **escalates and never silently delivers the degraded result**;
|
|
71
|
+
the orchestrator re-slices, runs in-session, or surfaces the ceiling to the
|
|
72
|
+
human, and never raises the ceiling itself (class C — `settings:set` refuses
|
|
73
|
+
it by construction). Absent is *uncapped*, never a low cap. Full contract:
|
|
74
|
+
[`subagent-boundary § The model ceiling`](../docs/contracts/subagent-boundary.md).
|
|
69
75
|
3. **Dispatch** via the form gate + matching `subagent-orchestration` mode
|
|
70
76
|
(independent → do-in-parallel; ordered → do-in-steps; risk/correctness →
|
|
71
77
|
+ judge; UI-heavy → live-app judge, efficacy-gated).
|
|
@@ -105,7 +111,17 @@ plus this telemetry). The
|
|
|
105
111
|
capability gate itself resolves from the committed host registry merged with a
|
|
106
112
|
live environment probe in `src/scripts/_lib/host_capability.ts`
|
|
107
113
|
(`probeHostCapabilities` — capability is a fact about the host, never a
|
|
108
|
-
settings override).
|
|
114
|
+
settings override).
|
|
115
|
+
|
|
116
|
+
**Never read a `false` capability as a host limitation without checking where it
|
|
117
|
+
came from.** The registry holds one row, so on every other host all six fields
|
|
118
|
+
are the all-false safe default — which records that *nobody answered*, not that
|
|
119
|
+
the host cannot spawn. `agent-config routing:doctor [--platform <host>]` prints
|
|
120
|
+
the value **and** its provenance per field (`registry` = a committed observation
|
|
121
|
+
this repo made once · `live-probe` = established in this process · `default` =
|
|
122
|
+
no answer). Run it before concluding delegation is unavailable here; the
|
|
123
|
+
same-shaped wrong guess about the council is the incident
|
|
124
|
+
[`council-availability`](council-availability.md) exists for. What stays
|
|
109
125
|
model-carried, honestly: the decomposition itself, the per-return
|
|
110
126
|
verification, and every dispatch on hosts without hook slots. The nudges are
|
|
111
127
|
advisory by design — whether they change behaviour is measured by the
|
|
@@ -18,10 +18,34 @@
|
|
|
18
18
|
* Blocking a pipeline on "the user has an open decision" would turn a
|
|
19
19
|
* visibility aid into a second thing to fight.
|
|
20
20
|
*
|
|
21
|
+
* `--reply` is the same projection shaped for the END OF A CHAT REPLY rather
|
|
22
|
+
* than a terminal pane, and it exists because the pull channel above is only
|
|
23
|
+
* read by someone who already knows to ask. Transcript forensics over three
|
|
24
|
+
* consumer sessions found five "what do I do now?" follow-ups, every one of
|
|
25
|
+
* them next to a blocker the agent HAD reported — as a file reference, as a
|
|
26
|
+
* bare option count, or as a choice of substitute work. What the same corpus
|
|
27
|
+
* also shows is that a tool's output gets carried into the reply verbatim
|
|
28
|
+
* (the dashboard's step count appears word-for-word inside eight option
|
|
29
|
+
* blocks). So the fix is not to make the agent format better from memory; it
|
|
30
|
+
* is to hand it the finished text. See ADR-222.
|
|
31
|
+
*
|
|
32
|
+
* Two properties carry the contract mechanically:
|
|
33
|
+
* - Nothing owned by the user open ⇒ EMPTY output. "No blocker → no block"
|
|
34
|
+
* stops being a judgement call, so the command is safe to call
|
|
35
|
+
* unconditionally at reply-close.
|
|
36
|
+
* - Exactly ONE blocker is rendered in full — the one that unblocks most.
|
|
37
|
+
* Every other one is a single trailing line. The user is never handed a
|
|
38
|
+
* flat list to weigh themselves.
|
|
39
|
+
*
|
|
40
|
+
* Labels are English like the rest of the CLI surface; the agent mirrors them
|
|
41
|
+
* into the user's language when it lifts them into a reply, exactly as it does
|
|
42
|
+
* for `Recommendation:` / `Empfehlung:`.
|
|
43
|
+
*
|
|
21
44
|
* Invocation (from project root):
|
|
22
45
|
* ./agent-config gates # decisions owned by the user
|
|
23
46
|
* ./agent-config gates --all # every open blocker, grouped by owner
|
|
24
47
|
* ./agent-config gates --json # machine-readable
|
|
48
|
+
* ./agent-config gates --reply # reply-close form; empty when none
|
|
25
49
|
*/
|
|
26
50
|
|
|
27
51
|
import * as path from 'node:path';
|
|
@@ -209,6 +233,76 @@ function render(entries: readonly Entry[], all: boolean): string {
|
|
|
209
233
|
return lines.join('\n') + '\n';
|
|
210
234
|
}
|
|
211
235
|
|
|
236
|
+
/**
|
|
237
|
+
* Reply-close form: the one blocking decision in full, the rest as one line.
|
|
238
|
+
*
|
|
239
|
+
* Deliberately narrower than `render()`. `Status` and `Owner` are roadmap-file
|
|
240
|
+
* metadata that a reader of a reply cannot act on, so they are dropped; what
|
|
241
|
+
* survives is what the user has to DO and how they will know it is done. The
|
|
242
|
+
* five-field shape stays where it is enforced — in the roadmap file — and does
|
|
243
|
+
* not follow the blocker into prose it would only pad.
|
|
244
|
+
*
|
|
245
|
+
* Returns '' when nothing is owned by the user, so the caller can append the
|
|
246
|
+
* result unconditionally and get silence when silence is correct.
|
|
247
|
+
*/
|
|
248
|
+
function renderReply(entries: readonly Entry[]): string {
|
|
249
|
+
const mine = entries.filter((e) => needsUser(e.blocker.owner));
|
|
250
|
+
if (mine.length === 0) {
|
|
251
|
+
return '';
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// `collectEntries` already sorted by unblocking weight, so the first entry
|
|
255
|
+
// IS the one that matters most. Picking it here rather than asking the
|
|
256
|
+
// caller to choose is the point: a flat list is the failure mode.
|
|
257
|
+
const lead = mine[0] as Entry;
|
|
258
|
+
const rest = mine.slice(1);
|
|
259
|
+
const lines: string[] = [];
|
|
260
|
+
|
|
261
|
+
lines.push(`Blocked: ${lead.blocker.blocks} — ${lead.roadmapRel}`);
|
|
262
|
+
|
|
263
|
+
const steps = regroupTodo(lead.blocker.todo);
|
|
264
|
+
const doLabel = isLegacy(lead.blocker) ? 'Blocked until:' : 'Do:';
|
|
265
|
+
if (steps.length === 0) {
|
|
266
|
+
lines.push(
|
|
267
|
+
`${doLabel} (no steps recorded — the blocker entry needs a **What to do:** list)`,
|
|
268
|
+
);
|
|
269
|
+
} else if (steps.length === 1) {
|
|
270
|
+
lines.push(...wrap(`${doLabel} ${steps[0] as string}`, WIDTH, ' '));
|
|
271
|
+
} else {
|
|
272
|
+
// Emitted as authored, never re-numbered: real blocker entries already
|
|
273
|
+
// carry their own `1.` / `2.` markers (the CI-enforced `What to do:`
|
|
274
|
+
// shape), so adding our own would produce "1. 1. …". An entry that
|
|
275
|
+
// arrives unnumbered stays unnumbered — that is a fact about the
|
|
276
|
+
// roadmap entry, and papering over it here would hide it from the
|
|
277
|
+
// person who could fix it.
|
|
278
|
+
lines.push(`${doLabel}`);
|
|
279
|
+
for (const s of steps) {
|
|
280
|
+
lines.push(...wrap(` ${s}`, WIDTH, ' '));
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
lines.push(...wrap(`Done when: ${lead.blocker.resolvedWhen}`, WIDTH, ' '));
|
|
284
|
+
|
|
285
|
+
if (rest.length > 0) {
|
|
286
|
+
// A count, not a roster. Naming all of them reproduces the exact
|
|
287
|
+
// failure this form exists to end — "zwölf Entscheidungen bei Dir …
|
|
288
|
+
// rund 850 Zeilen", which the transcript shows produced no decision at
|
|
289
|
+
// all. The one that blocks is written out above; the rest are one
|
|
290
|
+
// command away, and saying so is shorter than listing them and more
|
|
291
|
+
// honest than hiding them.
|
|
292
|
+
lines.push('');
|
|
293
|
+
lines.push(
|
|
294
|
+
...wrap(
|
|
295
|
+
`${rest.length} other decision${rest.length !== 1 ? 's' : ''} also wait${rest.length === 1 ? 's' : ''} on you, ` +
|
|
296
|
+
'none blocking this — `agent-config gates`.',
|
|
297
|
+
WIDTH,
|
|
298
|
+
' ',
|
|
299
|
+
),
|
|
300
|
+
);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
return lines.join('\n') + '\n';
|
|
304
|
+
}
|
|
305
|
+
|
|
212
306
|
function renderJson(entries: readonly Entry[], all: boolean): string {
|
|
213
307
|
const pick = all ? entries : entries.filter((e) => needsUser(e.blocker.owner));
|
|
214
308
|
return (
|
|
@@ -270,18 +364,28 @@ function main(argv?: readonly string[]): number {
|
|
|
270
364
|
const args = argv ?? process.argv.slice(2);
|
|
271
365
|
const all = args.includes('--all');
|
|
272
366
|
const json = args.includes('--json');
|
|
367
|
+
const reply = args.includes('--reply');
|
|
273
368
|
|
|
274
369
|
const repoRoot = _resolveRepoRoot(process.cwd());
|
|
275
370
|
const roadmapRoot = path.join(repoRoot, 'agents', 'roadmaps');
|
|
276
371
|
if (!_isDir(roadmapRoot)) {
|
|
372
|
+
// `--reply` stays silent here too: a project without roadmaps has no
|
|
373
|
+
// blocker to hand over, and a reply-close line saying so would be the
|
|
374
|
+
// ceremony the form exists to avoid.
|
|
277
375
|
process.stdout.write(
|
|
278
|
-
|
|
376
|
+
reply
|
|
377
|
+
? ''
|
|
378
|
+
: json
|
|
379
|
+
? '{"needsYou":0,"other":0,"blockers":[]}\n'
|
|
380
|
+
: 'No roadmaps directory — nothing to report.\n',
|
|
279
381
|
);
|
|
280
382
|
return 0;
|
|
281
383
|
}
|
|
282
384
|
|
|
283
385
|
const entries = collectEntries(roadmapRoot);
|
|
284
|
-
process.stdout.write(
|
|
386
|
+
process.stdout.write(
|
|
387
|
+
reply ? renderReply(entries) : json ? renderJson(entries, all) : render(entries, all),
|
|
388
|
+
);
|
|
285
389
|
return 0;
|
|
286
390
|
}
|
|
287
391
|
|
|
@@ -308,5 +412,5 @@ if (_isCliEntry()) {
|
|
|
308
412
|
process.exitCode = main();
|
|
309
413
|
}
|
|
310
414
|
|
|
311
|
-
export { main, needsUser, regroupTodo, wrap, collectEntries, render, renderJson };
|
|
415
|
+
export { main, needsUser, regroupTodo, wrap, collectEntries, render, renderJson, renderReply };
|
|
312
416
|
export type { Entry };
|
|
@@ -83,6 +83,17 @@ Read `docker-compose.yml` / `compose.yaml` to discover the actual service names.
|
|
|
83
83
|
- Use `make console` for interactive shell access.
|
|
84
84
|
- Use `make console-xdebug` for Xdebug container access.
|
|
85
85
|
|
|
86
|
+
### Tooling detection
|
|
87
|
+
|
|
88
|
+
Which test runner and quality commands exist depends on the project shape.
|
|
89
|
+
Check for `artisan` in the project root before picking one:
|
|
90
|
+
|
|
91
|
+
- **Laravel** (`artisan` present) — `php artisan test`, `vendor/bin/phpstan analyse`, `vendor/bin/rector process`
|
|
92
|
+
- **Plain Composer** (no `artisan`) — `vendor/bin/phpunit`, `vendor/bin/phpstan analyse`, `vendor/bin/rector process`
|
|
93
|
+
|
|
94
|
+
Either way the command runs inside the container:
|
|
95
|
+
`docker compose exec -T <php-service> <command>`.
|
|
96
|
+
|
|
86
97
|
### Image building
|
|
87
98
|
|
|
88
99
|
- Production images use `target: pro` — no dev dependencies.
|
|
@@ -157,6 +157,17 @@ Then add these **Laravel-specific** checks:
|
|
|
157
157
|
- Extract reusable UI pieces into components/partials when it matches project patterns.
|
|
158
158
|
- Escape output by default and use raw output only when safe and intentional.
|
|
159
159
|
|
|
160
|
+
## Translations and language files
|
|
161
|
+
|
|
162
|
+
- **Flat dot-notation keys only** — `'type.daily_report' => 'Daily Report'`.
|
|
163
|
+
Nested arrays (`'type' => ['daily_report' => …]`) are forbidden: they break
|
|
164
|
+
key referencing and make a one-line addition a nested diff.
|
|
165
|
+
- Reference with the helper and the same flat key —
|
|
166
|
+
`__('report.type.daily_report')`, `__('email.report.created.subject', ['number' => $number])`.
|
|
167
|
+
- Every key exists in **every** shipped locale. Adding to `lang/en/` without
|
|
168
|
+
`lang/de/` is a bug, not a TODO — the app ships to both audiences.
|
|
169
|
+
- Never hardcode a user-visible string in PHP.
|
|
170
|
+
|
|
160
171
|
## What NOT to do
|
|
161
172
|
|
|
162
173
|
- Do not put business logic into controllers, models, or Blade templates.
|
|
@@ -28,8 +28,8 @@ packs:
|
|
|
28
28
|
|
|
29
29
|
Do NOT use when:
|
|
30
30
|
|
|
31
|
-
- The diff is low-risk and no ownership map exists — fall back to
|
|
32
|
-
|
|
31
|
+
- The diff is low-risk and no ownership map exists — fall back to the
|
|
32
|
+
common role vocabulary below.
|
|
33
33
|
- A full PR description is requested — route to
|
|
34
34
|
[`create-pr-description`](../create-pr:description-only/SKILL.md) and let
|
|
35
35
|
it call this skill for the routing block.
|
|
@@ -55,7 +55,7 @@ Check, in order:
|
|
|
55
55
|
Parse each with YAML. Validate `version: 1` is present. If a file is
|
|
56
56
|
malformed, **stop and report the parse error** — never silently fall
|
|
57
57
|
back. If neither file exists, emit the generic role-based fallback
|
|
58
|
-
using
|
|
58
|
+
using the common role vocabulary below.
|
|
59
59
|
|
|
60
60
|
**Also** pull agent-written signals via the shared abstraction (see
|
|
61
61
|
[`memory-access`](../../../docs/guidelines/agent-infra/memory-access.md)):
|
|
@@ -114,12 +114,29 @@ If `ownership-map.yml` has an `updated` field older than 6 months,
|
|
|
114
114
|
include a staleness warning in the output. Still use the data — just
|
|
115
115
|
flag it.
|
|
116
116
|
|
|
117
|
+
## Common role vocabulary
|
|
118
|
+
|
|
119
|
+
The fallback set when no ownership entry matches. Extend it per project, but
|
|
120
|
+
keep these as the shared names — a role nobody else uses routes to nobody.
|
|
121
|
+
|
|
122
|
+
| Role | Typical focus |
|
|
123
|
+
|---|---|
|
|
124
|
+
| `backend` | business logic, validation, side effects, data integrity |
|
|
125
|
+
| `frontend` | UX, accessibility, client-side state, rendering |
|
|
126
|
+
| `security` | authz, secrets, trust boundaries, data exposure |
|
|
127
|
+
| `infra` / `ops` | rollout, migration safety, observability, retries |
|
|
128
|
+
| `database` | schema changes, indexes, query plans, rollback realism |
|
|
129
|
+
| `domain owner` | business invariants, policy intent, edge-case correctness |
|
|
130
|
+
| `qa` | test coverage, regression scenarios, flake risk |
|
|
131
|
+
|
|
132
|
+
Roles, never individuals: a package-shipped artifact names `security`, and the
|
|
133
|
+
consumer's CODEOWNERS or ownership map maps that to a person.
|
|
134
|
+
|
|
117
135
|
## Validation
|
|
118
136
|
|
|
119
137
|
Before returning:
|
|
120
138
|
|
|
121
|
-
1. Every emitted role is either in the common vocabulary
|
|
122
|
-
([`reviewer-awareness`](../../rules/reviewer-awareness.md)) or sourced
|
|
139
|
+
1. Every emitted role is either in the common vocabulary above or sourced
|
|
123
140
|
from an ownership entry — never invented.
|
|
124
141
|
2. Every historical-pattern match cites its `id` and `required_test`
|
|
125
142
|
verbatim.
|
|
@@ -191,7 +208,7 @@ Data source: <"ownership-map.yml + historical-bug-patterns.yml"
|
|
|
191
208
|
|
|
192
209
|
## See also
|
|
193
210
|
|
|
194
|
-
- [`reviewer-awareness`](../../rules/reviewer-awareness.md) —
|
|
211
|
+
- [`reviewer-awareness`](../../rules/reviewer-awareness.md) — the rule that routes here: anchor reviewer choice in paths and risk, never seniority
|
|
195
212
|
- [`review-routing-data-format`](../../../docs/guidelines/agent-infra/review-routing-data-format.md)
|
|
196
213
|
- [`create-pr-description`](../create-pr:description-only/SKILL.md)
|
|
197
214
|
- [`judge-test-coverage`](../judge-test-coverage/SKILL.md) — consumes
|
|
@@ -39,7 +39,7 @@ schema_version: 1
|
|
|
39
39
|
# CI guard: a release bump of `package.json` must update this value
|
|
40
40
|
# in lockstep — see scripts/check_template_pin_drift.ts (road-to-
|
|
41
41
|
# portable-runtime-and-update-check P3.3).
|
|
42
|
-
agent_config_version: "9.
|
|
42
|
+
agent_config_version: "9.33.0"
|
|
43
43
|
|
|
44
44
|
# --- Project identity ---
|
|
45
45
|
project:
|