@event4u/agent-config 9.28.0 → 9.29.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/AGENTS.md +6 -6
- package/CHANGELOG.md +66 -0
- package/README.md +1 -1
- package/agents/templates/.ai-council.yml.example +55 -24
- package/dist/agent-src/commands/cost/report.md +2 -2
- package/dist/agent-src/commands/team/adversarial.md +8 -7
- package/dist/agent-src/commands/team/delegate.md +13 -12
- package/dist/agent-src/commands/team/review.md +9 -8
- package/dist/agent-src/commands/team/status.md +9 -8
- package/dist/agent-src/commands/team.md +29 -19
- package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +88 -2
- package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +29 -21
- package/dist/agent-src/contexts/execution/host-capability-manifest.md +26 -15
- package/dist/agent-src/contexts/execution/orchestration-telemetry.md +18 -0
- package/dist/agent-src/contexts/execution/subagent-response-contract.md +54 -0
- package/dist/agent-src/contexts/execution/subagent-routing.md +13 -11
- package/dist/agent-src/contexts/execution/subagent-spawn-contract.md +25 -0
- package/dist/agent-src/contexts/execution/subagent-steering.md +6 -3
- package/dist/agent-src/rules/delegation-policy.md +11 -7
- package/dist/agent-src/rules/settings-ask-protocol.md +8 -7
- package/dist/agent-src/rules/token-budget-discipline.md +1 -1
- package/dist/agent-src/skills/forensics-report/SKILL.md +114 -0
- package/dist/agent-src/skills/forensics-report/evals/triggers.json +17 -0
- package/dist/agent-src/skills/premortem/SKILL.md +30 -1
- package/dist/agent-src/skills/reasoning-orchestrator/SKILL.md +2 -1
- package/dist/agent-src/skills/subagent-orchestration/SKILL.md +7 -5
- package/dist/agent-src/skills/subagent-orchestration/schemas/subagent-status.json +61 -3
- package/dist/agent-src/skills/test-case-discovery/SKILL.md +1 -1
- package/dist/agent-src/templates/AGENTS.md +4 -4
- package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/dist/agent-src/templates/roadmaps.md +23 -0
- package/dist/cli-delegate/{chunk-22GCIJ2O.js → chunk-66OVWGB5.js} +1 -1
- package/dist/cli-delegate/{chunk-GB2FSUEE.js → chunk-LCFJIQ4J.js} +32 -0
- package/dist/cli-delegate/{chunk-VSYT7OHO.js → chunk-LVRYBKTI.js} +31 -2
- package/dist/cli-delegate/{chunk-DVRS2KVR.js → chunk-MMXA5GY7.js} +10 -17
- package/dist/cli-delegate/{chunk-JXARCGVN.js → chunk-MP3JT3IU.js} +1 -1
- package/dist/cli-delegate/{chunk-PQSAQKHW.js → chunk-NZ5N2XQL.js} +3 -3
- package/dist/cli-delegate/{chunk-7OMQCH4V.js → chunk-OJM3MBJM.js} +1 -1
- package/dist/cli-delegate/{chunk-2BE5I2MN.js → chunk-RCIA67XN.js} +111 -90
- package/dist/cli-delegate/cmd_analyze_session.js +1 -1
- package/dist/cli-delegate/cmd_brand_status.js +1 -1
- package/dist/cli-delegate/cmd_conformance.js +6 -43
- package/dist/cli-delegate/cmd_doctor.js +9 -5
- package/dist/cli-delegate/cmd_explain.js +2 -2
- package/dist/cli-delegate/cmd_export.js +4 -4
- package/dist/cli-delegate/cmd_handoff.js +3 -3
- package/dist/cli-delegate/cmd_mcp_available.js +1 -1
- package/dist/cli-delegate/cmd_migrate.js +2 -2
- package/dist/cli-delegate/cmd_packs_active.js +2 -2
- package/dist/cli-delegate/cmd_prune.js +4 -4
- package/dist/cli-delegate/cmd_route_audit.js +2 -2
- package/dist/cli-delegate/cmd_route_explain.js +1 -1
- package/dist/cli-delegate/cmd_settings_get.js +1 -7
- package/dist/cli-delegate/cmd_settings_migrate.js +4 -4
- package/dist/cli-delegate/cmd_settings_set.js +1 -1
- package/dist/cli-delegate/cmd_sync.js +4 -4
- package/dist/cli-delegate/cmd_uninstall.js +4 -4
- package/dist/cli-delegate/cmd_update.js +1 -1
- package/dist/cli-delegate/cmd_upgrade.js +1 -1
- package/dist/cli-delegate/cmd_validate.js +4 -4
- package/dist/cli-delegate/cmd_versions.js +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +69 -20
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +3 -2
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +39 -2
- package/dist/discovery/trust-report.md +2 -2
- package/dist/discovery/workspaces.json +12 -4
- package/dist/hooks/dispatch.js +373 -35
- package/dist/install/install.mjs +42 -17
- package/dist/mcp/registry-manifest.json +2 -2
- package/dist/mcp/server.json +2 -2
- package/dist/mcp/server.mjs +651 -262
- package/dist/router.json +1 -1
- package/dist/scripts/_lib/agent_settings.js +54 -0
- package/dist/scripts/_lib/agent_settings.js.map +1 -1
- package/dist/scripts/condense.js +147 -2
- package/dist/scripts/condense.js.map +1 -1
- package/dist/server/schemas/settings.js +6 -7
- package/dist/server/schemas/settings.js.map +1 -1
- package/dist/shared/settingsCarveOut.js +0 -9
- package/dist/shared/settingsCarveOut.js.map +1 -1
- package/dist/shared/settingsClasses.js +11 -9
- package/dist/shared/settingsClasses.js.map +1 -1
- package/dist/ui/assets/{index-DmR0mbk4.js → index-JDAF00bC.js} +2 -2
- package/dist/ui/assets/{index-DmR0mbk4.js.map → index-JDAF00bC.js.map} +1 -1
- package/dist/ui/index.html +1 -1
- package/docs/contracts/settings-classes.md +39 -9
- package/package.json +1 -1
- package/src/agent-src/templates/AGENTS.md +4 -4
- package/src/config/agent-settings.template.yml +52 -66
- package/src/config/discovery/packs.yml +11 -0
- package/src/config/discovery/workspaces.yml +1 -1
- package/src/config/gate-violation-baselines.json +3 -3
- package/src/scripts/_cli/cmd_conformance.ts +14 -42
- package/src/scripts/_cli/cmd_doctor.ts +65 -48
- package/src/scripts/_lib/agent_settings.ts +58 -0
- package/src/scripts/_lib/auto_dispatch.corpus.test.ts +1 -1
- package/src/scripts/_lib/auto_dispatch.ts +23 -18
- package/src/scripts/_lib/capsule_trigger.ts +124 -0
- package/src/scripts/_lib/host_capability.ts +63 -6
- package/src/scripts/_lib/judgment_ladder.ts +382 -0
- package/src/scripts/_lib/orchestration_gate.ts +8 -0
- package/src/scripts/_lib/orchestration_record.ts +37 -0
- package/src/scripts/_lib/orchestration_savings.ts +1 -1
- package/src/scripts/_lib/self_repair.ts +160 -13
- package/src/scripts/_lib/self_repair_store.ts +28 -0
- package/src/scripts/_lib/subagent_capsule.ts +182 -0
- package/src/scripts/_lib/subagent_response.ts +19 -0
- package/src/scripts/_lib/subagent_spawn.ts +13 -0
- package/src/scripts/_lib/subagent_steering.ts +9 -4
- package/src/scripts/_lib/tier_budget_routing.ts +6 -1
- package/src/scripts/_lib/worker_budget.ts +37 -2
- package/src/scripts/ai_council/clients.ts +76 -54
- package/src/scripts/ai_council/config.ts +94 -6
- package/src/scripts/ai_council/handoff.ts +113 -0
- package/src/scripts/ai_council/modes.ts +19 -4
- package/src/scripts/ai_council/orchestrator.ts +105 -0
- package/src/scripts/ai_council/quorum.ts +84 -0
- package/src/scripts/ai_council/session.ts +44 -0
- package/src/scripts/ai_council/transport_resolver.ts +127 -1
- package/src/scripts/ai_team/availability.ts +110 -0
- package/src/scripts/ai_team/config.ts +34 -14
- package/src/scripts/ai_team/team_dispatch.ts +71 -29
- package/src/scripts/bench_critic_protocol.ts +396 -0
- package/src/scripts/check_detector_corpus.ts +202 -0
- package/src/scripts/check_hook_bundle_freshness.ts +4 -1
- package/src/scripts/condense.ts +162 -2
- package/src/scripts/council_cli.ts +401 -25
- package/src/scripts/forensics_report.ts +333 -0
- package/src/scripts/hooks/delegation_nudge_hook.ts +69 -35
- package/src/scripts/lint_discovery_vocabulary.ts +2 -0
- package/src/scripts/lint_never_silent.ts +276 -0
- package/src/scripts/lint_no_activation_gates.ts +271 -0
- package/src/scripts/orchestration_record.ts +8 -0
- package/src/scripts/rebuild_hook_bundle.ts +177 -0
- package/src/scripts/release.ts +74 -2
- package/src/scripts/routing_doctor.ts +21 -36
- package/src/scripts/score_skill_selection.ts +19 -5
- package/src/scripts/self_repair_cli.ts +287 -57
- package/src/scripts/team_events_spike.ts +271 -0
- package/src/scripts/team_review_gate_hook.ts +31 -9
- package/src/server/schemas/settings.ts +10 -17
- package/src/shared/settingsCarveOut.ts +0 -10
- package/src/shared/settingsClasses.ts +11 -9
package/dist/ui/index.html
CHANGED
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
document.documentElement.setAttribute('data-theme', theme);
|
|
28
28
|
})();
|
|
29
29
|
</script>
|
|
30
|
-
<script type="module" crossorigin src="/assets/index-
|
|
30
|
+
<script type="module" crossorigin src="/assets/index-JDAF00bC.js"></script>
|
|
31
31
|
<link rel="stylesheet" crossorigin href="/assets/index-jSfMW8_t.css">
|
|
32
32
|
</head>
|
|
33
33
|
<body>
|
|
@@ -129,18 +129,51 @@ larger set; it is the set that passes both halves.
|
|
|
129
129
|
| `personal.canary_name` | un-inferrable, and answering arms the session-degradation canary; one keypress to accept the prefill | `""` (canary dark) |
|
|
130
130
|
| `memory.learn_on_session_end` | it turns on automatic memory writes at the end of every session — a standing write the user should authorise | `false` |
|
|
131
131
|
|
|
132
|
+
## The one exception — `emergency.orchestration_halt`
|
|
133
|
+
|
|
134
|
+
The always-on-orchestration doctrine (subagents, council, team) deletes every
|
|
135
|
+
per-layer on/off setting: `subagents.enabled`, `subagents.auto`, and
|
|
136
|
+
`subagents.host_capabilities` are gone from the template, and the layer
|
|
137
|
+
activates on any capable host with an EMPTY settings file. One switch survives
|
|
138
|
+
that deletion on purpose, and it is not the same shape wearing a different
|
|
139
|
+
name.
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
ON-BY-DEFAULT, NOT OFF-BY-DEFAULT. ABSENT OR false MEANS THE STACK RUNS.
|
|
143
|
+
ARMING THE HALT IS CEREMONY-FREE — INCIDENTS ARE URGENT.
|
|
144
|
+
DISARMING IT REQUIRES A NON-EMPTY orchestration_halt_justification.
|
|
145
|
+
INCIDENT-RESPONSE USE ONLY.
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Enforcement, stated honestly (`enforced_by: none`).** The settings file is
|
|
149
|
+
hand-edited YAML — no machine sits on the write path, so the
|
|
150
|
+
justification-on-disarm rule and any per-transition telemetry are
|
|
151
|
+
MODEL-CARRIED conventions, not checked gates (the same honesty stance as
|
|
152
|
+
`security-sensitive-stop`). What IS checked: readers treat only strict
|
|
153
|
+
`true` as halted, and the `no-activation-gates` lint prevents the switch
|
|
154
|
+
from ever growing activation siblings. An agent editing this key follows
|
|
155
|
+
the convention; a human editing it is the owner exercising it.
|
|
156
|
+
|
|
157
|
+
The distinguishing test against "an activation gate under a new name": an
|
|
158
|
+
activation gate is symmetric — flipping it either way costs the same nothing,
|
|
159
|
+
and its purpose is to let a capability sit unused by default. This switch is
|
|
160
|
+
asymmetric by convention — cheap to arm during an incident, costed (a stated
|
|
161
|
+
reason) to disarm, never a silent preference. `subagents.downshift`, `subagents.quota_arbitrage`, and
|
|
162
|
+
`subagents.model_map` are unaffected by the deletion — they tune HOW a
|
|
163
|
+
dispatch runs, not WHETHER the layer exists, so they keep their own C rows.
|
|
164
|
+
|
|
132
165
|
## Counts
|
|
133
166
|
|
|
134
167
|
| Class | Keys |
|
|
135
168
|
|---|---|
|
|
136
169
|
| A — preference | 27 |
|
|
137
170
|
| B — consent | 3 |
|
|
138
|
-
| C — guarded |
|
|
139
|
-
| **Total** | **
|
|
171
|
+
| C — guarded | 107 |
|
|
172
|
+
| **Total** | **137** |
|
|
140
173
|
|
|
141
174
|
The total is every leaf in the template, where *leaf* means anything that is not
|
|
142
|
-
a **non-empty** map. An empty map (`subagents.host_capabilities: {}`) is a real
|
|
143
|
-
configurable value with a real default, so
|
|
175
|
+
a **non-empty** map. An empty map (like the former `subagents.host_capabilities: {}`) is a real
|
|
176
|
+
configurable value with a real default, so such keys count as leaves here — one row more than
|
|
144
177
|
the template↔schema parity test walks, deliberately, because a key with no
|
|
145
178
|
class is exactly what this contract exists to prevent.
|
|
146
179
|
|
|
@@ -229,27 +262,24 @@ Rows follow template order, so a diff against the template reads straight down.
|
|
|
229
262
|
| `screenshots.forbid_terminal_capture` | C | `true` | kill-switch over the highest-leak capture path |
|
|
230
263
|
| `screenshots.data_bearing_gate` | C | `"on"` | the human-confirmation gate over a published egress |
|
|
231
264
|
| `code_style.docblocks` | A | `minimal` | code convention |
|
|
232
|
-
| `subagents.enabled` | C | `true` | kill-switch for the whole subagent layer |
|
|
233
|
-
| `subagents.auto` | C | `"on"` | dispatches work without asking |
|
|
234
265
|
| `subagents.downshift` | C | `true` | routes to another model tier, which is spend and quality |
|
|
235
|
-
| `subagents.budget_routing` | C | `ask` | the budget-aware routing gate |
|
|
236
266
|
| `subagents.quota_arbitrage` | C | `true` | spends from a separate quota pool |
|
|
237
267
|
| `subagents.model_map.lite` | C | `""` | names an external model endpoint |
|
|
238
268
|
| `subagents.model_map.medium` | C | `""` | names an external model endpoint |
|
|
239
269
|
| `subagents.model_map.high` | C | `""` | names an external model endpoint |
|
|
240
|
-
| `subagents.host_capabilities` | C | `{}` | overrides the host capability manifest |
|
|
241
270
|
| `subagents.implementer_model` | C | `""` | names an external model endpoint |
|
|
242
271
|
| `subagents.judge_model` | C | `""` | names an external model endpoint |
|
|
243
272
|
| `subagents.max_parallel` | C | `3` | parallelism cap, and therefore a spend rate |
|
|
244
273
|
| `subagents.adversarial_council` | C | `"off"` | governs a paid verification step |
|
|
245
274
|
| `worktrees.mode` | C | `ask` | standing permission for autonomous worktree creation |
|
|
246
|
-
| `ai_team.enabled` | C | `false` | authorises paid external CLI calls |
|
|
247
275
|
| `ai_team.model` | C | `auto` | names an external model |
|
|
248
276
|
| `ai_team.allow_delegate` | C | `false` | grants an external tool write access to the repository |
|
|
249
277
|
| `ai_team.max_calls_per_day` | C | `50` | quota cap on a shared budget |
|
|
250
278
|
| `ai_team.suppress_setup_hint` | A | `false` | hint cosmetics |
|
|
251
279
|
| `ai_team.review_gate.managed` | C | `false` | governs an upstream review gate |
|
|
252
280
|
| `ai_team.review_gate.max_consecutive_blocks` | C | `3` | circuit-breaker threshold |
|
|
281
|
+
| `emergency.orchestration_halt` | C | `false` | the one audited incident switch over the always-on orchestration stack — see § The one exception above |
|
|
282
|
+
| `emergency.orchestration_halt_justification` | C | `""` | required non-empty before the halt may be lifted; an audit-trail field |
|
|
253
283
|
| `onboarding.onboarded` | C | `false` | flipping it bypasses the onboarding gate |
|
|
254
284
|
| `commands.auto_detect` | C | `enabled` | kill-switch for orchestrator auto-detection |
|
|
255
285
|
| `commands.suggestion.enabled` | A | `true` | a convenience layer; governs no gate and no spend |
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@event4u/agent-config",
|
|
3
3
|
"mcpName": "io.github.event4u-app/agent-config",
|
|
4
|
-
"version": "9.
|
|
4
|
+
"version": "9.29.0",
|
|
5
5
|
"description": "Governed skills, rules and commands for AI coding tools (Claude Code, Cursor, Windsurf, Copilot) — every claim machine-checked, including \"zero runtime daemon\".",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"private": false,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# {{project_name}}
|
|
2
2
|
|
|
3
|
-
<!-- Fill placeholders or run `/agents init`; delete after.
|
|
3
|
+
<!-- Fill placeholders or run `/agents init`; delete after. Recipes: `.augment/contexts/contracts/agents-md-anatomy.md`. -->
|
|
4
4
|
|
|
5
5
|
> {{project_description}}
|
|
6
6
|
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
|
|
9
9
|
| Layer | Location | Edits |
|
|
10
10
|
|---|---|---|
|
|
11
|
-
| Installed package | `.augment/`, `dist/agent-src/` |
|
|
12
|
-
| Project layer | `agents/`, `agents/overrides/`, `.agent-settings.yml` | your customizations
|
|
11
|
+
| Installed package | `.augment/`, `dist/agent-src/` | managed by `event4u/agent-config` |
|
|
12
|
+
| Project layer | `agents/`, `agents/overrides/`, `.agent-settings.yml` | your customizations |
|
|
13
13
|
|
|
14
14
|
## Pointers
|
|
15
15
|
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
- **Skills (on-demand expertise)** — domain skills surfaced by description, invoked on trigger match: [`.augment/skills/`](.augment/skills/).
|
|
19
19
|
- **Commands (workflows)** — slash-commands the agent runs end-to-end (`/work`, `/create-pr`, …): [`.augment/commands/`](.augment/commands/).
|
|
20
20
|
- **Project-specific docs** — your own architecture notes, roadmaps, sessions, contexts: [`agents/`](agents/).
|
|
21
|
-
- **Delegation & review** — dispatch independent-slice tasks to subagents instead of serial work; a mutating session ends after a neutral cross-model review: [`delegation-policy`](.augment/rules/delegation-policy.md).
|
|
21
|
+
- **Delegation & review** — dispatch independent-slice tasks to subagents instead of serial work; in a team (host-flag gated) the lead coordinates, teammates implement; a mutating session ends after a neutral cross-model review: [`delegation-policy`](.augment/rules/delegation-policy.md).
|
|
22
22
|
|
|
23
23
|
## Emergency triage — read this when nothing else is reachable
|
|
24
24
|
|
|
@@ -231,7 +231,8 @@ cost:
|
|
|
231
231
|
# separate tier cap — the global ceilings above still apply and the
|
|
232
232
|
# budget-routing relation works purely off them. Set a value to cap one
|
|
233
233
|
# tier (e.g. cheap: 10 keeps haiku-class delegation under $10/day-window
|
|
234
|
-
# of the ledger).
|
|
234
|
+
# of the ledger). Informational since the budget_routing key was removed
|
|
235
|
+
# (always-on orchestration): routing is judgment-ladder-driven.
|
|
235
236
|
per_tier:
|
|
236
237
|
cheap: null
|
|
237
238
|
medium: null
|
|
@@ -743,60 +744,27 @@ code_style:
|
|
|
743
744
|
|
|
744
745
|
# --- Subagent orchestration ---
|
|
745
746
|
#
|
|
746
|
-
#
|
|
747
|
-
# subagent
|
|
748
|
-
# auto
|
|
749
|
-
#
|
|
747
|
+
# Always-on orchestration (road-to-always-on-orchestration Phase 1): the
|
|
748
|
+
# subagent layer carries no per-run on/off setting. `subagents.enabled`,
|
|
749
|
+
# `subagents.auto`, and `subagents.host_capabilities` were REMOVED — a fresh
|
|
750
|
+
# install with this section untouched still activates auto-dispatch on any
|
|
751
|
+
# host whose capability probe reports a subagent primitive. Capability is a
|
|
752
|
+
# fact resolved from the host (registry + a live environment probe), never a
|
|
753
|
+
# setting; the one surviving incident-only control is `emergency.
|
|
754
|
+
# orchestration_halt` below. A leftover `subagents.enabled` / `subagents.auto`
|
|
755
|
+
# / `subagents.host_capabilities` key from an older install is ignored (one
|
|
756
|
+
# deprecation-warning line on load, per-key, per run).
|
|
757
|
+
#
|
|
758
|
+
# What remains below tunes HOW a delegated sub-task runs, never WHETHER the
|
|
759
|
+
# layer exists. Empty values fall back to the runtime defaults described in
|
|
760
|
+
# .augment/contexts/subagent-configuration.md and
|
|
750
761
|
# .augment/contexts/execution/auto-orchestration-activation.md.
|
|
751
762
|
subagents:
|
|
752
|
-
# Global master switch for the whole subagent layer.
|
|
753
|
-
# true (default) = the layer is available; false = fully disabled, the
|
|
754
|
-
# canonical kill-switch (no auto-dispatch, no model routing, in-session only).
|
|
755
|
-
enabled: true
|
|
756
|
-
|
|
757
|
-
# Automatic-dispatch mode: off | ask | on
|
|
758
|
-
#
|
|
759
|
-
# off = never auto-dispatch; subagents only via an explicit command.
|
|
760
|
-
# ask = classify the task; when delegable, ask once before dispatching.
|
|
761
|
-
# on = auto-dispatch delegable tasks without asking (surface the choice
|
|
762
|
-
# in one line).
|
|
763
|
-
#
|
|
764
|
-
# SHIPPED default is `on` on hosts whose capability manifest reports
|
|
765
|
-
# `subagent_spawn: true`, and `off` on hosts without a subagent primitive.
|
|
766
|
-
# Auto-dispatch stays a no-op wherever the manifest reports
|
|
767
|
-
# `subagent_spawn: false`, regardless of this value.
|
|
768
|
-
#
|
|
769
|
-
# The default was `ask` until 2026-07-09, when it was flipped to `on` after a
|
|
770
|
-
# re-evaluation (agents/settings/contexts/orchestration-default-flip-verdict.md
|
|
771
|
-
# § 2026-07-09; ADR-117). The flip rests on a bounded-downside argument, NOT a
|
|
772
|
-
# passed benchmark: delegable slices are already cost-routed to the cheapest
|
|
773
|
-
# capable tier, classification fires only on real structural signals (never
|
|
774
|
-
# unstructured or tiny work), and every return is verified — so `on` cannot
|
|
775
|
-
# delegate frontier-priced or speculative work. `resolveShippedDefault()`
|
|
776
|
-
# remains the telemetry-driven DEMOTION gate: a measured regression demotes
|
|
777
|
-
# back to `ask`.
|
|
778
|
-
auto: "on"
|
|
779
|
-
|
|
780
763
|
# Route delegable sub-tasks to the lowest-capable model tier (cost + speed
|
|
781
764
|
# via model downshift). true (default) = downshift per declared model_tier;
|
|
782
765
|
# false = every subagent runs on the session tier.
|
|
783
766
|
downshift: true
|
|
784
767
|
|
|
785
|
-
# Budget-aware cheap-request delegation (docs/contracts/budget-routing.md).
|
|
786
|
-
# Picks the cheapest CLASSIFIER-ADEQUATE tier that has available budget
|
|
787
|
-
# (cost.budgets.per_tier above); cheap exhausted but strong funded → strong
|
|
788
|
-
# tier; everything exhausted → session model + notice. Work is never
|
|
789
|
-
# blocked to save money, and the session model is never switched — routing
|
|
790
|
-
# happens as delegation with a model override. DISTINCT from `downshift`
|
|
791
|
-
# above: downshift is the quality/cost trade-off knob, budget_routing is
|
|
792
|
-
# the resource-availability gate (council 2026-08-03).
|
|
793
|
-
# ask = (default) first budget-motivated downshift of a session asks once
|
|
794
|
-
# auto = apply the relation silently (telemetry line per routed request)
|
|
795
|
-
# off = today's behavior; single-flip rollback — QUOTE it ("off") when
|
|
796
|
-
# editing: bare off is YAML-1.1 boolean false (readers coerce, but
|
|
797
|
-
# the quoted form is the unambiguous one, same as `auto: "on"`)
|
|
798
|
-
budget_routing: ask
|
|
799
|
-
|
|
800
768
|
# Prefer a separate-quota-pool model for delegable sub-tasks WHERE the host
|
|
801
769
|
# manifest reports `separate_quota_pool: true` (e.g. a subscription whose
|
|
802
770
|
# Sonnet allowance is distinct from Opus). Optional bonus only — behaviour is
|
|
@@ -811,12 +779,6 @@ subagents:
|
|
|
811
779
|
medium: ""
|
|
812
780
|
high: ""
|
|
813
781
|
|
|
814
|
-
# Optional host-capability override (see
|
|
815
|
-
# .augment/contexts/execution/host-capability-manifest.md). Any field set
|
|
816
|
-
# here wins; any field omitted falls back to the all-false safe default.
|
|
817
|
-
# Leave empty to let the agent resolve the manifest from host knowledge.
|
|
818
|
-
host_capabilities: {}
|
|
819
|
-
|
|
820
782
|
# Model for implementer subagents (empty = same tier as the session model)
|
|
821
783
|
implementer_model: ""
|
|
822
784
|
|
|
@@ -878,17 +840,23 @@ worktrees:
|
|
|
878
840
|
|
|
879
841
|
# --- AI Team (cross-model strong-pair review — /team family) ---
|
|
880
842
|
#
|
|
881
|
-
#
|
|
882
|
-
#
|
|
883
|
-
#
|
|
884
|
-
#
|
|
885
|
-
#
|
|
843
|
+
# One strong external model (via the codex CLI, subscription-authed)
|
|
844
|
+
# reviews inside the repo — the depth complement to the council's breadth.
|
|
845
|
+
# Schema + validation contract: `docs/contracts/ai-team-config.md`. The
|
|
846
|
+
# loader (`src/scripts/ai_team/config.ts`) rejects unknown keys fail-closed.
|
|
847
|
+
#
|
|
848
|
+
# Always-on orchestration (road-to-always-on-orchestration Phase 1, Step
|
|
849
|
+
# 1.3): `/team` carries no per-run on/off setting — `enabled` was REMOVED.
|
|
850
|
+
# A fresh install with this section untouched still surfaces `/team` when
|
|
851
|
+
# the codex CLI resolves on $PATH AND some auth for it is detectable
|
|
852
|
+
# (subscription login, API key, key file, or env key); otherwise every
|
|
853
|
+
# invocation degrades with one clear "codex CLI not available" line
|
|
854
|
+
# instead of a silent enabled:false refusal. Verify with `agent-config
|
|
855
|
+
# doctor --check team`. The one surviving incident-only control is
|
|
856
|
+
# `emergency.orchestration_halt` below. A leftover `enabled` key from an
|
|
857
|
+
# older install is accepted and ignored (one deprecation-warning line on
|
|
858
|
+
# load, per run).
|
|
886
859
|
ai_team:
|
|
887
|
-
# Master switch. false (default) = /team commands are never suggested
|
|
888
|
-
# and every invocation refuses with an enable pointer; true = the
|
|
889
|
-
# family is live (individual gates below still apply).
|
|
890
|
-
enabled: false
|
|
891
|
-
|
|
892
860
|
# Model handed to the codex CLI. 'auto' (default) = pass NO --model
|
|
893
861
|
# flag, the codex CLI's own default applies — this tracks the
|
|
894
862
|
# subscription's current strongest model instead of pinning a stale
|
|
@@ -897,8 +865,9 @@ ai_team:
|
|
|
897
865
|
|
|
898
866
|
# Second opt-in for the ONLY wrapper that delegates write access
|
|
899
867
|
# (/team:delegate → the plugin's native-Codex worker). false (default)
|
|
900
|
-
# = delegate refuses
|
|
901
|
-
#
|
|
868
|
+
# = delegate refuses even when /team itself is available. Availability
|
|
869
|
+
# (codex CLI installed + authenticated) is necessary but not
|
|
870
|
+
# sufficient — this key must ALSO be true before delegation is reachable.
|
|
902
871
|
allow_delegate: false
|
|
903
872
|
|
|
904
873
|
# Per-day cap on team calls. Team calls count into the EXISTING
|
|
@@ -934,6 +903,23 @@ ai_team:
|
|
|
934
903
|
# Positive integer.
|
|
935
904
|
max_consecutive_blocks: 3
|
|
936
905
|
|
|
906
|
+
# --- Emergency orchestration halt (the one incident-only kill switch) ---
|
|
907
|
+
#
|
|
908
|
+
# NOT an activation gate — see docs/contracts/settings-classes.md § "The one
|
|
909
|
+
# exception". The always-on orchestration stack (subagents, council, team)
|
|
910
|
+
# has no per-layer on/off setting; this is the single audited switch that
|
|
911
|
+
# survives, for incident response only.
|
|
912
|
+
emergency:
|
|
913
|
+
# false (default) = the stack runs normally. Flipping this to true requires
|
|
914
|
+
# no ceremony — incidents are urgent. Flipping it back to false requires
|
|
915
|
+
# `orchestration_halt_justification` below to be a non-empty string; both
|
|
916
|
+
# transitions emit one telemetry line (enum/bool fields only).
|
|
917
|
+
orchestration_halt: false
|
|
918
|
+
|
|
919
|
+
# Required non-empty before `orchestration_halt` may return to false.
|
|
920
|
+
# Ignored while the halt is being armed (arming is ceremony-free).
|
|
921
|
+
orchestration_halt_justification: ""
|
|
922
|
+
|
|
937
923
|
# --- Onboarding ---
|
|
938
924
|
#
|
|
939
925
|
# Tracks whether the initial setup flow (/onboard) has been completed
|
|
@@ -162,6 +162,17 @@
|
|
|
162
162
|
size_class: small
|
|
163
163
|
default_install: false
|
|
164
164
|
|
|
165
|
+
- id: forensics
|
|
166
|
+
label: Forensic Evidence
|
|
167
|
+
description: Machine-derived release evidence from git history alone — hotspot risk (change frequency x complexity) and change-coupling analyzers; deterministic, read-only, advisory to the release findings pipeline.
|
|
168
|
+
workspaces: [engineering]
|
|
169
|
+
requires: [engineering-base]
|
|
170
|
+
trust_level_default: experimental
|
|
171
|
+
surface_tier: lab
|
|
172
|
+
domain: engineering
|
|
173
|
+
size_class: small
|
|
174
|
+
default_install: false
|
|
175
|
+
|
|
165
176
|
- id: python
|
|
166
177
|
label: Python
|
|
167
178
|
description: Python-language patterns.
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
description: Code, tests, CI, reviews, architecture.
|
|
14
14
|
example_roles: [Developer, CTO, Tech Lead]
|
|
15
15
|
default_packs: [engineering-base, git]
|
|
16
|
-
optional_packs: [php, laravel, symfony, javascript, typescript, react, nextjs, python, frontend-design, brand, analysis-workbench, scale-discipline, history-discipline]
|
|
16
|
+
optional_packs: [php, laravel, symfony, javascript, typescript, react, nextjs, python, frontend-design, brand, analysis-workbench, scale-discipline, history-discipline, forensics]
|
|
17
17
|
|
|
18
18
|
- id: product
|
|
19
19
|
label: Product
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"$comment": "Violation ratchet for gates whose dead scan root was repaired. A repair REVEALS pre-existing debt; it does not create it. Each entry records the count revealed at repair time — the gate fails only when its count RISES. Lowering a count is a normal commit; raising one is a defect. Entries expire: a baseline that has not dropped within 56 days of `landed` (or of `reaffirmed.date`) fails its gate, because a number that never moves is suppression with extra steps. Mechanism + rationale: src/scripts/_lib/gate_baseline.ts. Decision: AI council 2026-08-02, roadmap road-to-gates-that-can-fail blocker `dead-gate-finding-triage`.",
|
|
3
3
|
"gates": {
|
|
4
4
|
"check_no_new_legacy_path:hardcoded-scan-roots": {
|
|
5
|
-
"count":
|
|
6
|
-
"landed": "2026-08-
|
|
7
|
-
"note": "Lines under src/scripts/**/*.{ts,mts,mjs} that pass the retired `.agent-src.uncondensed` directory into `path.join(...)` — a filesystem path CONSTRUCTED against the tree ADR-051 abandoned, which is the exact shape of all 14 dead gates. Deliberately narrow so the number is signal, not noise: 236 raw mentions under src/scripts → 147 string-literal lines → 67 path-constructing lines when the pass was written, after exempting src/scripts/_lib/agent_src.ts (the shared resolver, whose job IS owning the constant — gates that route through it survived the move). Detectors holding the literal as data to match, strip, or print are not counted, and no prose, docs, tests or fixtures are read: that full-tree shape was measured at 44 files / 213 hits and rejected as the wrong lint (see the note in check_no_new_legacy_path.ts::find_offenders). Recorded at 58 rather than 67 because Phase 1's scan-root repairs were landing on this branch while the pass was being written and had already removed 9 — a baseline above the truth silently permits new violations. This count goes to ZERO as the remaining repairs land; every repair is a lowering commit. Lowered 56→51 by the road-to-renewal-foundation Phase 1 dead-root sweep (check_always_budget, check_portability, check_references, lint_framework_leakage, lint_agents_md). Lowered 51→49 by the gate-hardening adoption PR: skill_collision_clusters and skill_overlap were repointed at the live skills tree via the shared resolver — two gates that had been reading the retired container and scoring 0 of 288 skills."
|
|
5
|
+
"count": 48,
|
|
6
|
+
"landed": "2026-08-09",
|
|
7
|
+
"note": "Lines under src/scripts/**/*.{ts,mts,mjs} that pass the retired `.agent-src.uncondensed` directory into `path.join(...)` — a filesystem path CONSTRUCTED against the tree ADR-051 abandoned, which is the exact shape of all 14 dead gates. Deliberately narrow so the number is signal, not noise: 236 raw mentions under src/scripts → 147 string-literal lines → 67 path-constructing lines when the pass was written, after exempting src/scripts/_lib/agent_src.ts (the shared resolver, whose job IS owning the constant — gates that route through it survived the move). Detectors holding the literal as data to match, strip, or print are not counted, and no prose, docs, tests or fixtures are read: that full-tree shape was measured at 44 files / 213 hits and rejected as the wrong lint (see the note in check_no_new_legacy_path.ts::find_offenders). Recorded at 58 rather than 67 because Phase 1's scan-root repairs were landing on this branch while the pass was being written and had already removed 9 — a baseline above the truth silently permits new violations. This count goes to ZERO as the remaining repairs land; every repair is a lowering commit. Lowered 56→51 by the road-to-renewal-foundation Phase 1 dead-root sweep (check_always_budget, check_portability, check_references, lint_framework_leakage, lint_agents_md). Lowered 51→49 by the gate-hardening adoption PR: skill_collision_clusters and skill_overlap were repointed at the live skills tree via the shared resolver — two gates that had been reading the retired container and scoring 0 of 288 skills. Lowered 49→48 by road-to-rule-delivery-integrity P2.2: score_skill_selection was repointed at the live skills tree via the shared resolver. It is the same shape as the two gates lowered before it — a scorer reading the retired container and scoring 0 of 288 skills — and here the consequence was sharper than a dead gate: the roadmap's pre-registered selection-accuracy criteria would have been compared against a baseline of silent zeros."
|
|
8
8
|
},
|
|
9
9
|
"audit_user_type_axis": {
|
|
10
10
|
"count": 1,
|
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
* (b) router-pointers — dist/router.json ids + routes_to resolve on disk
|
|
11
11
|
* (c) hook-dispatcher — dispatcher answers synthetic session_start/stop
|
|
12
12
|
* (d) lean-projection — lean_projection.mode matches projected artifacts
|
|
13
|
-
* (e) host-manifest — subagents.host_capabilities
|
|
13
|
+
* (e) host-manifest — a leftover subagents.host_capabilities override
|
|
14
|
+
* is deprecated + ignored (always-on orchestration
|
|
15
|
+
* resolves capability from a probe/registry only)
|
|
14
16
|
*
|
|
15
17
|
* All checks are deterministic — no LLM, no network. Exit contract:
|
|
16
18
|
* 0 = every check ok/skipped (warns allowed) and doctor --ci green
|
|
@@ -421,14 +423,6 @@ export function _check_lean_projection(
|
|
|
421
423
|
// Check (e) — host-capability manifest parses strictly + matches detection.
|
|
422
424
|
// ---------------------------------------------------------------------------
|
|
423
425
|
|
|
424
|
-
const HOST_MANIFEST_KEYS = new Set([
|
|
425
|
-
'schema_version',
|
|
426
|
-
'subagent_spawn',
|
|
427
|
-
'parallel_spawn',
|
|
428
|
-
'status_polling',
|
|
429
|
-
'separate_quota_pool',
|
|
430
|
-
]);
|
|
431
|
-
|
|
432
426
|
export function _check_host_manifest(projectRoot: string): Dict {
|
|
433
427
|
const detected = Object.entries(detectToolPresence(projectRoot))
|
|
434
428
|
.filter(([, v]) => v === true)
|
|
@@ -441,7 +435,7 @@ export function _check_host_manifest(projectRoot: string): Dict {
|
|
|
441
435
|
return {
|
|
442
436
|
id: 'host-manifest',
|
|
443
437
|
status: 'ok',
|
|
444
|
-
message: `no .agent-settings.yml —
|
|
438
|
+
message: `no .agent-settings.yml — host capability is always probe/registry-resolved (${detectedNote})`,
|
|
445
439
|
remedy: '',
|
|
446
440
|
};
|
|
447
441
|
}
|
|
@@ -462,44 +456,22 @@ export function _check_host_manifest(projectRoot: string): Dict {
|
|
|
462
456
|
return {
|
|
463
457
|
id: 'host-manifest',
|
|
464
458
|
status: 'ok',
|
|
465
|
-
message: `no host_capabilities override —
|
|
459
|
+
message: `no host_capabilities override — host capability is always probe/registry-resolved (${detectedNote})`,
|
|
466
460
|
remedy: '',
|
|
467
461
|
};
|
|
468
462
|
}
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
};
|
|
476
|
-
}
|
|
477
|
-
const problems: string[] = [];
|
|
478
|
-
for (const [key, value] of Object.entries(manifest as Dict)) {
|
|
479
|
-
if (!HOST_MANIFEST_KEYS.has(key)) {
|
|
480
|
-
problems.push(`unknown key '${key}'`);
|
|
481
|
-
continue;
|
|
482
|
-
}
|
|
483
|
-
if (key === 'schema_version') {
|
|
484
|
-
if (value !== 1) problems.push(`schema_version must be 1 (got ${JSON.stringify(value)})`);
|
|
485
|
-
continue;
|
|
486
|
-
}
|
|
487
|
-
if (typeof value !== 'boolean') {
|
|
488
|
-
problems.push(`'${key}' must be boolean (got ${JSON.stringify(value)})`);
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
if (problems.length > 0) {
|
|
492
|
-
return {
|
|
493
|
-
id: 'host-manifest',
|
|
494
|
-
status: 'fail',
|
|
495
|
-
message: `host_capabilities malformed: ${problems.slice(0, 4).join('; ')}`,
|
|
496
|
-
remedy: 'only schema_version:1 + four boolean capability fields are valid',
|
|
497
|
-
};
|
|
498
|
-
}
|
|
463
|
+
// Always-on orchestration (road-to-always-on-orchestration Phase 1)
|
|
464
|
+
// deleted `subagents.host_capabilities` as a live override — capability
|
|
465
|
+
// now resolves ONLY from the host probe/registry. A leftover key is
|
|
466
|
+
// therefore inert: its shape no longer matters, so this no longer fails
|
|
467
|
+
// on an unknown key or a non-boolean value — there is nothing left for a
|
|
468
|
+
// malformed override to break.
|
|
499
469
|
return {
|
|
500
470
|
id: 'host-manifest',
|
|
501
471
|
status: 'ok',
|
|
502
|
-
message:
|
|
472
|
+
message:
|
|
473
|
+
`subagents.host_capabilities is deprecated and ignored — host capability is ` +
|
|
474
|
+
`always probe/registry-resolved (${detectedNote})`,
|
|
503
475
|
remedy: '',
|
|
504
476
|
};
|
|
505
477
|
}
|
|
@@ -1050,7 +1050,7 @@ function _check_lockfile_freshness(manifest: Dict): Dict {
|
|
|
1050
1050
|
}
|
|
1051
1051
|
|
|
1052
1052
|
/** `shutil.which(name)` — first PATH hit (with PATHEXT on win32). */
|
|
1053
|
-
function shutilWhich(name: string): string | null {
|
|
1053
|
+
export function shutilWhich(name: string): string | null {
|
|
1054
1054
|
if (path.dirname(name) !== '.' && (name.includes('/') || name.includes('\\'))) {
|
|
1055
1055
|
// Has a path component: check directly.
|
|
1056
1056
|
return isExecutableFile(name) ? name : null;
|
|
@@ -2065,6 +2065,31 @@ function osErrorStr(exc: unknown): string {
|
|
|
2065
2065
|
const _CLI_PROVIDER_META: Readonly<Record<string, readonly [string, boolean]>> =
|
|
2066
2066
|
PROVIDER_CLI_META;
|
|
2067
2067
|
|
|
2068
|
+
/**
|
|
2069
|
+
* m5 fix (independent-review finding) — `MemberConfig.mode` is the RAW
|
|
2070
|
+
* per-member override only (`config.ts::_build_member` never writes the
|
|
2071
|
+
* `defaults.mode`-resolved value back onto it); a member that never sets
|
|
2072
|
+
* `mode:` locally has `member.mode === null` regardless of what the
|
|
2073
|
+
* council's global default is. `defaults.mode` shipped `'auto'` as its own
|
|
2074
|
+
* default (road-to-always-on-orchestration Phase 3.1), so the common,
|
|
2075
|
+
* unconfigured case for every member is `null` here — and `auto` may
|
|
2076
|
+
* legitimately resolve to the `cli` rung, exactly the case
|
|
2077
|
+
* `config.ts::_build_member`'s own binary-override validation already
|
|
2078
|
+
* accounts for ("`auto` may resolve to the cli rung, so a binary override
|
|
2079
|
+
* is legitimate there too"). A check gated on the literal `mode === 'cli'`
|
|
2080
|
+
* misses every `auto`/unset member, honouring neither its binary override
|
|
2081
|
+
* nor its quota — silently, for the majority default shape.
|
|
2082
|
+
*/
|
|
2083
|
+
function _effectiveMemberMode(member: ai_council_config.MemberConfig, cfg: ai_council_config.CouncilConfig): string {
|
|
2084
|
+
return member.mode ?? cfg.defaults.mode;
|
|
2085
|
+
}
|
|
2086
|
+
|
|
2087
|
+
/** True when `member` might run over CLI transport — `cli` pinned, or `auto` (which may resolve to it). */
|
|
2088
|
+
function _mayRunOverCli(member: ai_council_config.MemberConfig, cfg: ai_council_config.CouncilConfig): boolean {
|
|
2089
|
+
const mode = _effectiveMemberMode(member, cfg);
|
|
2090
|
+
return mode === 'cli' || mode === 'auto';
|
|
2091
|
+
}
|
|
2092
|
+
|
|
2068
2093
|
function _check_council_cli(project_root: string): Dict {
|
|
2069
2094
|
// Python wraps the council-module import in a try/except ImportError so a
|
|
2070
2095
|
// broken council install degrades to a `warn` instead of crashing doctor.
|
|
@@ -2097,7 +2122,7 @@ function _check_council_cli(project_root: string): Dict {
|
|
|
2097
2122
|
}
|
|
2098
2123
|
const cli_members: Array<[string, ai_council_config.MemberConfig]> = [];
|
|
2099
2124
|
for (const [name, m] of cfg.members.entries()) {
|
|
2100
|
-
if (m.enabled && m
|
|
2125
|
+
if (m.enabled && _mayRunOverCli(m, cfg) && name in _CLI_PROVIDER_META) {
|
|
2101
2126
|
cli_members.push([name, m]);
|
|
2102
2127
|
}
|
|
2103
2128
|
}
|
|
@@ -2216,11 +2241,12 @@ function _codex_home(): string {
|
|
|
2216
2241
|
|
|
2217
2242
|
/**
|
|
2218
2243
|
* Codex binary name for the team check — REUSES the council probe's binary
|
|
2219
|
-
* discovery: when a council config exists and declares an enabled
|
|
2220
|
-
*
|
|
2221
|
-
*
|
|
2222
|
-
*
|
|
2223
|
-
*
|
|
2244
|
+
* discovery: when a council config exists and declares an enabled `openai`
|
|
2245
|
+
* member whose effective mode is `cli` (pinned) OR `auto` (may resolve to
|
|
2246
|
+
* `cli` — see `_mayRunOverCli`) with a `binary` override, honour it; else
|
|
2247
|
+
* the provider default from `_CLI_PROVIDER_META` (`codex`). Never throws —
|
|
2248
|
+
* an unreadable or invalid council config falls back to the default binary
|
|
2249
|
+
* (the council-cli check owns reporting that problem).
|
|
2224
2250
|
*/
|
|
2225
2251
|
function _team_codex_binary_name(project_root: string): string {
|
|
2226
2252
|
const default_bin = (_CLI_PROVIDER_META['openai'] as [string, boolean])[0];
|
|
@@ -2236,21 +2262,12 @@ function _team_codex_binary_name(project_root: string): string {
|
|
|
2236
2262
|
return default_bin;
|
|
2237
2263
|
}
|
|
2238
2264
|
const member = cfg.members.get('openai');
|
|
2239
|
-
if (member && member.enabled && member
|
|
2265
|
+
if (member && member.enabled && _mayRunOverCli(member, cfg) && member.binary) {
|
|
2240
2266
|
return member.binary;
|
|
2241
2267
|
}
|
|
2242
2268
|
return default_bin;
|
|
2243
2269
|
}
|
|
2244
2270
|
|
|
2245
|
-
/** Settings-flag coercion shared with the tier-usage check (bool or string). */
|
|
2246
|
-
function _settings_flag(val: unknown): boolean {
|
|
2247
|
-
if (typeof val === 'boolean') return val;
|
|
2248
|
-
if (typeof val === 'string') {
|
|
2249
|
-
return ['true', 'yes', 'on', '1'].includes(val.trim().toLowerCase());
|
|
2250
|
-
}
|
|
2251
|
-
return false;
|
|
2252
|
-
}
|
|
2253
|
-
|
|
2254
2271
|
/**
|
|
2255
2272
|
* Decode a JWT payload's `exp` claim (epoch seconds) — base64 decode only,
|
|
2256
2273
|
* NO signature verification, no network. Non-JWT / undecodable → null.
|
|
@@ -2364,9 +2381,16 @@ function _read_ai_team_block(project_root: string): Dict {
|
|
|
2364
2381
|
* loop bound (`max_consecutive_blocks`, Phase 4 — unbuilt) is absent
|
|
2365
2382
|
* → WARN.
|
|
2366
2383
|
*
|
|
2367
|
-
*
|
|
2368
|
-
*
|
|
2369
|
-
*
|
|
2384
|
+
* Availability, not a setting (road-to-always-on-orchestration Phase 1,
|
|
2385
|
+
* Step 1.3): `ai_team.enabled` was DELETED — `/team`'s on/off state is the
|
|
2386
|
+
* codex binary + auth facts (a) computes below, mirroring
|
|
2387
|
+
* `checkCodexAvailability()` (`src/scripts/ai_team/availability.ts`).
|
|
2388
|
+
* Absent feature ≠ broken feature: with BOTH the binary and auth absent the
|
|
2389
|
+
* check reports ok ("team unavailable (default) — codex CLI not
|
|
2390
|
+
* installed") — a normal starting state, not a misconfiguration; WARN
|
|
2391
|
+
* fires only when something was set up PARTWAY (binary without auth, a
|
|
2392
|
+
* managed Review-Gate with an invalid bound, …) or a real sub-signal
|
|
2393
|
+
* fails.
|
|
2370
2394
|
*/
|
|
2371
2395
|
// ---------------------------------------------------------------------------
|
|
2372
2396
|
// detection check (road-to-zero-ceremony-detection Phases 3 + 4)
|
|
@@ -2526,36 +2550,11 @@ function _check_detection(project_root: string): Dict {
|
|
|
2526
2550
|
|
|
2527
2551
|
function _check_team(project_root: string): Dict {
|
|
2528
2552
|
const ai_team = _read_ai_team_block(project_root);
|
|
2529
|
-
const enabled = _settings_flag(ai_team['enabled']);
|
|
2530
2553
|
const gateRaw = ai_team['review_gate'];
|
|
2531
2554
|
const gate =
|
|
2532
2555
|
typeof gateRaw === 'object' && gateRaw !== null && !Array.isArray(gateRaw)
|
|
2533
2556
|
? (gateRaw as Dict)
|
|
2534
2557
|
: {};
|
|
2535
|
-
const gate_managed = _settings_flag(gate['managed']);
|
|
2536
|
-
|
|
2537
|
-
if (!enabled) {
|
|
2538
|
-
if (gate_managed) {
|
|
2539
|
-
return {
|
|
2540
|
-
id: 'team',
|
|
2541
|
-
status: 'warn',
|
|
2542
|
-
message:
|
|
2543
|
-
'half-configured: ai_team.review_gate.managed is on but ' +
|
|
2544
|
-
'ai_team.enabled is false — the gate never runs',
|
|
2545
|
-
remedy:
|
|
2546
|
-
'set `ai_team.enabled: true` in .agent-settings.yml, or ' +
|
|
2547
|
-
'remove `ai_team.review_gate.managed`',
|
|
2548
|
-
};
|
|
2549
|
-
}
|
|
2550
|
-
return {
|
|
2551
|
-
id: 'team',
|
|
2552
|
-
status: 'ok',
|
|
2553
|
-
message: 'team mode not configured (default-off)',
|
|
2554
|
-
remedy:
|
|
2555
|
-
'opt in via `ai_team.enabled: true` in .agent-settings.yml, ' +
|
|
2556
|
-
'then re-run `agent-config doctor --check team`',
|
|
2557
|
-
};
|
|
2558
|
-
}
|
|
2559
2558
|
|
|
2560
2559
|
const remedies: string[] = [];
|
|
2561
2560
|
|
|
@@ -2563,7 +2562,8 @@ function _check_team(project_root: string): Dict {
|
|
|
2563
2562
|
const binary_name = _team_codex_binary_name(project_root);
|
|
2564
2563
|
const binary_resolved = shutilWhich(binary_name);
|
|
2565
2564
|
const binary_glyph = binary_resolved !== null ? '✅' : '❌';
|
|
2566
|
-
|
|
2565
|
+
const binary_missing = binary_resolved === null;
|
|
2566
|
+
if (binary_missing) {
|
|
2567
2567
|
remedies.push('install the codex CLI: `npm install -g @openai/codex`');
|
|
2568
2568
|
}
|
|
2569
2569
|
|
|
@@ -2613,7 +2613,8 @@ function _check_team(project_root: string): Dict {
|
|
|
2613
2613
|
// (c) Review-Gate governance (Phase 4) — logic lives in
|
|
2614
2614
|
// src/scripts/ai_team/review_gate.ts (upstream gate probe + WARN
|
|
2615
2615
|
// states, incl. plugin-gate-on-while-unmanaged with the quoted
|
|
2616
|
-
// upstream cost warning).
|
|
2616
|
+
// upstream cost warning). Independent of /team's own availability —
|
|
2617
|
+
// `managed` governs the codex PLUGIN's own Stop-hook loop.
|
|
2617
2618
|
const gate_signal = review_gate_doctor_signal(project_root, gate);
|
|
2618
2619
|
const gate_str = gate_signal.gate_str;
|
|
2619
2620
|
remedies.push(...gate_signal.remedies);
|
|
@@ -2621,6 +2622,21 @@ function _check_team(project_root: string): Dict {
|
|
|
2621
2622
|
const detail =
|
|
2622
2623
|
`codex binary ${binary_glyph} (${binary_name}) · ` +
|
|
2623
2624
|
`${auth_str} · ${plugin_str} · ${gate_str}`;
|
|
2625
|
+
|
|
2626
|
+
if (binary_missing && !authed) {
|
|
2627
|
+
// Neither the binary nor auth is present — /team simply is not set
|
|
2628
|
+
// up on this machine yet. CLI-first doctrine (road-to-always-on-
|
|
2629
|
+
// orchestration Phase 1, Step 1.3): this is a normal starting
|
|
2630
|
+
// state, not a misconfiguration — still surface the full detail
|
|
2631
|
+
// (e.g. a `review_gate.managed` left on) so nothing is hidden.
|
|
2632
|
+
return {
|
|
2633
|
+
id: 'team',
|
|
2634
|
+
status: 'ok',
|
|
2635
|
+
message: `team unavailable (default) — codex CLI not installed · ${detail}`,
|
|
2636
|
+
remedy: remedies.join('; '),
|
|
2637
|
+
};
|
|
2638
|
+
}
|
|
2639
|
+
|
|
2624
2640
|
if (remedies.length > 0) {
|
|
2625
2641
|
return {
|
|
2626
2642
|
id: 'team',
|
|
@@ -2632,7 +2648,7 @@ function _check_team(project_root: string): Dict {
|
|
|
2632
2648
|
return {
|
|
2633
2649
|
id: 'team',
|
|
2634
2650
|
status: 'ok',
|
|
2635
|
-
message: `team
|
|
2651
|
+
message: `team available · ${detail}`,
|
|
2636
2652
|
remedy: '',
|
|
2637
2653
|
};
|
|
2638
2654
|
}
|
|
@@ -3556,6 +3572,7 @@ export {
|
|
|
3556
3572
|
_foreign_records,
|
|
3557
3573
|
_check_scope,
|
|
3558
3574
|
_check_manifest_integrity,
|
|
3575
|
+
_team_codex_binary_name,
|
|
3559
3576
|
_check_lockfile_freshness,
|
|
3560
3577
|
_check_global_binary,
|
|
3561
3578
|
_check_claude_plugin,
|