humanish 0.134.0 → 0.136.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 (62) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/actors/computer-use/loop/session.js +7 -2
  3. package/dist/actors/scripted-browser/actor.js +3 -3
  4. package/dist/actors/scripted-browser/steps.d.ts +9 -2
  5. package/dist/actors/scripted-browser/steps.js +17 -12
  6. package/dist/analysis/automatic-config.js +5 -3
  7. package/dist/analysis/evidence-sources.js +4 -7
  8. package/dist/analysis/evidence.js +4 -4
  9. package/dist/analysis/execute.js +2 -1
  10. package/dist/analysis/service.js +2 -1
  11. package/dist/analysis/source.d.ts +7 -4
  12. package/dist/analysis/source.js +22 -4
  13. package/dist/cli/commands/setup.js +7 -10
  14. package/dist/evidence/encoded-text.d.ts +13 -3
  15. package/dist/evidence/encoded-text.js +88 -25
  16. package/dist/evidence/image.d.ts +2 -2
  17. package/dist/evidence/image.js +47 -32
  18. package/dist/observer/data.d.ts +7 -3
  19. package/dist/observer/page-data.d.ts +6 -0
  20. package/dist/observer/page-data.js +34 -7
  21. package/dist/observer/participant-items.d.ts +15 -1
  22. package/dist/observer/participant-items.js +4 -3
  23. package/dist/observer/render.js +2 -4
  24. package/dist/observer/run-routes.js +4 -4
  25. package/dist/observer-app.html +4 -4
  26. package/dist/routes/computer-use/fanout-bundle.js +3 -3
  27. package/dist/routes/computer-use/participant-execution.js +1 -1
  28. package/dist/routes/computer-use/participant-runs.js +2 -2
  29. package/dist/routes/computer-use/single-bundle.js +3 -3
  30. package/dist/routes/scripted/setup.js +62 -17
  31. package/dist/routes/shared-world/bundle.js +3 -3
  32. package/dist/routes/shared-world/participant-specs.js +2 -2
  33. package/dist/routes/terminal/bundle.js +2 -2
  34. package/dist/run/bundle.d.ts +5 -1
  35. package/dist/run/locate.d.ts +13 -11
  36. package/dist/run/locate.js +20 -13
  37. package/dist/run/paths.js +38 -28
  38. package/dist/run/run.js +4 -3
  39. package/dist/run/stream-trace.d.ts +2 -2
  40. package/dist/run/stream-trace.js +24 -11
  41. package/dist/run/streams.d.ts +18 -3
  42. package/dist/run-study.d.ts +3 -3
  43. package/dist/run-study.js +3 -3
  44. package/dist/study/bundle-estimate.d.ts +21 -3
  45. package/dist/study/bundle-estimate.js +65 -45
  46. package/dist/study/config.d.ts +4 -3
  47. package/dist/study/config.js +8 -5
  48. package/dist/study/parse/actors.d.ts +6 -0
  49. package/dist/study/parse/actors.js +14 -0
  50. package/dist/study/parse/subject-state.js +4 -4
  51. package/dist/study/participant-assignment.js +2 -2
  52. package/dist/study/persona.d.ts +7 -1
  53. package/dist/study/persona.js +13 -5
  54. package/dist/study/plan-base.js +4 -3
  55. package/dist/tui-app.js +23 -23
  56. package/dist/verify/screenshot-reads.js +1 -1
  57. package/docs/architecture/observer.md +24 -7
  58. package/docs/architecture/state-driven-executor.md +4 -3
  59. package/docs/contracts/run-bundle.md +3 -0
  60. package/docs/contracts/study-analysis.md +7 -5
  61. package/docs/decisions/0002-observer-is-one-self-contained-file.md +3 -3
  62. package/package.json +1 -1
@@ -35,7 +35,7 @@ export async function readScreenshot(runPaths, relativePath) {
35
35
  const facts = {
36
36
  state: "read",
37
37
  size: read.bytes.length,
38
- error: screenshotEvidenceError(relativePath, read.bytes),
38
+ error: await screenshotEvidenceError(relativePath, read.bytes),
39
39
  redactedShape: isRedactedFrameShape(read.bytes),
40
40
  };
41
41
  if (read.stamp.ctimeNs <= startedNs - RACY_WINDOW_NS)
@@ -39,10 +39,22 @@ account participant's `executionProfile` without its receipts. `events.ndjson` i
39
39
  contract that live adapters update while a run is active.
40
40
 
41
41
  `observer/index.html` carries both parts: the data slot holds observer-data.json's
42
- content, and `<script id="observer-items" type="application/octet-stream"
43
- data-encoding="gzip">` holds the items and full artifact lists (`humanish.observer-items.v1`, by stream id)
44
- gzip-compressed in base64, which a `file://` page decodes without a fetch. Real
45
- trace items compress about eight times. The page joins the two before it renders
42
+ content, and `<script id="observer-items" type="application/json">` holds the items
43
+ and full artifact lists by stream id (`humanish.observer-items.v2`) as
44
+ `{ schema, runId, streams }`, where `streams` lists one entry for each participant: its
45
+ JSON with its stream id, gzip-compressed in base64, which a `file://` page decodes
46
+ without a fetch. The ids stay inside the compressed entries because verify's scan
47
+ reads the element's plain text. There, an id such as `GITHUB_TOKEN` before a long
48
+ base64 value reads as a credential, and `https://` with a later id shaped like an
49
+ address at an E2B host reads as one E2B URL across the base64 between them. Each participant is packed
50
+ (`src/observer/page-data.ts`) and decoded (`observer/lib/data.ts`) on its own, so no
51
+ string holds two participants' items. A run of 25 participants with
52
+ 30 MiB traces, 786 MB together, past V8's longest string of 536,870,888 characters,
53
+ renders to a 138 MiB page. The page itself is one string, at about 0.18 characters
54
+ for each trace byte, so it passes that limit near 3 GB of traces, and memory may run
55
+ out first; neither has been measured past 25 participants. Real trace items compress
56
+ about eight times. The page
57
+ joins the two before it renders
46
58
  (`joinObserverData` in `src/observer/participant-items.ts`), so every view reads the
47
59
  same data as before. A stream whose screenshot entries moved records how many in
48
60
  `screenshotArtifacts`, and the page renders nothing from items that are another
@@ -83,9 +95,14 @@ public-safe metadata.
83
95
 
84
96
  The browser polls `observer-feed.json` with `no-store` caching: the server's
85
97
  projection of the run as `{ data, items }`, observer-data.json's content and the
86
- items, from one read of the run per poll. While a participant runs, its entry in
87
- `items` carries `live`, a cursor `<position>.<generation>.<items>.<bytes>` naming its
88
- live file (`live/<position>.<generation>.ndjson`) and how far the list goes. The page
98
+ items packed as the page packs them (`observerFeedBody`), from one read of the run
99
+ per poll. The feed compresses each entry at gzip level 1 on the libuv thread pool, one
100
+ participant at a time, so the server answers other requests while it builds a poll.
101
+ Every poll sends every finished participant's items again: on the 25-participant run
102
+ above a poll takes 17 to 20 seconds, past the 15 seconds the page waits, so that page
103
+ never updates and says the server stopped answering. While a participant runs, its entry in `items` carries `live`, a cursor
104
+ `<position>.<generation>.<items>.<bytes>` naming its live file
105
+ (`live/<position>.<generation>.ndjson`) and how far the list goes. The page
89
106
  sends the cursors of its last body back as `?after=<cursor>,<cursor>`, and the server
90
107
  then reads and sends only the items past each one, marking that entry with
91
108
  `liveAfter`, the cursor they follow (`src/observer/feed-cursors.ts`). A cursor for an
@@ -110,9 +110,10 @@ action**, not a fatal error:
110
110
 
111
111
  Public-safety: the notice text carries only the substrate's own stderr (tailed +
112
112
  whitespace-collapsed) and a numeric exit code, and is still run through the loop's
113
- `redactNarration` (known-value scrub + pattern redaction). Raw typed text, secret
114
- values, and machine paths never appear. The action label comes from
115
- `describeCuaAction`, which never includes typed text.
113
+ `redactNarration` (known-value scrub, then pattern redaction of keys as written, base64- or
114
+ percent-encoded, then the known-value scrub again). Raw typed text, secret values, and machine
115
+ paths never appear. The action label comes from `describeCuaAction`, which never includes typed
116
+ text.
116
117
 
117
118
  ## You need a non-vision provider too
118
119
 
@@ -153,6 +153,9 @@ projection is served.
153
153
  observer-data.json is built from the loaded bundle. From 0.124.0 it leaves out each participant's
154
154
  trace items, which stay in the traces, and from this release it is `humanish.observer-data.v3`,
155
155
  which also leaves out each participant's per-request lists (docs/architecture/observer.md).
156
+ The Observer page and `observer-feed.json` carry the items as `humanish.observer-items.v2`, each
157
+ participant's entry gzip-compressed on its own, so `humanish observe` renders a run whose traces
158
+ together pass V8's longest string. It was measured on 25 participants with 30 MiB traces.
156
159
 
157
160
  ## Per-request lists
158
161
 
@@ -191,8 +191,9 @@ from run.json before any trace is read, and the first 80 captures selection may
191
191
  read. Beside the one trace it is reading, analysis holds at most 800 entries for
192
192
  each request and 80 for each participant; their size grows with each trace
193
193
  item's text. A run.json past 16 MiB is refused as `ANALYSIS_SOURCE_TOO_LARGE`, and
194
- a run.json or trace without the fields analysis reads as `ANALYSIS_SOURCE_INVALID`;
195
- each message names the file, says why, and says no request was sent. Analysis
194
+ a run.json or trace without the fields analysis reads, or a run.json with two of a
195
+ participant's run events sharing an id, as `ANALYSIS_SOURCE_INVALID`; each message
196
+ names the file, says why, and says no request was sent. Analysis
196
197
  verifies the run before it reads a trace, so a trace that does not match its
197
198
  index in run.json fails verify and `humanish analyze` reports
198
199
  `ANALYSIS_VERIFY_FAILED`. A trace past 32 MiB leaves the run `local_only`, and
@@ -287,9 +288,10 @@ value inside a bracketed span, such as `[REDACTED_373433393231]`, is found too:
287
288
  humanish writes (`[REDACTED_SECRET]`, `[REDACTED_LOCAL_PATH]`, `[REDACTED_RUNTIME_PATH]`,
288
289
  `[REDACTED_PROMPT_TEXT]`, `[REDACTED_LOBBY_CODE]`) are left as they are. If another reading of
289
290
  the stored field still holds a value (decoded once more, with percent escapes as UTF-8, with
290
- transfer escapes expanded, or with Latin-1 characters read as UTF-8 bytes), as for a value encoded
291
- twice, the whole field becomes `[REDACTED_SECRET]`. A known value in any of
292
- these forms in an ID, enum or reference refuses the response.
291
+ transfer escapes expanded, with Latin-1 characters read as UTF-8 bytes, with HTML references
292
+ left as written, or with only HTML references decoded), as for a value encoded twice, the whole
293
+ field becomes `[REDACTED_SECRET]`. A known value in any of these forms in an ID, enum or
294
+ reference refuses the response.
293
295
 
294
296
  When a reviewer amends a finding, its headline and experience describe the replaced claim.
295
297
  Text output, the Observer and feedback drafts show the reviewer's claim in their place and say the
@@ -13,9 +13,9 @@ exactly those cases.
13
13
  The `observer/` workspace builds with Vite into a single HTML file with fonts inlined and no
14
14
  network references. The root build copies it to `dist/observer-app.html`. `renderObserverHtml`
15
15
  is the one path every surface (observe, observe --all, watch, studies) uses; it injects the run's
16
- `humanish.observer-data.v3` snapshot into that file, with the participants' trace items beside it
17
- gzip-compressed (docs/architecture/observer.md). There is no second renderer and no feature
18
- flag; rolling back means pinning an older package version.
16
+ `humanish.observer-data.v3` snapshot into that file, with each participant's trace items beside
17
+ it, gzip-compressed on their own (docs/architecture/observer.md). There is no second renderer and
18
+ no feature flag; rolling back means pinning an older package version.
19
19
 
20
20
  ## Consequences
21
21
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "humanish",
3
- "version": "0.134.0",
3
+ "version": "0.136.0",
4
4
  "description": "Synthetic user research for apps, CLIs, and agent-facing product flows.",
5
5
  "keywords": [
6
6
  "cli",