Skip to content

Bluefly Factory Living Plan

Purpose: One continually curated working document for turning Bluefly's current factory into a Gas City-native autonomous work system. This is not a historical log. New findings should replace, reconcile, or delete stale guidance rather than being appended forever.

Current revision: 2026-09-24

1. North Star

Thomas should be able to submit one objective, leave, and return to either:

  1. a verified completed result, or
  2. a small number of decisions that genuinely require human authority.

Thomas must not be the message bus between ChatGPT, Claude, Codex, GitLab, terminals, or agents.

The acceptance test is simple:

One objective enters through the governed intake. A non-Thomas agent claims durable work, executes on a disposable surface, delivers through GitLab, Witness independently verifies the outcome, and BLU remains in the Gas City mail loop. No Thomas clipboard.

2. Architecture Lock

Use Gas City as Gas City intends. Do not build a second scheduler, agent framework, work graph, polling system, or orchestration layer around it.

The six Gas City primitives remain:

  • Agent = WHO
  • Bead = WHAT
  • Formula = HOW
  • Rig = WHERE
  • Pack = CONFIGURES
  • Event = OBSERVE

Surrounding mechanisms such as Mountain, Convoy, Mail, Order, Session, Provider, Sling, Hook/Claim, Wait, Receipt, and Evidence organize or operate those primitives. They are not additional primitives.

System authority remains:

  • Gas City: orchestration
  • Beads/Dolt: durable work and dependencies
  • GitLab: source, MRs, CI/CD, releases, chain of custody
  • BluCity-Docs: governed doctrine
  • ContextControl: governed human/context surface
  • Cedar/ContractPlane: authorization and policy decisions
  • OtterMon: observations, checks, findings, health, evidence, reverification
  • AgenticTools: reusable Agent, Skill, and Plugin source
  • LiteLLM: model gateway
  • Sessions/tmux/polecats: disposable execution surfaces, never work authority

3. Correct Gas City Control Model

Do not describe the factory as one fake linear pipeline.

Intent and durable work

Thomas / external system
        ↓
Mail / external-message binding
        ↓
BLU
        ↓
reconcile existing durable work first
        ↓
Mountain → Convoy → Bead
                    ↓
                  Agent
                    ↓
          disposable execution surface

Mail coordinates. BLU interprets and reconciles. Beads hold durable work. Mountains and Convoys organize objectives and bodies of work. Rigs scope where work belongs.

Event-driven automation

observed fact
     ↓
   Event
     ↓
Order trigger matches
     ↓
policy / execution gate
     ↓
Order action
     ↓
Formula or deterministic execution
     ↓
work / state / evidence changes
     ↓
new Event
     ↓
next eligible Order

Important correction:

  • Mail does not automatically become an Order.
  • An Order does not automatically become an Event.
  • Events can satisfy Order triggers.
  • Orders decide when reusable work runs.
  • Formulas encode repeatable methods.
  • Events replace polling.
  • Waits block on conditions without burning a model session.

4. BLU's Job

BLU is a Gas City-native coordinator, not a parallel orchestrator and not an implementation worker.

BLU should:

  • receive and interpret intent
  • inspect durable state
  • reconcile against existing Mountains, Convoys, and Beads
  • create or refine durable work only when necessary
  • resolve ownership and authority
  • route work through Gas City
  • use Mail for coordination
  • request independent verification
  • reconcile receipts and outcomes
  • escalate only genuine human-only decisions

BLU should not:

  • implement source changes
  • supervise shell commands turn by turn
  • maintain a private TODO system
  • keep giant reasoning sessions alive as work authority
  • poll CI
  • recreate Gas City scheduling in chat, tmux, CMUX, scripts, or another agent framework

BLU's desired steady state is small context, waiting on Mail.

5. Disposable Workers

Claude, Codex, OpenCode, self-hosted models, tmux sessions, polecats, and similar surfaces are replaceable workers.

They may:

  • claim bounded work
  • retrieve the minimum necessary context
  • execute
  • test
  • persist source/evidence
  • deliver
  • exit

They must not become the durable memory or orchestration authority.

If a session dies, the factory must be able to continue from Beads, source, events, evidence, and receipts.

6. Reuse Before Build

Before creating anything:

DOES GAS CITY ALREADY OWN THIS?
DOES BLUCITY-PACKS ALREADY CONTAIN IT?
DOES AGENTICTOOLS ALREADY OWN IT?
DOES GITLAB ALREADY OWN IT?
DOES DRUPAL CORE/CONTRIB ALREADY OWN IT?
DOES ANOTHER UPSTREAM PROJECT OWN IT?

If yes, configure, compose, project, or thinly adapt it. Do not recreate it.

The current factory problem is primarily unwired, degraded, duplicated, or unverified capability, not lack of capability.

7. First Proof: Thomas-Away Test

Do not expand the factory until one complete autonomous lifecycle works.

Test

Thomas submits one real objective through the governed intake and then stops participating for 2 to 4 hours.

The system must:

  1. receive the objective through Mail or the Gas City external-message binding
  2. let BLU reconcile it against existing work
  3. attach to existing Mountain/Convoy/Bead where possible
  4. create/refine durable work only if required
  5. route the Bead through Gas City
  6. let the correct agent claim it atomically
  7. execute on a disposable surface
  8. use existing Formula/Pack capability rather than bespoke prompting
  9. emit Events as state changes
  10. let Orders react to those Events
  11. use GitLab for delivery and CI
  12. use waits/events rather than model polling
  13. route failures automatically where policy permits
  14. request independent Witness verification
  15. reconcile evidence and receipt
  16. close or advance durable work
  17. contact Thomas only for a genuine human authority gate

Pass condition

THOMAS_COPY_PASTE=0
SIDE_CHANNEL_ROUTING=0
MODEL_POLLING=0
DUPLICATE_WORK_CREATED=0
NON_THOMAS_AGENT_CLAIMED=YES
DISPOSABLE_EXECUTION=YES
GITLAB_DELIVERY=YES
WITNESS_INDEPENDENT_VERIFICATION=YES
BLU_STAYED_IN_MAIL_LOOP=YES
FINAL_RECEIPT=YES

Every place Thomas had to intervene becomes evidence of a missing or broken factory connection. Fix those connections before adding more architecture.

8. Immediate Execution Order

Gate Zero: make the native factory trustworthy

Before claiming autonomy, restore and prove the native Gas City work path.

Current known issues requiring runtime re-verification include:

  • Beads/Dolt client/schema compatibility
  • controller health and degraded native_store_unavailable behavior
  • claim/lease path
  • Rig metadata health
  • pack locking/reproducibility
  • degraded patrol behavior
  • agent roster/identity consolidation
  • service identities instead of Thomas's credentials

Do not treat these historical observations as current truth. Re-observe runtime state before acting.

Then prove one connected graph

Choose one existing Convoy with real work. Do not create a showcase-only demo.

Prefer an objective whose existing capabilities already exercise:

  • Mail
  • Bead claim
  • Formula
  • Event
  • Order
  • GitLab MR/CI
  • Wait
  • Witness
  • Receipt

Wire what already exists. Do not rewrite existing formulas merely to make the demonstration cleaner.

9. External Interfaces

The default rule is: external systems enter Gas City, not the other way around.

Preferred pattern:

ChatGPT / ContextControl / external client
              ↓
      Gas City external-message/API boundary
              ↓
             Mail
              ↓
             BLU

MCP exposes tools/capabilities to compatible clients. External agent interoperability protocols may be useful at the boundary, but they must not become another work authority or scheduler.

tmux is an execution surface only.

Any ChatGPT-facing bridge must use a service identity and scoped authority. Never Thomas's personal credentials.

10. Human Authority Gate

Thomas should be interrupted only when policy requires human authority, such as:

  • destructive or irreversible operations outside delegated bounds
  • secret rotation or access that requires the human credential holder
  • security-sensitive approval that policy reserves for a human
  • material spend/budget decisions outside delegated limits
  • legal/commercial commitments
  • ambiguous product decisions with no accepted governing policy
  • explicit release/production approvals that remain human-owned

Everything else should route, wait, retry, fail, or escalate inside the factory.

11. Context and Cost

Do not solve memory by stuffing larger prompts.

Retrieval should follow authority:

documentation question → QMD → governing document
code question          → chosen code graph → source
work state             → Beads/Dolt
source/MR/CI            → GitLab
runtime                 → direct observation
policy                  → Cedar/accepted standards

Send only the relevant evidence to the model.

Models are capability providers, not work authority. Use provider-independent capability classes and measure cost per verified completed Bead, not merely token price.

12. Continuous Curation Rule

This document is a living plan, not an append-only notebook.

Every update should do one of four things:

  • KEEP a still-correct rule
  • REPLACE stale guidance with better evidence
  • MERGE duplicate ideas
  • DELETE obsolete ideas

Do not add a second master plan.

When this document conflicts with current runtime evidence, current source, an accepted Engineering Standard/ADR, canonical product specification, or newer explicit operator direction, update this document so the conflict disappears.

13. Current Decision

The next milestone is not another architecture project.

It is:

Make one existing Gas City lifecycle autonomous end to end, with Thomas absent from the transport path.

Only after that passes should the factory scale the pattern to additional Convoys, Rigs, and product operations.

14. Proof Sequence After the Thomas-Away Test

The first test proves that Gas City can carry work without Thomas acting as transport. The next tests prove that ContextControl can become the governed human/control surface without becoming a second orchestrator.

The sequence deliberately grows one dimension at a time.

Test 2 — ContextControl Mirrors the City

Question: Can Drupal show the current Gas City operating state using Gas City's own API contracts, with no duplicate work authority?

Goal: Recreate the useful visibility of the Gas City dashboard inside ContextControl using Drupal-native configuration and the existing api_normalization capability.

Current evidence says the Gas City Supervisor exposes an OpenAPI 3.1 surface with 127 paths, including status, Beads, Convoys/graphs, Events, Mail, sessions, Rigs, Packs, providers, waits, run census, usage, patches, and external-message endpoints. ContextControl has already demonstrated importing the Gas City OpenAPI contract into api_normalization as gascity_v1 with 127 endpoints.

POC scope:

  1. Revalidate the live Gas City /openapi.json. Runtime wins over the previously imported copy.
  2. Import or refresh that contract through api_normalization.
  3. Treat imported endpoint definitions as Drupal's integration metadata, not as a copy of Gas City state.
  4. Start read-only with a deliberately small API slice:
  5. city/status
  6. ready/open/in-progress work
  7. Convoy/Bead graph
  8. Events/event stream
  9. Agents/sessions
  10. run census/usage
  11. Build the operator UI with existing Drupal capability in this order:
  12. fieldable entities/configuration only where persistence is genuinely required
  13. Views
  14. Canvas/SDC
  15. ECA for Drupal-side reactions
  16. Drupal AI only where semantic interpretation adds value
  17. Show one city overview page and one work-detail page.
  18. Prove that every displayed item links back to its authoritative Gas City identifier and current source.
  19. Do not poll from an LLM. Prefer the Gas City event stream/events for change notification. If a small deterministic refresh is required for the first POC, mark it as temporary and replace it with the native event path.

Minimum visible UI:

CITY
  health / controller state

WORK
  Mountain → Convoy → Bead
  ready / claimed / blocked / completed

EXECUTION
  Agent → Session → Provider
  current Formula / run

EVENTS
  recent city events

ECONOMICS
  run census / usage

EVIDENCE
  verification / receipt state

Hard boundary: ContextControl observes and governs. Gas City remains the orchestration authority. Drupal must not invent a second Bead state machine, scheduler, retry engine, agent lifecycle, or durable work graph.

Pass condition:

LIVE_OPENAPI_IMPORTED=YES
CUSTOM_GASCITY_CLIENT=NO
DUPLICATE_WORK_STATE=NO
DRUPAL_NATIVE_UI=YES
CITY_OVERVIEW_WORKS=YES
WORK_DETAIL_WORKS=YES
AUTHORITATIVE_IDS_PRESERVED=YES
GAS_CITY_REMAINS_ORCHESTRATOR=YES

Test 3 — ContextControl Watches the City Live

Question: Can the Drupal surface update from Gas City Events instead of becoming another polling dashboard?

Goal: Prove one native Gas City lifecycle is visible in ContextControl as it happens.

Run the Test 1 objective again. ContextControl should show:

objective received
→ Bead routed
→ Bead claimed
→ execution started
→ Formula/run progressed
→ GitLab delivery changed
→ verification requested
→ Witness result
→ receipt / completion

Use Gas City Events as the change signal. ECA may translate those external facts into Drupal-side UI/cache/notification changes, but ECA does not own the work transition.

Pass condition:

EVENT_DRIVEN_VISIBILITY=YES
LLM_POLLING=0
DRUPAL_WORKFLOW_FORK=0
END_TO_END_RUN_VISIBLE=YES
EVENT_TO_AUTHORITY_TRACE=YES

Test 4 — Governed Human Action From Drupal

Question: Can a human safely initiate one Gas City operation from ContextControl without Drupal becoming the orchestrator?

Goal: Add exactly one write action after read-only visibility works.

Example:

ContextControl action
→ approved typed API capability
→ policy/authority check
→ Gas City external-message/Mail or native dispatch boundary
→ BLU reconciles durable work
→ Gas City routes
→ normal Test 1 lifecycle

Do not start by exposing all 127 API operations as buttons or unrestricted AI tools. The imported OpenAPI catalog is the discovery substrate. The product surface exposes only explicitly approved capabilities.

The first write operation should be low-risk and reversible, such as submitting a governed work request or requesting an existing Formula against a test Rig.

Pass condition:

ONE_APPROVED_WRITE_ACTION=YES
SERVICE_IDENTITY=YES
POLICY_CHECK=YES
BLU_RECONCILES=YES
DRUPAL_DIRECT_BEAD_MUTATION=NO
GAS_CITY_EXECUTES=YES
RECEIPT_RETURNS_TO_DRUPAL=YES

Test 5 — Drupal AI Explains, It Does Not Orchestrate

Question: Can Drupal AI help a team member understand city state without creating a competing agent/work system?

Goal: Give a ContextControl user a semantic operator assistant over the authoritative data already visible in Drupal.

Example questions:

What is blocked right now?
Why is this Convoy not advancing?
What changed since this morning?
Which work needs human authority?
What failed verification?
Where are we spending model cost?

The Drupal AI Agent receives only scoped, approved ContextControl/Gas City capabilities. It reads authoritative state and evidence, explains it, and may propose an approved action. It does not create its own hidden task graph or autonomous orchestration loop.

Reuse drupal/ai, ai_agents, ai_context, Tool API/MCP, and the existing OSSA bridge where current source confirms they fit. Classify any Drupal orchestration modules before enabling them. If they compete with Gas City for durable work authority, they stay disabled.

Pass condition:

AI_CAN_EXPLAIN_CITY=YES
SOURCE_LINKED_ANSWERS=YES
SCOPED_TOOL_ACCESS=YES
HIDDEN_WORK_GRAPH=NO
GAS_CITY_SOLE_ORCHESTRATOR=YES

Test 6 — Full Governed Operator Loop

Question: Can a normal Bluefly team member operate the factory from ContextControl without needing Gas City CLI knowledge?

