İçeriğe geç

ADR-007: Production Curation Lifecycle

Geliştirme · 0.0.0-dev

Yayın

Doküman
0.0.0-dev
Uygulama
0.0.0

Bu sayfa

Uygulama
0.0.0
  • Status: Accepted
  • Date: 2026-08-18
  • Decision owners: Corpus, annotation and database maintainers
  • Scope: Production curation of domain authority and occurrence annotations

Munderecat imports generated and legacy-derived annotations before release, but it must also support precise corrections after public IDs are cited. Compound boundaries, lexical analyses, Ottoman renderings, dictionary sense selections, headings, notes, repetition decisions and translation alignments can improve without changing the source-faithful core text.

ADR-001 separates core, domain authority, occurrence annotations, provenance and derived projections. ADR-002 makes published identities permanent and requires typed supersession for identity-changing corrections. ADR-005 fixes annotation coordinates, and ADR-006 requires immutable evidence and source closure. This ADR defines how a proposed change becomes accepted and effective without bypassing those contracts.

The main operational risks are:

  • treating a high-confidence generated result as an accepted human decision;
  • editing or deleting a cited record in place;
  • applying a stale review after another curator changed the same state;
  • allowing a broad query to affect a different set of rows at execution time;
  • partially applying a compound correction and its occurrence migrations;
  • rebuilding production tables from current rows and losing decision history; and
  • rolling back a mistaken decision by erasing its evidence.

Physical SQL, RLS and API representations are deferred. The lifecycle below is the semantic contract those implementations must enforce.

Production curation is one shared control protocol used by every annotation domain. Domains own the meaning and validation of their actions, but they do not create parallel decision ledgers or weaker acceptance paths.

The authoritative curation facts are append-only proposals, reviews, decisions, transactions and publication manifests. The current reader-facing state is a derived projection over those facts. Materialized rows, search indexes, caches and UI status labels are not decision authority.

The lifecycle can create or change domain-authority and occurrence-annotation state. It cannot:

  • mutate accepted core text, hierarchy, coordinates, positions or reconstruction;
  • reinterpret a shared span globally when only one domain assertion is wrong;
  • make provenance or normalized search values semantic authority; or
  • grant a generated process, runtime reader or direct database client acceptance authority.

The lifecycle has the following logically distinct records. A physical design may combine storage only if their identities and authority boundaries remain explicit.

Record Meaning Mutable?
candidate Machine- or import-produced suggestion with score and evidence No
proposal Exact requested action set submitted for a decision No
review One actor’s decision on one exact proposal revision No
curation_decision Quorum result for that proposal No
curation_transaction Atomic application of one accepted action set No
curation_release Published effective-state snapshot and ordered transaction inventory No
effective_state Rebuildable projection for one named curation release Replaceable

A candidate may be dismissed or promoted into a proposal. A curator may also submit a proposal without a generated candidate. Promotion copies immutable candidate and evidence references into the proposal; it does not convert confidence into authority.

Each proposal has a generated-once UUID, immutable payload digest and revision. A change to targets, actions, evidence, expected state or policy creates a new proposal revision or a successor proposal. A review always binds the exact proposal ID, revision and payload digest. Comments may be appended, but reviewed bytes never move.

Every proposal contains an ordered action set. Each action declares:

  • action kind and owning annotation domain;
  • exact target entity, occurrence, span or definition IDs;
  • exact expected lifecycle/revision facts for every existing target;
  • complete proposed identity-bearing and identity-preserving values;
  • referenced immutable core and annotation release IDs;
  • evidence and provenance assertion IDs;
  • applicable curation policy ID and version; and
  • the intended compatibility class when one has been defined by F2-018.

Targets are IDs, not mutable text matches, normalization keys or live SQL predicates. A discovery query may help author a proposal, but submission freezes its result as a canonically ordered target inventory plus count and digest. Execution rechecks that inventory. It never reruns the discovery query to discover new targets.

The shared action kinds are:

Kind Effect
create Issue a new domain or occurrence entity and establish initial accepted state
amend Append an identity-preserving value or metadata correction to an existing ID
set_lifecycle Change accepted/rejected/retired visibility without changing identity
supersede Apply ADR-002 replacement, split, merge or restructure with new IDs
retire Apply ADR-002 retirement with no successor
invalidate_decision Mark an earlier accepted decision ineffective under a later reviewed compensation
relate Add or retire an explicit typed relation without pretending it is supersession

Domain action schemas may be stricter. They cannot add an in-place identity-changing update, physical delete or implicit cascade.

The entity-kind identity contract from ADR-002 decides whether a value can be amended under the same ID. Evidence, confidence, editorial notes and lifecycle status normally preserve identity. A change to what a definition denotes, which core release/span an occurrence selects, or which ordered members it contains creates a successor identity.

Changing one definition does not silently rewrite its occurrences. A proposal must state separately whether it:

  1. corrects one occurrence only;
  2. supersedes a reusable definition only; or
  3. supersedes a definition and migrates an explicit occurrence inventory.

For example, changing the occurrence farz-i muhal olarak to farz-i muhal creates a new occurrence annotation bound to the shorter span and applies one typed ADR-002 replacement from the selected historical occurrence to the new occurrence. Retirement is valid only when no successor replaces the removed assertion. The correction does not change tokens, core text, other occurrences of the definition or another domain’s Ottoman rendering. Applying the same correction throughout the corpus requires a frozen list of every affected occurrence and an explicit result for every item.

Removing an annotation retires its occurrence; it does not remove covered tokens. Adding an annotation creates a new occurrence and, only when needed, a separately identified reusable definition. Trimming a compound does not make the excluded ki, de, ile or another token disappear from core or from independent annotations.

Proposal state is derived from append-only events:

submitted -> accepted -> applied -> published
| \-> application_failed
|-> rejected
|-> withdrawn
\-> superseded_by_proposal

submitted means the exact proposal is reviewable. A submitter may append a withdrawal before a terminal review. Any payload correction creates a successor proposal rather than editing the submitted one.

accepted means the configured review policy and quorum approved the exact payload. It does not mean that a failed or incomplete database write may be treated as applied. applied exists only after one atomic curation transaction commits. published means an immutable curation release manifest includes that transaction and its resulting state root.

rejected rejects the proposal, not historical evidence and not an already published entity unless the proposal explicitly requested a lifecycle action on that entity. Rejected proposed IDs remain reserved and auditable according to visibility policy; they are never recycled for another referent.

The policy version bound by a proposal determines eligible actor roles, quorum, separation of duties and evidence requirements for each action/domain/risk class. F2-018 may strengthen the matrix but cannot weaken these base rules:

  • an actor must have explicit current authority for the action at decision time;
  • every accepted proposal requires at least one approving actor distinct from its author; a zero-approval policy is invalid;
  • identity-changing, bulk, supersession and decision-invalidation actions require at least two distinct approving actors, including the owning domain role;
  • a review from an expired/revoked authority or a different policy version is invalid;
  • all required approvals bind identical proposal bytes; and
  • a database service account records authenticated actor decisions but is not itself the semantic reviewer.

Actor, role-grant snapshot, policy, review and decision facts are retained as private audit provenance when public disclosure is inappropriate. Public projections expose only approved non-sensitive attribution.

curation_executor may execute approved routines but has no direct table DML. app_runtime can read approved projections and execute approved reader routines only. Migration owners and break-glass operators do not gain semantic approval authority merely from technical privilege.

Applying an accepted proposal is one serializable semantic transaction. Before any effect becomes visible, it validates:

  1. exact proposal payload and accepted decision digests;
  2. actor/quorum, policy-version authority and the current authority/freeze epoch;
  3. complete evidence and used-source closure required by ADR-006;
  4. target kinds, domain ownership and identity contracts;
  5. immutable core release and anchor witnesses from ADR-005;
  6. expected lifecycle/revision tokens for every affected object;
  7. supersession cardinality, uniqueness and acyclicity from ADR-002;
  8. domain invariants, duplicate and negative cases;
  9. the frozen target inventory count and digest; and
  10. core reconstruction hashes before the operation.

The transaction then writes the new entities, append-only decision/event facts, supersession or relation edges and resulting projection revision together. Any failure rolls back all authoritative effects. Audit logs may report a failed attempt, but a failed attempt is never effective state.

Core hashes, actor authority, policy version and the authority/freeze epoch are checked again under their locked guards immediately before commit. A mismatch aborts the transaction. A core mismatch also freezes the affected curation lane for investigation. Annotation correction never becomes a core repair path.

Every proposal binds an expected_state contract over all affected authority streams:

  • current curation release or stream head ID;
  • ordered target ID and target revision inventory;
  • relevant supersession/resolution-policy version; and
  • the monotonic authority/freeze epoch for submission, application and publication;
  • the required lane state, such as open, for each affected operation; and
  • a canonical expected-state root.

The executor locks affected stream/target keys and the authority/freeze guard in canonical order and compares the contract immediately before application. Authority revocation and incident suspension atomically advance that guard epoch. A mismatch returns stale_proposal or operation_suspended with no authoritative write. The proposal must be reviewed again after rebasing; approval of old bytes cannot be carried to changed targets.

Wall-clock time, UUIDv7 sort order, insertion order and MAX(id) never select the current state. Current state comes from an explicit accepted stream/release head and its hash chain.

Every mutating lifecycle request, including submission, withdrawal, review recording, decision finalization, application, compensation, incident/freeze change and publication, carries an opaque stable idempotency key scoped to the authenticated operation channel. The first accepted binding stores the key, canonical request digest and resulting record, transaction, set or release ID atomically.

A retry with the same key and same digest returns the original result. The same key with different bytes fails with idempotency_conflict. A different key cannot apply an already-applied ordinary proposal twice because it has one accepted transaction identity. Publication records its key binding in the same compare-and-publish commit, so retry after an uncertain success returns the original release instead of a false stale-head result. Timeouts never authorize a blind retry with changed content.

A bulk proposal is not a dynamic command. It contains:

  • a human-readable discovery description;
  • the exact canonically ordered item/action inventory;
  • per-item expected revision and intended result;
  • inventory count and digest;
  • aggregate before/after semantic diff; and
  • representative positive and negative evidence where policy requires it.

Validation reports every item outcome before review. Application of one accepted bulk transaction is all-or-nothing. If scale requires chunks, the reviewed proposal first defines one immutable publication-set ID, the complete ordered chunk inventory, chunk count and set root. Every independently identified chunk transaction binds that same proposal digest, set ID/root, zero-based ordinal, total count and exact item/action inventory root. A chunk can be applied once; set-level and per-chunk operation channels have distinct stable idempotency keys and return their original results on retry.

The enclosing curation release must contain all and only the ordered chunks committed by that publication set. Membership, ordinals, roots and aggregate result are validated as a unit; ordinary unrelated transactions cannot impersonate or complete the set. The reader does not expose the new set until every required chunk is applied and the complete set passes validation. Partial staging is observable to operators, never disguised as full publication.

Accepted decisions, reviews and transactions are never edited or deleted. A mistake is corrected by a new proposal that references the exact prior decision and states the desired compensation.

Compensation is semantic, not a generic database inverse:

  • an erroneous amend receives a reviewed restoring amendment;
  • an erroneous creation is retired if it has no valid continuing role;
  • an erroneous retirement invalidates the exact retirement decision/event and atomically establishes the restored resolution path when the entity-kind policy permits restoration;
  • an erroneous supersession is invalidated by a reviewed decision and a corrected resolution path is established atomically; and
  • an erroneous bulk transaction is compensated by an explicit frozen item inventory, not by an unrecorded rollback script.

The old event remains resolvable with its invalidation/compensation link. Resolution policies use only decisions effective under the selected curation release and return the traversed history. They do not silently omit the mistake.

ADR-002 supersession uniqueness and acyclicity apply to the effective graph selected by one curation release. The immutable ledger may retain a formerly accepted event that a later release explicitly invalidates, but that event and its corrected replacement can never both be effective. Thus each predecessor still has at most one effective outgoing event and each successor at most one effective incoming event; history retention does not authorize competing current paths.

Each authority domain has an explicit canonical stream. Accepted transactions are staged facts; a curation_release publishes an ordered inventory of transaction IDs, one parent release ID, policy versions, source/core dependencies and a canonical resulting state root. The canonical public release history is single-parent and branch-free. Competing proposals can coexist, but only one reviewed publication path is current for a named release channel.

The effective-state projection is generated from the parent snapshot plus the exact ordered transaction inventory. The ordering is manifest data, not inferred from time, UUID or database order. Publication is an atomic compare-and-publish against the expected current release head. It locks and rechecks the authority/freeze guard, lane state and policy authority in the same commit. A stale expected head, advanced guard epoch, suspended lane, missing transaction, incomplete publication set, hash disagreement or closure failure publishes nothing.

Reader APIs bind responses to a curation release ID or an explicit current channel. Historical exact-ID lookup remains available subject to authorization. Current resolution returns the applied policy ID, release ID and supersession path; it never silently rewrites the requested ID.

A rebuild starts from certified core/domain package inputs and an immutable accepted curation release. Release inventories are deltas, not cumulative lists. The rebuilder walks the complete single-parent chain to the declared genesis release, verifies every parent link and root, then replays each release delta exactly once from genesis to the requested release. It uses the versioned action interpreters and policy artifacts bound by provenance. It must not start from a parent snapshot and also replay ancestor deltas, or derive acceptance from current materialized rows, is_current flags, confidence, timestamps or the absence of a row.

