humanish 0.111.1 → 0.111.3
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/ARCHITECTURE.md +1 -1
- package/CHANGELOG.md +29 -0
- package/dist/cli/commands/study-route-computer-use.js +3 -8
- package/dist/cli/commands/study-route-preview.js +4 -6
- package/dist/cli/commands/study-route-shared-world.js +6 -7
- package/dist/evidence/redaction.d.ts +2 -2
- package/dist/evidence/redaction.js +3 -3
- package/dist/observer-app.html +6 -6
- package/dist/routes/computer-use/bundle-parts.d.ts +1 -32
- package/dist/routes/computer-use/bundle-parts.js +5 -92
- package/dist/routes/computer-use/e2b-desktop/prepare.js +11 -4
- package/dist/routes/computer-use/fanout-bundle.js +3 -2
- package/dist/routes/computer-use/live-phase.js +3 -7
- package/dist/routes/computer-use/participant-deps.d.ts +46 -0
- package/dist/routes/computer-use/participant-deps.js +48 -0
- package/dist/routes/computer-use/participant-facts.d.ts +5 -4
- package/dist/routes/computer-use/participant-facts.js +37 -2
- package/dist/routes/computer-use/participant-feedback.d.ts +33 -0
- package/dist/routes/computer-use/participant-feedback.js +92 -0
- package/dist/routes/computer-use/participant-model.d.ts +11 -0
- package/dist/routes/computer-use/participant-model.js +15 -0
- package/dist/routes/computer-use/preflight.js +33 -65
- package/dist/routes/computer-use/result.js +13 -52
- package/dist/routes/computer-use/route.js +6 -7
- package/dist/routes/computer-use/setup.d.ts +2 -6
- package/dist/routes/computer-use/setup.js +47 -93
- package/dist/routes/computer-use/single-bundle.js +3 -2
- package/dist/routes/computer-use/types.d.ts +2 -2
- package/dist/routes/preview.js +2 -8
- package/dist/routes/scripted/bundle.d.ts +2 -6
- package/dist/routes/scripted/result.d.ts +2 -1
- package/dist/routes/scripted/result.js +4 -4
- package/dist/routes/scripted/route.js +13 -38
- package/dist/routes/scripted/setup.d.ts +2 -1
- package/dist/routes/scripted/setup.js +21 -28
- package/dist/routes/scripted/subject.d.ts +3 -18
- package/dist/routes/scripted/subject.js +22 -78
- package/dist/routes/scripted/types.d.ts +2 -2
- package/dist/routes/shared-world/bundle.js +36 -1
- package/dist/routes/shared-world/comms.d.ts +2 -1
- package/dist/routes/shared-world/comms.js +3 -7
- package/dist/routes/shared-world/handoff.d.ts +2 -2
- package/dist/routes/shared-world/handoff.js +1 -1
- package/dist/routes/shared-world/participant-specs.d.ts +4 -5
- package/dist/routes/shared-world/participant-specs.js +19 -25
- package/dist/routes/shared-world/plan.js +11 -7
- package/dist/routes/shared-world/provisioned.d.ts +2 -1
- package/dist/routes/shared-world/provisioned.js +37 -80
- package/dist/routes/shared-world/result.js +17 -35
- package/dist/routes/shared-world/route.js +33 -36
- package/dist/routes/shared-world/setup.d.ts +2 -3
- package/dist/routes/shared-world/setup.js +11 -29
- package/dist/routes/shared-world/types.d.ts +6 -15
- package/dist/routes/terminal/dry-run.js +14 -24
- package/dist/routes/terminal/live-finish.d.ts +0 -1
- package/dist/routes/terminal/live-finish.js +2 -2
- package/dist/routes/terminal/route.js +9 -15
- package/dist/routes/terminal/session.d.ts +2 -3
- package/dist/routes/terminal/session.js +28 -40
- package/dist/routes/terminal/trace.d.ts +1 -1
- package/dist/routes/terminal/types.d.ts +2 -2
- package/dist/run/run.d.ts +55 -1
- package/dist/run/run.js +38 -2
- package/dist/run/secrets.d.ts +22 -0
- package/dist/run/secrets.js +33 -0
- package/dist/run/study-result.d.ts +34 -0
- package/dist/run/study-result.js +16 -0
- package/dist/study/requirements.d.ts +60 -5
- package/dist/study/requirements.js +88 -2
- package/dist/study/run-study-events.d.ts +4 -3
- package/dist/study/run-study-events.js +9 -14
- package/dist/study/run-study-options.d.ts +4 -1
- package/dist/study/run-study-options.js +22 -32
- package/dist/substrates/e2b/subject-sandbox.d.ts +58 -0
- package/dist/substrates/e2b/subject-sandbox.js +94 -0
- package/docs/contracts/core.md +5 -4
- package/docs/contracts/feedback.md +12 -5
- package/package.json +1 -1
package/ARCHITECTURE.md
CHANGED
|
@@ -129,7 +129,7 @@ comments name an invariant by its rule.
|
|
|
129
129
|
| The run bundle is the source of truth, and the Observer derives from it | `verifyRun` grades only `run.json` and its artifacts (`src/verify/verify.ts`). It reads `status.json` and the sandbox and reclaim receipts only for the `RUN_NOT_FINISHED` warning (`runNotFinished` in `src/verify/liveness.ts`), which changes no check and no grade. `buildObserverData` takes the bundle (`src/observer/data.ts`) | `tests/observer/data-contract.test.ts`; `tests/verify/run-not-finished.test.ts` checks that the grades are the same when `status.json` contradicts the bundle or is gone; `docs/decisions/0001-run-bundle-is-the-source-of-truth.md` |
|
|
130
130
|
| Unsupported execution is refused before side effects | `parseStudy` (`src/study/config.ts`), `taskProtocolValidationReason` (`src/study/validation.ts`), `planComputerUseStudy` (`src/routes/computer-use/plan.ts`) | `tests/admission/library.test.ts` checks each library refusal for a run directory, a desktop module load, a caller executor or provider, and a subprocess; `tests/admission/cli.test.ts` checks each CLI refusal for a run directory, a started process and a scorer's host code; `tests/study/task-route-preflight.test.ts`; `pnpm cli:preflight:test` runs `scripts/task-route-preflight-proof.mjs` with `tests/fixtures/task-route-preflight/deny-side-effects.mjs` preloaded |
|
|
131
131
|
| A sandbox id is recorded before any work runs in it | `acquireE2BDesktopSandbox` and `acquireE2BShellSandbox` (`src/substrates/e2b/sandbox.ts`) tag the sandbox with its run's owner tags, register the create with `beginSandboxCreate` (`src/run/sandbox-creates.ts`) and write the receipt before they return the handle, and every route that creates a sandbox calls them; `reclaimRunSandboxes` (`src/run/reclaim.ts`) switches on the receipt's provider, kills by exact id and by the run's exact tags | `tests/substrates/e2b/sandbox.test.ts`, which also checks that `Sandbox.create` has one call site in `src/`, `tests/routes/terminal/acquisition-boundary.test.ts`, `tests/run/reclaim.test.ts`; `tests/routes/scripted/route.test.ts` checks create, receipt, then first work |
|
|
132
|
-
| Bundles carry no secrets | `redactText` and `scrubLiterals` (`src/evidence/redaction.ts`); `scanRunPublicSafetyArtifacts` (`src/verify/artifacts.ts`); `buildShareSafety` (`src/verify/verify.ts`) grades `share_ready`, `local_only` or `blocked`
|
|
132
|
+
| Bundles carry no secrets | `redactText` and `scrubLiterals` (`src/evidence/redaction.ts`); `RunSecrets` (`src/run/secrets.ts`) holds the literal values each run scrubs; `scanRunPublicSafetyArtifacts` (`src/verify/artifacts.ts`); `buildShareSafety` (`src/verify/verify.ts`) grades `share_ready`, `local_only` or `blocked` | `tests/evidence/redaction-hooks.test.ts`, `tests/routes/known-secrets.test.ts`, `tests/run/transient-comms-secrets.test.ts`, `tests/verify/evidence-refs.test.ts` |
|
|
133
133
|
| Goldens pin route output | `runDirSnapshot` (`tests/helpers/run-golden.ts`) snapshots a whole run folder | `tests/golden/routes/`, `tests/golden/observer-data/`, `tests/golden/labs/`; `tests/study/plan-lab.test.ts` checks that every `StudyRoute` has a dry-run golden |
|
|
134
134
|
| A run is closed on every exit, only a published run is analyzed, and `latest.json` moves only after its run is published | `runScope` and `FinishedRun` (`src/run/run.ts`); `completeAutomaticAnalysis` requires an issued `FinishedRun` for the result's run; `Run.finish` writes `latest.json` last through `writePreparedRunLatestPointer` (`src/run/contained-output.ts`) | `tests/run/run-lifecycle.test.ts`, which also checks that `src/run/run.ts` is the pointer's one writer, `tests/analysis/automatic-analysis.test.ts` |
|
|
135
135
|
|
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,35 @@ The Unreleased section holds the full notes for the next version until it is tag
|
|
|
8
8
|
|
|
9
9
|
## Unreleased
|
|
10
10
|
|
|
11
|
+
## 0.111.3: Shared-world feedback candidates, scripted E2B key scrubbed, subject sandbox warnings (2026-10-06)
|
|
12
|
+
|
|
13
|
+
humanish 0.111.3 gives shared-world runs feedback candidates and repairs seven places where one
|
|
14
|
+
route's warnings, refusals, secret scrubbing or run directory checks differed from the other
|
|
15
|
+
routes'. A shared-world participant who reports friction or gives up becomes a candidate that
|
|
16
|
+
`humanish feedback` drafts, and each candidate from a run with several participants shows that
|
|
17
|
+
participant's own instructions as `expected`. A scripted run scrubs the value of `E2B_API_KEY` from
|
|
18
|
+
the errors and subject setup output it records, and writes `[REDACTED_SECRET]` where it wrote
|
|
19
|
+
`[redacted]`. A shared-world study with `caps.maxUsd` and no `caps.maxTotalUsd` warns that the cap
|
|
20
|
+
applies to each participant. The subject sandbox of a scripted clone study or a provisioned
|
|
21
|
+
shared-world study warns when its create was retried or E2B reports no size. A scripted clone study
|
|
22
|
+
missing a `subject.env` value, and a provisioned shared-world study missing `OPENAI_API_KEY`,
|
|
23
|
+
refuse with the wording computer use gives. Computer-use and shared-world runs check the run
|
|
24
|
+
directory again after a `prepareDesktop` hook and an Observer render.
|
|
25
|
+
|
|
26
|
+
[Release notes](https://github.com/danielgwilson/humanish/releases/tag/v0.111.3)
|
|
27
|
+
|
|
28
|
+
## 0.111.2: A taller Observer frame, even grid cards, a notice when the server stops (2026-10-06)
|
|
29
|
+
|
|
30
|
+
humanish 0.111.2 changes the Observer and nothing else. The focus view's heading line holds the
|
|
31
|
+
Back button, the participant pager, the name, the status and the inspector toggle, and the assigned
|
|
32
|
+
task and participant background move into the Details tab, so the frame at 1600x1000 is 171 px
|
|
33
|
+
taller. Every grid card has a 44 px caption, so phone-sized and desktop cards in one row end at the
|
|
34
|
+
same height. An open Observer page whose server stopped shows one notice with the run id and two
|
|
35
|
+
ways back to the recording, where 0.111.1 showed "Frame unavailable" on every tile. The CLI, the
|
|
36
|
+
library and the study routes are the same as in 0.111.1.
|
|
37
|
+
|
|
38
|
+
[Release notes](https://github.com/danielgwilson/humanish/releases/tag/v0.111.2)
|
|
39
|
+
|
|
11
40
|
## 0.111.1: E2B URLs in study URLs, fan-out dry runs verify, zero-data-retention cache holds (2026-10-06)
|
|
12
41
|
|
|
13
42
|
humanish 0.111.1 fixes a study URL refusal and two verify problems that an adopter met on 0.111.0,
|
|
@@ -12,7 +12,7 @@ import { exposureRequestFromOptions, followDecision, followObserver, planObserve
|
|
|
12
12
|
import { writeRunFindings } from "../findings.js";
|
|
13
13
|
import { formatCuaStudyHuman } from "./study-format.js";
|
|
14
14
|
import { resolveRouteShouldOpen } from "./study-route-open.js";
|
|
15
|
-
import {
|
|
15
|
+
import { refusedResult } from "../../run/study-result.js";
|
|
16
16
|
import { declaredParticipantCount } from "../../study/study-fields.js";
|
|
17
17
|
/**
|
|
18
18
|
* The computer-use route's CLI setup: its settings, the watch and exposure plan, the runStudyWith options
|
|
@@ -51,17 +51,12 @@ export function computerUseRouteRun(args) {
|
|
|
51
51
|
};
|
|
52
52
|
}
|
|
53
53
|
function refuseCua(args, dryRun, code, message) {
|
|
54
|
-
const result = {
|
|
55
|
-
...studyResultIdentity("computer-use", args.config.id),
|
|
56
|
-
ok: false,
|
|
57
|
-
cwd: args.options.cwd,
|
|
54
|
+
const result = refusedResult("computer-use", { studyId: args.config.id, cwd: args.options.cwd, error: { code, message } }, {
|
|
58
55
|
actor: args.config.actor?.type ?? "",
|
|
59
56
|
appUrl: "",
|
|
60
57
|
dryRun,
|
|
61
58
|
runId: args.options.runId ?? "not-created",
|
|
62
|
-
|
|
63
|
-
error: { code, message },
|
|
64
|
-
};
|
|
59
|
+
});
|
|
65
60
|
writeResult(args.command, args.io, result, formatCuaStudyHuman);
|
|
66
61
|
args.io.setExitCode(2);
|
|
67
62
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
|
-
import {
|
|
2
|
+
import { refusedResult } from "../../run/study-result.js";
|
|
3
3
|
import { formatRunHuman, parseStudyCount, writeResult, } from "../io.js";
|
|
4
4
|
import { planObserver, showObserver, staticObserverOpen } from "../observer-follow.js";
|
|
5
5
|
import { declaredParticipantCount } from "../../study/study-fields.js";
|
|
@@ -10,16 +10,14 @@ import { declaredParticipantCount } from "../../study/study-fields.js";
|
|
|
10
10
|
export function previewRouteRun(args) {
|
|
11
11
|
const participantCount = parseStudyCount(args.options.count, declaredParticipantCount(args.config) ?? 4);
|
|
12
12
|
if (participantCount === null) {
|
|
13
|
-
const result = {
|
|
14
|
-
|
|
15
|
-
ok: false,
|
|
13
|
+
const result = refusedResult("preview", {
|
|
14
|
+
studyId: args.config.id,
|
|
16
15
|
cwd: args.options.cwd,
|
|
17
|
-
warnings: [],
|
|
18
16
|
error: {
|
|
19
17
|
code: "HUMANISH_INVALID_PARTICIPANT_COUNT",
|
|
20
18
|
message: "--count must be a positive integer.",
|
|
21
19
|
},
|
|
22
|
-
};
|
|
20
|
+
}, {});
|
|
23
21
|
writeResult(args.command, args.io, result, formatRunHuman);
|
|
24
22
|
args.io.setExitCode(2);
|
|
25
23
|
return undefined;
|
|
@@ -9,7 +9,7 @@ import { followDecision, followObserver, showObserver, staticObserverOpen, withO
|
|
|
9
9
|
import { writeRunFindings } from "../findings.js";
|
|
10
10
|
import { formatConcurrentSharedWorldStudyHuman } from "./study-format.js";
|
|
11
11
|
import { resolveRouteShouldOpen, watchFinishedPlan } from "./study-route-open.js";
|
|
12
|
-
import {
|
|
12
|
+
import { refusedResult } from "../../run/study-result.js";
|
|
13
13
|
import { participantList } from "../../study/study-fields.js";
|
|
14
14
|
/**
|
|
15
15
|
* The shared-world route's CLI setup: dry run, open and follow semantics, the live Observer server
|
|
@@ -30,10 +30,11 @@ export function sharedWorldRouteRun(args) {
|
|
|
30
30
|
followDecision({ wantsMachine, detach: args.options.detach, serve: args.options.serve }).follow;
|
|
31
31
|
const port = parseObserverPort(args.options.port ?? "0");
|
|
32
32
|
const failConcurrent = (message, runId) => {
|
|
33
|
-
const result = {
|
|
34
|
-
|
|
35
|
-
ok: false,
|
|
33
|
+
const result = refusedResult("shared-world", {
|
|
34
|
+
studyId: args.config.id,
|
|
36
35
|
cwd: args.options.cwd,
|
|
36
|
+
error: { code: "HUMANISH_SHARED_WORLD_FAILED", message },
|
|
37
|
+
}, {
|
|
37
38
|
actor: args.config.actor?.type ?? "",
|
|
38
39
|
topology: "shared-world",
|
|
39
40
|
topologyMode: "concurrent",
|
|
@@ -42,9 +43,7 @@ export function sharedWorldRouteRun(args) {
|
|
|
42
43
|
dryRun,
|
|
43
44
|
runId: runId ?? args.options.runId ?? "not-created",
|
|
44
45
|
roles: [],
|
|
45
|
-
|
|
46
|
-
error: { code: "HUMANISH_SHARED_WORLD_FAILED", message },
|
|
47
|
-
};
|
|
46
|
+
});
|
|
48
47
|
writeResult(args.command, args.io, result, formatConcurrentSharedWorldStudyHuman);
|
|
49
48
|
args.io.setExitCode(2);
|
|
50
49
|
};
|
|
@@ -112,11 +112,11 @@ export interface RedactionHooks {
|
|
|
112
112
|
/** The default hooks wired into every actor: redaction.ts is the source of truth. */
|
|
113
113
|
export declare const defaultRedactionHooks: RedactionHooks;
|
|
114
114
|
/**
|
|
115
|
-
* Replace each literal value with
|
|
115
|
+
* Replace each literal value with `marker`. For values that have no secret shape to
|
|
116
116
|
* pattern-match, such as provisioned keys and subject env values. `values` is read on each call,
|
|
117
117
|
* so a value registered later is scrubbed too.
|
|
118
118
|
*/
|
|
119
|
-
export declare function scrubLiterals(values: readonly string[]): (text: string) => string;
|
|
119
|
+
export declare function scrubLiterals(values: readonly string[], marker?: string): (text: string) => string;
|
|
120
120
|
/**
|
|
121
121
|
* Coerce an unknown thrown value to its message string. Prefer this over the
|
|
122
122
|
* inline `error instanceof Error ? error.message : String(error)` so error
|
|
@@ -522,12 +522,12 @@ function blurPass(src, width, height, radius, horizontal) {
|
|
|
522
522
|
return out;
|
|
523
523
|
}
|
|
524
524
|
/**
|
|
525
|
-
* Replace each literal value with
|
|
525
|
+
* Replace each literal value with `marker`. For values that have no secret shape to
|
|
526
526
|
* pattern-match, such as provisioned keys and subject env values. `values` is read on each call,
|
|
527
527
|
* so a value registered later is scrubbed too.
|
|
528
528
|
*/
|
|
529
|
-
export function scrubLiterals(values) {
|
|
530
|
-
return (text) => values.reduce((current, value) => current.split(value).join(
|
|
529
|
+
export function scrubLiterals(values, marker = "[REDACTED_SECRET]") {
|
|
530
|
+
return (text) => values.reduce((current, value) => current.split(value).join(marker), text);
|
|
531
531
|
}
|
|
532
532
|
/**
|
|
533
533
|
* Coerce an unknown thrown value to its message string. Prefer this over the
|