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
Annotation.attributes carrier: neither the model field nor the column exists today —
this task adds the field (values keyed by attribute name) and migration 5 for the column
(idempotent, shared schema object, _downgrade_to_version_one entry — the migration rules
in adapters/migrations.py).
Provenance rules enforced: model requires model_ref; confidence ∈ [0,1]
(already in the domain model — the service must surface them as clean domain errors,
not raw pydantic ValidationErrors).
UUIDs generated server-side at creation if absent; updates address by UUID only.
Progress is marked explicitly via JobService.mark_progress, never recomputed by this
service. Open decision for this task's plan: whether mark_progress(annotated) should
start requiring ≥1 stored annotation on the asset — decide and record it, either way.
Acceptance criteria
Each violation class has a dedicated error type + test
Writing to a job whose batch is not in_annotation is rejected (BatchNotInAnnotation)
Update/delete by UUID; unknown UUID is a clean domain error
Migration 5 idempotent; fresh-vs-migrated schema equality test still green
Context
Severity policy (vision doc, decision F): schema violations are a hard reject at write
time, in the kernel — never delegated to the UI's good faith.
Body updated 2026-07-27 to match what #6/#8/#9 actually shipped — see the reconciliation
comment below for the diff against the original.
Deliverables
add/update/delete annotations(job, [annotation])— validates against the batch's pinnedschema version: class exists, the annotation's geometry
typematches the class'sgeometry(singular — one geometry per class, per kernel: SchemaService — monotonic immutable versioning, additive/destructive change classification, LabelClass/Attribute/allowed_geometries validation #6), required attributes presentand type-correct.
Annotation.attributescarrier: neither the model field nor the column exists today —this task adds the field (values keyed by attribute name) and migration 5 for the column
(idempotent, shared schema object,
_downgrade_to_version_oneentry — the migration rulesin
adapters/migrations.py).modelrequiresmodel_ref;confidence∈ [0,1](already in the domain model — the service must surface them as clean domain errors,
not raw pydantic
ValidationErrors).in_annotationraise the existingBatchNotInAnnotation— do not add a second error for the same rule (kernel: JobService — states pending→in_progress→completed, per-asset progress (unannotated|annotated|skipped|review_pending|accepted), schema version pinned per batch #9 convention).Out of scope (moved by #9)
Progress is marked explicitly via
JobService.mark_progress, never recomputed by thisservice. Open decision for this task's plan: whether
mark_progress(annotated)shouldstart requiring ≥1 stored annotation on the asset — decide and record it, either way.
Acceptance criteria
in_annotationis rejected (BatchNotInAnnotation)