@event4u/agent-config 9.27.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.
Files changed (220) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/AGENTS.md +13 -12
  3. package/CHANGELOG.md +165 -0
  4. package/README.md +1 -1
  5. package/agents/templates/.ai-council.yml.example +55 -24
  6. package/dist/agent-src/commands/analyze/conformance.md +24 -0
  7. package/dist/agent-src/commands/cost/report.md +2 -2
  8. package/dist/agent-src/commands/team/adversarial.md +8 -7
  9. package/dist/agent-src/commands/team/delegate.md +13 -12
  10. package/dist/agent-src/commands/team/review.md +9 -8
  11. package/dist/agent-src/commands/team/status.md +9 -8
  12. package/dist/agent-src/commands/team.md +29 -19
  13. package/dist/agent-src/contexts/execution/auto-dispatch-classification.md +88 -2
  14. package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +29 -21
  15. package/dist/agent-src/contexts/execution/host-capability-manifest.md +26 -15
  16. package/dist/agent-src/contexts/execution/orchestration-telemetry.md +28 -3
  17. package/dist/agent-src/contexts/execution/subagent-response-contract.md +54 -0
  18. package/dist/agent-src/contexts/execution/subagent-routing.md +13 -11
  19. package/dist/agent-src/contexts/execution/subagent-spawn-contract.md +25 -0
  20. package/dist/agent-src/contexts/execution/subagent-steering.md +6 -3
  21. package/dist/agent-src/rules/artifact-engagement-recording.md +4 -1
  22. package/dist/agent-src/rules/autonomous-execution.md +1 -1
  23. package/dist/agent-src/rules/brand-source-of-truth.md +33 -6
  24. package/dist/agent-src/rules/context-hygiene.md +3 -1
  25. package/dist/agent-src/rules/council-availability.md +93 -0
  26. package/dist/agent-src/rules/cross-source-consistency.md +3 -0
  27. package/dist/agent-src/rules/delegation-policy.md +38 -10
  28. package/dist/agent-src/rules/design-fidelity.md +3 -0
  29. package/dist/agent-src/rules/evaluator-independence.md +2 -1
  30. package/dist/agent-src/rules/external-code-graph-interop.md +2 -1
  31. package/dist/agent-src/rules/finance-safety-floor.md +1 -1
  32. package/dist/agent-src/rules/git-history-discipline.md +1 -1
  33. package/dist/agent-src/rules/history-discipline.md +3 -1
  34. package/dist/agent-src/rules/legal-safety-floor.md +1 -1
  35. package/dist/agent-src/rules/no-pr-progress-comments.md +3 -1
  36. package/dist/agent-src/rules/onboarding-gate.md +3 -1
  37. package/dist/agent-src/rules/roadmap-ci-steps-policy.md +4 -1
  38. package/dist/agent-src/rules/role-mode-adherence.md +1 -1
  39. package/dist/agent-src/rules/scale-discipline.md +3 -1
  40. package/dist/agent-src/rules/self-repair-loop.md +103 -0
  41. package/dist/agent-src/rules/session-canary.md +2 -1
  42. package/dist/agent-src/rules/settings-ask-protocol.md +8 -7
  43. package/dist/agent-src/rules/strategy-safety-floor.md +1 -1
  44. package/dist/agent-src/rules/token-budget-discipline.md +4 -2
  45. package/dist/agent-src/rules/tool-safety.md +5 -1
  46. package/dist/agent-src/skills/adversarial-review/SKILL.md +1 -1
  47. package/dist/agent-src/skills/analysis-autonomous-mode/SKILL.md +1 -1
  48. package/dist/agent-src/skills/forensics-report/SKILL.md +114 -0
  49. package/dist/agent-src/skills/forensics-report/evals/triggers.json +17 -0
  50. package/dist/agent-src/skills/performance-analysis/SKILL.md +1 -1
  51. package/dist/agent-src/skills/persona-improvement/SKILL.md +1 -1
  52. package/dist/agent-src/skills/premortem/SKILL.md +30 -1
  53. package/dist/agent-src/skills/project-analyzer/SKILL.md +1 -1
  54. package/dist/agent-src/skills/reasoning-orchestrator/SKILL.md +2 -1
  55. package/dist/agent-src/skills/security-audit/SKILL.md +1 -1
  56. package/dist/agent-src/skills/sequential-thinking/SKILL.md +1 -1
  57. package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +1 -1
  58. package/dist/agent-src/skills/subagent-orchestration/SKILL.md +7 -5
  59. package/dist/agent-src/skills/subagent-orchestration/schemas/subagent-status.json +61 -3
  60. package/dist/agent-src/skills/test-case-discovery/SKILL.md +1 -1
  61. package/dist/agent-src/skills/universal-project-analysis/SKILL.md +1 -1
  62. package/dist/agent-src/templates/AGENTS.md +8 -12
  63. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  64. package/dist/agent-src/templates/roadmaps.md +23 -0
  65. package/dist/cli/registry.js +7 -0
  66. package/dist/cli/registry.js.map +1 -1
  67. package/dist/cli-delegate/chunk-66OVWGB5.js +270 -0
  68. package/dist/cli-delegate/{chunk-HJ6DAJHR.js → chunk-LCFJIQ4J.js} +89 -7
  69. package/dist/cli-delegate/{chunk-VSYT7OHO.js → chunk-LVRYBKTI.js} +31 -2
  70. package/dist/cli-delegate/{chunk-DVRS2KVR.js → chunk-MMXA5GY7.js} +10 -17
  71. package/dist/cli-delegate/{chunk-WR6GTRHJ.js → chunk-MP3JT3IU.js} +3 -3
  72. package/dist/cli-delegate/{chunk-3KJIMFTB.js → chunk-NZ5N2XQL.js} +467 -305
  73. package/dist/cli-delegate/{chunk-AIIUU73N.js → chunk-OJM3MBJM.js} +1 -1
  74. package/dist/cli-delegate/{chunk-BCPIOAGV.js → chunk-RCIA67XN.js} +117 -96
  75. package/dist/cli-delegate/chunk-REKCMYOU.js +2991 -0
  76. package/dist/cli-delegate/cmd_analyze_session.js +1 -1
  77. package/dist/cli-delegate/cmd_brand_status.js +134 -0
  78. package/dist/cli-delegate/cmd_conformance.js +10 -47
  79. package/dist/cli-delegate/cmd_converge.js +3 -3
  80. package/dist/cli-delegate/cmd_doctor.js +10 -6
  81. package/dist/cli-delegate/cmd_explain.js +80 -330
  82. package/dist/cli-delegate/cmd_export.js +6 -6
  83. package/dist/cli-delegate/cmd_fleet.js +3 -3
  84. package/dist/cli-delegate/cmd_handoff.js +3 -3
  85. package/dist/cli-delegate/cmd_mcp_available.js +433 -0
  86. package/dist/cli-delegate/cmd_migrate.js +3 -3
  87. package/dist/cli-delegate/cmd_packs_active.js +153 -0
  88. package/dist/cli-delegate/cmd_preflight.js +1 -1
  89. package/dist/cli-delegate/cmd_prune.js +6 -6
  90. package/dist/cli-delegate/cmd_route_audit.js +8 -8
  91. package/dist/cli-delegate/cmd_route_explain.js +4 -4
  92. package/dist/cli-delegate/cmd_settings_get.js +266 -0
  93. package/dist/cli-delegate/cmd_settings_migrate.js +6 -6
  94. package/dist/cli-delegate/cmd_settings_set.js +8 -2968
  95. package/dist/cli-delegate/cmd_sync.js +6 -6
  96. package/dist/cli-delegate/cmd_uninstall.js +6 -6
  97. package/dist/cli-delegate/cmd_update.js +4 -4
  98. package/dist/cli-delegate/cmd_upgrade.js +4 -4
  99. package/dist/cli-delegate/cmd_validate.js +6 -6
  100. package/dist/cli-delegate/cmd_versions.js +4 -4
  101. package/dist/discovery/deprecation-report.md +1 -1
  102. package/dist/discovery/discovery-manifest.json +164 -55
  103. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  104. package/dist/discovery/discovery-manifest.summary.md +4 -3
  105. package/dist/discovery/orphan-report.md +1 -1
  106. package/dist/discovery/packs.json +44 -5
  107. package/dist/discovery/trust-report.md +11 -11
  108. package/dist/discovery/workspaces.json +16 -6
  109. package/dist/hooks/dispatch.js +9341 -6131
  110. package/dist/install/install.mjs +739 -524
  111. package/dist/mcp/registry-manifest.json +3 -3
  112. package/dist/mcp/server.json +2 -2
  113. package/dist/mcp/server.mjs +777 -281
  114. package/dist/router.json +1 -1
  115. package/dist/scripts/_lib/agent_settings.js +134 -15
  116. package/dist/scripts/_lib/agent_settings.js.map +1 -1
  117. package/dist/scripts/condense.js +147 -2
  118. package/dist/scripts/condense.js.map +1 -1
  119. package/dist/server/schemas/settings.js +6 -7
  120. package/dist/server/schemas/settings.js.map +1 -1
  121. package/dist/shared/settingsCarveOut.js +0 -9
  122. package/dist/shared/settingsCarveOut.js.map +1 -1
  123. package/dist/shared/settingsClasses.js +11 -9
  124. package/dist/shared/settingsClasses.js.map +1 -1
  125. package/dist/ui/assets/{index-DmR0mbk4.js → index-JDAF00bC.js} +2 -2
  126. package/dist/ui/assets/{index-DmR0mbk4.js.map → index-JDAF00bC.js.map} +1 -1
  127. package/dist/ui/index.html +1 -1
  128. package/docs/contracts/settings-classes.md +68 -17
  129. package/docs/guidelines/agent-infra/memory-access.md +14 -3
  130. package/package.json +1 -1
  131. package/src/agent-src/templates/AGENTS.md +8 -12
  132. package/src/config/agent-settings.template.yml +52 -66
  133. package/src/config/budgets.yml +29 -0
  134. package/src/config/discovery/packs.yml +11 -0
  135. package/src/config/discovery/workspaces.yml +1 -1
  136. package/src/config/evaluator-budgets.json +4 -4
  137. package/src/config/gate-coverage.yml +26 -0
  138. package/src/config/gate-violation-baselines.json +3 -3
  139. package/src/scripts/_cli/cmd_brand_status.ts +174 -0
  140. package/src/scripts/_cli/cmd_conformance.ts +14 -42
  141. package/src/scripts/_cli/cmd_doctor.ts +65 -48
  142. package/src/scripts/_cli/cmd_mcp_available.ts +266 -0
  143. package/src/scripts/_cli/cmd_packs_active.ts +225 -0
  144. package/src/scripts/_cli/cmd_settings_get.ts +324 -0
  145. package/src/scripts/_dispatch.bash +57 -0
  146. package/src/scripts/_lib/agent_settings.ts +140 -16
  147. package/src/scripts/_lib/auto_dispatch.corpus.test.ts +1 -1
  148. package/src/scripts/_lib/auto_dispatch.ts +23 -18
  149. package/src/scripts/_lib/capsule_trigger.ts +124 -0
  150. package/src/scripts/_lib/carrier_divergence.ts +135 -0
  151. package/src/scripts/_lib/host_capability.ts +144 -4
  152. package/src/scripts/_lib/judgment_ladder.ts +382 -0
  153. package/src/scripts/_lib/orchestration_gate.ts +8 -0
  154. package/src/scripts/_lib/orchestration_record.ts +37 -0
  155. package/src/scripts/_lib/orchestration_savings.ts +1 -1
  156. package/src/scripts/_lib/prompt_shape.ts +88 -0
  157. package/src/scripts/_lib/review_skipped_record.ts +102 -0
  158. package/src/scripts/_lib/rule_layer_overlap.ts +254 -0
  159. package/src/scripts/_lib/self_repair.ts +489 -0
  160. package/src/scripts/_lib/self_repair_store.ts +128 -0
  161. package/src/scripts/_lib/subagent_capsule.ts +182 -0
  162. package/src/scripts/_lib/subagent_response.ts +19 -0
  163. package/src/scripts/_lib/subagent_spawn.ts +13 -0
  164. package/src/scripts/_lib/subagent_steering.ts +9 -4
  165. package/src/scripts/_lib/tier_budget_routing.ts +6 -1
  166. package/src/scripts/_lib/transcript_entry.ts +80 -0
  167. package/src/scripts/_lib/worker_budget.ts +37 -2
  168. package/src/scripts/ai_council/clients.ts +76 -54
  169. package/src/scripts/ai_council/config.ts +94 -6
  170. package/src/scripts/ai_council/handoff.ts +113 -0
  171. package/src/scripts/ai_council/modes.ts +19 -4
  172. package/src/scripts/ai_council/orchestrator.ts +105 -0
  173. package/src/scripts/ai_council/quorum.ts +84 -0
  174. package/src/scripts/ai_council/session.ts +44 -0
  175. package/src/scripts/ai_council/transport_resolver.ts +127 -1
  176. package/src/scripts/ai_team/availability.ts +110 -0
  177. package/src/scripts/ai_team/config.ts +34 -14
  178. package/src/scripts/ai_team/team_dispatch.ts +71 -29
  179. package/src/scripts/bench_critic_protocol.ts +396 -0
  180. package/src/scripts/check_branch_freshness.ts +255 -0
  181. package/src/scripts/check_council_config_location.ts +125 -1
  182. package/src/scripts/check_detector_corpus.ts +202 -0
  183. package/src/scripts/check_hook_bundle_freshness.ts +4 -1
  184. package/src/scripts/check_standing_rule_delivery.ts +314 -0
  185. package/src/scripts/condense.ts +162 -2
  186. package/src/scripts/config/profiles.ts +13 -3
  187. package/src/scripts/conformance_scan.ts +272 -24
  188. package/src/scripts/council_availability_hook.ts +188 -0
  189. package/src/scripts/council_cli.ts +527 -32
  190. package/src/scripts/forensics_report.ts +333 -0
  191. package/src/scripts/hook_manifest.yaml +107 -26
  192. package/src/scripts/hooks/block_no_verify.ts +39 -2
  193. package/src/scripts/hooks/block_unauthorized_git.ts +156 -7
  194. package/src/scripts/hooks/concern_registry.ts +10 -0
  195. package/src/scripts/hooks/delegation_nudge_hook.ts +484 -0
  196. package/src/scripts/hooks/end_review_nudge_hook.ts +726 -0
  197. package/src/scripts/hooks/orchestration_record_hook.ts +342 -0
  198. package/src/scripts/install.ts +151 -0
  199. package/src/scripts/language_mirror_hook.ts +30 -37
  200. package/src/scripts/lint_discovery_vocabulary.ts +2 -0
  201. package/src/scripts/lint_never_silent.ts +276 -0
  202. package/src/scripts/lint_no_activation_gates.ts +271 -0
  203. package/src/scripts/measure_scope_dedup.ts +19 -13
  204. package/src/scripts/onboarding_gate_hook.ts +40 -1
  205. package/src/scripts/orchestration_record.ts +12 -1
  206. package/src/scripts/preamble_byte_census.ts +9 -20
  207. package/src/scripts/rebuild_hook_bundle.ts +177 -0
  208. package/src/scripts/release.ts +74 -2
  209. package/src/scripts/report_carrier_divergence.ts +364 -0
  210. package/src/scripts/report_skill_activation.ts +257 -0
  211. package/src/scripts/report_skill_obligation_violations.ts +579 -0
  212. package/src/scripts/routing_doctor.ts +95 -39
  213. package/src/scripts/score_skill_selection.ts +19 -5
  214. package/src/scripts/self_repair_cli.ts +470 -0
  215. package/src/scripts/self_repair_hook.ts +241 -0
  216. package/src/scripts/team_events_spike.ts +271 -0
  217. package/src/scripts/team_review_gate_hook.ts +31 -9
  218. package/src/server/schemas/settings.ts +10 -17
  219. package/src/shared/settingsCarveOut.ts +0 -10
  220. package/src/shared/settingsClasses.ts +11 -9
