Skip to main content

Change, Concurrency, And Release Workflow

This guide owns the mechanics between a Ready work item and a named release: branching, worktree isolation, concurrent agents, Unity asset ownership, integration, build identity, and release proposals.

It is practitioner guidance, not a universal STAGE requirement. A small solo project may use a simpler route when the owner accepts the risk. The Safety Kernel, project-native rules, and human product authority remain controlling.

Use this guide with:

Operating Model

The recommended model for a solo human director working with agents is:

Human-directed trunk-based development with short-lived work-item branches, isolated worktrees, bounded agent concurrency, serial Unity integration, and human-gated releases.

The default is deliberately conservative:

  1. one active player-facing work item;
  2. one mutating agent;
  3. one short-lived branch and worktree for that item;
  4. explicit ownership of paths that are unsafe to merge;
  5. integration back to main as soon as the coherent slice is accepted; and
  6. a human decision before release naming or publication.

Parallel mutation is an exception for genuinely independent lanes. Read-only research, review, diagnosis, and test analysis can run concurrently without claiming ownership of project files.

End-To-End Path

flowchart LR
C["Cue"] --> D["Gameplay or technical Dialogue"]
D --> R["Ready work item"]
R --> W["Branch, worktree, and path ownership"]
W --> B["Build one bounded change"]
B --> Q["Claim-matched quality gates"]
Q --> U["Unity or production-consumer rehearsal"]
U --> H["Director's Call"]
H -->|revise| B
H -->|reject| X["Preserve finding and close route"]
H -->|accept| M["Serial integration to main"]
M --> S["Integrated main smoke"]
S --> K["Checkpointed"]
K --> P["Human-reviewed release proposal"]
P --> T["Tag and reproducible build"]
T --> O["Human publication"]

Checkpointed and released are different states. A useful accepted commit does not need an immediate public version, and a tag does not prove that a build was distributed or that players accepted it.

Ready Work Item

Give each durable item a stable project-native identifier, such as MS-014. The carrier can remain a sticky note, Markdown entry, or issue. The identifier exists to join the branch, commits, evidence, and human decision without requiring a ticketing platform.

Before mutation, record:

  • intended outcome and reason to do it now;
  • newest human decision and any unresolved product question;
  • protected state and non-goals;
  • smallest complete slice;
  • base branch and exact base revision;
  • branch and worktree;
  • owned paths and exclusive paths;
  • dependencies and expected integration order;
  • selected Source, Model, Engine, Consumer, Distribution, and Director gates;
  • stop conditions; and
  • likely release impact: none, patch, minor, or undecided.

If a product decision is still unresolved, return to Dialogue. Do not hide it inside a branch name or let multiple agents implement competing assumptions.

Branches And Worktrees

Default Shape

Use one branch and one worktree per mutating work item:

feat/MS-014-moon-forecast
fix/MS-021-paused-announcement
perf/MS-024-pool-settlement-markers
exp/MS-027-layout-study
docs/STAGE-057-change-workflow

The recommended lifecycle is hours and normally no more than one working day. Merge or close the branch once its bounded decision is complete. Avoid a permanent develop branch and ordinary long-lived release branches; they delay integration and obscure the exact state the owner played.

A typical manual start is:

git fetch origin
git worktree add ../moon-shepherd-MS-014 \
-b feat/MS-014-moon-forecast origin/main

Record the base SHA before work starts. A worktree isolates files; it does not make two changes independent. Independence still depends on contracts, ownership, and integration order.

Direct Work On Main

The owner may deliberately use main for a tiny, single-mutator, low-risk change. It is not the default for autonomous or concurrent mutation. Never use direct-to-main work merely to avoid defining ownership or reviewing a diff.

Where the hosting service supports it, protect main with required checks, linear history, and no force pushes. A personal repository can still allow the owner to merge without manufacturing team ceremony.

Branch Completion

Prefer one coherent integrated commit per work item. A branch may contain several local checkpoints while developing, but squash merging is usually the cleanest mapping from one Ready item to one reversible main change.

Use Conventional Commit syntax when the project adopts it. The STAGE repository itself requires this syntax for new commits under ADR 0063:

feat(gameplay): add moon forecast choice
fix(ui): prevent paused announcement progress
perf(world): pool settlement markers
docs(stage): clarify exclusive asset ownership
test(simulation): cover night transition invariants

The type describes the change, not its release impact. A fix may still alter a compatibility contract, and a feat does not automatically authorize a minor release. The human release proposal makes that classification.

Bounded Agent Concurrency

Default Capacity

Use one mutating agent unless parallelism clearly shortens the path to the next human decision. For a solo director, STAGE recommends at most two mutating agents at once, plus read-only research or review agents. This is an operating recommendation derived from attention and integration cost, not an empirically universal limit.

Parallel mutation is appropriate only when all are true:

  • the gameplay or product direction is already agreed;
  • each lane has an independently testable outcome;
  • write scopes are path-disjoint or governed by an explicit stable contract;
  • neither lane waits on an unresolved interface from the other;
  • Unity and generated-asset ownership is unambiguous;
  • integration order is known; and
  • the human can review the results promptly.

Parallel agents support one active player-facing item through independent lanes. They do not create several competing product directions.

Handoff Record

Every mutating lane should leave:

  • work-item ID and branch;
  • base and final revision;
  • files intentionally changed;
  • generated or external outputs affected;
  • checks attempted and their exact outcomes;
  • engine or human checks still required;
  • decisions made and assumptions introduced;
  • known conflicts or integration order; and
  • cleanup still needed.

The receiving integrator verifies this record against the diff. Agent prose is orientation, not proof.

This lane record serves branch integration. When unfinished work also crosses a Codex task boundary, follow Task Continuity And Context Recovery: keep durable project knowledge in canonical sources and use a disposable revision-bound Task Handoff only for resume state.

Path Ownership And Leases

A path lease is a temporary declaration that one active mutator owns a path or asset family. It is coordination metadata, not permanent architecture.

Use two classes:

  • owned paths: another lane may read them but must coordinate before editing overlapping lines or contracts;
  • exclusive paths: no second mutator edits them until the lease ends.

Include Unity .meta files with their assets. Include named generated outputs with the source or generator lane that owns regeneration. A broad directory lease is justified only when the tool or format makes narrower ownership unsafe.

If two Ready items need the same exclusive path, serialize them or split an interface change into a prerequisite branch. Do not rely on merge conflict resolution as the planning mechanism.

The proposed local lease registry is .git/stage/active-work.json. It would remain untracked because active worktrees and owners are workstation state. STAGE does not currently implement or require this registry.

Unity-Specific Ownership

Unity projects add shared serialized state and an editor that imports files, writes metadata, and caches a project-wide view.

Editor Rule

  • Never run two Unity Editors against the same worktree.
  • A code-only agent should not open Unity unless its evidence route needs it.
  • A Unity-owning branch gets its own worktree and its own Library.
  • Use one canonical integration Editor on main.
  • Merge Unity-owning changes serially, let the integration Editor import and compile, then run the integrated engine and consumer checks.

Do not share or copy Library as project authority. Cache reuse is an optimization only.

Exclusive Unity Paths

