ai-consultants 5.1.1 → 5.2.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 (48) hide show
  1. package/.claude/commands/ai-consultants:consult.md +21 -5
  2. package/.env.example +84 -44
  3. package/CLAUDE.md +79 -38
  4. package/README.md +117 -60
  5. package/SKILL.md +45 -25
  6. package/bin/ai-consultants +62 -1
  7. package/docs/COST_RATES.md +121 -46
  8. package/docs/JSON_SCHEMA.md +155 -294
  9. package/docs/RECIPES.md +60 -33
  10. package/docs/SETUP.md +162 -53
  11. package/docs/SMART_ROUTING.md +37 -22
  12. package/docs/cost_rates.json +100 -30
  13. package/package.json +2 -2
  14. package/references/configuration.md +116 -44
  15. package/references/details.md +10 -5
  16. package/scripts/build_context.sh +30 -5
  17. package/scripts/classify_question.sh +30 -9
  18. package/scripts/config.sh +113 -84
  19. package/scripts/configure.sh +92 -19
  20. package/scripts/consult_all.sh +409 -61
  21. package/scripts/doctor.sh +26 -22
  22. package/scripts/followup.sh +32 -14
  23. package/scripts/install.sh +12 -0
  24. package/scripts/lib/agy_exit_guard.sh +80 -0
  25. package/scripts/lib/api.sh +133 -59
  26. package/scripts/lib/api_query.sh +48 -22
  27. package/scripts/lib/cache.sh +34 -5
  28. package/scripts/lib/common.sh +354 -40
  29. package/scripts/lib/costs.sh +97 -9
  30. package/scripts/lib/json_schema_check.jq +65 -0
  31. package/scripts/lib/personas.sh +39 -18
  32. package/scripts/lib/response_canonicalize.jq +97 -0
  33. package/scripts/lib/schema.json +150 -118
  34. package/scripts/lib/session.sh +28 -8
  35. package/scripts/lib/synthesis_canonicalize.jq +90 -0
  36. package/scripts/lib/user_config.sh +22 -7
  37. package/scripts/query_claude.sh +3 -2
  38. package/scripts/query_codex.sh +3 -3
  39. package/scripts/query_gemini.sh +38 -12
  40. package/scripts/query_glm.sh +1 -1
  41. package/scripts/query_grok.sh +1 -1
  42. package/scripts/query_kimi.sh +21 -7
  43. package/scripts/query_minimax.sh +15 -11
  44. package/scripts/query_mistral.sh +6 -3
  45. package/scripts/query_qwen3.sh +12 -3
  46. package/scripts/synthesize.sh +101 -15
  47. package/templates/consultation_report.md +2 -0
  48. package/templates/synthesis_prompt.md +2 -0
@@ -15,7 +15,7 @@ Query multiple AI models for expert opinions on a coding question.
15
15
  1. If no question provided in $ARGUMENTS, ask the user what they want to consult about.
16
16
 
17
17
  Separate supported consultation options from the question before running the
18
- panel. In particular, preserve `--preset <name>` and `--strategy <name>` as
18
+ panel. In particular, preserve `--mode <name>`, `--preset <name>` and `--strategy <name>` as
19
19
  CLI arguments placed before the question; they are not part of the question
20
20
  text. Reject an incomplete option instead of guessing its value.
21
21
 
@@ -39,15 +39,30 @@ Query multiple AI models for expert opinions on a coding question.
39
39
  - Shell-quote every context-file path as one argument.
40
40
  - Install a shell trap that removes only the exact query file when the Bash
41
41
  invocation exits; question text must not persist in the temp directory.
42
+ Some harnesses (Codex) reject `rm -f`; `unlink "<file>"` removes it too.
42
43
  - Capture `caller_root="$PWD"` before changing directories. Pass it through
43
44
  `--context-root` so regular files from the user's project are staged under
44
45
  a private temp directory without widening the runtime filesystem allowlist.
45
46
 
46
47
  ```bash
47
- caller_root="$PWD"; cd "${AI_CONSULTANTS_DIR:-$HOME/.claude/skills/ai-consultants}" && INVOKING_AGENT=claude ./scripts/consult_all.sh [--preset <name>] [--strategy <name>] --context-root "$caller_root" --query-file "<private-question-file>" "<file1[@TAG]>" "<file2[@TAG]>" ...
48
+ caller_root="$PWD"; cd "${AI_CONSULTANTS_DIR:-$HOME/.claude/skills/ai-consultants}" && INVOKING_AGENT=claude ./scripts/consult_all.sh [--mode <name> | --preset <name>] [--strategy <name>] --context-root "$caller_root" --query-file "<private-question-file>" "<file1[@TAG]>" "<file2[@TAG]>" ...
48
49
  ```
49
50
  - Each `<fileN>` is a file path, optionally suffixed with `@PRIMARY` or `@CONTEXT`.
50
- - **Capture the last line of stdout** — it contains the output directory path (e.g., `/tmp/ai_consultations/20260315_143022_12345/`).
51
+ - **Capture the last line of stdout** — it contains the output directory path (e.g., `~/.cache/ai-consultants/consultations/20260315_143022_12345`).
52
+ - **No time limit by default.** Reasoning models can take several minutes.
53
+ If your shell tool can run a command in the background and read its output
54
+ while it runs, do so; otherwise use the longest timeout your tool allows.
55
+ - While waiting, the run logs `Output: <output_dir>` near the start and
56
+ `Still waiting after Ns for: <consultants>` every 30 seconds. You decide
57
+ when to stop waiting:
58
+ - `touch "<output_dir>/.proceed"` continues with the answers already
59
+ received: consultants still running are stopped, then synthesis runs.
60
+ Sent during synthesis, it skips the synthesis.
61
+ - `touch "<output_dir>/.abort"` ends the run and keeps the partial output.
62
+ Stopping does not cancel what a provider already generated and billed, so
63
+ keep waiting unless the user wants results now or a consultant looks stuck
64
+ (for example, far slower than the rest of the panel). Never stop the run
65
+ with SIGKILL: it would leave consultant CLIs running. Use `.abort` or SIGTERM.
51
66
  - Keep `INVOKING_AGENT=claude` exactly as shown. Never invoke
52
67
  `query_claude.sh` directly and never remove self-exclusion to increase the
53
68
  panel count.
@@ -56,7 +71,7 @@ Query multiple AI models for expert opinions on a coding question.
56
71
  - Read `<output_dir>/report.md` using the **Read** tool
57
72
  - Read `<output_dir>/synthesis.json` using the **Read** tool (may not exist if synthesis was skipped or failed)
58
73
  - If neither exists, use the **Glob** tool with pattern `<output_dir>/*.json` to discover individual consultant response files, then read each one
59
- - `claude.json` must not exist and `.synthesis_provider` must not be
74
+ - `claude.json` must not exist and the `synthesis_provider` field of `synthesis.json` must not be
60
75
  `claude`. If either appears, report a self-exclusion failure instead of
61
76
  presenting the run as valid.
62
77
 
@@ -89,7 +104,8 @@ Query multiple AI models for expert opinions on a coding question.
89
104
  ```bash
90
105
  cd "${AI_CONSULTANTS_DIR:-$HOME/.claude/skills/ai-consultants}" && ./scripts/doctor.sh
91
106
  ```
