Skip to content

hdresearch/seed-couch

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

5 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ›‹οΈ seed-couch β€” Crash on My Couch

Fleet hospitality protocol: invite guests, auto-provision sandboxed VMs, enforce resource limits, and kill-switch when needed.

What It Does

The Couch Flow:

Host creates invite β†’ shares code β†’ Guest redeems code β†’ VM auto-provisions β†’ Guest runs
     ↓                                     ↓                    ↓
  Resource limits set              "provisioning" status    "running" status
  Permissions defined              Auth token returned      Agent endpoint live
  Expiry window configured         Background VM spawn      Usage monitoring starts
  1. Host creates a single-use invite code with resource limits (CPU, memory, disk, tokens, duration) and permissions (internet, sub-agents, host services).
  2. Guest redeems the invite code β€” no auth needed. Gets back a guest token and a "provisioning" status.
  3. System spawns a VM from the golden commit in the background. Once ready, the guest status flips to "running" with a VM endpoint.
  4. Host monitors guest resource usage, checks limit violations, and can kill-switch at any time.

Key Concepts

Concept Description
Invite Single-use code with resource limits + permissions + expiry
Guest A redeemed invite β†’ provisioning β†’ running β†’ expired/revoked
Resource Limits CPU cores, memory, disk, network egress, tokens, duration
Permissions Internet access, sub-agent spawning, host service access
Kill Switch Immediately revoke a guest and destroy their VM

How to Plant

  1. Paste this repo into any AI agent with Node.js access.
  2. Tell the agent: "Plant this seed. Set up the couch hospitality service."
  3. The agent reads the protocol, wires up the routes, and starts the service.

Quick Start

# Copy src/ into your project
cp -r src/* your-project/src/couch/

# Wire routes in your server.ts:
#   Public (no auth):  app.route("/couch", couchPublicRoutes)   # redeem + status
#   Authenticated:     app.route("/couch", couchRoutes)         # invites + guests

# Configure VM provisioning (optional):
#   Set VERS_API_KEY and GOLDEN_COMMIT_ID in your config store
#   Without these, guests get "provisioning" status but no auto-VM

Protocol

Public Endpoints (no auth)

Method Path Description
POST /couch/redeem Redeem an invite code β†’ get guest token
GET /couch/status?token=... Guest checks their own status

Authenticated Endpoints (bearer token)

Method Path Description
POST /couch/invites Create a new invite
GET /couch/invites List invites (filterable by status)
DELETE /couch/invites/:id Revoke an active invite
GET /couch/guests List guests (auth tokens stripped)
GET /couch/guests/:id/status Guest resource usage + limit check
DELETE /couch/guests/:id Kill switch β€” revoke + destroy VM
POST /couch/guests/:id/activate Internal: mark guest as running
PUT /couch/guests/:id/usage Internal: update resource counters

Create Invite (POST /couch/invites)

{
  "createdBy": "noah",
  "label": "for ty β€” 72h test run",
  "resourceLimits": {
    "maxCpuCores": 2,
    "maxMemoryMB": 4096,
    "maxDiskGB": 20,
    "maxNetworkEgressGB": 10,
    "maxDurationHours": 72,
    "maxTokenBudget": 50000000
  },
  "permissions": {
    "canAccessInternet": true,
    "canSpawnSubAgents": false,
    "canAccessHostServices": false
  },
  "expiresInHours": 24
}

Redeem Invite (POST /couch/redeem)

{
  "code": "inv_abc123...",
  "name": "ty",
  "publicKey": "ssh-ed25519 AAAA..."  // optional
}

Response (201):

{
  "guestId": "01ABC...",
  "status": "provisioning",
  "authToken": "guest_xyz789...",
  "resourceLimits": { ... },
  "permissions": { ... },
  "expiresAt": "2026-02-18T00:00:00Z",
  "agentEndpoint": null
}

The guest polls GET /couch/status?token=guest_xyz789... until status becomes "running" and agentEndpoint is populated.

Auto-Provisioning Flow

When VM provisioning is configured (VERS_API_KEY + GOLDEN_COMMIT_ID):

  1. Guest redeems invite β†’ immediate 201 response with "provisioning" status
  2. Background: POST /vm/from_commit with the golden commit ID
  3. VM boots from snapshot in ~2 seconds
  4. Guest record updated: status: "running", vmId, agentEndpoint
  5. Guest polls /couch/status and sees the endpoint

Without provisioning configured: Guests stay in "provisioning" status. The host can manually activate via POST /couch/guests/:id/activate.

How to Verify

# 1. Create an invite
curl -X POST http://localhost:3000/couch/invites \
  -H "Content-Type: application/json" \
  -d '{"createdBy":"noah","label":"test"}'

# 2. Redeem it (public endpoint)
curl -X POST http://localhost:3000/couch/redeem \
  -H "Content-Type: application/json" \
  -d '{"code":"inv_...", "name":"guest-1"}'

# 3. Check status
curl "http://localhost:3000/couch/status?token=guest_..."

# 4. List guests
curl http://localhost:3000/couch/guests

# 5. Kill switch
curl -X DELETE http://localhost:3000/couch/guests/<GUEST_ID>

# 6. Run tests
npx vitest run

File Structure

seed-couch/
β”œβ”€β”€ seed.yaml              # Seed manifest (v0.3.1 spec)
β”œβ”€β”€ README.md              # This file
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ store.ts           # CouchStore β€” invites, guests, resource tracking, expiration
β”‚   β”œβ”€β”€ routes.ts          # Hono routes β€” public redeem + authenticated management
β”‚   └── vers-client.ts     # Minimal Vers API client for VM provisioning
└── tests/
    └── couch.test.ts      # Store unit tests + route integration tests

Extracted From

Reference implementation running in production on the HD Research fleet (vers-agent-services/src/couch/). Used for real guest provisioning with Vers VM auto-spawn from golden images.

License

CC-BY-4.0

About

πŸ›‹οΈ Crash on My Couch β€” fleet hospitality protocol with invite codes, sandboxed VMs, and kill switches

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors