ORACLE CANONICAL ARCHITECTURE¶
Authority: Gas City Docs (docs.gascity.com), OpenClaw Docs. Principle: Oracle is the production reference Gas City runtime. It consumes artifacts and provisions rigs on demand; it does not permanently host 136+ static development checkouts. Rule: Before creating any new directory, repository, runtime component, configuration file, deployment mechanism, or workflow — determine whether the capability already exists upstream. If it exists upstream, extend or configure it. If not, document why and define ownership, inputs, outputs, and lifecycle.
0. Operator Access & Separation of Environments¶
Invariant:
OPERATOR_LOCATION != PRODUCTION_CITY_LOCATION— GitLab defines source. Oracle runs the production reference City. Mac runs the local development City. NAS provides durability/backup. Tailscale connects.
| Layer | Role |
|---|---|
| GitLab | Authoritative source, CI/CD, packages, containers, MRs |
Oracle (bluefly-platform.tailcf98b3.ts.net) |
Production Reference Gas City Runtime + Beads Work Authority |
| Developer Mac | Local Development City (BluCity) + Thin Operator Client (gc, glab, bd, CMUX) |
NAS (blueflynas.tailcf98b3.ts.net) |
Durability custodian, database backups, release artifacts, model storage — never hot runtime |
| Tailscale | Private encrypted overlay network (MagicDNS, Tailscale SSH) |
Operator Flow:
device → Tailscale → bluefly-platform → blu / gc / bd / API
Clients do not require full local source trees or shadow Beads ledgers to operate the production Gas City.
1. Canonical Filesystem & Dedicated Storage¶
Dedicated Block Volume Mount (/opt/bluefly/ or /srv/gascity/bluefly)¶
To prevent root-disk exhaustion, Gas City hot runtime is mounted on a dedicated high-speed local block SSD.
/opt/bluefly/
├── blucity/ # Gas City root (production deployment)
│ ├── city.toml # Deployment policy (portable, committed)
│ ├── pack.toml # Pack identity + imports (portable, committed)
│ ├── packs.lock # Pinned import hashes (CLI-generated, committed)
│ ├── agents/ # Agent directories
│ ├── formulas/ # Reusable workflow methods
│ ├── orders/ # Scheduled/event-driven dispatch
│ ├── commands/ # gc subcommands
│ ├── doctor/ # Custom gc doctor checks
│ └── .gc/ # Machine-local state (NEVER committed)
│ ├── site.toml # Rig path bindings + workspace_name
│ ├── credentials.toml # Secret pointers only (0600)
│ ├── store/ # High-churn SQLite infra store (sessions, orders, nudges)
│ ├── worktrees/ # Ephemeral agent worktrees (auto-pruned on bead close)
│ └── runtime/ # Orchestrator sockets, locks, logs
├── deployments/
│ └── agent-docker/ # Infrastructure containers (Docker Compose)
└── runtime/
├── data/ # Persistent database volumes (Dolt server data)
├── logs/
└── secrets/ # Secrets at rest (chmod 700, never in Git)
Machine-Local Tool State¶
~/.gc/ # User-global Gas City state (contexts.toml, auth keys, global cache)
/opt/bluefly/blucity/.gc/ # Machine-local site bindings & hot runtime
2. Rig Provisioning on Demand¶
Oracle does not permanently maintain static checkouts of all 136+ Bluefly projects.
ON-DEMAND PROVISIONING:
gc --context prod rig add --git-url https://gitlab.com/blueflyio/<repo> --name <name>
- Rigs are provisioned dynamically from GitLab when work requires them.
- Ephemeral worker worktrees are allocated under
.gc/worktrees/<rig>/during execution. - Lifecycle automation (
auto_prune_worker_dir = true,auto_reap_closed_bead_worktrees = true) cleans up worktrees upon Bead completion.
3. Storage Architecture & Lifecycle Compaction¶
============================================================
ORACLE DISK PROTECTION & COMPACTION GATES
============================================================
1. WORKTREE PRUNING:
auto_prune_worker_dir = true
auto_reap_closed_bead_worktrees = true
(Gated on clean git status, zero unpushed commits, and closed bead state).
2. DOLT AUTO-GC:
auto_gc_enabled = true
(Runs background Dolt maintenance to prevent noms journal bloat).
3. BACKUP RETENTION:
Periodic cleanup of .beads/backup/ with bounded retention policy.
4. SPLIT STORAGE CLASSES:
work → Dolt (durable work ledger)
infra → SQLite under .gc/store (high-churn sessions, orders, nudges, graph)
4. Canonical Runtime Ownership¶
| Layer | Owner | Managed by |
|---|---|---|
| Gas City supervisor | upstream gc supervisor |
systemd |
| City config | blucity GitLab repo |
GitLab CI (deploy:oracle) |
| Rig bindings | .gc/site.toml (machine-local) |
gc-site-bind (CI) / gc rig add |
| Pack imports | blucity-packs GitLab repo |
gc import install |
| Container services | agent-docker GitLab repo |
Docker Compose |
| OpenClaw gateway | agent-docker compose |
Docker Compose |
| Dolt database | Gas City managed | gc start |
| Beads (work store) | Gas City managed | gc start |
| Machine-local state | Tool-owned | ~/.gc/, blucity/.gc/site.toml |
| Secrets | secrets/ + CI variables |
1Password / GitLab CI variables |
5. Canonical Artifact Flow¶
Source code (GitLab)
→ build → Docker image / NPM package / OCI image
→ push → Registry (GitLab Container Registry / NPM)
→ pull → Oracle (agent-docker compose)
→ run → Runtime service
blucity-packs (GitLab)
→ gc import install (reads pack.toml + packs.lock)
→ Oracle pack cache
→ city loads → Agent behavior (prompts, formulas, orders, doctor checks)
6. Cold-Start Deployment¶
1. Provision Oracle host & attach dedicated block volume (iac / cloud-init)
2. Mount block volume at /opt/bluefly
3. Clone blucity → /opt/bluefly/blucity
4. Clone agent-docker → /opt/bluefly/deployments/agent-docker
5. Push blucity through governed CI: stamp → deploy:oracle → gc-site-bind → verify
6. cd /opt/bluefly/blucity && gc import install && gc start
7. cd /opt/bluefly/deployments/agent-docker && docker compose up -d
8. gc status && gc doctor
Operator access: connect via Tailscale to bluefly-platform, then use blu/gc/bd.
7. Recovery & Maintenance¶
gc supervisor status # check supervisor
gc doctor # check health
gc reload # reload config (no restart)
gc restart # restart agents
gc stop && gc start # full restart
gc status && gc doctor # verify
gc import check && gc import install
Current State¶
What exists today. Separated from target/migration so that six months out it is obvious what was real. Tag everything; do not aspirational-wash.
Capability baseline¶
🟡 N = unmeasured (not zero). Authority-context resolution (blu work current) fails preflight
locally and the canonical workspace root is not a Gas Town workspace. The runtime baseline is owned by
the Capability Registry (Gas City + Oracle), readable only via gt / blu remote. See
ADR-0002. First runtime work item: restore
measurability of N, not write capability code.
Oracle — the 3-VM incident (Observed 2026-06-24)¶
| VM | State | Disposition |
|---|---|---|
VM B 150.136.74.174 |
🟢 the real production server (60+ services); never imported to Terraform | ADOPT (terraform import) |
VM A 109832 / 100.74.25.39 |
⚪ empty shell created by a mis-aimed apply; cloudflared crash-looping | TERMINATE |
VM C 100.103.48.75 |
🟡 Feb duplicate; runs the live OpenClaw (:18789) | migrate OpenClaw → VM B, then TERMINATE |
claw.copaw.us is broken because the "social" Cloudflare tunnel targets a Tailscale hostname VM B
cannot reach; a socat proxy on :18789 bridges to VM C. Immediate fix: point the tunnel at
http://localhost:18789.
Oracle — single-instance runtime (Observed 2026-07-04)¶
The 3-VM incident is consolidated: OCI reports one instance bluefly-platform (shape
VM.Standard.A1.Flex, lifecycle RUNNING), public 150.136.226.103, tailnet 100.64.56.113.
It is offline on the tailnet (Tailscale: last seen ~1d). This is not a conflict — the VM boots,
but the 2026-07-03 serial console shows tailscale up run with an empty auth key ("invalid key:
unable to validate API key") because the oracle-authkey field is missing from the Tailscale
1Password item (op read exits 1). That missing field is the root cause of the offline node.
The same boot surfaced two cloud-init defects, both fixed in iac MR !71 → release/v0.1.x:
- op read used the invalid --raw flag (op 2.34.1). The git clone of agent-docker/blucity-packs
failed "HTTP Basic: Access denied"; the most likely explanation supported by current evidence is
that the failing op read left DEPLOY_TOKEN empty — not independently verified during that boot.
Fixed to --no-newline.
- beads download used releases/latest/download/beads_linux_arm64.tar.gz → 404 (release assets are
version-stamped). Pinned to v1.1.0 (beads_1.1.0_linux_arm64.tar.gz, arm64); URL now returns 200.
iac CI is green on release/v0.1.x + main. Remaining owner action to bring the node online:
mint a Tailscale auth key (admin 2FA) and populate the oracle-authkey field; the fixed cloud-init
then joins the node on the next apply.
Tooling (Observed)¶
gt, bd, blu, buildkit resolve on PATH. The only beads DB found locally is empty. Workspace is
BluCity (not BluTown); hard-coded BluTown paths in some gateway code cause silent timeouts — a
portability defect, not a stale path (ADR-0003).
Governance repo¶
🟡 bluefly-governance exists locally only; not authoritative until pushed to a GitLab remote
(ADR-0001).
Oracle — GitLab Runner fleet drift (Observed 2026-07-30)¶
🔴 terraform/gitlab/runners.tf (iac) declares 6 runners with specific tags/concurrency/resource
limits. Live Oracle (/opt/bluefly/agent-docker/.../config.toml, SSH-verified) had only 2 of 6
registered, concurrent=8 global with zero per-runner limit and zero Docker resource caps —
directly matching independently-observed host resource-storm and CI gitleaks-stampede incidents.
Root cause traced (not assumed): deploy:oracle (agent-docker .gitlab-ci.yml) runs
docker compose up -d on every deploy but had no step touching config.toml — registration was a
one-time manual gitlab-runner register outside CI, never reconciled since. Full inventory:
iac terraform/gitlab/RUNNER-INVENTORY.md.
Fix in flight, not yet applied: agent-docker MR!211. See target lifecycle in
GitLab Runner Convergence Lifecycle.
Target State¶
Where infrastructure is going. ⚪ Planned unless tagged otherwise. No commands here — see Migration Plan.
Factory Law¶
Nothing is edited in production. Everything is rebuilt from authority.
[!CAUTION] Constitutional Invariants 1. Every persistent byte has exactly one authoritative owner. 2. Runtime may never become authority. 3. Every projection is reproducible from authority. 4. Every cache is disposable. 5. Infrastructure defines how execution is constructed. 6. Execution mutates state. 7. State never mutates infrastructure. 8. Secrets are retrieved, not stored. 9. Every deployment must be reproducible from authority. 10. Authority may be replicated. Ownership may not. 11. Every architectural exception requires an explicit documented justification.
Authority Decision Test¶
Every engineering change must answer these five questions before it is merged. If a proposal cannot answer these, it must be rejected: 1. Who owns this data? 2. Who is allowed to modify it? 3. Who consumes it? 4. Can it be regenerated? 5. If not, where is its authoritative home?
Terminology: Projection¶
Projection: A derived representation that may be deleted and regenerated entirely from authoritative sources. A projection must never become the system of record. (Examples: receipts, search indexes, compiled graphs, documentation sites, package artifacts, and caches are all projections).
Clean Plane & Authority Graph¶
Separating customer experience, operator orchestration, durable work, source delivery, and physical storage:
Human & Experience Plane (Owns Interface & Approval) * Drupal / AMCS / ContextControl.ai owns customer UI, Canvas, context governance, approval workflows, and site building.
Operator Plane (Owns Orchestration) * Gas City owns agent execution, session lifecycle, routing, formulas, orders, packs, and worktree lifecycles.
Work & State Authority (Owns Work Graph)
* Beads (bd / Dolt) owns tasks, epics, blockers, dependencies, and priority.
Source & Release Authority (Owns Code & Artifacts) * GitLab / Upstream SCMs own source code, merge requests, CI/CD pipelines, package registries, and container images. * 1Password owns secrets (retrieved dynamically, never persisted in Git). * Cloudflare owns DNS, edge ingress, and tunnel routing. * Keycloak owns federated identity and authentication.
Custodian (Owns Durability & Backups) * Synology NAS acts as custodian for durable backups, long-term artifacts, models, and restore points.
Execution Runtime (Owns Hot Compute) * Oracle Runtime VM acts as the production reference Gas City host on dedicated fast block storage. * Developer Workstation (Mac) acts as a lightweight local development City and client interface.
Storage Class Division & Lifecycle Law¶
============================================================
STORAGE CLASS DIVISION
============================================================
HOT RUNTIME (Oracle Dedicated Block SSD / Mac Local SSD):
• .gc/worktrees/ (Active execution trees)
• .gc/runtime/ (Sockets, process locks, fifos)
• .gc/store/ (High-churn SQLite infra: sessions, orders, nudges)
• .beads/dolt/ (Active Dolt database)
DURABLE STORAGE (Synology NAS / Offsite Backup / S3):
• Database backups & snapshots (bd backup / Dolt dumps)
• Long-term artifact archive
• Model weights & large embeddings
• OpenClaw shared durable workspace
RULE: NEVER run hot .gc/worktrees, SQLite, or Dolt over SMB/NFS.
The Factory Flow¶
flowchart TD
subgraph HumanPlane["Human & Customer Plane"]
Drupal["Drupal AMCS / ContextControl.ai"]
end
subgraph SourceGitLab["Source & Delivery (GitLab)"]
GL[GitLab Source / CI / Packages / Registry]
end
subgraph OperatorPlane["Operator Control Plane (Oracle Gas City)"]
GC[Gas City Controller]
Worktrees[".gc/worktrees (Ephemeral local SSD)"]
InfraStore[".gc/store (SQLite High-Churn Infra)"]
DoltStore[".beads/ (Dolt Work Graph)"]
end
subgraph CustodianNAS["Durability & Backup Custodian (NAS)"]
Backups[(Platform_Data_Persistent - Backups/Dumps)]
Artifacts[(Platform_Artifacts - Releases/Receipts)]
Models[(Platform_AI_Models - Weights/GGUF)]
end
Drupal -->|HTTP/SSE Connected Client API| GC
GL -->|Provision Rigs on Demand via Git URL| Worktrees
GC -->|Executes Work in| Worktrees
GC -->|Infra State| InfraStore
GC -->|Durable Tasks| DoltStore
DoltStore -->|Periodic Snapshots & Dumps| Backups
GL -->|Release Artifacts| Artifacts
1. NAS (Synology DS224+) — Durability & Backup Custodian¶
Each Shared Folder represents a bounded context with a distinct lifecycle, mapping directly to Synology features (Snapshots, Hyper Backup, ACLs).
| Shared Folder | Lifecycle | Authoritative Owner | Description |
|---|---|---|---|
Platform_Source |
Immutable | GitLab / Upstreams | Cold source mirrors / archive. |
Platform_Infrastructure |
Declarative | IaC | Compose files, Traefik config, systemd units. |
Platform_Identity |
Secure | 1Password / IdP | Trust relationships, exported config, certs, realm definitions. Secret material remains authoritative in 1Password. |
Platform_Data_Persistent |
Dynamic / Backup | DB Dumps & Storage | Durable State: Database backups (Postgres, Dolt dumps), Drupal uploads, Object storage. NOT live mmap database engines. |
Platform_Data_Cache |
Ephemeral | DBs / Caches | Regenerable State: Temporary indexes, cold caches. |
Platform_Packages |
Derived Release | CI Pipelines | Internal package distribution mirrors (npm, Composer, Docker). |
Platform_Artifacts |
Derived Artifact | CI Pipelines | Release bundles, receipts, compiled exports, test reports. |
Platform_Knowledge |
Curated | Humans / Agents | Engineering standards, documentation, research. |
Platform_AI_Models |
Static | Training Pipeline | Foundation models, LoRAs, GGUF, ONNX, TensorRT, weights. |
Platform_AI_State |
Dynamic | Vector DBs / RAG | Vector snapshots, RAG index dumps, conversation archives. |
Platform_Operations |
Append-only | System | Logs, Metrics, Audit, Receipts, Deployment history, Backups. |
Snapshot & Backup Policy (Synology Optimized)¶
- Hyper Backup (Offsite/Cloud):
Platform_Identity,Platform_Knowledge,Platform_Operations, andPlatform_Data_Persistentbackups. - Excluded from Hyper Backup:
Platform_Data_Cache,Platform_Packages,Platform_Artifacts,Platform_AI_Models. - Btrfs Snapshot Replication: Enabled on namespaces that benefit from rapid rollback:
Platform_Infrastructure,Platform_Identity,Platform_Source,Platform_Knowledge.
2. Oracle — Dedicated Production Gas City Host¶
- One runtime authority (Gas City Host): a single Oracle VM (VM B), fully reproducible from IaC. The Oracle VM is fundamentally a Gas City host, not a raw unmanaged server.
- Dedicated Block Volume: Oracle mounts a dedicated local block SSD (e.g.
/opt/bluefly/blucityor/srv/gascity/bluefly) for Gas City runtime, eliminating system-disk bloat and avoiding SMB/NFS latency. - On-Demand Rig Provisioning: Rigs are provisioned via Git URL (
gc rig add --git-url ...) when work requires them. Oracle does not host 136 permanent static checkouts. - Lifecycle & Disk Protection Gates:
auto_prune_worker_dir = trueandauto_reap_closed_bead_worktrees = trueprune ephemeral agent worktrees upon Bead closure after clean-git checks.auto_gc_enabled = trueon Dolt + periodic maintenance prevents journal ballooning.- Bounded retention on
.beads/backup/prevents unbounded local backup growth. - Split storage architecture isolates high-churn infra (
graph,sessions,messaging,orders,nudges) into SQLite under.gc/store. - Strict 4-Layer Deployment Hierarchy:
- Terraform: Owns the Machine / VM.
- cloud-init: Owns Host provisioning (bootstrap, native dependencies, Tailscale).
- Host (Systemd/Native): Owns upstream host components:
gc,openclaw,dolt. - agent-docker: Restricted entirely to Infrastructure containers (
observability,identity,drupal,databases).
GitLab Runner Convergence Lifecycle¶
Terraform (iac/terraform/gitlab/runners.tf)
-> gitlab_user_runner resources + masked group CI variables (RUNNER_TOKEN_*)
-> GitLab Deployment (agent-docker deploy:oracle)
-> docker compose up -d
-> register-gitlab-runners.sh (renders config.toml from template + tokens, restarts)
-> verify-gitlab-runners.sh (structural diff: declared template vs. live config.toml)
-> runner-convergence-report.md (CI artifact, every deploy, 90-day retention)
-> Oracle Runtime
-> drift fails the deploy job (allow_failure: false) — no silent divergence
3. Developer Workstation (Mac)¶
- The local Mac is a lightweight development environment containing the local dev City (
BluCity) and client tooling (gc,glab,bd, CMUX). - Contains only active development rigs (e.g. ContextControl, AMCS, BluCity-Docs, BluCity-Packs).
- Does not host 136 permanent repository checkouts or production authority.
Migration Plan¶
How we get from Current State to Target State. Governed by the Dual-Lane Execution Strategy: Lane 1 builds product immediately; Lane 2 converges the factory in parallel without blocking product delivery.
Dual-Lane Execution Model¶
┌────────────────────────────────────────┐ ┌────────────────────────────────────────┐
│ LANE 1: SHIP PRODUCT NOW │ │ LANE 2: FACTORY CONVERGENCE │
│ │ │ │
│ • Drupal AMCS site template │ │ • Dedicated Oracle block volume │
│ • ContextControl.ai ↔ Gas City Tool API│ │ • Worktree pruning & Dolt auto-GC │
│ • Canvas agent site building │ │ • Split storage migration evaluation │
│ • Bead status visualization in Drupal │ │ • Pack / Formula registry hardening │
│ • Portable Customer Pack release │ │ • Clean GitLab CI & IaC deployment │
└────────────────────────────────────────┘ └────────────────────────────────────────┘
Phase 1: Oracle Gas City & Storage Convergence (Lane 2)¶
- Dedicated Block Storage: Attach and mount a dedicated high-speed block volume for
/opt/bluefly/blucityor/srv/gascity/blueflyto isolate hot Gas City runtime from the VM root disk. - Lifecycle & Compaction Gates:
- Configure
auto_prune_worker_dir = trueandauto_reap_closed_bead_worktrees = trueincity.toml. - Enable
auto_gc_enabled = trueon Dolt and schedule periodic compaction runs. - Configure bounded retention on
.beads/backup/to eliminate unbounded backup bloat. - Split Storage Architecture Evaluation:
- Test routing high-churn infra classes (
graph,sessions,messaging,orders,nudges) to SQLite under.gc/store. - Preserve durable
workin Dolt/Beads ledger. - On-Demand Rig Model:
- Cease maintaining 136 static repo checkouts on Oracle; provision rigs dynamically via
gc rig add --git-url ....
Phase 2: Private Cloud Durability & Backups (NAS)¶
- Provision Durable Namespaces: Create and configure
Platform_*Shared Folders in Synology DSM (Platform_Source,Platform_Infrastructure,Platform_Identity,Platform_Data_Persistent,Platform_Artifacts,Platform_AI_Models). - Apply Backup Policies: Configure Btrfs Snapshots and Hyper Backup rules for durable state and backups (WAL, logical database dumps, release artifacts).
- Strict Non-Hot Rule: Explicitly prohibit running live mmap database engines or hot
.gc/worktreesdirectly over SMB/NFS mounts.
Phase 3: Product Integration & Multi-Tenant Packaging (Lane 1)¶
- Drupal ↔ Gas City Connected-Client API: Wire ContextControl.ai / Drupal Tool API to Gas City's HTTP/SSE control surface for headless agent session execution and turn streams.
- Customer Factory Release: Package the reusable capability layer into Bluefly Packs, Formulas, Skills, Recipes, and Containers for repeatable single-tenant customer deployments.