You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Needs a founder decision before implementation. This is a policy question, not a bug: no layer states an answer today, and picking one inline would be choosing a data model by accident.
The question, in the vocabulary that now exists
Between two annotations of the same asset with different provenance, which one does the trunk project?
"Provenance" is literal now. PR #311 added annotation.job_id — which round of work produced a label — so two labels on one asset from two rounds are distinguishable for the first time. Before that the batch id travelled only on a transient event and the question could not even be asked of stored data.
A correction batch starts unannotated. Its assets already carry the parent round's labels; the child's job begins with none of its own. So the moment somebody annotates in a correction batch and promotes it, an asset in the trunk has labels from two rounds — and DatasetService.promote is a union against current membership, which says nothing about annotations at all. The old and the new coexist, and every release manifest cut afterwards carries both.
That is reachable through the UI today. Nothing refuses it, and nothing reconciles it.
What is actually undecided
Does a correction supersede, or accumulate? Superseding needs a rule for which round wins (latest by job? the one whose batch pinned the newest schema?) and a decision about whether the superseded labels are deleted, hidden, or kept and filtered at manifest time.
Is supersession per asset or per annotation? A correction that fixes one box out of twelve either replaces the whole asset's labels or merges — and merging needs identity across rounds, which annotations do not have (a new round mints new ids).
What does ReleaseService do? A manifest is a pure function of content and its hash is the contract, so whatever is decided has to be expressible at manifest-build time without a second source of truth.
Does an exporter see it differently? Formats are lossy-aware already; supersession is a different axis.
Adjacent open policy — F14
F14 (cross-batch progress reconciliation) is the sibling and should probably be decided in the same session. Nothing prevents one asset sitting in several batches with divergent per-asset progress; promotion flattens per batch only (dataset_service.py, _promotable). Correction batches make that ordinary rather than exotic — a corrected asset is by construction in at least two batches — so "which progress is the asset's" and "which labels are the asset's" are two halves of one conversation.
Why it was deferred rather than guessed
The batch-lifecycle skill lists trunk supersession under "What is NOT settled (do not improvise)" and instructs stopping rather than choosing a policy inline. The 2026-08 run honoured that: T8 records who wrote a label and deliberately does not decide which label wins, and every PR in the run says so.
Suggested shape of a decision session
Bring: a worked example of a 48-frame batch with 3 corrected frames; what a release manifest should contain for that dataset; and whether a reviewer should be able to see the superseded round at all (an audit question, not only a storage one).
Needs a founder decision before implementation. This is a policy question, not a bug: no layer states an answer today, and picking one inline would be choosing a data model by accident.
The question, in the vocabulary that now exists
"Provenance" is literal now. PR #311 added
annotation.job_id— which round of work produced a label — so two labels on one asset from two rounds are distinguishable for the first time. Before that the batch id travelled only on a transient event and the question could not even be asked of stored data.The concrete trigger, shipped in #313
Correction batches exist end to end as of the 2026-08 remediation run:
Batch.parent_batch_idrecords lineage (Correction-batch prerequisites: batch lineage and annotation provenance (G3, G4) #311, gap G4).POST /batches/{id}/correctionscuts a draft over the parent's assets (Correction-batch surfaces: creation, corrections, and asset→batches (G1, G2, G7) #312, gap G7).A correction batch starts unannotated. Its assets already carry the parent round's labels; the child's job begins with none of its own. So the moment somebody annotates in a correction batch and promotes it, an asset in the trunk has labels from two rounds — and
DatasetService.promoteis a union against current membership, which says nothing about annotations at all. The old and the new coexist, and every release manifest cut afterwards carries both.That is reachable through the UI today. Nothing refuses it, and nothing reconciles it.
What is actually undecided
ReleaseServicedo? A manifest is a pure function of content and its hash is the contract, so whatever is decided has to be expressible at manifest-build time without a second source of truth.lossy-aware already; supersession is a different axis.Adjacent open policy — F14
F14 (cross-batch progress reconciliation) is the sibling and should probably be decided in the same session. Nothing prevents one asset sitting in several batches with divergent per-asset progress; promotion flattens per batch only (
dataset_service.py,_promotable). Correction batches make that ordinary rather than exotic — a corrected asset is by construction in at least two batches — so "which progress is the asset's" and "which labels are the asset's" are two halves of one conversation.Why it was deferred rather than guessed
The
batch-lifecycleskill lists trunk supersession under "What is NOT settled (do not improvise)" and instructs stopping rather than choosing a policy inline. The 2026-08 run honoured that: T8 records who wrote a label and deliberately does not decide which label wins, and every PR in the run says so.Suggested shape of a decision session
Bring: a worked example of a 48-frame batch with 3 corrected frames; what a release manifest should contain for that dataset; and whether a reviewer should be able to see the superseded round at all (an audit question, not only a storage one).