Goal: Combine Tests 2 through 5 into the first real product loop.

Human sees city state in Drupal
→ asks Drupal AI what needs attention
→ reviews authoritative evidence
→ chooses an approved action
→ ContextControl checks human/policy authority
→ request enters Gas City
→ BLU reconciles and routes
→ disposable worker executes
→ GitLab carries delivery
→ Witness verifies
→ receipt returns
→ ContextControl shows outcome

This is the first meaningful proof of ContextControl as the governed human/control surface over Gas City, rather than a dashboard mockup.

Pass condition:

CLI_REQUIRED_FOR_NORMAL_OPERATOR=NO
THOMAS_COPY_PASTE=0
CONTEXTCONTROL_IS_HUMAN_SURFACE=YES
GAS_CITY_IS_EXECUTION_AUTHORITY=YES
POLICY_AND_IDENTITY_ENFORCED=YES
INDEPENDENT_VERIFICATION=YES
EVIDENCE_VISIBLE=YES
FULL_RECEIPT_VISIBLE=YES

15. Rule for These Tests

Do not build Tests 2 through 6 in parallel.

TEST_1  autonomous Gas City lifecycle
   ↓
TEST_2  read-only Drupal visibility
   ↓
TEST_3  event-driven live visibility
   ↓
TEST_4  one governed write action
   ↓
TEST_5  AI interpretation over governed capabilities
   ↓
TEST_6  complete operator loop

Each test must reuse the previous test's proven path. A failed test creates a repair Bead against the existing capability or authority owner. It does not justify a parallel subsystem.

The architecture test throughout is:

Could ContextControl disappear tomorrow and Gas City would still know exactly what work exists and what state it is in?

If the answer becomes no, Drupal has crossed the boundary and become a second orchestrator. Correct the design before continuing.

16. Production POC Contract

These tests are not simulations, demos, stubs, or architecture theater. They are incremental production proofs. Every test must use the real authority, real identity path, real API contract, real durable work, real delivery path, and real evidence path that the production product will use.

Product boundary

ContextControl is the commercial product and Drupal is its governed human/control surface. Gas City remains the orchestration and execution authority. The product may translate Gas City terminology for users, but it must not translate away authority.

Working product vocabulary:

ContextControl Gas City / Bluefly authority
Objective Mountain
Initiative Convoy
Work Item Bead
Workspace Rig
Procedure Formula
Automation Order
Signal Event
Capability Pack Pack
Agent Agent
Mail Mail
Run Session / disposable execution
Receipt Operational Receipt / evidence

The mapping is presentation metadata. The native identifiers remain preserved and inspectable.

Scientific method for every test

Each proof must record:

HYPOTHESIS=
CURRENT_AUTHORITY=
BASELINE=
UPSTREAM_OWNER=
CAPABILITY_MATCH=
MINIMUM_CHANGE=
TEST_INPUT=
EXPECTED_OBSERVATION=
FALSIFICATION_CONDITION=
ACTUAL_OBSERVATION=
EVIDENCE=
WITNESS=
RESULT=PASS|FAIL|PARTIAL
DEFECT_OR_NEXT_BEAD=
CUSTOM_LOC_ADDED=
CUSTOM_LOC_REMOVED=
DUPLICATE_CAPABILITIES_REMOVED=
OBSOLETE_FILES_REMOVED=
NEW_LONG_TERM_OWNER_SURFACES=
NET_OWNERSHIP_DELTA=
TEMPORARY_WORKAROUND_COUNT=0
STUB_COUNT=0
SIMULATION_COUNT=0

A repository change is not proof. Runtime behavior plus independent verification is proof.

No prototype debt

The POC must converge directly toward production. Therefore:

FAKE_DATA=NO
MOCK_GAS_CITY=NO
STUB_API=NO
SIMULATED_EVENT=NO, except an explicit contract test that is never presented as runtime proof
SECOND_WORK_GRAPH=NO
CUSTOM_SCHEDULER=NO
CUSTOM_AGENT_LOOP=NO
LLM_POLLING=NO
THOMAS_CREDENTIALS=NO
UNVERSIONED_PACK=NO
GENERIC_OPENAPI_TO_AI_TOOL_EXPLOSION=NO

Temporary compatibility code is permitted only when a proven upstream defect blocks the production path and the workaround has an owner, test, removal condition, and tracked defect. Otherwise fail the test rather than hide the failure.

Upstream substitution gate

Before source mutation, the assigned Agent must prove whether the need is already owned by Gas City, Drupal core/contrib, Drupal AI, Tool API/MCP, ECA, Canvas/SDC, GitLab, AgenticTools, BluCity-Packs, Cedar/ContractPlane, OtterMon, or another accepted upstream component.

Default disposition:

UPSTREAM_EXISTS      → CONFIGURE / COMPOSE / PROJECT
EXISTING_BLUEFLY_CAPABILITY → WIRE / REPAIR / VERIFY
REAL_GAP             → THIN ADAPTER ONLY
CUSTOM_CODE          → LAST RESORT

For ContextControl UI, preserve the assembly order:

Core
→ Contrib
→ Contrib configuration
→ Recipe/config action
→ Canvas/SDC
→ ECA/FlowDrop
→ Drupal AI
→ Tool API/MCP
→ Existing Bluefly extension
→ Custom code

api_normalization normalizes and stores API contract metadata. It must not mechanically generate an unrestricted AI tool for every imported endpoint. The current direction is the cleaned Content Entity model with source identifiers preserved. Do not restore removed generic plugin managers, wrapper tools, events, hooks, DTOs, or deleted speculative submodules merely to make a POC easier.

17. Execution Contract and Operational Receipt

Every consequential operation receives the same contract before dispatch and the same receipt after execution. This is the machine-checkable replacement for repeated prose instructions.

Pre-execution contract

OBJECTIVE=
INITIATIVE=
WORK_ITEM=
WORK_AUTHORITY=Beads/Dolt
SOURCE_AUTHORITY=
ROLE=
RESOLVED_AGENT=
AGENT_SOURCE=UPSTREAM|BLUEFLY|PROVIDER_DERIVED
OWNER=
WORKSPACE=
CLAIM=
UPSTREAM_OWNER=
CAPABILITY_MATCH=
SERVICE_IDENTITY=
POLICY=
DEPENDENCIES=
EXECUTION_SURFACE=
PROCEDURE=
AUTOMATION_TRIGGER=
ACCEPTANCE=
VERIFICATION=
DELIVERY_PATH=
EVIDENCE_PATH=
HUMAN_GATE=
FACTORY_GATE=PASS|FAIL|PARTIAL

No implementation dispatch when FACTORY_GATE != PASS. Read-only discovery is exempt.

Operational Receipt

Do not create a second receipt system. Extend and verify the existing Operational Receipt path. Every completed or failed operation must produce enough evidence to answer:

RECEIPT_ID=
OBJECTIVE=
INITIATIVE=
WORK_ITEM=
ROLE=
RESOLVED_AGENT=
AGENT_SOURCE=
AGENT=
SERVICE_IDENTITY=
WORKSPACE=
CLAIM_ID=
PROCEDURE=
RUN_ID=
SOURCE_REVISION_BEFORE=
SOURCE_REVISION_AFTER=
EVENTS_OBSERVED=
DELIVERY=
CI_RESULT=
WITNESS=
VERIFICATION_RESULT=
POLICY_DECISION=
EVIDENCE_REFERENCES=
MODEL_ALIAS=
ACTUAL_MODEL=
PROVIDER=
LOCAL_OR_PAID=
INPUT_TOKENS=
OUTPUT_TOKENS=
COST=
LATENCY=
RETRY_COUNT=
CUSTOM_LOC_ADDED=
CUSTOM_LOC_REMOVED=
DUPLICATE_CAPABILITIES_REMOVED=
OBSOLETE_FILES_REMOVED=
NEW_LONG_TERM_OWNER_SURFACES=
NET_OWNERSHIP_DELTA=
UPSTREAM_REUSE=
RESULT=PASS|FAIL|PARTIAL
UNLOCKS_NEXT_TEST=YES|NO
NEXT_ACTION=

The receipt should reference authoritative evidence rather than copying whole logs or creating a new evidence database. Cost fields may be blank until native telemetry provides them; never invent values.

18. Team Contract

Roles route to the narrowest owner. Agents do not expand their own scope to compensate for another broken role.

Role names are doctrine, not automatically runtime identities. Before dispatch, every role must resolve to a currently configured Gas City Agent, provider-derived worker, or imported upstream role. The execution contract records ROLE, RESOLVED_AGENT, AGENT_SOURCE, and SERVICE_IDENTITY. If no resolvable Agent exists, dispatch is blocked rather than silently substituting a chat session or Thomas.

Role Owns End state / receipt obligation Must not do
BLU intake, reconciliation, authority resolution, routing, Mail, receipts one connected durable graph, correct owner, final reconciled receipt implementation, CI polling, private TODO graph
MAYOR Gas City dispatch dispatch/claim path functions under native Gas City rules become Bluefly's second planner
HARBORMASTER cross-rig delivery, GitLab MR/release coordination source delivered through governed GitLab path with delivery evidence implement unrelated product logic
REFINERY deduplication, cleanup, convergence, retirement fewer duplicate/stale assets, explicit deletion/convergence evidence create replacements before classifying existing assets
FOUNDRY proven Bluefly-owned gaps smallest production implementation for a demonstrated gap rebuild upstream/contrib capability
DRUPAL ContextControl/Drupal architecture and implementation Drupal-native product surface using core/contrib/config first create a second Gas City work graph or custom PHP by default
SENTINEL security, secrets, service identity, policy exposure scoped non-human identity and security evidence use Thomas credentials or hide exposure
WITNESS independent verification independent PASS/FAIL/PARTIAL tied to acceptance and runtime evidence verify its own implementation
FORGE clean-consumer/reproducibility/release proof prove a fresh consumer can use the capability from released/versioned artifacts rely on developer-local state
DEACON deterministic patrol and lifecycle hygiene health/patrol evidence without model-token supervision perform semantic implementation work
POLECAT disposable bounded execution execute claimed Work Item, persist result/evidence, exit cleanly become durable work authority

Team invariants remain:

BLU_ROUTES=YES
BLU_EXECUTES=NO
MAYOR_DISPATCHES=YES
POLECAT_EXECUTES=YES
HARBORMASTER_DELIVERS=YES
REFINERY_CONVERGES=YES
DRUPAL_OWNS_DRUPAL=YES
SENTINEL_OWNS_SECURITY=YES
FORGE_PROVES_REUSE=YES
WITNESS_VERIFIES_INDEPENDENTLY=YES
FOUNDRY_BUILDS_ONLY_PROVEN_GAPS=YES
DEACON_PATROLS_DETERMINISTICALLY=YES

19. Proof Ownership Matrix

Each proof has one primary owner, supporting roles, one independent verifier, and one artifact that matters.

Proof Primary owner Support Witness verifies Required product evidence
Test 1: Thomas-Away BLU for routing; native Gas City dispatch for execution MAYOR, POLECAT, HARBORMASTER, SENTINEL WITNESS complete receipt with zero Thomas transport
Test 2: ContextControl Mirrors City DRUPAL FOUNDRY only for a proven integration gap; SENTINEL for read identity WITNESS live API contract imported, authoritative IDs preserved, read-only UI
Test 3: Live Visibility DRUPAL DEACON for deterministic health; FOUNDRY only for proven adapter gap WITNESS real Gas City lifecycle appears from real Events without model polling
Test 4: Governed Write DRUPAL for UX, BLU for reconciliation SENTINEL, MAYOR WITNESS one approved action enters Gas City with policy decision and receipt
Test 5: Drupal AI Explains DRUPAL SENTINEL for scoped tools, BLU for authority mapping WITNESS source-linked explanation over authoritative state, no hidden work graph
Test 6: Operator Loop DRUPAL for product surface, BLU for factory coordination all narrow owners as required WITNESS normal operator completes governed loop without CLI or Thomas transport
Test 7: Clean Consumer FORGE DRUPAL, HARBORMASTER, SENTINEL WITNESS fresh environment reproduces the product path from released artifacts
Test 8: Second Real Objective BLU same role system, no bespoke setup WITNESS second objective reuses the proven path with lower re-derivation
Test 9: Customer/Operator Proof PRODUCT/DRUPAL for UX; BLU for factory coordination SENTINEL for identity/policy; narrow runtime owners as needed WITNESS non-expert operator understands state, takes one safe action, and understands the receipt without CLI or Thomas

20. Tests 7 and 8: Production, Not Demo

Test 7 — Clean Consumer Reproduction

Question: Is the proven ContextControl + Gas City path actually a product capability, or does it only work on Thomas's development estate?

FORGE provisions a clean supported environment from released/version-pinned artifacts. No copying local state, no unpublished branch dependency, no personal credential, no hand-edited database, and no undocumented command sequence.

Pass condition:

CLEAN_ENVIRONMENT=YES
RELEASED_ARTIFACTS_ONLY=YES
PACKS_VERSION_PINNED=YES
SERVICE_IDENTITIES=YES
MANUAL_DB_EDIT=NO
LOCAL_MACHINE_SECRET_DEPENDENCY=NO
UNDOCUMENTED_FIXUP=0
PRODUCT_PATH_REPRODUCED=YES
WITNESS_PASS=YES

Test 8 — Second Real Objective

Question: Does the factory get cheaper and more reusable on the next real run?

Run a second materially different real objective through the same production path. Do not modify the architecture merely to accommodate the test. Measure reuse and failures against Test 1/Test 6.

Pass condition:

NEW_ORCHESTRATION_LAYER=NO
NEW_DUPLICATE_CAPABILITY=NO
THOMAS_COPY_PASTE=0
REUSED_PROCEDURES=YES
REUSED_AUTOMATIONS=YES
REUSED_PRODUCT_UI=YES
WITNESS_PASS=YES
COST_PER_VERIFIED_COMPLETED_WORK_ITEM_MEASURED=YES
RE_DERIVATION_REDUCED=YES

Passing Tests 1 through 8 proves a technically productizable, reproducible capability. It does not prove the product. Test 9 is required before we claim the operator experience is commercially usable.

Test 9 — Customer / Operator Proof

Question: Can a real user who does not know Gas City operate ContextControl successfully without Thomas or CLI knowledge?

This is the first commercial usability proof. The operator uses ContextControl product language, not Gas City jargon, while the receipt still preserves the native Gas City identities and evidence underneath.

The operator must be able to:

UNDERSTAND_OBJECTIVE=YES
UNDERSTAND_CURRENT_STATE=YES
IDENTIFY_BLOCKED_OR_ATTENTION_REQUIRED=YES
IDENTIFY_HUMAN_AUTHORITY_REQUIRED=YES
TAKE_ONE_POLICY_AUTHORIZED_ACTION=YES
SEE_LIVE_OUTCOME=YES
UNDERSTAND_RECEIPT=YES
GASCITY_VOCABULARY_REQUIRED=NO
CLI_REQUIRED=NO
THOMAS_INTERPRETATION_REQUIRED=NO
WITNESS_PASS=YES

Failure here is a product/UX defect, not permission to bypass Gas City or duplicate its state in Drupal.

21. Production Definition of Done

A feature is not done because a page renders, an Agent says success, a branch exists, or a test fixture passes.

