OneEnv
← All posts🌿 Part 7 of 21

Branches & Merges: The Governance Spine

ShareLinkedInX

Four domains sharing "one change, one notification, explicit approval" turned out to be only half the story — they didn't share how a change actually got to that notification. Env value edits applied immediately and fanned out live. API and validation edits sat as a hidden per-service draft, swept up by a central Publish button. DB table/column proposals used a third mechanism entirely, a boolean flag an admin flipped. Three inconsistent staging models, one governance promise. We replaced all three with one.

Everything stages on a Branch now

A Branch is scoped to the whole workspace, not to any one domain — an env value, a DB column, an API route, and a validation rule can all ride the same branch, staged and reviewed as one unit. Picking or creating a branch happens once, from a selector in the topbar; every governed-edit form after that just stages its change against whichever branch is active.

Branch
workspace-scoped: draft → submitted → approved/rejected → merged
BranchChange
one staged edit — domain, create/update/delete, before + after

One review, then the same per-service checklist as before

Submitting a branch creates exactly one notification — a single Owner/Admin approve/reject on the whole branch, the same shape as a pull request review. The reviewer isn't deciding blind: the branch page shows a per-domain change summary, an impact matrix previewing exactly which services would be notified, a readiness score that docks points for conflicts and breaking changes, and a comment thread where a reviewer can formally request changes. Approving merges every staged change into its real master row and then runs the exact same per-domain trigger the product always used, so the part everyone already trusted — each individually affected service still gets its own approve/reject on the value itself — didn't go away. It just moved to fire from the merge instead of from the original edit.

Submit branch
→
One branch review
Owner/Admin, whole branch
→
Merge
applies every change
→
Per-domain fan-out
scored for impact & risk
→
Each service
still approves/rejects

Conflicts are caught, not silently overwritten

Every staged change snapshots the entity's value at the moment it was staged. If something else changes that same entity before your branch merges, the snapshot won't match reality anymore and the merge is blocked — a one-click rebase re-snapshots against current state so you can see exactly what moved before deciding to proceed, instead of one edit silently clobbering another. The branch page also warns you earlier than that: it lists the other open branches touching the same entities, so a collision is visible while both branches are still drafts.

And merges are undoable

A merged branch can be reverted: OneEnv creates a new draft branch with before/after swapped for every update-type change, linked back to the branch it undoes, and it goes through the standard submit → review → merge path like any other change — an undo is a governed decision too, not a backdoor. Structural creates/deletes are skipped and reported rather than guessed at.

What this replaced

Before — three mechanismsNow — one Branch
Env value edits applied immediately, fanned out liveStaged as a branch_change, only applied when the branch merges
API/validation edits: a hidden per-service draft, swept up by a central Publish buttonStaged the same way as everything else on your active branch
DB table/column proposals: a pending-promotion flag an admin flippedA branch_change with the row marked private until merge

A merged branch is also the permanent record of what changed — there's no separate versioned snapshot table to keep in sync with it. What's deliberately unchanged: a service's own local override still stages then publishes on its own, no branch involved — that was never a shared-value governance decision, just a service opting itself out. And plain entity creation, renames, and archives stay exactly as silent and immediate as they always were; only the specific edits that other people rely on are branch-gated.

ShareLinkedInX