Phase 5 — Promote Investigation Rows to a Collection
Goal
Turn verified Investigation candidates into durable operational records through an explicit, reviewable human action.Product flow
- User selects one or more candidate rows.
- User chooses an existing Collection or creates one through the normal Collection UI.
- Driftless previews field mapping, conflicts and rows that will be skipped.
- User confirms.
- Server performs an idempotent batch promotion and returns created, updated, skipped and failed counts with per-row reasons.
Contract
Add a typed promotion request containing:- investigation id;
- target collection id;
- selected candidate ids;
- explicit source-field -> collection-field mapping;
- idempotency key;
- conflict policy from a closed enum (
skip,update_blank_fields).
- source investigation id;
- candidate id;
- evidence ids or a durable link back to the Investigation;
- promotion timestamp and actor;
- resolved entity id when present.
Identity and idempotency
Preferred identity order:- resolved entity id;
- normalized company domain;
- strong public identifier when the source contract permits it;
- deterministic candidate id scoped to the source Investigation.
Governance
- Human identity required.
- Workspace and Collection authorization required.
- Read the target Collection criterion before presenting/performing mapping.
- Respect Collection schema and lifecycle stages.
- Default new records to the Collection’s valid initial stage.
- The model may suggest a mapping; code validates and the human confirms it.
Acceptance
- Preview and final mutation agree on created/updated/skipped counts.
- Retry after a network timeout is safe.
- Mixed success reports every row; it does not roll back valid independent rows unless existing Collection semantics require transactionality.
- Promoted records link back to evidence without copying unbounded source payloads.
- Cross-workspace, stale mapping and invalid-stage cases fail closed.
