Commit ecd4322
authored
Agent evidence workflow: principles docs, e2e dev CLI, typed emulator client (#977)
* Document the service emulators: AGENTS.md note + emulate skill
When tests or demos need an upstream API, OAuth provider, or webhook
source, agents should reach for the @executor-js/emulate emulators
instead of hand-writing stubs. The new skill captures the control-plane
reference (/_emulate/openapi, /credentials, /ledger, /seed), the
hosted-instance addressing, the connect-handoff ledger-assertion
pattern, and the hard-won gotchas (Secure cookies need HTTPS
off-localhost; per-boot id counters need a fresh app DB).
.gitignore: carve .claude/skills/ out of the .claude/ ignore so skills
are shareable repo state while worktrees/settings stay local.
* Restructure agent docs: principles in AGENTS.md, mechanics in RUNNING.md
Root AGENTS.md becomes the stable contract layer and gains the missing
piece both recent agent sessions fumbled: a definition of done for
user-visible work. Done is something the user can open — (1) an e2e
scenario with direct links to the runs that prove the change, (2) the
session's dev server left up and reachable over the tailnet so the user
can take over, (3) an honest list of what to try by hand. The same
machinery runs in reverse: seed an environment into a state (live bug
repro, staged data) and hand across the link.
Mechanics move to a new RUNNING.md that opens by declaring itself
possibly stale — trust it as a starting point, verify against the code,
update on drift. It carries setup, the boot recipes (pointing at the
e2e globalsetup files as source of truth), run/viewer/sharing
operations, the leave-an-instance-up recipe with the Secure-cookie/
HTTPS constraint, and the hard-won environment gotchas.
e2e/AGENTS.md points at both. Docs deliberately avoid pinning URL
formats and flags that churn — agents discover those.
* Add the e2e dev CLI: the scenario primitives, interactive
cd e2e && bun run cli — boot a target and keep it up (up [--share]),
mint identities, make typed API calls, drive MCP sessions, read the
emulator request ledger, and tear down (down). The point: develop
against a live instance with the exact machinery the tests use, then
crystallize the journey into a scenario — and the booted instance IS
the handoff demo (AGENTS.md evidence contract) and the seeding vehicle
(drive a bug repro or staged state, hand across the URL).
The boot recipes move out of the vitest globalsetups into shared
setup/<target>.boot.ts modules — one boot path for suites (ephemeral)
and the CLI (persistent, detached runner owning cloud's in-process
WorkOS/Autumn emulators). up --share binds the tailnet: plain http for
selfhost; for cloud it fronts both the app and the WorkOS emulator
with tailscale-serve HTTPS (Secure cookies) and threads the public
origins through WORKOS_API_URL / emulator baseUrl / Vite allowed
hosts. Instances are tracked in e2e/.dev/<target>.json so a deliberate
long-lived instance is distinguishable from a leak; logs land next to
the state file (boot.ts gains logFile + pids for that).
Verified: both targets up/down cleanly through the CLI, identity/api/
mcp/ledger all answer, a scenario attaches to a CLI-booted instance
via E2E_SELFHOST_URL, both refactored globalsetups boot standalone
(api-tools green on cloud + selfhost), full suite run — the two cloud
failures (sources-api envelope, auth-methods mixed-source) reproduce
identically on the clean baseline, so they predate this change.
* Migrate to @executor-js/emulate 0.7.0's typed control-plane client
0.7.0 ships EmulatorClient + connectEmulator: one typed handle over the
/_emulate control plane (credentials.mint, ledger.list/clear, seed,
reset, manifest, ...) wherever the emulator runs — locally spawned or
hosted. Every hand-rolled fetch + response cast goes away:
- connect-handoff: mints via credentials.mint and asserts against
LedgerEntry[] (match on request.body) instead of substring-searching
the raw ledger text.
- targets/cloud setAccessTokenTtl: client.seed() instead of a raw POST.
- CLI ledger command: typed entries, JSON output.
- emulate skill: the client table replaces the raw-endpoint table as
the primary interface; raw /_emulate stays documented for curl use.
Also folds the CLI onto src/ports.ts claimPorts (from the worktree-env
PR this branch now stacks on) — the CLI's ad-hoc probe-and-walk is
gone; a held block lock marks the instance and releases on down.
Verified: connect-handoff green on selfhost + cloud (the ledger
assertion exercises the hosted resend emulator's typed client), the
token-expiry mcp-execute scenario green on cloud (exercises seed).1 parent 2ae9f50 commit ecd4322
16 files changed
Lines changed: 1110 additions & 184 deletions
File tree
- .claude/skills/emulate
- e2e
- scenarios
- scripts
- setup
- targets
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
70 | 70 | | |
71 | 71 | | |
72 | 72 | | |
73 | | - | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
74 | 76 | | |
75 | 77 | | |
76 | 78 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | | - | |
4 | | - | |
5 | | - | |
6 | | - | |
7 | | - | |
8 | | - | |
9 | | - | |
10 | | - | |
11 | | - | |
12 | | - | |
13 | | - | |
14 | | - | |
15 | | - | |
16 | | - | |
17 | | - | |
18 | | - | |
19 | | - | |
20 | | - | |
21 | | - | |
22 | | - | |
23 | | - | |
24 | | - | |
25 | | - | |
26 | | - | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
27 | 9 | | |
28 | 10 | | |
29 | 11 | | |
| |||
36 | 18 | | |
37 | 19 | | |
38 | 20 | | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
39 | 64 | | |
40 | 65 | | |
41 | 66 | | |
| |||
44 | 69 | | |
45 | 70 | | |
46 | 71 | | |
47 | | - | |
48 | | - | |
49 | | - | |
50 | | - | |
51 | | - | |
52 | | - | |
53 | | - | |
54 | | - | |
55 | | - | |
56 | | - | |
57 | | - | |
58 | | - | |
59 | | - | |
60 | | - | |
61 | | - | |
62 | 72 | | |
63 | 73 | | |
64 | 74 | | |
| |||
102 | 112 | | |
103 | 113 | | |
104 | 114 | | |
105 | | - | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
0 commit comments