humanish 0.93.1 → 0.95.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.
- package/README.md +26 -3
- package/dist/automatic-analysis-completion.d.ts +1 -1
- package/dist/automatic-analysis-completion.js +2 -2
- package/dist/automatic-analysis-completion.js.map +1 -1
- package/dist/automatic-analysis-config.d.ts +3 -0
- package/dist/automatic-analysis-config.js +6 -3
- package/dist/automatic-analysis-config.js.map +1 -1
- package/dist/automatic-study-analysis.d.ts +2 -0
- package/dist/automatic-study-analysis.js +8 -2
- package/dist/automatic-study-analysis.js.map +1 -1
- package/dist/comms-catch-host.js +33 -4
- package/dist/comms-catch-host.js.map +1 -1
- package/dist/comms-connections.d.ts +50 -0
- package/dist/comms-connections.js +123 -0
- package/dist/comms-connections.js.map +1 -0
- package/dist/comms-email-catch.d.ts +2 -1
- package/dist/comms-email-catch.js +5 -2
- package/dist/comms-email-catch.js.map +1 -1
- package/dist/comms-fake-inbox.d.ts +1 -1
- package/dist/comms-fake-inbox.js +15 -12
- package/dist/comms-fake-inbox.js.map +1 -1
- package/dist/comms-images.d.ts +7 -0
- package/dist/comms-images.js +39 -0
- package/dist/comms-images.js.map +1 -0
- package/dist/comms-inbox.d.ts +7 -1
- package/dist/comms-inbox.js +120 -21
- package/dist/comms-inbox.js.map +1 -1
- package/dist/comms-sandbox-catch.d.ts +1 -1
- package/dist/comms-sandbox-catch.js +60 -11
- package/dist/comms-sandbox-catch.js.map +1 -1
- package/dist/comms-types.d.ts +9 -0
- package/dist/concurrent-shared-world-lab.js +6 -3
- package/dist/concurrent-shared-world-lab.js.map +1 -1
- package/dist/cua-actor-lab.js +25 -12
- package/dist/cua-actor-lab.js.map +1 -1
- package/dist/doctor-lab.d.ts +23 -0
- package/dist/doctor-lab.js +70 -0
- package/dist/doctor-lab.js.map +1 -0
- package/dist/e2b-terminal-lab.js +5 -2
- package/dist/e2b-terminal-lab.js.map +1 -1
- package/dist/export.js +35 -18
- package/dist/export.js.map +1 -1
- package/dist/first-run-path.js +5 -4
- package/dist/first-run-path.js.map +1 -1
- package/dist/init.js +5 -7
- package/dist/init.js.map +1 -1
- package/dist/key-resolution.d.ts +1 -1
- package/dist/key-resolution.js +6 -4
- package/dist/key-resolution.js.map +1 -1
- package/dist/lab-config.d.ts +8 -3
- package/dist/lab-config.js +36 -8
- package/dist/lab-config.js.map +1 -1
- package/dist/lab-preflight.js +1 -1
- package/dist/lab-preflight.js.map +1 -1
- package/dist/lab-summary.d.ts +2 -2
- package/dist/lab-summary.js +11 -7
- package/dist/lab-summary.js.map +1 -1
- package/dist/local-agent-cli.d.ts +7 -3
- package/dist/local-agent-cli.js +75 -16
- package/dist/local-agent-cli.js.map +1 -1
- package/dist/observer-app.html +6 -6
- package/dist/observer.d.ts +6 -0
- package/dist/observer.js +11 -2
- package/dist/observer.js.map +1 -1
- package/dist/program.d.ts +2 -0
- package/dist/program.js +148 -82
- package/dist/program.js.map +1 -1
- package/dist/run.d.ts +6 -1
- package/dist/run.js +33 -19
- package/dist/run.js.map +1 -1
- package/dist/scripted-browser-lab.js +5 -2
- package/dist/scripted-browser-lab.js.map +1 -1
- package/dist/secret-prompt.d.ts +2 -0
- package/dist/secret-prompt.js +36 -0
- package/dist/secret-prompt.js.map +1 -0
- package/dist/shared-world-lab.js +5 -2
- package/dist/shared-world-lab.js.map +1 -1
- package/dist/study-analysis-engine.d.ts +5 -0
- package/dist/study-analysis-engine.js +11 -2
- package/dist/study-analysis-engine.js.map +1 -1
- package/dist/study-analysis-provider.d.ts +1 -1
- package/dist/study-analysis-provider.js +33 -3
- package/dist/study-analysis-provider.js.map +1 -1
- package/dist/study-analysis-service.d.ts +2 -0
- package/dist/study-analysis-service.js +4 -2
- package/dist/study-analysis-service.js.map +1 -1
- package/dist/tui-app.js +121 -121
- package/dist/tui-contract.d.ts +13 -1
- package/dist/tui-contract.js.map +1 -1
- package/docs/architecture/comms-inbox.md +78 -0
- package/docs/contracts/schemas.md +33 -5
- package/docs/contracts/study-analysis.md +11 -1
- package/docs/goals/current.md +6 -6
- package/docs/product/automatic-analysis.md +13 -4
- package/docs/ramp/README.md +14 -3
- package/docs/release/0.94.0-reliability.md +48 -0
- package/docs/release/0.95.0-connections-setup.md +38 -0
- package/package.json +6 -2
- package/skills/humanish/SKILL.md +28 -7
package/dist/tui-contract.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ import type { TuiActionResult } from "./tui-actions.js";
|
|
|
6
6
|
import type { TuiProjectState } from "./tui-project.js";
|
|
7
7
|
import type { ReadRunIndexOptions, RunIndexResult } from "./run-index.js";
|
|
8
8
|
import type { LaunchRunOptions, LaunchRunResult } from "./tui-launch.js";
|
|
9
|
+
import type { CommsSetupResult, CommsSetupStatus } from "./comms-connections.js";
|
|
9
10
|
/** The humanish version string shown in the frame, so a screenshot in a bug report is datable. */
|
|
10
11
|
export interface TuiVersionInfo {
|
|
11
12
|
cli: string;
|
|
@@ -16,6 +17,11 @@ export interface TuiVersionInfo {
|
|
|
16
17
|
* one place, and anything absent here is something the TUI simply cannot do.
|
|
17
18
|
*/
|
|
18
19
|
export interface TuiCapabilities {
|
|
20
|
+
/** Optional for older embedders. Credentials are never returned to the view. */
|
|
21
|
+
comms?: {
|
|
22
|
+
read(): Promise<CommsSetupStatus>;
|
|
23
|
+
save(): Promise<CommsSetupResult>;
|
|
24
|
+
};
|
|
19
25
|
/** Read every run in the project, cheapest source first. */
|
|
20
26
|
readRunIndex(cwd: string, options?: ReadRunIndexOptions): Promise<RunIndexResult>;
|
|
21
27
|
/**
|
|
@@ -62,6 +68,9 @@ export interface TuiCapabilities {
|
|
|
62
68
|
initProject(cwd: string): Promise<TuiActionResult>;
|
|
63
69
|
}
|
|
64
70
|
export interface TuiOptions {
|
|
71
|
+
/** Return to setup after the host-owned hidden prompt has finished. */
|
|
72
|
+
initialScreen?: "connections";
|
|
73
|
+
connectionNotice?: string;
|
|
65
74
|
/** The project the surface is reading. Already resolved by the CLI. */
|
|
66
75
|
cwd: string;
|
|
67
76
|
version: TuiVersionInfo;
|
|
@@ -80,7 +89,10 @@ export interface TuiOptions {
|
|
|
80
89
|
* Start the surface. Resolves with the process exit code when the operator quits — the TUI owns the
|
|
81
90
|
* screen until then, so the CLI must not write to stdout while this is pending.
|
|
82
91
|
*/
|
|
83
|
-
export type
|
|
92
|
+
export type TuiHandoff = {
|
|
93
|
+
action: "agentmail-key";
|
|
94
|
+
};
|
|
95
|
+
export type StartTui = (options: TuiOptions) => Promise<number | TuiHandoff>;
|
|
84
96
|
/** The shape `dist/tui-app.js` exports. Asserted at the load boundary in program.ts. */
|
|
85
97
|
export interface TuiModule {
|
|
86
98
|
startTui: StartTui;
|
package/dist/tui-contract.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tui-contract.js","sourceRoot":"","sources":["../src/tui-contract.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,EAAE;AACF,6FAA6F;AAC7F,mGAAmG;AACnG,+EAA+E;AAC/E,EAAE;AACF,gGAAgG;AAChG,+FAA+F;AAC/F,gGAAgG;AAChG,mGAAmG;AACnG,6DAA6D;AAC7D,EAAE;AACF,mGAAmG;AACnG,mBAAmB;
|
|
1
|
+
{"version":3,"file":"tui-contract.js","sourceRoot":"","sources":["../src/tui-contract.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,EAAE;AACF,6FAA6F;AAC7F,mGAAmG;AACnG,+EAA+E;AAC/E,EAAE;AACF,gGAAgG;AAChG,+FAA+F;AAC/F,gGAAgG;AAChG,mGAAmG;AACnG,6DAA6D;AAC7D,EAAE;AACF,mGAAmG;AACnG,mBAAmB;AAyGnB,mFAAmF;AACnF,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAErC;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,gBAAwB,OAAO,CAAC,OAAO;IACrE,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IACvF,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,kBAAkB,CAAC;AAC/D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,OAAO,IAAI,GAAG,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;AAC1C,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAKtC;IACC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;QACrB,OAAO,+BAA+B,kBAAkB,cAAc,KAAK,CAAC,WAAW,mCAAmC,CAAC;IAC7H,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;QACzB,OAAO,8GAA8G,CAAC;IACxH,CAAC;IACD,OAAO,KAAK,CAAC,WAAW;QACtB,CAAC,CAAC,yEAAyE;QAC3E,CAAC,CAAC,kJAAkJ,CAAC;AACzJ,CAAC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Participant inboxes
|
|
2
|
+
|
|
3
|
+
The catch captures application mail without sending it to an external recipient.
|
|
4
|
+
Humanish gives each participant an address and a matching
|
|
5
|
+
`/inbox/for/<address-digest>` URL. The same address scope applies to list, message,
|
|
6
|
+
plain view, latest-message and JSON routes. Navigating back from a missing message
|
|
7
|
+
stays in that scope. An unknown scope is empty; it never falls back to all mail.
|
|
8
|
+
A lane without an assigned address receives no inbox instruction.
|
|
9
|
+
|
|
10
|
+
This works with separate participant worlds, shared worlds, and an external catch.
|
|
11
|
+
Sharing an application world does not require sharing an inbox. If a lab deliberately
|
|
12
|
+
assigns the same address to two participants, both see that address's mail. Generated
|
|
13
|
+
addresses that collide after normalization are made distinct. A message addressed
|
|
14
|
+
to several participants appears in each recipient's inbox and retains its actual
|
|
15
|
+
To field.
|
|
16
|
+
|
|
17
|
+
`/inbox` remains available and is labeled **Shared operator inbox**. Address digests
|
|
18
|
+
are routing identifiers, not authentication credentials. The catch is study
|
|
19
|
+
infrastructure, not a mailbox service with hostile-tenant isolation. Keep its network
|
|
20
|
+
exposure appropriate for test mail. The read-only listener cannot expose the private
|
|
21
|
+
`/deliveries` drain, even when supplied a valid drain token. The capture listener
|
|
22
|
+
retains its existing optional bearer-token protection for that endpoint.
|
|
23
|
+
|
|
24
|
+
A standalone catch tracks its generated files. Reusing its directory with a changed
|
|
25
|
+
`--recipient` roster or an emptied delivery log removes obsolete message, latest and
|
|
26
|
+
recipient routes; unrelated files are untouched.
|
|
27
|
+
|
|
28
|
+
## Existing external catches
|
|
29
|
+
|
|
30
|
+
Upgrade the Humanish installation that runs `humanish comms catch` and **restart that
|
|
31
|
+
catch process**, as well as upgrading the installation that starts the study. Updating
|
|
32
|
+
only the study client leaves an older catch without participant routes.
|
|
33
|
+
|
|
34
|
+
Before allocating participants, the client checks `/health` on both `catchBaseUrl`
|
|
35
|
+
and a distinct `inboxBaseUrl`. Each must return the normal service marker and
|
|
36
|
+
`capabilities: ["recipient-inbox-v1", ...]`. Missing, malformed or older responses
|
|
37
|
+
fail admission with an upgrade/restart instruction. Existing email capture endpoints
|
|
38
|
+
and unscoped operator URLs remain available; their payload contracts are unchanged.
|
|
39
|
+
|
|
40
|
+
## Captured and remote images
|
|
41
|
+
|
|
42
|
+
The SMTP catch preserves MIME parts with a Content-ID when they contain PNG, JPEG,
|
|
43
|
+
GIF or WebP bytes. The generic `/emails` payload can also carry runtime-only
|
|
44
|
+
`inlineImages` entries with `contentId`, `contentType` and `base64`. Provider-specific
|
|
45
|
+
attachment fields are not converted; unsupported or missing CID references show an
|
|
46
|
+
explicit unavailable-image placeholder instead of pretending capture succeeded.
|
|
47
|
+
|
|
48
|
+
Captured images are limited to 12 entries, 1 MiB each and 2 MiB total. The renderer
|
|
49
|
+
checks canonical base64 and the declared raster format's signature before creating a
|
|
50
|
+
data URL. This is not a full image decoder; malformed raster content can still fail
|
|
51
|
+
in the browser. Inline data URLs receive the same per-image checks. SVG, arbitrary
|
|
52
|
+
attachment URLs and local paths are not fetched or converted.
|
|
53
|
+
|
|
54
|
+
HTTP(S) images remain browser loads with `no-referrer`. Humanish does not fetch or
|
|
55
|
+
proxy them server-side. Relative image URLs use the existing declared origin-rewrite
|
|
56
|
+
map when available; otherwise they receive an explicit placeholder. Remote URLs that
|
|
57
|
+
return errors retain the browser's alt-text fallback. The renderer does not claim to
|
|
58
|
+
repair a dead URL. The inbox retains `script-src 'none'` and the existing HTML
|
|
59
|
+
neutralization and origin-rewrite protections.
|
|
60
|
+
|
|
61
|
+
Raw mail and image bytes remain runtime catch data. Persisted comms evidence remains
|
|
62
|
+
digest-only; adding image capture does not add raw attachments to the run artifact.
|
|
63
|
+
|
|
64
|
+
## Reproduce the contract
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
pnpm exec vitest run tests/comms*.test.ts
|
|
68
|
+
pnpm exec tsx scripts/comms-inbox-proof.ts
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The browser proof starts owned loopback HTTP, read-only inbox and SMTP listeners,
|
|
72
|
+
sends fictional multipart mail through the real MIME parser, and renders two recipient
|
|
73
|
+
inboxes in Chromium at desktop and phone sizes. It checks decoded CID/data/remote
|
|
74
|
+
images, unavailable sources, a genuine remote 404, recipient isolation across HTML
|
|
75
|
+
and JSON, navigation, script blocking, referrer suppression, directory reuse and drain
|
|
76
|
+
access. Screenshots and a machine-readable receipt are saved under the ignored
|
|
77
|
+
`.humanish/comms-inbox-proof/` directory. It uses no external email delivery, paid model
|
|
78
|
+
calls or hosted desktop, and makes no claim about those providers.
|
|
@@ -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.
|
|
6
|
+
`0.95.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.
|
|
@@ -265,10 +265,13 @@ A lab is a composition over code primitives, not a hardcoded kind:
|
|
|
265
265
|
`redactScreenshots: true` (blur unimplemented there) and
|
|
266
266
|
`allowPublicTargets: true` fail-closed rather than ignoring them.
|
|
267
267
|
- `comms` (#297; hosted on the clone/local-tree computer-use lanes and the
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
email
|
|
268
|
+
concurrent shared-world getHost plane, or connected to an external catch on
|
|
269
|
+
app-url/operator-provided subjects; unwired on sequential `concurrency: 1`
|
|
270
|
+
shared worlds): off-app
|
|
271
|
+
email the app itself sends, made a persona-driven testable surface. Lab
|
|
272
|
+
configuration rejects `comms.sms` and unknown channel names; message-bus SMS
|
|
273
|
+
types do not imply a supported SMS execution route. SMTP capture is supported
|
|
274
|
+
on per-lane provisioned routes and rejected for shared-world studies.
|
|
272
275
|
`comms.email` = `{ kind: fake, injectEnv?, port?, recipients?, linkOrigin?, external? }`.
|
|
273
276
|
`injectEnv` is the ADOPTER-NAMED env var the app reads for its email-API base
|
|
274
277
|
URL (e.g. `RESEND_API_URL`); the harness sets it to an in-sandbox catch (so it
|
|
@@ -310,6 +313,31 @@ A lab is a composition over code primitives, not a hardcoded kind:
|
|
|
310
313
|
persona saw the email is its screenshots of the inbox page. Requires `python3`
|
|
311
314
|
in the subject sandbox (the stock E2B desktop template has it).
|
|
312
315
|
|
|
316
|
+
### Communication connection setup
|
|
317
|
+
|
|
318
|
+
`.humanish/local/comms.yaml` is a project-local, non-secret configuration file:
|
|
319
|
+
|
|
320
|
+
```yaml
|
|
321
|
+
schema: humanish.comms-connections.v1
|
|
322
|
+
connections:
|
|
323
|
+
agentmail:
|
|
324
|
+
provider: agentmail
|
|
325
|
+
apiKeyEnv: AGENTMAIL_API_KEY
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
Only AgentMail setup is currently supported. Connection names use lowercase
|
|
329
|
+
letters, digits and hyphens, beginning with a letter, up to 48 characters.
|
|
330
|
+
`apiKeyEnv` names an environment variable; it never contains its value.
|
|
331
|
+
Invalid fields, unsupported providers and unsafe filesystem paths are rejected.
|
|
332
|
+
Adding an existing name with different settings refuses to overwrite it.
|
|
333
|
+
|
|
334
|
+
`comms connections list --json` returns `humanish.comms-setup.v1`: configured
|
|
335
|
+
profiles and local key presence/source, not provider authentication or delivery.
|
|
336
|
+
`comms providers --json` returns `humanish.comms-providers.v1` with explicit
|
|
337
|
+
setup/receiving availability. The key store accepts `humanish keys set agentmail`.
|
|
338
|
+
Saving a connection neither modifies a lab nor creates a provider resource;
|
|
339
|
+
`comms.email.connection` in a study remains unsupported and is rejected.
|
|
340
|
+
|
|
313
341
|
Lab backends report results in their own schemas (`humanish.run-result.v1`,
|
|
314
342
|
`humanish.oss-lab-result.v1`, `humanish.oss-meta-lab-result.v1`,
|
|
315
343
|
`humanish.cua-lab-result.v2`, `humanish.scripted-lab-result.v1`,
|
|
@@ -31,7 +31,17 @@ admission. It bounds a conservative estimate, not an exact provider bill.
|
|
|
31
31
|
estimate retains valid findings and usage but returns a partial result and a
|
|
32
32
|
nonzero command exit, including when that version is reused.
|
|
33
33
|
|
|
34
|
-
The
|
|
34
|
+
The default deadline is ten minutes. With no explicit output-token limit, analysis
|
|
35
|
+
uses 32,768 tokens if admission fits the declared budget, or retains the prior
|
|
36
|
+
16,384-token allowance otherwise. Explicit limits are never adjusted. Selection
|
|
37
|
+
happens before dispatch; `admission.outputTokenAllowance` exposes it in dry-run,
|
|
38
|
+
and the saved configuration, digest and automatic job bind the selected allowance.
|
|
39
|
+
This selection never increases the spending limit or starts a retry.
|
|
40
|
+
The configured wall-clock deadline covers the entire request, including waiting
|
|
41
|
+
for response headers and reading the body. A request-scoped dispatcher prevents
|
|
42
|
+
Node's separate fetch timeout from cutting a longer configured deadline short;
|
|
43
|
+
it does not change other network requests in the process. Transport failures
|
|
44
|
+
retain only an allowlisted cause code, never provider exception text or URLs.
|
|
35
45
|
The analysis checks the assigned requirements against the retained end state;
|
|
36
46
|
an unverified essential result remains unknown even if the participant reported
|
|
37
47
|
success. Findings keep reported concerns and observed recovery distinct across
|
package/docs/goals/current.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# Current Goals
|
|
2
2
|
|
|
3
|
-
Status date: 2026-09-
|
|
3
|
+
Status date: 2026-09-20. Release baseline: `0.95.0`.
|
|
4
4
|
|
|
5
5
|
This page guides work on current merged source. Published behavior is described
|
|
6
|
-
in the [release notes](../release/0.
|
|
6
|
+
in the [release notes](../release/0.95.0-connections-setup.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.
|
|
91
|
+
## Current Program Truth (source `0.95.0`)
|
|
92
92
|
|
|
93
93
|
| Surface | Available in merged source | Remaining boundary |
|
|
94
94
|
| --- | --- | --- |
|
|
@@ -100,9 +100,9 @@ substitute for it.
|
|
|
100
100
|
| Observer | Live/recorded views, shared grid and participant playback, participant assignments, action-specific links, saved moments, zoom, comparison and phone-width review | Sparse captures cannot prove every action's effect; visual comparison alone is not a controlled experiment |
|
|
101
101
|
| Review and feedback | Verification grades, feedback drafts, portable HTML, redacted bundle derivatives and computer-use completion-source labels | Sharing requires the appropriate grade; participant reports and condition matches still need task adjudication |
|
|
102
102
|
| Study findings | Default post-run analysis on supported live routes with a separate disclosed $3 admission estimate limit and opt-out; explicit `analyze`, fairer evidence selection, concern review and versioned findings with exact source links | Model interpretation needs review; bounded selection and source truncation limit coverage; opening Observer never dispatches analysis |
|
|
103
|
-
| TUI and serving | Detached starts, run stopping, reclamation, Observer attachment, loopback serving
|
|
104
|
-
| Off-app communication |
|
|
105
|
-
| Mobile and media | Hosted viewport/emulation, desktop geometry checks, bounded dwell and declared camera feed |
|
|
103
|
+
| TUI and serving | Detached starts, run stopping, reclamation, Observer attachment, loopback serving, run library and AgentMail connection/key setup | Stopping a process does not itself prove sandbox cleanup; TUI views over CLI `stats`/`export` remain follow-ups |
|
|
104
|
+
| Off-app communication | Recipient-scoped synthetic email inboxes, supported inline raster images, email capture and digest-only thread evidence | Scope prevents accidental cross-recipient browsing; it is not tenant authentication or real-provider delivery. AgentMail setup does not enable receiving; SMS is not a configured execution route |
|
|
105
|
+
| Mobile and media | Hosted viewport/emulation, desktop geometry checks, bounded dwell and declared camera feed; a synthetic video-only call with separate hosted peers is proven | Audio, TURN, provider-specific rooms, physical-device and touch fidelity remain unproven; unsupported media declarations are rejected |
|
|
106
106
|
|
|
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)
|
|
@@ -4,16 +4,19 @@ Supported live studies automatically request analysis after each recording finis
|
|
|
4
4
|
separate from participant feedback and the recorded study verdict.
|
|
5
5
|
|
|
6
6
|
The default is `gpt-6-astra` with high reasoning effort, a separate $3 admission
|
|
7
|
-
estimate limit
|
|
7
|
+
estimate limit and a 600-second timeout. When no output limit is specified,
|
|
8
|
+
Humanish selects 32,768 tokens if the exact input's admission estimate fits that
|
|
9
|
+
budget; otherwise it keeps the established 16,384-token allowance. This preserves
|
|
10
|
+
previously admitted studies without increasing their spending limit. To customize it:
|
|
8
11
|
|
|
9
12
|
```yaml
|
|
10
13
|
review:
|
|
11
14
|
analysis:
|
|
12
15
|
maxCostUsd: 3
|
|
13
|
-
# Optional
|
|
16
|
+
# Optional overrides. Omit maxOutputTokens for budget-aware selection.
|
|
14
17
|
model: gpt-6-astra
|
|
15
|
-
timeoutMs:
|
|
16
|
-
maxOutputTokens:
|
|
18
|
+
timeoutMs: 600000
|
|
19
|
+
# maxOutputTokens: 32768
|
|
17
20
|
# question: Where did participants need to recover?
|
|
18
21
|
```
|
|
19
22
|
|
|
@@ -21,6 +24,12 @@ Omitting `review.analysis` uses these defaults. Set `review.analysis: false` to
|
|
|
21
24
|
run participants without the additional analysis request. An explicit analysis
|
|
22
25
|
mapping requires `maxCostUsd`. This limits an admission estimate, not the
|
|
23
26
|
provider's final bill, and is separate from participant spending limits. Analysis
|
|
27
|
+
can decline a large study before dispatch when its conservative estimate exceeds
|
|
28
|
+
that limit. Use `analyze --dry-run --max-cost <usd>` on retained evidence to inspect
|
|
29
|
+
the estimate and selected token allowance before deliberately choosing a larger budget. Explicit
|
|
30
|
+
`maxOutputTokens` and `--max-output-tokens` limits are honored exactly. The output allowance
|
|
31
|
+
includes reasoning as well as the report; exhausting it does not produce a usable
|
|
32
|
+
report and never starts an automatic retry. Analysis
|
|
24
33
|
sends selected retained text and captures to OpenAI using `OPENAI_API_KEY`.
|
|
25
34
|
Analysis runs in the Humanish runner using its credentials. This setting adds no
|
|
26
35
|
credential channel to the target application; each participant backend retains
|
package/docs/ramp/README.md
CHANGED
|
@@ -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.
|
|
5
|
+
Package/source version in this tree: `0.95.0` (2026-09-20). 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
|
|
@@ -47,6 +47,16 @@ If a change does not improve one of those loops, it probably belongs elsewhere.
|
|
|
47
47
|
|
|
48
48
|
## Current State
|
|
49
49
|
|
|
50
|
+
The [0.95.0 release note](../release/0.95.0-connections-setup.md) describes
|
|
51
|
+
AgentMail connection setup, hidden key entry and return to the TUI, matching
|
|
52
|
+
CLI setup commands, and truthful credential status. Real email receiving is
|
|
53
|
+
still unavailable; saved connections cannot be used in studies yet.
|
|
54
|
+
|
|
55
|
+
The [0.94.0 release note](../release/0.94.0-reliability.md) describes analysis
|
|
56
|
+
request deadlines and budget-aware output, smaller portable recordings,
|
|
57
|
+
recipient-scoped synthetic inboxes, route-aware setup checks, decoded capture
|
|
58
|
+
transitions, pin movement, and explicit camera-support boundaries.
|
|
59
|
+
|
|
50
60
|
The [0.93.1 release note](../release/0.93.1-observer-review-controls.md) describes
|
|
51
61
|
a compact findings overview, separate analysis-attempt details, styled Observer
|
|
52
62
|
selects and checkboxes, clearer pin/theme states, and smoother navigation.
|
|
@@ -149,11 +159,12 @@ Implemented:
|
|
|
149
159
|
deterministic proof, while concurrent has deterministic and kept live proof;
|
|
150
160
|
- `subject.source: local-tree`, which packages one selected working tree with a
|
|
151
161
|
content pin before using the same provision-and-serve path as clone subjects;
|
|
152
|
-
- an off-app comms funnel for email
|
|
162
|
+
- an off-app comms funnel for email-gated flows: a vendor-neutral in-sandbox
|
|
153
163
|
catch redirects the app's own send API, a persona reads a minimal inbox surface
|
|
154
164
|
and clicks through, and a digest-only `humanish.comms-thread.v1` artifact
|
|
155
165
|
records the thread with no raw address, link, or code — wired into the
|
|
156
|
-
computer-use and shared-world routes and live-proven on computer-use
|
|
166
|
+
computer-use and concurrent shared-world routes and live-proven on computer-use.
|
|
167
|
+
SMS is not yet a configured execution route;
|
|
157
168
|
- resolved-persona directives that actually shape the actor prompt on the
|
|
158
169
|
terminal-product route (traits are applied and recorded in the actor trace, not
|
|
159
170
|
decorative), reusing the same `persona.ts` compiler as the computer-use lane;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Humanish 0.94.0
|
|
2
|
+
|
|
3
|
+
Long analysis requests now honor Humanish's configured deadline instead of
|
|
4
|
+
ending early at the HTTP client's header timeout. The default deadline is ten
|
|
5
|
+
minutes. Omitted output settings use up to 32,768 tokens when the existing
|
|
6
|
+
declared budget admits that allowance, otherwise retaining 16,384. Explicit
|
|
7
|
+
output settings remain exact. This adds no retries or automatic budget increase.
|
|
8
|
+
|
|
9
|
+
Portable HTML stores each distinct raster capture once and resolves it on
|
|
10
|
+
demand. A retained 12-participant, 344-capture recording decreased from about
|
|
11
|
+
309 MiB to 143 MiB without changing capture bytes or timestamps. Existing
|
|
12
|
+
recordings remain readable; new exports retain the same sharing checks.
|
|
13
|
+
|
|
14
|
+
Participant inbox links now open that participant's synthetic recipient scope.
|
|
15
|
+
Unknown scopes fail closed, while the shared inbox remains explicitly labeled
|
|
16
|
+
for operators. Supported captured inline images render; unsupported references
|
|
17
|
+
show an explanation. Remote images still depend on their original host.
|
|
18
|
+
Recipient scopes are navigation isolation, not tenant authentication.
|
|
19
|
+
|
|
20
|
+
`humanish doctor --lab <lab>` separates participant authentication, hosted
|
|
21
|
+
desktop requirements and automatic-analysis credentials. Local Codex or Claude
|
|
22
|
+
authentication is checked through that CLI rather than inferred from a file.
|
|
23
|
+
The keyless first run needs no model or desktop credentials.
|
|
24
|
+
Projects without `package.json` are valid; `doctor` treats the missing optional
|
|
25
|
+
npm integration as information while still rejecting unsafe or unreadable files.
|
|
26
|
+
|
|
27
|
+
Observer keeps the previous decoded capture visible while loading the selected
|
|
28
|
+
one, labels it as previous evidence, and withholds action pins until the selected
|
|
29
|
+
image is ready. Pinning animates the displaced cards as well as the selected
|
|
30
|
+
card, preserving focus and respecting reduced motion. Pin and unpin are
|
|
31
|
+
available directly on each card, with readable metadata and phone touch targets.
|
|
32
|
+
A repeatable browser
|
|
33
|
+
gate checks capture transitions, motion and automated accessibility in both
|
|
34
|
+
themes at desktop and phone widths.
|
|
35
|
+
|
|
36
|
+
An actual Humanish participant joined a synthetic camera room with a separate
|
|
37
|
+
hosted peer, exchanged moving video, and left. A second participant denied the
|
|
38
|
+
native camera prompt and stayed outside the room. Unsupported media routes and
|
|
39
|
+
microphone-file injection now fail before execution instead of silently ignoring
|
|
40
|
+
the declaration. This proves one video-only Chromium path; audio, TURN and
|
|
41
|
+
provider-specific rooms remain unproven.
|
|
42
|
+
|
|
43
|
+
Kept evidence and limits:
|
|
44
|
+
|
|
45
|
+
- [Analysis reliability](../goals/computer-use-actor/receipts/analysis-reliability-2026-09-19.md)
|
|
46
|
+
- [Portable recording comparison](../goals/observer-qol/receipts/2026-09-19-portable-export.md)
|
|
47
|
+
- [Setup, inbox and camera proof](../goals/computer-use-actor/receipts/reliability-2026-09-19.md)
|
|
48
|
+
- [Observer capture and accessibility gate](https://github.com/danielgwilson/humanish/blob/main/scripts/observer-reliability-proof.md)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# 0.95.0 — Connections and hidden key entry
|
|
2
|
+
|
|
3
|
+
Open `humanish tui` and press **c** to configure AgentMail. **Add API key**
|
|
4
|
+
opens a hidden terminal prompt, then returns to Connections. Ctrl+C cancels
|
|
5
|
+
without changing the existing key or profile. Existing keys can be reused or
|
|
6
|
+
replaced. Entry uses the host's key store, outside the TUI rendering contract.
|
|
7
|
+
|
|
8
|
+
Keys live in the existing user-level store with file mode 0600. Project
|
|
9
|
+
connection metadata lives in `.humanish/local/comms.yaml` and contains only a
|
|
10
|
+
provider name and environment-variable reference. Explicit environment/env-file
|
|
11
|
+
values retain precedence; strict key mode continues to disable discovery.
|
|
12
|
+
The screen identifies those cases instead of claiming a newly stored key is active.
|
|
13
|
+
|
|
14
|
+
Agents have matching commands:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
humanish comms providers --json
|
|
18
|
+
humanish keys set agentmail
|
|
19
|
+
humanish comms connections add agentmail --json
|
|
20
|
+
humanish comms connections list --json
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
This is connection setup only. Authentication, permissions, capacity and
|
|
24
|
+
delivery are unverified, and this version does not acquire mailboxes or enable
|
|
25
|
+
provider-backed email in studies. Unsupported study connection/SMS selectors
|
|
26
|
+
and shared-world SMTP declarations fail before execution. Supported local
|
|
27
|
+
email capture remains available.
|
|
28
|
+
|
|
29
|
+
The release also includes TUI `--env-file` propagation and route-specific key
|
|
30
|
+
requirements from #793. Dry-run, local-agent and terminal participants no longer
|
|
31
|
+
inherit a hardcoded OpenAI-plus-E2B key requirement.
|
|
32
|
+
|
|
33
|
+
Validation covers local configuration, containment, credential precedence,
|
|
34
|
+
hidden entry/cancellation/paste, persistence and TUI frames at 80 and 45
|
|
35
|
+
columns. `pnpm tui:connections:proof` drives the built CLI in a real PTY with
|
|
36
|
+
synthetic keys and an isolated store, checking cancellation, replacement,
|
|
37
|
+
restart and absence of credential values from terminal output. It requires
|
|
38
|
+
Python 3 with Unix PTY support; it does not contact AgentMail.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "humanish",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.95.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": [
|
|
@@ -80,7 +80,9 @@
|
|
|
80
80
|
"docs:check": "tsx scripts/generate-cli-docs.ts --check",
|
|
81
81
|
"observer:browser:proof": "node scripts/observer-browser-proof.mjs",
|
|
82
82
|
"observer:iframe:proof": "node scripts/observer-iframe-proof.mjs",
|
|
83
|
-
"observer:chrome:proof": "node scripts/observer-chrome-proof.mjs"
|
|
83
|
+
"observer:chrome:proof": "node scripts/observer-chrome-proof.mjs",
|
|
84
|
+
"observer:reliability:proof": "node scripts/observer-reliability-proof.mjs",
|
|
85
|
+
"tui:connections:proof": "python3 scripts/tui-connections-proof.py"
|
|
84
86
|
},
|
|
85
87
|
"repository": {
|
|
86
88
|
"type": "git",
|
|
@@ -94,6 +96,7 @@
|
|
|
94
96
|
"commander": "^14.0.3",
|
|
95
97
|
"playwright-core": "^1.60.0",
|
|
96
98
|
"pngjs": "^7.0.0",
|
|
99
|
+
"undici": "^6.28.1",
|
|
97
100
|
"yaml": "^2.9.0",
|
|
98
101
|
"zod": "^4.4.3"
|
|
99
102
|
},
|
|
@@ -114,6 +117,7 @@
|
|
|
114
117
|
"@e2b/desktop": "^2.4.0",
|
|
115
118
|
"@types/node": "^20.19.41",
|
|
116
119
|
"@types/pngjs": "^6.0.5",
|
|
120
|
+
"axe-core": "4.13.0",
|
|
117
121
|
"tsx": "^4.22.4",
|
|
118
122
|
"typescript": "^6.0.3",
|
|
119
123
|
"vitest": "^4.1.7"
|
package/skills/humanish/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: humanish
|
|
3
|
-
description: Install and configure Humanish CLI in a JavaScript app as an open-source-safe persona simulation harness. Use when an agent needs to add humanish, run safe first setup, create synthetic personas or scenarios, configure env var names without values, capture the email
|
|
3
|
+
description: Install and configure Humanish CLI in a JavaScript app as an open-source-safe persona simulation harness. Use when an agent needs to add humanish, run safe first setup, create synthetic personas or scenarios, configure env var names without values, capture the email an app sends so a persona can complete an email-gated flow (e.g. a signup verification link or one-time code), run verification and Observer commands, or draft public-safe feedback issues without GitHub mutation.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Humanish CLI
|
|
@@ -36,10 +36,21 @@ Everything it shows has a machine-readable equivalent, which is what you want:
|
|
|
36
36
|
| browsing runs | `npx humanish runs --json` |
|
|
37
37
|
| starting a run | `npx humanish lab run <lab> --json --no-open` |
|
|
38
38
|
| a run's outcome | `npx humanish review --run <id> --json` |
|
|
39
|
+
| communication setup | `npx humanish comms providers --json` and `npx humanish comms connections list --json` |
|
|
39
40
|
|
|
40
41
|
If a human asks you to "open the TUI", tell them the command to type; do not run
|
|
41
42
|
it on their behalf.
|
|
42
43
|
|
|
44
|
+
For AgentMail credential setup, a human can open `humanish tui`, press `c`,
|
|
45
|
+
and choose **Add API key**. Hidden entry returns to Connections after saving or
|
|
46
|
+
cancelling. The key is stored for that OS user, while the connection profile is
|
|
47
|
+
project-local. Never ask for the key in chat. The CLI alternative is
|
|
48
|
+
`humanish keys set agentmail` (hidden prompt; agents may use `--stdin` from an
|
|
49
|
+
authorized credential source), followed by
|
|
50
|
+
`humanish comms connections add agentmail --json`. Existing env/file precedence
|
|
51
|
+
and `HUMANISH_STRICT_KEYS=1` still apply. Read installed provider capabilities:
|
|
52
|
+
this release supports setup only, not authenticated checks or real email delivery.
|
|
53
|
+
|
|
43
54
|
## Setup Workflow
|
|
44
55
|
|
|
45
56
|
1. Inspect public target-repo files only: `package.json`, docs, route/app
|
|
@@ -203,9 +214,9 @@ npx humanish watch first-run
|
|
|
203
214
|
npx humanish lab run first-run --json --no-open
|
|
204
215
|
```
|
|
205
216
|
|
|
206
|
-
### Off-app email
|
|
217
|
+
### Off-app email verification (comms)
|
|
207
218
|
|
|
208
|
-
When a flow is gated behind an email
|
|
219
|
+
When a flow is gated behind an email the app itself sends — a signup
|
|
209
220
|
verification link, a one-time code, a magic link — add a `comms:` block. The
|
|
210
221
|
harness redirects the app's email-API sends into a catch INSIDE the sandbox (no
|
|
211
222
|
mail leaves the machine), gives the persona a synthetic inbox to open and click
|
|
@@ -213,6 +224,11 @@ through, and writes a digest-only `humanish.comms-thread.v1` evidence artifact (
|
|
|
213
224
|
raw address/link/code persists). Reach for this whenever a persona must read mail
|
|
214
225
|
the app sent it to finish a step.
|
|
215
226
|
|
|
227
|
+
Lab execution supports email capture only. `comms.sms`, saved connection
|
|
228
|
+
selectors and unknown channel names are rejected. AgentMail connection/key
|
|
229
|
+
setup is available separately; it does not enable real receiving yet. Real SMS
|
|
230
|
+
delivery is also unavailable; a message-bus type does not establish route support.
|
|
231
|
+
|
|
216
232
|
```yaml
|
|
217
233
|
comms:
|
|
218
234
|
email:
|
|
@@ -247,10 +263,15 @@ The app keeps calling its email API normally (Resend/SendGrid-shaped, or a custo
|
|
|
247
263
|
profile); only the base URL is redirected. Route support: the clone/local-tree
|
|
248
264
|
computer-use route (inbox on the sandbox's own loopback) and the CONCURRENT
|
|
249
265
|
shared-world route (inbox getHost-exposed from the subject sandbox; the default
|
|
250
|
-
since every seat now runs live at once).
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
266
|
+
since every seat now runs live at once). SMTP capture is supported on per-lane
|
|
267
|
+
provisioned routes; shared-world SMTP is rejected because it is not wired there.
|
|
268
|
+
For app-url/operator-provided subjects, run `humanish comms catch` on a reachable
|
|
269
|
+
host, point the app's email sends at that catch, and declare
|
|
270
|
+
`comms.email.external.catchBaseUrl` (plus `inboxBaseUrl` if different). A declared
|
|
271
|
+
`authTokenEnv` is an environment variable name, never a credential value.
|
|
272
|
+
Sequential `concurrency: 1` shared-world email remains unwired; do not silently
|
|
273
|
+
change study concurrency to work around that limitation. The in-sandbox catch
|
|
274
|
+
needs `python3` (the stock E2B desktop has it).
|
|
254
275
|
Evidence is digest-only (`humanish.comms-thread.v1` — counts and digests, never
|
|
255
276
|
raw mail); the *readable* proof a persona saw the email is its screenshots of the
|
|
256
277
|
inbox page. See `docs/contracts/schemas.md` for the full `comms:` shape and
|