You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Revised 2026-03-31 (v3): Updated against canonical source at wasteland/schema/commons.sql and wasteland/internal/. Previous revisions were based on an outdated SKILL.md.
Problem
Gastown by Kilo towns cannot participate in the Wasteland federation. The Wasteland coordinates work across Gastown installations via Dolt databases on DoltHub. Our state lives in Durable Object SQLite — we need a bridge.
Non-Goals
Creating wastelands (we only join existing ones)
Gas City runtime adoption (we have our own reconciler)
Badge computation (read-only for now)
Acting as a Wasteland maintainer/validator (initially — we are a contributor)
Wild-west mode (DoltHub REST API does not support it — RemoteDB.CanWildWest() returns error at backend/remote.go:208-211)
Wasteland Protocol Summary
Grounded in wasteland/schema/commons.sql, wasteland/internal/commons/, and wasteland/internal/api/.
Core Model
The Wasteland is a federated work economy. Each participant ("rig") maintains a fork of a shared Dolt database (the "commons"). Work items ("wanted posters") are posted to the commons. Rigs browse, claim, complete, and get reputation stamps for their work. The fork-push-PR cycle is the only write path when using the DoltHub API backend.
open --> claimed --> in_review --> completed
| | | ^
| v v +-- accept (+ reputation stamp)
| (unclaim) (reject +-- close (no stamp)
| | → claimed)
| v
| open
|
v
withdrawn
Key semantics:
Claiming is mandatory before submission. SubmitCompletion (commons.go:371) requires WHERE status='claimed' AND claimed_by=?. No skip-claim/bounty path.
Reject sends in_review → claimed (NOT back to open). The claimer retains the claim and can resubmit. The completion record is deleted during rejection (commons.go:887-891).
Accept issues a reputation stamp and sets status='completed'.
Authorization is role-based (lifecycle.go:146-170): poster, claimer, admin — NOT trust-level-based.
Wanted Type Values
feature, bug, design, rfc, docs, inference — map to bead labels. The inference type is for verifiable distributed LLM inference jobs (docs/verifiable-inference.md).
Sandbox Fields
The wanted table includes sandbox_required (TINYINT), sandbox_scope (JSON), and sandbox_min_tier (VARCHAR) for items requiring sandboxed execution. When importing wanted items as beads, check sandbox_required and note it in bead metadata for container environment configuration.
Trust Levels
Stored in rigs.trust_level (INT DEFAULT 0). Registration hard-codes trust_level = 1 (registration.go:10). Trust levels are NOT enforced by the codebase — authorization in lifecycle.go uses role-based logic (poster, claimer, admin list), not trust levels. Trust levels are a social signal, not a technical gate.
Authentication
DoltHub API tokens (NOT OAuth). Source: backend/remote.go:454:
User creates token at dolthub.com/settings/tokens
Header: Authorization: token $DOLTHUB_TOKEN
Base URL: https://www.dolthub.com/api/v1alpha1
Hosted mode uses Nango for OAuth delegation (hosted/nango.go), but underlying auth is still DoltHub tokens.
Registers with trust_level = 1. We need the owner's email to construct the HOP URI.
Write Model: Fork-Push-PR (mandatory)
PR mode is the only option for API-based integration (RemoteDB.CanWildWest() returns error). Branch naming: wl/<rig-handle>/<wanted-id>.
Fork the upstream commons to your DoltHub org
Commit changes to a branch on your fork
Push to DoltHub
Upstream maintainer merges via DoltHub PR
REST API Surface
Source: wasteland/internal/api/routes.go:4-52 and hosted/server.go:53-59
Read endpoints (callable from TownDO via DoltHub REST API)
Endpoint
Purpose
GET /api/wanted
Browse board (query params for filtering)
GET /api/wanted/{id}
Item detail
GET /api/dashboard
Personal dashboard
GET /api/scoreboard/detail
Leaderboard detail
GET /api/profile/{handle}
Rig profile
Mutation endpoints (require fork-push, done via wl CLI in container)
Endpoint
CLI Command
Purpose
POST /api/wanted
wl post
Post new wanted item
POST /api/wanted/{id}/claim
wl claim <id>
Claim item
POST /api/wanted/{id}/unclaim
wl unclaim <id>
Release claim
POST /api/wanted/{id}/done
wl done <id> --evidence <url>
Submit completion
POST /api/sync
wl sync
Force sync
Important: We don't call the Wasteland REST API directly for writes. The mutation endpoints are for the Wasteland's own web UI. Our integration uses the wl CLI binary in the container, which handles the fork-push-PR cycle internally.
Architecture
TownDO (SQLite — source of truth)
↕ reconciler events
↓
Alarm loop:
├── Inbound: poll wanted board via DoltHub REST API
│ (same API as RemoteDB: GET /api/v1alpha1/{org}/{db}/main?q=...)
│ Requires: DOLTHUB_TOKEN header
└── Outbound: on bead close → emit wasteland_completion_ready event
↓
Reconciler side effects:
├── publish_wasteland_completion → call container to run `wl done`
├── claim_wasteland_item → call container to run `wl claim`
└── sync_wasteland_board → call container to run `wl sync`
↓
Container:
├── `wl` CLI binary (v0.3.0, ~50MB, installed in Dockerfile)
├── Pre-configured: `wl join` during onboarding
├── Env: DOLTHUB_TOKEN, DOLTHUB_ORG
└── Agent processes (unchanged — polecats work on beads, not Wasteland)
Reconciler Integration
New Event Types
'wasteland_items_synced'// Poll completed, new items found'wasteland_completion_ready'// Bead closed with wasteland origin'wasteland_published'// Completion pushed to fork successfully'wasteland_publish_failed'// Completion push failed (for retry)'wasteland_claimed'// Item claimed on wasteland
New Reconciler Rules (reconcileWasteland)
Rule 1: Publish completions for closed beads with wasteland origin
WHERE status = 'closed'
AND metadata.wasteland_wanted_id IS NOT NULL
AND metadata.wasteland_published_at IS NULL
→ emit publish_wasteland_completion
Rule 2: Escalate stale completions (published > 7 days, not validated)
→ create escalation for Mayor
Rule 3: Retry failed publishes (with backoff, max 3 attempts)
→ re-emit publish_wasteland_completion
wasteland?: z.object({enabled: z.boolean().default(false),connections: z.array(z.object({id: z.string().uuid(),upstream: z.string(),// e.g. "hop/wl-commons"fork: z.string(),// e.g. "our-org/wl-commons"dolthub_token: z.string(),// encryptedrig_handle: z.string(),owner_email: z.string(),// needed for HOP URI constructionprovider: z.enum(['dolthub','github']).default('dolthub'),poll_interval_ms: z.number().default(300_000),})).default([]),otel_enabled: z.boolean().default(false),})
Multi-wasteland support per SKILL.md.
Mayor Tools
Tool
wl Equivalent
Description
gt_wasteland_browse
wl browse
Browse available wanted items, filter by project/tags/priority/type
gt_wasteland_post
wl post
Post a new wanted item to the board
gt_wasteland_claim
wl claim
Claim a wanted item → creates a bead in the town
gt_wasteland_publish
wl done
Publish completion with evidence (auto-triggered on bead close, or manual)
Polecats have NO Wasteland tools. The Wasteland boundary is at the reconciler + Mayor level. Imported wanted items become regular beads; closures trigger automatic completion publishing.
Onboarding Flow
User navigates to town settings → "Wasteland" section
Clicks "Connect to Wasteland"
User provides:
DoltHub API token (from dolthub.com/settings/tokens)
Upstream commons URL (default: hop/wl-commons)
Rig handle (auto-suggested)
Owner email (for HOP URI: hop://{email}/{handle}/)
We validate the token against the DoltHub API
We fork the upstream commons to the user's DoltHub org
We run wl join <upstream> in the container
We register the town as a rig: rig_type = 'agent', parent_rig = <human-owner-handle>, trust_level = 1
Create a rig_links entry linking the agent rig to the human owner's rig
Parent
Part of #204 (Phase 4: Hardening)
Problem
Gastown by Kilo towns cannot participate in the Wasteland federation. The Wasteland coordinates work across Gastown installations via Dolt databases on DoltHub. Our state lives in Durable Object SQLite — we need a bridge.
Non-Goals
RemoteDB.CanWildWest()returns error atbackend/remote.go:208-211)Wasteland Protocol Summary
Grounded in
wasteland/schema/commons.sql,wasteland/internal/commons/, andwasteland/internal/api/.Core Model
The Wasteland is a federated work economy. Each participant ("rig") maintains a fork of a shared Dolt database (the "commons"). Work items ("wanted posters") are posted to the commons. Rigs browse, claim, complete, and get reputation stamps for their work. The fork-push-PR cycle is the only write path when using the DoltHub API backend.
Schema (v1.2 —
wasteland/schema/commons.sql— 8 tables)_meta1.2)rigswantedcompletionsstamps{"quality": N, "reliability": N}), confidence (FLOAT), severity, context_id, context_type, skill_tags (JSON), message, prev_stamp_hash, block_hash, hop_uri, created_at.CHECK (NOT(author = subject))— cannot self-stamp.badgesboot_blockschain_metarig_linksCHECK (rig_a != rig_b),UNIQUE (rig_a, rig_b)Wanted Item Lifecycle
Source:
wasteland/internal/commons/lifecycle.go:30-39Key semantics:
SubmitCompletion(commons.go:371) requiresWHERE status='claimed' AND claimed_by=?. No skip-claim/bounty path.in_review → claimed(NOT back toopen). The claimer retains the claim and can resubmit. The completion record is deleted during rejection (commons.go:887-891).status='completed'.lifecycle.go:146-170): poster, claimer, admin — NOT trust-level-based.Wanted Type Values
feature,bug,design,rfc,docs,inference— map to bead labels. Theinferencetype is for verifiable distributed LLM inference jobs (docs/verifiable-inference.md).Sandbox Fields
The
wantedtable includessandbox_required(TINYINT),sandbox_scope(JSON), andsandbox_min_tier(VARCHAR) for items requiring sandboxed execution. When importing wanted items as beads, checksandbox_requiredand note it in bead metadata for container environment configuration.Trust Levels
Stored in
rigs.trust_level(INT DEFAULT 0). Registration hard-codestrust_level = 1(registration.go:10). Trust levels are NOT enforced by the codebase — authorization inlifecycle.gouses role-based logic (poster, claimer, admin list), not trust levels. Trust levels are a social signal, not a technical gate.Authentication
DoltHub API tokens (NOT OAuth). Source:
backend/remote.go:454:dolthub.com/settings/tokensAuthorization: token $DOLTHUB_TOKENhttps://www.dolthub.com/api/v1alpha1hosted/nango.go), but underlying auth is still DoltHub tokens.Rig Registration
registration.go:8-12generates:Registers with
trust_level = 1. We need the owner's email to construct the HOP URI.Write Model: Fork-Push-PR (mandatory)
PR mode is the only option for API-based integration (
RemoteDB.CanWildWest()returns error). Branch naming:wl/<rig-handle>/<wanted-id>.REST API Surface
Source:
wasteland/internal/api/routes.go:4-52andhosted/server.go:53-59Read endpoints (callable from TownDO via DoltHub REST API)
GET /api/wantedGET /api/wanted/{id}GET /api/dashboardGET /api/scoreboard/detailGET /api/profile/{handle}Mutation endpoints (require fork-push, done via
wlCLI in container)POST /api/wantedwl postPOST /api/wanted/{id}/claimwl claim <id>POST /api/wanted/{id}/unclaimwl unclaim <id>POST /api/wanted/{id}/donewl done <id> --evidence <url>POST /api/syncwl syncImportant: We don't call the Wasteland REST API directly for writes. The mutation endpoints are for the Wasteland's own web UI. Our integration uses the
wlCLI binary in the container, which handles the fork-push-PR cycle internally.Architecture
Reconciler Integration
New Event Types
New Reconciler Rules (
reconcileWasteland)New Action Types
All are side effects (deferred async container calls), similar to
dispatch_agentandpoll_pr.Alarm Loop Pre-Phase
TownConfig Schema
Multi-wasteland support per SKILL.md.
Mayor Tools
wlEquivalentgt_wasteland_browsewl browsegt_wasteland_postwl postgt_wasteland_claimwl claimgt_wasteland_publishwl donegt_wasteland_statuswl me+wl statusgt_wasteland_syncwl syncPolecats have NO Wasteland tools. The Wasteland boundary is at the reconciler + Mayor level. Imported wanted items become regular beads; closures trigger automatic completion publishing.
Onboarding Flow
dolthub.com/settings/tokens)hop/wl-commons)hop://{email}/{handle}/)wl join <upstream>in the containerrig_type = 'agent',parent_rig = <human-owner-handle>,trust_level = 1rig_linksentry linking the agent rig to the human owner's rigContainer Changes
Tier 1 (required)
Container env vars:
DOLTHUB_TOKEN,DOLTHUB_ORGTier 2 (future)
Install Dolt binary (~100MB) + local MySQL server for sub-ms queries, versioned history, offline resilience.
Acceptance Criteria
Tier 1
rig_type='agent',parent_rig,trust_level=1, HOP URI)rig_linksentry for agent-to-human linkingwl donein containerclaimedstatus required beforedone)wlbinary v0.3.0 installed in container Dockerfilesandbox_required,sandbox_scope,sandbox_min_tier) mapped to bead metadatain_review → claimed(claimer retains claim)Tier 2 (future)
References
wasteland/schema/commons.sql(v1.2)wasteland/internal/commons/commons.gowasteland/internal/commons/lifecycle.gowasteland/internal/api/routes.gowasteland/internal/commons/registration.gowasteland/internal/backend/remote.go