Treat these as exclusive by default:

  • scenes (.unity);
  • prefabs and prefab variants;
  • ScriptableObject and other authored .asset files;
  • ProjectSettings/**;
  • Packages/manifest.json and package lock state;
  • Input System action assets;
  • Addressables settings and groups;
  • localization tables;
  • Wwise projects, integration settings, and generated SoundBanks;
  • animation controllers and timelines when several lanes would rewrite the same graph; and
  • generated materials, textures, meshes, or asset families owned by one named generator.

Project conventions may narrow this list after repeated safe evidence. They should not silently widen concurrent mutation.

Smart Merge Boundary

UnityYAMLMerge can recover some .unity and .prefab conflicts. It is not the collaboration strategy. A syntactically merged scene can still have broken references, changed transforms, duplicated objects, or a result no human intended. Reopen the integrated asset in Unity and verify the real consumer.

Binary assets and ambiguous serialized conflicts return to the human owner. Do not choose one side, regenerate, or discard authored state automatically.

Integration

Use a single integration lane:

  1. confirm the branch still represents one Ready item;
  2. inspect the full diff and handoff;
  3. integrate prerequisite contract changes first;
  4. rebase or update the dependent branch on current main;
  5. rerun the selected branch gates;
  6. squash merge one branch at a time;
  7. open the canonical Unity integration worktree when applicable;
  8. wait for import, compilation, and middleware readiness;
  9. run the integrated consumer smoke on main;
  10. record the Director's Call and checkpoint; and
  11. remove the merged worktree and branch.

If integration fails, stop at the first causally useful failure. Prefer reverting one coherent merge or reopening the work item over stacking speculative fixes on a state nobody has rehearsed.

CI may parallelize independent Source and Model jobs. Serialize Unity jobs for the same project and cancel stale runs from superseded revisions. Green branch CI does not replace the integrated main smoke.

Three Separate Identities

Do not overload one number with three jobs.

IdentityAnswersExample
Product release versionWhat player-facing release is this?0.7.0
Exact build identityWhich source and environment produced this binary?0.7.0-dev.23+g8c43a91
Data contract versionWhich save, content, network, or artifact schema applies?save: 3, content: 5

Product Release Version

Semantic Versioning is a useful release-language convention when the project has declared what compatibility means.

Before 1.0.0, STAGE recommends:

  • 0.MINOR.0 for an accepted player-facing milestone or capability;
  • 0.MINOR.PATCH for fixes, balancing, polish, and content corrections that preserve that milestone's intended contract; and
  • the next minor plus an explicit note for a breaking pre-1.0 change.

After 1.0.0, a major version identifies an intentionally broken declared compatibility contract. It does not mean "large amount of work."

A project may ship date-based or milestone names instead, but it still needs a stable rule. Version numbers do not measure fun, quality, or architectural maturity.

Exact Build Identity

Every testable build should expose:

  • product version;
  • Git SHA;
  • dirty or clean state;
  • build number or timestamp;
  • engine version;
  • target platform; and
  • relevant content or save contract versions.

One starting point is:

git describe --tags --long --dirty

The build receipt and diagnostics should preserve the exact result. SemVer narrows a regression interval; the source revision and git bisect identify the actual change.

Data Contract Versions

Version saves, content catalogs, network protocols, mod APIs, and STAGE artifact schemas independently. A patch release can contain a compatible data migration. A new gameplay milestone does not automatically change the save format.

Release Proposal

A release is a human-reviewed proposal, not a side effect of merging any feature branch.

Recommended flow:

  1. accepted checkpoints accumulate on main;
  2. automation opens a draft proposing the next version and changelog from reviewed commits;
  3. the human completes or rejects its release record, synchronized references, evidence, and version;
  4. the full gate passes and the human merges the completed proposal;
  5. the human creates the annotated tag and any GitHub Release from the accepted merge; and
  6. plugin refresh, store, package, or public source publication remains an explicit human operation.

Release Please prepares STAGE's draft proposal after successful main quality under ADR 0064. It explicitly skips tag and GitHub Release creation. Do not automate publication merely because version calculation can be automated.

For the STAGE repository's actual manual release process, use Maintaining STAGE. This guide does not claim that the repository already uses the proposed game-project release automation.

Human And Agent Authority

Human-Only Decisions

  • gameplay hypothesis and intended player experience;
  • whether ambiguous behavior is a defect or a design change;
  • ownership decisions for conflicting authored assets;
  • integration order when alternatives change product meaning;
  • Director acceptance;
  • release-version approval;
  • merging a release proposal; and
  • public or store publication.

Delegable Operations

  • create a declared branch and worktree;
  • inspect overlap and report path conflicts;
  • implement inside an approved scope;
  • run deterministic gates;
  • derive exact build identity;
  • propose a commit type, changelog, and version;
  • prepare a clean-checkout build; and
  • remove merged worktrees after verifying no unique state remains.

Delegation does not let an agent weaken checks, resolve ambiguous asset authority, broaden scope, or publish.

Moon Shepherd Example

Suppose the Director accepts a thin-loop hypothesis: a visible moon forecast should help the player decide whether to spend scarce lantern oil tonight or save it for a harsher configuration tomorrow.

MS-014 feat/MS-014-moon-forecast
Outcome: forecast supports one legible oil decision
Owned: deterministic forecast model and focused tests
Exclusive: MoonForecastPanel.uxml, MoonForecastPanel.uss
Human gate: can the owner explain and use the forecast unprompted?

MS-015 feat/MS-015-forecast-presentation
Outcome: accepted forecast state is readable in the production UI
Dependency: MS-014 model contract
Owned: presenter and view styling
Exclusive: forecast prefab or UI document
Integration order: MS-014, then rebase and rehearse MS-015

Do not start both while the forecast meaning is unresolved. Once the model contract is accepted, the model lane and a path-disjoint audio research lane could proceed concurrently. The Unity UI asset remains exclusive. Both merge serially, followed by one integrated main-menu-to-night consumer rehearsal.

If the owner cannot understand the forecast, the work returns to Dialogue. A passing simulation test does not authorize more moon types or a release.

Failure Handling

SituationResponse
Main or target worktree is unexpectedly dirtystop; identify ownership before staging, resetting, or moving anything
Two lanes claim the same exclusive pathserialize or extract a prerequisite contract
Branch drifts for more than a working dayreframe, integrate the coherent part, or close it; do not preserve drift as progress
Unity serialized conflict is ambiguousreturn to the human; do not auto-choose or regenerate
Branch passes but integrated main failskeep the item uncheckpointed; diagnose the production boundary
Release classification is ambiguousleave it undecided in the proposal
CI is flakypreserve the failing seed and environment; do not pass by retry
Agent handoff conflicts with the diff or current revisiontrust source state, newest human direction, and canonical project sources; inspect and reorient rather than inferring or resetting

Current Policy And Proposed Automation

CapabilityState
Director work-item templateavailable
Git branches and worktreesavailable through Git
Manual path ownership in a work itemavailable
STAGE change and release repository gatesavailable for this repository
Hosted check-only source gateavailable for this repository
Project-owned Unity integration rehearsalproject-specific
stage work start/status/handoff/finish helperproposed, not implemented
Local .git/stage/active-work.json lease registryproposed, not implemented
Conventional Commit lintrequired in the STAGE repository; optional for adopting projects
Automated build-identity injectionproject-specific, not implemented by STAGE
Release Please proposal workflowavailable in STAGE; draft-only and never tags or publishes
Hosted Unity build/test pipelineearned per project, not a STAGE default

Potential stage work automation should remain a thin safety helper:

  • start verifies base state, creates the branch/worktree, and checks declared overlap;
  • status reports active work, stale bases, and leases;
  • handoff prints source-backed change and evidence coordinates; and
  • finish verifies integration before offering cleanup.

It must not choose product scope, steal a lease, auto-resolve Unity assets, weaken a gate, merge, version, or publish.

Measures

Use measures to expose coordination cost:

  • Ready-to-first-rehearsal time;
  • branch lifetime and diff size;
  • path and contract conflicts;
  • failed integrated-main smokes;
  • rework after integration;
  • escaped defects by missed gate;
  • human review and diagnosis time; and
  • release proposal corrections.

Do not optimize commit count, branch count, agent concurrency, story points, or release frequency as value proxies.

Why This Shape

This workflow combines established practices without claiming that their combination is scientifically optimal:

The STAGE-specific contribution is the control boundary: small-batch source mechanics are placed under the Director's Flow, project-native authority, claim-matched gates, and human product acceptance.