It is done only when:

REAL_AUTHORITY_USED=YES
REAL_IDENTITY_USED=YES
REAL_API_CONTRACT_USED=YES
REAL_DURABLE_WORK_USED=YES
REAL_EVENT_OR_WAIT_PATH_USED=YES
REAL_GITLAB_DELIVERY_USED=YES, when source changes
POLICY_ENFORCED=YES
INDEPENDENT_VERIFICATION=YES
OPERATIONAL_RECEIPT=YES
AUTHORITATIVE_EVIDENCE_LINKED=YES
CUSTOM_CODE_JUSTIFIED=YES|NOT_REQUIRED
STUBS_REMAINING=0
SIMULATIONS_PRESENTED_AS_PROOF=0
TEMPORARY_WORKAROUNDS_UNTRACKED=0

The product rule is simple: fail visibly rather than fake success. Repair the production path rather than route around it.

22. Chain of Proof Law

The proof sequence is a dependency chain, not a roadmap that can be parallelized.

TEST_N+1_ELIGIBLE = TEST_N_PROVEN

No test may begin until the immediately preceding test has produced all of the following:

RESULT=PASS
EXPECTED_EVIDENCE=OBSERVED
FALSIFICATION_CONDITION=NOT_TRIGGERED
WITNESS_VERIFICATION=PASS
OPERATIONAL_RECEIPT=COMPLETE
RUNTIME_EVIDENCE=VALID
ADVANCEMENT_GATE=PASS
UNLOCKS_NEXT_TEST=YES

The following do not unlock the next test:

PASS_BY_ASSERTION=PROHIBITED
PASS_BY_REPOSITORY_STATE=PROHIBITED
PASS_BY_SIMULATION=PROHIBITED
PASS_BY_STUB=PROHIBITED
SKIP_TEST=PROHIBITED
PARALLEL_FUTURE_TEST_EXECUTION=PROHIBITED

Failure is also deterministic:

IF TEST_N = FAIL | PARTIAL | DEGRADED | UNVERIFIED
THEN:
  TEST_N+1 = BLOCKED
  CREATE_OR_REFINE_REPAIR_WORK = YES
  ATTACH_REPAIR_TO_FAILED_TEST = YES
  PRESERVE_EVIDENCE = YES
  RE-RUN_TEST_N = REQUIRED

Every test must declare its falsification condition before execution. An agent may not redefine success after seeing the result.

The chain is currently:

GATE_ZERO
→ TEST_1  autonomous Gas City lifecycle
→ TEST_2  minimal read-only ContextControl projection
→ TEST_3  event-driven live projection
→ TEST_4  one governed write action
→ TEST_5  AI explanation over governed capabilities
→ TEST_6  full operator loop
→ TEST_7  clean-consumer reproduction
→ TEST_8  second real objective
→ TEST_9  customer/operator proof

Test 9 is the commercial proof: a user who is not a Gas City expert can understand the product vocabulary, see what is happening, identify what needs attention, safely take an authorized action, and understand the resulting receipt without CLI access or Thomas acting as interpreter.

Passing Tests 1–8 means the capability is technically productizable. Passing Test 9 begins to prove the actual ContextControl product.

23. Gas City Capability Horizon — Know the Whole Platform, Prove It Incrementally

This section exists so later product work does not accidentally rebuild Gas City functionality that was already available upstream. It is an architectural inventory and test horizon, not permission to implement future stages early. Section 22 remains controlling.

23.1 The canonical six primitives

Gas City itself defines exactly six primitives:

Gas City primitive Meaning ContextControl product language
Agent WHO performs work Agent
Bead WHAT the durable unit of work is Work Item
Formula HOW reusable work is performed Procedure
Rig WHERE work is scoped Workspace
Pack CONFIGURES agents, formulas, orders and supporting capability Capability Pack
Event OBSERVE immutable activity Signal

Do not promote surrounding mechanisms or Gastown role names into additional Gas City primitives.

A key architectural fact is that Beads are the universal durable substrate. Tasks, mail, sessions, and convoys are represented through the same durable store with different types. Dependencies are needs edges, so blocked work stays unavailable until dependencies close. This is why sessions can die without taking the work graph with them.

23.2 Orchestration machinery beneath the primitives

These are first-class Gas City mechanisms that ContextControl should expose or consume where useful, but they are not additional primitives:

Mechanism What Gas City owns Product opportunity later
Orchestrator drives formula graphs, reconciles desired agents/sessions, advances ready work invisible backend runtime; show health and state, do not recreate it
Bead store / Dolt durable ground truth for work, dependencies, mail, session records and convoy records project authoritative work into Drupal; never fork state
Event bus / SSE append-only observable activity with replay cursors live ContextControl activity stream, notifications and cache invalidation
Session live provider process and conversation, either on-demand or always-on Agent detail, live status, transcript, controlled interaction
Convoy container bead grouping related work Initiative
Order trigger + action; automates formula or deterministic exec Automation
Sling creates/routes delegated work without binding to a specific session governed delegation action
Hook / claim injects work/mail/nudges and atomically lets workers claim routed work largely invisible product plumbing; expose claim evidence
Mail persistent bead-backed message channel first-class Mail / Inbox UI
Nudge immediate terminal input to a session; not durable like mail operator action for exceptional live interaction, not default workflow
Wait blocks on a condition without burning an LLM session show waiting state; never model-poll CI or other long operations
Connected client / extmsg binds an external HTTP client/conversation to a Gas City session over HTTP + SSE ContextControl Chat can become a native Gas City participant rather than a parallel chat system
Provider process/runtime implementation behind a session model/provider observability and policy, not work authority
Patch target-specific override for agents/providers/rigs without copying configuration product configuration where variation is required
Pool / scale_check demand-driven scaling of identical workers with min/max session bounds capacity controls and operator visibility
Named session persistent configured session, including always-on mode long-lived coordinator/chat roles without inventing a daemon
JSON Schema machine contracts exposed by gc --json-schema generated validation and API integration rather than handwritten contracts
Supervisor REST API typed HTTP control plane for city state and actions primary ContextControl integration contract
Event cursor / request_id asynchronous mutation correlation and resumable event consumption reliable Drupal async UX without polling

23.3 tmux is a native execution surface, not our orchestrator

Gas City already treats tmux as a session provider. gc session attach enters the live tmux-backed conversation, while peek, logs, and nudge let operators observe or interact without making tmux the system of record.

On Linux, GC_AGENT_SLICE can place tmux agent process trees into a dedicated systemd user slice so CPU and memory policy can apply across the fleet. This is a host deployment capability, not city configuration. For unattended hosts, the user manager must survive logout if those scoped processes are expected to remain alive.

ContextControl should eventually display session/provider/runtime health and resource attribution. It should not manage work by scraping tmux panes or use tmux sessions as durable state.

23.4 Communication model — no direct agent graph

Gas City intentionally avoids direct agent references. Sessions coordinate indirectly through the store:

MAIL = durable message
SLING = durable delegated work
HOOKS = provider integration that surfaces mail/work/nudges

The sender names a destination, not a process. Gas City resolves whether zero, one, or many matching sessions exist and whether one needs to wake. This indirection is essential to scaling and crash recovery.

For ContextControl this means:

Chat  → external-message / session participant path
Mail  → Gas City Mail
Work  → Beads / Convoys
Live  → Sessions
State → Events

Do not create a second Drupal message bus between Agents.

23.5 Mail should become a first-class ContextControl product surface

Target product navigation after the earlier proofs succeed:

ContextControl
├── Chat
├── Mail
│   ├── My Inbox
│   ├── Agent Mail
│   ├── Team Mail
│   ├── Requests / Approvals
│   └── System / Automation
├── Work
│   ├── Objectives
│   ├── Initiatives
│   ├── Work Items
│   └── Assigned to Me
├── Agents
├── Activity
├── Automations
├── Procedures
└── Receipts

Mail remains authoritative in Gas City. Drupal projects it, filters it by identity/policy, relates it to Work Items and Initiatives, and exposes authorized replies/actions.

23.6 Orders deserve their own product proof

Orders are not merely cron jobs. Gas City supports triggers including cooldown, cron, condition, event, and manual, with an action that invokes a formula or deterministic execution. The orchestrator evaluates due triggers on its tick and emits order lifecycle Events.

A later proof should demonstrate all of the following using existing Order semantics rather than Drupal scheduling:

MANUAL_TRIGGER=PASS
EVENT_TRIGGER=PASS
CONDITION_TRIGGER=PASS
SCHEDULE_TRIGGER=PASS
ORDER_HISTORY_VISIBLE_IN_DRUPAL=PASS
ORDER_ENABLE_DISABLE_GOVERNED=PASS
DRUPAL_SCHEDULER_CREATED=NO

ContextControl can brand Orders as Automations, but Gas City remains their execution authority.

23.7 Events are more powerful than a dashboard feed

Gas City exposes the same event contract through REST listing, SSE streams, and gc events. Events have semantic type values such as bead, mail, session and request lifecycle events, and streams support resume cursors.

Asynchronous API mutations return request_id plus an event cursor; clients are expected to wait for the matching terminal event rather than poll state. ContextControl should adopt this pattern directly.

Future proof:

DRUPAL_ACTION_RETURNS_REQUEST_ID=YES
EVENT_CURSOR_CAPTURED=YES
SSE_RESUME_PROVEN=YES
TERMINAL_EVENT_CORRELATED=YES
HTTP_POLL_LOOP=NO
LLM_POLL_LOOP=NO

23.8 Sessions deserve a distinct operator model

Gas City supports:

ON_DEMAND_SESSION  = created for work, retired when idle
ALWAYS_ON_SESSION  = declared by pack and kept available

A running Agent is a Session. Sessions can be listed, peeked, attached, nudged, logged and streamed. On orchestrator restart, Gas City can adopt live sessions rather than blindly respawning them.

Later ContextControl UI should distinguish:

Agent definition
≠ Agent pool
≠ live Session
≠ Work Item

Conflating these objects would create a misleading product model.

23.9 Polecats, Deacons, Dogs, Witness, Refinery, Mayor and Crew are Pack roles

These names are important, but they are not core Gas City primitives. They come from orchestration packs such as Gastown and are implemented through the same six primitives and normal session/pool mechanisms.

The current Gastown pack documents city-scoped roles such as mayor, deacon, boot and a dog utility pool, plus rig-scoped witness, refinery and polecat agents. Polecats can be pooled and scaled per rig. Mayor/deacon/boot can be configured as always-on sessions; witness can also be always-on at rig scope; refinery can be on-demand. Mechanical housekeeping also exists in the builtin core pack.

Bluefly rule:

Consume and configure upstream roles when they match the required capability. Do not rebuild MAYOR, DEACON, WITNESS, REFINERY, POLECAT, or dog mechanics merely to preserve Bluefly naming.

ContextControl may brand the user-facing role, but the receipt must preserve the resolved Gas City Agent identity.

23.10 Deacon and Dog proof horizon

Do not implement these before the prior chain unlocks them. Preserve them as later production proofs:

Patrol proof

DEACON_OR_EQUIVALENT_RESOLVED=YES
PATROL_IS_DETERMINISTIC=YES
STALE_LEASE_DETECTED=YES
FAILED_SESSION_DETECTED=YES
WORKTREE_OR_SESSION_HYGIENE_PROVEN=YES
MODEL_TOKEN_SUPERVISION_REQUIRED=NO

Dog/utility-worker proof

UPSTREAM_DOG_CAPABILITY_IDENTIFIED=YES
BOUNDED_UTILITY_WORK=YES
POOL_SCALING_PROVEN=YES
NO_NEW_BLUEFLY_DAEMON=YES
NO_DUPLICATE_PATROL_LOOP=YES

23.11 Polecat proof horizon

Polecats are a useful later proof of disposable horizontal execution:

WORK_ITEM_ROUTED=YES
POLECAT_SESSION_CREATED_OR_REUSED=YES
ATOMIC_CLAIM=YES
RIG_SCOPE_PRESERVED=YES
POOL_MAX_ENFORCED=YES
RESULT_PERSISTED_OUTSIDE_SESSION=YES
IDLE_SESSION_RETIRED=YES
RESTART_DOES_NOT_LOSE_WORK=YES

The product value is not the word “polecat.” The product value is elastic, replaceable workers over durable work.

23.12 Connected-client proof for ContextControl Chat

Gas City's external messaging API already supports registering an external LLM client, authorizing it to bind to a session, subscribing to a durable SSE reply stream, sending inbound turns, and reconnecting.

This is a strong candidate for the production Chat integration because Drupal can participate in a real Gas City session instead of creating its own agent conversation authority.

Later proof:

CONTEXTCONTROL_CLIENT_REGISTERED=YES
SCOPED_BEARER_IDENTITY=YES
AUTHORIZED_SESSION_BINDING=YES
DURABLE_SSE_SUBSCRIPTION=YES
INBOUND_TURN_REACHES_GAS_CITY_SESSION=YES
REPLY_RETURNS_TO_CONTEXTCONTROL=YES
RECONNECT_PRESERVES_CONVERSATION=YES
SECOND_CHAT_AUTHORITY=NO

23.13 ContextControl CRUD end state

The commercial end state remains Drupal as the product surface and Gas City as the backend orchestrator.

A normal user should eventually be able to manage branded product objects from Drupal:

Objective    ↔ Mountain
Initiative   ↔ Convoy
Work Item    ↔ Bead
Workspace    ↔ Rig
Procedure    ↔ Formula
Automation   ↔ Order
Signal       ↔ Event
Capability Pack ↔ Pack
Agent        ↔ Agent
Mail         ↔ Mail
Run          ↔ Session
Receipt      ↔ Operational Receipt

But CRUD must respect the authority type:

  • Runtime/durable objects use the authoritative Gas City API.
  • Versioned configuration such as Procedures, Automations, Packs or Agent definitions must use the native Gas City representation and governed GitLab source/delivery path where source control is authoritative.
  • Drupal provides forms, permissions, validation, workflow, Views and product language.
  • Drupal must not silently create an independent canonical copy.

The desired user experience is ordinary product CRUD. The implementation underneath must preserve Gas City-native contracts, identifiers, versions, events, policy and receipts.

23.14 Architectural stopping rule

This inventory is deliberately broader than the current implementation test. It prevents architectural amnesia, but it must not become backlog inflation.

For every mechanism above:

KNOWN=YES
DOCUMENTED=YES
IMPLEMENT_NOW=NO

until the preceding proof explicitly unlocks it.

The architectural question before every new ContextControl feature remains:

Is this exposing or governing a capability Gas City already owns, or are we accidentally rebuilding Gas City in Drupal?

If Gas City owns it, ContextControl projects, brands, governs and consumes it.

23.15 Deep Gas City feature inventory for later proofs

This inventory is sourced from the current upstream Gas City documentation and exists to prevent us from designing around surface-level assumptions. It does not unlock implementation. Section 22 still governs advancement.

