Bluefly Factory Operating Contract¶
Current docs.gascity.com is the primary authority for Gas City semantics. This document is Bluefly policy and configuration. It must conform to upstream, not reinterpret it.
Gas City orchestrates agent fleets. Bluefly owns governance, products, and provenance around that orchestrator. Build with the platform, never around it.
Three-Layer Operating Architecture¶
The factory operates across three distinct governance layers:
1. Engineering Standard (BluCity-Docs): Canonical, human-readable doctrine ("what Bluefly's rules are and why").
2. Cedar Policies (cedar_policies): Machine-parsable, schema-validated authorization PDP rules enforcing deterministic Allow | Deny decisions at mutation boundaries (cedar-factory-authorization-standard.md).
3. Gas City (BluCity): Native orchestration runtime selecting workers, dispatching formulas, handling orders, and enforcing Cedar policy decision gates prior to mutation.
Descriptive agent prompts tell workers what they should do (advisory). Cedar policy gates enforce what mutations are mechanically allowed (deterministic PDP/PEP).
Document split¶
This file owns why the factory exists and the durable model: Gas City primitives, authority boundaries, Git completion law, and upstream-first operating philosophy.
How humans and Agents operate BluCity lives in blucity-operator-contract.md: command classes, operator vs Agent responsibility, safety and mutation boundaries, and discovery rules.
Exact gc commands live in the version-specific capability map in cli-resources-reference.md. Re-verify that map against the installed binary after a platform upgrade. Do not copy a command dump into this file.
Git completion law (ES-GITCC): git-completion-contract.md. This factory contract does not restate the command sequence.
Authority order (Gas City work)¶
When two sources disagree, do not silently pick the one that fits an old Bluefly assumption. Record both URLs. Escalate genuine upstream conflict.
1. CURRENT docs.gascity.com
2. Current official Gas City specs / reference / runbooks
3. Current upstream implementation and 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 (this file and siblings)
7. Historical chats / old artifacts
Upstream source/docs outrank Bluefly interpretation. If this file disagrees with current docs.gascity.com or the installed gc, the defect is here: DOC_DRIFT=YES. Fix this file. Do not change working source to match stale doctrine.
Six primitives¶
Upstream defines six canonical primitives. Nothing else is a primitive. (How Gas City Works)
| Primitive | Role | Is |
|---|---|---|
| Agent | WHO | Pack-configured worker: name, provider, prompt, scope. The platform hardcodes zero roles. |
| Bead | WHAT | One unit of durable work. Tasks, mail, sessions, and convoys are beads differing by type. |
| Formula | HOW | A reusable written method. Applying it materializes a bead graph that outlives the file and any session. |
| Rig | WHERE | An external project, usually a Git repository, with its own bead namespace and agent scope. |
| Pack | CONFIGURES | Unit of configuration. Declares agents, formulas, and orders. The City is the local/root pack plus deployment details. |
| Event | OBSERVE | Outbound notification fired by activity. Not polled. |
Roles such as Mayor, Witness, Refinery, Polecat, and Deacon, and constructs such as Session, Order, Convoy, Drain, Provider, City, and Supervisor, are mechanisms and configuration around those primitives, not additional primitives. A reviewer, mayor, planner, or worker is an Agent a Pack supplies. (How Gas City Works)
Convoy and Drain exist. They are not peers of the six. Drain is a Formula v2 fan-out construct. (Formula spec v2)
Sling (gc sling) is the one-shot create-and-route operation. Orders trigger formulas automatically. (Understanding Formulas)
Agents recover context with bd prime when needed, then pull routed work: gc hook → bd show → bd update --claim. Do not treat bd prime as the work picker or replace the hook with fleet-wide bd ready. Full execution contract: beads-work-ownership-contract.md.
Gas Town is a pack configuration of this engine, not a second platform. Do not treat Gas Town vocabulary as native Gas City architecture.
City, pack, and rig binding¶
A City is the local/root Pack plus deployment details. (Tutorial 01)
| File | Owns |
|---|---|
pack.toml + pack dirs |
Layer 1: Portable team behavior and configuration (agents/, commands/, doctor/, formulas/, orders/, template-fragments/, overlay/, assets/). Shared behavior arrives through explicit pack imports. |
city.toml |
Layer 2: Portable rig identity/declaration and city deployment/runtime settings (including upstream model endpoints, provider choices, and pack patch blocks). |
.gc/site.toml + .gc/ |
Layer 3: Machine-local rig path bindings and runtime state. Hard Law: Never commit .gc/ runtime state into packs. |
That is the governing model for the installed gc 1.4.x line, matching Tutorial 01. Do not document city.toml path= as the current normal model.
Agent 5-Axis Model¶
Upstream explicitly models an Agent through five independent, orthogonal configuration axes (Configuring an Agent):
- Per Agent: HARNESS (CLI), MODEL, UPSTREAM (Provider/gateway), TRANSPORT (Driver)
- City / Environment-wide: RUNTIME (Session execution environment)
Do not collapse these into one field called
provider. Gas City historically overloads that term (agent provider= harness,session provider= runtime backend). Use explicit terms:HARNESS,MODEL,UPSTREAM,TRANSPORT,RUNTIME.
Bluefly must not create custom model-routing platforms. Native upstream declarations in city.toml configure model providers (including cloud providers, LiteLLM gateway, or local LM Studio http://blu.tailcf98b3.ts.net:1234), with secrets referenced as $VAR and backed by 1Password runtime environment (STD-AUTH-001 / AUTHENTICATE_ONCE=YES).
Machine Automation (JSON Contract Law)¶
All software, hooks, dashboards, scripts, and agents calling gc MUST use --json or --json-schema, evaluate exit codes, and MUST NOT parse TTY formatting or grep human output (Using JSON from gc).
External Messaging API (extmsg) & Interaction Semantics¶
Gas City's external messaging API (Connected Clients) supports external clients participating in an active City session via HTTP/SSE (POST /v0/extmsg/clients → GET /v0/extmsg/.../subscribe → POST /v0/extmsg/inbound).
Interaction Semantics:
extmsgis candidate infrastructure for conversational/session interactions (e.g. Drupal conversational UI). Do not presumeextmsgreplaces Tool API, ECA, MCP, Orders, or governed work actions. For deterministic product actions (workflow advancement, tool execution, CMS mutation), Tool API, MCP, Events, or Orders remain the correct primitives. Evaluation ladder: 1.extmsg(for session chat) → 2. MCP → 3. Tool API → 4. Thin adapter.
Communication Law (binding)¶
Claude-native messaging is not an inter-agent control plane. Agent-to-agent and agent-to-operator communication goes through Gas City mail. Chat transcripts are not durable, not addressable, not auditable, and vanish with the session.
gc sling = durable work routing -- assign a Bead to an agent
gc mail send = agent / operator communication
Beads = durable work state, evidence, blockers, completion
Claude chat = NOT a control plane
Usage:
# agent to agent
gc mail send <session-alias> --from <sender> -s "<subject>" -m "<message>"
# agent to operator
gc mail send human --from <sender> -s "<subject>" -m "<message>"
# durable work assignment
gc sling <target> <bead-id>
Addressing constraint, verified 2026-09-13. gc mail send resolves a session
alias or human -- not an agent qualified name. --all broadcasts only to live
sessions. If the recipient's session is not materialised the address does not resolve:
gc mail send harbormaster returned unknown recipient "harbormaster": session not
found while organization.harbormaster was configured but asleep.
When the recipient is unavailable, do NOT fall back to Claude messaging. Route the
work durably with gc sling and let the session receive it when it materialises, then
continue with other executable work. A handoff that exists only in a chat transcript is
not a handoff.
Distinguish the two states honestly. gc sling succeeding means
HANDOFF_DURABLY_RECORDED=YES; it does not mean EXECUTION_STARTED=YES. Verify
pickup separately rather than reporting a routed bead as work in progress.
Rigs are registered with gc rig add. Isolation is by issue_prefix, not a separate database.
Beads / Dolt topology¶
ONE DOLT SERVER PER CITY
+ CITY + RIG .beads/ SCOPES
+ ISSUE_PREFIX FILTERING
The city and all normal rigs resolve to one Dolt server. Each scope has its own .beads/config.yaml and issue_prefix. bd applies that prefix as a hard query filter. From a rig, you see that rig's namespace. From the city root, you see only the city namespace.
This is not a federated bd list and not one independent Dolt server per rig. gc bd --rig is directory routing, not federation.
Recorded upstream wording gap (do not collapse into a third model): Beads Storage Topology describes isolation as issue_prefix query filtering on one Dolt server. Managed-city endpoints also describes each rig as a logical database inside that same server (database "hq", database "<rig-prefix>"). Both agree on one Dolt process per city and no inherited-rig local server. Bluefly's deploy/oracle/beads-topology.yaml takes the second reading: inherited endpoint plus a unique dolt_database plus a unique issue_prefix. Compatible. Not a license for per-rig Dolt processes.
native_store_unavailable / gate=identity_match¶
This is a Gas City native-store preflight gate, not a missing remote ledger.
gc prefers an in-process NativeDoltStore. Preflight must pass. Known gates include identity_match, dolt_mode_safe, version_compat, and bd_context_agreement. Failure means the native store is off and gc falls back to per-call bd (slower), or reports native_store_unavailable. It does not mean invent a second Dolt, federate bd list, or copy Oracle .beads/dolt into git.
| Symptom | What it actually is | What it is not |
|---|---|---|
gate=identity_match / metadata project_id is missing |
.beads/metadata.json project_id does not match the Dolt database _project_id, or the key is absent so the match cannot run. |
Proof the ledger is empty. Proof you need a local store. |
gate=dolt_mode_safe |
Native store requires dolt_mode=server. Embedded mode is a different open of a different directory. |
A storage-mode flip is not data migration. |
Empty bd list from a scope |
Prefix filter. From the city root you see only the city prefix. From a rig you see only that rig. | Federated emptiness. Missing remote. |
Prefix bc against database hq |
Wrong issue_prefix on the city scope. bd queries bc-* and never sees hq-*. |
A second city. |
Portable source vs runtime identity (resolved)¶
The open question is not “which ledger.” It is what Git may carry vs what bind must inject.
| Layer | Lives in | Contents |
|---|---|---|
| Portable city Beads contract | Tracked .beads/config.yaml, .beads/metadata.json, .beads/.gitignore |
issue_prefix: hq; dolt_database: hq; dolt_mode: server; gc.endpoint_origin: managed_city as the unbound default (if this clone were started unmanaged, gc start would own Dolt). Types. No host, port, or project_id. |
| Oracle deployment topology | Tracked deploy/oracle/beads-topology.yaml |
Live endpoint: city_canonical @ 127.0.0.1:3308, database hq, city root /opt/bluefly/blucity. Rig tuples: inherited endpoint + unique dolt_database + unique issue_prefix. |
| Bind / runtime identity | Not Git. Written by gc-site-bind / gc beads city use-external onto the live checkout |
Live gc.endpoint_origin: city_canonical; host/port; .beads/dolt-server.port mirror; metadata.json project_id matching the Dolt _project_id; .gc/site.toml paths. |
managed_city keeps its upstream meaning: city owns Dolt lifecycle. Git recording that unbound default is a packaging fact. It is not a synonym for city_canonical and not “pre-bind portable source.”
project_id is runtime identity. Do not commit a live Oracle or Mac project_id. identity_match is a live preflight: missing project_id → native store off → BdStore fallback. Repair is bind-time injection against the existing city Dolt, not a second database. Observed Mac sequence (2026-09-09): missing project_id → gate=identity_match → fallback → metadata repaired → gate clears → all 14 rigs reconcile to the same city Dolt.
.beads/identity.toml is gitignored. A comment calling it “canonical, git-tracked” is false. Do not start tracking it in order to mint an identity.
Prefix contract: tracked city prefix is hq. A Mac checkout that rewrites hq → bc (or adds duplicate issue-prefix: bc) is runtime dirt on a non-authoritative city. Discard it. Do not push it. Prefix changes are ledger events.
Do not: bd init a replacement store, delete .beads/dolt, run gc doctor --fix as first repair, commit project_id, invent per-rig Dolt servers, or federate Mac/Oracle bd list.
Leftover nested Dolt stores (Mac, 2026-09-10)¶
Three on-disk Dolt areas under .beads/ are not interchangeable. DoltHub is not city authority. Do not dolt pull / merge / push / reset / init (or --force) to join them. Do not delete leftover stores as a Git change.
| Path | Role |
|---|---|
.beads/dolt |
Live Mac managed store. gc data_dir. 127.0.0.1:38991, database hq. Disposable / non-canonical runtime. |
.beads/.dolt |
Leftover nested Dolt repo. DoltHub origin bluefly/BluCity. Unrelated history. UNREFERENCED_LEGACY_STATE. |
.beads/embeddeddolt |
Inactive split store (gc doctor bd-split-store). |
| Oracle | Canonical runtime: city_canonical @ 127.0.0.1:3308 / hq. |
no common ancestor between .beads/.dolt and its DoltHub origin/main is expected leftover state, not a sync job. Mac managed_city @ :38991 and Oracle city_canonical @ :3308 are two deployments of the same city source, not a federated view of one store.
city.toml [dolt] port = 3308 is Oracle-shaped portable intent. The Mac listen port is runtime (.beads/dolt-server.port). Do not rewrite city.toml to 38991 to match the workstation.
A runtime project_id in gitignored .beads/identity.toml with none in tracked metadata.json is the portable-vs-runtime split. Do not commit project_id to Git to “fix” identity_match.
City agent law: BluCity .claude/rules/beads-scope.md. Topology comments: BluCity deploy/oracle/beads-topology.yaml.
City-generated gc-beads-bd shim (Mac, 2026-09-10)¶
Gas City 1.4.1 owns the City-scoped generated shim. ~/.gc/scripts/gc-beads-bd.sh was contaminated leftover (it targeted a /tmp/gc-regress-* fixture). The duplicate HOME entrypoint was removed, not repaired in place. Do not restore it. Do not track .gc/scripts/ in Git.
Verified 2026-09-10 on the Mac workstation (absolute city-root path is runtime evidence, not portable source):
CANONICAL_SHIM=
<city-root>/.gc/scripts/gc-beads-bd.sh
HOME_SHIM=
ABSENT
HOME_SHIM_REFERENCES=
0
FIXTURE_EXECUTABLE_REFERENCES=
0
GC_BD_SHIM_CONVERGENCE=PASS
LOCAL_REGRESSION_FIXTURE_CONTAMINATION=REMOVED
DUPLICATE_HOME_ENTRYPOINT=REMOVED
CITY_GENERATED_ENTRYPOINT=AUTHORITATIVE
UPSTREAM_BUG=NO
DOLT_MUTATED=NO
BEADS_MUTATED=NO
No further shim work unless gc 1.4.1 regenerates a bad target.
Leave these completely separate (not this receipt):
BluCity/.beads/.dolt
= UNREFERENCED_LEGACY_STATE
= preserved for separate disposition
Mac Beads identity
= unresolved
gc reload [dolt] conflict
= unresolved
Endpoint origin¶
(Managed-city endpoints, Beads topology)
| Value | Meaning |
|---|---|
managed_city |
City owns the 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/uses its own explicit endpoint. |
managed_city = pre-bind portable source is wrong. Do not write it.
What survives as Bluefly policy¶
These are Bluefly ownership rules. They are not extra Gas City primitives.
GAS CITY OWNS ORCHESTRATION
BEADS HOLDS DURABLE WORK
FORMULAS HOLD REPEATABLE METHOD
RIGS DEFINE PROJECT SCOPE
PACKS CARRY REUSABLE CONFIGURATION
GITLAB OWNS SOURCE / CI / RELEASE
DRUPAL OWNS APPLICATION AND BUSINESS BEHAVIOR
DDEV IS AN EXECUTION SURFACE
AGENT SESSIONS ARE DISPOSABLE
CHAT IS NOT THE WORK GRAPH
WORK ON DISK IS NOT DONE
Git completion law: git-completion-contract.md. Valid completed work must be committed, pushed, MRed to release/v0.N.x, merged, merge-verified, and the worktree removed. A green MR is not done.
Drupal is a Rig from Gas City's engineering perspective. Drupal does not become a second engineering scheduler or a Beads replacement.
Custom code is operational liability. Use the highest upstream or composable layer that satisfies the requirement. Measure net code avoided or deleted, not only code produced.
Three orthogonal systems¶
The factory consists of three connected systems. They are Bluefly's composition, not a restatement of the six primitives.
1. Business object graph (Bluefly)¶
Defines what exists: Authority → Contract → Capability → Product → Repository → Deployment → Runtime.
These are durable business objects. They have identity and governance. They do not execute. They change only through reconciliation.
2. Runtime execution loop (Gas City)¶
Defines how work progresses.
A Formula materializes Beads. The orchestrator drives that graph: fans ready work to Agents in a Rig, gates steps on dependencies, retries failures, and completes outside any human session. Orders trigger formulas. Events observe. Sessions are disposable; work survives because Beads survive.
Bluefly never owns scheduling, orchestration, retries, review loops, worker allocation, parallel execution, or convergence logic. Those belong to Gas City.
3. Evidence graph (Bluefly)¶
Defines what happened. Receipts are immutable. Corrections create new receipts. The system asks what changed since the previous reconciliation, not "what happened?" Beads are the durable work ledger.
Core principle¶
Every capability converges toward its smallest stable owner.
Local ownership is temporary. The burden of proof is on keeping custom ownership.
Engineering principles¶
Adopt before build. Use existing platform capabilities first.
Configure before customize. Prefer Packs, Formulas, Orders, contracts, schemas, runtime configuration, and provider configuration before writing code.
Compose before extend. Compose the six primitives. Do not invent a seventh.
One authority. Every capability has exactly one authoritative owner.
Declarative runtime. Desired state belongs in configuration. Execution belongs to Gas City.
Platform over project. Never optimize a single repository at the expense of the factory.
Authority boundaries¶
| Authority | Owns |
|---|---|
| GitLab | Source history, merge authority, CI/CD, packages, releases |
| Gas City | Orchestration: Agents, Formulas, Rigs, Packs, Events, sessions, orders |
| Beads | Durable work state |
| Drupal | Application and business behavior, as a Rig |
| DDEV | Local Drupal execution surface |
| IaC | Deployment and runtime configuration of the City |
| 1Password | Secret storage and delivery |
| Oracle | Production Gas City runtime |
| NAS | Private appliance / backup / artifacts — not a second City |
| Bluefly | Governance, contracts, capabilities, products, deployments, provenance |
Do not list Mayor, Molecule, Polecat, Witness, Refinery, or Deacon as Gas City primitives. Those are pack-configured agents or Formula constructs.
Bluefly operating lanes (BLU, MAYOR, REFINERY, FOUNDRY, DRUPAL, SENTINEL, WITNESS, HARBORMASTER, FORGE) are the team command model. They are not additional primitives. Canonical: agent-team.md (TEAM-CMD-001).
Ownership convergence¶
Need capability
│
▼
Already owned? ──Yes──► Integrate
│ No
▼
Can ownership move upstream? ──Yes──► Contribute
│ No
▼
Own the smallest possible surface
│
▼
Continuously delete local ownership
Factory Modes¶
Light Factory (Default)¶
Use upstream Drupal, contributed modules, standard libraries, existing GitLab components, native Gas City primitives, public packs, and standard protocols.
Dark Factory (Exception Only)¶
Bluefly builds custom code only when an upstream requirement genuinely cannot be met. Every Dark Factory component must have: - Documented upstream gap - Smallest viable scope - Clear owner and maintenance cost - Defined replacement/exit strategy
Preferred extension order¶
- Existing upstream / platform capability
- Pack
- Formula
- Order
- Existing Agent (pack-configured)
- Runtime / provider configuration
- Existing contract or schema
- Thin adapter
- Custom implementation
If any higher layer satisfies the requirement, stop. Do not create another abstraction.
Deployment model¶
| Surface | Role |
|---|---|
| Developer workstation | Development only. Never authoritative. Operator client, not a second City. |
| GitLab | Source, merge, CI, release, package authority. |
| Oracle | Production Gas City runtime. City root /opt/bluefly/blucity. |
| NAS | Private appliance, backup, artifacts. Not a second City. |
Developer workstations are never production infrastructure.
GitLab release lifecycle¶
GitLab owns source, merge, CI, packages, and releases. This is why, not a second orchestrator.
Normal feature delivery must not require Thomas. Agents and CI own:
feature/fix/chore → release/v0.N.x → development package/tag → keep the promotion MR current
Thomas owns only when release/v0.N.x is ready to promote to main.
FEATURE_TO_RELEASE_AUTOMATIC=YES
THOMAS_FEATURE_MERGE_REQUIRED=NO
AUTOMATIC_MAJOR_BUMP=NO
AUTOMATIC_MINOR_BUMP=NO
AUTOMATIC_PATCH_BUMP=YES
PROMOTION_MR_AUTO_CREATE=YES
PROMOTION_MR_AUTO_UPDATE=YES
PROMOTION_MR_DUPLICATES=0
RELEASE_TO_MAIN_AUTO_MERGE=NO
CUSTOM_RELEASE_CI_PER_PROJECT=NO
SHARED_RELEASE_COMPONENT=gitlab_components
Implement the lifecycle once in blueflyio/gitlab_components. Do not invent unique release YAML in consumer projects. Canonical development tags are 0.N.(patch+1)-dev.K (example 0.1.5-dev.1). Composer uses dev-release/v0.N.x. Branch model, patch-only versioning, and the development sequence are git-standard.md. Agent completion and promotion-gate behavior are git-completion-contract.md. Human vs agent duties are blucity-operator-contract.md.
Complete Factory Architecture¶
HUMAN AUTHORITY
│
exceptional gates only
│
▼
┌─────────────────────────────────────────────────────────────┐
│ DRUPAL │
│ product / CMS / ECA / workflow / customer UX │
└─────────────────────────────┬───────────────────────────────┘
│
Tool API / MCP / extmsg
│
▼
┌─────────────────────────────────────────────────────────────┐
│ GAS CITY │
│ │
│ Orders Formulas Beads Hooks Packs │
│ │ │ │ │ │ │
│ └──────────┴───────────┴──────────┴───────────┘ │
│ │ │
│ Mayor / Polecats / specialists │
└─────────────────────────────┬───────────────────────────────┘
│
governed work
▼
┌─────────────────────────────────────────────────────────────┐
│ GITLAB │
│ │
│ source → MR → gitlab_components → CI → event │
└─────────────────────────────┬───────────────────────────────┘
│
└──────────────┐
▼
Gas City Order
│
continuation
│
▼
Beads
Configuration over code¶
Prefer Packs, Formulas, Orders, contracts, schemas, runtime manifests, provider configuration, prompt configuration, and scale policies.
Avoid custom orchestrators, custom schedulers, custom review systems, custom deployment engines, repository-specific infrastructure, duplicate runtimes, and AI chat frameworks as platforms.
JSON Contracts for Machine Automation¶
Any Bluefly automation, dashboard, hook, test, or agent invoking gc must use --json:
gc ... --json
Use --json-schema to discover and validate contracts.
SOFTWARE_CALLING_GC:
MUST:
use --json when supported
respect process exit code
validate expected schema fields
prefer --json-schema contracts
MUST NOT:
grep human tables
regex terminal banners
parse column spacing
depend on prose status messages
Event-Driven Continuation¶
Polling is forbidden unless no upstream event mechanism exists. - GitLab CI webhooks → Gas City Orders → Formula / Bead transitions - Drupal / ECA events → Tool API / external messaging → Gas City turns - Events wake the system; they never wake Thomas.
Drupal ↔ Gas City Boundary¶
Drupal owns CMS content, workflow, and user state. Gas City owns engineering work, Beads, Orders, Formulas, and workers.
Handshake Decision Order:¶
- Can Gas City External Messaging (
/v0/extmsg) solve it? (HTTP client + SSE responses) - Can existing MCP tools solve it?
- Can Drupal Tool API + Gas City endpoints solve it?
- Thin adapter.
- Stop before building a custom platform.
AG-UI¶
Applications own presentation. Agents own intelligence. AG-UI owns interaction. Business capabilities should become MCP tools whenever possible.
Applications must not own orchestration, provider SDKs, memory, vector search, prompt routing, streaming, or tool execution. Those belong to the platform.
Good platform citizenship¶
Every change should reduce ownership, increase declarative configuration, strengthen upstream capabilities, improve reproducibility, preserve one authority, reduce workstation dependency, remove duplicated logic, and leave the platform simpler than it was found.
The best implementation is usually the one that deletes code.
Decision gate¶
Before introducing implementation:
- Does current docs.gascity.com already provide this?
- Does the installed
gcalready provide this? - Can a Pack express it?
- Can a Formula execute it?
- Can an Order trigger it?
- Can an existing pack-configured Agent perform it?
- Can a Contract or Schema express it?
- Can MCP expose it?
- Can AG-UI present it?
- Can a thin adapter bridge the gap?
If the answer to any question is yes, stop. Use the platform.
Only after every option is exhausted may custom implementation be proposed, with evidence that the platform could not satisfy the requirement.
Git completion law¶
Binding: git-completion-contract.md (ES-GITCC). Docs agents are in scope.
Work on disk is not done. A commit is not done. A pushed branch is not done. An open MR is not done. A green MR is not done.
VALID_COMPLETED_WORK + UNCOMMITTED = FAILURE
VALID_COMPLETED_WORK + UNPUSHED = FAILURE
VALID_COMPLETED_WORK + NO_MR = FAILURE
GREEN_MERGEABLE_MR + NOT_MERGED = FAILURE
MERGED_MR + ABANDONED_WORKTREE = CLEANUP_FAILURE
Normal flow: feature/fix/chore → release/v0.N.x → development package (artifact projects) → main only through the separate governed promotion process. Never feature → main. Never main → release/v0.N.x. Never auto-merge release → main. Never ask Thomas to merge ordinary feature work. Feature beads close after release integration; they do not wait for main. Binding: git-standard.md and git-completion-contract.md.
Do not accept a polecat-done handoff of unpushed branches, or WIP that is uncommitted and has no authorizing Bead. If merge is unauthorized: BLOCKED_BY=MERGE_PERMISSION_OR_OPERATOR_GATE. Do not claim completion.
Contrib-First and Net-Negative Ownership¶
Bluefly adopts existing Drupal, Gas City, GitLab, and established open-source capabilities before creating local implementations. Custom implementation is permitted only when an evidenced capability audit shows that native configuration, an upstream extension point, a maintained ecosystem project, or a thin standards-based integration cannot satisfy the requirement. Success is measured as ownership removed or avoided while preserving: - required behavior; - authorization and security boundaries; - observability and evidence; - operational recoverability; - upstream compatibility. Lines of code removed may support this assessment, but line count alone is not the governing metric. Product priorities, repository-specific designs, module names, routes, package versions, and implementation sequences belong in Beads and owning repositories, not in this operating contract.
Gas City Operations Authority¶
Gas City operational procedures are not duplicated here. Operators must use the current upstream runbooks for:
- failed gc start diagnosis;
- managed-city endpoint ownership and recovery;
- Dolt bloat and compaction;
- bd auto-backup cleanup;
- hardened remote-city operation;
- split storage-class migration.
Bluefly documentation records only:
1. the selected deployment profile;
2. Bluefly-specific deviations;
3. version compatibility;
4. authorization boundaries;
5. verification evidence.
When current upstream documentation conflicts with this contract, classify the difference as DOC_DRIFT and reconcile the affected Bluefly documents before changing runtime state.
Endpoint Topology¶
Endpoint mutations must use gc rig set-endpoint. Inherited port files are mirrors and must not be hand-edited.
Dolt Health Obligations¶
Operators must monitor dolt-noms-size, bd-backup-size, compaction quarantine, backup ownership, recovery capacity, and escalation based on upstream Gas City runbooks.
Split Storage Architecture¶
Split storage must remain disabled until the deployed binary and worker queries support gc ready (currently missing from installed versions).
Drupal Gateway¶
Drupal calls the Bluefly gateway. The gateway must enforce TLS, network boundary, signed write grants, unauthenticated read plane protection, replay/idempotency, and audit receipts.
Cedar Enforcement¶
TARGET_ARCHITECTURE: Cedar enforcement is planned. ENFORCED_AND_VERIFIED: Not yet active. Do not claim mutations cross a Cedar PEP until real negative tests prove it.