ADR-0011: Oracle Upstream Convergence — Remove Bluefly Runtime Ownership¶
Status: Proposed (operator approval required) Date: 2026-07-17 (v2 — same day: added live-runtime evidence pass over SSH read-only inventory + per-deletion proof obligations) Method: Primary upstream evidence only. Every claim tagged RETRIEVED / OBSERVED / INFERRED / NOT_FOUND / UNKNOWN. Deletion standard (operator, 2026-07-17): every deletion must name (a) the upstream feature replacing it, (b) the exact documentation/source proving equivalence, (c) confirmation Bluefly has no remaining requirement beyond the upstream feature. Anything short of that is downgraded to MIGRATE/VERIFY/BLOCKED — never deleted on inference.
Context¶
Oracle (bluefly-platform) drifted from IaC through SSH mutation. Directive: converge to official Gas City / Gas City / Beads; Bluefly contributes only IaC, packs, configuration, business logic. The running server is evidence, not authority — but it IS evidence, and the v2 pass collected it.
Evidence sources¶
| Tag | Source |
|---|---|
| D1 | docs.gascity.com/getting-started/coming-from-gascity (RETRIEVED 2026-07-17) |
| D2 | docs.gascity.com/getting-started/installation (RETRIEVED 2026-07-17) |
| D3 | gc v1.3.2 CLI help: supervisor install, init, import, doctor, dashboard, maintenance, start, register, rig (OBSERVED 2026-07-17) |
| D4 | docs.gascityhall.ai/installing/ + gt install --help (RETRIEVED/OBSERVED 2026-07-17) |
| D5 | github.com/gascityhall/beads README (RETRIEVED 2026-07-17) |
| D6 | BluCity-Docs Engineering-Standard/gc-architectural-facts.md — master doc |
| D7 | Applications/iac: terraform/oci/cloud-init.tftpl, openclaw/requirements.yml, runtime/bluefly-runtime.oracle.yml (full stages read), runtime/verify-oracle.mjs (full read) (RETRIEVED) |
| D8 | Oracle live inventory, read-only SSH, 2026-07-17 15:0x UTC (OBSERVED) |
| D9 | Operator-supplied upstream org inventory (gascityhall/, openclaw/, nexu-io/, kagent-dev/) |
| D10 | github.com/gascityhall/tmux-adapter README (RETRIEVED 2026-07-17) |
| D11 | github.com/dolthub/dolt releases (RETRIEVED 2026-07-17) |
| D12 | Applications/blucity grep: zero gt <cmd> references in formulas/, orders/, agents/, contracts/, city.toml, pack.toml (OBSERVED 2026-07-17) |
Keystone upstream facts (unchanged from v1)¶
- "Rather than running a separate
~/gttown, the Gas City pack runs inside a Gas City deployment … You don't maintain separate systems; Gas City replaces Gas City entirely through the Gas City pack abstraction." (D1) gc supervisor install— "Install the machine-wide supervisor as a platform service." (D3)gc init --file city.toml --preserve-existingfor committed workspaces;gc import installinstalls from pack.toml + packs.lock;gc start"fetches remote packs as needed" (D3).- Built-in dashboard:
gc dashboard serve(D3, D6). gc doctor --fixis "the canonical remediation path" (D3).[maintenance.dolt]supervisor loop (D3); beads: "use the dedicated backup command" (D5).- Compose (service stack) + Gas City (agent orchestration) are complementary; Terraform → cloud-init → Compose → GC is upstream-aligned (D6).
- Consume upstream via contracts/releases/packs — no production clones of upstream (D6).
- OpenClaw deploys via
openclaw-ansible(D9); iac pins v2.0.0 (D7). - gc prerequisites include "dolt 2.1.0 or newer" (D2).
v2 — Live-runtime findings (D8) that changed verdicts¶
- The declared IaC boot path is dead on the live box:
gc-worker.serviceDISABLED/inactive (state refreshed 2026-08-24; was enabled/inactive at time of original audit),gc-city-init.serviceDISABLED/failed (was enabled/failed at time of original audit) — the disable was applied deliberately as reboot-safety containment after the 2026-08-23 work-store-wipe incident, superseded by a properExecStartPre=health gate (iac!202).dolt-sql-server.serviceenabled/inactive (unchanged) — yet a gc supervisor IS listening on :8372. The hand-unit path is demonstrably not what runs production. Reinforces replacing hand units withgc supervisor install+gc register. Conclusion and REPLACE verdict below are unaffected by this state refresh. - The gt town is operationally live, not vestigial:
~/gtholds 20+ registered rigs (mayor/rigs.json: agent_docker →/opt/bluefly/agent-docker, blu_cli, compliance_engine, contractplane_sdk, openclaw, deacon, mayor, …). tmux sessionsadapter-monitor/converter-monitorup since Jul 7. Deleting~/gttoday would destroy the active operating model. - tmux-adapter is gt-only upstream: sole directory flag is
--gt-dir("Gas City town directory"); no releases; no service guidance (D10).tmux-converteractive on :8081;tmux-adapterenabled/activating. It serves OpenClaw terminal streaming FROM the gt town. - Dolt question resolved: live box runs dolt 2.1.10 (hand-upgraded — drift vs the pinned v1.42.0), dolthub releases are at v2.2.1 (D11), gascityhall/dolt fork has no releases. gc's "dolt 2.1.0 or newer" (D2) = dolthub 2.x line. Contract
^1.42and cloud-init pin v1.42.0 are stale → pin ≥2.1 (current: 2.2.1). - City data plane is dead: only the gt town's dolt listens (:3308). Nothing on :3307 → the
[federation.wasteland]DSN (…:3307/gascity) and the "city-level dolt" do not function today. - Undeclared unit found running:
gastown-gateway.service("Gas Town Control Center gateway (agent-docker)") — running, absent from cloud-init. New audit row. - verify-oracle.mjs is not duplication: it is a 117-line generic runner executing checks declared as configuration in
bluefly-runtime.oracle.ymlstages.*. The verify stage delegates city verification togc doctor(checkgc-runtime-health, comment: "Gas City owns runtime verification — not a bespoke :8372/health curl") and otherwise asserts Bluefly infrastructure contracts gc explicitly does not own (D6 fact 3): LiteLLM health, OpenClaw container, claude credential perms, docker network, disk floor, repo presence. Stageacceptis intentionally absent — delegated to a future Gas City certification pack.
Deletion proof obligations — dispositions after v2¶
| Item | (a) Upstream replacement | (b) Equivalence proof | (c) Bluefly residual? | Verdict |
|---|---|---|---|---|
verify-oracle.mjs + contract stages |
gc doctor for city runtime only |
D3 + D7: the tool already delegates to gc doctor |
YES — LiteLLM/OpenClaw/secrets/network/disk are Bluefly deployment invariants outside gc scope (D6 fact 3) | KEEP (amend checks in MR-2 where mechanisms rename; no equivalent upstream feature exists for infra-contract assertion) |
~/gt town on Oracle |
gc city + gascity pack (D1); rigs via gc rig add (D3) |
D1 conceptual; mechanical bead/rig continuity NOT yet proven | YES until migrated — 20+ live rigs, active beads, tmux-adapter serves from it (D8) | MIGRATE-THEN-RETIRE, gated. Retirement blocked on: per-rig gc rig add re-registration + bead-store continuity procedure with upstream citation + tmux-adapter dependency resolution |
| tmux-adapter/-converter + hand units | NONE for gc (gt-only, D10) | n/a | YES — OpenClaw terminal streaming in active use (D8) | KEEP while gt lives; lifetime coupled to gt town. File upstream issue for gc support; retire with gt only when OpenClaw streaming has a supported path |
gc-worker.service, gc-city-init.service |
gc supervisor install + gc register/gc start |
D3 verbatim; D8: hand units inactive/failed while supervisor runs anyway | NO | REPLACE (proof complete) |
| Heredoc city/pack config generation | Committed city repo; gc init --preserve-existing; gc start fetches remote packs (D3) |
D3 verbatim | NO — config moves into committed repo | REPLACE (proof complete) |
blucity-packs clone + 1-min cron |
Remote imports + committed packs.lock; gc import install/upgrade; gc start auto-fetch |
D3 verbatim | NO | REPLACE; commit packs.lock (untracked today; broke Mac gc bd 2026-07-17 — missing platform-compiler entry) |
gascity-dashboard clone + symlink |
Built-in supervisor dashboard, gc dashboard serve |
D3, D6-Phase0 | VERIFY: confirm no Bluefly feature depends on the cloned app beyond built-in (Phase 0 check: what serves it, who consumes it) | REPLACE pending (c) |
dolt-sql-server.service hand unit |
No upstream unit; infra services → Compose (D6); dolt server-mode documented (D5) | D5/D6 | YES — wasteland federation DSN + beads server-mode need A dolt server; currently dead (D8) | REPLACE with declared service (Compose, official image, dolt ≥2.1); DSN repaired in MR-2; gc doctor is the arbiter |
dolt-backup.sh + cron.d |
dolt backup sync (native), gc exec order ("plugins become orders", D1), gc maintenance (D3) |
D1/D3/D5 | Backup target (NAS) is Bluefly config — expressed as order args | REPLACE |
dolt pin v1.42.0 / contract ^1.42 |
dolthub ≥2.1 (D2, D11; live 2.1.10 D8) | D2+D11 | NO | FIX PIN (resolved UNKNOWN) |
| OpenClaw hand dirs (opc-owned) | openclaw-ansible v2.0.0 (already in iac, D7) | D7/D9 | Inventory/secrets remain Bluefly config | REPLACE (CI-run ansible) |
Caddy /opt/bluefly/caddy |
Traefik declared (D7); :80/:443 listener attribution UNKNOWN (D8 — needs sudo ss) | pending | pending route audit | VERIFY→DELETE (Phase 0 proves who owns :80/:443 first) |
gastown-gateway.service (undeclared, running) |
UNKNOWN owner (agent-docker unit?) | pending | pending | VERIFY — declare in IaC or retire; new Phase 0 row |
/opt/agent-platform, ~/.ddev, ~/rigs (empty), ~/tsc, .bashrc.gascity-backup, duckdb |
n/a (no declared owner) | Phase 0 one-shot claim check | pending | VERIFY→DELETE after claim check |
~/.gc, ~/.beads, ~/.dolt, ~/.claude |
Upstream tools' own state | D3/D5 | n/a (data plane) | KEEP |
| agent-docker Compose defs; runtime contract YAML; wl/qmd pins | n/a — Bluefly configuration / official releases | D6 | n/a | KEEP (contract text fix: providers.gc.install says npm; official is brew/release tarball, D2) |
Execution (all via MR; SSH stays read-only)¶
- Gate A (operator): approve gt→gc migration plan (not deletion): per-rig
gc rig add, bead continuity procedure proven with upstream citation, tmux-adapter/OpenClaw path resolved (upstream issue filed). Until complete, gt town stays. - Gate B (operator): instance shape (A1 free-tier ⇒ in-place converge; else recreate). Verify in
terraform/oci/instance.tf+ console. - MR-1 (blucity): commit complete packs.lock; Oracle deployment config into committed city definition (resolve
bluefly-cityrepo question — UNKNOWN, verify commit 064afa8 intent). - MR-2 (iac): cloud-init → official steps only (prereqs D2; pins: gc 1.3.2, bd 1.1.0, dolt ≥2.1; clone city repo;
gc supervisor install;gc register; Compose stack incl. dolt service; openclaw-ansible job; verify-oracle checks amended,gc doctor --jsongate). Delete hand gc units, heredocs, pack-sync cron, backup script/cron, dashboard clone (pending its (c)). - MR-3 (blucity-packs): backup exec order +
[maintenance.dolt]. - Phase 0 (CI, read-only): claim checks for VERIFY rows (:80/:443 owner, gastown-gateway, duckdb, dashboard consumers) + full inventory receipt.
- Phase 1 salvage: dolt-native backups of all stores (incl.
~/gttown beads) → NAS. - Migration phase (Gate A): execute gt→gc rig/bead migration; retire gt + tmux-adapter per coupling rule.
- Reset per Gate B; CI verification:
gc doctor --json+ verify stage +docker compose pshealthy. Manual step required ⇒ pipeline defect. - Guardrail: scheduled drift pipeline (terraform plan -detailed-exitcode + doctor + verify). Capability gaps → upstream issues, never hand-fixes.
Consequences¶
- Proof-complete replacements: hand gc units, heredoc config, pack clone+cron, backup script, dolt pin.
- Downgraded from v1 (evidence won): verify-oracle.mjs kept as Bluefly infra-contract configuration; gt town migrated, not deleted; tmux-adapter lifetime coupled to gt; dashboard clone deletion pending consumer check.
- New drift discovered by v2 pass: dead declared units vs live undeclared supervisor; dead :3307 data plane / federation DSN; hand dolt upgrade;
gastown-gateway.service.
v3 — Verification resolutions, portfolio curation, execution model (2026-07-17, same day)¶
Standing constraint (operator)¶
"Gas City and Gas City are the platform. Build within them, extend them, contribute upstream to them, and configure them. Do not build parallel infrastructure around them unless explicitly directed otherwise." Defaults: extend GC over competing runtimes; extend GT while it remains the active operational model during migration; Packs = reusable capabilities; Cities = deployment definitions; machine-local runtime state stays out of Git; upstream contribution over forks; custom code last resort.
Resolved: the "two Platform Compilers" collision (evidence)¶
- The
platform/compilerpack formula (blucity-packs) invokesscripts/compiler/{load-authorities,resolve-contracts,resolve-dependencies,construct-canonical-graph,validate-graph,generate-projections,emit-receipts}.sh. Those scripts exist nowhere: the only occurrence ofscripts/compileracross api-schema-registry, blucity, and blucity-packs is the formula file itself; api-schema-registry has noscripts/dir (OBSERVED). - The only implemented compiler is api-schema-registry's TypeScript
PlatformCompiler(package.json bin: platform-compiler → dist/index.js;src/compiler/PlatformCompiler.ts+ Dolt/OpenApi/TypeScript projections) — matching the pack formula's contract stages (OBSERVED). - Conclusion: no second compiler was implemented; the pack is an orchestration spec pointing at phantom entry points. Consolidation direction (decision bead, not executed): the pack orchestrates the real
platform-compilerbinary, or the shell entry points are created in the compiler's home repo — one compiler, one home.
Resolved: gc deployment lifecycle (no duplicated registration)¶
Upstream: gc init "bootstraps the city directory, registers it with the supervisor, and starts the orchestrator" (docs.gascity.com quickstart); gc start "registers the city with the machine-wide supervisor, ensures the supervisor is running" and "fetches remote packs as needed" (CLI). gc supervisor install adds only boot persistence ("platform service that starts on login"). Converged flow: clone city repo → gc start → gc supervisor install — no separate gc register, no hand-written units.
Resolved: dolt pin inventory (complete)¶
Exactly two pin sites exist, both in iac: terraform/oci/cloud-init.tftpl:132 (downloads v1.42.0) and runtime/bluefly-runtime.oracle.yml:110 (^1.42). No dolt version pins in blucity or blucity-packs (OBSERVED). Documented minimum "2.1.0 or newer"; live box 2.1.10; dolthub latest v2.2.1. Fix = those two lines.
Consistency requirements for the iac MR¶
- ADR-0012 (Accepted): OpenTofu is the reference IaC provisioning provider — the convergence MR aligns tooling with it rather than assuming Terraform.
- ADR-0014 (Proposed): Strict IaC Deployment Plan for Gas City — read and reconcile before rewriting cloud-init; this ADR-0011 and ADR-0014 must not diverge.
Repository portfolio (curation complete, six audits 2026-07-17)¶
| Repository | Canonical Role | Lifecycle | Runtime | Recommendation |
|---|---|---|---|---|
| blucity | Platform deployment definition (gc city) | Active — frozen until fix/bc-1op-repin-compiler-packs lands |
Yes | Keep; boundary cleanup only |
| blucity-packs | Business capabilities (amcs flagship) | Active | No (import/deploy-time) | Keep; prune ~28 empty scaffolds; relocate 2 verticals; only consumers are blucity + iac |
| blutown | Operational GT town — git home of live Oracle HQ | TBD = the GT→GC strategy decision (A active / B backup+history / C archive) | Yes (checkpoint of live runtime) | Defer lifecycle; P0 de-bloat regardless |
| blucity-docs | Canonical engineering memory; Platform Compiler input; QMD corpus | Active, at-risk (≈6 days uncommitted on polecat/hq-s20; degraded NAS git) |
Compile/governance layer | Keep; commit+push, shed operational concerns |
| api-schema-registry | Contracts SoT (schemas.bluefly.io/*) + implemented Platform Compiler |
Active (feature branch; consumers pin release/v0.1.x) |
Install/build-time (5 consumers) | Keep contracts+compiler core; shed drifted concerns |
Disappeared-tomorrow signal: nothing in live production depends on the gc stack yet — blast radii are fresh-install/compile/governance time; convergence carries no production risk, gated only on the blutown lifecycle decision.
Execution model (operator-directed)¶
- Durable decisions live here (this ADR + index) — the session plan file is deleted after incorporation.
- Implementation work = beads, one per bounded change.
- One bounded MR at a time; first: the two-line iac pin/typo fix (bluecity→blucity, dolt pins, seo-pack import name).
- Temporary audit/planning artifacts are removed once incorporated.