humanish 0.141.0 → 0.143.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 (99) hide show
  1. package/ARCHITECTURE.md +1 -0
  2. package/CHANGELOG.md +21 -0
  3. package/README.md +3 -1
  4. package/dist/analysis/admission.d.ts +8 -0
  5. package/dist/analysis/admission.js +15 -4
  6. package/dist/analysis/automatic-config.d.ts +17 -3
  7. package/dist/analysis/automatic-config.js +56 -12
  8. package/dist/analysis/automatic.js +13 -7
  9. package/dist/analysis/execute.d.ts +6 -5
  10. package/dist/analysis/execute.js +27 -26
  11. package/dist/analysis/gemini-wire.d.ts +9 -0
  12. package/dist/analysis/gemini-wire.js +166 -0
  13. package/dist/analysis/image-tokens.d.ts +4 -2
  14. package/dist/analysis/image-tokens.js +24 -3
  15. package/dist/analysis/job.d.ts +1 -0
  16. package/dist/analysis/job.js +1 -0
  17. package/dist/analysis/models.d.ts +12 -0
  18. package/dist/analysis/models.js +47 -0
  19. package/dist/analysis/openai-wire.d.ts +6 -0
  20. package/dist/analysis/openai-wire.js +102 -0
  21. package/dist/analysis/provider.d.ts +19 -7
  22. package/dist/analysis/provider.js +21 -101
  23. package/dist/analysis/responses.d.ts +3 -0
  24. package/dist/analysis/responses.js +19 -0
  25. package/dist/analysis/service.js +11 -3
  26. package/dist/analysis/types.d.ts +12 -2
  27. package/dist/analysis/validation.d.ts +1 -0
  28. package/dist/analysis/validation.js +17 -15
  29. package/dist/cli/commands/analyze.js +11 -7
  30. package/dist/cli/commands/observe.js +26 -1
  31. package/dist/cli/commands/run-command.d.ts +1 -1
  32. package/dist/cli/commands/run-command.js +12 -0
  33. package/dist/cli/commands/study-remote.d.ts +13 -0
  34. package/dist/cli/commands/study-remote.js +125 -0
  35. package/dist/cli/commands/study-route-computer-use.js +26 -2
  36. package/dist/cli/commands/study-route-scripted.js +1 -0
  37. package/dist/cli/commands/study-route-shared-world.js +1 -0
  38. package/dist/cli/commands/study-route-terminal.js +1 -0
  39. package/dist/cli/commands/study-run.js +34 -0
  40. package/dist/cli/commands/watch.js +5 -0
  41. package/dist/cli/doctor.js +7 -2
  42. package/dist/cli/findings.d.ts +9 -1
  43. package/dist/cli/findings.js +62 -17
  44. package/dist/cli/io.d.ts +8 -0
  45. package/dist/cli/io.js +2 -1
  46. package/dist/keys/key-resolution.d.ts +10 -0
  47. package/dist/keys/key-resolution.js +33 -5
  48. package/dist/observer/listen.d.ts +7 -2
  49. package/dist/observer/listen.js +10 -4
  50. package/dist/observer/render.d.ts +2 -0
  51. package/dist/observer/render.js +1 -1
  52. package/dist/observer-app.html +1 -1
  53. package/dist/remote/launch.d.ts +56 -0
  54. package/dist/remote/launch.js +365 -0
  55. package/dist/remote/observer-proxy.d.ts +11 -0
  56. package/dist/remote/observer-proxy.js +66 -0
  57. package/dist/remote/plan.d.ts +35 -0
  58. package/dist/remote/plan.js +114 -0
  59. package/dist/remote/reattach.d.ts +17 -0
  60. package/dist/remote/reattach.js +81 -0
  61. package/dist/remote/runner.d.ts +84 -0
  62. package/dist/remote/runner.js +241 -0
  63. package/dist/routes/computer-use/e2b-desktop/start.js +1 -1
  64. package/dist/routes/computer-use/types.d.ts +2 -0
  65. package/dist/routes/scripted/types.d.ts +2 -0
  66. package/dist/routes/shared-world/types.d.ts +2 -0
  67. package/dist/routes/terminal/types.d.ts +2 -0
  68. package/dist/run/costs.d.ts +2 -1
  69. package/dist/run/pricing.d.ts +13 -1
  70. package/dist/run/pricing.js +50 -4
  71. package/dist/run/results.d.ts +1 -1
  72. package/dist/run/run-cost.d.ts +2 -1
  73. package/dist/run/run-cost.js +6 -1
  74. package/dist/run/run.d.ts +13 -0
  75. package/dist/run/run.js +18 -7
  76. package/dist/run/sandbox-creates.d.ts +10 -3
  77. package/dist/run/sandbox-creates.js +48 -6
  78. package/dist/run-study.d.ts +5 -0
  79. package/dist/study/doctor.js +14 -1
  80. package/dist/study/requirements.d.ts +1 -1
  81. package/dist/study/requirements.js +8 -6
  82. package/dist/study/route-inputs.js +4 -0
  83. package/dist/study/run-study-events.d.ts +1 -1
  84. package/dist/study/run-study-events.js +9 -2
  85. package/dist/substrates/e2b/base-module.d.ts +3 -0
  86. package/dist/substrates/e2b/base-module.js +40 -0
  87. package/dist/substrates/e2b/desktop-browser.d.ts +1 -1
  88. package/dist/substrates/e2b/desktop-browser.js +24 -6
  89. package/dist/substrates/e2b/sdk.d.ts +24 -0
  90. package/dist/substrates/e2b/sdk.js +5 -1
  91. package/dist/substrates/e2b/shell-only.d.ts +5 -0
  92. package/dist/substrates/e2b/shell-only.js +27 -0
  93. package/dist/substrates/modal/sandbox.js +27 -28
  94. package/dist/substrates/modal/sdk.d.ts +7 -0
  95. package/dist/tui-app.js +46 -46
  96. package/docs/contracts/study-analysis.md +85 -4
  97. package/docs/product/automatic-analysis.md +42 -8
  98. package/package.json +2 -2
  99. package/skills/humanish/SKILL.md +18 -1
