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:
- the Stage Director's Flow, which decides what is Ready and records the human disposition;
- the Delivery Method, which implements one bounded change; and
- Quality Gates And CI, which selects evidence appropriate to the claim.
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:
- one active player-facing work item;
- one mutating agent;
- one short-lived branch and worktree for that item;
- explicit ownership of paths that are unsafe to merge;
- integration back to
mainas soon as the coherent slice is accepted; and - 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
.assetfiles; ProjectSettings/**;Packages/manifest.jsonand 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:
- confirm the branch still represents one Ready item;
- inspect the full diff and handoff;
- integrate prerequisite contract changes first;
- rebase or update the dependent branch on current
main; - rerun the selected branch gates;
- squash merge one branch at a time;
- open the canonical Unity integration worktree when applicable;
- wait for import, compilation, and middleware readiness;
- run the integrated consumer smoke on
main; - record the Director's Call and checkpoint; and
- 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.
| Identity | Answers | Example |
|---|---|---|
| Product release version | What player-facing release is this? | 0.7.0 |
| Exact build identity | Which source and environment produced this binary? | 0.7.0-dev.23+g8c43a91 |
| Data contract version | Which 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.0for an accepted player-facing milestone or capability;0.MINOR.PATCHfor 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:
- accepted checkpoints accumulate on
main; - automation opens a draft proposing the next version and changelog from reviewed commits;
- the human completes or rejects its release record, synchronized references, evidence, and version;
- the full gate passes and the human merges the completed proposal;
- the human creates the annotated tag and any GitHub Release from the accepted merge; and
- 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
| Situation | Response |
|---|---|
| Main or target worktree is unexpectedly dirty | stop; identify ownership before staging, resetting, or moving anything |
| Two lanes claim the same exclusive path | serialize or extract a prerequisite contract |
| Branch drifts for more than a working day | reframe, integrate the coherent part, or close it; do not preserve drift as progress |
| Unity serialized conflict is ambiguous | return to the human; do not auto-choose or regenerate |
| Branch passes but integrated main fails | keep the item uncheckpointed; diagnose the production boundary |
| Release classification is ambiguous | leave it undecided in the proposal |
| CI is flaky | preserve the failing seed and environment; do not pass by retry |
| Agent handoff conflicts with the diff or current revision | trust source state, newest human direction, and canonical project sources; inspect and reorient rather than inferring or resetting |
Current Policy And Proposed Automation
| Capability | State |
|---|---|
| Director work-item template | available |
| Git branches and worktrees | available through Git |
| Manual path ownership in a work item | available |
| STAGE change and release repository gates | available for this repository |
| Hosted check-only source gate | available for this repository |
| Project-owned Unity integration rehearsal | project-specific |
stage work start/status/handoff/finish helper | proposed, not implemented |
Local .git/stage/active-work.json lease registry | proposed, not implemented |
| Conventional Commit lint | required in the STAGE repository; optional for adopting projects |
| Automated build-identity injection | project-specific, not implemented by STAGE |
| Release Please proposal workflow | available in STAGE; draft-only and never tags or publishes |
| Hosted Unity build/test pipeline | earned per project, not a STAGE default |
Potential stage work automation should remain a thin safety helper:
startverifies base state, creates the branch/worktree, and checks declared overlap;statusreports active work, stale bases, and leases;handoffprints source-backed change and evidence coordinates; andfinishverifies 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:
- DORA's trunk-based guidance favors few active branches, frequent integration, and no separate integration phase.
- DORA's small-batch guidance emphasizes fast feedback and notes that large AI-generated changes are harder to review.
- GitHub Flow provides a lightweight branch model.
- Git worktree provides isolated working directories for concurrent branches.
- Conventional Commits and Semantic Versioning provide machine-readable change and release language.
- Unity Smart Merge provides conflict assistance for Unity YAML, with the consumer verification limits described above.
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.