humanish 0.0.1 → 0.15.1
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/AGENTS.md +77 -0
- package/CONTRIBUTING.md +39 -0
- package/LICENSE +21 -0
- package/README.md +437 -8
- package/SECURITY.md +34 -0
- package/dist/actor-contract.d.ts +107 -0
- package/dist/actor-contract.js +286 -0
- package/dist/actor-contract.js.map +1 -0
- package/dist/actor-registry.d.ts +73 -0
- package/dist/actor-registry.js +93 -0
- package/dist/actor-registry.js.map +1 -0
- package/dist/adapter-extension.d.ts +54 -0
- package/dist/adapter-extension.js +214 -0
- package/dist/adapter-extension.js.map +1 -0
- package/dist/argv.d.ts +1 -0
- package/dist/argv.js +8 -0
- package/dist/argv.js.map +1 -0
- package/dist/artifact-reference.d.ts +22 -0
- package/dist/artifact-reference.js +47 -0
- package/dist/artifact-reference.js.map +1 -0
- package/dist/browser-evidence-hygiene.d.ts +7 -0
- package/dist/browser-evidence-hygiene.js +40 -0
- package/dist/browser-evidence-hygiene.js.map +1 -0
- package/dist/claude-agent-sdk.d.ts +94 -0
- package/dist/claude-agent-sdk.js +363 -0
- package/dist/claude-agent-sdk.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +5 -0
- package/dist/cli.js.map +1 -0
- package/dist/codex-app-server-ui.d.ts +39 -0
- package/dist/codex-app-server-ui.js +357 -0
- package/dist/codex-app-server-ui.js.map +1 -0
- package/dist/codex-app-server.d.ts +144 -0
- package/dist/codex-app-server.js +754 -0
- package/dist/codex-app-server.js.map +1 -0
- package/dist/command-failure.d.ts +29 -0
- package/dist/command-failure.js +54 -0
- package/dist/command-failure.js.map +1 -0
- package/dist/computer-use-actor.d.ts +52 -0
- package/dist/computer-use-actor.js +48 -0
- package/dist/computer-use-actor.js.map +1 -0
- package/dist/computer-use.d.ts +232 -0
- package/dist/computer-use.js +615 -0
- package/dist/computer-use.js.map +1 -0
- package/dist/concurrency.d.ts +1 -0
- package/dist/concurrency.js +27 -0
- package/dist/concurrency.js.map +1 -0
- package/dist/concurrent-shared-world-lab.d.ts +115 -0
- package/dist/concurrent-shared-world-lab.js +1094 -0
- package/dist/concurrent-shared-world-lab.js.map +1 -0
- package/dist/core/git-state.d.ts +33 -0
- package/dist/core/git-state.js +277 -0
- package/dist/core/git-state.js.map +1 -0
- package/dist/core/git-workspace.d.ts +31 -0
- package/dist/core/git-workspace.js +447 -0
- package/dist/core/git-workspace.js.map +1 -0
- package/dist/core/index.d.ts +4 -0
- package/dist/core/index.js +3 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/run-primitives.d.ts +66 -0
- package/dist/core/run-primitives.js +120 -0
- package/dist/core/run-primitives.js.map +1 -0
- package/dist/cua-actor-lab.d.ts +621 -0
- package/dist/cua-actor-lab.js +2845 -0
- package/dist/cua-actor-lab.js.map +1 -0
- package/dist/device-presets.d.ts +67 -0
- package/dist/device-presets.js +50 -0
- package/dist/device-presets.js.map +1 -0
- package/dist/e2b-desktop-executor.d.ts +101 -0
- package/dist/e2b-desktop-executor.js +309 -0
- package/dist/e2b-desktop-executor.js.map +1 -0
- package/dist/e2b-desktop-launch.d.ts +144 -0
- package/dist/e2b-desktop-launch.js +59 -0
- package/dist/e2b-desktop-launch.js.map +1 -0
- package/dist/e2b-detached.d.ts +53 -0
- package/dist/e2b-detached.js +130 -0
- package/dist/e2b-detached.js.map +1 -0
- package/dist/e2b-terminal-lab.d.ts +345 -0
- package/dist/e2b-terminal-lab.js +1532 -0
- package/dist/e2b-terminal-lab.js.map +1 -0
- package/dist/env-file.d.ts +14 -0
- package/dist/env-file.js +108 -0
- package/dist/env-file.js.map +1 -0
- package/dist/feedback.d.ts +51 -0
- package/dist/feedback.js +351 -0
- package/dist/feedback.js.map +1 -0
- package/dist/image-evidence.d.ts +2 -0
- package/dist/image-evidence.js +33 -0
- package/dist/image-evidence.js.map +1 -0
- package/dist/index.d.ts +63 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/init-templates.d.ts +12 -0
- package/dist/init-templates.js +369 -0
- package/dist/init-templates.js.map +1 -0
- package/dist/init.d.ts +26 -0
- package/dist/init.js +429 -0
- package/dist/init.js.map +1 -0
- package/dist/lab-app-runner.d.ts +78 -0
- package/dist/lab-app-runner.js +403 -0
- package/dist/lab-app-runner.js.map +1 -0
- package/dist/lab-config.d.ts +583 -0
- package/dist/lab-config.js +1789 -0
- package/dist/lab-config.js.map +1 -0
- package/dist/lab-engine.d.ts +77 -0
- package/dist/lab-engine.js +216 -0
- package/dist/lab-engine.js.map +1 -0
- package/dist/lab-preflight.d.ts +67 -0
- package/dist/lab-preflight.js +385 -0
- package/dist/lab-preflight.js.map +1 -0
- package/dist/labs.d.ts +53 -0
- package/dist/labs.js +382 -0
- package/dist/labs.js.map +1 -0
- package/dist/observer-assets.d.ts +2 -0
- package/dist/observer-assets.js +2630 -0
- package/dist/observer-assets.js.map +1 -0
- package/dist/observer-data.d.ts +63 -0
- package/dist/observer-data.js +145 -0
- package/dist/observer-data.js.map +1 -0
- package/dist/observer-static.d.ts +39 -0
- package/dist/observer-static.js +306 -0
- package/dist/observer-static.js.map +1 -0
- package/dist/observer.d.ts +46 -0
- package/dist/observer.js +550 -0
- package/dist/observer.js.map +1 -0
- package/dist/openai-responses-cu.d.ts +113 -0
- package/dist/openai-responses-cu.js +545 -0
- package/dist/openai-responses-cu.js.map +1 -0
- package/dist/oss-lab.d.ts +52 -0
- package/dist/oss-lab.js +344 -0
- package/dist/oss-lab.js.map +1 -0
- package/dist/oss-meta-lab-scoring.d.ts +15 -0
- package/dist/oss-meta-lab-scoring.js +145 -0
- package/dist/oss-meta-lab-scoring.js.map +1 -0
- package/dist/oss-meta-lab.d.ts +277 -0
- package/dist/oss-meta-lab.js +4529 -0
- package/dist/oss-meta-lab.js.map +1 -0
- package/dist/oss-remote-telemetry.d.ts +77 -0
- package/dist/oss-remote-telemetry.js +403 -0
- package/dist/oss-remote-telemetry.js.map +1 -0
- package/dist/persona.d.ts +35 -0
- package/dist/persona.js +133 -0
- package/dist/persona.js.map +1 -0
- package/dist/pi-agent-core.d.ts +77 -0
- package/dist/pi-agent-core.js +203 -0
- package/dist/pi-agent-core.js.map +1 -0
- package/dist/program.d.ts +54 -0
- package/dist/program.js +2349 -0
- package/dist/program.js.map +1 -0
- package/dist/redaction.d.ts +90 -0
- package/dist/redaction.js +292 -0
- package/dist/redaction.js.map +1 -0
- package/dist/run-paths.d.ts +56 -0
- package/dist/run-paths.js +340 -0
- package/dist/run-paths.js.map +1 -0
- package/dist/run.d.ts +794 -0
- package/dist/run.js +4844 -0
- package/dist/run.js.map +1 -0
- package/dist/scripted-browser-actor.d.ts +297 -0
- package/dist/scripted-browser-actor.js +1399 -0
- package/dist/scripted-browser-actor.js.map +1 -0
- package/dist/scripted-browser-lab.d.ts +107 -0
- package/dist/scripted-browser-lab.js +788 -0
- package/dist/scripted-browser-lab.js.map +1 -0
- package/dist/selected-output-paths.d.ts +49 -0
- package/dist/selected-output-paths.js +354 -0
- package/dist/selected-output-paths.js.map +1 -0
- package/dist/shared-world-lab.d.ts +208 -0
- package/dist/shared-world-lab.js +1049 -0
- package/dist/shared-world-lab.js.map +1 -0
- package/dist/source-archive.d.ts +82 -0
- package/dist/source-archive.js +408 -0
- package/dist/source-archive.js.map +1 -0
- package/dist/stop-conditions.d.ts +26 -0
- package/dist/stop-conditions.js +66 -0
- package/dist/stop-conditions.js.map +1 -0
- package/dist/terminal-agent-actor.d.ts +36 -0
- package/dist/terminal-agent-actor.js +23 -0
- package/dist/terminal-agent-actor.js.map +1 -0
- package/docs/architecture/actor-contract.md +431 -0
- package/docs/architecture/github-feedback-loop.md +189 -0
- package/docs/architecture/local-codex-tui-actor.md +213 -0
- package/docs/architecture/observer.md +118 -0
- package/docs/architecture/oss-lab-poc.md +250 -0
- package/docs/architecture/project-layout.md +166 -0
- package/docs/architecture/state-driven-executor.md +203 -0
- package/docs/architecture/terminal-product-lane.md +148 -0
- package/docs/contracts/adapter-fixtures.md +80 -0
- package/docs/contracts/core.md +71 -0
- package/docs/contracts/feedback.md +145 -0
- package/docs/contracts/policy.md +311 -0
- package/docs/contracts/run-bundle.md +358 -0
- package/docs/contracts/schemas.md +984 -0
- package/docs/goals/current.md +428 -0
- package/docs/principles/invariants-and-defaults.md +135 -0
- package/docs/principles/self-driving-harness.md +129 -0
- package/docs/product/open-source-install-experience.md +237 -0
- package/docs/ramp/README.md +207 -0
- package/docs/release/open-source-readiness.md +208 -0
- package/docs/release/public-readiness-standard.md +205 -0
- package/docs/roadmap/world-class-open-source-v0.md +311 -0
- package/package.json +102 -8
- package/skills/humanish/SKILL.md +244 -0
- package/skills/humanish/agents/openai.yaml +7 -0
- package/index.js +0 -1
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# Terminal-product real-agent lane (issue #154)
|
|
2
|
+
|
|
3
|
+
Date: 2026-06-16
|
|
4
|
+
|
|
5
|
+
Status: SLICE 1 shipped — the config + routing skeleton, DRY-RUN only. The live
|
|
6
|
+
in-sandbox backend, the command-scoped credential boundary, cleanup,
|
|
7
|
+
interventions, the cost/no-spend ledger, and the product-adapter extension seam
|
|
8
|
+
are later slices. See the ratified goal packet
|
|
9
|
+
([`docs/goals/terminal-product-lane/goal.md`](../goals/terminal-product-lane/goal.md))
|
|
10
|
+
for the full slice plan and the safety contract.
|
|
11
|
+
|
|
12
|
+
## What this is
|
|
13
|
+
|
|
14
|
+
A lab lane for **terminal-product real-agent studies**: a real autonomous coding
|
|
15
|
+
agent (Codex) discovering and using a CLI/product from its **public surfaces
|
|
16
|
+
only**, running **inside an E2B shell** with command-scoped runtime auth, capped
|
|
17
|
+
at no-spend, emitting durable terminal/substrate/cost/no-spend/cleanup/
|
|
18
|
+
intervention proof that verifies fail-closed. This is distinct from the browser
|
|
19
|
+
lanes: it is not testing whether a browser can click a local web app — it tests
|
|
20
|
+
whether an autonomous agent can discover and use a CLI/product surface from
|
|
21
|
+
public materials.
|
|
22
|
+
|
|
23
|
+
It rides the established lane-addition pattern (proven by the scripted-browser
|
|
24
|
+
and local-app lanes): a new `subject.source` × `execution.target`, a routing
|
|
25
|
+
predicate, a backend enum + dispatch, a registered actor with a capability lane,
|
|
26
|
+
fail-closed cross-validation, and forward-declared warnings.
|
|
27
|
+
|
|
28
|
+
## The composition
|
|
29
|
+
|
|
30
|
+
| Axis | Value |
|
|
31
|
+
| --- | --- |
|
|
32
|
+
| `subject.source` | `terminal-product` |
|
|
33
|
+
| `subject.product` | `{ name, publicSurfaces[] }` — the only world the agent sees |
|
|
34
|
+
| `execution.target` | `e2b-terminal` (or absent → implied) |
|
|
35
|
+
| `execution.terminal` | `{ transport: exec-stream, stdin: disabled }` |
|
|
36
|
+
| `execution.runtimeAuth` | `openai-env` (names-only evidence this slice) |
|
|
37
|
+
| `scenario.caps` | `{ maxUsd, maxJobs, maxMinutes }` — the blast-radius budget |
|
|
38
|
+
| `policies` | `allowPrivateRepoAccess` / `allowProviderCredentials` / `allowPaymentCredentials` / `allowGitHubMutation`, all DEFAULT FALSE |
|
|
39
|
+
| `actors[0].type` | `codex-exec` — a registered terminal actor (`keyPlacement: in-sandbox-command-scoped`) |
|
|
40
|
+
| `LabBackend` | `terminal` → `runTerminalProductLab` ([`src/e2b-terminal-lab.ts`](../../src/e2b-terminal-lab.ts)) |
|
|
41
|
+
|
|
42
|
+
Routing is `routesToTerminalProduct(config)` — the single source of truth that
|
|
43
|
+
both `selectLabBackend` and the forward-declared-warning logic consume, mirroring
|
|
44
|
+
`routesToComputerUse` / `routesToScriptedBrowser`.
|
|
45
|
+
|
|
46
|
+
## The safety contract (the lane's reason to exist)
|
|
47
|
+
|
|
48
|
+
This lane **inverts** the credential-placement default of every other E2B route.
|
|
49
|
+
On the computer-use route the model's key stays *outside* the sandbox; here the
|
|
50
|
+
agent-under-test runs *inside* with a real `OPENAI_API_KEY`/`CODEX_API_KEY` and
|
|
51
|
+
is **presumed exfiltratable**. The doctrine (invariants-and-defaults.md, the
|
|
52
|
+
placement rule): *keys live where the keyed process runs — and nowhere else;
|
|
53
|
+
blast radius is bounded by key scoping and budgets, not by hoping.*
|
|
54
|
+
|
|
55
|
+
The inversion is declared as registry metadata, not a code convention: the
|
|
56
|
+
terminal actor's capabilities carry `keyPlacement: "in-sandbox-command-scoped"`.
|
|
57
|
+
SLICE 1 ships the DECLARED field + value (the contract is honest about where the
|
|
58
|
+
key would go); SLICE 2's engine enforces command-scoped injection (only into the
|
|
59
|
+
per-command `envs` of the `codex` invocation, never `Sandbox.create({envs})`)
|
|
60
|
+
keyed off that capability, plus the deny-by-default credential allowlist, the
|
|
61
|
+
positive-allowlist sandbox metadata, the cleanup proof, the interventions ledger,
|
|
62
|
+
and a minimal fail-closed cap.
|
|
63
|
+
|
|
64
|
+
## SLICE 1 scope (DRY-RUN only — what is honest now)
|
|
65
|
+
|
|
66
|
+
`runTerminalProductLab` implements ONLY the dry-run path: it builds a valid
|
|
67
|
+
`humanish.run-bundle.v1` contract bundle, honestly labeled contract-only, with:
|
|
68
|
+
|
|
69
|
+
- the subject declared as a terminal-product with its public surfaces, provenance
|
|
70
|
+
**UNPINNED** (the agent drives public surfaces, not a clone — invariant 5);
|
|
71
|
+
- the author mission recorded as plaintext (public-safe committed lab text) + a
|
|
72
|
+
**digest** of the full composed prompt (nothing beyond the author mission goes
|
|
73
|
+
plaintext);
|
|
74
|
+
- the caps / deny-by-default policies / runtime-auth channel recorded as
|
|
75
|
+
declarations (names only — invariant 1);
|
|
76
|
+
- a terminal-kind stream that is an honest **contract placeholder**: stdin
|
|
77
|
+
disabled, empty tail, `transport: snapshot` — **not** `pty` (captured
|
|
78
|
+
non-interactive exec output is never an interactive PTY; invariant 6 + the
|
|
79
|
+
goal packet's PTY ruling). SLICE 2 fills the redacted exec-stream capture;
|
|
80
|
+
- empty/placeholder ledgers (substrate lifecycle, command log, terminal event
|
|
81
|
+
stream, interventions, cost) that SLICE 2/3 fill.
|
|
82
|
+
|
|
83
|
+
The dry-run bundle passes the EXISTING `verifyRun`. Terminal-specific verifier
|
|
84
|
+
checks (terminal/transcript presence, lifecycle, cleanup, interventions,
|
|
85
|
+
metadata allowlist, no-credential-in-artifacts, no-spend) are SLICE 2/3.
|
|
86
|
+
|
|
87
|
+
A non-dry-run (live) call returns a structured `HUMANISH_TERMINAL_AGENT_NOT_IMPLEMENTED`
|
|
88
|
+
failure (fail-closed, clear code) — it never creates a sandbox, never injects a
|
|
89
|
+
key, never spends. SLICE 2 implements the real session.
|
|
90
|
+
|
|
91
|
+
The DI seams SLICE 2 needs (`loadModule`, `buildSandbox`, `runtimeAuthEnv`,
|
|
92
|
+
`detachedTimers`) are declared on `TerminalProductLabHooks` and threaded through
|
|
93
|
+
`RunLabOptions.terminalHooks`, mirroring `cuaHooks` / `scriptedHooks` — but only
|
|
94
|
+
the dry-run path is implemented this slice.
|
|
95
|
+
|
|
96
|
+
## SLICE 4 — the product-adapter extension seam (layer 6)
|
|
97
|
+
|
|
98
|
+
This lane is proof-roadmap **layer 6**: an adopter attaches product-specific
|
|
99
|
+
scoring + feedback as a THIN in-repo extension WITHOUT forking core. SLICE 4
|
|
100
|
+
ships the SEAM (not a built-in product scorer — the adopter's scorecard lives in
|
|
101
|
+
the adopter's repo):
|
|
102
|
+
|
|
103
|
+
- **Exported contract types** a thin adapter types against from the package
|
|
104
|
+
barrel (`humanish`) alone — never a deep `src/` import: `RunBundle`,
|
|
105
|
+
`RunFeedbackCandidate`, `RunAdapterScore`, `RunMeaningfulUseScore`
|
|
106
|
+
(+ `RunMeaningfulUseComponentId`), `ActorTrace`, and the terminal-lane
|
|
107
|
+
`TerminalProductScoringContext` / `TerminalLedgers` / `TerminalCostLedger` /
|
|
108
|
+
`NoSpendProof` / `CostLine` / record types. Before this slice these were not
|
|
109
|
+
exported — which FORCED a fork (a thin adapter could not type against the
|
|
110
|
+
bundle), the gap issue #154 acceptance #8 names.
|
|
111
|
+
- **A registrable scorer / feedback DI hook** on `TerminalProductLabHooks`:
|
|
112
|
+
`score?(ctx: TerminalProductScoringContext) => RunAdapterScore | Promise<…>`
|
|
113
|
+
and `deriveFeedback?(ctx) => RunFeedbackCandidate[] | Promise<…>`. The lane
|
|
114
|
+
calls the hooks over the FULLY-ASSEMBLED, redacted evidence and attaches the
|
|
115
|
+
results (`bundle.adapterScore`, appended `bundle.feedbackCandidates`) WITHOUT
|
|
116
|
+
core knowing any product noun. Default (no hook) behavior is unchanged: the
|
|
117
|
+
mission-based verdict stands alone.
|
|
118
|
+
- **Adapter-namespaced product nouns.** Product-specific concepts (public
|
|
119
|
+
CLI/product command observed, hosted product success-or-blocker, feedback
|
|
120
|
+
id/draft, media/job/asset ids, no-media/no-provider-spend proof,
|
|
121
|
+
defection/friction risk) ride ONLY under a single namespaced field
|
|
122
|
+
(`RunFeedbackCandidate.adapter: { namespace, data }` and
|
|
123
|
+
`RunAdapterScore.{namespace, data}`) so core's enums stay product-agnostic and
|
|
124
|
+
a future inert-field audit never misfires. No adopter noun is hardcoded into a
|
|
125
|
+
core enum (avoiding closed-taxonomy rot); `e2b-terminal` is added to the
|
|
126
|
+
substrate enum so a terminal-agent candidate names its substrate honestly.
|
|
127
|
+
|
|
128
|
+
The seam is fail-closed: the lane scrubs+redacts the returned payloads and DROPS
|
|
129
|
+
any malformed score/candidate with a warning, and `verifyRun` re-checks the
|
|
130
|
+
surviving shapes — a bad extension never poisons a verifiable bundle. Proven by
|
|
131
|
+
`tests/terminal-product-adapter-seam.test.ts` (a thin in-repo example adapter
|
|
132
|
+
typing against the barrel only, registering a scorer, attaching namespaced nouns,
|
|
133
|
+
emitting a candidate; the bundle verifies). No live rung — the seam is contract,
|
|
134
|
+
not spend.
|
|
135
|
+
|
|
136
|
+
The adopter's real scorecard is its OWN thin extension; the live receipt for the
|
|
137
|
+
end-to-end lane is tracked under #159, and true duplex PTY replay is deferred to
|
|
138
|
+
SLICE 5.
|
|
139
|
+
|
|
140
|
+
## The reference adopter (codename-neutral)
|
|
141
|
+
|
|
142
|
+
The requesting adopter is a public creative-CLI product (see issue #154 for its
|
|
143
|
+
concrete public surfaces). Committed source and docs here stay codename-neutral
|
|
144
|
+
per the public-surface scan; the committed CI fixture
|
|
145
|
+
([`humanish/labs/terminal-product-demo.yaml`](../../humanish/labs/terminal-product-demo.yaml))
|
|
146
|
+
uses a FICTIONAL mock CLI (`widgetsmith-cli`) with `example.com` surfaces. The
|
|
147
|
+
adopter's real public surfaces appear only in operator-run docs and the GitHub
|
|
148
|
+
issue, never in scanned committed text.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Adapter Fixture Parity Contract
|
|
2
|
+
|
|
3
|
+
Date: 2026-06-02
|
|
4
|
+
|
|
5
|
+
Status: v0 draft contract for public-safe adapter fixture parity.
|
|
6
|
+
|
|
7
|
+
## Purpose
|
|
8
|
+
|
|
9
|
+
Adapter fixtures prove that Humanish can carry target-specific evidence without
|
|
10
|
+
moving target truth into core schemas. A fixture is not a product claim. It is a
|
|
11
|
+
public-safe contract packet that shows the routes, personas, milestones,
|
|
12
|
+
terminal evidence, feedback drafts, and policy decisions a real adapter must
|
|
13
|
+
emit before live behavior can be trusted.
|
|
14
|
+
|
|
15
|
+
The fixture contract keeps three boundaries explicit:
|
|
16
|
+
|
|
17
|
+
- Core owns run-bundle identity, artifact layout, verification, review,
|
|
18
|
+
redaction, and feedback mechanics.
|
|
19
|
+
- Adapters own target routes, scenario language, personas, milestone names,
|
|
20
|
+
command surfaces, and acceptance proof.
|
|
21
|
+
- Public issue drafts use redacted artifact pointers only; they do not require
|
|
22
|
+
GitHub tokens, hosted product memory, private transcripts, or live mutation.
|
|
23
|
+
|
|
24
|
+
## Fixture Set
|
|
25
|
+
|
|
26
|
+
The committed fixture set lives under `adapters/fixtures/`.
|
|
27
|
+
|
|
28
|
+
| Fixture | Proves | Required artifacts |
|
|
29
|
+
| --- | --- | --- |
|
|
30
|
+
| `post-auth-return-dry-run` | A web-app adapter can keep upload, studio, and auth-return milestones adapter-owned while emitting a product-neutral dry-run bundle. | `adapter.json`, `persona.json`, `scenario.json`, `milestones.json`, `run-bundle.json` |
|
|
31
|
+
| `terminal-feedback-lifecycle` | A terminal-first adapter can emit sanitized transcript evidence, issue-draft material, cost/redaction policy, verification checks, and feedback lifecycle proof without browser-only assumptions. | `adapter.json`, `policy.json`, `run-bundle.json`, `feedback-draft.json`, `verify-result.json`, `transcripts/sanitized-terminal.txt` |
|
|
32
|
+
|
|
33
|
+
## Promotion Gates
|
|
34
|
+
|
|
35
|
+
A fixture can be promoted only when:
|
|
36
|
+
|
|
37
|
+
- every example is synthetic or redacted;
|
|
38
|
+
- artifact paths are relative and do not contain traversal segments, absolute
|
|
39
|
+
local paths, hosted stream URLs, or auth-bearing links;
|
|
40
|
+
- credential policy records env var names only, never values;
|
|
41
|
+
- adapter-owned nouns do not appear in core schema docs or core runtime code;
|
|
42
|
+
- public feedback material states that GitHub mutation was not performed;
|
|
43
|
+
- the fixture can be checked with `pnpm test tests/adapter-fixtures.test.ts`
|
|
44
|
+
and `pnpm public-surface:scan`.
|
|
45
|
+
|
|
46
|
+
## Dry-Run Web-App Fixture Shape
|
|
47
|
+
|
|
48
|
+
The web-app fixture models a local app with three adapter-owned route groups:
|
|
49
|
+
|
|
50
|
+
- `upload`: synthetic file input and validation state;
|
|
51
|
+
- `studio`: synthetic work surface and result-review state;
|
|
52
|
+
- `auth-return`: a post-authentication return path using a synthetic state id.
|
|
53
|
+
|
|
54
|
+
The dry-run bundle does not add route or milestone fields to core. Instead, it
|
|
55
|
+
references adapter-owned routes through `streams[].ui.route`, milestone events
|
|
56
|
+
through lifecycle/event records, and the milestone manifest through relative
|
|
57
|
+
artifact pointers.
|
|
58
|
+
|
|
59
|
+
## Terminal Feedback Fixture Shape
|
|
60
|
+
|
|
61
|
+
The terminal fixture models a command-driven product surface. Its bundle uses a
|
|
62
|
+
`terminal` evidence stream, a sanitized transcript pointer, a feedback
|
|
63
|
+
candidate, a separate feedback draft artifact, and a verification result that
|
|
64
|
+
checks required public-safe files without reading or requiring raw private
|
|
65
|
+
transcripts. Policy is adapter-owned and records:
|
|
66
|
+
|
|
67
|
+
- `spend_policy: no_spend`;
|
|
68
|
+
- `network_policy: no_network`;
|
|
69
|
+
- `github.mutation: not_requested`;
|
|
70
|
+
- `hosted_product_memory.required: false`;
|
|
71
|
+
- redaction status and denied material classes.
|
|
72
|
+
|
|
73
|
+
This keeps terminal and feedback parity independent from browser screenshots.
|
|
74
|
+
|
|
75
|
+
## Proof Commands
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
pnpm test tests/adapter-fixtures.test.ts
|
|
79
|
+
pnpm public-surface:scan
|
|
80
|
+
```
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Core Contract
|
|
2
|
+
|
|
3
|
+
Date: 2026-06-02
|
|
4
|
+
|
|
5
|
+
Status: v0 draft contract with tested primitive helpers in `src/core`.
|
|
6
|
+
|
|
7
|
+
## Purpose
|
|
8
|
+
|
|
9
|
+
Core is the reusable layer that makes a run bundle stable enough for agents,
|
|
10
|
+
reviewers, and maintainers to trust. It owns generic run identity, artifact
|
|
11
|
+
layout, source state summaries, lifecycle records, latest/history pointers, and
|
|
12
|
+
timing summaries.
|
|
13
|
+
|
|
14
|
+
Core does not own product routes, personas, scenarios, app topology, provider
|
|
15
|
+
setup, or repository-specific proof language.
|
|
16
|
+
|
|
17
|
+
## Public-Safe Defaults
|
|
18
|
+
|
|
19
|
+
Core records must be safe to include in public run bundles by default:
|
|
20
|
+
|
|
21
|
+
- artifact paths are relative;
|
|
22
|
+
- run ids contain only lowercase letters, numbers, and dashes;
|
|
23
|
+
- git state summarizes status without branch names, remotes, file names, file
|
|
24
|
+
paths, or absolute working directories;
|
|
25
|
+
- lifecycle and timing records are explicit inputs, not inferred prose;
|
|
26
|
+
- latest/history pointers identify local artifacts, not hosted private logs.
|
|
27
|
+
|
|
28
|
+
## Primitive Set
|
|
29
|
+
|
|
30
|
+
| Primitive | Contract |
|
|
31
|
+
| --- | --- |
|
|
32
|
+
| Run id | Deterministic from explicit prefix, timestamp, and entropy; valid ids match `^[a-z0-9][a-z0-9-]{0,127}$`. |
|
|
33
|
+
| Artifact layout | Builds stable relative pointers under `.humanish/runs/<run-id>/` plus `.humanish/runs/latest.json`. |
|
|
34
|
+
| Latest pointer | `{ schema, runId, path, updatedAt }` using `humanish.latest-run.v1`. |
|
|
35
|
+
| History entry | `{ schema, runId, createdAt, mode, path }` using `humanish.run-history-entry.v1`. |
|
|
36
|
+
| Lifecycle event | `{ at, event, message }`; event and message are required. |
|
|
37
|
+
| Timing summary | `{ startedAt, endedAt, durationMs, status }`; running records have null end and duration. |
|
|
38
|
+
| Git state | `{ schema, status, capturedAt, head, changes, note }` using `humanish.git-state.v1`. |
|
|
39
|
+
|
|
40
|
+
## Git State Boundary
|
|
41
|
+
|
|
42
|
+
Git state is intentionally lossy. It answers:
|
|
43
|
+
|
|
44
|
+
- is this a work tree?
|
|
45
|
+
- is it clean or dirty?
|
|
46
|
+
- what short HEAD hash is available?
|
|
47
|
+
- is HEAD attached, detached, unborn, or unknown?
|
|
48
|
+
- how many staged, unstaged, and untracked entries exist?
|
|
49
|
+
|
|
50
|
+
It does not record:
|
|
51
|
+
|
|
52
|
+
- branch names;
|
|
53
|
+
- remotes;
|
|
54
|
+
- file names;
|
|
55
|
+
- file paths;
|
|
56
|
+
- absolute directories;
|
|
57
|
+
- diffs;
|
|
58
|
+
- commit messages.
|
|
59
|
+
|
|
60
|
+
That makes it useful for repeatability and review without turning run bundles
|
|
61
|
+
into a source leak.
|
|
62
|
+
|
|
63
|
+
## Stop Conditions
|
|
64
|
+
|
|
65
|
+
Core work stops if:
|
|
66
|
+
|
|
67
|
+
- a core primitive needs a product-specific noun to make sense;
|
|
68
|
+
- an artifact path can escape the run root;
|
|
69
|
+
- a public record includes a raw cwd, branch name, remote, file name, diff, or
|
|
70
|
+
credential-like value;
|
|
71
|
+
- a run id cannot be reproduced from explicit inputs.
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# Feedback Contract
|
|
2
|
+
|
|
3
|
+
Date: 2026-06-01
|
|
4
|
+
|
|
5
|
+
Status: v0 local issue draft generation with run-candidate support.
|
|
6
|
+
|
|
7
|
+
## Purpose
|
|
8
|
+
|
|
9
|
+
Feedback is the bridge between simulation evidence and public issue filing.
|
|
10
|
+
|
|
11
|
+
`humanish feedback` should let a persona simulation say:
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
this user-like run found this concrete friction
|
|
15
|
+
here is the evidence
|
|
16
|
+
here is the likely owner
|
|
17
|
+
here is the redaction proof
|
|
18
|
+
here is the next state
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
It should not be an issue spammer, infra dependency, or generic comment
|
|
22
|
+
collector.
|
|
23
|
+
|
|
24
|
+
## Privacy Rule
|
|
25
|
+
|
|
26
|
+
Feedback payloads must be public-safe by default. They may not contain PII,
|
|
27
|
+
PHI, secrets, keys, tokens, raw private transcripts, private screenshots, raw
|
|
28
|
+
customer data, raw patient data, or private product source.
|
|
29
|
+
|
|
30
|
+
Public issue drafting fails closed if redaction cannot prove the payload is
|
|
31
|
+
safe. A verified run bundle is not automatically public-promotable: feedback
|
|
32
|
+
commands also require `humanish verify` to report
|
|
33
|
+
`shareSafety.status: share_ready`.
|
|
34
|
+
|
|
35
|
+
## Command Stages
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
humanish feedback list --run latest
|
|
39
|
+
humanish feedback draft --run latest --json
|
|
40
|
+
humanish feedback verify --run latest --json
|
|
41
|
+
humanish feedback issue --run latest --repo owner/repo --format markdown
|
|
42
|
+
humanish feedback issue-url --run latest --repo owner/repo
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### `list`
|
|
46
|
+
|
|
47
|
+
Reads feedback candidates from the run bundle. Does not mutate. Candidates are
|
|
48
|
+
generated by lab/adapters when actor evidence identifies a concrete
|
|
49
|
+
setup-quality gap, ceremonial/absent study quality, target-app blocker, or
|
|
50
|
+
Humanish CLI blocker. The OSS
|
|
51
|
+
meta-lab is one maintainer dogfood example, not the only candidate source.
|
|
52
|
+
|
|
53
|
+
### `draft`
|
|
54
|
+
|
|
55
|
+
Builds structured feedback from the strongest run candidate first. If no
|
|
56
|
+
candidate is present, falls back to the dry-run contract follow-up. Writes a
|
|
57
|
+
draft under the run bundle, not GitHub.
|
|
58
|
+
|
|
59
|
+
### `verify`
|
|
60
|
+
|
|
61
|
+
Checks schema, evidence pointers, idempotency key, redaction result, and public
|
|
62
|
+
issue eligibility.
|
|
63
|
+
|
|
64
|
+
### `issue`
|
|
65
|
+
|
|
66
|
+
Prints or writes a public-safe GitHub issue body. It does not call the GitHub
|
|
67
|
+
API. The user files the issue in the public or eventually public repository.
|
|
68
|
+
|
|
69
|
+
### `issue-url`
|
|
70
|
+
|
|
71
|
+
Prints a prefilled GitHub issue URL when the platform supports one. It still
|
|
72
|
+
does not create the issue.
|
|
73
|
+
|
|
74
|
+
## Schema
|
|
75
|
+
|
|
76
|
+
```yaml
|
|
77
|
+
humanish_feedback:
|
|
78
|
+
schema: humanish.feedback.v1
|
|
79
|
+
run_id: "<run-id>"
|
|
80
|
+
adapter_id: "<adapter-id>"
|
|
81
|
+
scenario_id: "<scenario-id>"
|
|
82
|
+
persona_id: "<persona-id-or-class>"
|
|
83
|
+
actor: "<actor-runtime>"
|
|
84
|
+
substrate: "<substrate>"
|
|
85
|
+
failure_owner: "harness|target-app|actor|environment|unknown"
|
|
86
|
+
summary: "<public-safe concrete summary>"
|
|
87
|
+
expected: "<public-safe expected behavior>"
|
|
88
|
+
actual: "<public-safe observed behavior>"
|
|
89
|
+
source_bundle: "<path-or-url>"
|
|
90
|
+
evidence:
|
|
91
|
+
- path: "<relative artifact pointer>"
|
|
92
|
+
kind: "screenshot|state|review|trace|log|filesystem"
|
|
93
|
+
note: "<public-safe note>"
|
|
94
|
+
redaction:
|
|
95
|
+
status: "passed|failed|not_applicable"
|
|
96
|
+
notes: "<public-safe note>"
|
|
97
|
+
idempotency_key: "<stable-key>"
|
|
98
|
+
proposed_next_state: "watch|adapter-hardening|target-app-setup|actor-auth|setup-quality-review|study-quality-review"
|
|
99
|
+
acceptance_proof:
|
|
100
|
+
- "<command or artifact that would close this>"
|
|
101
|
+
adapter:
|
|
102
|
+
namespace: "<adapter namespace>"
|
|
103
|
+
data: {}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
`adapter` is optional and namespaced. Adapters may place product-specific
|
|
107
|
+
concepts there (for example route groups, milestone ids, product acceptance
|
|
108
|
+
details, or adopter-owned rubric data). Core validates only that `namespace` is
|
|
109
|
+
non-empty and `data` is a record; keys inside `data` are never core enums.
|
|
110
|
+
|
|
111
|
+
## Failure Owners
|
|
112
|
+
|
|
113
|
+
| Owner | Meaning |
|
|
114
|
+
| --- | --- |
|
|
115
|
+
| `harness` | Humanish or adapter logic produced invalid evidence or execution. |
|
|
116
|
+
| `target-app` | The target app setup, dev server, or local surface blocked the run. |
|
|
117
|
+
| `actor` | The coding-agent/persona actor failed to complete a requested setup or usage path. |
|
|
118
|
+
| `environment` | E2B, local browser, shell, filesystem, network, or dependency substrate failed. |
|
|
119
|
+
| `unknown` | Evidence is useful but ownership is not yet clear. |
|
|
120
|
+
|
|
121
|
+
## Issue Draft Gates
|
|
122
|
+
|
|
123
|
+
Generating a public issue draft is blocked when:
|
|
124
|
+
|
|
125
|
+
- required schema fields are missing;
|
|
126
|
+
- source bundle is missing;
|
|
127
|
+
- evidence pointers are missing or invalid;
|
|
128
|
+
- redaction did not pass;
|
|
129
|
+
- `shareSafety.status` is `local_only` or `blocked`;
|
|
130
|
+
- any payload may contain PII, PHI, secrets, or private operational context;
|
|
131
|
+
- proposed next state is `agent_ready` without a readiness block;
|
|
132
|
+
- the feedback is a dry-run-only product claim;
|
|
133
|
+
- idempotency key is missing.
|
|
134
|
+
|
|
135
|
+
## GitHub Issue Semantics
|
|
136
|
+
|
|
137
|
+
GitHub issues filed from feedback should say `contributes to` unless the
|
|
138
|
+
acceptance proof closes the full product claim. The public issue should include
|
|
139
|
+
only redacted evidence pointers and reproduction instructions that a maintainer
|
|
140
|
+
can use without private local context.
|
|
141
|
+
|
|
142
|
+
The public CLI should not require GitHub tokens, hosted product memory, queues,
|
|
143
|
+
webhooks, Actions, databases, or Projects. Maintainers may later build separate
|
|
144
|
+
repo-local tooling that consumes the same issue schema, but that is outside the
|
|
145
|
+
default public feedback path.
|