humanish 0.139.1 → 0.140.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 (56) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +5 -4
  3. package/dist/analysis/automatic-completion.js +24 -0
  4. package/dist/analysis/automatic-config.d.ts +15 -6
  5. package/dist/analysis/automatic-config.js +25 -9
  6. package/dist/cli/commands/study-route-computer-use.js +2 -3
  7. package/dist/cli/commands/study-route-scripted.js +3 -4
  8. package/dist/cli/commands/study-route-shared-world.js +2 -3
  9. package/dist/cli/commands/study-route-terminal.js +3 -4
  10. package/dist/cli/commands/study-run.js +1 -1
  11. package/dist/cli/doctor.d.ts +2 -0
  12. package/dist/cli/doctor.js +3 -0
  13. package/dist/cli/findings.d.ts +17 -14
  14. package/dist/cli/findings.js +37 -31
  15. package/dist/cli/io.d.ts +5 -1
  16. package/dist/cli/io.js +11 -2
  17. package/dist/cli/run-findings.d.ts +19 -0
  18. package/dist/cli/run-findings.js +106 -0
  19. package/dist/guest/bootstrap.d.ts +4 -2
  20. package/dist/guest/bootstrap.js +15 -7
  21. package/dist/guest/display-config.d.ts +31 -0
  22. package/dist/guest/display-config.js +35 -0
  23. package/dist/guest/runtime-desktop.d.ts +9 -3
  24. package/dist/guest/runtime-desktop.js +59 -25
  25. package/dist/guest/runtime.d.ts +2 -1
  26. package/dist/guest/runtime.js +1 -1
  27. package/dist/guest-runtime-main.js +2 -1
  28. package/dist/routes/computer-use/e2b-desktop/fidelity.js +10 -17
  29. package/dist/routes/computer-use/local-vm.js +34 -1
  30. package/dist/routes/computer-use/plan.js +1 -1
  31. package/dist/routes/scripted/plan.js +1 -1
  32. package/dist/routes/shared-world/plan.js +1 -1
  33. package/dist/routes/terminal/plan.js +1 -1
  34. package/dist/run/route-shell.js +1 -1
  35. package/dist/study/doctor.js +11 -6
  36. package/dist/study/init-templates.js +9 -3
  37. package/dist/study/mobile-emulation.d.ts +27 -0
  38. package/dist/study/mobile-emulation.js +60 -0
  39. package/dist/study/plan.js +1 -1
  40. package/dist/study/preflight-result.js +1 -1
  41. package/dist/study/summary.js +1 -1
  42. package/dist/study/warnings.js +5 -2
  43. package/dist/substrates/e2b/cdp-probe.d.ts +2 -6
  44. package/dist/substrates/e2b/desktop-cdp.d.ts +0 -2
  45. package/dist/substrates/e2b/desktop-cdp.js +0 -2
  46. package/dist/substrates/local/firecracker-desktop.d.ts +5 -0
  47. package/dist/substrates/local/firecracker-desktop.js +7 -1
  48. package/dist/substrates/local/runtime-config.d.ts +12 -0
  49. package/dist/substrates/local/runtime-config.js +55 -13
  50. package/dist/substrates/local/runtime-release.js +8 -8
  51. package/dist/substrates/local/runtime.js +1 -0
  52. package/docs/contracts/study-analysis.md +14 -8
  53. package/docs/principles/invariants-and-defaults.md +1 -1
  54. package/docs/product/automatic-analysis.md +46 -11
  55. package/package.json +1 -1
  56. package/skills/humanish/SKILL.md +45 -26
@@ -3,15 +3,16 @@
3
3
  Study analysis is an independent interpretation of retained participant evidence.
4
4
  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
- Supported live runs request analysis on completion by default, with a separate
7
- $3 cap on its expected cost. Set `review.analysis: false` to disable that request;
8
- see [automatic analysis](../product/automatic-analysis.md).
6
+ Supported live runs request analysis on completion by default. A study that declares no analyst
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
9
+ disable that request; see [automatic analysis](../product/automatic-analysis.md).
9
10
 
10
11
  ## Invocation
11
12
 
12
13
  ```bash
13
- humanish analyze --run latest --max-cost 3 --dry-run --json
14
- humanish analyze --run latest --max-cost 3 --json
14
+ humanish analyze --run latest --max-cost 10 --dry-run --json
15
+ humanish analyze --run latest --max-cost 10 --json
15
16
  humanish observe --run latest
16
17
  humanish analyze list --run latest --json
17
18
  humanish analyze show --run latest --json
@@ -116,9 +117,11 @@ the current merge instructions, billed $1.92, most of its input served from the
116
117
  provider's prompt cache, and each of its 466 citations resolved. Two runs do not
117
118
  calibrate the merge request's estimate.
118
119
 
119
- ## Explicit Codex account analysis
120
+ ## Codex account analysis
120
121
 
121
- An existing completed recording can use a separate restricted Codex analyst:
122
+ A study whose participant is a Codex `local-agent` uses this analyst unless it declares another,
123
+ and any study can select it with `review.analysis.provider: codex`. An existing completed
124
+ recording can use it too:
122
125
 
123
126
  ```bash
124
127
  humanish analyze --run latest --provider codex --dry-run --json
@@ -486,7 +489,10 @@ The states without findings:
486
489
  - `skipped`: the automatic analysis was skipped or refused, for example without
487
490
  `OPENAI_API_KEY`, or the run's study file sets `review.analysis: false`
488
491
  (`AUTOMATIC_ANALYSIS_DISABLED`, read from the file when the view is built). `next` is
489
- `analyze --max-cost 3`, which runs an analysis anyway. For an analysis refused for its
492
+ `analyze --max-cost 10`, which runs an analysis anyway. For a skip without `OPENAI_API_KEY`
493
+ on a machine where Codex is signed in with a ChatGPT account (read when the view is built),
494
+ `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
490
496
  cost, the message gives the expected cost, the worst case and the cap, and `next` sets
491
497
  `--max-cost` to the worst case rounded up.
492
498
  - `failed`: the latest attempt failed or was cancelled and no usable version exists. `next`
@@ -90,7 +90,7 @@ silently drifting from one is not.
90
90
  | Default | Why it is the default | Legitimate override |
91
91
  | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
92
92
  | Dry-run | Spend safety (the live-spend rule sets the floor; dry-run keeps it far away) | `mode: live` |
93
- | Post-run analysis on supported live studies | Findings accompany the recording; a separate $3 cap on its expected cost is visible before execution | `review.analysis: false` disables it; an explicit mapping sets another analysis budget. Dry-run and unsupported routes never dispatch; missing default credentials produce a recorded skip |
93
+ | Post-run analysis on supported live studies | Findings accompany the recording; a Codex participant's run is analyzed by the same account, and otherwise a separate $10 cap on its expected cost is visible before execution | `review.analysis: false` disables it; an explicit mapping sets another analysis budget. Dry-run and unsupported routes never dispatch; missing default credentials produce a recorded skip |
94
94
  | Separate worlds (`per-lane-worlds`) | Isolation, attribution, reproducibility | `route: shared-world`: N participants against one mutable plane for scenarios that are about interaction between participants. Participants run at once, as many as `execution.concurrency` (two or more) and the E2B plan's limit allow, unless the study declares when each one starts (`participants[].startAfterMs`). The plane is one getHost-exposed subject sandbox with synthetic seeded data, or an operator-owned public deployment (external-public), driven by N actor sandboxes. The bundle declares the weaker `attributionClass: shared-world` and a verify-enforced `attributionLimits` ceiling (`best-effort-causal-attribution` and the rest of the concurrent set). Sequential turns at `execution.concurrency: 1` were removed in 0.106.0. |
95
95
  | External key placement | Smallest blast radius: when the keyed process (e.g. a computer-use provider loop) runs outside the sandbox, its key never enters | In-sandbox placement when the keyed process runs inside (an agent harness under test); declared per actor type, with a spend budget |
96
96
  | Loopback entry URLs | Public-safety: never drive third-party sites unbidden | `policies.allowPublicTargets` for an owner-declared deployment/preview (a Vercel preview of your own app). Multi-participant public/preview fan-out needs explicit `participants[].target` for every participant, so the adapter-owned topology is declared rather than inferred. Provisioned clone subjects always serve in-sandbox on loopback |
@@ -3,7 +3,14 @@
3
3
  Supported live studies automatically request analysis after each recording finishes. Findings remain
4
4
  separate from participant feedback and the recorded study verdict.
5
5
 
6
- The default is `gpt-6-astra` with high reasoning effort, a separate $3 cap on its
6
+ A study that declares no `review.analysis` gets its analyst from its participant (`actor`). A
7
+ Codex `local-agent` participant, on a local or hosted desktop, gets the Codex account analyst
8
+ described below, so a study run on a signed-in Codex needs no OpenAI API key for its findings.
9
+ Every other participant, including a Claude Code `local-agent` participant, gets the OpenAI
10
+ analyst. humanish never moves a study to the other analyst because a key is missing: the account
11
+ that pays for analysis is the one the study names or its participant implies.
12
+
13
+ The OpenAI default is `gpt-6-astra` with high reasoning effort, a separate $10 cap on its
7
14
  expected cost and a 600-second timeout. When no output limit is specified,
8
15
  humanish selects 32,768 tokens if the exact input's expected cost still fits that
9
16
  cap; otherwise it keeps the established 16,384-token allowance. This preserves
@@ -12,7 +19,7 @@ previously admitted studies without increasing their spending limit. To customiz
12
19
  ```yaml
13
20
  review:
14
21
  analysis:
15
- maxCostUsd: 3
22
+ maxCostUsd: 10
16
23
  # Optional overrides. Omit maxOutputTokens for budget-aware selection.
17
24
  model: gpt-6-astra
18
25
  timeoutMs: 600000
@@ -20,7 +27,8 @@ review:
20
27
  # question: Where did participants need to recover?
21
28
  ```
22
29
 
23
- Omitting `review.analysis` uses these defaults. Set `review.analysis: false` to
30
+ Omitting `review.analysis` uses these defaults for any participant other than a Codex
31
+ `local-agent`. Set `review.analysis: false` to
24
32
  run participants without the additional analysis request. An explicit analysis
25
33
  mapping using the default OpenAI API provider requires `maxCostUsd`. Admission
26
34
  refuses the request when both its worst case and its expected cost plus a 10% margin are over
@@ -33,9 +41,10 @@ the cap admits no analysis at all, it says so instead. A study of more than 16 p
33
41
  analysed in cohorts of at most 16, one request each, and one more request merges their reports;
34
42
  the range covers every request and the analysis line names them (see
35
43
  [runs with more than 16 participants](../contracts/study-analysis.md#runs-with-more-than-16-participants)).
36
- The default $3 cap refuses the analysis of 17 participants even for a run that keeps no evidence,
37
- so a default analysis of more than 16 participants is skipped with
38
- `AUTOMATIC_ANALYSIS_ADMISSION_REFUSED` unless `review.analysis.maxCostUsd` admits it. Use `analyze --dry-run --max-cost <usd>` on retained
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
47
+ `--max-cost` that admits it. Use `analyze --dry-run --max-cost <usd>` on retained
39
48
  evidence to inspect the expected cost, the worst case and the selected token
40
49
  allowance before deliberately choosing a larger budget. Explicit
41
50
  `maxOutputTokens` and `--max-output-tokens` limits are honored exactly. The output allowance
@@ -65,8 +74,8 @@ enforced output-token ceiling are unknown, so omit `maxCostUsd` and
65
74
  allocated. There is no API fallback. Missing or unsupported account setup leaves
66
75
  an explicit failed analysis state and the original recording intact. Use
67
76
  `humanish doctor --study <study>` for setup checks; account allowance and model access
68
- remain untested until a request. An omitted provider still means OpenAI, including
69
- hosted studies whose participant uses a local Codex or Claude login. This setting
77
+ remain untested until a request. An omitted provider means this analyst for a Codex
78
+ `local-agent` participant on any target, and OpenAI for every other participant. This setting
70
79
  does not enable managed local desktops.
71
80
 
72
81
  The same configuration works through `humanish run <study>`,
@@ -95,7 +104,7 @@ runner continues after the TUI closes; reopening the TUI or Observer reads the
95
104
  existing job and does not start another request. Concurrent or repeated automatic
96
105
  invocations cannot silently retry a paid attempt. If a process disappears while
97
106
  an attempt is in flight, its state can be unknown rather than falsely complete.
98
- Use manual `humanish analyze --run <exact-run-id> --max-cost 3` for an intentional
107
+ Use manual `humanish analyze --run <exact-run-id> --max-cost 10` for an intentional
99
108
  follow-up after inspecting the existing attempt and its accounting. For the account branch, use `humanish analyze --run <exact-run-id> --provider codex --rerun` without a dollar limit.
100
109
 
101
110
  Stopping participant execution does not start a fresh automatic analysis. A
@@ -113,8 +122,12 @@ unknown analysis produces exit code 2 without discarding the recording. When the
113
122
  run's own result is ok, the first line of the human output reads
114
123
  `humanish run <study>: live run finished; the analysis did not complete`. A missing
115
124
  `OPENAI_API_KEY` skips default analysis and preserves a successful run exit;
116
- `automaticAnalysisTrigger: "default"` distinguishes that case in JSON. So does a
117
- default analysis whose expected cost, plus the margin, is over the default $3 cap:
125
+ `automaticAnalysisTrigger: "default"` distinguishes that case in JSON. The skip names the next
126
+ command: with Codex signed in with a ChatGPT account it is `humanish analyze --run <id>
127
+ --provider codex`, and the message names `review.analysis.provider: codex` as the setting that
128
+ makes that analyst the study's; otherwise it says to set the key and names `humanish analyze
129
+ --run <id> --max-cost 10`. So does a
130
+ default analysis whose expected cost, plus the margin, is over the default $10 cap:
118
131
  it is skipped with `AUTOMATIC_ANALYSIS_ADMISSION_REFUSED` and the run exits 0. For
119
132
  any analysis refused for its cost, the job records the expected cost, the worst
120
133
  case and the cap, and the CLI, `humanish review` and the Observer give them with
@@ -126,6 +139,28 @@ findings remain visibly partial; a valid partial result can succeed, while a
126
139
  partial result with an analysis error still fails the command. Recorded task
127
140
  outcomes and the deterministic review verdict are never rewritten by analysis.
128
141
 
142
+ After a live run the human output ends with the analysis line. When the analysis left findings,
143
+ the line gives its state and the top three findings follow, with the `humanish review --run <id>`
144
+ command that prints all of them. Otherwise the line says what happened and a `next:` line gives
145
+ the command that gets findings, when one can. A dry run keeps its one line,
146
+ `analysis: skipped for dry runs`.
147
+
148
+ `run --json` and `watch --json` carry the same on `automaticAnalysis`: `message`, the sentence the
149
+ human line is built from, and `nextCommand`, the command that gets findings or, when the analysis
150
+ left them, the `review` command (null when no command can). When the analysis left findings the
151
+ JSON also has `findings`:
152
+
153
+ | Field | Meaning |
154
+ | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
155
+ | `analysisId` | The analysis the findings come from |
156
+ | `status` | `complete` or `partial` |
157
+ | `count` | How many findings the analysis made |
158
+ | `designFindingCount` | How many design findings it made; null for an analysis written before them |
159
+ | `top` | At most five findings, highest priority first: `id`, `title`, `headline`, `impact`, `confidence` and `participants` (the affected participant ids) |
160
+ | `review` | `humanish review --run <id>`, which prints every finding with its evidence |
161
+ | `observer` | The run's Observer page opened on the findings (`observer/index.html#/report`); null without an Observer |
162
+ | `path` | analysis.json relative to the project directory |
163
+
129
164
  `automaticAnalysis.reason` is one of these codes, in `--json` and in the human line
