humanish 0.15.2 → 0.16.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 +15 -7
- package/dist/actor-contract.d.ts +2 -3
- package/dist/actor-contract.js +6 -7
- package/dist/actor-contract.js.map +1 -1
- package/dist/actor-registry.d.ts +4 -4
- package/dist/actor-registry.js +8 -7
- package/dist/actor-registry.js.map +1 -1
- package/dist/artifact-reference.js +1 -1
- package/dist/artifact-reference.js.map +1 -1
- package/dist/concurrent-shared-world-lab.js +24 -11
- package/dist/concurrent-shared-world-lab.js.map +1 -1
- package/dist/cua-actor-lab.d.ts +101 -4
- package/dist/cua-actor-lab.js +456 -77
- package/dist/cua-actor-lab.js.map +1 -1
- package/dist/device-presets.d.ts +4 -4
- package/dist/device-presets.js +5 -5
- package/dist/device-presets.js.map +1 -1
- package/dist/e2b-terminal-lab.d.ts +18 -20
- package/dist/e2b-terminal-lab.js +28 -28
- package/dist/e2b-terminal-lab.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lab-config.d.ts +27 -28
- package/dist/lab-config.js +6 -6
- package/dist/lab-config.js.map +1 -1
- package/dist/lab-engine.d.ts +1 -1
- package/dist/lab-engine.js +8 -10
- package/dist/lab-engine.js.map +1 -1
- package/dist/observer-assets.js +92 -15
- package/dist/observer-assets.js.map +1 -1
- package/dist/oss-meta-lab.js +2 -4
- package/dist/oss-meta-lab.js.map +1 -1
- package/dist/program.js +1 -1
- package/dist/program.js.map +1 -1
- package/dist/run.d.ts +38 -0
- package/dist/run.js +71 -1
- package/dist/run.js.map +1 -1
- package/dist/shared-world-lab.d.ts +20 -1
- package/dist/shared-world-lab.js +197 -23
- package/dist/shared-world-lab.js.map +1 -1
- package/dist/terminal-agent-actor.d.ts +12 -7
- package/dist/terminal-agent-actor.js +18 -16
- package/dist/terminal-agent-actor.js.map +1 -1
- package/docs/architecture/actor-contract.md +32 -21
- package/docs/architecture/observer.md +15 -9
- package/docs/architecture/state-driven-executor.md +3 -3
- package/docs/architecture/terminal-product-lane.md +29 -25
- package/docs/assets/humanish-drawdb-hero.png +0 -0
- package/docs/contracts/adapter-fixtures.md +4 -2
- package/docs/contracts/core.md +9 -4
- package/docs/contracts/feedback.md +4 -2
- package/docs/contracts/policy.md +5 -3
- package/docs/contracts/run-bundle.md +24 -3
- package/docs/contracts/schemas.md +34 -23
- package/docs/goals/current.md +69 -20
- package/docs/ramp/README.md +32 -13
- package/docs/release/open-source-readiness.md +5 -4
- package/docs/release/public-readiness-standard.md +6 -1
- package/package.json +1 -1
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import type { ActorPersonaRef, ActorStatus, ActorCompletionReason, ActorTrace } from "./actor-contract.js";
|
|
2
|
-
/**
|
|
2
|
+
/**
|
|
3
|
+
* Backward-compatible fail-closed marker for the intentionally unsupported direct runner.
|
|
4
|
+
* The name is retained because it is already exported public API.
|
|
5
|
+
*/
|
|
3
6
|
export declare const TERMINAL_AGENT_NOT_IMPLEMENTED_CODE: "HUMANISH_TERMINAL_AGENT_NOT_IMPLEMENTED";
|
|
4
7
|
/**
|
|
5
8
|
* Options the engine hands the terminal agent session. The transport is the captured
|
|
6
9
|
* non-interactive exec stream (stdin disabled), NOT an interactive PTY — see ActorProtocol
|
|
7
|
-
* "terminal-exec" and the goal packet's PTY ruling.
|
|
8
|
-
*
|
|
10
|
+
* "terminal-exec" and the goal packet's PTY ruling. This compatibility shape documents the
|
|
11
|
+
* descriptor boundary; the route-owned live implementation composes equivalent inputs with the
|
|
12
|
+
* additional provider, policy, cap, and cleanup controls it needs.
|
|
9
13
|
*/
|
|
10
14
|
export interface TerminalAgentSessionOptions {
|
|
11
15
|
/** Where the session writes its native trace/transcript/event-stream artifacts. */
|
|
@@ -16,7 +20,7 @@ export interface TerminalAgentSessionOptions {
|
|
|
16
20
|
persona: ActorPersonaRef;
|
|
17
21
|
/** The product's declared PUBLIC surfaces (http(s) URLs / refs) — the only world the agent sees. */
|
|
18
22
|
publicSurfaces: string[];
|
|
19
|
-
/** Session wall-clock budget (also
|
|
23
|
+
/** Session wall-clock budget (the route also requires scenario.caps.maxMinutes). */
|
|
20
24
|
timeoutMs: number;
|
|
21
25
|
/** Per-run verdict nonce: the agent must echo it so replayed text can't forge the verdict. */
|
|
22
26
|
verdictNonce: string;
|
|
@@ -29,8 +33,9 @@ export interface TerminalAgentSessionResult {
|
|
|
29
33
|
trace: ActorTrace;
|
|
30
34
|
}
|
|
31
35
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
36
|
+
* Backward-compatible registry entry. Direct execution is intentionally unsupported: only the
|
|
37
|
+
* terminal-product lab route owns enough context to enforce command-scoped auth, caps, evidence
|
|
38
|
+
* capture, and by-id cleanup together. Fail closed instead of implying that the descriptor method
|
|
39
|
+
* itself runs the shipped live route.
|
|
35
40
|
*/
|
|
36
41
|
export declare function runTerminalAgentSession(_options: TerminalAgentSessionOptions): Promise<TerminalAgentSessionResult>;
|
|
@@ -1,23 +1,25 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
1
|
+
// Registry contract for the terminal-product lane. The shipped live implementation is
|
|
2
|
+
// intentionally route-owned by `runTerminalProductLab` in `e2b-terminal-lab.ts`: that route must
|
|
3
|
+
// coordinate sandbox creation, command-scoped runtime auth, caps, evidence capture, and by-id
|
|
4
|
+
// cleanup as one fail-closed lifecycle.
|
|
5
5
|
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
// `runTerminalAgentSession` remains exported because it was part of the public actor-descriptor
|
|
7
|
+
// shape before the route-owned lifecycle shipped. Its options cannot carry the host/provider
|
|
8
|
+
// controls needed to enforce that lifecycle, so direct calls are intentionally unsupported and
|
|
9
|
+
// fail closed. Use `runTerminalProductLab` (or `runLab` with a terminal-product config) for both
|
|
10
|
+
// dry-run and live execution.
|
|
11
|
+
/**
|
|
12
|
+
* Backward-compatible fail-closed marker for the intentionally unsupported direct runner.
|
|
13
|
+
* The name is retained because it is already exported public API.
|
|
14
|
+
*/
|
|
14
15
|
export const TERMINAL_AGENT_NOT_IMPLEMENTED_CODE = "HUMANISH_TERMINAL_AGENT_NOT_IMPLEMENTED";
|
|
15
16
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
17
|
+
* Backward-compatible registry entry. Direct execution is intentionally unsupported: only the
|
|
18
|
+
* terminal-product lab route owns enough context to enforce command-scoped auth, caps, evidence
|
|
19
|
+
* capture, and by-id cleanup together. Fail closed instead of implying that the descriptor method
|
|
20
|
+
* itself runs the shipped live route.
|
|
19
21
|
*/
|
|
20
22
|
export async function runTerminalAgentSession(_options) {
|
|
21
|
-
throw new Error(`${TERMINAL_AGENT_NOT_IMPLEMENTED_CODE}:
|
|
23
|
+
throw new Error(`${TERMINAL_AGENT_NOT_IMPLEMENTED_CODE}: direct runTerminalAgentSession calls are intentionally unsupported. Terminal execution is route-owned so the lab can enforce command-scoped runtime auth, caps, evidence capture, and by-id cleanup together. Use runTerminalProductLab or runLab with a terminal-product config.`);
|
|
22
24
|
}
|
|
23
25
|
//# sourceMappingURL=terminal-agent-actor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminal-agent-actor.js","sourceRoot":"","sources":["../src/terminal-agent-actor.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"terminal-agent-actor.js","sourceRoot":"","sources":["../src/terminal-agent-actor.ts"],"names":[],"mappings":"AAAA,sFAAsF;AACtF,iGAAiG;AACjG,8FAA8F;AAC9F,wCAAwC;AACxC,EAAE;AACF,gGAAgG;AAChG,6FAA6F;AAC7F,+FAA+F;AAC/F,iGAAiG;AACjG,8BAA8B;AAI9B;;;GAGG;AACH,MAAM,CAAC,MAAM,mCAAmC,GAAG,yCAAkD,CAAC;AAgCtG;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,QAAqC;IAErC,MAAM,IAAI,KAAK,CACb,GAAG,mCAAmC,qRAAqR,CAC5T,CAAC;AACJ,CAAC"}
|
|
@@ -1,27 +1,34 @@
|
|
|
1
1
|
# Actor Contract
|
|
2
2
|
|
|
3
|
-
Date: 2026-06-06 (updated 2026-
|
|
4
|
-
|
|
5
|
-
Status: accepted
|
|
6
|
-
`humanish.actor-trace.v1` (`src/actor-contract.ts`) and a
|
|
7
|
-
|
|
8
|
-
`
|
|
9
|
-
`actors[0].type` a
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
3
|
+
Date: 2026-06-06 (current-state note updated 2026-07-14)
|
|
4
|
+
|
|
5
|
+
Status: accepted contract with a partially open extension surface. Shipped:
|
|
6
|
+
the evidence schema `humanish.actor-trace.v1` (`src/actor-contract.ts`) and a
|
|
7
|
+
closed first-party registry of six descriptors (`src/actor-registry.ts`:
|
|
8
|
+
`codex-app-server`, `pi-agent-core`, `claude-agent-sdk`,
|
|
9
|
+
`openai-computer-use`, `scripted-browser`, `codex-exec`). `actors[0].type` is a
|
|
10
|
+
real dispatch key on the computer-use, scripted-browser, and terminal-product
|
|
11
|
+
routes. Product scoring, feedback, and artifact hooks are extension seams, but
|
|
12
|
+
public out-of-tree actor registration and its conformance certification are not
|
|
13
|
+
shipped. Also not shipped: the full `Actor.run(input)` interface,
|
|
14
|
+
`RedactionHooks` injection, `ApprovalPolicy`, `StagehandCuaActor`, and the
|
|
15
|
+
`persona-fidelity` verify check. Decision 6's capture-time screenshot stance
|
|
16
|
+
was recanted in 0.6.0; see the inline notes and the capture-vs-publish rule in
|
|
15
17
|
[`docs/principles/invariants-and-defaults.md`](../principles/invariants-and-defaults.md).
|
|
16
18
|
|
|
19
|
+
`codex-exec` is a real dispatch key for terminal-product labs, but the exported
|
|
20
|
+
descriptor `runSession` is a fail-closed compatibility entry. Live execution is
|
|
21
|
+
owned by `runTerminalProductLab`, which coordinates sandbox creation,
|
|
22
|
+
command-scoped runtime auth, evidence, caps, and by-id cleanup.
|
|
23
|
+
|
|
17
24
|
## Context
|
|
18
25
|
|
|
19
|
-
>
|
|
20
|
-
> accepted (one real actor, hardcoded dispatch).
|
|
21
|
-
>
|
|
26
|
+
> Historical context: this section describes the world as it stood when the
|
|
27
|
+
> design was accepted (one real actor, hardcoded dispatch). The current state is
|
|
28
|
+
> the six-descriptor first-party registry described in the status note above.
|
|
22
29
|
|
|
23
|
-
An actor is the thing that drives a persona scenario and produces evidence.
|
|
24
|
-
Humanish
|
|
30
|
+
An actor is the thing that drives a persona scenario and produces evidence. At
|
|
31
|
+
design time Humanish had exactly one real actor: the local Codex integration in
|
|
25
32
|
`src/codex-app-server.ts` (plus the `codex-exec` and `codex-tui` variants in
|
|
26
33
|
`src/run.ts`). The actor selection is a hardcoded `if (actor === ...)` dispatch,
|
|
27
34
|
`RunStream.codex` is Codex-shaped, and the evidence schema is
|
|
@@ -91,6 +98,9 @@ API surface.
|
|
|
91
98
|
|
|
92
99
|
## The contract
|
|
93
100
|
|
|
101
|
+
The excerpt below shows the central contract fields; exported source types are
|
|
102
|
+
authoritative.
|
|
103
|
+
|
|
94
104
|
```ts
|
|
95
105
|
export const ACTOR_TRACE_SCHEMA = "humanish.actor-trace.v1";
|
|
96
106
|
|
|
@@ -127,20 +137,21 @@ export interface ActorTraceItem {
|
|
|
127
137
|
export interface ActorCapabilities {
|
|
128
138
|
headless: boolean;
|
|
129
139
|
structuredTrace: boolean;
|
|
130
|
-
lanes: Array<"code" | "app" | "computer-use" | "scripted-browser">;
|
|
140
|
+
lanes: Array<"code" | "app" | "computer-use" | "scripted-browser" | "terminal">;
|
|
131
141
|
producesScreenshots: boolean;
|
|
132
142
|
byoModel: boolean;
|
|
133
143
|
preGrantableApprovals: boolean; // can run unattended without a human prompt
|
|
134
144
|
inProcessTools: boolean; // can inject product tools without a subprocess
|
|
135
145
|
license: "open" | "source-available" | "proprietary";
|
|
146
|
+
keyPlacement?: "external" | "in-sandbox-command-scoped";
|
|
136
147
|
}
|
|
137
148
|
|
|
138
149
|
export interface ActorTrace {
|
|
139
150
|
schema: typeof ACTOR_TRACE_SCHEMA;
|
|
140
|
-
provider: string; // "codex-app-server" | "pi-agent-core" | "claude-agent-sdk" | "openai-responses-cu" | "browser-persona"
|
|
151
|
+
provider: string; // e.g. "codex-app-server" | "pi-agent-core" | "claude-agent-sdk" | "openai-responses-cu" | "browser-persona" | "codex"
|
|
141
152
|
providerVersion?: string;
|
|
142
|
-
protocol: "json-rpc" | "json-stream" | "in-process-sdk" | "cua-loop" | "scripted-steps";
|
|
143
|
-
lane: "code" | "app" | "computer-use" | "scripted-browser";
|
|
153
|
+
protocol: "json-rpc" | "json-stream" | "in-process-sdk" | "cua-loop" | "scripted-steps" | "terminal-exec";
|
|
154
|
+
lane: "code" | "app" | "computer-use" | "scripted-browser" | "terminal";
|
|
144
155
|
persona: { id: string; traitsApplied: string[]; promptDigest: string }; // proves traits were threaded
|
|
145
156
|
// "raw" = full-fidelity frames retained (valid for LOCAL use; redact before
|
|
146
157
|
// publishing); "blurred"/"ocr_scrubbed" = publish-safe; "n/a" = none captured.
|
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
# Observer Architecture
|
|
2
2
|
|
|
3
|
-
Date: 2026-06-01
|
|
3
|
+
Date: 2026-06-01 (current-state note updated 2026-07-14)
|
|
4
4
|
|
|
5
|
-
Status: implemented for synthetic
|
|
6
|
-
|
|
5
|
+
Status: implemented for synthetic streams and persisted live browser,
|
|
6
|
+
terminal-product, fan-out, and sequential/concurrent shared-world evidence.
|
|
7
|
+
Plain computer-use and shared-world runs can publish an in-progress bundle to
|
|
8
|
+
an attached loopback Observer without persisting runtime stream-auth URLs. The
|
|
9
|
+
version-pinned README image is a synthetic technical sample, not real-application
|
|
10
|
+
proof.
|
|
7
11
|
|
|
8
12
|
## Decision
|
|
9
13
|
|
|
10
14
|
The Observer is a mission-control surface over durable run artifacts, not a
|
|
11
15
|
static report page.
|
|
12
16
|
|
|
13
|
-
Every run writes
|
|
17
|
+
Every run writes durable local evidence under `.humanish/runs/<run-id>/`. Active
|
|
18
|
+
runs refresh their bundle and Observer projection; later review, feedback, or
|
|
19
|
+
Observer commands may add derived artifacts:
|
|
14
20
|
|
|
15
21
|
```text
|
|
16
22
|
.humanish/runs/<run-id>/
|
|
@@ -25,7 +31,7 @@ Every run writes immutable local evidence under `.humanish/runs/<run-id>/`:
|
|
|
25
31
|
|
|
26
32
|
`run.json` remains the source bundle. `observer/observer-data.json` is the
|
|
27
33
|
normalized view model consumed by the Observer. `events.ndjson` is the appendable
|
|
28
|
-
event stream contract that live adapters
|
|
34
|
+
event stream contract that live adapters update while a run is active.
|
|
29
35
|
|
|
30
36
|
## Stream Model
|
|
31
37
|
|
|
@@ -95,12 +101,12 @@ A host adapter may provide:
|
|
|
95
101
|
If no embed URL exists, the Observer still renders the Codex-style timeline and
|
|
96
102
|
session contract instead of failing the lane.
|
|
97
103
|
|
|
98
|
-
##
|
|
104
|
+
## Historical slice and remaining gaps
|
|
99
105
|
|
|
100
|
-
|
|
101
|
-
|
|
106
|
+
The original 2026-06-01 slice implemented the Observer substrate and synthetic
|
|
107
|
+
stream contracts; local `codex-exec` active-run snapshots followed.
|
|
102
108
|
|
|
103
|
-
|
|
109
|
+
Subsequent additions through 2026-06-11 included:
|
|
104
110
|
|
|
105
111
|
- Playwright-backed browser proof with scripted, app-specific
|
|
106
112
|
`browser.steps` authored in `humanish/scenarios/*.yaml` (`src/run.ts`);
|
|
@@ -134,9 +134,9 @@ import { runLab, parseLabConfig, type CuaExecutor, type CuaProvider } from "huma
|
|
|
134
134
|
|
|
135
135
|
// local-app YAML (shareable; fails closed without hooks):
|
|
136
136
|
// schema: humanish.lab.v2
|
|
137
|
-
// id:
|
|
137
|
+
// id: downstream-local-app-state
|
|
138
138
|
// subject: { source: local-app, appUrl: http://localhost:5173 }
|
|
139
|
-
// actors: [{ type: openai-computer-use, persona:
|
|
139
|
+
// actors: [{ type: openai-computer-use, persona: curious-tester, mission: "…" }]
|
|
140
140
|
// scenario: { mode: live }
|
|
141
141
|
const parsed = parseLabConfig(yaml);
|
|
142
142
|
if (!parsed.ok) throw new Error(parsed.error.message);
|
|
@@ -199,5 +199,5 @@ Read every optional field defensively, and spread-omit optional fields
|
|
|
199
199
|
surface with no precedent in this repo (the scripted lane loads only declarative
|
|
200
200
|
YAML; serve commands run isolated inside the disposable E2B sandbox). It earns
|
|
201
201
|
its place only behind its own clamping / trust / digest-pinning design.
|
|
202
|
-
|
|
202
|
+
the validated library consumer does not need it: a caller builds the bridge in its own
|
|
203
203
|
trusted code (entry point 2 above).
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
# Terminal-product real-agent lane (issue #154)
|
|
2
2
|
|
|
3
|
-
Date: 2026-06-16
|
|
4
|
-
|
|
5
|
-
Status:
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
Date: 2026-06-16 (current-state note updated 2026-07-14)
|
|
4
|
+
|
|
5
|
+
Status: live terminal-product route shipped in `0.8.0`. The in-sandbox backend,
|
|
6
|
+
command-scoped credential placement, exact-id cleanup proof, an interventions ledger,
|
|
7
|
+
cost/no-spend ledger, caps, and product scoring/feedback hooks are implemented;
|
|
8
|
+
the kept 2026-07-09 live receipt verifies 15/15 checks and `share_ready` at a
|
|
9
|
+
`$0` cap. That capability receipt is not adopter replacement: no deletion
|
|
10
|
+
branch has yet removed the reference adopter's bespoke generic study harness.
|
|
11
|
+
See the ratified goal packet
|
|
9
12
|
([`docs/goals/terminal-product-lane/goal.md`](../goals/terminal-product-lane/goal.md))
|
|
10
13
|
for the full slice plan and the safety contract.
|
|
11
14
|
|
|
@@ -33,7 +36,7 @@ fail-closed cross-validation, and forward-declared warnings.
|
|
|
33
36
|
| `subject.product` | `{ name, publicSurfaces[] }` — the only world the agent sees |
|
|
34
37
|
| `execution.target` | `e2b-terminal` (or absent → implied) |
|
|
35
38
|
| `execution.terminal` | `{ transport: exec-stream, stdin: disabled }` |
|
|
36
|
-
| `execution.runtimeAuth` | `openai-env` (names-only evidence
|
|
39
|
+
| `execution.runtimeAuth` | `openai-env` (names-only durable evidence) |
|
|
37
40
|
| `scenario.caps` | `{ maxUsd, maxJobs, maxMinutes }` — the blast-radius budget |
|
|
38
41
|
| `policies` | `allowPrivateRepoAccess` / `allowProviderCredentials` / `allowPaymentCredentials` / `allowGitHubMutation`, all DEFAULT FALSE |
|
|
39
42
|
| `actors[0].type` | `codex-exec` — a registered terminal actor (`keyPlacement: in-sandbox-command-scoped`) |
|
|
@@ -54,16 +57,16 @@ blast radius is bounded by key scoping and budgets, not by hoping.*
|
|
|
54
57
|
|
|
55
58
|
The inversion is declared as registry metadata, not a code convention: the
|
|
56
59
|
terminal actor's capabilities carry `keyPlacement: "in-sandbox-command-scoped"`.
|
|
57
|
-
SLICE 1
|
|
58
|
-
key would go); SLICE 2's engine
|
|
60
|
+
SLICE 1 shipped the DECLARED field + value (the contract was honest about where
|
|
61
|
+
the key would go); SLICE 2's engine added command-scoped injection (only into the
|
|
59
62
|
per-command `envs` of the `codex` invocation, never `Sandbox.create({envs})`)
|
|
60
63
|
keyed off that capability, plus the deny-by-default credential allowlist, the
|
|
61
64
|
positive-allowlist sandbox metadata, the cleanup proof, the interventions ledger,
|
|
62
65
|
and a minimal fail-closed cap.
|
|
63
66
|
|
|
64
|
-
## SLICE 1 scope (DRY-RUN only
|
|
67
|
+
## Historical SLICE 1 scope (DRY-RUN only when shipped)
|
|
65
68
|
|
|
66
|
-
`runTerminalProductLab`
|
|
69
|
+
At SLICE 1, `runTerminalProductLab` implemented only the dry-run path: it built a valid
|
|
67
70
|
`humanish.run-bundle.v1` contract bundle, honestly labeled contract-only, with:
|
|
68
71
|
|
|
69
72
|
- the subject declared as a terminal-product with its public surfaces, provenance
|
|
@@ -76,22 +79,22 @@ and a minimal fail-closed cap.
|
|
|
76
79
|
- a terminal-kind stream that is an honest **contract placeholder**: stdin
|
|
77
80
|
disabled, empty tail, `transport: snapshot` — **not** `pty` (captured
|
|
78
81
|
non-interactive exec output is never an interactive PTY; invariant 6 + the
|
|
79
|
-
goal packet's PTY ruling). SLICE 2
|
|
82
|
+
goal packet's PTY ruling). SLICE 2 later added redacted exec-stream capture;
|
|
80
83
|
- empty/placeholder ledgers (substrate lifecycle, command log, terminal event
|
|
81
|
-
stream, interventions, cost) that SLICE 2/3
|
|
84
|
+
stream, interventions, cost) that SLICE 2/3 later filled.
|
|
82
85
|
|
|
83
|
-
The dry-run bundle
|
|
86
|
+
The dry-run bundle passed the existing `verifyRun`. Terminal-specific verifier
|
|
84
87
|
checks (terminal/transcript presence, lifecycle, cleanup, interventions,
|
|
85
|
-
metadata allowlist, no-credential-in-artifacts, no-spend)
|
|
88
|
+
metadata allowlist, no-credential-in-artifacts, no-spend) landed in SLICE 2/3.
|
|
86
89
|
|
|
87
|
-
|
|
88
|
-
failure
|
|
89
|
-
|
|
90
|
+
At SLICE 1, a non-dry-run call returned a structured
|
|
91
|
+
`HUMANISH_TERMINAL_AGENT_NOT_IMPLEMENTED` failure before launch or spend.
|
|
92
|
+
SLICE 2 implemented the real session.
|
|
90
93
|
|
|
91
94
|
The DI seams SLICE 2 needs (`loadModule`, `buildSandbox`, `runtimeAuthEnv`,
|
|
92
95
|
`detachedTimers`) are declared on `TerminalProductLabHooks` and threaded through
|
|
93
|
-
`RunLabOptions.terminalHooks`, mirroring `cuaHooks` / `scriptedHooks
|
|
94
|
-
|
|
96
|
+
`RunLabOptions.terminalHooks`, mirroring `cuaHooks` / `scriptedHooks`; only the
|
|
97
|
+
dry-run path was implemented in that slice.
|
|
95
98
|
|
|
96
99
|
## SLICE 4 — the product-adapter extension seam (layer 6)
|
|
97
100
|
|
|
@@ -130,12 +133,13 @@ any malformed score/candidate with a warning, and `verifyRun` re-checks the
|
|
|
130
133
|
surviving shapes — a bad extension never poisons a verifiable bundle. Proven by
|
|
131
134
|
`tests/terminal-product-adapter-seam.test.ts` (a thin in-repo example adapter
|
|
132
135
|
typing against the barrel only, registering a scorer, attaching namespaced nouns,
|
|
133
|
-
emitting a candidate; the bundle verifies).
|
|
134
|
-
not
|
|
136
|
+
emitting a candidate; the bundle verifies). At SLICE 4 this was contract proof,
|
|
137
|
+
not a live rung; the later end-to-end lane receipt is linked from the status
|
|
138
|
+
note.
|
|
135
139
|
|
|
136
|
-
The adopter's real scorecard is its OWN thin extension
|
|
137
|
-
|
|
138
|
-
SLICE 5.
|
|
140
|
+
The adopter's real scorecard is its OWN thin extension. The end-to-end lane's
|
|
141
|
+
live receipt is kept under the terminal-product goal, and true duplex PTY replay
|
|
142
|
+
is deferred to SLICE 5.
|
|
139
143
|
|
|
140
144
|
## The reference adopter (codename-neutral)
|
|
141
145
|
|
|
Binary file
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# Adapter Fixture Parity Contract
|
|
2
2
|
|
|
3
|
-
Date: 2026-06-02
|
|
3
|
+
Date: 2026-06-02 (current-state note updated 2026-07-14)
|
|
4
4
|
|
|
5
|
-
Status:
|
|
5
|
+
Status: committed contract fixtures with passing parity checks. A fixture
|
|
6
|
+
proves that core can carry an adapter-owned evidence shape; it does not prove a
|
|
7
|
+
live adopter integration or satisfy a deletion-branch depth phase.
|
|
6
8
|
|
|
7
9
|
## Purpose
|
|
8
10
|
|
package/docs/contracts/core.md
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
# Core Contract
|
|
2
2
|
|
|
3
|
-
Date: 2026-06-02
|
|
3
|
+
Date: 2026-06-02 (current-state note updated 2026-07-14)
|
|
4
4
|
|
|
5
|
-
Status:
|
|
5
|
+
Status: the listed primitives are shipped and tested. This document does not
|
|
6
|
+
claim that every producer already uses one centralized store: run identity,
|
|
7
|
+
history, and provider-resource lifecycle still span route-specific code and
|
|
8
|
+
remain consolidation work.
|
|
6
9
|
|
|
7
10
|
## Purpose
|
|
8
11
|
|
|
@@ -19,7 +22,9 @@ setup, or repository-specific proof language.
|
|
|
19
22
|
Core records must be safe to include in public run bundles by default:
|
|
20
23
|
|
|
21
24
|
- artifact paths are relative;
|
|
22
|
-
- run
|
|
25
|
+
- ids produced by the core run-id builder contain only lowercase letters,
|
|
26
|
+
numbers, and dashes; runtime readers separately accept existing IDs that are
|
|
27
|
+
any safe single path segment;
|
|
23
28
|
- git state summarizes status without branch names, remotes, file names, file
|
|
24
29
|
paths, or absolute working directories;
|
|
25
30
|
- lifecycle and timing records are explicit inputs, not inferred prose;
|
|
@@ -29,7 +34,7 @@ Core records must be safe to include in public run bundles by default:
|
|
|
29
34
|
|
|
30
35
|
| Primitive | Contract |
|
|
31
36
|
| --- | --- |
|
|
32
|
-
| Run id |
|
|
37
|
+
| Run id | The core builder is deterministic from explicit prefix, timestamp, and entropy, and emits ids matching `^[a-z0-9][a-z0-9-]{0,127}$`. Runtime artifact binding uses the broader compatibility rule in `src/run-paths.ts`: one non-empty segment, excluding `.`, `..`, separators, and NUL. |
|
|
33
38
|
| Artifact layout | Builds stable relative pointers under `.humanish/runs/<run-id>/` plus `.humanish/runs/latest.json`. |
|
|
34
39
|
| Latest pointer | `{ schema, runId, path, updatedAt }` using `humanish.latest-run.v1`. |
|
|
35
40
|
| History entry | `{ schema, runId, createdAt, mode, path }` using `humanish.run-history-entry.v1`. |
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# Feedback Contract
|
|
2
2
|
|
|
3
|
-
Date: 2026-06-01
|
|
3
|
+
Date: 2026-06-01 (current-state note updated 2026-07-14)
|
|
4
4
|
|
|
5
|
-
Status:
|
|
5
|
+
Status: local feedback candidate, draft, verification, Markdown, and issue-URL
|
|
6
|
+
generation are shipped. These commands do not mutate GitHub, and public output
|
|
7
|
+
fails closed unless the run verifies as `share_ready`.
|
|
6
8
|
|
|
7
9
|
## Purpose
|
|
8
10
|
|
package/docs/contracts/policy.md
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
# Policy Contract
|
|
2
2
|
|
|
3
|
-
Date: 2026-06-02
|
|
3
|
+
Date: 2026-06-02 (current-state note updated 2026-07-14)
|
|
4
4
|
|
|
5
|
-
Status:
|
|
6
|
-
assisted-run boundaries.
|
|
5
|
+
Status: shipped policy reference for credential, network, spend, redaction,
|
|
6
|
+
sharing, and assisted-run boundaries. Support remains route-specific; the
|
|
7
|
+
parser, route validation, and verifier determine whether a declared field is
|
|
8
|
+
consumed, rejected, or reported as a warning.
|
|
7
9
|
|
|
8
10
|
Safety amendment (2026-07-14): beginning with `0.15.1`, stored provider IDs are
|
|
9
11
|
evidence and never authorize core provider mutation. The bundled OSS meta-lab
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
# Run Bundle Contract
|
|
2
2
|
|
|
3
|
-
Date: 2026-06-02
|
|
3
|
+
Date: 2026-06-02 (current-state note updated 2026-07-14)
|
|
4
4
|
|
|
5
|
-
Status:
|
|
6
|
-
|
|
5
|
+
Status: `humanish.run-bundle.v1` is the shipped evidence contract. The
|
|
6
|
+
TypeScript shape and fail-closed verification in `src/run.ts` are
|
|
7
|
+
authoritative; this document explains the stable public fields and extension
|
|
8
|
+
rules rather than independently versioning the runtime.
|
|
7
9
|
|
|
8
10
|
## Purpose
|
|
9
11
|
|
|
@@ -77,6 +79,25 @@ Persisted `run.json` files must not contain absolute local target paths. Runtime
|
|
|
77
79
|
commands may return the caller's working directory in process-local JSON
|
|
78
80
|
responses, but durable run bundles use the public-safe `[target-cwd]` marker.
|
|
79
81
|
|
|
82
|
+
## Hosted Desktop Geometry
|
|
83
|
+
|
|
84
|
+
Hosted browser streams may carry additive `desktopGeometry` evidence. Its fields keep four
|
|
85
|
+
different facts separate:
|
|
86
|
+
|
|
87
|
+
- `screen.requested`: the E2B/X screen size requested by config;
|
|
88
|
+
- `screen.verified`: the screen size measured in-sandbox with `xdpyinfo`;
|
|
89
|
+
- `browserWindow`: outer browser bounds measured after the window-fill attempt;
|
|
90
|
+
- `viewport`: the page's CSS layout viewport and device-pixel ratio measured through CDP on
|
|
91
|
+
Chromium-family hosted browsers.
|
|
92
|
+
|
|
93
|
+
For new hosted-desktop computer-use bundles, `stream.viewport` mirrors the measured
|
|
94
|
+
`desktopGeometry.viewport`; it is omitted when runtime measurement is unavailable. It is never
|
|
95
|
+
filled from the requested screen size. Dry-run bundles therefore carry the requested screen but
|
|
96
|
+
no verified screen, browser bounds, or viewport. Historical bundles remain loadable and may
|
|
97
|
+
contain the older requested-screen `stream.viewport` shape without `desktopGeometry`.
|
|
98
|
+
Deterministic Playwright-style adapters remain free to declare a viewport that they also render
|
|
99
|
+
exactly; this hosted-desktop rule does not change that contract.
|
|
100
|
+
|
|
80
101
|
## Subject Provenance
|
|
81
102
|
|
|
82
103
|
`subject` is an optional, additive top-level field: structured provenance for
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# Contract Schema Index
|
|
2
2
|
|
|
3
|
-
Date: 2026-06-02 (updated 2026-
|
|
3
|
+
Date: 2026-06-02 (current-state note updated 2026-07-14)
|
|
4
4
|
|
|
5
|
-
Status:
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
Status: reference map for the major contracts shipped through source version
|
|
6
|
+
`0.16.0`; it is not an exhaustive inventory of command/result envelopes. Exported types,
|
|
7
|
+
schema constants, parsers, and validators in `src/` are authoritative. Rows
|
|
8
|
+
marked "reserved" name layering intent only — no code emits or validates them
|
|
9
|
+
yet. Do not emit a reserved schema.
|
|
8
10
|
|
|
9
11
|
## Purpose
|
|
10
12
|
|
|
@@ -110,9 +112,13 @@ A lab is a composition over code primitives, not a hardcoded kind:
|
|
|
110
112
|
appear in `subject.env`) pointing at state the lab does not control,
|
|
111
113
|
recorded as UNPINNED in provenance. Commands persist in evidence as
|
|
112
114
|
sha256-16 digests only, never as text;
|
|
113
|
-
- `actors`: who drives it. On
|
|
114
|
-
`actors[0].type` is a real
|
|
115
|
-
|
|
115
|
+
- `actors`: who drives it. On computer-use (including shared-world),
|
|
116
|
+
scripted-browser, and terminal-product routes, `actors[0].type` is a real
|
|
117
|
+
dispatch key resolved against the actor registry. On synthetic and meta-lab
|
|
118
|
+
routes it remains a descriptive label (e.g. `synthetic-persona`). The
|
|
119
|
+
`codex-exec` descriptor's direct `runSession` member is a fail-closed
|
|
120
|
+
compatibility entry, not the live runner; the terminal-product lab route
|
|
121
|
+
owns the live sandbox, auth, cap, evidence, and cleanup lifecycle.
|
|
116
122
|
`actors[0].count` carries route-specific meanings: synthetic route lane
|
|
117
123
|
count (simCount); scripted-browser route surface roster (1 = desktop,
|
|
118
124
|
2 = desktop + mobile, default 1); computer-use **E2B** route the HOMOGENEOUS
|
|
@@ -188,12 +194,14 @@ A lab is a composition over code primitives, not a hardcoded kind:
|
|
|
188
194
|
`terminal.transport` is `exec-stream` — captured NON-interactive exec output
|
|
189
195
|
(stdin disabled); `pty` is rejected because labeling captured exec output as
|
|
190
196
|
an interactive PTY would overstate the mechanism (invariant 6; a true duplex
|
|
191
|
-
PTY transport
|
|
197
|
+
PTY transport does not ship). `terminal.stdin` defaults to `disabled`
|
|
192
198
|
(`sent`/assisted input is rejected until the interventions ledger + a
|
|
193
199
|
non-comparable marker exist). `runtimeAuth: openai-env` declares the agent's
|
|
194
|
-
runtime-auth channel — recorded as NAMES ONLY
|
|
195
|
-
|
|
196
|
-
|
|
200
|
+
runtime-auth channel — recorded as NAMES ONLY. On a live run, the engine
|
|
201
|
+
resolves the registered terminal descriptor and requires
|
|
202
|
+
`keyPlacement: in-sandbox-command-scoped` before creating a sandbox. The key
|
|
203
|
+
is passed only to the agent command, never to `Sandbox.create` or metadata;
|
|
204
|
+
a dry-run neither reads nor injects it;
|
|
197
205
|
- `scenario`: `mode: dry-run` (contract evidence, no spend) or `live`.
|
|
198
206
|
`scenario.ref` is CONSUMED (and REQUIRED) on the scripted-browser route: it
|
|
199
207
|
resolves a committed scenario (`humanish/scenarios/<ref>.yaml` or a repo
|
|
@@ -483,9 +491,10 @@ world ("M of N"); PROVEN CONCURRENCY (overlapping windows); and system-state evo
|
|
|
483
491
|
under load (the stateSeries) with best-effort temporal correlation. It CANNOT claim
|
|
484
492
|
strict causal attribution of a delta to an actor (concurrent ⇒ ambiguous), determinism
|
|
485
493
|
of exact state, per-action granularity, or concurrency-SAFETY (races are OBSERVED, never
|
|
486
|
-
PROVEN absent). HONESTY: the deterministic $0 gate proves the plumbing + the
|
|
487
|
-
contract
|
|
488
|
-
|
|
494
|
+
PROVEN absent). HONESTY: the deterministic $0 gate proves the plumbing + the
|
|
495
|
+
attribution contract. A kept 2026-06-17 live receipt separately proves one
|
|
496
|
+
bounded three-persona trial against a synthetic plane. Neither the deterministic
|
|
497
|
+
gate nor that receipt proves scale, repeatability, or adopter-harness replacement.
|
|
489
498
|
|
|
490
499
|
## Adapter
|
|
491
500
|
|
|
@@ -639,27 +648,29 @@ inside run bundles (per-stream transport and status) and lab execution config
|
|
|
639
648
|
|
|
640
649
|
## Terminal Cost Ledger And No-Spend Proof
|
|
641
650
|
|
|
642
|
-
The terminal-product lane (`src/e2b-terminal-lab.ts`)
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
651
|
+
The terminal-product lane (`src/e2b-terminal-lab.ts`) passes a real provider key
|
|
652
|
+
only to the in-sandbox agent command, never to sandbox-global env or metadata,
|
|
653
|
+
so the no-spend claim must be REAL — derived from a ledger, never asserted. The
|
|
654
|
+
live run writes both to `terminal-ledgers.json` (a `cost` block + a
|
|
655
|
+
`noSpendProof` block, additive to `humanish.terminal-ledgers.v1`).
|
|
646
656
|
|
|
647
657
|
The cost ledger (`humanish.terminal-cost-ledger.v1`) has one line per category —
|
|
648
658
|
`product`, `media`, `payment`, `provider` — and follows a strict **null
|
|
649
659
|
discipline** that distinguishes three states and never conflates them:
|
|
650
660
|
|
|
651
661
|
- `usd: 0` — **known zero**: the category was metered and billed nothing.
|
|
652
|
-
- `usd: null` — **not measured**: no spend signal exists for the category
|
|
653
|
-
|
|
662
|
+
- `usd: null` — **not measured**: no spend signal exists for the category on
|
|
663
|
+
this run. `null` is written explicitly (never `undefined`-omitted, never guessed
|
|
654
664
|
to `0`). A line with `null` says "this category exists but we did not measure
|
|
655
665
|
it"; the no-spend proof reports it as unmeasured and does NOT claim it is zero.
|
|
656
666
|
- line **absent** — **not applicable** (n/a) to the lane/run.
|
|
657
667
|
|
|
658
668
|
`knownTotalUsd` sums ONLY the non-null lines (a `null` line contributes nothing
|
|
659
669
|
and is never coerced to `0`); `fullyMeasured` is true only when no line is null.
|
|
660
|
-
|
|
661
|
-
`tokenUsage.costUsd` when present (else `null`); `product`/`media`/`payment`
|
|
662
|
-
`null`
|
|
670
|
+
Core meters only the `provider` line, populated from the actor trace's
|
|
671
|
+
`tokenUsage.costUsd` when present (else `null`); `product`/`media`/`payment`
|
|
672
|
+
remain `null` unless an adapter supplies those signals through the shipped
|
|
673
|
+
cost-probe seam.
|
|
663
674
|
|
|
664
675
|
```yaml
|
|
665
676
|
schema: humanish.terminal-cost-ledger.v1
|