The rebuild emits:

  • the complete consumed transaction inventory and digest;
  • per-domain effective-state roots;
  • supersession/resolution graph root;
  • rejected, retired and historical-ID resolution checks;
  • before/after core reconstruction hashes; and
  • the overall effective-state root expected by the curation release.

All roots must match before a projection can replace the previous materialization. Different physical row order is harmless; different semantic roots fail closed.

An incident can suspend proposal acceptance, application and publication independently. Revoking executor credentials prevents new application but does not alter existing accepted history. Derived projections may be rebuilt from the last good release.

Break-glass access requires a time-bounded incident record and the configured human approvals. It may restore availability or collect evidence, but it cannot perform an unrecorded semantic correction. Any emergency semantic change must be represented by the same compensating lifecycle before it becomes the canonical state.

The lifecycle exposes distinct questions:

  • get candidate/proposal returns exact payload, evidence and review status;
  • get exact entity returns the historical entity and lifecycle summary;
  • resolve current returns explicit release/policy and full resolution result;
  • get decision history returns proposals, reviews, transactions and compensation;
  • preview semantic diff evaluates one frozen proposal without applying it; and
  • get effective state reads one named curation release projection.

Pending, rejected, retired, superseded, stale, unavailable and integrity-error states remain distinct. Absence, an empty meaning, low confidence and retirement are never interchangeable UI or API states.

Implementations must prove at least:

  1. Direct DML cannot create accepted state or alter accepted core/domain/occurrence referents through runtime or curation roles.
  2. Reviews with wrong proposal bytes, insufficient quorum, revoked authority or stale policy fail without authoritative writes.
  3. Identity-preserving actions retain the ID; identity-changing fixtures create the correct ADR-002 successor topology and preserve historical lookup.
  4. Stale expected-state and duplicate idempotency fixtures fail deterministically.
  5. Single and bulk transactions are atomic under injected failures at every write stage; no partial effective state becomes visible.
  6. Dynamic-query drift cannot change a submitted bulk target inventory.
  7. Compensating fixtures preserve the original event and produce the expected current resolution path.
  8. Replaying the same curation release from clean certified inputs yields identical effective-state and graph roots.
  9. Missing evidence, unused bundled evidence, invalid anchors and supersession cycles fail publication.
  10. Core release and reconstruction hashes are identical before and after every successful annotation curation fixture.
  11. Historical IDs remain resolvable after rejection, retirement, supersession and compensation according to visibility policy.
  12. Readers never observe a partially published multi-transaction release set.
  • Maintainers can add, remove, trim or replace one annotation after production without changing core text or invalidating citations.
  • Corpus-wide corrections remain possible, but their exact blast radius is reviewable and reproducible.
  • Generated pipelines can improve aggressively while acceptance remains human- and evidence-controlled.
  • Rebuilds preserve manual work and prove the same effective state instead of relying on a mutable database snapshot.
  • Mistakes can be corrected without hiding what was previously published.
  • Curation requires proposals, reviews and publication manifests instead of direct row editing.
  • Bulk edits need frozen inventories and may require staged publication sets.
  • Historical and compensating records consume storage and complicate current-state queries.
  • Every domain must define action validation and identity contracts before production writes are enabled.

This is simpler operationally but destroys cited historical state, makes stale review undetectable and prevents deterministic replay. It is rejected.

This is valid only before public identity issuance for disposable derived candidates. After publication it remints or retargets identities and loses manual decisions. It is rejected for production curation.

A mutable latest row cannot prove who accepted which bytes, reconstruct compensation or distinguish rejection from absence. It is rejected as authority, though it may be a derived cache.

The result can drift between review and execution. A predicate may support discovery, but only an exact frozen ID/action inventory is executable.

Domain validation differs, but separate ledgers create inconsistent authority, rollback and provenance semantics. One shared lifecycle with typed domain actions is required.

  • F2-010 defines public API versioning, RLS exposure and concrete error envelopes.
  • F2-018 defines compatibility classes and the complete two-person approval matrix.
  • F2-019 defines physical source, evidence, run and curation-event schemas.
  • F3/F4 schema work implements constraints, grants, routines and replay projections.
  • Domain phases define Ottoman, lexical, heading, note, repetition and translation action payloads and semantic validators.

Revisit this ADR if:

  • an annotation domain cannot express a valid correction through the shared action and supersession model;
  • PostgreSQL cannot enforce atomic compare-and-apply without unsafe direct DML;
  • release volume makes single-parent curation history impractical while preserving a deterministic branch-free public state; or
  • legal retention requirements require redaction of evidence that conflicts with permanent public identity and audit obligations.