130
165
  `analysis: <state> (<reason>)`:
131
166
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "humanish",
3
- "version": "0.139.1",
3
+ "version": "0.140.0",
4
4
  "description": "Synthetic user research for apps, CLIs, and agent-facing product flows.",
5
5
  "keywords": [
6
6
  "cli",
@@ -95,10 +95,13 @@ exact returned path, not a basename that could resolve to another manifest.
95
95
 
96
96
  ## Choosing a findings analyst
97
97
 
98
- Analysis is separate from the participant. Hosted and manual defaults use the
99
- OpenAI API with its own admission budget. An explicitly local browser study with
100
- a Codex participant defaults to a separate Codex account analyst. To select that
101
- restricted Codex ChatGPT account analyst on other supported studies,
98
+ Analysis is separate from the participant. A study that declares no analyst
99
+ gets one from its participant: a Codex `local-agent` participant, local or
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.
102
+ Without `OPENAI_API_KEY` that OpenAI analysis is skipped, and the run output
103
+ names the next command: `analyze --provider codex` when Codex is signed in. To
104
+ select the restricted Codex ChatGPT account analyst on any supported study,
102
105
  set `review.analysis.provider: codex` or pass `analyze --provider codex` on a
103
106
  completed recording. This uses remote inference and the qualified CLI/login,
104
107
  not local inference or the participant's existing conversation. See
@@ -133,7 +136,8 @@ the pinned runtime; a live local run also prepares it automatically. The normal
133
136
  See [the complete example and limits](https://humanish.dev/docs/local-browser).
134
137
 
135
138
  Local browsers currently require a loopback app URL with an explicit port above
136
- 1023 and use a 960×720 Chromium desktop. For email-gated local apps, start
139
+ 1023 and use a 960×720 Chromium desktop unless a device preset or
140
+ `execution.desktop.resolution` sets each participant's screen. For email-gated local apps, start
137
141
  `humanish comms catch`, point the app's email sends at it, and declare
138
142
  `comms.email.external.catchBaseUrl`. Use `doctor --study` to check its recipient
139
143
  routes. This captures app sends without mailbox-provider credentials; it does
@@ -419,14 +423,15 @@ credits, or claim product behavior proof from a dry run.
419
423
  When the target app can run locally, prove a known browser path with a
420
424
  scripted-browser study after starting the app on loopback. The study replays a
421
425
  `browser.steps` scenario (see above) on a desktop surface, plus a mobile one
422
- with `count: 2`. The scripted steps make no model requests. Post-run analysis
423
- still runs by default when `OPENAI_API_KEY` is set, with a $3 cap; keep
424
- `review.analysis: false` to skip it. Copy the shape of
426
+ with `count: 2`. The scripted steps make no model requests; the analysis after
427
+ the run does, and it is what produces findings. Copy the shape of
425
428
  [`humanish/studies/scripted-demo.yaml`](https://github.com/danielgwilson/humanish/blob/main/humanish/studies/scripted-demo.yaml)
426
429
  or the example in the
427
- [study file reference](https://humanish.dev/docs/study-files#scripted-browser-scenarios):
428
- set `subject.appUrl` to the loopback URL, `scenario` to the scenario id,
429
- and `mode: live`. Without `mode: live` the study is a dry run that opens
430
+ [study file reference](https://humanish.dev/docs/study-files#scripted-browser-scenarios),
431
+ leaving out the demo's `review.analysis: false`, which keeps that zero-spend
432
+ demo from requesting analysis: set `subject.appUrl` to the loopback URL,
433
+ `scenario` to the scenario id, and `mode: live`. Set `review.analysis: false`
434
+ only when the user has chosen a run with no findings. Without `mode: live` the study is a dry run that opens
430
435
  no browser.
431
436
 
432
437
  ```bash
@@ -441,6 +446,32 @@ Do not use `humanish watch --count ...` as a substitute for a scripted-browser
441
446
  study. `watch` without a study starts a preview run for the Observer; a live scripted-browser
442
447
  study captures desktop and mobile browser evidence against a running app.
443
448
 
449
+ ## After a Live Run, Read and Report Its Findings
450
+
451
+ A live run ends with a separate analysis of its evidence, and `run --json`
452
+ carries what that analysis left. `findings.count` is how many findings it made;
453
+ `findings.top` holds at most five, each with its `title`, `headline`, `impact`,
454
+ `confidence` and the ids of the `participants` it affected; `findings.review` is
455
+ the command that prints every finding with its evidence; `findings.observer` is
456
+ the Observer page that opens on the findings. When the analysis left no
457
+ findings, `findings` is absent, `automaticAnalysis.message` says why, and
458
+ `automaticAnalysis.nextCommand` is the command that gets them (null when no
459
+ command can). Run that command, or tell the user to.
460
+
461
+ Read the full findings before reporting anything else:
462
+
463
+ ```bash
464
+ npx humanish review --run <id> # the verdict, then each analysis finding
465
+ npx humanish review --run <id> --json # the same; findings are under `analysis`
466
+ ```
467
+
468
+ Report each finding to the user: its title, impact, confidence and recovery, the participants it
469
+ affected, and the capture files it cites. These come from the post-run analysis of the evidence.
470
+ Label the participant's own report in the review summary as the participant's account. When
471
+ `analysis.state` is not `ready`, report `analysis.message` and the `analysis.next` command in
472
+ place of findings; `analysis.next` is null when no command can produce them. `latest` moves with
473
+ every run, including dry runs, so use the run id the run printed.
474
+
444
475
  ## Optional Live E2B Study
445
476
 
446
477
  Live headed E2B desktop participants are optional. Add the substrate dependency only
@@ -473,21 +504,9 @@ publish their names, screenshots, logs, source snippets, or operational details.
473
504
 
474
505
  ## Reporting Back
475
506
 
476
- After a live run, read its findings before anything else:
477
-
478
- ```bash
479
- npx humanish review --run <id> # the verdict, then each analysis finding
480
- npx humanish review --run <id> --json # the same; findings are under `analysis`
481
- ```
482
-
483
- Report each finding to the user: its title, impact, confidence and recovery, the participants it
484
- affected, and the capture files it cites. These come from the post-run analysis of the evidence.
485
- Label the participant's own report in the review summary as the participant's account. When
486
- `analysis.state` is not `ready`, report `analysis.message` and the `analysis.next` command in
487
- place of findings; `analysis.next` is null when no command can produce them. `latest` moves with
488
- every run, including dry runs, so use the run id the run printed.
489
-
490
- Then report:
507
+ Report a live run's findings first, as
508
+ [After a Live Run, Read and Report Its Findings](#after-a-live-run-read-and-report-its-findings)
509
+ describes. Then report:
491
510
 
492
511
  - files changed in the target repo;
493
512
  - exact proof commands run;