humanish 0.114.0 → 0.115.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/CONTEXT.md +1 -1
  3. package/dist/actors/closing-report-limits.d.ts +11 -0
  4. package/dist/actors/closing-report-limits.js +13 -0
  5. package/dist/actors/closing-report.d.ts +68 -0
  6. package/dist/actors/closing-report.js +55 -0
  7. package/dist/actors/codex/restricted-participant-policy.d.ts +4 -47
  8. package/dist/actors/codex/restricted-participant-policy.js +12 -40
  9. package/dist/actors/computer-use/loop/debrief.d.ts +1 -10
  10. package/dist/actors/computer-use/loop/debrief.js +10 -46
  11. package/dist/actors/computer-use/loop/impressions.d.ts +2 -2
  12. package/dist/actors/computer-use/loop/impressions.js +6 -1
  13. package/dist/actors/computer-use/loop.d.ts +0 -1
  14. package/dist/actors/computer-use/loop.js +3 -3
  15. package/dist/actors/computer-use/openai-conversation.d.ts +1 -1
  16. package/dist/actors/computer-use/openai-conversation.js +3 -29
  17. package/dist/actors/computer-use/openai-provider.js +11 -5
  18. package/dist/actors/contract.d.ts +2 -20
  19. package/dist/actors/contract.js +0 -13
  20. package/dist/analysis/admission.d.ts +14 -4
  21. package/dist/analysis/admission.js +14 -9
  22. package/dist/analysis/execute.d.ts +5 -0
  23. package/dist/analysis/execute.js +3 -0
  24. package/dist/analysis/finding-lead.d.ts +27 -0
  25. package/dist/analysis/finding-lead.js +23 -0
  26. package/dist/analysis/service.js +5 -3
  27. package/dist/cli/commands/notes.js +4 -3
  28. package/dist/cli/findings.js +10 -32
  29. package/dist/cli/io.js +4 -7
  30. package/dist/cli/telemetry.js +10 -22
  31. package/dist/cli/update-check.js +6 -18
  32. package/dist/cli/user-config.d.ts +11 -0
  33. package/dist/cli/user-config.js +25 -0
  34. package/dist/comms/email-catch.js +7 -31
  35. package/dist/evidence/encoded-text.d.ts +12 -11
  36. package/dist/evidence/encoded-text.js +81 -70
  37. package/dist/evidence/redaction.d.ts +11 -0
  38. package/dist/evidence/redaction.js +21 -10
  39. package/dist/evidence/secret-scrub.d.ts +14 -1
  40. package/dist/evidence/secret-scrub.js +108 -32
  41. package/dist/feedback/draft.d.ts +1 -1
  42. package/dist/feedback/draft.js +13 -16
  43. package/dist/feedback/export-bundle.js +3 -3
  44. package/dist/feedback/export.js +32 -46
  45. package/dist/feedback/feedback.js +6 -19
  46. package/dist/keys/key-resolution.js +12 -17
  47. package/dist/observer/artifact.d.ts +1 -1
  48. package/dist/observer/http.d.ts +7 -0
  49. package/dist/observer/http.js +19 -1
  50. package/dist/observer/notes-route.d.ts +0 -1
  51. package/dist/observer/notes-route.js +24 -44
  52. package/dist/observer/pinned-files.js +4 -19
  53. package/dist/observer/render.js +3 -2
  54. package/dist/observer/run-routes.js +13 -28
  55. package/dist/observer/serve.js +2 -1
  56. package/dist/observer-app.html +3 -3
  57. package/dist/run/contained-output.d.ts +6 -5
  58. package/dist/run/contained-output.js +19 -26
  59. package/dist/run/evidence-files.d.ts +7 -0
  60. package/dist/run/evidence-files.js +24 -14
  61. package/dist/run/note-files.d.ts +26 -45
  62. package/dist/run/note-files.js +86 -58
  63. package/dist/run/note-shape.d.ts +35 -0
  64. package/dist/run/note-shape.js +20 -0
  65. package/dist/run/notes.d.ts +3 -6
  66. package/dist/run/notes.js +18 -24
  67. package/dist/run/participant-records.d.ts +2 -0
  68. package/dist/run/participant-records.js +17 -2
  69. package/dist/run/transient-comms-secrets.d.ts +6 -5
  70. package/dist/run/transient-comms-secrets.js +19 -24
  71. package/dist/study/summary.d.ts +4 -5
  72. package/dist/study/summary.js +4 -2
  73. package/dist/study/warnings.js +2 -1
  74. package/dist/tui-app.js +1 -1
  75. package/docs/architecture/actor-contract.md +3 -3
  76. package/docs/architecture/restricted-codex-analysis.md +1 -1
  77. package/docs/architecture/state-driven-executor.md +1 -1
  78. package/docs/contracts/run-bundle.md +7 -3
  79. package/docs/contracts/schemas.md +12 -12
  80. package/docs/contracts/study-analysis.md +12 -4
  81. package/package.json +7 -6
  82. package/skills/humanish/SKILL.md +1 -2
@@ -169,7 +169,7 @@ The rest of this section names keys by their v3 spelling:
169
169
  - `subject.state` (clone or local-tree subjects, computer-use route): the
170
170
  subject's state story. `state.seed[]` declares ordered, bounded
171
171
  seed/migration/fixture steps (`{ name, command, when: before-build |
172
- before-start | after-ready, timeoutMs }`) executed in-sandbox around the
172
+ before-start | after-ready, timeoutMs }`) executed in-sandbox around the
173
173
  serve sequence; `state.external[]` declares env var names (each must also
174
174
  appear in `subject.env`) pointing at state the study does not control,
175
175
  recorded as unpinned in provenance. Commands persist in evidence as
@@ -189,7 +189,7 @@ before-start | after-ready, timeoutMs }`) executed in-sandbox around the
189
189
  single participant (no E2B to fan out);
190
190
  - a `participants` list (computer-use E2B route): a differentiated fan-out,
191
191
  each entry `{ id?, actorType?, surface?, caseGroup?, persona?, device?,
192
- instruction?, target?, entry?, host?, reasoningEffort?, stopWhen?, dwell? }` becoming one independent E2B desktop (or, on the
192
+ instruction?, target?, entry?, host?, reasoningEffort?, stopWhen?, dwell? }` becoming one independent E2B desktop (or, on the
193
193
  shared-world routes, one participant against the shared plane). `actorType`,
194
194
  `surface`, and `caseGroup` are adapter-owned public-safe labels for grouping
195
195
  simulated users; they are not core enums, and `actorType` is deliberately
@@ -530,10 +530,10 @@ Core-owned fields:
530
530
  convention `study:<id>`, or `lab:<id>` from runs written before 0.108, and nothing else.
531
531
  - `subject` (optional, additive): structured subject provenance,
532
532
  `{ source: clone | app-url | local-tree, repo?, commit?, archiveSha256?,
533
- dirty?, envNames?, state }` where `state` is `{ provenance: seeded |
534
- unpinned | declared-not-run | undeclared | external-public, seed?: [{ name, when,
535
- commandDigest, ok?, exitCode?, timedOut?, durationMs? }], externalEnvNames?
536
- }`. Emitted by the computer-use and shared-world routes and the clone
533
+ dirty?, envNames?, state }` where `state` is `{ provenance: seeded |
534
+ unpinned | declared-not-run | undeclared | external-public, seed?: [{ name, when,
535
+ commandDigest, ok?, exitCode?, timedOut?, durationMs? }], externalEnvNames?
536
+ }`. Emitted by the computer-use and shared-world routes and the clone
537
537
  scripted-browser route; absent on pre-existing and other bundles. `repo`/`commit` are clone-route fields; `archiveSha256`
538
538
  (64-hex sha256, the local-tree provenance pin) and `dirty` (host git
539
539
  porcelain status at pack time) are local-tree-route fields, additive under
@@ -542,7 +542,7 @@ commandDigest, ok?, exitCode?, timedOut?, durationMs? }], externalEnvNames?
542
542
  sha256-16 of the exact seed command; command text and env values never
543
543
  appear. `humanish verify` fails closed when a live `local-tree` bundle carries
