humanish 0.97.0 → 0.98.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 (144) hide show
  1. package/AGENTS.md +86 -79
  2. package/CONTRIBUTING.md +7 -2
  3. package/README.md +7 -1
  4. package/dist/actor-contract.d.ts +35 -1
  5. package/dist/actor-contract.js +38 -0
  6. package/dist/actor-contract.js.map +1 -1
  7. package/dist/adapter-extension.js +1 -0
  8. package/dist/adapter-extension.js.map +1 -1
  9. package/dist/browser-control-client.d.ts +14 -0
  10. package/dist/browser-control-client.js +134 -0
  11. package/dist/browser-control-client.js.map +1 -0
  12. package/dist/browser-control-dispatcher.d.ts +14 -0
  13. package/dist/browser-control-dispatcher.js +109 -0
  14. package/dist/browser-control-dispatcher.js.map +1 -0
  15. package/dist/browser-control-protocol.d.ts +371 -0
  16. package/dist/browser-control-protocol.js +155 -0
  17. package/dist/browser-control-protocol.js.map +1 -0
  18. package/dist/browser-control-transport.d.ts +24 -0
  19. package/dist/browser-control-transport.js +156 -0
  20. package/dist/browser-control-transport.js.map +1 -0
  21. package/dist/comms-lease-store.d.ts +1 -0
  22. package/dist/comms-lease-store.js +9 -3
  23. package/dist/comms-lease-store.js.map +1 -1
  24. package/dist/computer-use-actor.d.ts +2 -2
  25. package/dist/computer-use-actor.js +6 -1
  26. package/dist/computer-use-actor.js.map +1 -1
  27. package/dist/computer-use.d.ts +23 -1
  28. package/dist/computer-use.js +253 -70
  29. package/dist/computer-use.js.map +1 -1
  30. package/dist/cua-actor-lab.d.ts +6 -1
  31. package/dist/cua-actor-lab.js +55 -15
  32. package/dist/cua-actor-lab.js.map +1 -1
  33. package/dist/cua-executor-error.d.ts +31 -0
  34. package/dist/cua-executor-error.js +48 -0
  35. package/dist/cua-executor-error.js.map +1 -0
  36. package/dist/cua-provider-error.d.ts +12 -0
  37. package/dist/cua-provider-error.js +28 -0
  38. package/dist/cua-provider-error.js.map +1 -0
  39. package/dist/desktop-session.js +3 -1
  40. package/dist/desktop-session.js.map +1 -1
  41. package/dist/doctor-lab.d.ts +2 -0
  42. package/dist/doctor-lab.js +25 -7
  43. package/dist/doctor-lab.js.map +1 -1
  44. package/dist/e2b-desktop-executor.d.ts +1 -24
  45. package/dist/e2b-desktop-executor.js +2 -127
  46. package/dist/e2b-desktop-executor.js.map +1 -1
  47. package/dist/e2b-terminal-lab.js +1 -0
  48. package/dist/e2b-terminal-lab.js.map +1 -1
  49. package/dist/frame-signature.d.ts +24 -0
  50. package/dist/frame-signature.js +128 -0
  51. package/dist/frame-signature.js.map +1 -0
  52. package/dist/guest-bootstrap.d.ts +43 -0
  53. package/dist/guest-bootstrap.js +240 -0
  54. package/dist/guest-bootstrap.js.map +1 -0
  55. package/dist/guest-browser-tools.d.ts +8 -0
  56. package/dist/guest-browser-tools.js +66 -0
  57. package/dist/guest-browser-tools.js.map +1 -0
  58. package/dist/guest-chromium-text.d.ts +27 -0
  59. package/dist/guest-chromium-text.js +281 -0
  60. package/dist/guest-chromium-text.js.map +1 -0
  61. package/dist/guest-desktop-executor.d.ts +22 -0
  62. package/dist/guest-desktop-executor.js +177 -0
  63. package/dist/guest-desktop-executor.js.map +1 -0
  64. package/dist/guest-desktop-native.d.ts +14 -0
  65. package/dist/guest-desktop-native.js +131 -0
  66. package/dist/guest-desktop-native.js.map +1 -0
  67. package/dist/guest-runtime-desktop.d.ts +35 -0
  68. package/dist/guest-runtime-desktop.js +231 -0
  69. package/dist/guest-runtime-desktop.js.map +1 -0
  70. package/dist/guest-runtime-main.d.ts +1 -0
  71. package/dist/guest-runtime-main.js +31 -0
  72. package/dist/guest-runtime-main.js.map +1 -0
  73. package/dist/guest-runtime-revision.d.ts +1 -0
  74. package/dist/guest-runtime-revision.js +3 -0
  75. package/dist/guest-runtime-revision.js.map +1 -0
  76. package/dist/guest-runtime.d.ts +25 -0
  77. package/dist/guest-runtime.js +96 -0
  78. package/dist/guest-runtime.js.map +1 -0
  79. package/dist/lab-config.js +10 -3
  80. package/dist/lab-config.js.map +1 -1
  81. package/dist/lab-engine.js +6 -0
  82. package/dist/lab-engine.js.map +1 -1
  83. package/dist/lab-summary.d.ts +2 -0
  84. package/dist/lab-summary.js +5 -0
  85. package/dist/lab-summary.js.map +1 -1
  86. package/dist/local-agent-cli.js +1 -1
  87. package/dist/local-agent-cli.js.map +1 -1
  88. package/dist/local-firecracker-desktop.d.ts +13 -0
  89. package/dist/local-firecracker-desktop.js +150 -0
  90. package/dist/local-firecracker-desktop.js.map +1 -0
  91. package/dist/local-firecracker-study.d.ts +9 -0
  92. package/dist/local-firecracker-study.js +93 -0
  93. package/dist/local-firecracker-study.js.map +1 -0
  94. package/dist/local-runtime-config.d.ts +6 -0
  95. package/dist/local-runtime-config.js +56 -0
  96. package/dist/local-runtime-config.js.map +1 -0
  97. package/dist/local-runtime-release.d.ts +3 -0
  98. package/dist/local-runtime-release.js +8 -0
  99. package/dist/local-runtime-release.js.map +1 -0
  100. package/dist/local-runtime.d.ts +25 -0
  101. package/dist/local-runtime.js +113 -0
  102. package/dist/local-runtime.js.map +1 -0
  103. package/dist/observer-app.html +4 -4
  104. package/dist/pricing.d.ts +22 -1
  105. package/dist/pricing.js +22 -0
  106. package/dist/pricing.js.map +1 -1
  107. package/dist/program.js +26 -0
  108. package/dist/program.js.map +1 -1
  109. package/dist/restricted-codex-participant-policy.d.ts +39 -0
  110. package/dist/restricted-codex-participant-policy.js +69 -0
  111. package/dist/restricted-codex-participant-policy.js.map +1 -0
  112. package/dist/restricted-codex-participant-run.d.ts +20 -0
  113. package/dist/restricted-codex-participant-run.js +78 -0
  114. package/dist/restricted-codex-participant-run.js.map +1 -0
  115. package/dist/restricted-codex-participant.d.ts +14 -0
  116. package/dist/restricted-codex-participant.js +178 -0
  117. package/dist/restricted-codex-participant.js.map +1 -0
  118. package/dist/restricted-codex-session.d.ts +2 -2
  119. package/dist/restricted-codex-session.js +11 -17
  120. package/dist/restricted-codex-session.js.map +1 -1
  121. package/dist/run-detail.js +4 -2
  122. package/dist/run-detail.js.map +1 -1
  123. package/dist/run.d.ts +12 -5
  124. package/dist/run.js +17 -1
  125. package/dist/run.js.map +1 -1
  126. package/dist/shared-world-lab.js +2 -2
  127. package/dist/shared-world-lab.js.map +1 -1
  128. package/dist/study-analysis-job.d.ts +2 -2
  129. package/dist/study-analysis-validation.d.ts +14 -14
  130. package/dist/study-costs.js +6 -0
  131. package/dist/study-costs.js.map +1 -1
  132. package/dist/tui-app.js +37 -37
  133. package/docs/architecture/browser-control.md +117 -0
  134. package/docs/architecture/guest-desktop.md +87 -0
  135. package/docs/architecture/local-browser-runtime.md +100 -0
  136. package/docs/architecture/restricted-codex-analysis.md +4 -2
  137. package/docs/architecture/runtime-broker-core.md +30 -0
  138. package/docs/contracts/schemas.md +1 -1
  139. package/docs/goals/current.md +24 -8
  140. package/docs/product/open-source-install-experience.md +7 -0
  141. package/docs/ramp/README.md +24 -13
  142. package/docs/release/0.98.0-local-browser-studies.md +31 -0
  143. package/package.json +4 -2
  144. package/skills/humanish/SKILL.md +23 -3
@@ -0,0 +1,117 @@
1
+ # Internal browser control
2
+
3
+ The browser-control client implements the existing `CuaExecutor` over an
4
+ already-owned Node `Duplex`. The matching dispatcher invokes an owner-supplied
5
+ executor. This is a preparatory internal boundary, not a managed-local runtime,
6
+ CLI mode, browser launcher, VM isolation claim, or installer.
7
+
8
+ ## Ownership and admission
9
+
10
+ `createBrowserControlClient({ transport, identity, requestTimeoutMs? })` returns
11
+ `{ executor, ready(), close() }`. `ready()` performs a lazy handshake; the first
12
+ observation/action also performs it when needed. The owner closes the client
13
+ when its session ends. The client never discovers endpoints, opens sockets,
14
+ spawns processes, reconnects, retries, or replays a mutation.
15
+
16
+ `attachBrowserControlDispatcher({ transport, identity, executor, isAuthorized,
17
+ authoritySignal })` returns `{ close() }`. The authority signal is required.
18
+ The owner establishes the channel and authority independently; the identity's
19
+ `generation`, `challenge`, and `runtimeRevision` only check consistency.
20
+ Each is a bounded ASCII token. A matching string does not prove a lease or
21
+ authenticate executable bytes.
22
+
23
+ The dispatcher checks current authorization immediately before invoking browser
24
+ I/O. It passes a signal combining owner revocation, channel loss, and its request
25
+ deadline to `execute`. The physical driver must check that signal immediately
26
+ before **each actual input**, including after asynchronous preparation. Closing
27
+ the channel cannot roll back already-dispatched input or prove the browser has
28
+ stopped. The physical owner remains responsible for resource cleanup and the
29
+ independent watchdog. Observation has no cancellation parameter in the existing
30
+ executor interface; late observations are discarded after closure.
31
+
32
+ One operation may be pending, including handshake and observation. Concurrent
33
+ calls are rejected rather than queued. The client marks its executor with
34
+ `stallRecovery: 'fail_closed'`, so an earlier computer-use loop deadline cannot
35
+ trigger the legacy observation retry or idle-action skip behavior.
36
+
37
+ ## Wire contract
38
+
39
+ Each frame is a four-byte unsigned big-endian length followed by strict UTF-8
40
+ JSON. The parser allocates its bounded payload only after validating the length;
41
+ it handles fragmented and coalesced input without repeatedly concatenating it.
42
+ A partially received frame has a nonrenewing 35-second assembly deadline.
43
+
44
+ Version 1 has only `HELLO`, `OBSERVE`, and `EXECUTE`. Both directions carry the
45
+ version, operation, identity, strictly increasing sequence and `request-N`
46
+ correlation ID. Execute additionally carries the distinct `action-N` ID.
47
+ Unknown fields, methods, versions, stale identity, duplicates, missing or wrong
48
+ correlation, malformed UTF-8/JSON and oversized frames close admission. There is
49
+ no generic CDP, command, file, navigation-management, or runtime-management method.
50
+ Initial target navigation remains an adapter-owned operation.
51
+
52
+ Replies acknowledge completion or contain a finite `CuaExecutorError` code and
53
+ `not_dispatched` / `outcome_uncertain` disposition. They never include raw
54
+ exception prose, typed text, page URLs, or browser errors in their error fields.
55
+ A generic driver exception after invocation is uncertain; only a genuine typed
56
+ driver declaration can attest that input was never dispatched.
57
+
58
+ The client resolves execute only after a matching completion acknowledgement and
59
+ its write callback. Cancellation, deadline, explicit close, or channel loss after
60
+ a possible write is uncertain and terminal. A later acknowledgement cannot reopen
61
+ that channel. Pre-aborted signals and locally rejected input cause no write.
62
+ Cancellation during the preliminary handshake remains a pre-dispatch action
63
+ failure. No exactly-once or rollback guarantee is implied by sequence IDs.
64
+
65
+ ## Finite bounds
66
+
67
+ | Input | Version 1 bound |
68
+ | --- | --- |
69
+ | Framed JSON | 12 MiB |
70
+ | PNG bytes | 8 MiB |
71
+ | Image dimensions | 4096 per side, at most 16,000,000 pixels |
72
+ | Typed text and each observed string | 64 KiB UTF-8 |
73
+ | Key chord | 16 keys, 64 characters per key |
74
+ | Drag | 1–1024 points |
75
+ | Coordinates, deltas, scroll position | Finite, within ±1,000,000; fractions preserved |
76
+ | Wait | 0–30 seconds, fractions preserved |
77
+ | Client request | 35 seconds by default; caller may choose 1–60 seconds |
78
+ | Dispatcher request | 35 seconds including acknowledgement write |
79
+
80
+ Observation requires a PNG and state signature. It may include bounded URL,
81
+ title, text, and fractional scroll position; those remain runtime-only under the
82
+ existing loop contract. Arbitrary `appState` is refused because v1 has no closed
83
+ schema for it. The protocol does not truncate strings, round coordinates, or
84
+ silently drop unsupported state.
85
+
86
+ PNG admission checks signature, IHDR before decoder allocation, chunk framing,
87
+ IDAT/IEND presence, no trailing bytes, CRCs and full decode. Version 1 admits
88
+ 8-bit, noninterlaced browser PNGs. Interlaced and 16-bit images are rejected:
89
+ the current decoder has an unbounded interlaced inflation branch, so admitting
90
+ those would require a separately bounded decoder. Image dimensions and the
91
+ pixel product are checked before decoding, independently of compressed size.
92
+
93
+ ## Verification boundary
94
+
95
+ `tests/browser-control-protocol.test.ts`, `browser-control-transport.test.ts`
96
+ and `browser-control-client.test.ts` exercise production schemas and framing,
97
+ all action kinds, image limits, correlation, malformed input, revocation,
98
+ concurrency, lost acknowledgements, backpressure and cancellation. These use
99
+ synthetic PNGs and inert paired byte streams, with no network, model or VM calls.
100
+ They establish the protocol contract, not a real-browser or managed-runtime
101
+ claim. The separate owned-child/browser conformance proof must retain real
102
+ pixels and independently observed fixture mutations through the same modules.
103
+
104
+ From a source checkout, run `pnpm build && pnpm browser-control:proof` with a
105
+ Chromium installation that supports its sandbox. The proof uses a fresh profile,
106
+ a private local socket, a separate controller process and a synthetic loopback
107
+ page. It checks a normal save, a lost acknowledgement after one save, and owner
108
+ revocation/cancellation during input preparation. Screenshots, loop traces,
109
+ independent save counts and exact child/profile cleanup results are retained in
110
+ `.humanish/browser-control-proof/`. Failed cleanup remains unconfirmed and keeps
111
+ the private recovery directory; killing a controller alone does not prove its
112
+ browser stopped.
113
+
114
+ This is deterministic `runComputerUseLoop` conformance, not model perception,
115
+ the study producer, a ready-desktop adapter, a durable local-study bundle or
116
+ Observer qualification. Page request interception does not establish process-wide
117
+ egress isolation. Those integration and runtime boundaries remain separate gates.
@@ -0,0 +1,87 @@
1
+ # Headed browser guest components
2
+
3
+ These internal components implement native input and full-desktop captures for a
4
+ maintained browser-only guest. They do not enable a public local-runtime mode.
5
+ The VM owner, control transport, app network policy, installed setup and complete
6
+ study journey require separate qualification.
7
+
8
+ The driver uses the existing `CuaExecutor` contract behind
9
+ [browser control](browser-control.md). Coordinates refer to the complete Xvfb
10
+ frame, including the browser's address bar. Invalid points are refused instead
11
+ of moved to a different target. Captures must match the admitted geometry and
12
+ pass the bounded PNG validator. Browser URL/title/DOM metadata is absent in this
13
+ component; callers must not invent it from the screenshot or infer task matches.
14
+ Progress detection uses the same coarse frame signature as the hosted desktop.
15
+
16
+ ## Input boundary
17
+
18
+ The actor receives the existing finite action union. Native tool paths, display,
19
+ Xauthority and guest temporary directory come from the owner. Key names map to a
20
+ closed list before reaching xdotool, whose own command syntax must never receive
21
+ arbitrary participant strings. A native wheel step is not an exact pixel-scroll
22
+ promise; one action permits at most 100 wheel steps. The entire drag is checked
23
+ before its first input.
24
+
25
+ Each input checks the current authority after asynchronous preparation. A
26
+ partial or unacknowledged input closes the executor; it is never automatically
27
+ replayed. Releasing a held button can itself click or drop, so revocation does
28
+ not inject a cleanup mouseup into the app. The owner must stop the private
29
+ browser/display. A stopped helper alone does not establish desktop or VM absence.
30
+
31
+ Text in a focused, editable top-level document uses Chromium's fixed
32
+ `Input.insertText` command over the owner's private Playwright pipe. The actor
33
+ receives no CDP, JavaScript, selector, or debugging endpoint. A separate isolated
34
+ world checks actual document focus and binds preparation to the editable element;
35
+ page changes, additional tabs, dialogs, iframe focus and ambiguous focus are
36
+ refused. The owner acquires the one page and native window before untrusted
37
+ navigation. The driver never chooses another tab or brings one to the front.
38
+ Focus can change between protocol messages; this is not atomic element-targeted
39
+ input or a general multi-window driver.
40
+
41
+ Address-bar text is admitted only after an explicit Ctrl+L action, uses printable
42
+ ASCII, and repeats that chord after checking the owned active window. Unicode
43
+ or control characters in browser chrome are refused. Clicking an arbitrary
44
+ chrome field does not authorize text entry there. Content insertion is browser
45
+ text/IME insertion, not a stream of physical key presses; keyboard shortcuts
46
+ remain native. There is no alternate-route fallback after a failed insertion.
47
+
48
+ Direct native Unicode typing and a one-transfer clipboard helper were rejected
49
+ by exact Chromium field readback. Successful process or clipboard transfer
50
+ acknowledgements did not establish successful application input. The supported
51
+ text paths likewise need application readback to establish task outcomes.
52
+
53
+ Native children use fixed paths and a minimal explicit environment. Operator
54
+ credentials and inherited Xauthority are not forwarded. Native address-bar text travels over the
55
+ helper's stdin; web text travels over the private browser pipe, never a shell. Helpers have bounded deadlines and output;
56
+ raw diagnostic text is never returned as an executor error. Only an acquired,
57
+ still-live child handle authorizes termination. If capture-helper exit cannot
58
+ be confirmed, its private files stay for runtime-owner reclamation.
59
+
60
+ ## Build and proof
61
+
62
+ The source-only [guest recipe](https://github.com/danielgwilson/humanish/blob/main/runtime/browser-guest/README.md) builds a
63
+ pinned Debian/Chromium/Xvfb development base with package/source references and
64
+ notices. It is not a redistributed release image or a VM qualification receipt.
65
+ A native ARM64 build and its exact browser behavior are separate from amd64.
66
+
67
+ After building the development image and JavaScript, run the scoped native proof
68
+ with its exact local image ID:
69
+
70
+ ```sh
71
+ HUMANISH_GUEST_IMAGE=sha256:<image-id> pnpm guest-desktop:proof
72
+ ```
73
+
74
+ This launches an ordinary disposable container with no network, host mounts or
75
+ host devices. Chromium retains its sandbox. The harness downloads and verifies
76
+ the hash-pinned upstream Playwright Docker seccomp profile, which permits the
77
+ user namespaces needed by that sandbox. This container configuration is a test
78
+ environment, not the proposed Firecracker boundary. The harness retains failed
79
+ attempts, full-frame captures, synthetic app readback and exact-container cleanup
80
+ under ignored `.humanish/guest-desktop-proof/`.
81
+
82
+ The proof covers visible browser chrome, address-bar navigation, Unicode and
83
+ rapid/large/stalled-renderer text insertion, page/focus rejection, pointer and
84
+ keyboard input, native scrolling and cancellation. CI reruns this proof for
85
+ changes to the guest driver, image recipe, protocol or dependency lockfile. Its deterministic fixture is not a model participant,
86
+ a run bundle, a host network policy, an independent watchdog or a Linux/Mac
87
+ installed study. Those remain separate gates before local runtime support.
@@ -0,0 +1,100 @@
1
+ # Local browser studies
2
+
3
+ Linux x64 users can run isolated Firecracker browser participants from the
4
+ installed CLI or TUI. Docker manages their containers and private state volumes;
5
+ the normal study runner supplies scheduling, recordings, Observer and findings.
6
+ No separate host service is installed.
7
+
8
+ ## Start a study
9
+
10
+ Prerequisites: a local, rootful Docker Engine; Linux KVM (`/dev/kvm`) and TUN
11
+ (`/dev/net/tun`); and a signed-in, supported Codex CLI. See
12
+ [Codex account setup](restricted-codex-analysis.md) for the qualified version
13
+ and account restrictions. Docker access is an administrative capability.
14
+ Humanish does not install Docker or change host permissions.
15
+
16
+ Start your app on loopback, then save a lab such as
17
+ `.humanish/labs/local-browser.yaml`:
18
+
19
+ ```yaml
20
+ schema: humanish.lab.v2
21
+ id: local-browser
22
+ title: Review the note editor
23
+ subject:
24
+ source: app-url
25
+ appUrl: http://127.0.0.1:3000
26
+ actors:
27
+ - type: local-agent
28
+ localAgent: codex
29
+ count: 2
30
+ mission: Create a note and explain anything confusing about saving it.
31
+ scenario:
32
+ mode: live
33
+ execution:
34
+ target: local
35
+ concurrency: 2
36
+ timeoutMs: 120000
37
+ ```
38
+
39
+ ```sh
40
+ npx humanish init --yes
41
+ npx humanish runtime status --json
42
+ npx humanish doctor --lab .humanish/labs/local-browser.yaml --json
43
+ npx humanish lab run .humanish/labs/local-browser.yaml
44
+ ```
45
+
46
+ The first live run downloads the pinned runtime archive (about 569 MiB), verifies
47
+ its exact size and SHA-256, and loads it into Docker. Later runs reuse the image.
48
+ `humanish runtime setup` prepares it in advance. Status, doctor and dry-run never
49
+ download an image or launch a participant. Preparation does not consume the
50
+ participant's task-time budget. The TUI lists the same lab and runtime readiness;
51
+ starting it uses the same preparation and execution path.
52
+
53
+ This configuration needs neither an E2B key nor an OpenAI API key. Participants
54
+ and the separate post-run analyst use Codex account quota and **remote model
55
+ inference**. It is not an offline model. The restricted participant has no host
56
+ shell, checkout mount or credential files. Account dollar cost and output-token
57
+ ceilings are unknown; numeric dollar/token caps are rejected. Set
58
+ `review.analysis: false` to skip analysis.
59
+
60
+ For API billing and its supported caps, use `type: openai-computer-use`, remove
61
+ `localAgent`, and provide `OPENAI_API_KEY`. Its analysis retains the existing API
62
+ default. Neither path silently falls back to another provider or hosted desktop.
63
+ Existing labs without `execution.target: local` retain their previous behavior.
64
+
65
+ ## Current limits
66
+
67
+ - Linux x64 only. Mac/Lima setup is a separate follow-up.
68
+ - A local Docker Engine; remote contexts, rootless Docker and Docker Desktop
69
+ virtual machines are not supported by this host adapter.
70
+ - Loopback HTTP(S) app URLs on explicit ports above 1023. Each participant can
71
+ reach its selected app port, plus public destinations over ordinary TCP/UDP.
72
+ Other private host/LAN destinations and cloud metadata are blocked.
73
+ - Chromium at 960×720, 2 vCPUs and 2 GiB guest RAM per participant. Docker's
74
+ enclosing memory limit is 3 GiB. Start with a small concurrency for your host;
75
+ these allocations are not a promise of measured peak memory or capacity.
76
+ - Browser-only. Inbox and camera/microphone declarations are rejected until
77
+ integrated. TAP/NAT networking preserves the path to optional media.
78
+ - A 20-minute default and maximum participant session budget, within the runtime
79
+ image's 30-minute process lifetime. A shorter `execution.timeoutMs` is supported.
80
+ - Codex participants currently use `gpt-6-astra` at low effort. Hosted templates,
81
+ device presets and hosted sandbox timeouts do not apply.
82
+
83
+ Normal close removes the owned container and its private state volume. If the
84
+ controller dies, the disconnected guest reboots, Firecracker exits and Docker
85
+ removes both. A small host socket directory can remain after abrupt death.
86
+ Run evidence remains in `.humanish/` under the normal local capture and sharing
87
+ rules. An unconfirmed release is reported as such.
88
+
89
+ ## Runtime maintenance
90
+
91
+ The npm build pins a release URL, byte count, SHA-256 and immutable Docker image
92
+ ID in `src/local-runtime-release.ts`. It has no moving `latest` image dependency.
93
+ Runtime releases include source archives and notices separately; study users do
94
+ not download those archives. Updating a runtime requires a reviewed catalog
95
+ change and a new CLI release.
96
+
97
+ Source builders can use the
98
+ [maintained recipes](../../runtime/local-firecracker/README.md) and set
99
+ `HUMANISH_LOCAL_RUNTIME_IMAGE` to an already-built compatible local image. An
100
+ invalid override fails; it does not cause an implicit registry pull.
@@ -34,8 +34,10 @@ host RPCs and asynchronous question messages before accepting any report. The
34
34
  actual notification/denial captures and provenance are in
35
35
  [`tests/fixtures/restricted-codex`](https://github.com/danielgwilson/humanish/blob/46330116726f74080fa18947c36da4fb4b333805/tests/fixtures/restricted-codex/README.md).
36
36
 
37
- There is one active analyst/readiness session per Humanish process, across all
38
- provider factories. One fresh thread receives one turn. Evidence is not silently
37
+ Each request owns a separate child process, temporary home and fresh thread;
38
+ participant, analyst and readiness requests may run concurrently. An unresolved
39
+ child process blocks new requests until its exit is confirmed. Each thread receives
40
+ one turn. Evidence is not silently
39
41
  downselected: at most 128 images, 20 MiB decoded image data, and 32 MiB serialized
40
42
  request data are admitted. Generated report text is limited to 2 MiB. Raw input
41
43
  notifications echo image data URLs, so their frame budget is the larger of 2 MiB
@@ -0,0 +1,30 @@
1
+ # Runtime broker authority core
2
+
3
+ The source-only [broker core](https://github.com/danielgwilson/humanish/blob/main/runtime/broker/README.md)
4
+ defines bounded requests and lease decisions for a future Linux runtime owner.
5
+ It is not an installed service, resource controller, or public runtime mode.
6
+
7
+ Requests cannot supply host paths, service names, commands, user identities,
8
+ resource limits or cleanup claims. The future transport obtains the peer UID
9
+ from the operating system and checks it against owner policy. A separate
10
+ generation capability authorizes each study; default diagnostics and serialized
11
+ ledgers omit the raw capability. Repeating an acquisition or allocation attempt
12
+ does not mint a second resource.
13
+
14
+ The model reserves capacity through uncertain creation and cleanup. Expiry,
15
+ revocation, detected sleep and host-clock discontinuity cannot be undone by a
16
+ late renewal. A saved launch plan is not dispatch authority: the owner must
17
+ revalidate it immediately before starting a resource. Only a separate owner
18
+ attestation that creation has settled and the acquired resources are absent can
19
+ free a reservation. Recovery reads the ledger for reconciliation, never to resume
20
+ a study or adopt resources by their names.
21
+
22
+ The owner must persist intent before consuming effects, advance trusted time
23
+ independently of requests, and bind every resource to actual acquired OS
24
+ identities. The pure model does none of those OS operations. Its tests establish
25
+ protocol and state transitions; they do not establish peer authentication,
26
+ durable writes, process containment, watchdog timing, sleep detection or cleanup.
27
+
28
+ Installation, root-owned storage, authenticated sockets, service supervision,
29
+ artifact verification and VM/network control require separate implementation
30
+ and privileged qualification. The existing npm execution routes are unchanged.
@@ -3,7 +3,7 @@
3
3
  Date: 2026-06-02 (current-state note updated 2026-07-14)
4
4
 
5
5
  Status: reference map for the major contracts shipped through source version
6
- `0.97.0`; it is not an exhaustive inventory of command/result envelopes. Exported types,
6
+ `0.98.0`; it is not an exhaustive inventory of command/result envelopes. Exported types,
7
7
  schema constants, parsers, and validators in `src/` are authoritative. Rows
8
8
  marked "reserved" name layering intent only — no code emits or validates them
9
9
  yet. Do not emit a reserved schema.
@@ -1,9 +1,9 @@
1
1
  # Current Goals
2
2
 
3
- Status date: 2026-09-23. Release baseline: `0.97.0`.
3
+ Status date: 2026-09-24. Release baseline: `0.98.0`.
4
4
 
5
5
  This page guides work on current merged source. Published behavior is described
6
- in the [release notes](../release/0.97.0-codex-account-analysis.md).
6
+ in the [release notes](../release/0.98.0-local-browser-studies.md).
7
7
  The [September 9 history](https://github.com/danielgwilson/humanish/blob/main/docs/goals/current-history-2026-09-09.md)
8
8
  preserves the former status log; its queues do not supersede this page.
9
9
 
@@ -88,7 +88,7 @@ requires decision-equivalent retained evidence and a real deletion branch.
88
88
  No first-party deletion branch has met that gate. Public demonstrations do not
89
89
  substitute for it.
90
90
 
91
- ## Current Program Truth (source `0.97.0`)
91
+ ## Current Program Truth (source `0.98.0`)
92
92
 
93
93
  | Surface | Available in merged source | Remaining boundary |
94
94
  | --- | --- | --- |
@@ -107,13 +107,24 @@ substitute for it.
107
107
  Use the [task support matrix](../architecture/task-protocol-support.md),
108
108
  [actor registry](https://github.com/danielgwilson/humanish/blob/main/src/actor-registry.ts)
109
109
  and [CLI reference](https://humanish.dev/docs/cli) when choosing a concrete path.
110
- Source behavior and required tests outrank stale status prose.
110
+ Source and tests establish observed behavior. Resolve conflicts with requirements
111
+ explicitly; neither stale status prose nor a passing test makes a bug correct.
111
112
 
112
113
  The library-assisted `local-app` route now includes a
113
114
  [runnable npm example](../architecture/examples/state-driven-local-app/README.md).
114
115
  Its deterministic provider demonstrates the integration with a real loopback
115
116
  app; it does not establish persona effectiveness or independent adoption.
116
117
 
118
+ The [local browser runtime](../architecture/local-browser-runtime.md)
119
+ runs isolated Linux browser participants through the same scheduler, recordings
120
+ and automatic analysis as hosted studies. It uses Docker-owned resources and
121
+ ordinary TAP/NAT networking. Continue managed-local work from this complete study
122
+ path; the earlier offline owner/service qualification experiments are historical
123
+ fixtures, not an installation architecture or a prerequisite queue. Explicit
124
+ Linux local labs now use the installed CLI/TUI, with a verified runtime download
125
+ before the first live run. Mac support, inbox integration and optional media
126
+ remain unfinished. Existing hosted labs retain their behavior.
127
+
117
128
  ## Gates And Deferred Work
118
129
 
119
130
  - Live OSS meta-lab execution remains disabled until repository-derived
@@ -135,10 +146,12 @@ app; it does not establish persona effectiveness or independent adoption.
135
146
  Follow [AGENTS.md](../../AGENTS.md), the [invariants](../principles/invariants-and-defaults.md)
136
147
  and the [public-readiness standard](../release/public-readiness-standard.md).
137
148
 
138
- - Keep `main` clean and work on scoped branches/worktrees. Substantial work
139
- needs an issue with scope, authority, required proof and stop conditions.
149
+ - Keep `main` clean and work on scoped branches/worktrees. Keep the task's scope,
150
+ authority, relevant checks and material failure boundaries in its issue, PR or
151
+ current handoff; do not create a separate packet for routine work.
140
152
  - Existing explicit shipping authority governs implementation and merge;
141
- otherwise issue readiness does not create authority by itself.
153
+ otherwise issue readiness does not create authority by itself. Machine-readiness
154
+ fields gate automated queue pickup, not directly assigned interactive work.
142
155
  - Never commit secrets, private transcripts/screenshots, customer data or
143
156
  private project context. Keep generated proof in ignored `.humanish/` and
144
157
  retain needed evidence before removing a worktree.
@@ -153,7 +166,10 @@ and the [public-readiness standard](../release/public-readiness-standard.md).
153
166
 
154
167
  ## Proof Before Shipping
155
168
 
156
- From a clean contributor worktree:
169
+ Use the [verification guidance](../../AGENTS.md#verification): check the changed
170
+ behavior and material risks, then stop unless new evidence warrants more work.
171
+ Required CI remains the merge gate. For a release, run the full release gates
172
+ from a clean contributor worktree:
157
173
 
158
174
  ```bash
159
175
  pnpm install --frozen-lockfile
@@ -235,3 +235,10 @@ them should install `@e2b/desktop` explicitly instead of receiving that
235
235
  substrate as part of the default Humanish package install. When a GitHub token is
236
236
  present, repo labels are redacted in durable artifacts by default; live stream
237
237
  auth URLs are used only by the attached watch server and are not persisted.
238
+
239
+ An explicitly selected [local browser lab](../architecture/local-browser-runtime.md)
240
+ can instead use Linux x64, Docker/KVM and an existing Codex ChatGPT login for
241
+ participants and findings. The installed CLI prepares its pinned image before
242
+ the first live run. It does not install host prerequisites, and Mac, inbox and
243
+ media integration remain separate follow-ups. Existing hosted lab configuration
244
+ is preserved.
@@ -2,7 +2,7 @@
2
2
 
3
3
  Status: public-safe contributor and agent ramp.
4
4
 
5
- Package/source version in this tree: `0.97.0` (2026-09-23). The Observer is phone-usable as a stated requirement (observer/AGENTS.md); interactive primitives start from Base UI. The Observer renderer is the observer/ workspace artifact only; the legacy string-concat renderer was deleted at cutover (#426), and rollback is a version pin to 0.42.0. The containment boundary introduced in
5
+ Package/source version in this tree: `0.98.0` (2026-09-24). The Observer is phone-usable as a stated requirement (observer/AGENTS.md); interactive primitives start from Base UI. The Observer renderer is the observer/ workspace artifact only; the legacy string-concat renderer was deleted at cutover (#426), and rollback is a version pin to 0.42.0. The containment boundary introduced in
6
6
  `0.15.1` remains in force: managed run and output paths bind to validated
7
7
  physical filesystem identities, and stored provider IDs are evidence, not
8
8
  cleanup authority. The bundled OSS meta-lab is dry-run only until
@@ -14,19 +14,26 @@ context.
14
14
 
15
15
  ## First Read
16
16
 
17
- Read these in order:
17
+ Start with three things:
18
18
 
19
- 1. [`AGENTS.md`](../../AGENTS.md) for public boundary and engineering rules.
20
- 2. [`docs/principles/invariants-and-defaults.md`](../principles/invariants-and-defaults.md) — which rules are invariants and which are overridable defaults, each with the reason it exists and the check that enforces it. (The enforcement is what makes a rule real here — when a doc sentence and a test disagree, trust the test and say so.)
21
- 3. [`README.md`](../../README.md) for install, commands, and package shape.
22
- 4. [`docs/goals/current.md`](../goals/current.md) for the active product goal.
23
- 5. [`docs/goals/proof-roadmap/goal.md`](https://github.com/danielgwilson/humanish/blob/main/docs/goals/proof-roadmap/goal.md) for the ratified proof architecture (repo-only; not shipped in the npm package, hence the absolute link).
24
- 6. [`docs/product/open-source-install-experience.md`](../product/open-source-install-experience.md) for first-run UX.
25
- 7. [`docs/roadmap/world-class-open-source-v0.md`](../roadmap/world-class-open-source-v0.md) for staged delivery history (historical; see its status banner).
26
- 8. [`docs/architecture/observer.md`](../architecture/observer.md) for Observer architecture.
27
- 9. [`docs/contracts/run-bundle.md`](../contracts/run-bundle.md) and [`docs/contracts/policy.md`](../contracts/policy.md) for proof contracts.
28
- 10. [`docs/release/public-readiness-standard.md`](../release/public-readiness-standard.md) before deciding what must be scrubbed.
29
- 11. [`docs/release/open-source-readiness.md`](../release/open-source-readiness.md) before touching public packaging or repository visibility.
19
+ 1. [`AGENTS.md`](../../AGENTS.md) for engineering judgment and public boundaries.
20
+ 2. The current task and [`docs/goals/current.md`](../goals/current.md) for current
21
+ product status. Explicit task direction takes precedence over historical queues.
22
+ 3. Instructions in the component being changed, then its relevant contracts.
23
+
24
+ Use the references below as needed. Historical plans are context, not a backlog
25
+ to resume automatically. Keep one concise current task handoff with the requested
26
+ outcome, demonstrated behavior, next complete result, constraints and rejected or
27
+ deferred approaches; link evidence rather than repeating its chronology.
28
+
29
+ | When working on | Reference |
30
+ | --- | --- |
31
+ | Install, commands or first-run UX | [`README.md`](../../README.md), [install experience](../product/open-source-install-experience.md) |
32
+ | Security, evidence handling or defaults | [Invariants and defaults](../principles/invariants-and-defaults.md) |
33
+ | Observer | [Observer architecture](../architecture/observer.md) and its component instructions |
34
+ | Bundle formats or policy | [Run bundle](../contracts/run-bundle.md), [policy](../contracts/policy.md) |
35
+ | Public artifacts or packaging | [Public-readiness standard](../release/public-readiness-standard.md), [release procedure](../release/open-source-readiness.md) |
36
+ | Proof architecture or historical decisions | [Proof roadmap](https://github.com/danielgwilson/humanish/blob/main/docs/goals/proof-roadmap/goal.md), [historical delivery roadmap](../roadmap/world-class-open-source-v0.md) |
30
37
 
31
38
  ## Mental Model
32
39
 
@@ -47,6 +54,10 @@ If a change does not improve one of those loops, it probably belongs elsewhere.
47
54
 
48
55
  ## Current State
49
56
 
57
+ The [0.98.0 release note](../release/0.98.0-local-browser-studies.md) describes
58
+ installed Linux browser studies with managed runtime images, Codex account
59
+ participants and automatic analysis, and shared CLI/TUI setup checks.
60
+
50
61
  The [0.97.0 release note](../release/0.97.0-codex-account-analysis.md) describes
51
62
  explicit Codex account analysis on a qualified Linux CLI/login profile, with
52
63
  separate analyst authority, evidence-linked reports and unknown-dollar accounting.
@@ -0,0 +1,31 @@
1
+ # 0.98.0 — Local browser studies on Linux
2
+
3
+ Explicit local browser labs now run from the installed CLI and TUI. On Linux
4
+ x64 with Docker/KVM and a supported Codex ChatGPT login, isolated Firecracker
5
+ participants use the normal scheduler, recordings, Observer and automatic
6
+ analysis without E2B or OpenAI API keys. Codex inference remains remote and
7
+ consumes account quota; dollar cost is unknown.
8
+
9
+ `humanish runtime setup` prepares a pinned, verified runtime image. A live local
10
+ lab also prepares it automatically before starting participants. `runtime status`
11
+ and `doctor --lab` inspect readiness without downloading or launching a browser.
12
+ The TUI shows that same runtime status. Existing hosted labs retain their
13
+ configuration, and a missing local prerequisite never selects another provider.
14
+
15
+ The [setup guide](../architecture/local-browser-runtime.md) includes a complete
16
+ manifest and the current limits. This release supports loopback apps, fixed
17
+ 960×720 Chromium desktops, and optional OpenAI API participants. Mac/Lima,
18
+ local inboxes and local camera/microphone integration remain follow-ups.
19
+
20
+ Private state uses a Docker-owned anonymous volume, removed with its container
21
+ on normal close or controller death. Runtime image downloads are checked for
22
+ exact size and SHA-256 before loading; matching source archives and notices
23
+ are distributed separately.
24
+
25
+ Validation includes a packed installation outside the checkout: two concurrent
26
+ Codex participants saved distinct notes in a local app, the app confirmed both
27
+ saves, the recordings verified, and automatic analysis completed without model
28
+ or desktop API keys. Separate checks cover controller death and state-volume
29
+ removal, download integrity/cancellation, missing prerequisites and preserving
30
+ existing hosted configurations. This is a small Linux integration proof, not
31
+ a claim about Mac readiness, high concurrency or real conferencing apps.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "humanish",
3
- "version": "0.97.0",
3
+ "version": "0.98.0",
4
4
  "description": "Open-source-safe CLI for persona simulation, observer review, and public-safe feedback drafts.",
5
5
  "author": "Daniel G Wilson <daniel@danielgwilson.com>",
6
6
  "keywords": [
@@ -76,13 +76,15 @@
76
76
  "tui:smoke": "node scripts/tui-smoke.mjs",
77
77
  "tui:test": "pnpm --filter humanish-tui test",
78
78
  "release:dogfood": "node scripts/release-dogfood.mjs",
79
+ "browser-control:proof": "node scripts/browser-control-proof.mjs",
79
80
  "docs:generate": "tsx scripts/generate-cli-docs.ts",
80
81
  "docs:check": "tsx scripts/generate-cli-docs.ts --check",
81
82
  "observer:browser:proof": "node scripts/observer-browser-proof.mjs",
82
83
  "observer:iframe:proof": "node scripts/observer-iframe-proof.mjs",
83
84
  "observer:chrome:proof": "node scripts/observer-chrome-proof.mjs",
84
85
  "observer:reliability:proof": "node scripts/observer-reliability-proof.mjs",
85
- "tui:connections:proof": "python3 scripts/tui-connections-proof.py"
86
+ "tui:connections:proof": "python3 scripts/tui-connections-proof.py",
87
+ "guest-desktop:proof": "node scripts/guest-desktop-proof.mjs"
86
88
  },
87
89
  "repository": {
88
90
  "type": "git",
@@ -95,9 +95,10 @@ 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. Existing manual and automatic defaults
99
- use the OpenAI API with its own admission budget; a local-agent participant does
100
- not change that default. To use the restricted Codex ChatGPT account analyst,
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,
101
102
  set `review.analysis.provider: codex` or pass `analyze --provider codex` on a
102
103
  completed recording. This uses remote inference and the qualified CLI/login,
103
104
  not local inference or the participant's existing conversation. See
@@ -112,6 +113,25 @@ local evidence/configuration only; `doctor --lab` checks setup without a model
112
113
  request. Inspect a failed attempt before explicitly retrying `--provider codex
113
114
  --rerun`. Opening Observer never starts analysis.
114
115
 
116
+ ## Local browser setup
117
+
118
+ On Linux x64 with a local rootful Docker Engine, KVM and TUN, an `app-url` lab can
119
+ set `execution.target: local` and `actors[0].type: local-agent` with
120
+ `localAgent: codex`. It uses the supported Codex ChatGPT login, not E2B or an
121
+ OpenAI API key. Inference is remote and consumes account quota. Existing hosted
122
+ labs stay hosted; never silently change their execution or billing provider.
123
+
124
+ Use `humanish runtime status --json` and `humanish doctor --lab <path> --json`
125
+ for read-only setup inspection. `humanish runtime setup` downloads and verifies
126
+ the pinned runtime; a live local run also prepares it automatically. The normal
127
+ `humanish lab run <path>` command and TUI use the same study runner and Observer.
128
+ See [the complete example and limits](../../docs/architecture/local-browser-runtime.md).
129
+
130
+ Local browsers currently require a loopback app URL with an explicit port above
131
+ 1023, use a 960×720 Chromium desktop, and reject inbox/media declarations. Mac
132
+ setup is not integrated. Do not claim that installing the CLI also installs
133
+ Docker or makes these prerequisites available.
134
+
115
135
  ## Format Stack
116
136
 
117
137
  When creating or editing Humanish files: