ADR-0028: Gas City Repository Model — GitLab Canonical, Oracle Working Clone, Ephemeral Worktrees¶
| Field | Value |
|---|---|
| Status | Proposed |
| Date | 2026-08-26 |
| Author | BLU (lead architect) |
| Approver | Thomas Scola |
| Scope | Platform-wide — Gas City rig registration, Oracle checkouts, agent execution |
| Related | ADR-0023 (repository authority), ADR-0026, ADR-0027 |
Context¶
Oracle currently has duplicate project directories (top-level /opt/bluefly/<name> vs /opt/bluefly/rigs/<name>). That is a path-generation and ownership problem. It is not a reason to introduce bare repositories as the Gas City registered-rig type.
Bluefly already has a NAS/Mac bare-repo + git worktree client workflow (ADR-0006 / ADR-0023 Recovery and Development authorities). That workflow is not the Gas City execution model.
Upstream Gas City (docs.gascity.com, current gc source and tests) treats a rig as an external project directory registered with the city. Agents that mutate a repo use work_dir plus git worktree under the city .gc/worktrees/ tree.
Decision¶
GITLAB=canonical source identity
REGISTERED_RIG=
non-bare working repository
stable governed anchor
content identity proven by remote+HEAD+working-tree state
AGENT_WORK=
separate git worktree
ephemeral
branch/work-item scoped
REGISTERED_RIG_SHARED_MUTATION=NO
BARE_REPOSITORY=
valid as origin/mirror/storage role
NOT registered execution rig target
GAS_CITY_REGISTERED_RIG=NON_BARE_WORKING_REPOSITORY
AGENT_EXECUTION=EPHEMERAL_GIT_WORKTREE
Do not invent a custom Bluefly model where upstream Gas City/Gas City already provides worktree semantics. Do not reopen bare clone / mirror clone / shared clone / repo cache as the registered-rig question.
Three layers¶
LAYER_1 — Canonical source
GitLab is repository identity and source authority (same as ADR-0023 Source Authority). Examples:
blueflyio/blu/blucityblueflyio/blu/blucity-packsblueflyio/blu/blucity-docs
Mac checkouts (blueflyio/blu/blucity and siblings) are client copies of the same GitLab identity. Folder casing is irrelevant. Git remote establishes identity. Mac is not Oracle runtime authority. Do not compare path strings as if they were identities.
LAYER_2 — Oracle registered rig
One governed non-bare working clone per rig. Requirements:
.gitexistsgit rev-parse --is-bare-repositoryisfalse(Bluefly deploy-validation candidate; see below)git rev-parse --is-inside-work-treeistrueoriginmatches the canonical GitLab repo- working tree exists
- known deployed SHA
- clean governed state
- Gas City registration (
.gc/site.tomlpath binding) points here
The registered checkout is the stable project anchor. Random agents do not share-edit it.
REGISTERED_RIG_SHARED_MUTATION=NO
REGISTERED_RIG_MUTATION_BY_RANDOM_AGENT=NO
LAYER_3 — Agent execution
Ephemeral git worktrees created from the registered rig checkout.
Target pattern:
REGISTERED_RIG
→ git worktree
→ bounded agent workspace
→ branch
→ commit
→ MR
→ cleanup
WORKTREE_PER_AGENT/BEAD=YES
AGENT_EXECUTION.EPHEMERAL=YES
BRANCH_PER_WORK=YES
Scale is one governed checkout plus many worktrees, not fifty clones of every project.
Upstream evidence (adopt, do not invent)¶
| Fact | Authority |
|---|---|
| A rig is an external project directory registered with the city | How Gas City works, Tutorial 01 |
gc rig add <project-directory> binds that directory |
Tutorial 01; gc rig add Long: "Register an external project directory as a rig" |
Portable names in city.toml; machine-local paths in .gc/site.toml |
Tutorial 01; released gc 1.3.2 / 1.4.1 |
dir is identity; work_dir isolates mutating sessions |
Coming from Gas City, config |
When work_dir is unset, rig-scoped agents use the rig root |
internal/workdir/workdir.go ResolveWorkDirPath |
Crew/polecat pre_start runs worktree-setup.sh which does git -C "$RIG_ROOT" worktree add into .gc/worktrees/<rig>/<agent> |
gascity pack assets/scripts/worktree-setup.sh; gascity example city.toml |
| Per-bead worktrees are reaped from the rig's own repository worktree list, excluding the main working tree | cmd/gc/bead_worktree_reaper.go |
gc tests seed a working-tree rig plus a separate bare origin |
initReapRig in bead_worktree_reaper_integration_test.go |
UPSTREAM_REGISTERED_RIG_MODEL=NON_BARE_PROJECT_DIRECTORY
UPSTREAM_AGENT_WORKTREE_MODEL=GIT_WORKTREE_FROM_RIG_ROOT_UNDER_CITY_.gc/worktrees
BLUEFLY_TARGET_MODEL=ADOPT_UPSTREAM
GAP=NONE
A bare origin remote in tests is GitLab's analogue, not the registered rig.
Default work_dir = rig root is why a bare registered rig would break ordinary file-editing agents. That is implementation confirmation of the docs, not a Bluefly invention.
Source intent vs live registration¶
These are SOURCE INTENT. They are not live-registration proof.
| Rig | GitLab identity | Source-intent Oracle path |
|---|---|---|
| blucity | https://gitlab.com/blueflyio/blu/blucity | /opt/bluefly/blucity |
| blucity-packs | https://gitlab.com/blueflyio/blu/blucity-packs | /opt/bluefly/rigs/blucity-packs |
| blucity-docs | https://gitlab.com/blueflyio/blu/blucity-docs | /opt/bluefly/rigs/blucity-docs |
LIVE_ORACLE_REGISTRATION=NOT_ESTABLISHED_UNTIL_MAYOR_PROOF
Mayor on Oracle (HOSTNAME=bluefly-platform, VENUE=ORACLE) inspects each candidate with content, not directory name:
RIG=
PATH=
REMOTE=
HEAD=
DIRTY=
CONTENT_IDENTITY=
REGISTERED_BY_GC=
SOURCE_INTENT_MATCH=
A Cursor cloud agent that is not on Oracle must STOP. /opt/bluefly absent and :3308 absent is not Oracle proof.
Duplicate copies are classified by GitLab remote, HEAD, dirty state, Gas City registration, runtime consumer, and contents. Not by directory name. Not by inventing a bare-repo layer.
Deploy validation¶
Current Bluefly deploy validation (path exists, is git repo, origin matches) is our contract. It is not proof that Gas City supports bare repositories as a proper execution model.
DEPLOY_VALIDATION_SHOULD_EVENTUALLY_PROVE_NON_BARE_WORKTREE=YES
SOURCE_VALIDATION_CHANGE_REQUIRED=CANDIDATE
A later bounded MR may add:
git rev-parse --is-bare-repository==falsegit rev-parse --is-inside-work-tree==true
only after citing the current upstream tests named above. Do not ship that check in the same change as path-ownership cleanup. Do not treat passing today's exists/is-git/origin checks as architecture.
What this does not change¶
- ADR-0023: GitLab remains Source Authority; NAS remains Recovery Authority; Mac remains Development client.
- NAS bare clones may still exist as recovery or as a Mac worktree source. They are not Gas City registered rigs.
blu-cli/blu-worktreeagainstAGENT_PLATFORM_HOMEbare storage is a different product surface. Do not reuse it as the Gas City rig model.
Rule¶
GitLab stores the canonical repository. Oracle holds the registered working checkout. Agents work in ephemeral worktrees. Do not use bare repos to solve a path-ownership problem. Do not use directory names to solve a content-identity problem. Do not send Oracle proof to Cursor.