@@ -5,7 +5,8 @@ It is separate from the participant's account, recorded outcome, and the run's
5
5
  deterministic review verdict. Opening an Observer never starts a provider request.
6
6
  Supported live runs request analysis on completion by default. A study that declares no analyst
7
7
  gets the Codex account analyst when its participant is a Codex `local-agent`, and the OpenAI
8
- analyst with a separate $10 cap on its expected cost otherwise. Set `review.analysis: false` to
8
+ analyst with a separate $10 cap on its expected cost otherwise. A study can also select the
9
+ [Gemini API analyst](#gemini-api-analysis). Set `review.analysis: false` to
9
10
  disable that request; see [automatic analysis](../product/automatic-analysis.md).
10
11
 
11
12
  ## Invocation
@@ -24,7 +25,8 @@ study's input and admission estimate without credentials, a provider request,
24
25
  or a new analysis artifact. It prints the expected cost, the worst case and the
25
26
  cap; a refused dry run says why, and names the `--max-cost` that admits it.
26
27
 
27
- The default provider is `openai`; its default model is `gpt-6-astra`, with high reasoning effort. A request sends selected retained text and
28
+ The default provider is `openai`; its default model is `gpt-6.1-sol`, at medium reasoning effort
29
+ ([reasoning effort](#reasoning-effort)). A request sends selected retained text and
28
30
  captures to OpenAI, without tools, redirects, provider-side response storage, or
29
31
  automatic retries. `--question` adds a reviewer question; it never changes the
30
32
  participant assignment. For OpenAI API analysis, `--max-cost` is required, including for dry-run
@@ -117,6 +119,81 @@ the current merge instructions, billed $1.92, most of its input served from the
117
119
  provider's prompt cache, and each of its 466 citations resolved. Two runs do not
118
120
  calibrate the merge request's estimate.
119
121
 
122
+ ## Reasoning effort
123
+
124
+ `review.analysis.reasoningEffort`, or `analyze --reasoning-effort <level>`, sets how long an API
125
+ analyst reasons before it answers. OpenAI receives it as `reasoning.effort`, and Gemini as
126
+ `generationConfig.thinkingConfig.thinkingLevel` in capitals. Each model takes the levels its
127
+ provider documents for it (OpenAI's model pages and Gemini's thinking guide, read 2026-10-21):
128
+
129
+ | Model | Levels |
130
+ | ----------------------------------------------------------------------- | ----------------------------------------------- |
131
+ | `gpt-6-astra`, `gpt-6.1-sol` | `low`, `medium`, `high`, `xhigh`, `max` |
132
+ | `gpt-6-luna`, `gpt-5.6`, `gpt-5.6-sol`, `gpt-5.6-terra`, `gpt-5.6-luna` | `none`, `low`, `medium`, `high`, `xhigh`, `max` |
133
+ | `gpt-5.5` | `none`, `low`, `medium`, `high`, `xhigh` |
134
+ | `gemini-3.8-flash` | `low`, `medium`, `high` |
135
+
136
+ Any other level is refused before a request, with a message naming the levels the model takes.
137
+ The Codex account analyst runs at its fixed low effort, and a declared effort with
138
+ `provider: codex` is refused.
139
+
140
+ The default analyst, an OpenAI analysis that names no model and declares no effort, is
141
+ `gpt-6.1-sol` at `medium`, and its resolved configuration writes `reasoningEffort: medium`. A study
142
+ or command that names a model but no effort runs that model at `high`; only the default analyst
143
+ runs at medium. That analysis's configuration has no `reasoningEffort` field, so its configuration
144
+ hash, and with it reuse of an earlier analysis, is what it was before the field existed. A declared effort is stored in the analysis artifact's
145
+ `config`, `high` included, and gives the configuration its own hash. An artifact whose config has
146
+ no `reasoningEffort` ran at `high`.
147
+
148
+ Admission expects the same output at every effort, from analyses billed at `high`. No billed
149
+ analysis at a lower effort calibrates a smaller expectation yet, so a lower effort's expected cost
150
+ is likely over its bill: on 24 one-participant Taskly analyses on 2026-10-22, `gpt-6.1-sol` at
151
+ medium wrote a mean 3,747 output tokens against the 13,000 admission expects. The worst case spends the whole output allowance at any effort.
152
+
153
+ ## Gemini API analysis
154
+
155
+ `review.analysis.provider: gemini`, or `analyze --provider gemini`, sends the same request to
156
+ Google's Gemini API:
157
+
158
+ ```bash
159
+ humanish keys set gemini
160
+ humanish analyze --run latest --provider gemini --max-cost 2 --dry-run --json
161
+ humanish analyze --run latest --provider gemini --model gemini-3.8-flash --max-cost 2 --json
162
+ ```
163
+
164
+ The request goes to `generativelanguage.googleapis.com/v1beta/models/<model>:generateContent`
165
+ with the key in the `x-goog-api-key` header. It carries the same instructions, packet and
166
+ captures, with each capture at `MEDIA_RESOLUTION_HIGH`, the analysis's reasoning effort as its
167
+ thinking level (`HIGH` unless declared), one candidate,
168
+ the standard service tier, no tools and `store: false`. The key is `GEMINI_API_KEY` when set,
169
+ else `GOOGLE_API_KEY`. Google's client libraries prefer `GOOGLE_API_KEY`; humanish does not, so a
170
+ `GOOGLE_API_KEY` exported for another Google API never replaces the stored Gemini key. Key
171
+ discovery fills neither name while the other is already in the environment. Without either, the attempt ends with
172
+ `ANALYSIS_API_KEY_MISSING` and nothing is sent; the OpenAI key is never used.
173
+
174
+ The supported model is `gemini-3.8-flash`, the one with a completed live analysis. The other
175
+ Gemini models whose pages list image input and structured output join once a live analysis on
176
+ each completes. `--max-cost` is required, and admission, the cost cap, `--max-output-tokens`
177
+ (at most 32,768) and the partial result for a bill above the worst case work as on OpenAI.
178
+ Admission prices each capture at 1,120 tokens, the media-resolution guide's figure for a
179
+ high-resolution image, and expects twice the output it expects from OpenAI: one
180
+ `gemini-3.8-flash` analysis of one participant wrote 24,246 output tokens. Usage maps
181
+ `promptTokenCount` to input, `candidatesTokenCount` plus `thoughtsTokenCount` to output, and
182
+ `cachedContentTokenCount` to cached input; a usage record whose `totalTokenCount` disagrees
183
+ with those parts is kept as unknown. Rates are Google's paid standard tier. `gemini-3.8-flash`
184
+ has a published price change on 2027-01-01, and each request is priced at the rates of the day
185
+ it is sent. A free-tier key bills nothing, and Google's terms
186
+ let it use free-tier content to improve its products.
187
+
188
+ Gemini refuses the analysis schemas while they carry `maxItems`, so the request leaves those
189
+ array limits out of the schema and states them, by field path, at the end of the system
190
+ instruction. The response is still checked against the full schema. A `STOP` candidate
191
+ whose only non-thought part is the JSON answer completes. `MAX_TOKENS` and `CONTINUATION` end
192
+ as `output_incomplete`. A blocked prompt and the `SAFETY`, `RECITATION`, `LANGUAGE`,
193
+ `BLOCKLIST`, `PROHIBITED_CONTENT`, `SPII`, `ESCALATION` and image-safety finish reasons end as
194
+ `refusal`. Any other finish reason or answer shape ends as `invalid_response`. An HTTP error
195
+ keeps only its status code, which the attempt's warnings name.
196
+
120
197
  ## Codex account analysis
121
198
 
122
199
  A study whose participant is a Codex `local-agent` uses this analyst unless it declares another,
@@ -492,11 +569,15 @@ The states without findings:
492
569
  `analyze --max-cost 10`, which runs an analysis anyway. For a skip without `OPENAI_API_KEY`
493
570
  on a machine where Codex is signed in with a ChatGPT account (read when the view is built),
494
571
  `next` is `analyze --provider codex` and the message names `review.analysis.provider: codex`
495
- in the run's study file; otherwise the message says to set the key. For an analysis refused for its
572
+ in the run's study file; otherwise the message says to set the key. A study analyzed on Gemini
573
+ is skipped with `AUTOMATIC_ANALYSIS_GEMINI_KEY_MISSING`; its message names `keys set gemini`,
574
+ and `next` is `analyze --provider gemini --model <model> --max-cost 10`.
575
+ For an analysis refused for its
496
576
  cost, the message gives the expected cost, the worst case and the cap, and `next` sets
497
577
  `--max-cost` to the worst case rounded up.
498
578
  - `failed`: the latest attempt failed or was cancelled and no usable version exists. `next`
499
- reruns it with the same analyst, `--provider codex` for the Codex account analyst.
579
+ reruns it with the same analyst: `--provider codex` for the Codex account analyst, and
580
+ `--provider gemini --model <model>` for a Gemini one.
500
581
  - `none`: no analysis ran for this live run and nothing records why, for example a run that
501
582
  started from a library call, or one whose study file has moved or changed id.
502
583
  - `dry_run`: a dry run has no participant evidence to analyze. `next` is `run` with the run's own
@@ -10,8 +10,12 @@ Every other participant, including a Claude Code `local-agent` participant, gets
10
10
  analyst. humanish never moves a study to the other analyst because a key is missing: the account
11
11
  that pays for analysis is the one the study names or its participant implies.
12
12
 
13
- The OpenAI default is `gpt-6-astra` with high reasoning effort, a separate $10 cap on its
14
- expected cost and a 600-second timeout. When no output limit is specified,
13
+ The OpenAI default is `gpt-6.1-sol` at medium reasoning effort (`review.analysis.reasoningEffort`
14
+ sets another), a separate $10 cap on its
15
+ expected cost and a 600-second timeout. A study or command that names a model but no effort runs
16
+ that model at high; only the default analyst, with no model named, runs at medium. On the same
17
+ recordings it matched `gpt-6-astra` at high, the earlier default, at about one seventh of the cost
18
+ ([analysis models on fixed recordings](https://github.com/danielgwilson/humanish/blob/main/docs/evidence/benchmark/2026-10-22-analysis-models.md)). When no output limit is specified,
15
19
  humanish selects 32,768 tokens if the exact input's expected cost still fits that
16
20
  cap; otherwise it keeps the established 16,384-token allowance. This preserves
17
21
  previously admitted studies without increasing their spending limit. To customize it:
@@ -21,7 +25,9 @@ review:
21
25
  analysis:
22
26
  maxCostUsd: 10
23
27
  # Optional overrides. Omit maxOutputTokens for budget-aware selection.
24
- model: gpt-6-astra
28
+ # A named model without reasoningEffort runs at high.
29
+ model: gpt-6.1-sol
30
+ reasoningEffort: medium
25
31
  timeoutMs: 600000
26
32
  # maxOutputTokens: 32768
27
33
  # question: Where did participants need to recover?
@@ -41,16 +47,20 @@ the cap admits no analysis at all, it says so instead. A study of more than 16 p
41
47
  analysed in cohorts of at most 16, one request each, and one more request merges their reports;
42
48
  the range covers every request and the analysis line names them (see
43
49
  [runs with more than 16 participants](../contracts/study-analysis.md#runs-with-more-than-16-participants)).
44
- The default $10 cap admits a single request at the evidence limits ($3.79 expected for one
45
- participant, $4.54 for 16) and the analysis of 17 to 40 participants from $4.60 to $7.05 with no
46
- evidence; a run that keeps more evidence can still be refused, and its skip names the
50
+ The default $10 cap admits the default analyst up to the evidence limits: a single request at
51
+ $0.76 expected for one participant and $0.91 for 16, and 17 to 40 participants at $0.92 to $3.24
52
+ from no evidence to the limits. Admission expects 13,000 output tokens for one participant at any
53
+ effort; on 24 Taskly analyses `gpt-6.1-sol` at medium wrote a mean 3,747 and cost a mean $0.06.
54
+ `gpt-6-astra` at high expects $3.79 for one participant at the limits and $4.60 to $7.05 for 17 to
55
+ 40 with no evidence, so a run that keeps more evidence can be refused, and its skip names the
47
56
  `--max-cost` that admits it. Use `analyze --dry-run --max-cost <usd>` on retained
48
57
  evidence to inspect the expected cost, the worst case and the selected token
49
58
  allowance before deliberately choosing a larger budget. Explicit
50
59
  `maxOutputTokens` and `--max-output-tokens` limits are honored exactly. The output allowance
51
60
  includes reasoning as well as the report; exhausting it does not produce a usable
52
61
  report and never starts an automatic retry. Analysis
53
- sends selected retained text and captures to OpenAI using `OPENAI_API_KEY`.
62
+ sends selected retained text and captures to OpenAI using `OPENAI_API_KEY`, or to Google with
63
+ `provider: gemini`.
54
64
  Analysis runs in the humanish runner using its credentials. This setting adds no
55
65
  credential channel to the target application; each participant's route keeps
56
66
  its existing authentication boundary. Review the separate analysis budget before running a manifest live; an actor's
@@ -78,6 +88,28 @@ remain untested until a request. An omitted provider means this analyst for a Co
78
88
  `local-agent` participant on any target, and OpenAI for every other participant. This setting
79
89
  does not enable managed local desktops.
80
90
 
91
+ To use Google's Gemini API for the separate analyst:
92
+
93
+ ```yaml
94
+ review:
95
+ analysis:
96
+ provider: gemini
97
+ model: gemini-3.8-flash
98
+ maxCostUsd: 2
99
+ ```
100
+
101
+ Gemini analysis sends the same evidence packet and captures to Google, at the high thinking level
102
+ unless the study declares a `reasoningEffort`,
103
+ with each capture at high media resolution. It reads `GEMINI_API_KEY`, which `humanish keys set
104
+ gemini` stores, and `GOOGLE_API_KEY` only when `GEMINI_API_KEY` is unset. Key discovery treats
105
+ the two names as one key: a project's `.humanish/local/provider.env` or the user store never adds
106
+ one while the other is already in the environment. A missing Gemini key skips the analysis
107
+ (`AUTOMATIC_ANALYSIS_GEMINI_KEY_MISSING`); the OpenAI key is never used in its place. Admission,
108
+ `maxCostUsd`, `maxOutputTokens` and priced usage work as they do on OpenAI, at the paid-tier
109
+ rates in `src/run/pricing.ts`; requests made with a free-tier key bill nothing, and Google's
110
+ terms let it use free-tier content to improve its products. The supported model is
111
+ `gemini-3.8-flash`, the one with a completed live analysis.
112
+
81
113
  The same configuration works through `humanish run <study>`,
82
114
  `watch <study>`, and TUI live starts. Direct library calls to the five recording
83
115
  producers honor it too. Supported routes are computer-use, scripted-browser,
@@ -147,7 +179,8 @@ run's own result is ok, the first line of the human output reads
147
179
  command: with Codex signed in with a ChatGPT account it is `humanish analyze --run <id>
148
180
  --provider codex`, and the message names `review.analysis.provider: codex` as the setting that
149
181
  makes that analyst the study's; otherwise it says to set the key and names `humanish analyze
150
- --run <id> --max-cost 10`. So does a
182
+ --run <id> --max-cost 10`. A study analyzed on Gemini names `humanish keys set gemini` and
183
+ `humanish analyze --run <id> --provider gemini --model <model> --max-cost 10`. So does a
151
184
  default analysis whose expected cost, plus the margin, is over the default $10 cap:
152
185
  it is skipped with `AUTOMATIC_ANALYSIS_ADMISSION_REFUSED` and the run exits 0. For
153
186
  any analysis refused for its cost, the job records the expected cost, the worst
@@ -197,6 +230,7 @@ JSON also has `findings`:
197
230
  | `AUTOMATIC_ANALYSIS_SOURCE_UNAVAILABLE` | `skipped` | This invocation published no run to analyze, or the run id is invalid |
198
231
  | `AUTOMATIC_ANALYSIS_SOURCE_CHANGED` | `failed` | The run directory changed after the run published its bundle |
199
232
  | `AUTOMATIC_ANALYSIS_KEY_MISSING` | `skipped` | No OpenAI API key |
233
+ | `AUTOMATIC_ANALYSIS_GEMINI_KEY_MISSING` | `skipped` | No Gemini API key for a study analyzed on Gemini |
200
234
  | `AUTOMATIC_ANALYSIS_NO_PARTICIPANT_EVIDENCE` | `skipped` | A default analysis found no participant evidence |
201
235
  | `AUTOMATIC_ANALYSIS_ACTOR_CANCELLED` | `skipped` | The harness cancelled the participants, or a signal stopped the run |
202
236
  | `AUTOMATIC_ANALYSIS_CLEANUP_UNCONFIRMED` | `skipped` | A local VM study could not confirm its cleanup; the command exits 2 |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "humanish",
3
- "version": "0.141.0",
3
+ "version": "0.143.0",
4
4
  "description": "Synthetic user research for apps, CLIs, and agent-facing product flows.",
5
5
  "keywords": [
6
6
  "cli",
@@ -96,7 +96,7 @@
96
96
  "comms:agentmail:contract": "node --import tsx scripts/agentmail-contract-check.mjs",
97
97
  "format": "oxfmt",
98
98
  "format:check": "oxfmt --check",
99
- "lint": "node scripts/check-lint-cap.mjs --max-warnings=411",
99
+ "lint": "node scripts/check-lint-cap.mjs --max-warnings=410",
100
100
  "knip": "knip",
101
101
  "prose:check": "node scripts/check-code-prose.mjs",
102
102
  "vocabulary:check": "tsx scripts/check-retired-words.ts",
@@ -98,7 +98,8 @@ exact returned path, not a basename that could resolve to another manifest.
98
98
  Analysis is separate from the participant. A study that declares no analyst
99
99
  gets one from its participant: a Codex `local-agent` participant, local or
100
100
  hosted, defaults to a separate Codex account analyst; every other participant,
101
- Claude Code included, defaults to the OpenAI API with a $10 admission budget.
101
+ Claude Code included, defaults to the OpenAI API (`gpt-6.1-sol` at medium
102
+ reasoning effort) with a $10 admission budget.
102
103
  Without `OPENAI_API_KEY` that OpenAI analysis is skipped, and the run output
103
104
  names the next command: `analyze --provider codex` when Codex is signed in. To
104
105
  select the restricted Codex ChatGPT account analyst on any supported study,
@@ -108,6 +109,22 @@ not local inference or the participant's existing conversation. See
108
109
  [the analysis contract](../../docs/contracts/study-analysis.md) for the current
109
110
  CLI/model qualification and setup limits.
110
111
 
112
+ To analyze on Gemini, the user stores a key with `npx humanish keys set gemini`
113
+ (`GEMINI_API_KEY`; `GOOGLE_API_KEY` is read only when `GEMINI_API_KEY` is
114
+ unset), then sets `review.analysis: {provider: gemini, maxCostUsd: <n>}` or
115
+ passes `analyze --provider gemini --max-cost <n>`. The supported model is
116
+ `gemini-3.8-flash`. This sends the evidence packet and
117
+ captures to Google. Admission, the cost cap and priced usage work as on OpenAI,
118
+ and a missing Gemini key never falls back to OpenAI. On a free-tier key, Google
119
+ may use the content to improve its products; tell the user before a study with
120
+ private evidence runs on one.
121
+
122
+ `review.analysis.reasoningEffort` (or `analyze --reasoning-effort <level>`)
123
+ sets an OpenAI or Gemini analyst's reasoning effort. When unset it is `medium`
124
+ for the default analyst, which names no model, and `high` for a named model.
125
+ Each model takes only the levels its provider documents, and `analyze` refuses
126
+ the others before any request with the levels the model takes.
127
+
111
128
  When post-run analysis is refused for its cost, the run output and `humanish
112
129
  review` give its expected cost, its worst case and the command that runs it,
113
130
  `humanish analyze --run <id> --max-cost <n>`. Show the user those costs and run