@@ -0,0 +1,174 @@
1
+ /**
2
+ * `agent-config brand:status` — is a consumer brand layer present, and where.
3
+ *
4
+ * Phase 2.4 of `road-to-capability-answerability`. `brand-source-of-truth` makes
5
+ * a precedence claim — a registered brand outranks the curated corpus — and an
6
+ * agent can only honour it by knowing whether a registered brand EXISTS. Before
7
+ * this verb the rule named the artefact and no path at all, so "is there a
8
+ * consumer brand here" was answerable only by guessing a filename, and the
9
+ * silent failure is the expensive one: the corpus quietly supplies defaults and
10
+ * the output looks fine.
11
+ *
12
+ * ## The filename defect this verb exposes
13
+ *
14
+ * The rule names `.tokens.json`, with a leading dot, four times. The only real
15
+ * resolver in the tree — `BRAND_TOKEN_PATHS` in the UI scaffold directive —
16
+ * looks for `tokens.json`, without one, in four conventional locations. A
17
+ * consumer who followed the rule literally would author a file the resolver can
18
+ * never find, and nothing would report it. So this verb searches the canonical
19
+ * list AND separately reports a dot-prefixed file sitting beside it, because
20
+ * "you have a brand file in the wrong place" is a different answer from "you
21
+ * have no brand".
22
+ *
23
+ * The path list is IMPORTED from the resolver rather than restated. A probe with
24
+ * its own copy of the search order is a second answer waiting to disagree with
25
+ * the first, which is the whole defect class this roadmap closes.
26
+ *
27
+ * Read-only by construction. Exit code is always `0`: "no brand layer" is a
28
+ * legitimate answer (greenfield), not a failure.
29
+ */
30
+
31
+ import * as fs from 'node:fs';
32
+ import * as path from 'node:path';
33
+ import process from 'node:process';
34
+ import { fileURLToPath, pathToFileURL } from 'node:url';
35
+
36
+ import { resolve_project_root } from '../_lib/agent_settings.js';
37
+ import { BRAND_TOKEN_PATHS } from '../../agent-src/templates/scripts/work_engine/directives/ui/scaffold.js';
38
+
39
+ export interface BrandStatusOptions {
40
+ cwd: string;
41
+ json: boolean;
42
+ }
43
+
44
+ export interface BrandStatusResult {
45
+ code: 0;
46
+ out: string[];
47
+ err: string[];
48
+ }
49
+
50
+ /** The first canonical path holding a tokens file under `root`, or `null`. */
51
+ export function findBrandTokens(root: string): string | null {
52
+ for (const rel of BRAND_TOKEN_PATHS) {
53
+ try {
54
+ if (fs.statSync(path.join(root, rel)).isFile()) return rel;
55
+ } catch {
56
+ continue;
57
+ }
58
+ }
59
+ return null;
60
+ }
61
+
62
+ /**
63
+ * Dot-prefixed near-misses — a `.tokens.json` beside each canonical location.
64
+ *
65
+ * These are files a consumer plausibly created by following the rule's own
66
+ * wording, and every one of them is invisible to the resolver.
67
+ */
68
+ export function findDottedNearMisses(root: string): string[] {
69
+ const found: string[] = [];
70
+ for (const rel of BRAND_TOKEN_PATHS) {
71
+ const dotted = path.join(path.dirname(rel), `.${path.basename(rel)}`);
72
+ const normalised = dotted.startsWith('./') ? dotted.slice(2) : dotted;
73
+ try {
74
+ if (fs.statSync(path.join(root, normalised)).isFile()) found.push(normalised);
75
+ } catch {
76
+ continue;
77
+ }
78
+ }
79
+ return found;
80
+ }
81
+
82
+ export function runBrandStatus(opts: BrandStatusOptions): BrandStatusResult {
83
+ const out: string[] = [];
84
+ const [projectRoot] = resolve_project_root(null, { cwd: opts.cwd });
85
+ const found = findBrandTokens(projectRoot);
86
+ const nearMisses = findDottedNearMisses(projectRoot);
87
+
88
+ if (opts.json) {
89
+ out.push(
90
+ JSON.stringify(
91
+ {
92
+ brand_layer_present: found !== null,
93
+ tokens_file: found,
94
+ searched: [...BRAND_TOKEN_PATHS],
95
+ dotted_near_misses: nearMisses,
96
+ project_root: projectRoot,
97
+ },
98
+ null,
99
+ 2,
100
+ ),
101
+ );
102
+ return { code: 0, out, err: [] };
103
+ }
104
+
105
+ if (found !== null) {
106
+ out.push(`brand layer present — ${found}`);
107
+ out.push(' brand-source-of-truth applies: these tokens outrank the corpus.');
108
+ } else {
109
+ out.push('brand layer none');
110
+ out.push(` searched ${BRAND_TOKEN_PATHS.join(', ')}`);
111
+ out.push(' meaning no consumer brand to be authoritative. The corpus is the only');
112
+ out.push(' ground, and every emitted value is corpus-sourced — which is the');
113
+ out.push(' greenfield branch of brand-source-of-truth, not a misconfiguration.');
114
+ }
115
+
116
+ if (nearMisses.length > 0) {
117
+ out.push(
118
+ '',
119
+ '⚠️ A dot-prefixed tokens file exists and is NOT read by anything:',
120
+ ...nearMisses.map((m) => ` ${m}`),
121
+ ' The resolver searches `tokens.json`, never `.tokens.json`. Rename it to one',
122
+ ' of the searched paths above, or it stays invisible while looking authored.',
123
+ );
124
+ }
125
+
126
+ return { code: 0, out, err: [] };
127
+ }
128
+
129
+ interface ParsedArgv {
130
+ ok: boolean;
131
+ message?: string;
132
+ json?: boolean;
133
+ }
134
+
135
+ export function parseArgv(argv: readonly string[]): ParsedArgv {
136
+ let json = false;
137
+ for (const a of argv) {
138
+ if (a === '--json') {
139
+ json = true;
140
+ } else if (a === '-h' || a === '--help') {
141
+ return { ok: false, message: 'usage: agent-config brand:status [--json]' };
142
+ } else {
143
+ return { ok: false, message: `unknown argument: ${a}` };
144
+ }
145
+ }
146
+ return { ok: true, json };
147
+ }
148
+
149
+ export function main(argv: readonly string[] = process.argv.slice(2)): number {
150
+ const parsed = parseArgv(argv);
151
+ if (!parsed.ok) {
152
+ process.stderr.write(`${parsed.message ?? 'usage error'}\n`);
153
+ return 2;
154
+ }
155
+ const result = runBrandStatus({ cwd: process.cwd(), json: parsed.json === true });
156
+ for (const line of result.out) process.stdout.write(`${line}\n`);
157
+ for (const line of result.err) process.stderr.write(`${line}\n`);
158
+ return result.code;
159
+ }
160
+
161
+ function _isCliEntry(): boolean {
162
+ if (process.argv[1] === undefined) return false;
163
+ const argvUrl = pathToFileURL(path.resolve(process.argv[1])).href;
164
+ if (import.meta.url === argvUrl) return true;
165
+ try {
166
+ return fs.realpathSync(fileURLToPath(import.meta.url)) === fs.realpathSync(path.resolve(process.argv[1]));
167
+ } catch {
168
+ return false;
169
+ }
170
+ }
171
+
172
+ if (_isCliEntry()) {
173
+ process.exitCode = main();
174
+ }
@@ -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 parses strictly
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 — safe-default manifest applies (${detectedNote})`,
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 — safe-default manifest applies (${detectedNote})`,
459
+ message: `no host_capabilities override — host capability is always probe/registry-resolved (${detectedNote})`,
466
460
  remedy: '',
467
461
  };
468
462
  }
469
- if (typeof manifest !== 'object' || Array.isArray(manifest)) {
470
- return {
471
- id: 'host-manifest',
472
- status: 'fail',
473
- message: 'subagents.host_capabilities is not a mapping',
474
- remedy: 'use the four boolean fields from the host-capability manifest contract',
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: `host_capabilities override parses strictly (${detectedNote})`,
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.mode === 'cli' && name in _CLI_PROVIDER_META) {
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 cli-mode
2220
- * `openai` member with a `binary` override, honour it; else the provider
2221
- * default from `_CLI_PROVIDER_META` (`codex`). Never throws — an unreadable
2222
- * or invalid council config falls back to the default binary (the council-cli
2223
- * check owns reporting that problem).
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.mode === 'cli' && member.binary) {
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
- * Absent feature ≠ broken feature: with `ai_team` absent or disabled the
2368
- * check reports ok ("team mode not configured (default-off)"); WARN fires
2369
- * only on failing sub-signals or inconsistent half-configured states.
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
- if (binary_resolved === null) {
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 mode enabled · ${detail}`,
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,