92
- - **Exit code 124** (timeout): Suggest `--preset fast` for quicker results or increasing the timeout (e.g., `GEMINI_TIMEOUT=300`)
107
+ - **Consultant timeouts** (`Timeout after …s` in the output): a hard limit was set with `<NAME>_TIMEOUT`. Suggest `0` (no limit, the default) or `--mode fast-check` for quicker results
108
+ - **Stopped consultants** (`Stopped by the host`): present the answers received and name the consultants that were stopped before answering
93
109
  - **Partial failures** (some consultants responded, others didn't): Present the successful results normally and note which consultants failed at the end
94
110
  - **Empty output directory** (no JSON files produced): Suggest running `doctor.sh` to verify CLI installations and API keys
95
111
 
package/.env.example CHANGED
@@ -1,14 +1,16 @@
1
1
  # =============================================================================
2
2
  # AI Consultants - Environment Variables
3
3
  # =============================================================================
4
- # Copy this file to .env and customize as needed.
5
- # All variables have sensible defaults - only override what you need.
4
+ # Template for the private user configuration, normally
5
+ # ~/.config/ai-consultants/.env (created by `ai-consultants init`, or written
6
+ # with detected values by `ai-consultants configure`). Another private
7
+ # directory can be selected with AI_CONSULTANTS_CONFIG_DIR; a project .env is
8
+ # never read automatically. Keep the file at mode 600: it may hold API keys.
9
+ # All variables have sensible defaults - only override what you need, and
10
+ # exported environment variables take precedence over this file.
6
11
  #
7
12
  # IMPORTANT: At least 2 consultants must be enabled for the system to work.
8
13
  #
9
- # Export variables before running, or source this file:
10
- # source .env && ./scripts/consult_all.sh "Your question"
11
- #
12
14
  # For detailed setup instructions, see: docs/SETUP.md
13
15
 
14
16
  # =============================================================================
@@ -18,7 +20,7 @@
18
20
  # or use the CLI's built-in auth flow.
19
21
 
20
22
  # Google Gemini API key (only needed for API mode; the agy CLI uses OAuth)
21
- # Get yours at: https://makersuite.google.com/app/apikey
23
+ # Get yours at: https://aistudio.google.com/apikey
22
24
  # CLI mode uses the Antigravity CLI (agy); sign in by running `agy` once.
23
25
  # GEMINI_API_KEY=your-google-api-key
24
26
 
@@ -77,9 +79,12 @@ ENABLE_GROK=true
77
79
  ENABLE_MINIMAX=true
78
80
  ENABLE_CLAUDE=true
79
81
 
80
- # API-only consultants (default: disabled - require API keys)
81
- ENABLE_GLM=false
82
- ENABLE_DEEPSEEK=false
82
+ # API-only consultants (default: disabled - require API keys).
83
+ # Left commented on purpose: an explicit "false" is a durable opt-out that
84
+ # presets (including max_quality) will never override, even once a key is
85
+ # added. Uncomment with "true" after setting the key, or run `configure`.
86
+ # ENABLE_GLM=true
87
+ # ENABLE_DEEPSEEK=true
83
88
 
84
89
  # =============================================================================
85
90
  # CLI/API MODE SWITCHING (v2.6+)
@@ -112,27 +117,33 @@ ENABLE_DEEPSEEK=false
112
117
  # https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1/chat/completions
113
118
 
114
119
  # =============================================================================
115
- # MODEL CONFIGURATION (August 2026 premium defaults)
120
+ # MODEL CONFIGURATION (October 2026 premium defaults)
116
121
  # =============================================================================
117
122
 
118
123
  # Gemini - The Architect (CLI mode via Antigravity CLI: agy)
119
- GEMINI_MODEL="Gemini 3.7 Flash (High)"
120
- GEMINI_TIMEOUT=180
124
+ GEMINI_MODEL="Gemini 4 Argon (High)"
125
+ GEMINI_TIMEOUT=0
121
126
  GEMINI_CMD=agy
122
- # API-mode model ID (only used when GEMINI_USE_API=true)
123
- GEMINI_API_MODEL=gemini-3.1-pro-preview
124
- # Gemini 3.1 Pro and 3.6 Flash remain valid CLI pins. API mode stays on the
125
- # separately verified 3.1 Pro ID; gemini-3.7-flash is an API-only opt-in until
126
- # that transport completes its own authenticated smoke.
127
- # Reasoning effort for the agy CLI. Passed as --effort <value>. Accepts only
128
- # low|medium|high; anything else is rejected by the provider and surfaces as a
129
- # diagnosed error (provider owns the enum — same stance as QWEN3_REASONING_EFFORT).
127
+ # API-mode model ID (only used when GEMINI_USE_API=true). Gemini 4 Argon needs
128
+ # a paid-tier key: Google excludes it from the Free tier and the AI Pro plan.
129
+ GEMINI_API_MODEL=gemini-4-argon
130
+ # Argon's thinking tokens count toward this output budget (API only).
131
+ GEMINI_API_MAX_TOKENS=32768
132
+ # Pin "Gemini 3.8 Flash (High)" or gemini-3.1-pro-preview to keep the previous
133
+ # targets; Gemini 3.1 Pro and 3.6 Flash remain valid CLI pins. gemini-3.8-flash
134
+ # is an API-only opt-in until that transport completes its own authenticated smoke.
135
+ # Reasoning effort for the agy CLI, passed as --effort <value>. Current agy
136
+ # advertises low|medium|high|max globally, but named Gemini 4 Argon and 3.8
137
+ # High/Medium/Low variants reject --effort: leave GEMINI_REASONING_EFFORT unset
138
+ # for those CLI targets and choose the level with GEMINI_MODEL. Native Gemini
139
+ # 3.7/3.8 Flash and 4 Argon API thinking supports low|medium|high through this
140
+ # setting; Argon defaults to high, matching its CLI target.
130
141
  # GEMINI_REASONING_EFFORT=
131
142
 
132
143
  # Codex - The Pragmatist
133
- CODEX_MODEL=gpt-6-astra
144
+ CODEX_MODEL=gpt-6.1-sol
134
145
  CODEX_API_MAX_TOKENS=16384
135
- CODEX_TIMEOUT=180
146
+ CODEX_TIMEOUT=0
136
147
  CODEX_CMD=codex
137
148
  # Reasoning effort for the codex CLI (and API mode). Passed as
138
149
  # -c model_reasoning_effort=<value>. The provider owns the accepted enum;
@@ -140,28 +151,29 @@ CODEX_CMD=codex
140
151
  # CODEX_REASONING_EFFORT=
141
152
 
142
153
  # Mistral Vibe - The Devil's Advocate
143
- # API model ID. Vibe uses the separate CLI alias below. Mistral Medium 3.5,
144
- # Large 3, and Small 4 API IDs are documented opt-ins until an API smoke passes.
145
- MISTRAL_MODEL=mistral-large-3
154
+ # API model ID (MISTRAL_USE_API=true only). Vibe uses the separate CLI alias
155
+ # below. Mistral Large 4 is a public preview and is absent from GET /v1/models
156
+ # even when the key can call it. Pin mistral-large-3 to keep the previous target.
157
+ MISTRAL_MODEL=mistral-large-4
146
158
  MISTRAL_CLI_MODEL=mistral-medium-3.5
147
- MISTRAL_API_MAX_TOKENS=4096
159
+ MISTRAL_API_MAX_TOKENS=16384
148
160
  # Official API opt-ins: use mistral-medium-3-5, mistral-large-2512, or
149
161
  # mistral-small-2603 for MISTRAL_MODEL after an authenticated API smoke.
150
- MISTRAL_TIMEOUT=180
162
+ MISTRAL_TIMEOUT=0
151
163
  MISTRAL_CMD=vibe
152
164
  MISTRAL_MAX_TURNS=4
153
165
 
154
166
  # Kimi - The Eastern Sage (K3 via Kimi Code CLI)
155
167
  KIMI_MODEL=kimi-code/k3
156
168
  # max_quality selects the inventory-probed kimi-code/k3-256k target.
157
- KIMI_TIMEOUT=180
169
+ KIMI_TIMEOUT=0
158
170
  KIMI_CMD=kimi
159
171
 
160
172
  # Claude - The Synthesizer
161
173
  CLAUDE_MODEL=claude-fable-5-1 # ai-consultants:default
162
174
  # For the lower-cost standard/medium Claude tier, set CLAUDE_MODEL to
163
- # claude-opus-5 (or apply_model_tier standard for a single run).
164
- CLAUDE_TIMEOUT=240
175
+ # claude-opus-5-5 (or apply_model_tier standard for a single run).
176
+ CLAUDE_TIMEOUT=0
165
177
  CLAUDE_CMD=claude
166
178
  CLAUDE_API_MAX_TOKENS=16384
167
179
  # Reasoning effort for the claude CLI (and API mode). Passed as --effort <value>.
@@ -170,14 +182,14 @@ CLAUDE_API_MAX_TOKENS=16384
170
182
  # CLAUDE_REASONING_EFFORT=
171
183
 
172
184
  # Qwen3 - The Analyst (CLI/API switchable v2.7)
173
- QWEN3_MODEL=qwen3.7-max
174
- QWEN3_TIMEOUT=180
175
- QWEN3_MAX_QUALITY_TIMEOUT=600
185
+ QWEN3_MODEL=qwen3.8-max
186
+ QWEN3_TIMEOUT=0
187
+ QWEN3_MAX_QUALITY_TIMEOUT=0
176
188
  QWEN3_API_MAX_TOKENS=16384
177
189
  QWEN3_CMD=qwen
178
190
  # Reasoning effort. API mode ONLY - the qwen CLI has no effort flag, so in CLI
179
- # mode this is ignored (with a warning); set model.reasoningEffort in
180
- # ~/.qwen/settings.json instead. Accepted: none|minimal|low|medium|high|xhigh|max
191
+ # mode this is ignored (with a warning); configure the effort in
192
+ # ~/.qwen/settings.json instead (see docs/RECIPES.md). Accepted: none|minimal|low|medium|high|xhigh|max
181
193
  # (the provider's own enum). The valid subset depends on the model:
182
194
  # qwen3.8-max takes all of them EXCEPT 'none' - thinking cannot be
183
195
  # disabled on it - and defaults to xhigh. An unsupported combination is
@@ -199,15 +211,15 @@ QWEN3_CMD=qwen
199
211
 
200
212
  # GLM - The Methodologist
201
213
  GLM_MODEL=glm-5.3-flash
202
- GLM_TIMEOUT=180
214
+ GLM_TIMEOUT=0
203
215
  GLM_API_MAX_TOKENS=16384
204
216
  GLM_API_URL=https://api.z.ai/api/coding/paas/v4/chat/completions
205
217
  # GLM_REASONING_EFFORT= # max_quality sets max
206
218
 
207
219
  # Grok Build CLI + xAI API fallback - The Provocateur
208
220
  GROK_CMD=grok
209
- GROK_MODEL=grok-4.6
210
- GROK_TIMEOUT=180
221
+ GROK_MODEL=grok-4.7
222
+ GROK_TIMEOUT=0
211
223
  GROK_MAX_TURNS=4
212
224
  GROK_OAUTH_MODE=shared
213
225
  GROK_API_MAX_TOKENS=4096
@@ -216,8 +228,8 @@ GROK_API_URL=https://api.x.ai/v1/chat/completions
216
228
 
217
229
  # DeepSeek - The Code Specialist
218
230
  DEEPSEEK_MODEL=deepseek-flash
219
- DEEPSEEK_TIMEOUT=180
220
- DEEPSEEK_MAX_QUALITY_TIMEOUT=600
231
+ DEEPSEEK_TIMEOUT=0
232
+ DEEPSEEK_MAX_QUALITY_TIMEOUT=0
221
233
  DEEPSEEK_API_MAX_TOKENS=16384
222
234
  DEEPSEEK_API_URL=https://api.deepseek.com/v1/chat/completions
223
235
  # DEEPSEEK_REASONING_EFFORT= # max_quality sets max
@@ -226,7 +238,7 @@ DEEPSEEK_API_URL=https://api.deepseek.com/v1/chat/completions
226
238
  MINIMAX_CMD=mmx
227
239
  MINIMAX_MODEL=MiniMax-M2.7
228
240
  # max_quality selects the smoke-tested MiniMax-M3 target.
229
- MINIMAX_TIMEOUT=180
241
+ MINIMAX_TIMEOUT=0
230
242
  MINIMAX_API_MAX_TOKENS=4096
231
243
  MINIMAX_MAX_TOKENS=4096
232
244
  MINIMAX_MAX_QUALITY_TOKENS=16384
@@ -267,8 +279,8 @@ SYNTHESIS_MODEL=
267
279
  SYNTHESIS_EXTRACT_FIELDS=true
268
280
  SYNTH_MAX=10
269
281
  SYNTH_DETAIL_MAX_CHARS=4000
270
- SYNTHESIS_TIMEOUT=240
271
- SYNTHESIS_TOTAL_TIMEOUT=480
282
+ SYNTHESIS_TIMEOUT=0
283
+ SYNTHESIS_TOTAL_TIMEOUT=0
272
284
 
273
285
  # Health gate and quorum: validate the live panel before spending on a full run
274
286
  ENABLE_HEALTH_GATE=false # Adds one small ping per selected consultant
@@ -289,7 +301,8 @@ API_BASE_BACKOFF=2
289
301
  API_MAX_BACKOFF=60
290
302
  API_RATE_LIMIT=30
291
303
 
292
- # Optional response limits by question category
304
+ # Deprecated no-op, kept for configuration compatibility: no adapter applies
305
+ # these per-category limits. Use the *_API_MAX_TOKENS settings instead.
293
306
  ENABLE_RESPONSE_LIMITS=false
294
307
  MAX_RESPONSE_TOKENS_BY_CATEGORY=QUICK_SYNTAX:200,CODE_REVIEW:800,BUG_DEBUG:800,ARCHITECTURE:1000,SECURITY:1000,DATABASE:600,GENERAL:500
295
308
 
@@ -308,6 +321,9 @@ MAX_SESSION_COST=1.00
308
321
  # Question classification (required for smart routing)
309
322
  ENABLE_CLASSIFICATION=true
310
323
  CLASSIFICATION_MODE=pattern # pattern (fast) or llm (accurate)
324
+ # llm mode asks the Claude CLI (economy model, stateless, tool-free) and is
325
+ # skipped when Claude is the invoking host. Bounded by this timeout (seconds).
326
+ # CLASSIFICATION_TIMEOUT=30
311
327
 
312
328
  # Smart routing: select consultants based on question category
313
329
  ENABLE_SMART_ROUTING=false
@@ -357,6 +373,30 @@ MAX_RETRIES=2 # Max retry attempts on failure
357
373
  RETRY_DELAY_SECONDS=5 # Pause between retries
358
374
  LAUNCH_STAGGER_MAX_SECONDS=2
359
375
 
376
+ # Every *_TIMEOUT for consultants and synthesis defaults to 0: no time limit.
377
+ # A timed-out call is usually still billed while its answer is lost, so the
378
+ # invoking host decides when to stop waiting. While consult_all.sh waits it
379
+ # logs progress every WAIT_HEARTBEAT_SECONDS (0 = silent) and accepts:
380
+ # touch <output dir>/.proceed continue with the answers received
381
+ # (also: kill -USR1 <pid>, or a first Ctrl-C)
382
+ # touch <output dir>/.abort end the run (also: SIGTERM, or a second Ctrl-C)
383
+ # A positive *_TIMEOUT restores a hard limit for that consultant.
384
+ WAIT_HEARTBEAT_SECONDS=30
385
+ # agy can print its whole answer and then never exit. When its output is one
386
+ # complete JSON object unchanged for this many seconds, the run ends agy and
387
+ # keeps the answer (0 = always wait for agy to exit).
388
+ AGY_EXIT_GRACE_SECONDS=60
389
+
390
+ # Agentic consultant CLIs (agy, qwen, kimi) run from a private empty working
391
+ # directory so they cannot load project instructions or read files beyond the
392
+ # built context. Set to false to run them from the current directory.
393
+ # CLI_WORKSPACE_ISOLATION=true
394
+
395
+ # agy, vibe and kimi accept the prompt only as a command-line argument, which
396
+ # is visible in the process list and size-limited (128 KiB per argument on
397
+ # Linux). Larger prompts fail before dispatch; override the computed limit here.
398
+ # ARGV_PROMPT_MAX_BYTES=
399
+
360
400
  # Output directory base
361
401
  # DEFAULT_OUTPUT_DIR_BASE=/custom/cache/consultations
362
402
 
package/CLAUDE.md CHANGED
@@ -6,7 +6,7 @@ AI Consultants is a multi-model coverage system that queries up to 10 AI consult
6
6
 
7
7
  **Self-Exclusion**: The invoking agent is automatically excluded from both the panel and synthesis. Claude Code won't query or synthesize with Claude, Codex CLI won't query or synthesize with Codex, etc.
8
8
 
9
- **Version**: 5.1.1
9
+ **Version**: 5.2.0
10
10
 
11
11
  ## Distribution
12
12
 
@@ -33,7 +33,6 @@ ai-consultants/
33
33
  ├── bin/
34
34
  │ └── ai-consultants # npm/npx entry point (bash wrapper)
35
35
  ├── package.json # npm distribution metadata (zero dependencies)
36
- ├── .npmignore # Excludes dev artifacts from npm package
37
36
  ├── scripts/
38
37
  │ ├── consult_all.sh # Main orchestrator - entry point
39
38
  │ ├── config.sh # Centralized configuration
@@ -52,9 +51,13 @@ ai-consultants/
52
51
  │ ├── schema.json # JSON output schema
53
52
  │ ├── routing.sh # Smart routing (category affinity) + cost-aware routing
54
53
  │ ├── session.sh # Session management
55
- │ ├── costs.sh # Cost tracking + response limits
54
+ │ ├── costs.sh # Cost tracking + budget enforcement
56
55
  │ ├── cache.sh # Semantic caching (v2.3)
57
56
  │ ├── api_query.sh # API mode query execution (v2.6)
57
+ │ ├── response_canonicalize.jq # Consultant answer repairs before validation
58
+ │ ├── synthesis_canonicalize.jq # synthesis.json contract
59
+ │ ├── json_schema_check.jq # jq-only schema validator used by tests
60
+ │ ├── agy_exit_guard.sh # Keeps a complete agy answer when agy never exits
58
61
  │ └── progress.sh # Progress bars
59
62
  ├── references/
60
63
  │ ├── configuration.md # Full configuration reference
@@ -67,7 +70,7 @@ ai-consultants/
67
70
  │ ├── SMART_ROUTING.md # Affinity matrix
68
71
  │ └── JSON_SCHEMA.md # Output schema
69
72
  └── templates/
70
- └── synthesis_prompt.md # Synthesis prompt
73
+ └── synthesis_prompt.md # Reference copy only; the runtime prompt is inline in synthesize.sh
71
74
  ```
72
75
 
73
76
  ## Claude Skills Compliance
@@ -235,9 +238,9 @@ curl -L code.kimi.com/install.sh | bash
235
238
  ```
236
239
 
237
240
  **Environment Variables:**
238
- - `ENABLE_KIMI` - Enable Kimi consultant (default: false)
241
+ - `ENABLE_KIMI` - Enable Kimi consultant (default: true)
239
242
  - `KIMI_CMD` - CLI command (default: kimi)
240
- - `KIMI_TIMEOUT` - Timeout in seconds (default: 180)
243
+ - `KIMI_TIMEOUT` - Timeout in seconds (default: 0, no limit)
241
244
  - `KIMI_MODEL` - Kimi CLI model alias (default: kimi-code/k3; passed explicitly with `--model`)
242
245
 
243
246
  **Persona:** The Eastern Sage - Focuses on holistic understanding, balance of perspectives, and wisdom from diverse viewpoints.
@@ -349,10 +352,10 @@ Three normal tiers plus a `maximum` tier are configurable via `apply_model_tier(
349
352
 
350
353
  | Tier | Description | Example Models |
351
354
  |------|-------------|----------------|
352
- | **premium** | Latest flagship models | claude-fable-5-1, Gemini 3.7 Flash (High), gpt-6-astra |
353
- | **maximum** | All 10 consultants; maximum targets and highest provider effort | claude-fable-5-1, K3-256k, Qwen3.8-Max, MiniMax M3; Grok xhigh, GLM/DeepSeek max |
354
- | **standard** | Good quality at reasonable cost | claude-opus-5, Gemini 3.7 Flash (High), gpt-5.6-terra |
355
- | **economy** | Optimized for speed and low cost | claude-haiku-4-5, Gemini 3.7 Flash (Low), gpt-5.6-luna |
355
+ | **premium** | Latest flagship models | claude-fable-5-1, Gemini 4 Argon (High), gpt-6.1-sol |
356
+ | **maximum** | All 10 consultants; maximum targets and highest provider effort | claude-fable-5-1, Gemini 4 Argon (High), K3-256k, Qwen3.8-Max, MiniMax M3; Grok xhigh, GLM/DeepSeek max |
357
+ | **standard** | Good quality at reasonable cost | claude-opus-5-5, Gemini 3.8 Flash (High), gpt-5.6-terra |
358
+ | **economy** | Optimized for speed and low cost | claude-haiku-4-5, Gemini 3.8 Flash (Low), gpt-5.6-luna |
356
359
 
357
360
  **Default models are now premium tier** for maximum quality.
358
361
 
@@ -365,7 +368,7 @@ apply_model_tier "standard" # Set all consultants to standard models
365
368
  apply_model_tier "economy" # Set all consultants to economy models
366
369
 
367
370
  # Get model for a specific consultant and tier (v2.8.1)
368
- get_model_for_tier "gemini" "premium" # → Gemini 3.7 Flash (High) on agy
371
+ get_model_for_tier "gemini" "premium" # → Gemini 4 Argon (High) on agy
369
372
  get_model_for_tier "claude" "economy" # → claude-haiku-4-5
370
373
  ```
371
374
 
@@ -389,20 +392,20 @@ All consultants now use premium models by default:
389
392
  | Consultant | Default Model |
390
393
  |------------|---------------|
391
394
  | Claude | claude-fable-5-1 |
392
- | Gemini | Gemini 3.7 Flash (High) (via agy CLI); API: gemini-3.1-pro-preview |
393
- | Codex | gpt-6-astra |
394
- | Mistral | CLI: mistral-medium-3.5; API: mistral-large-3 |
395
+ | Gemini | Gemini 4 Argon (High) (via agy CLI); API: gemini-4-argon |
396
+ | Codex | gpt-6.1-sol (max_quality: gpt-6-astra) |
397
+ | Mistral | CLI: mistral-medium-3.5; API: mistral-large-4 (preview) |
395
398
  | DeepSeek | deepseek-flash (DeepSeek-V4.1-Flash) |
396
399
  | GLM | glm-5.3-flash |
397
- | Grok | grok-4.6 |
398
- | Qwen3 | qwen3.7-max |
400
+ | Grok | grok-4.7 |
401
+ | Qwen3 | qwen3.8-max (standard/economy: qwen3.8-flash) |
399
402
  | Kimi | kimi-code/k3 |
400
403
  | MiniMax | MiniMax-M2.7 |
401
404
 
402
405
  Override with environment variables: `CLAUDE_MODEL`, `GEMINI_MODEL`, `CODEX_MODEL`, `KIMI_MODEL`, etc.
403
406
 
404
407
  Grok is CLI-first through the official Grok Build `grok` command, with
405
- `grok-4.6` passed explicitly in headless mode. The prompt is delivered with
408
+ `grok-4.7` passed explicitly in headless mode. The prompt is delivered with
406
409
  `--prompt-file`; HOME and CWD are isolated, built-in/MCP tools are denied, and
407
410
  the strict sandbox prevents user or project extensions from joining the
408
411
  consultation. The xAI Chat Completions path is retained only when the CLI is
@@ -412,10 +415,10 @@ is surfaced and never silently rerouted to the API.
412
415
 
413
416
  The live full-panel smoke defines the `max_quality` runtime envelope, not just
414
417
  the model names. Mistral and Grok receive four bounded advisory turns plus an
415
- explicit no-tools/workspace instruction. Qwen3.8-Max gets a 600-second Token
416
- Plan timeout; DeepSeek V4 Pro/max gets 600 seconds and 16,384 completion tokens;
417
- GLM gets 16,384; MiniMax M3 gets 16,384 plus a compact Markdown contract in
418
- mmx's native system channel. OpenAI-compatible
418
+ explicit no-tools/workspace instruction. Qwen3.8-Max and DeepSeek get
419
+ `QWEN3_MAX_QUALITY_TIMEOUT`/`DEEPSEEK_MAX_QUALITY_TIMEOUT` (default 0, no limit);
420
+ DeepSeek gets 16,384 completion tokens; GLM gets 16,384; MiniMax M3 gets 16,384
421
+ plus the shared JSON response contract in mmx's native system channel. OpenAI-compatible
419
422
  `finish_reason=length` is an error. Every
420
423
  response records `metadata.response_quality=structured|fallback|error`:
421
424
  malformed JSON-looking output fails closed, while real markdown/prose is kept
@@ -463,18 +466,20 @@ Reduces redundant API calls by caching responses based on query + context finger
463
466
  # Configuration in config.sh
464
467
  ENABLE_SEMANTIC_CACHE=true # Enable caching (default: true)
465
468
  CACHE_TTL_HOURS=24 # Cache expiration
466
- CACHE_DIR=/tmp/ai_consultants_cache
469
+ CACHE_DIR=~/.cache/ai-consultants/cache # XDG default
467
470
  ```
468
471
 
469
472
  Functions in `lib/cache.sh`:
470
- - `generate_fingerprint()` - Creates hash from query + category + context
473
+ - `generate_fingerprint()` - Creates hash from query + category + context + consultant identity (`cache_identity()`: model, transport, effort, persona)
471
474
  - `check_cache()` - Returns cached response if valid
472
475
  - `store_cache()` - Stores response with metadata
473
476
  - `cleanup_cache()` - Removes expired entries
474
477
  - `get_cache_stats()` - Returns cache statistics as JSON
475
478
 
476
- ### Response Length Limits (Opt-in)
477
- Limits output tokens by question category to reduce costs.
479
+ ### Response Length Limits (deprecated no-op)
480
+ **Never applied by any adapter** (most consultant CLIs expose no output cap);
481
+ the settings are accepted for configuration compatibility only. Use the
482
+ `*_API_MAX_TOKENS` settings to bound API responses.
478
483
 
479
484
  ```bash
480
485
  ENABLE_RESPONSE_LIMITS=false # Default: false (opt-in per quality review)
@@ -496,7 +501,7 @@ COMPLEXITY_THRESHOLD_MEDIUM=6 # Score 4-6 = medium, 7-10 = complex
496
501
  ```
497
502
 
498
503
  Functions in `lib/routing.sh`:
499
- - `select_consultants_cost_aware()` - Selects consultants based on complexity
504
+ - `select_consultants_cost_aware()` - Selects consultants based on complexity (used by the smart-routing path)
500
505
  - `get_cost_aware_model()` - Returns economic model for simple queries
501
506
  - `calculate_query_complexity()` - Scores query 1-10
502
507
 
@@ -505,7 +510,12 @@ Functions in `lib/costs.sh`:
505
510
  - `get_model_tier()` - Returns economy/standard/premium
506
511
 
507
512
  ### Fallback Escalation
508
- Automatically re-queries with premium models if confidence is too low.
513
+ Active only with `ENABLE_COST_AWARE_ROUTING=true`. Re-queries a **structured**
514
+ response whose confidence is below the threshold on the consultant's premium
515
+ model for its active transport (`model_env_var_for`). Error and fallback
516
+ envelopes are never escalated, the same model is never re-asked, a
517
+ maximum-tier target is never "escalated" to premium, and each re-query passes
518
+ `enforce_budget` first.
509
519
 
510
520
  ```bash
511
521
  FALLBACK_CONFIDENCE_THRESHOLD=7 # Escalate if confidence < 7
@@ -586,17 +596,18 @@ for f in scripts/*.sh scripts/lib/*.sh; do bash -n "$f" && echo "OK: $f"; done
586
596
  | `ENABLE_SMART_ROUTING` | false | Intelligent routing by category |
587
597
  | `ENABLE_COST_TRACKING` | true | Track costs |
588
598
  | `MAX_SESSION_COST` | 1.00 | Max budget ($) |
589
- | `CLAUDE_MODEL` | claude-fable-5-1 | Claude model (use claude-opus-5 for lower-cost standard) |
599
+ | `CLAUDE_MODEL` | claude-fable-5-1 | Claude model (use claude-opus-5-5 for lower-cost standard) |
590
600
  | `CLAUDE_API_MAX_TOKENS` | 16384 | Claude API thinking + visible-output budget |
591
- | `GEMINI_MODEL` | Gemini 3.7 Flash (High) | Gemini agy CLI model |
592
- | `GEMINI_API_MODEL` | gemini-3.1-pro-preview | Gemini API-mode model ID (v2.15) |
593
- | `CODEX_MODEL` | gpt-6-astra | Codex model (v2.5) |
594
- | `MISTRAL_MODEL` | mistral-large-3 | Mistral model (v2.5) |
601
+ | `GEMINI_MODEL` | Gemini 4 Argon (High) | Gemini agy CLI model |
602
+ | `GEMINI_API_MODEL` | gemini-4-argon | Gemini API-mode model ID (v2.15) |
603
+ | `GEMINI_API_MAX_TOKENS` | 32768 | Gemini API thinking + visible-output budget |
604
+ | `CODEX_MODEL` | gpt-6.1-sol | Codex model (max_quality: gpt-6-astra) |
605
+ | `MISTRAL_MODEL` | mistral-large-4 | Mistral API model (Vibe uses `MISTRAL_CLI_MODEL`) |
595
606
  | `MISTRAL_CLI_MODEL` | mistral-medium-3.5 | Vibe CLI model alias |
596
607
  | `SYNTHESIS_STRATEGY` | coverage | Synthesis strategy (coverage=union of distinct points) |
597
608
  | `ENABLE_SEMANTIC_CACHE` | true | Semantic response caching (v2.3) |
598
609
  | `CACHE_TTL_HOURS` | 24 | Cache expiration in hours (v2.3) |
599
- | `ENABLE_RESPONSE_LIMITS` | false | Response token limits (v2.3, opt-in) |
610
+ | `ENABLE_RESPONSE_LIMITS` | false | Deprecated no-op (never applied) |
600
611
  | `ENABLE_COST_AWARE_ROUTING` | false | Cost-based model routing (v2.3) |
601
612
  | `ENABLE_COMPACT_REPORT` | true | Compact report format (v2.3) |
602
613
  | `ENABLE_BUDGET_LIMIT` | false | Budget enforcement (v2.4, opt-in) |
@@ -629,17 +640,18 @@ The system handles errors with:
629
640
 
630
641
  - **Automatic retry**: `MAX_RETRIES` attempts (default: 2)
631
642
  - **Delay between retries**: `RETRY_DELAY_SECONDS` (default: 5s)
632
- - **Cross-platform timeout**: Supports Linux (`timeout`), macOS (`gtimeout`), and POSIX fallback
633
- - **Exit codes**: 0 = success, 1 = error, 124 = timeout
643
+ - **Cross-platform timeout** (only when a positive `*_TIMEOUT` is set): Linux (`timeout`), macOS (`gtimeout`), and POSIX fallback
644
+ - **Exit codes**: 0 = success, 1 = error, 124 = timeout; a host abort exits 130 (`.abort`, second Ctrl-C), 143 (SIGTERM) or 129 (SIGHUP)
634
645
 
635
646
  ```bash
636
647
  # Retry configuration
637
648
  MAX_RETRIES=3
638
649
  RETRY_DELAY_SECONDS=10
639
650
 
640
- # Per-consultant timeout
641
- GEMINI_TIMEOUT=240
642
- CODEX_TIMEOUT=180
651
+ # Per-consultant timeout: 0 (default) = no limit; the invoking host decides
652
+ # when to stop waiting (touch <output dir>/.proceed or .abort)
653
+ GEMINI_TIMEOUT=0
654
+ CODEX_TIMEOUT=0
643
655
  ```
644
656
 
645
657
  ## Extended Documentation
@@ -760,6 +772,35 @@ curl -fsSL https://raw.githubusercontent.com/matteoscurati/ai-consultants/main/s
760
772
 
761
773
  ## Changelog
762
774
 
775
+ ### v5.2.0 (2026-10-19)
776
+
777
+ - **Host context described the wrong project.** Hosts `cd` into the skill root, and `build_context.sh` reported `pwd`/`find .` from there. `consult_all.sh` now runs it from `--context-root` (staged files are absolute temp paths, still admitted by `_is_temp_path`).
778
+ - **API-only consultants never received the response contract.** `run_api_consultant` (GLM, DeepSeek, MiniMax API, custom agents) skipped `build_query_with_persona`, so every answer was prose -> fallback -> never attributable coverage, and `max_quality` could not reach `coverage_integrity=MET`. MiniMax CLI now gets the contract through `--system`. The live GLM smoke then exposed a nested/one-brace-short `confidence`; `normalize_consultant_response_text` lifts/repairs only that exact shape. Rejected payloads keep `metadata.raw_excerpt` so the next failure is diagnosable without a billed re-run.
779
+ - **Cache key ignored the model.** `cache_identity()` (model/API/CLI model, transport, effort, format, URL, budgets, persona) is part of every fingerprint; `CACHE_KEY_VERSION` invalidates old entries once.
780
+ - **Synthesis extraction** used a sed line range that ends at the first `}` line; now `strip_json_fence` then first-`{`..last-`}`. The synthesis call is estimated into `synthesis.json.synthesis_metadata` and billed by `calculate_session_cost` (`_synthesis_estimated_cost`).
781
+ - **Follow-up** history stores the full query, `get_session_by_id` returns the current-session shape, whole-panel follow-ups run with `AI_CONSULTANTS_SKIP_SESSION_SAVE=true` inside the follow-up directory and are recorded on the original session.
782
+ - **Transport privacy/limits.** Questions reach classify/build_context/synthesize via stdin (`-`); the request builders (`lib/api.sh`, `query_minimax.sh`) read the prompt with `jq --rawfile prompt /dev/stdin`, and curl gets headers and body through process substitution (`-H @<(...)`, `--data-binary @<(...)`), so neither the key nor the prompt is in argv or in a temp file a stopped query would leave behind. Process substitution does not survive the POSIX `run_with_timeout` fallback (the background job loses `/dev/fd/63`), so `doctor` bounds its probe with curl's own `-m`. `guard_argv_prompt_size` fails fast for argv-only CLIs (agy/vibe/kimi) and synthesis skips agy above the limit; agy/qwen/kimi run from `make_cli_workspace` directories. The POSIX timeout fallback never reads a TTY.
783
+ - **Test gate hermeticity** now lives in `test_all.sh` (empty `AI_CONSULTANTS_CONFIG_DIR`, documented keys and `_AI_CONSULTANTS_*` markers unset), fixing the root cause of the release-gate leaks recorded in v2.23.0/v2.25.1/v3.0.0. `npm run lint` is the single lint invocation for CI and publish.
784
+ - **JSON contracts.** `lib/response_canonicalize.jq` (consultant answers) and `lib/synthesis_canonicalize.jq` (synthesis.json) apply only deterministic, content-preserving repairs; `summary` is never derived from `detailed` (detailed text is deliberately not atomized) and a string `response` stays fallback prose. `lib/schema.json` v3 describes the real envelopes plus `synthesis_artifact`; `lib/json_schema_check.jq` + `assert_schema_valid` make it executable in tests. Estimates use `model_env_var_for` (tier + transport).
785
+ - **Codex model policy.** `gpt-6.1-sol` is the default/premium Codex target and `gpt-6-astra` stays the maximum target (`get_model_for_tier`, `docs/cost_rates.json` premium tier and fallback). `_codex_frontier_model` in `lib/api.sh` gives both the implicit `high` effort and the none/minimal rejection (provider docs: low|medium|high|xhigh|max, default medium). `configure` migrates unpinned `gpt-6-astra` too and keeps the earliest `migrated-from`. One authorized CLI smoke passed (structured, measured usage, requested-only identity).
786
+ - **Qwen/GLM policy.** `qwen3.8-max` is default/premium/maximum on all Qwen transports (the Token Plan-only gate in `apply_model_tier` is gone; `xhigh` is set only on the OpenAI-compatible wire, `QWEN3_MAX_QUALITY_TIMEOUT` everywhere, default 0); `qwen3.8-flash` serves standard/economy. GLM maximum is `glm-5.3`. Live checks passed for all four. 401/403 failures now carry the provider reason (`provider_error_summary`): a renewed Token Plan issues a new plan key, and DashScope without purchase returns `AccessDenied.Unpurchased`.
787
+ - **Mistral API policy.** `mistral-large-4` (public preview, 2026-10-06) is `MISTRAL_MODEL` and every API tier; `configure` migrates unpinned `mistral-large-3`. Rates use the list price ($1.36/$4.18 per 1M), not the 50% preview price, so budgets fail safe. Evidence: one authorized 1-token chat call (2026-10-15) returned HTTP 200, provider-reported model `mistral-large-4`, `service_tier: standard`. `GET /v1/models` omits the preview (and every Large model) for that key, so listing is not an access check. A first `query_mistral.sh` smoke (same day, HTTP 200, 244 in / 3833 out tokens, ~44 s) failed closed because `message.content` was a chunk array (`thinking` + `text`); `parse_openai_response` now joins only `text` chunks (test in `test_api_transport.sh`). `MISTRAL_API_MAX_TOKENS` default 4096 -> 16384: that smoke spent 3833 of 4096 tokens, mostly thinking. A second authorized smoke after both fixes passed: `response_quality=structured`, provider-reported `mistral-large-4`, Devil's Advocate persona, confidence 9, 244 in / 3296 out measured tokens, ~44 s, schema-valid envelope. Vibe economy moved from the retired `devstral-small-2` to `mistral-medium-3.5`. Vibe stays on `mistral-medium-3.5`.
788
+ - **Gemini policy.** Gemini 4 Argon (GA 2026-10-13; API ID `gemini-4-argon`, generateContent supported) serves maximum and premium/default: `Gemini 4 Argon (High)` on `agy`, `gemini-4-argon` on the API. Standard/economy keep `Gemini 3.8 Flash (High/Low)` on the CLI and `gemini-3.1-pro-preview` on the API (no shutdown announced; `gemini-3.8-flash` API stays opt-in until its own smoke). `configure` migrates unpinned `Gemini 3.8 Flash (High)` (plus the older Pro 3.1 / Flash 3.7 High values) and unpinned `gemini-3.1-pro-preview`. Rates use the list price ($4/$20 per 1M), not the introductory $2/$10 through 2026-11-30. API wire: `GEMINI_API_MAX_TOKENS` (default 32768, Google's minimum advice and per-request non-streaming cap) replaces the fixed 4096 because thinking counts toward `maxOutputTokens`; Argon accepts low|medium|high and defaults to `high` like its CLI target; no sampling parameters are sent (Argon ignores them); `parse_google_ai_response` joins visible text parts and skips `thought` parts. Evidence: `agy models` 1.3.6 lists Argon Low/Medium/High; one authorized `query_gemini.sh` CLI smoke on 2026-10-16 returned `response_quality=structured`, confidence 9, capability-probed identity, ~49 s, schema-valid (agy reports no usage, so tokens are estimated). No authenticated Gemini API smoke was run, so the API transport is offline-tested only. Google excludes Argon from the Free tier and the AI Pro plan. `GEMINI_TIMEOUT` defaults to 0 (no limit, see the timeout policy below), in line with Google's advice to use long client timeouts for hard prompts.
789
+ - **Timeout policy.** Generation has no wall-clock limit by default: every consultant `*_TIMEOUT`, `QWEN3/DEEPSEEK_MAX_QUALITY_TIMEOUT` and `SYNTHESIS_TIMEOUT`/`SYNTHESIS_TOTAL_TIMEOUT` default to 0 (`run_with_timeout 0` runs the command directly; `run_api_query` omits curl `-m`; `format_timeout_label` logs "none"). Reason: a client timeout usually still bills the provider call and loses the answer, and Argon/Large 4 approach the old 180 s limit. The user explicitly rejected a safety ceiling. Instead the host decides: `consult_all.sh` polls children once per second (Bash 3.2 has no `wait -n`), logs a heartbeat every `WAIT_HEARTBEAT_SECONDS` (30), and honors *proceed* (`<dir>/.proceed`, SIGUSR1, first Ctrl-C: stop the current phase, continue with received answers; during synthesis, skip it) and *abort* (`<dir>/.abort`, SIGTERM 143, SIGHUP 129, second Ctrl-C 130). Stopped consultants become `NAME:STOPPED`: partial JSON deleted, counted against quorum, not recorded as a reliability failure, excluded from cost with a billing caveat. `lib/common.sh::kill_process_tree` freezes, terminates and finally kills the whole descendant tree (walked with portable `ps -A -o pid= -o ppid=`), with stderr silenced so Bash job-termination notices stay out of logs. Escalation and synthesis run in the background under `_wait_child_under_host_control`; traps are restored after synthesis. SIGKILL on `consult_all.sh` cannot clean up and would orphan CLIs (documented). Probe limits stay: agy inventory 10-12 s, auth 8-12 s, health gate 30 s, doctor live 45 s, LLM classifier 30 s (falls back to pattern). `configure` migrates unpinned generated 180/240/480/600 values to `0 # ai-consultants:default`; pins and custom values stay limits. Tests: `test_common.sh` Test 15, `test_api_transport.sh` (curl args), `test_configure.sh` (migration), `test_e2e.sh` Tests 6-8 (proceed via file, abort via file, SIGUSR1 during synthesis; all assert no surviving stub process).
790
+ - **Review fixes (`/code-review max` on this branch).** `normalize_consultant_response_text` took its JSON-like probe from `sed`/`cut -c1`, which work line by line, so a pretty-printed truncated answer became a successful fallback instead of failing closed; it now reads the first non-blank character of the whole text, and a canonical result with several JSON values fails closed (it used to reach `build_structured_response --argjson` and leave an empty envelope). `run_api_query` wrote the key-bearing headers to a mktemp file that a stopped or killed query left on disk (reproduced with `kill_process_tree`); headers and body now go through process substitution, and the builders read the prompt from stdin (a 1.2 MB prompt previously produced an empty body via E2BIG). A host proceed during escalation ends the phase (`break`, it used to start the next billed re-query), and `_discard_late_proceed` keeps a request that lands after a phase finished from skipping the next one. The pattern classifier strips dependency/constructor/field/fault injection before the SECURITY check; `build_context.sh` never lists `$HOME` or `/` as the project tree; `provider_error_summary` reads string `error` fields (xAI); `json_schema_check.jq` reports an unknown definition or `$ref`; `kill_process_tree` re-lists the frozen tree until it is stable, from one `ps` snapshot per listing. Regression tests: `test_common.sh` Tests 8, 12, 13, 16; `test_api_transport.sh` (on-disk check, large prompts, xAI reason); `test_context_optimization.sh` Test 18; each failed on the pre-fix tree.
791
+ - **Live verification after the review (2026-10-19).** Default models, `MAX_RETRIES=1`, cache off. `balanced` (Gemini Argon High agy, Sol CLI, Large 4 API): 3/3 structured, 181 s, reported $0.22 incl. synthesis. Every consultant enabled (`DEFAULT_PRESET=` override): 9/10 structured in 172 s, reported $0.59; synthesis represented 83/83 IDs, schema-valid. Kimi failed on an expired Kimi Code OAuth grant (`OAuthUnauthorizedError` in the CLI's session wire; nothing reached the model) and passed a separate single call after `kimi login`. The adapter surfaced only the first stderr line, a `max_retries_per_step` config deprecation warning, as the reason: `run_query` reports the first line, not the first error line (open). No host stop was needed, so `.proceed`/`.abort` remain offline-tested only. The pre-run INFO estimate used to be the generic 4-consultant default-rate figure ($0.063 for both runs); it now logs the refined per-panel estimate.
792
+ - **Host harness check (2026-10-19).** Static: Codex 0.163 has no custom prompts/commands (skills only, from `~/.codex/skills` and `~/.agents/skills`); the Gemini CLI 0.64 `FileCommandLoader` globs `**/*.toml`, so `.gemini/commands/*.md` never registers (and the CLI is Homebrew-deprecated and no longer serves personal OAuth accounts); agy 1.4.2 reads `<workspace>/.agents/skills/<name>/` and `~/.gemini/config/skills/<name>/` (from its built-in instructions); the Gemini CLI shell tool kills a command after 300 s without output (the 30 s heartbeat covers it). `.codex/commands`/`.gemini/commands` stay as host-specific reference text (`test_install.sh` checks them) but are not slash commands. Live, one headless run each against this branch (temporary `~/.agents/skills` symlink and `~/.claude/commands` copies, restored afterwards): Claude Code ran the command in the foreground with a 600 s Bash timeout (it auto-backgrounds past that) and read `.synthesis_provider` as a file name, hence the clearer wording; Codex's first launch was rejected by Codex itself ("rm -f style commands are not permitted"), hence the `unlink` hint, and its memories led it to disable synthesis; agy followed the contract exactly, ran the command async (`WaitMsBeforeAsync` 10 s) and waits at most 30 min for background tasks in print mode. Claude Code host cost $0.59 (Opus 5.5).
793
+ - **Live host control and harnesses (2026-10-19, second pass).** Every stop path ran live (`.proceed`, USR1, `.abort`, SIGTERM, SIGHUP) with no process left. A real terminal Ctrl-C (SIGINT to the whole group) exposed a bug: under `set -e` the interrupted poll `sleep` ended the run with 130 and orphaned the consultant CLIs (they ignore SIGINT as background jobs); fixed with an async poll pause, a Round 1 poll loop without errexit (an interrupted `date`/`jq` would end the run too), `trap '' INT` in every consultant/escalation/synthesis job (Bash 5.2 in CI did not ignore SIGINT in them, so the adapter died and orphaned its CLI; Bash 3.2 does), host-request checks before collecting (a CLI that Ctrl-C ended is `stopped`) and an EXIT safety net; `test_e2e.sh` Tests 9-10 send SIGINT to the process group. agy 1.4.2 printed a complete synthesis and never exited (its log stops after "Stream goroutine exited", without "Language server shutting down"), so the no-timeout run hung for 16 min: `scripts/lib/agy_exit_guard.sh` (`AGY_EXIT_GRACE_SECONDS`). Hosts: Claude Code proceeds on request; agy finds `~/.gemini/config/skills` and aborts on request; Codex `workspace-write` without approvals gets 0/3 (network), and its auto-reviewer refuses the escalation (code to external providers), so the approval must come from the user; the Gemini CLI is rejected for individual accounts (`UNSUPPORTED_CLIENT`). Failure reasons were then fixed against network-denied reproductions (`sandbox-exec` with `(deny network*)`, nothing billed): `pick_error_line` (shared by `run_query` and `get_consultant_error_reason`) skips warnings and stack frames, `describe_curl_exit` names API network failures, agy inventory failures carry agy's message, and `diagnosed_failures_network_hint` flags an all-network failure (sandbox). The user's `~/.kimi-code/config.toml` `max_retries_per_step` was renamed to `max_attempts_per_step` (same value; `kimi doctor` valid).
794
+ - Release 5.2.0 bumps the version surfaces and adds `docs/releases/v5.2.0.md`; the showcase site syncs after npm serves 5.2.0. Frozen benchmark inputs are unchanged. Residual: a non-improving escalation re-query is still not billed (its file is deleted). `history.json` now stores every full question and is never pruned.
795
+
796
+ ### v5.1.2 (2026-09-28)
797
+
798
+ - **Model selection remains transport-specific.** Grok 4.7 replaces the premium/maximum default, Opus 5.5 replaces standard Claude, and Gemini 3.8 High/Low replace the respective CLI targets. Fable and API Pro 3.1 remain separate defaults. Native Gemini 3.8 API thinking accepts low/medium/high and rejects incompatible explicit values before dispatch.
799
+ - **Configuration preservation.** Exact historical defaults migrate while explicit choices survive. Quoted values plus inline default/pin markers now round-trip correctly; the previous parser retained quotes after removing the comment and missed the migration.
800
+ - **Accounting.** Google GenerateContent output is candidates plus thoughts; prompt count already includes cached input. New rates remain estimates when no provider cost is available. Grok 4.7 rates double above 200K input; Gemini introductory rates expire on 2026-12-31 and require a catalog refresh.
801
+ - **Validation scope.** Exact implementation-head CI passed 34/34 suites; Grok 4.7, Opus 5.5 and Gemini 3.8 High/Low CLI smokes passed on that code. Gemini named variants select effort through the model name and reject an additional --effort; initial rejected attempts and separately authorized corrected successes are recorded. Frozen P1.6 inputs and saved Grok work remain untouched. No model-quality gain is inferred from smoke checks.
802
+
803
+
763
804
  ### v5.1.1 (2026-09-10)
764
805
 
765
806
  - **DeepSeek V4.1 Flash policy.** `scripts/config.sh` selects `deepseek-flash` for the default and every tier. `scripts/configure.sh` migrates only the two exact historical unpinned defaults; durable pins and explicit overrides remain intact. No credentials are imported or personal configuration rewritten by the upgrade.