ADR-0027: Upstream Documentation is the Governing Contract¶
| Field | Value |
|---|---|
| Status | Accepted |
| Date | 2026-08-26 |
| Author | BLU (lead architect) |
| Approver | Thomas Scola |
| Scope | Platform-wide — Gas City architecture, Oracle cutover, Beads topology |
| Related | ADR-0022, ADR-0025 (Rule B.5 withdrawn), ADR-0026, ADR-0028 |
Context¶
ADR-0025 Rule B item 5 stated that the runtime contract wins over documentation where they disagree. That rule is withdrawn. It authorized local workarounds, site-specific topologies, and silent reinterpretation of upstream Gas City whenever Oracle disagreed with the docs.
Oracle currently runs Gas City (gt 1.2.1) with Gas City installed but not the active control plane. That observation is drift. It is not a design decision.
Decision¶
For Gas City semantics, operator-locked order (2026-09-09):
1. CURRENT docs.gascity.com
2. Current official Gas City specs / reference / runbooks
3. Current upstream implementation/tests when docs conflict or are incomplete
4. Live behavior of the exact installed gc version
5. Bluefly configuration / deployment facts
6. BluCity-Docs policy
7. Historical chats / old artifacts
Contributor engdocs/ design notes are not current docs.gascity.com. They sit at layer 3, and only after the published docs are incomplete or in conflict. Oracle deployment facts sit at layer 5; they measure conformance, they do not redefine primitives.
Observed runtime may prove drift, incompatibility, dirty state, or incomplete deployment. It does not authorize an alternative topology.
If Oracle behavior conflicts with upstream:
- Do not normalize the conflict as the new design.
- Do not invent a local workaround.
- Record the exact documentation URL, release, command, and observed contradiction.
- Determine whether Oracle is outdated, dirty, misconfigured, or incorrectly deployed.
- Correct it through a governed source, release, and deployment change.
- Escalate a genuine upstream contradiction rather than silently choosing runtime behavior.
Documentation conflict handling¶
If two upstream pages appear inconsistent:
- Record both URLs and the disagreement. Do not silently choose the page that fits an old Bluefly assumption.
- Prefer the current official tutorial or runbook for operational procedure when it matches the installed
gcversion. - Use current upstream implementation and tests when docs conflict or are incomplete.
- Stop any destructive operation until the conflict is resolved.
Recorded conflict as of 2026-08-26, expanded 2026-09-09:
| Source | Layer | What it says |
|---|---|---|
| Tutorial 01 | 1 | Portable rig names in city.toml; machine-local paths in .gc/site.toml |
Installed gc 1.3.2 / 1.4.1 |
4 | Same as Tutorial 01. path= on city.toml [[rigs]] is rejected as pre-1.0 |
| Understanding Packs | 1 | Example [[rigs]] still shows path = "../checkout-service" |
| Coming from Gas City | 1 | Leftover language that each [[rigs]] has a path |
| gc-start walkthrough | 1 | “site.toml inference is gone; city.toml is now the sole source of truth for rig locations”; resolution is path= on each [[rigs]] |
Pack v2 contributor notes (engdocs/design/packv2/skew-analysis.md, doc-rig-binding-phases.md) |
3 | Migration still described as in progress; rig.path currently stored in city.toml in that design track |
Prefer Tutorial 01 and the installed binary. Do not put path= back into city.toml. Do not call that preference "runtime wins." Escalate leftover pages upstream; they are not a Bluefly architecture.
Addendum, RETRIEVED 2026-09-09, github.com/gascityhall/gascity/blob/main/engdocs/design/packv2/skew-analysis.md and .../engdocs/design/packv2/doc-rig-binding-phases.md: recorded upstream disagreement, not a Bluefly target model. Contributor Pack v2 design notes still describe rig paths as stored in city.toml, with .gc/site.toml as an in-progress destination. Current docs.gascity.com Tutorial 01 and installed gc 1.4.1 use:
city.toml = portable rig identity/declaration
.gc/site.toml = machine-local rig path binding
Operator lock, 2026-09-09: current online Gas City documentation is the primary authority for Gas City semantics. That tutorial + live gc 1.4.1 is the governing model for Bluefly. Do not put path= back into city.toml as the normal current model. Do not treat a path is required error as permission to rewrite the architecture; treat it as an upgrade/misconfig/dirty-deploy signal against the installed binary, and call out remaining contributor-docs skew instead of silently choosing it.
Beads storage topology (locked)¶
Official authority:
- https://docs.gascity.com/reference/internal/beads-topology (last modified 2026-06-15)
- https://docs.gascity.com/runbooks/managed-city-endpoints
| Fact | Value |
|---|---|
| City root | /opt/bluefly/blucity |
City .beads/ |
required, prefix hq |
| City endpoint origin | city_canonical |
| City endpoint | 127.0.0.1:3308 database hq |
| Rig count | 15 |
Each rig .beads/ |
required, unique issue_prefix |
| Rig endpoint origin | inherited_city |
| Rig-local Dolt servers | 0 |
gc bd --rig |
directory routing, not federation |
Do not replace per-project .beads/ with one central directory. Do not run one Dolt per project. Do not use a project-local embedded ledger for production work. .beads/dolt-server.port is a compatibility mirror, not the canonical declaration. Storage-mode flips are not data migration.
This is not a federated bd list and not one independent Dolt server per rig.
Recorded nuance: the topology page describes prefix filtering on one shared store. The managed-city-endpoints runbook describes each rig as a logical database inside that one Dolt server. Those are two descriptions of the same city-owned Dolt, not two architectures.
Endpoint origins mean only this:
| Value | Meaning |
|---|---|
managed_city |
City owns Dolt lifecycle. gc start starts it. gc stop stops it. |
city_canonical |
Explicit externally managed Dolt. gc does not manage it. |
inherited_city |
Rig resolves through the parent city. |
explicit |
Rig owns or uses its own explicit endpoint. |
managed_city = pre-bind portable source is false. Do not use it.
Owning operations: gc beads city use-external (city bind), gc rig set-endpoint --inherit (rig join). Hand-edits of port files, bd dolt start inside inherited rigs, and bd dolt set port inside inherited rigs are forbidden.
Symptoms such as native_store_unavailable, gate=identity_match, and metadata project_id is missing are investigated against this one-server-plus-prefix topology (endpoint origin, issue_prefix filter, metadata.json / identity.toml). They are not license to invent a second ledger architecture.
Mac live probe, 2026-09-09 (layer 5 deployment fact, not a new model): city root metadata and identity.toml both carry project_id=7c7e2440-c581-4df6-8359-586b1283041d. All 14 registered rigs are inherited_city and also have project_id. The Mac city Dolt is managed_city on 127.0.0.1:38991 database hq, city issue_prefix=bc. Oracle city_canonical :3308 is a different deployment of the same city source, not a federated view of the Mac store. The missing-project_id files are four city-repo worktree .beads/metadata.json copies (worktrees/chore-gitignore-agent-memory-blu and three .claude/worktrees/agent-*): dolt_mode=server, dolt_database=hq, no project_id, no identity.toml, and at least one worktree config contradicts itself (issue_prefix: hq and issue-prefix: bl). That is incomplete worktree scope state against the one city server. bd doctor already classifies extra worktree .beads/ trees as cruft that should be redirect-only. Separately, bead bc-40c records native_store_unavailable from bd binary skew (Homebrew 1.2.2 active while a GOPATH bd remains on PATH). Neither finding is a second Dolt or a local/remote ledger split.
Authoritative work graph¶
The canonical work graph is the endpoint, not a pathname:
HOST=127.0.0.1 PORT=3308 DATABASE=hq
Preserve it in place during recovery. Do not import it into another ledger, copy shadow records into it without reconciliation, flip storage mode and call that migration, delete the embedded shadow store, relocate /home/ubuntu/gt/.dolt-data/hq, or create a replacement empty hq. Empty output is not proof of an empty ledger.
HQ writes require a proven backend from /home/ubuntu/gt: BACKEND=dolt MODE=server HOST=127.0.0.1 PORT=3308 DATABASE=hq PREFIX=hq REDIRECTED=false, then POST_COUNT >= PRE_COUNT. Do not write if the backend cannot be established. Do not run HQ Bead commands from /home/ubuntu. Do not mutate the shadow ledger.
Oracle cutover classification¶
TARGET_AUTHORITY=GAS_CITY
TEMPORARY_LEGACY_PLANE=GAS_TOWN
GC_RUNTIME_ACTIVE=NO and GT_RUNTIME_ACTIVE=YES means RUNTIME_CONFORMANCE=FAIL and CUTOVER_STATUS=INCOMPLETE. Preserve the working legacy plane until Gas City is proven. Do not elevate Gas City into the target design. No GT retirement is authorized until independent WITNESS acceptance.
Remote signed writes¶
https://docs.gascity.com/runbooks/remote-hardened-city describes a different deployment class: a self-hosted city accepting remote mutations over HTTP+SSE with a signed X-GC-City-Write grant, TLS, and a network front.
This host-local cutover binds a city to loopback 127.0.0.1:3308. Remote signed writes are not part of that documented execution path and are not a cutover prerequisite. If a later city needs that capability and the deployed release lacks it, the remedy is a separate governed upgrade MR — not a reinterpretation of the host-local contract around the old binary.
Role split¶
MAYOR coordinates Oracle runtime, collects evidence, and owns the final runtime receipt. MAYOR does not author a change and certify that same change.
REFINERY owns release and deployment mechanics. The BluCity implementer owns source and deployment correction. WITNESS owns exact-head functional acceptance. SENTINEL owns provenance, exposure, secret absence, and governance verification. HARBORMASTER owns later storage relocation only.
Rule¶
Current docs.gascity.com defines the target. The installed gc release defines what must be deployed to implement it. Runtime evidence measures conformance. Runtime drift does not override the documentation. If Oracle cannot implement the documented contract, fix or upgrade Oracle through governed source. Do not invent a third architecture.
Canonical Bluefly policy restatement: factory-operating-contract.md.
Consequences¶
- ADR-0025 Rule B.5 is withdrawn; this record replaces it.
- BluCity
city.tomlcomments that say "RUNTIME CONTRACT WINS" are defects and must be corrected in source. - Oracle GT remaining active is classified as an incomplete cutover, not as an approved control plane.
- Capability gaps in released
gc(for examplegc rig addfailing to converge against a fully pre-declared unbound rig set) are escalated or implemented through the released.gc/site.tomlcontract. They are not a new beads topology. - Destructive operations (ledger relocation, storage-mode migration, GT retirement, empty-hq replacement) are out of this cutover.
Addendum — 2026-09-09 (operator, current docs.gascity.com)¶
Current online Gas City documentation is the primary authority for Gas City semantics. Bluefly docs are downstream policy/configuration.
Authority order for Gas City work:
- Current docs.gascity.com
- Current official Gas City specs/reference/runbooks
- Current upstream implementation/tests when docs conflict or are incomplete
- Live behavior of the exact installed
gcversion - Bluefly configuration/deployment facts
- BluCity-Docs policy
- Historical chats / old artifacts
Governing rig-binding model for Bluefly's deployed gc 1.4.1 is Tutorial 01: portable identity in city.toml, machine-local path in .gc/site.toml. That replaces any Bluefly document treating city.toml path= as the normal current model.
The 2026-09-09 contributor-docs addendum above remains a recorded upstream disagreement (Pack v2 skew / rig-binding phases). It does not restore city.toml path= as Bluefly policy.
managed_city means the city owns the Dolt lifecycle (gc start / gc stop). It is not "pre-bind portable source."
Mayor, Witness, Refinery, Polecat, Deacon, Molecule, Convoy, and Drain are not additional primitives. The six primitives are Agent, Bead, Formula, Rig, Pack, Event. Factory policy: factory-operating-contract.md.
Addendum 2026-09-09 — portable source vs runtime identity¶
Tracked BluCity city Beads source is prefix hq, dolt_database: hq, dolt_mode: server, and must not commit project_id. Live Oracle origin is city_canonical at /opt/bluefly/blucity (127.0.0.1:3308). Git may record unbound-default managed_city; that is not a pre-bind synonym and not the live Oracle origin. /opt/bluefly/city is superseded. native_store_unavailable / gate=identity_match is a live metadata preflight, not a second ledger. Full contract: factory-operating-contract.md.
Addendum 2026-09-10 — leftover nested Dolt vs live city store¶
Mac live store is .beads/dolt (managed_city @ 127.0.0.1:38991 / hq). .beads/.dolt is leftover DoltHub (bluefly/BluCity) with no common ancestor to that remote's main; it is UNREFERENCED_LEGACY_STATE, not city authority. .beads/embeddeddolt is inactive. Do not dolt pull / merge / push / reset / init to join leftover, Mac, or Oracle stores. city.toml [dolt] port = 3308 stays Oracle-shaped; Mac listen port is runtime. Do not delete leftover stores as a Git change. Full contract: factory-operating-contract.md.