544
544
  no well-formed `archiveSha256`, in addition to the existing `subject state
545
- provenance` check.
545
+ provenance` check.
546
546
  - `desktopTemplate` (optional, additive): the custom E2B desktop template (image)
547
547
  the run's sandbox(es) launched on, from `execution.desktop.template`, so the
548
548
  evidence shows which image ran. Present only when a template was configured;
@@ -665,7 +665,7 @@ A shared-world bundle adds two additive, optional fields to `humanish.run-bundle
665
665
  0.106.0):
666
666
  - `sequence: [roleId, …]`: the role ids that actually took a turn, in declared order.
667
667
  - `skippedTail` (optional, live sequential only): `{ afterRoleId, roles,
668
- cause, maxTotalUsd?, estimatedTotalUsd? }`. Each ordered `roles` entry names
668
+ cause, maxTotalUsd?, estimatedTotalUsd? }`. Each ordered `roles` entry names
669
669
  `{ roleId, simId, streamId }` for an unstarted participant. Together with the
670
670
  executed prefix it must account for the full declared denominator. The
671
671
  predecessor must have a matching `harness_error`, explicit `session_error`,
@@ -700,7 +700,7 @@ cause, maxTotalUsd?, estimatedTotalUsd? }`. Each ordered `roles` entry names
700
700
  the internet-reachable getHost URL is synthetic seeded data (author-trust + a
701
701
  provenance gate, not a no-real-data guarantee).
702
702
  - `laneWindows: [{ roleId, simId, streamId, startedAt, endedAt, verdict, routeHostDigest,
703
- commit?, seedDigest }]`: one harness-clocked window per actor; overlapping windows
703
+ commit?, seedDigest }]`: one harness-clocked window per actor; overlapping windows
704
704
  prove ≥2 personas were active simultaneously. `routeHostDigest` == `plane.hostDigest`
705
705
  (every actor drove exactly the harness-minted host).
706
706
  - `stateSeries: [{ timestamp, digest }]`: cadence digests of the shared world under
@@ -1029,7 +1029,7 @@ Core-owned fields:
1029
1029
  (the Codex participant), or, when the participant ended the session itself
1030
1030
  without them, one impressions-only request (OpenAI computer-use, threaded or
1031
1031
  `explicit_context`). That request is recorded as `debrief` with `trigger:
1032
- participant_end` and never has a `report` or `messageId`; it leaves the
1032
+ participant_end` and never has a `report` or `messageId`; it leaves the
1033
1033
  participant's `reason`, outcome and friction as they were. An empty `items`
1034
1034
  list means the participant named none. `status: not_collected` carries a
1035
1035
  `reason`: the closing report or impressions request was skipped or failed
@@ -1374,7 +1374,7 @@ Three new `.v1` schema tags ship, all additive and optional so
1374
1374
  the E2B shell sandbox (its acquired-to-cleanup span and `e2b.getInfo` size) and
1375
1375
  one `model-tokens` line for the Codex participant, priced from the model the route passed
1376
1376
  to Codex (`gpt-5.6-sol` unless the study declares one) with `basis:
1377
- aggregated_turns_base_rate`, or `null` with `no_token_usage`. Older terminal bundles record
1377
+ aggregated_turns_base_rate`, or `null` with `no_token_usage`. Older terminal bundles record
1378
1378
  `no_rate_for_model` (model `codex`). The terminal trace records the same `estimatedCost`. The sandbox line is not part of the
1379
1379
  terminal cost ledger, whose lines are checked against `caps.maxUsd`.
1380
1380
 
@@ -1674,7 +1674,7 @@ record its own:
1674
1674
 
1675
1675
  - **Adapter score** (`humanish.adapter-score.v1`, `RunBundle.adapterScore`).
1676
1676
  A namespaced summary the adapter's `score` hook returns: `{ schema, namespace,
1677
- status, score, summary, data? }`. Core never reads `data`, where the adopter's
1677
+ status, score, summary, data? }`. Core never reads `data`, where the adopter's
1678
1678
  component rubric rides; `namespace` (an adopter slug) scopes the whole
1679
1679
  record so a future inert-field audit never misfires.
1680
1680
  - **Namespaced product-noun block** (`RunFeedbackCandidate.adapter`). The
@@ -39,9 +39,11 @@ high-detail image tokens, and prices input at the model's highest input rate.
39
39
  The expected output is 12,000 tokens plus 1,000 per participant, at most the
40
40
  output allowance; the worst case spends the whole allowance. `admission` in
41
41
  `--json` output has `estimatedCostUsd` (the expected cost), `worstCaseCostUsd`,
42
- `maxCostUsd`, `inputTokenAllowance` (the input tokens priced) and
43
- `outputTokenAllowance`. On 148 billed gpt-6-astra analyses the expected cost was
44
- 1.08 to 7.3 times the bill, and 1.08 to 1.32 times for those billed $1 or more.
42
+ `admittedCostUsd` (the figure compared with the cap: the expected cost plus 10%,
43
+ or the worst case when that is lower), `maxCostUsd`, `inputTokenAllowance` (the
44
+ input tokens priced) and `outputTokenAllowance`. On 148 billed gpt-6-astra
45
+ analyses the expected cost was 1.08 to 7.3 times the bill, and 1.08 to 1.32
46
+ times for those billed $1 or more.
45
47
  A refusal's message gives the expected cost, the worst case, the cap, and
46
48
  `humanish analyze --run <id> --max-cost <n>` with `n` the worst case rounded up.
47
49
 
@@ -205,7 +207,13 @@ The narrative scrub removes a run's known transient values, such as a received o
205
207
  link, from every generated text field. It finds each value as written and in its encoded forms:
206
208
  percent-encoded, JSON-escaped, base64, base64url and hex, and where escapes split it. A field
207
209
  with a value is stored decoded with the value replaced; a field without one keeps its spelling. A
208
- known value in any of these forms in an ID, enum or reference refuses the response.
210
+ value inside a bracketed span, such as `[REDACTED_373433393231]`, is found too: only the markers
211
+ humanish writes (`[REDACTED_SECRET]`, `[REDACTED_LOCAL_PATH]`, `[REDACTED_RUNTIME_PATH]`,
212
+ `[REDACTED_PROMPT_TEXT]`, `[REDACTED_LOBBY_CODE]`) are left as they are. If another reading of
213
+ the stored field still holds a value (decoded once more, with percent escapes as UTF-8, with
214
+ transfer escapes expanded, or with Latin-1 characters read as UTF-8 bytes), as for a value encoded
215
+ twice, the whole field becomes `[REDACTED_SECRET]`. A known value in any of
216
+ these forms in an ID, enum or reference refuses the response.
209
217
 
210
218
  When a reviewer amends a finding, its headline and experience describe the replaced claim.
211
219
  Text output, the Observer and feedback drafts show the reviewer's claim in their place and say the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "humanish",
3
- "version": "0.114.0",
3
+ "version": "0.115.0",
4
4
  "description": "Synthetic user research for apps, CLIs, and agent-facing product flows.",
5
5
  "keywords": [
6
6
  "cli",
@@ -112,13 +112,14 @@
112
112
  "@e2b/desktop": "^2.4.0",
113
113
  "@types/node": "catalog:",
114
114
  "@types/pngjs": "^6.0.5",
115
- "axe-core": "4.13.0",
116
- "knip": "6.38.0",
115
+ "axe-core": "4.14.0",
116
+ "fast-check": "catalog:",
117
+ "knip": "6.40.0",
117
118
  "oxc-parser": "catalog:",
118
- "oxfmt": "0.71.0",
119
- "oxlint": "1.86.0",
119
+ "oxfmt": "0.72.0",
120
+ "oxlint": "1.87.0",
120
121
  "oxlint-tsgolint": "7.0.2003",
121
- "skills": "1.7.0",
122
+ "skills": "1.7.1",
122
123
  "tsx": "^4.23.15",
123
124
  "typescript": "catalog:",
124
125
  "vitest": "catalog:"
@@ -342,8 +342,7 @@ The following configuration selects **local capture**:
342
342
  ```yaml
343
343
  comms:
344
344
  email:
345
- injectEnv:
346
- RESEND_API_URL # adopter-named: whatever env var YOUR app reads for its
345
+ injectEnv: RESEND_API_URL # adopter-named: whatever env var YOUR app reads for its
347
346
  # email-API base URL. The harness sets it to the in-sandbox catch — do NOT also
348
347
  # list it in subject.env. VERIFY the app actually reads this variable: a stock
349
348
  # email SDK does not honor a base-URL env unless the app passes it through, and