Skip to content

kernel: trunk supersession — which annotation does the dataset project when a correction re-annotates a promoted asset? (G5) #315

Description

@JArmandoAnaya

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.

The concrete trigger, shipped in #313

Correction batches exist end to end as of the 2026-08 remediation run:

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

  1. 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.
  2. 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).
  3. 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.
  4. 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).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    deferred-needs-inputBlocked on a decision that belongs to the founderkernelvisionset.kernel — domain, ports, adapters, services

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions