What is Conta Fork Yeah?
What it solves
Many domains keep data on a per-period basis — a fiscal year, a budget cycle, a sprint, a software release, a campaign window — where each period is a separate edit-target but is conceptually a continuation of the one before. The pattern shows up well outside finance: course catalogues per semester, schedule rosters per season, configuration sets per release, anything else that’s versioned by an integer period.
At period boundary you rarely start from a blank slate — you want to carry the previous period’s data forward and continue editing it from there. You may also want to copy a snapshot of the current data without progressing the period, for scenarios like "save as" or branching.
The naïve approach — load the source graph, deep-copy it, save the copy — runs into three recurring problems:
-
Lineage is lost. Once the copy is saved, there’s no record of where it came from or which row was the parent of which.
-
Identifiers are reused or randomised inconsistently. References between entities point at the wrong period, or stop pointing anywhere.
-
Partial failures are catastrophic. A single invalid item halfway through a 200-entry copy aborts the whole operation.
conta-fork-yeah provides primitives for all three:
-
Lineage is recorded explicitly on each forked entity via
ForkSources. A continued copy from season 1 to season 2 carries aforkedFromlike:{ "continuedFrom": { "forkMode": "ToNext", "identifier": "dj:8a1c…->nj:550e…", "forkedAt": "2026-04-28T08:30:00Z" } } -
New identifiers are generated through a single
SourceIdentifierGeneratorper fork operation, so cross-references stay consistent. -
Bulk forks use
ForkAttemptso each item succeeds or fails independently and the caller can inspect the outcome.
Where the name comes from
The vocabulary is borrowed straight from version control. Forking a repository takes an existing project as the starting point, produces a divergent copy, and keeps a pointer back to where it came from — and from that point forward the two histories evolve independently.
conta-fork-yeah applies the same idea to domain object graphs:
-
the existing graph is the source,
-
the new graph is the fork,
-
the pointer back is
ForkSources(withcopiedFrom/continuedFromslots), -
the two then evolve independently.
The metaphor extends a bit further: the mode of a fork — ToCopy, ToNext, ToPrevious — is roughly analogous to "fork at HEAD", "fork onto next branch", "fork onto previous branch".
And like a repository fork, nothing automatically flows back from one to the other after the split (see Forks and Commands).
Vocabulary
The library uses a small set of terms consistently:
- Fork
-
The act of producing a new instance of an entity (and usually its children) from an existing one.
- Source
-
The entity that was forked from. Recorded on the new entity as part of its
ForkSources. - Mode
-
How the fork happened —
ToCopy,ToNext, orToPrevious. See The Forking Model. - Lineage
-
The chain of
ForkSourcerecords left on a forked entity. Lets you walk backwards from the new instance to whatever it was derived from. - Identifier
-
The
key:uuidpair that uniquely names an entity in the lineage chain (e.g.fa:550e8400-…). - Source identifier
-
A path of up to three identifiers that locates an entity inside its parent hierarchy (e.g.
dj:…→nj:…). See Identifiers.