Native orchestration truths

  • The orchestrator runs formula graphs, fans ready work out across agents, holds blocked work behind needs dependencies, retries failures, reconciles desired session state, and drives the graph outside any one chat session.
  • The Bead store is the durable substrate. Tasks, messages, sessions, and convoys are all bead types. A crashed session does not erase work.
  • Events are immutable append-only records with monotonic sequence numbers. Humans, agents, hooks, Orders, dashboards, and API clients can all observe the same stream.
  • Event-triggered Orders advance from stream cursors so the same event is not processed twice.
  • Asynchronous Supervisor mutations return a request_id and event_cursor; clients are expected to wait on the matching terminal Event rather than poll.

These facts are architectural constraints for ContextControl, not implementation suggestions.

Formula capability worth preserving

Formula v2 is much more than a list of prompts. It is the native workflow graph language. Later proofs should deliberately exercise the capabilities that matter to a product rather than writing parallel workflow logic in Drupal:

DEPENDENCY_DAG
PARALLEL_FANOUT
CONTROL_BEADS
COMPILE_TIME_CONTROL
RUNTIME_CONTROL
VARIABLES_AND_RIG_DEFAULTS
RETRY_PATTERN
ORCHESTRATOR_FINALIZATION
WORK_MATERIALIZED_AS_BEADS

When a Procedure is edited in ContextControl, the product must ultimately preserve and validate the native Formula contract rather than inventing a Drupal-only workflow representation.

Order capability worth preserving

Orders are the native WHEN layer. Current upstream trigger types are:

cooldown
cron
condition
event
manual

An Order can drive a Formula or deterministic execution. Condition checks have their own bounded timeout, separate from the dispatched action. Event Orders use cursor-based consumption. Manual Orders remain discoverable but do not auto-fire.

Product consequence: an Automation form in ContextControl should project these native trigger semantics. Drupal cron, Queue API, ECA scheduling, or an AI loop must not become a replacement scheduler for Gas City work.

Pack is larger than Agents + Formulas + Orders

The authoritative Pack schema currently supports a broader reusable product surface:

pack.toml
agents/
assets/
commands/
doctor/
formulas/
orders/
skills/
mcp/
template-fragments/
overlay/

And pack configuration can also declare:

imports
named sessions
services
providers
runtimes
agent patches
globals
pricing

This matters for the ContextControl end state. A Capability Pack product screen should eventually be able to explain and govern the whole native package, not only formulas and agents. Do not create Bluefly-specific top-level pack directories that the upstream pack specification does not recognize.

Commands and Doctor checks

Pack commands are native operator commands exposed through gc; Doctor checks are native invariant checks aggregated by gc doctor.

Later product opportunities:

Commands  → branded operator actions / runbooks
Doctor    → product health / readiness / known-invariant checks

ContextControl should project their results and policy, not recreate a competing command framework or health-check engine.

Agent model is five-axis, not provider-name equals agent

Current Gas City guidance separates an Agent across independent axes:

HARNESS
MODEL
UPSTREAM
TRANSPORT
RUNTIME

The configured Agent adds prompt, scope, defaults, pooling, and hook behavior. A live Agent instance is a Session. ContextControl must therefore avoid a UI that conflates:

Agent definition
Provider/harness
Model
Live Session
Pool capacity
Work assignment

Those need distinct product concepts even if the first POC displays them on one detail page.

Pools and elastic workers

Gas City can scale identical Agent sessions using a scale_check, bounded by minimum and maximum active session counts. This is the native mechanism underneath the polecat operating style.

Later capacity proof:

DEMAND_OBSERVED=YES
POOL_SCALES_UP=YES
MAX_BOUND_ENFORCED=YES
IDLE_WORKERS_RETIRE=YES
WORK_SURVIVES_WORKER_EXIT=YES
NO_CUSTOM_AUTOSCALER=YES

Health patrol is platform infrastructure

The migration guidance is explicit: stall detection, restart-with-backoff, reconcile-to-desired-state, session scaling, Order evaluation, health patrol, and cleanup of ephemeral run state belong to the orchestrator path.

Therefore Bluefly must not build a permanent "Deacon service" to reproduce those mechanics. A Deacon may exist as a configured role when judgment is useful, but deterministic fleet health remains Gas City infrastructure.

Dogs are not a universal primitive

A Dog is a pack-level utility-agent pattern, not a Gas City primitive. The current Gastown pack has its own dog pool, while the Dolt pack has a separate dog for Dolt maintenance. Many historical "dog" duties should now be deterministic exec Orders with no LLM session at all.

Decision rule:

CAN_EXEC_ORDER_DO_IT=YES  → USE_EXEC_ORDER
NEEDS_AGENT_JUDGMENT=YES  → CONSIDER_SCALABLE_AGENT
NEEDS_NEW_DAEMON=NO_BY_DEFAULT

Polecat, Crew, Witness, Refinery, Mayor, Deacon are operating models

Upstream Gas City explicitly treats these as configuration, not platform types:

Mayor     → configured coordinator Agent / named Session
Deacon    → primarily orchestrator patrol; optional configured Agent
Witness   → Events + Waits + Formulas + optional configured Agent
Refinery  → Agent / Formula / Order post-processing step
Polecat   → scalable transient Agent, often isolated in a worktree
Crew      → persistent named Agents / Sessions
Dog       → utility Agent where deterministic execution is insufficient

This is an important correction to Bluefly role design. We can brand roles, but we should compose upstream mechanisms rather than hard-code role semantics into our product.

tmux and process isolation

Gas City sessions may be tmux-backed. gc session attach is the interactive entrance; peek, logs, and nudge provide non-attached observation/control. tmux remains a Session Provider, not work authority.

On Linux, GC_AGENT_SLICE can wrap tmux pane commands in transient systemd user scopes under a configured slice. This gives the factory a native path toward fleet CPU/memory governance without writing a Bluefly process supervisor.

Later infrastructure proof:

TMUX_SESSION_PROVIDER_PROVEN=YES
ATTACH_AND_DETACH=YES
PEEK_WITHOUT_ATTACH=YES
LOG_STREAM=YES
NUDGE_PATH=YES
SYSTEMD_AGENT_SLICE_PROVEN=YES_IF_LINUX
WORK_AUTHORITY_IN_TMUX=NO

Mail, nudge, hooks, sling and claim are deliberately different

Do not collapse these into a generic "message" concept:

MAIL   = durable message bead, unread/read state, threadable, optionally notify/wake
NUDGE  = immediate terminal input, not durable work communication
SLING  = create + route delegated durable work
HOOK   = provider integration that surfaces Mail, work and queued nudges
CLAIM  = atomic acquisition of eligible routed work

Mail itself does not need to wake an Agent. --notify may request a managed wake. This distinction should survive in ContextControl UX so a human can understand whether they are sending durable coordination, assigning work, or interrupting a live Session.

Connected clients make ContextControl Chat a native participant

Gas City already provides the integration pattern ContextControl needs:

POST /v0/extmsg/clients
GET  /v0/extmsg/{provider}/{account_id}/{conversation_id}/subscribe
POST /v0/extmsg/inbound

The reply stream uses SSE and supports replay from Last-Event-ID. The first inbound turn creates the conversation binding; later turns reuse it. Tokens are revocable.

This should be preferred over inventing a second Drupal-to-agent chat transport if current runtime verification confirms the contract fits the product requirements.

Supervisor API and OpenAPI are the product contract surface

The Supervisor API is typed HTTP + SSE. Current documented surfaces include city state and lifecycle, sessions, Mail, Convoys, Orders, Formulas, participants/transcripts/adapters, configuration/Packs, Events, and connected-client messaging. The published OpenAPI contract is the integration authority for api_normalization.

ContextControl integration rule:

DISCOVER_FROM_LIVE_OPENAPI=YES
GENERATE_OR_CONFIGURE_CLIENT=YES
HANDWRITE_DUPLICATE_GASCITY_CLIENT=NO
PRESERVE_REQUEST_ID=YES
PRESERVE_EVENT_CURSOR=YES
PRESERVE_NATIVE_IDENTITY=YES

Patch rather than fork

Gas City supports Agent/provider/Rig patching so a target can vary without copying an imported Pack. ContextControl configuration should expose this native override concept where product users need divergence.

Product language can be simpler, but the underlying operation should remain a patch rather than producing a forked Pack.

Native capability projection

Gas City already has first-class machine projection surfaces that later automation should consume before custom adapters:

gc --json
gc --json-schema
gc skill ...
gc mcp ...
OpenAPI 3.1
SSE event streams

This is directly aligned with ContextControl's API-normalization approach. Prefer machine contracts over prompt-parsing CLI text.

23.16 Later proof catalog, not current backlog

The following are intentionally recorded now so they are not forgotten, but each remains locked behind the Chain of Proof Law:

P10  MAIL_CONSOLE_PROOF
P11  ORDER_AUTOMATION_PROOF
P12  FORMULA_GRAPH_PROOF
P13  SESSION_OPERATOR_PROOF
P14  ELASTIC_WORKER_POOL_PROOF
P15  HEALTH_PATROL_AND_RECOVERY_PROOF
P16  CONNECTED_CLIENT_CHAT_PROOF
P17  PACK_FULL_LIFECYCLE_PROOF
P18  COMMAND_AND_DOCTOR_PROJECTION_PROOF
P19  PATCH_WITHOUT_FORK_PROOF
P20  RESOURCE_GOVERNANCE_PROOF

These are not authorized to begin because they exist in this document. They become eligible only when the immediately preceding accepted product proof explicitly unlocks them, or when a future curation pass folds them into the existing numbered chain.

The rule is still:

Learn the whole upstream platform now. Build only the next proven layer.

23.17 Upstream sources reviewed for this capability horizon

Current research basis, re-check before implementation because Gas City is moving quickly:

  • https://docs.gascity.com/getting-started/how-gas-city-works
  • https://docs.gascity.com/getting-started/coming-from-gastown
  • https://docs.gascity.com/tutorials/01-cities-and-rigs
  • https://docs.gascity.com/tutorials/02-agents
  • https://docs.gascity.com/tutorials/03-sessions
  • https://docs.gascity.com/tutorials/04-communication
  • https://docs.gascity.com/tutorials/05-formulas
  • https://docs.gascity.com/tutorials/06-beads
  • https://docs.gascity.com/tutorials/07-orders
  • https://docs.gascity.com/guides/gastown-config-recipes
  • https://docs.gascity.com/guides/connected-clients
  • https://docs.gascity.com/guides/multi-agent-engineering-environment
  • https://docs.gascity.com/reference/api
  • https://docs.gascity.com/reference/system-packs
  • https://docs.gascity.com/reference/tmux-agent-slice
  • https://docs.gascity.com/reference/specs/pack-spec
  • https://docs.gascity.com/reference/specs/formula-spec-v2

The upstream docs index itself is https://docs.gascity.com/llms.txt. Future architecture review starts from that index rather than assuming this list is complete.

24. Product Visual Evidence Program

Visual artifacts support understanding and product design; they are never authority. Every visual must be derivable from the same canonical contracts and runtime evidence used by the tests.

The first architecture graphic is ContextControl over Gas City: Product Surface and Native Orchestration. It establishes the product boundary: Drupal is the governed human surface; Gas City is the orchestration and work-state authority. Future graphics should preserve that boundary.

Build the visual set incrementally alongside the proof chain:

V1  PRODUCT_ARCHITECTURE_MAP
    ContextControl surfaces → native Gas City APIs/primitives

V2  CHAIN_OF_PROOF_MAP
    Gate Zero → Tests 1–9 with evidence gates and unlock conditions

V3  GAS_CITY_PRIMITIVE_MAP
    Agent / Bead / Formula / Rig / Pack / Event plus supporting mechanisms

V4  EVENT_DRIVEN_LIFECYCLE_MAP
    observed fact → Event → Order → Formula → Beads → Agent/Session → new Event

V5  MAIL_AND_CHAT_MAP
    ContextControl Chat + Mail → extmsg/Mail → BLU/session → sling/claim → durable work

V6  CONTEXTCONTROL_INFORMATION_ARCHITECTURE
    Chat / Mail / Work / Agents / Activity / Automations / Procedures / Receipts

V7  AUTHORITY_MAP
    Drupal vs Gas City vs Beads/Dolt vs GitLab vs policy vs evidence vs AgenticTools

V8  CRUD_CONTRACT_MAP
    branded Drupal object ↔ native Gas City object ↔ source/runtime authority ↔ receipt

V9  RUNTIME_AND_CAPACITY_MAP
    Agent definition → pool → Session → provider → tmux/systemd slice → Rig

V10 ECONOMICS_AND_EVIDENCE_MAP
    Work Item → Run → model/provider → cost/latency/retries → Witness → verified outcome

Visual rules:

SOURCE_LINKED=YES
NATIVE_IDS_PRESERVED_WHERE_RELEVANT=YES
PRODUCT_TERMS_VISIBLE=YES
GASCITY_TERMS_MAPPABLE=YES
SIMULATED_RUNTIME_DATA_PRESENTED_AS_REAL=NO
DUPLICATE_ARCHITECTURE_INVENTED=NO

The visual program follows the same chain law as the product: later diagrams may describe future capability, but they do not authorize implementation before prior tests pass.

25. Factory Behavior: P0 Defect Law

P0: AGENTS_EXIT_FACTORY_AT_HANDOFF_BOUNDARY

OBSERVED: Agents use Beads during work but return coordination to Thomas at completion (e.g., "Let me know how you'd like to proceed...").

REQUIRED: Every Agent inherits one common Gas City participation contract. Do not ask Thomas what to do next if HUMAN_GATE=NO.

ACCEPTANCE:

GC_MAIL_ON_START=YES
BEAD_ON_START=YES
CLAIM_BEFORE_MUTATION=YES
BEAD_UPDATED_DURING_WORK=YES
GC_MAIL_FOR_HANDOFF=YES
NEXT_OWNER_ROUTED=YES
THOMAS_QUEUE_MANAGEMENT=0
ASK_WHAT_NEXT=0
SESSION_CAN_SLEEP_AFTER_DURABLE_HANDOFF=YES

26. Private Edge / Network Alignment Factory Law

The architecture decision for the Factory Edge is FINAL. Do not reopen it unless runtime evidence proves it impossible.

Final Cloudflare Ingress

Cloudflare Tunnel has exactly these application routes: * dash.blutown.ai (path=*, origin=http://bluefly-platform:443) * hooks.blutown.ai (path=^/hook, origin=http://bluefly-platform:8372) * catch-all (http_status:404)

factory-api.blutown.ai MUST NOT be a Cloudflare Tunnel public hostname.

Authority Boundaries

  • hooks.blutown.ai: public external webhook ingress only (narrow /hook path). Authenticated/verified by the supported Gas City webhook mechanism.
  • dash.blutown.ai: intentional dashboard/customer-facing edge.
  • factory-api.blutown.ai: private branded Tailnet API edge. NOT Cloudflare Tunnel. NOT public Supervisor exposure.
  • Gas City Supervisor: backend runtime service. Must not become the public edge.

Documentation Disposition

The canonical architecture must say: * PUBLIC EXTERNAL WEBHOOK → Cloudflare Tunnel → hooks.blutown.ai → declared /hook path * PUBLIC/CUSTOMER DASHBOARD → dash.blutown.ai → intended dashboard edge * PRIVATE FACTORY API → factory-api.blutown.ai → Tailnet/private edge → Gas City API

Do not preserve stale documents that say factory-api via Cloudflare Tunnel or events.blutown.ai via Cloudflare Tunnel.