Relationships
#2806 gatorwalk-factory: studio model type and its local serve method
Opened by skunk-ape · 9/30/2026· Shipped 9/30/2026
Part of the gatorwalk-factory studio (gatorwalk-factory/ in swamp-extensions). Read gatorwalk-factory/README.md and DESIGN.md first. Design proposal (decisions recorded 2026-09-30): https://claude.ai/artifact/BNCKp7w3G3Q8VdmnCDDWHP. Prototype, with its source under source/ (read it with the Artifact tool): https://claude.ai/artifact/1wAxrpUqZ47FAjE4fU9idD. Both links are private to the maintainer.
Goal
A local server for the studio, started from swamp: swamp model create @swamp/gatorwalk-factory/studio studio once per repo, then swamp model method run studio serve. It serves the studio page on 127.0.0.1 and reads the lifecycle and scenario files that the repo's lifecycle holders name. It is its own model type, not a method on the holder (decided 2026-09-30), so one studio covers every lifecycle in the repo through a picker and never takes a holder's lock.
The studio views and simulates; it never writes (decided 2026-09-30: edits come from the agent). The agent edits lifecycles/<name>.yaml and its scenario files, and the page reloads them as they change.
Scope
- The model type
@swamp/gatorwalk-factory/studio(a string literal, like the others) with the methodserve: an optionalportinput (default 0, a random port). It runsDeno.serve({ hostname: "127.0.0.1", signal: ctx.signal }), logs the URL, and blocks until Ctrl-C. - It finds lifecycle holders through the definition repository (
HOLDER_TYPE) and resolves each holder's file as the holder does (#2803). - Routes. Every path is resolved on the server from a holder; a request names a holder, never a path. All routes are
GET; anything else gets 405.
| Route | Does |
|---|---|
GET /, /assets/* |
the page |
GET /api/lifecycles |
holders, with the file each names |
GET /api/lifecycles/<holder> |
text, digest, path |
GET /api/lifecycles/<holder>/scenarios[/<name>] |
the same, for scenario files |
GET /api/events |
server-sent events on Deno.watchFs changes, so the page reloads an agent's edit |
- Security:
- Bind 127.0.0.1 only.
Hostmust be127.0.0.1:<port>orlocalhost:<port>(DNS rebinding, which would otherwise let a hostile page read the files).- A request that carries
Originmust carry the server's exact origin. No CORS headers are ever sent. - Scenario names must match
NameSchema. The resolved real path must sit inside the holder'slifecycles/directory. - No route writes a file or runs swamp, a shell or a method.
- CSP
default-src 'self'; fonts bundled. - No token or cookie: there is no write to protect, and the files are ones the local account can already read. If a write route is ever added, it needs the token, cookie and digest-checked write from the proposal first.
- Build: UI source in
gatorwalk-factory/studio/;deno task build:studiorunsdeno bundle --platform browser --minifyintostudio/dist/, which is committed. A verification command inverification/checks.yamlrebuilds it and fails on any diff. Shipping:additionalFilesat go-live. Until then there is no manifest (no_manifest_test.ts), so finddist/relative to the model module in source mode. - The page in this issue is a minimal shell: a holder picker, the file's text (read-only), and reload on events. Design mode is its own issue.
- DESIGN.md: a section "The studio server", with the security posture and why the studio is read-only.
Acceptance
- Unit tests for each route and each refusal (bad Host, bad Origin, a non-GET method, a bad scenario name, a path escaping
lifecycles/), against a temp repo. - An integration test starts
servethrough the CLI on a free port, loads/, changes the lifecycle file on disk, receives the event, and reads the new text.
Needs: #2803. Blocks: Design mode.
Shipped
Click a lifecycle step above to view its details.
system commented 9/30/2026, 3:48:16 PM
Classified automatically when this issue was filed.
- Source: Extensions
If you feel this classification is incorrect, add a ripple to tell us so.
skunk-ape commented 9/30/2026, 4:04:47 PM
Re-scoped. Seth decided on 2026-09-30 that the studio views and simulates but never edits: "Edits should come from the agent... I just don't think we should go down the road of having users create or edit by hand." The agent writes lifecycles and scenarios as files, and the local page reloads them. The write path is gone: the PUT routes, the one-time token and cookie, digest-checked atomic writes, and saving drafts that fail the schema. All routes are GET, and anything else gets 405. Kept: the 127.0.0.1 binding, the Host check against DNS rebinding, the Origin check on any request that sends one, path confinement, file watch with SSE live reload, and the build, dist and freshness check. If a write route is ever added, the token, cookie and digest design has to come back first. The tests and acceptance now cover reads and live reload instead of saving.
Sign in to post a ripple.