@event4u/agent-config 9.32.0 → 9.34.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 +85 -72
- package/dist/agent-src/commands/agent-handoff.md +15 -3
- 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/orchestration-telemetry.md +3 -0
- package/dist/agent-src/rules/delegation-policy.md +6 -0
- package/dist/agent-src/scripts/archive_completed_roadmaps.ts +35 -1
- package/dist/agent-src/scripts/roadmap_gates.ts +107 -3
- package/dist/agent-src/skills/corpus-grounding/SKILL.md +21 -12
- package/dist/agent-src/skills/design-tokens/SKILL.md +15 -0
- 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/react-shadcn-ui/SKILL.md +24 -0
- package/dist/agent-src/skills/review-routing/SKILL.md +23 -6
- package/dist/agent-src/skills/rule-writing/SKILL.md +23 -0
- package/dist/agent-src/skills/skill-writing/SKILL.md +80 -2
- package/dist/agent-src/skills/systematic-debugging/SKILL.md +5 -3
- package/dist/agent-src/skills/tailwind-engineer/SKILL.md +24 -0
- 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/cli/registry.js +4 -4
- package/dist/cli/registry.js.map +1 -1
- package/dist/cli-delegate/chunk-HTIU3W56.js +66 -0
- package/dist/cli-delegate/{chunk-2WELHO3P.js → chunk-I5EAFRII.js} +35 -0
- package/dist/cli-delegate/{chunk-ITIQSGOQ.js → chunk-MA4GFWDY.js} +7 -4
- package/dist/cli-delegate/{chunk-PFBV6XRT.js → chunk-Q26HT4QT.js} +1 -63
- package/dist/cli-delegate/{chunk-542DZR4P.js → chunk-REMEZSVP.js} +1660 -146
- package/dist/cli-delegate/{chunk-3EWYC3YK.js → chunk-UEZ7D35A.js} +4 -3
- package/dist/cli-delegate/{chunk-LVRYBKTI.js → chunk-YPAWXXXR.js} +158 -0
- package/dist/cli-delegate/cmd_conformance.js +256 -226
- package/dist/cli-delegate/cmd_doctor.js +3 -2
- package/dist/cli-delegate/cmd_export.js +1 -1
- package/dist/cli-delegate/cmd_handoff.js +21 -28
- package/dist/cli-delegate/cmd_memory_get.js +1 -1
- package/dist/cli-delegate/cmd_prune.js +1 -1
- package/dist/cli-delegate/cmd_route_audit.js +1 -1
- package/dist/cli-delegate/cmd_session_recycle.js +20 -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 +17 -17
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +2 -2
- package/dist/discovery/dormancy-report.md +17 -0
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +3 -3
- package/dist/discovery/trust-report.md +1 -1
- package/dist/discovery/workspaces.json +3 -3
- package/dist/hooks/dispatch.js +114 -7
- package/dist/install/install.mjs +7 -4
- package/dist/mcp/registry-manifest.json +3 -3
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +3755 -1168
- package/docs/guidelines/agent-infra/failure-signatures.md +47 -12
- package/package.json +2 -2
- package/src/agent-src/scripts/archive_completed_roadmaps.ts +35 -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/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 +25 -4
- package/src/scripts/_dispatch.bash +5 -3
- package/src/scripts/_lib/env_kill_switch.ts +37 -0
- package/src/scripts/_lib/orchestration_record.ts +45 -0
- package/src/scripts/_lib/security_lint.ts +18 -4
- package/src/scripts/_lib/self_repair.ts +60 -0
- package/src/scripts/_lib/self_repair_store.ts +65 -5
- package/src/scripts/_lib/subagent_capsule.ts +78 -1
- package/src/scripts/ai_council/clients.ts +31 -0
- package/src/scripts/ai_council/events_log.ts +130 -8
- package/src/scripts/ai_council/orchestrator.ts +50 -3
- package/src/scripts/ai_council/pricing.ts +48 -1
- package/src/scripts/ai_council/prompts.ts +165 -3
- package/src/scripts/ai_council/quorum.ts +30 -0
- package/src/scripts/ai_council/session.ts +11 -0
- package/src/scripts/ai_team/review_gate.ts +2 -2
- package/src/scripts/ask_transport.ts +20 -1
- package/src/scripts/build_discovery_manifest.ts +165 -0
- package/src/scripts/cache_realization_report.ts +38 -0
- package/src/scripts/check_claims.ts +51 -2
- package/src/scripts/check_release_highlights.ts +7 -1
- package/src/scripts/ci_time_ratio.ts +3 -1
- 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/discovery_graph.ts +201 -27
- package/src/scripts/dispatch_economy_report.ts +5 -2
- package/src/scripts/dispatch_r2_reviewer.ts +102 -1
- package/src/scripts/install.ts +20 -6
- package/src/scripts/lint_budget_ownership.ts +81 -0
- package/src/scripts/lint_handoffs.ts +92 -2
- package/src/scripts/lint_hedge_words.ts +317 -0
- package/src/scripts/lint_mcp_config_security.ts +1 -1
- package/src/scripts/lint_skill_frontmatter_safety.ts +56 -2
- 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 +10 -0
- package/src/scripts/report_conformance_funnel.ts +40 -0
- package/src/scripts/schemas/subagent.schema.json +3 -2
- package/src/scripts/self_repair_cli.ts +26 -1
- package/src/scripts/skill_linter.ts +58 -2
|
@@ -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.34.0",
|
|
10
10
|
"keywords": [
|
|
11
11
|
"agent-config",
|
|
12
12
|
"skills",
|
package/CHANGELOG.md
CHANGED
|
@@ -314,107 +314,120 @@ Entry-shape contract: [`docs/contracts/CHANGELOG-conventions.md`](docs/contracts
|
|
|
314
314
|
> keeps the active era under the 250-line drift cap enforced by
|
|
315
315
|
> `tests/test_changelog_eras.py`.
|
|
316
316
|
|
|
317
|
-
# Era: 9.
|
|
317
|
+
# Era: pre-9.34.0 — archived
|
|
318
318
|
|
|
319
|
-
>
|
|
319
|
+
> All entries before `9.34.0` live in
|
|
320
|
+
> [`docs/archive/CHANGELOG-pre-9.34.0.md`](docs/archive/CHANGELOG-pre-9.34.0.md).
|
|
321
|
+
> The archive is read-only; git tags remain the canonical
|
|
322
|
+
> source for what shipped. Splitting them out of the main file
|
|
323
|
+
> keeps the active era under the 250-line drift cap enforced by
|
|
324
|
+
> `tests/test_changelog_eras.py`.
|
|
325
|
+
|
|
326
|
+
# Era: 9.34.x — current
|
|
327
|
+
|
|
328
|
+
> Started at `9.34.0`. Full entries live inline below.
|
|
320
329
|
> The drift test caps this era at 250 lines of entry body; growth past
|
|
321
|
-
> that forces a new era split (`# Era: 9.
|
|
330
|
+
> that forces a new era split (`# Era: 9.35.x`, etc.) — see
|
|
322
331
|
> [`docs/contracts/CHANGELOG-conventions.md § Era splits`](docs/contracts/CHANGELOG-conventions.md).
|
|
323
332
|
|
|
324
|
-
## [9.
|
|
333
|
+
## [9.34.0](https://github.com/event4u-app/agent-config/compare/9.33.0...9.34.0) (2026-08-11)
|
|
325
334
|
|
|
326
335
|
### Release highlights
|
|
327
336
|
|
|
328
337
|
<!-- 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:**
|
|
330
|
-
- **Default changes + migration:**
|
|
331
|
-
- **Security and correctness:**
|
|
338
|
+
- **Behaviour changes:** _none_
|
|
339
|
+
- **Default changes + migration:** _auto-derived, rewrite before merge:_ commits naming a default, migration or migrate in 4420340.
|
|
340
|
+
- **Security and correctness:** _auto-derived, rewrite before merge:_ security-scoped commits in 4420340, b2fc429.
|
|
332
341
|
- **Honest nulls:** _none_
|
|
333
342
|
- **Known limitations:** _none_
|
|
334
343
|
|
|
335
344
|
### Features
|
|
336
345
|
|
|
337
|
-
* **
|
|
338
|
-
* **
|
|
339
|
-
* **
|
|
340
|
-
* **
|
|
341
|
-
* **
|
|
346
|
+
* **handoff-envelope:** a checkable off-limits path list, and a validated reversibility tag ([33fd14c](https://github.com/event4u-app/agent-config/commit/33fd14ca8c8aa3ade0081e5f5bf33b6baef6f3f7))
|
|
347
|
+
* **r2-dispatch:** tell the three stale-artefact states apart, and route each to its contract path ([ca417a1](https://github.com/event4u-app/agent-config/commit/ca417a13ebd7890bbefedec89399add96a3f8eca))
|
|
348
|
+
* **lint-handoffs:** make a blank Open-questions section a finding, not a pass ([a22534b](https://github.com/event4u-app/agent-config/commit/a22534bbf8e80eb5e32d7e547651b8efa55a47dc))
|
|
349
|
+
* **self-repair:** bound record creation per source, and count what the cap refuses ([76aa7b5](https://github.com/event4u-app/agent-config/commit/76aa7b56dd53212f0b4f5d556cae27054bb2a358))
|
|
350
|
+
* **discovery:** add a dormancy report that names an unavailable signal ([99cfa2f](https://github.com/event4u-app/agent-config/commit/99cfa2f632320b7e1300e0d539292e1c038437a6))
|
|
351
|
+
* **discovery-graph:** add a zero-inbound query, per-pass stats and error containment ([ed3d532](https://github.com/event4u-app/agent-config/commit/ed3d5325285476e86fae62c679b6d20cbbff923f))
|
|
352
|
+
* **lint-hedge-words:** diff-scoped advisory hedge lint with a declared stage ([364ef70](https://github.com/event4u-app/agent-config/commit/364ef707dce9e29917d4bc9f5d2b2aeedc4572da))
|
|
353
|
+
* **claims:** bind six external research cites, gate the successor pointer ([37cc8fe](https://github.com/event4u-app/agent-config/commit/37cc8fee84343b8cb92edf7778b97ce235086dc8))
|
|
354
|
+
* **skill-linter:** gate Security constraints on script-bearing skills ([b2fc429](https://github.com/event4u-app/agent-config/commit/b2fc4292540fe140ca9ead90b32bebaac133d2d0))
|
|
355
|
+
* **council:** check a synthesis verdict against its own stance tally ([37103c3](https://github.com/event4u-app/agent-config/commit/37103c3e68efd749dd1d386f3402b8bc0679255d))
|
|
342
356
|
|
|
343
357
|
### Bug Fixes
|
|
344
358
|
|
|
345
|
-
* **
|
|
346
|
-
* **
|
|
347
|
-
* **
|
|
348
|
-
* **
|
|
349
|
-
* **
|
|
350
|
-
* **
|
|
351
|
-
* **
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
*
|
|
356
|
-
* **
|
|
357
|
-
* **roadmap:** P2.2 build half shipped, its threshold unevaluated with a blocker ([1e478fd](https://github.com/event4u-app/agent-config/commit/1e478fdc317fdf12df001c1b98ef264df54a3742))
|
|
358
|
-
* **contracts:** the flow contract documents the self-fix loop and the dod slot ([0ebaaba](https://github.com/event4u-app/agent-config/commit/0ebaabae9e12c75446efefc5be6f6b33b9d0435f))
|
|
359
|
-
* **roadmap:** capability-answerability Phase 1 closed, blocker narrowed to one question ([c37af04](https://github.com/event4u-app/agent-config/commit/c37af045ecbf62b31e6878befdc88d763498d7a9))
|
|
360
|
-
* **rules:** delegation-policy names the capability provenance check ([e05de77](https://github.com/event4u-app/agent-config/commit/e05de771d74e8284e2e64e91e33be66b1bd15e23))
|
|
361
|
-
* **contracts:** the host-capability contract documents six fields, not five ([566b984](https://github.com/event4u-app/agent-config/commit/566b984681d1a1a5ef76643fa6f90f297c284e81))
|
|
362
|
-
|
|
363
|
-
### Tests
|
|
364
|
-
|
|
365
|
-
* **work-engine:** pin the loop contract and update the changed halt shapes ([eb88aa6](https://github.com/event4u-app/agent-config/commit/eb88aa695121a01c0c1e10de9804f1df3424c334))
|
|
359
|
+
* **tests:** satisfy exactOptionalPropertyTypes in the two new spec files ([4f9cd9b](https://github.com/event4u-app/agent-config/commit/4f9cd9b46370920daa0a39aa5cb10a65b70e70a4))
|
|
360
|
+
* **security-lint:** report the corpus a gate actually walked, not the shared default ([4420340](https://github.com/event4u-app/agent-config/commit/4420340cba6f5f091d2b836f21e747878fd71ed3))
|
|
361
|
+
* **roadmap-archival:** never rewrite path strings inside frozen records ([8805814](https://github.com/event4u-app/agent-config/commit/88058140884f14c275737e0e612daee005db2bd7))
|
|
362
|
+
* **review:** re-align the round-3 dispositions and escape the table pipes ([c569ba5](https://github.com/event4u-app/agent-config/commit/c569ba54c95e0d16ab315cb7a5223a33d34f3268))
|
|
363
|
+
* **review:** close the round-3 findings, including four npm ci sites the verify regex could not see ([57867df](https://github.com/event4u-app/agent-config/commit/57867dfd5dbb2d00bbc02deace9c0312e999b423))
|
|
364
|
+
* **review:** repair the round-2 findings, including a self-falsifying cost table ([90cb3ca](https://github.com/event4u-app/agent-config/commit/90cb3caff641d4bb4ef515813b7ec44af92d6636))
|
|
365
|
+
* **lint-hedge-words:** harden the gate scope so the coverage ratchet holds ([d0c9d9e](https://github.com/event4u-app/agent-config/commit/d0c9d9e9b6812d59a7a89e8287bc4b89800aa28d))
|
|
366
|
+
* **council:** let the reserved split label yield to a real option ([30328d8](https://github.com/event4u-app/agent-config/commit/30328d8811bd65f35f2bf42bc6b4fbe8cc76fa4c))
|
|
367
|
+
* **council:** address the R2 completion-review findings ([02c786c](https://github.com/event4u-app/agent-config/commit/02c786c28646da19e8c9cee94ab49b826f91a611))
|
|
368
|
+
* **review:** repair the seven completion-review findings ([efa7cc1](https://github.com/event4u-app/agent-config/commit/efa7cc1d150e0679678db22252dedbbcb838051f))
|
|
369
|
+
* address the nine R2 completion-review findings ([02cdfbb](https://github.com/event4u-app/agent-config/commit/02cdfbb28f04e432cccff7c14ba9f12e177feb0e))
|
|
370
|
+
* **ci-time-ratio:** correct the output-path docstring and register a task target ([1e28e18](https://github.com/event4u-app/agent-config/commit/1e28e1884ea8be49f6b8412e3b1c2d8c7240e9c9))
|
|
366
371
|
|
|
367
|
-
###
|
|
368
|
-
|
|
369
|
-
* **carrier:** re-bind to the post-merge scope — the fixed point ([884104c](https://github.com/event4u-app/agent-config/commit/884104c15d8257579a320932c671b489d96e7b06))
|
|
370
|
-
* **carrier:** re-bind the R2 round to the shipping content, all 6 terminal ([9bbfbc3](https://github.com/event4u-app/agent-config/commit/9bbfbc35388f54c77fdae27315025843a6ea79f5))
|
|
371
|
-
* **carrier:** R2 completion review round 1 — 6 findings, all open ([75be940](https://github.com/event4u-app/agent-config/commit/75be940f4f9bcbf71e1f1248467637fc51c6b63b))
|
|
372
|
+
### Performance
|
|
372
373
|
|
|
373
|
-
|
|
374
|
+
* **tests:** render the proof page once in build_proof.test.ts ([c4d699b](https://github.com/event4u-app/agent-config/commit/c4d699ba61c4ad5a1a19ca292b4d3218748069b5))
|
|
374
375
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
### Release highlights
|
|
378
|
-
|
|
379
|
-
<!-- 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. -->
|
|
380
|
-
- **Behaviour changes:** _none_
|
|
381
|
-
- **Default changes + migration:** _none_
|
|
382
|
-
- **Security and correctness:** _none_
|
|
383
|
-
- **Honest nulls:** _none_
|
|
384
|
-
- **Known limitations:** _none_
|
|
385
|
-
|
|
386
|
-
### Features
|
|
376
|
+
### Documentation
|
|
387
377
|
|
|
388
|
-
* **
|
|
378
|
+
* **dispatch-safety:** close 3.1, 3.2 and 3.3, and record why 3.4 waits for producers ([9efe07e](https://github.com/event4u-app/agent-config/commit/9efe07e11b40eb5231d267f89968045af87163d9))
|
|
379
|
+
* **dispatch-safety:** ADR-109 amendment 4, and close 1.3, 1.4 and 4.1 ([5f7e83a](https://github.com/event4u-app/agent-config/commit/5f7e83ad61488c1098ce5696731664b24a13ac2f))
|
|
380
|
+
* **review:** declare the no-code-surface skip for the org-pack decision ([4a573c0](https://github.com/event4u-app/agent-config/commit/4a573c0565854f0f561de8258eb776b1f51eb1fd))
|
|
381
|
+
* **council:** record the gate-scoped solo-attendance floor as ADR-224 ([686c23d](https://github.com/event4u-app/agent-config/commit/686c23df83b84c33f5bfac5257d1b187a0174f73))
|
|
382
|
+
* **roadmap:** close estate-lifecycle Phases 2-4 and record the two refusals ([f64b7fc](https://github.com/event4u-app/agent-config/commit/f64b7fc87fd6c0701ff5601676f067af2fe024fe))
|
|
383
|
+
* **governance:** separate the two lifecycle vocabularies and answer the deferred field ([212a38c](https://github.com/event4u-app/agent-config/commit/212a38c45622b9ee2329fe2929db2949a2c612de))
|
|
384
|
+
* **decision:** decline the external pack source root ([87f8943](https://github.com/event4u-app/agent-config/commit/87f894310ec1b07d64d86cef7d9b8a3cb5595a0a))
|
|
385
|
+
* **review:** disposition the round-3 findings ([c78afd5](https://github.com/event4u-app/agent-config/commit/c78afd510497d08b3684fc5fe42230b7a82b2af3))
|
|
386
|
+
* **review:** disposition the round-2 findings and preserve both rounds ([59b4561](https://github.com/event4u-app/agent-config/commit/59b45613fdd7eb3ffef275b5062f36c366428015))
|
|
387
|
+
* **review:** re-bind the findings after the gate-hardening fix ([0928422](https://github.com/event4u-app/agent-config/commit/092842250cb6b861e9cc217e0708bc63d411513b))
|
|
388
|
+
* **review:** disposition the seven findings against the repair commit ([910f7c4](https://github.com/event4u-app/agent-config/commit/910f7c4e85886f194f214ceeafe06c2b479b154e))
|
|
389
|
+
* **review:** record the completion-review findings for ci-economy ([d5e1fbd](https://github.com/event4u-app/agent-config/commit/d5e1fbdd3184adc4cd0c4f2a88776ae475e99422))
|
|
390
|
+
* **roadmap:** resolve the council-integrity deferral into a READY follow-up ([94f25c2](https://github.com/event4u-app/agent-config/commit/94f25c25d7911ef9fc177db21dba0e294e7e143a))
|
|
391
|
+
* **review:** re-bind the completion-review findings to the post-fix scope ([0208175](https://github.com/event4u-app/agent-config/commit/0208175e677af8db7632be58e7384209dceae45e))
|
|
392
|
+
* **roadmap:** close 15 of 16 ci-economy steps, cancel the build fan-out ([3a3523d](https://github.com/event4u-app/agent-config/commit/3a3523de29b269b9b580fd9bd071d94cafa0a2cd))
|
|
393
|
+
* **adr:** ADR-223 records no required-check demotion on cost grounds ([6e0d45a](https://github.com/event4u-app/agent-config/commit/6e0d45ae673f2cd8fa8c0e36f09110b4a573de7e))
|
|
394
|
+
* **development:** correct the testing section and document the in-process runner ([53ce1f6](https://github.com/event4u-app/agent-config/commit/53ce1f6fa2ef56ff3bc1737c987dd6e918c81928))
|
|
395
|
+
* **ci-cost-budget:** re-anchor the baseline to CI-recorded figures ([2972545](https://github.com/event4u-app/agent-config/commit/2972545e966319ebf4c632e1931ebc8c084b8816))
|
|
396
|
+
* **review:** R2 completion-review findings for the authoring-contract branch ([d97c428](https://github.com/event4u-app/agent-config/commit/d97c42860ea1ce4b6b63a347c824f00a536d853f))
|
|
397
|
+
* **failure-signatures:** stable ids, per-row drills, capability-claim row ([c18295e](https://github.com/event4u-app/agent-config/commit/c18295e0108955418eabf064502b591432cdeb1a))
|
|
398
|
+
* **skill-writing:** reclassify two unenforced sections, add three patterns ([07d8ce1](https://github.com/event4u-app/agent-config/commit/07d8ce1198699833f0154112831ae7fcf4703ba0))
|
|
399
|
+
* **roadmap:** close council-integrity 2.1 and 3.1, record two premise corrections ([088f7ab](https://github.com/event4u-app/agent-config/commit/088f7ab87de41ecbe21c46d7efefef1ed5f04a60))
|
|
400
|
+
|
|
401
|
+
### Refactoring
|
|
402
|
+
|
|
403
|
+
* one definition of the env kill-switch predicate ([689cc55](https://github.com/event4u-app/agent-config/commit/689cc5558a55ccab4728175955459973a5b03e4e))
|
|
389
404
|
|
|
390
|
-
###
|
|
405
|
+
### Build
|
|
391
406
|
|
|
392
|
-
* **
|
|
393
|
-
* **hooks:** replace the fence regex with a scanner, and stop shipping a moving figure ([2fe01e7](https://github.com/event4u-app/agent-config/commit/2fe01e79804c37380e8c968b6efdf71b7d9d33fa))
|
|
394
|
-
* **hooks:** per-session pin marker, atomic write, enforced read cap ([67abbb6](https://github.com/event4u-app/agent-config/commit/67abbb63028ab79fa6d04083523fbb6ffb9033c3))
|
|
395
|
-
* **scripts:** measure the gate per TURN, and withdraw the figures that were not ([313e665](https://github.com/event4u-app/agent-config/commit/313e665354c1dd0512aceb21475dbc532f6b9ba5))
|
|
396
|
-
* **hooks:** turn-end-gate — key the guard on the turn, not the prompt text ([b3392e6](https://github.com/event4u-app/agent-config/commit/b3392e60ceeae500b639040e8849b801fc661008))
|
|
407
|
+
* **toolchain:** enable tsc incremental buildinfo and the eslint cache ([344bf97](https://github.com/event4u-app/agent-config/commit/344bf979e7c355c1a97d7407706f198fd5bf78ee))
|
|
397
408
|
|
|
398
|
-
###
|
|
409
|
+
### CI
|
|
399
410
|
|
|
400
|
-
* **
|
|
401
|
-
* **evidence:** classify the 109 carrier divergences, and correct two records ([c2fc109](https://github.com/event4u-app/agent-config/commit/c2fc109f7ca30f621455a9a754803055a0b1a0d9))
|
|
402
|
-
* **evidence:** map the scripts settings read path against the server one ([858a256](https://github.com/event4u-app/agent-config/commit/858a25646352fd3603800e5657527591a00e16ae))
|
|
403
|
-
* **review:** record the R2 findings on the fix pass, before touching it ([65aee68](https://github.com/event4u-app/agent-config/commit/65aee68691d85bdba928b4de65f4e28025c80852))
|
|
404
|
-
* **review:** record the R2 findings for turn-end-gate before fixing anything ([9f204c5](https://github.com/event4u-app/agent-config/commit/9f204c55a73a45bada0baa7925bc000df7bee912))
|
|
411
|
+
* **workflows:** add PR-scoped concurrency and flag the bare npm ci calls ([522c052](https://github.com/event4u-app/agent-config/commit/522c05283ea2f5d4b7ca65c5862d21520291f0db))
|
|
405
412
|
|
|
406
|
-
###
|
|
413
|
+
### Chores
|
|
407
414
|
|
|
408
|
-
* **
|
|
409
|
-
* **
|
|
415
|
+
* **roadmap:** regenerate the dashboard after the second main merge ([92bf6fb](https://github.com/event4u-app/agent-config/commit/92bf6fb58e50170176a76d5892098b0d19d21e8c))
|
|
416
|
+
* **dist:** project the reversibility-tag paragraphs into the command tree ([2d33951](https://github.com/event4u-app/agent-config/commit/2d339519eee0dd84b4b876de8222e5503c08d04c))
|
|
417
|
+
* **tests:** drop two dead symbols left by the py2ts parity teardown ([cfecb9d](https://github.com/event4u-app/agent-config/commit/cfecb9dd1466af91791ad60fcdb768a85ab5cf4f))
|
|
418
|
+
* **roadmap:** close council-integrity-followup, open the implementation plan ([6efce85](https://github.com/event4u-app/agent-config/commit/6efce8541f6e3ec48789d2e4dc6333adcfb8148d))
|
|
419
|
+
* **roadmap:** archive install-lifecycle and re-depth its moved links ([6790d85](https://github.com/event4u-app/agent-config/commit/6790d857c0869cf2d08c8d74c149d94dcf0a346b))
|
|
420
|
+
* **tests:** drop the dead tail in the discovery-manifest test ([fe258f9](https://github.com/event4u-app/agent-config/commit/fe258f9da91b594f06837694619a5f6934e5a0dc))
|
|
421
|
+
* **roadmap:** archive the authoring-contract roadmap ([4aea8f7](https://github.com/event4u-app/agent-config/commit/4aea8f7a241a063ed371edd1f53fad31e56340a4))
|
|
410
422
|
|
|
411
|
-
###
|
|
423
|
+
### Other
|
|
412
424
|
|
|
413
|
-
* **
|
|
414
|
-
* **
|
|
415
|
-
* **
|
|
425
|
+
* **council-integrity:** re-bind after merging origin/main a second time ([dd58e0c](https://github.com/event4u-app/agent-config/commit/dd58e0c7c46c27ec0784621096c7f091fd29c44e))
|
|
426
|
+
* **council-integrity:** re-bind after merging origin/main ([eb84ecb](https://github.com/event4u-app/agent-config/commit/eb84ecb6c0bee33c4d9ec43b85b50493badf4b26))
|
|
427
|
+
* **council-integrity:** re-bind the findings artefact to the fixed scope ([267ff3f](https://github.com/event4u-app/agent-config/commit/267ff3f3b4dae46a82bc38a4d1399d93b0304e57))
|
|
428
|
+
* **council-integrity:** record R2 completion-review findings before any fix ([ccf6650](https://github.com/event4u-app/agent-config/commit/ccf6650bbe7287a92e58177d6fe9ef8fc1cbb6a3))
|
|
416
429
|
|
|
417
|
-
Tests:
|
|
430
|
+
Tests: 13068 (+133 since 9.33.0)
|
|
418
431
|
|
|
419
432
|
# Era: pre-4.0.0 — archived
|
|
420
433
|
|
|
@@ -167,9 +167,11 @@ Markdown, no host API). Required fields, in order:
|
|
|
167
167
|
## Contract owed
|
|
168
168
|
{what the current phase must produce before yielding}
|
|
169
169
|
## Decisions
|
|
170
|
-
- {
|
|
170
|
+
- {decision taken, with one-line rationale} {optionally close the line with
|
|
171
|
+
`[reversible]` or `[irreversible]` — those two spellings exactly}
|
|
171
172
|
## Open questions
|
|
172
|
-
- {unresolved items the next session must not silently drop
|
|
173
|
+
- {unresolved items the next session must not silently drop — each as a
|
|
174
|
+
question ending in `?`; write `none` when there genuinely are none}
|
|
173
175
|
## Next command
|
|
174
176
|
{the single command or step to run first on resume}
|
|
175
177
|
```
|
|
@@ -177,7 +179,11 @@ Markdown, no host API). Required fields, in order:
|
|
|
177
179
|
**Resume rule:** a workflow skill's step 0 checks for this file and resumes
|
|
178
180
|
from its contract (mode-inference table) instead of re-deriving state; a
|
|
179
181
|
long phase refreshes the file before yielding. Validated by
|
|
180
|
-
`lint_handoffs.ts` when present — a missing required field is red
|
|
182
|
+
`lint_handoffs.ts` when present — a missing required field is red, and so is an
|
|
183
|
+
`## Open questions` section that answers neither way (blank, or a bare `TBD` /
|
|
184
|
+
`TODO` / `...`). A `?`-terminated question passes; so does an explicit `none` —
|
|
185
|
+
the check exists to stop a blank section reading as an all-clear, not to force a
|
|
186
|
+
question where there is none.
|
|
181
187
|
|
|
182
188
|
**Critical-planning-file safety protocol** (applies to HANDOFF.md and agent
|
|
183
189
|
roadmap edits): read the current file FIRST; take a timestamped backup copy
|
|
@@ -225,6 +231,12 @@ do not auto-execute.
|
|
|
225
231
|
- **Branch name is critical** — always include it.
|
|
226
232
|
- **Open tasks are critical** — the new chat needs to know what's left.
|
|
227
233
|
- **Decisions are important** — prevents the new chat from re-asking settled questions.
|
|
234
|
+
A decision line may close with `[reversible]` or `[irreversible]`, which tells the
|
|
235
|
+
successor "we picked A over B, easy to revisit" apart from "we already migrated the
|
|
236
|
+
data". The tag is optional; those two spellings are the only accepted ones, and a
|
|
237
|
+
near-miss (`[reversble]`, `[Irreversible]`) is a validation error rather than a
|
|
238
|
+
silently untagged line. No claim is made that tagging improves resumption — that
|
|
239
|
+
stays the registered, unmeasured `envelope_resume_success` metric.
|
|
228
240
|
- **File list is optional** — only include if the new chat will need to edit specific files.
|
|
229
241
|
- **NEVER render a printed handoff as live markdown** — see Iron Law above.
|
|
230
242
|
|
|
@@ -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.
|
|
@@ -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).
|
|
@@ -128,12 +128,42 @@ function _branch_touched_paths(root: string, base: string): Set<string> | null {
|
|
|
128
128
|
return out;
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
+
/**
|
|
132
|
+
* Paths where a repo-relative path is DATA, not a live reference — so
|
|
133
|
+
* rewriting it falsifies a record instead of keeping a link resolvable.
|
|
134
|
+
*
|
|
135
|
+
* Two classes, and the second is why this predicate exists at all:
|
|
136
|
+
*
|
|
137
|
+
* - `agents/evidence/**` — a committed record of what was true, or of what a
|
|
138
|
+
* reviewer was shown, at one point in time. Retroactively editing it makes it
|
|
139
|
+
* claim something that did not happen, which is the failure
|
|
140
|
+
* `evaluator-independence` exists to prevent ("the prompt ships with the
|
|
141
|
+
* verdict" is worthless if a later sweep can edit the prompt).
|
|
142
|
+
* - `*.patch` anywhere — a patch's `diff --git a/… b/…` and `+++ b/…` lines are
|
|
143
|
+
* the payload. Rewriting them detaches the patch from the commit it records
|
|
144
|
+
* AND makes `git apply` target a path the diff never created.
|
|
145
|
+
*
|
|
146
|
+
* Measured 2026-08-11: archiving one roadmap rewrote four frozen artefacts
|
|
147
|
+
* under `agents/evidence/reviews/`, including the `diff.patch` headers of a
|
|
148
|
+
* recorded review input. Nothing caught it — the sweep reported it as
|
|
149
|
+
* "4 ref(s) migrated", which reads like success.
|
|
150
|
+
*/
|
|
151
|
+
const _FROZEN_RECORD_PREFIXES: readonly string[] = ['agents/evidence/'];
|
|
152
|
+
|
|
153
|
+
/** Is `rel` a frozen record whose path strings must not be rewritten? */
|
|
154
|
+
export function _is_frozen_record(rel: string): boolean {
|
|
155
|
+
const norm = rel.split(path.sep).join('/');
|
|
156
|
+
return _FROZEN_RECORD_PREFIXES.some((p) => norm.startsWith(p)) || norm.endsWith('.patch');
|
|
157
|
+
}
|
|
158
|
+
|
|
131
159
|
/**
|
|
132
160
|
* Rewrite full-path references `old_rel` → `new_rel` in tracked files.
|
|
133
161
|
*
|
|
134
162
|
* Only the exact repo-relative path is rewritten (bare-filename mentions are
|
|
135
163
|
* left alone). The archived file's own path never matches because the search
|
|
136
|
-
* string is the un-archived path.
|
|
164
|
+
* string is the un-archived path. Frozen records are skipped — see
|
|
165
|
+
* `_is_frozen_record`; a link left dangling in a historical record is correct,
|
|
166
|
+
* because the record describes a tree that no longer exists.
|
|
137
167
|
*/
|
|
138
168
|
function _inbound_ref_rewrite(
|
|
139
169
|
root: string,
|
|
@@ -165,6 +195,10 @@ function _inbound_ref_rewrite(
|
|
|
165
195
|
// skip the roadmap file itself
|
|
166
196
|
continue;
|
|
167
197
|
}
|
|
198
|
+
if (_is_frozen_record(rel)) {
|
|
199
|
+
// A record of a past state — rewriting it falsifies the record.
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
168
202
|
const fp = path.join(root, rel);
|
|
169
203
|
let text: string;
|
|
170
204
|
try {
|
|
@@ -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 };
|