A successful SQLite INSERT ... ON CONFLICT ... DO UPDATE is not, by itself, evidence that the statement targeted the partial unique index an engineer intended. SQLite defines the text between ON CONFLICT and DO as the conflict target, and its grammar allows a predicate after the indexed columns specifically so a partial uniqueness constraint can be identified. UPSERT acts only on uniqueness constraints: a UNIQUE or PRIMARY KEY declaration, or a unique index. Partial indexes, meanwhile, cover only rows for which their WHERE expression evaluates true.
The operational trap is therefore semantic, not merely syntactic. If a table has several uniqueness rules, especially multiple partial unique indexes over the same key columns, a syntactically valid conflict target can identify a different uniqueness rule from the one the application contract names. The database may return success while the validation question remains unanswered: which predicate-defined uniqueness domain actually governed the operation? SQLite's own internal description calls the optional conflict-target WHERE expression the field used to identify partial unique indexes.
This playbook treats that question as a release-acceptance problem. It uses a disposable database, synthetic rows, a pinned target SQLite release, an independent expected-case manifest, explicit negative controls, state reconciliation, preserved failure evidence, and a four-way ACCEPT / REPAIR / RERUN / HOLD decision. The current official SQLite release verified during research is 3.54.1, released October 16, 2026; SQLite publishes Linux command-line tools for that version as sqlite-tools-linux-x64-3540100.zip.
No behavioral case below is represented as locally executed. The research environment did not provide an executable sqlite3 CLI, and the official binary could not be fetched into that isolated runtime. Consequently every case is marked EXPECTED / NOT EXECUTED. Documentation claims and expected fixture outcomes are deliberately kept separate.
Define the acceptance contract and baseline
The acceptance contract should not be “the SQL returned without error.” That signal is too weak. For this investigation, acceptance means that the conflict target identifies the declared uniqueness domain, the affected row belongs to that domain, the resulting state agrees with an independently written oracle, and the evidence is tied to an exact SQLite build.
SQLite documents four facts that define the technical boundary. First, the conflict target specifies the uniqueness constraint that triggers the UPSERT. Second, only one matching ON CONFLICT clause runs for an input row, and clauses are considered in order. Third, UPSERT processing applies only to uniqueness constraints, including unique indexes. Fourth, a partial index contains only rows for which its WHERE expression is true.
Do not conflate this UPSERT syntax with SQLite's older conflict-resolution mechanism such as INSERT OR IGNORE, OR REPLACE, ROLLBACK, ABORT, or FAIL. SQLite explicitly documents them as two different uses of the phrase “ON CONFLICT.” The older clause selects a resolution algorithm; the UPSERT conflict target selects the uniqueness constraint relevant to the UPSERT arm.
The acceptance artifacts are:
Artifact | Purpose | Acceptance assertion |
version.txt | Pins runtime | sqlite3 -version equals approved version |
schema.sql | Declares competing partial unique indexes | Stored schema matches reviewed DDL |
manifest.tsv | Independent oracle | Expected target and final state predate execution |
case-*.sql | One synthetic case each | No case mutates another case's database |
stdout.txt / stderr.txt | Raw engine evidence | Preserved verbatim |
before.tsv / after.tsv | State evidence | Identity and values reconcile |
schema.tsv | Index evidence | Unique/partial flags and predicates captured |
integrity.txt | Structural check | PRAGMA integrity_check returns ok |
ledger.tsv | Human review | Every case receives status and disposition |
SQLite exposes enough metadata to make the schema evidence independent of application assumptions. PRAGMA index_list(table) reports whether each index is unique and whether it is partial, while sqlite_schema.sql records the CREATE INDEX text for programmer-created indexes.
The target baseline for this playbook is SQLite 3.54.1. That release is current as of November 12, 2026 according to SQLite's official release and download pages.
# Required precondition for an executed acceptance run.
# This command has NOT been executed for the report below.
# EXPECTED / NOT EXECUTED
sqlite3 -version | tee evidence/version.txt
test "$(sqlite3 -version | awk '{print $1}')" = "3.54.1"Measurable pass condition: the first token printed by the candidate sqlite3 binary is exactly 3.54.1, and version.txt is retained with the evidence bundle.
Measurable fail condition: the command is unavailable, reports another version, or the version cannot be attributed to the binary that actually executed the cases.
That last condition matters. “Our dependency manifest says SQLite 3.54.1” is not runtime evidence. Capture the binary's report from the process used for the fixture.
The Machine learning evaluation article focuses on model metrics, baselines, protected test data, thresholding, calibration, and reproducible ML performance claims. Its reusable principle is independent evaluation; its workflow, datasets, metrics, and failure modes are unrelated to SQLite uniqueness arbitration.
Create the isolated fixture and expected-case manifest
The fixture needs two competing partial uniqueness domains over the same key columns. That is the smallest useful design for exposing the difference between “SQLite accepted my UPSERT” and “SQLite selected the uniqueness rule I meant.”
Use a synthetic contact table:
-- schema.sql
-- EXPECTED / NOT EXECUTEDPRAGMA foreign_keys = ON;CREATE TABLE contact (
id INTEGER PRIMARY KEY,
tenant_id INTEGER NOT NULL,
email TEXT NOT NULL,
deleted_at TEXT,
verified INTEGER NOT NULL CHECK (verified IN (0,1)),
payload TEXT NOT NULL
);CREATE UNIQUE INDEX ux_contact_live_email
ON contact(tenant_id, email)
WHERE deleted_at IS NULL;CREATE UNIQUE INDEX ux_contact_verified_email
ON contact(tenant_id, email)
WHERE verified = 1;Both indexes are legal SQLite partial unique indexes: adding WHERE makes an index partial, and adding UNIQUE requires entries that actually belong to that index to be unique. Rows whose predicate is false or NULL are omitted from that partial index.
The two domains are intentionally different:
Index | Key | Predicate | Business-style interpretation |
ux_contact_live_email | (tenant_id,email) | deleted_at IS NULL | One live row per email |
ux_contact_verified_email | (tenant_id,email) | verified = 1 | One verified row per email |
The fixture is disposable:
#!/bin/sh
# run-fixture.sh
# EXPECTED / NOT EXECUTEDset -euROOT="${ROOT:-$(pwd)/sqlite-upsert-partial-fixture}"
DB="$ROOT/fixture.db"
EVIDENCE="$ROOT/evidence"rm -rf "$ROOT"
mkdir -p "$EVIDENCE"sqlite3 -version > "$EVIDENCE/version.txt"sqlite3 "$DB" < schema.sqlsqlite3 -tabs "$DB" "
SELECT name, \"unique\", origin, partial
FROM pragma_index_list('contact')
ORDER BY name;
" > "$EVIDENCE/index-list.tsv"sqlite3 -tabs "$DB" "
SELECT name, sql
FROM sqlite_schema
WHERE type='index'
AND tbl_name='contact'
ORDER BY name;
" > "$EVIDENCE/schema.tsv"sqlite3 "$DB" "PRAGMA integrity_check;" \
> "$EVIDENCE/integrity-initial.txt"sqlite_schema is appropriate here because SQLite documents its sql column as the SQL text that recreates application-defined schema objects, subject to limited normalization.
The expected-case manifest must be written before case output is inspected. It is not generated from the database under test.
# manifest.tsv
# EXPECTED / NOT EXECUTED
case target_domain expected_engine_result expected_row_effect decision_if_match
C01 live success update live row ACCEPT
C02 verified success update verified row HOLD
C03 live success insert tombstone ACCEPT
C04 no_matching_target prepare/error none ACCEPT
C05 update_abort constraint error statement rollback ACCEPT
C06 live-negative no live-row update insert ACCEPTThe manifest is an independent test oracle because it declares semantics in domain language (live, verified, no_matching_target) instead of copying whatever SQLite reports. The test runner later translates actual rows and error classes back into those domain assertions.
The fixture should also capture index columns and collations:
-- EXPECTED / NOT EXECUTED
SELECT FROM pragma_index_xinfo('ux_contact_live_email');
SELECT FROM pragma_index_xinfo('ux_contact_verified_email');SQLite documents PRAGMA index_xinfo as returning the key and auxiliary columns of an index, including sort direction and collating sequence.
The asyncio context capture article studies when asyncio.to_thread() captures contextvars, distinguishing coroutine construction, task scheduling, context capture, and worker execution. Its useful shared discipline is event-boundary isolation. Its subject is Python task/context timing, not database uniqueness.
A proper negative control verifies that the harness can distinguish a row that belongs to the intended live uniqueness domain from one that does not.
-- negative-control.sql
-- EXPECTED / NOT EXECUTEDDELETE FROM contact;INSERT INTO contact
(id, tenant_id, email, deleted_at, verified, payload)
VALUES
(1, 10, '[email protected]', '2026-01-01T00:00:00Z', 0, 'tombstone');INSERT INTO contact
(tenant_id, email, deleted_at, verified, payload)
VALUES
(10, '[email protected]', '2026-02-01T00:00:00Z', 0, 'second tombstone')
ON CONFLICT(tenant_id, email)
WHERE deleted_at IS NULL
DO UPDATE SET payload = excluded.payload;SELECT id, tenant_id, email, deleted_at, verified, payload
FROM contact
ORDER BY id;Because neither row satisfies deleted_at IS NULL, neither belongs to ux_contact_live_email; the expected result is two rows, not an update of row 1. That expectation follows from the documented definition of partial-index membership.
Negative-control pass condition: two tombstoned rows exist after the statement, row 1 retains payload='tombstone', and the new row has payload='second tombstone'.
Negative-control fail condition: row 1 is updated, only one row remains, or the case cannot distinguish the intended predicate domain.
Status: EXPECTED / NOT EXECUTED.
Reproduce the misleading success and comparison case
The misleading-success case deliberately targets the verified uniqueness domain while the hypothetical release requirement names the live domain. Nothing here assumes SQLite behaves incorrectly. The point is that a valid statement can be wrong relative to the caller's intended contract.
Seed a row that is verified but deleted:
-- case-C02-wrong-domain.sql
-- EXPECTED / NOT EXECUTEDDELETE FROM contact;INSERT INTO contact
(id, tenant_id, email, deleted_at, verified, payload)
VALUES
(1, 10, '[email protected]',
'2026-01-01T00:00:00Z', 1, 'before');INSERT INTO contact
(tenant_id, email, deleted_at, verified, payload)
VALUES
(10, '[email protected]',
'2026-02-01T00:00:00Z', 1, 'after')
ON CONFLICT(tenant_id, email)
WHERE verified = 1
DO UPDATE SET payload = excluded.payload;SELECT changes();SELECT id, tenant_id, email, deleted_at, verified, payload
FROM contact
ORDER BY id;The statement explicitly names (tenant_id,email) WHERE verified = 1. The fixture contains a unique partial index with exactly that declared domain. If the statement succeeds by updating row 1, it demonstrates that the SQL is operational for the verified rule; it does not show that the statement validated ux_contact_live_email. SQLite's UPSERT documentation says the conflict target specifies which uniqueness constraint triggers that arm.
The expected ledger entry is therefore deliberately uncomfortable:
Case | API/CLI signal | Semantic target | Intended release target | Expected disposition |
C02 | success | verified | live | HOLD |
Status: EXPECTED / NOT EXECUTED.
Now run the comparison with the predicate that defines the intended live index:
-- case-C01-live.sql
-- EXPECTED / NOT EXECUTEDDELETE FROM contact;INSERT INTO contact
(id, tenant_id, email, deleted_at, verified, payload)
VALUES
(1, 10, '[email protected]',
NULL, 0, 'before');INSERT INTO contact
(tenant_id, email, deleted_at, verified, payload)
VALUES
(10, '[email protected]',
NULL, 0, 'after')
ON CONFLICT(tenant_id, email)
WHERE deleted_at IS NULL
DO UPDATE SET payload = excluded.payload;SELECT changes();SELECT id, tenant_id, email, deleted_at, verified, payload
FROM contact
ORDER BY id;Here the target predicate corresponds to ux_contact_live_email, and both the existing and proposed rows are members of that partial uniqueness domain. A successful update plus the expected final row is evidence for this bounded case.
This distinction matters because query-planner partial-index logic should not be substituted for conflict-target reasoning. SQLite's partial-index documentation discusses when a query predicate implies an index predicate (W⇒X) and explains that the planner uses deliberately limited matching rules rather than a general theorem prover. That documentation concerns query usability, not a promise that arbitrary logically equivalent expressions will identify an UPSERT target.
For release validation, avoid clever logical rewrites of the target predicate. Preserve the reviewed partial-index predicate in the UPSERT unless a separately executed case proves the intended version accepts the alternative.
A comparison invariant is stronger than “both commands return success”:
EXPECTED / NOT EXECUTED
C01:
target predicate = deleted_at IS NULL
seeded conflicting row satisfies deleted_at IS NULL
final state = same row identity, payload changed to "after"
C02:
target predicate = verified = 1
seeded conflicting row satisfies verified = 1
final state = same row identity, payload changed to "after"
Required differential:
C01 and C02 exercise different predicate-defined uniqueness domains.Pass: each case's seed satisfies only the domain it is intended to isolate, and final-state evidence agrees with the independent manifest.
Fail: the rows accidentally satisfy both predicates, fixture state leaks between cases, or reviewers infer index identity solely from a zero exit status.
The Kubernetes preStop article treats graceful termination as a lifecycle-budget and evidence problem, including pinned tool versions and preserved state. Its reusable idea is that one successful signal does not prove a different lifecycle boundary.
Exercise failure boundaries and preserve per-case evidence
A validation suite that contains only success paths cannot show that it detects incorrect conflict targets. Failure evidence is part of the acceptance contract.
The first boundary is a target that should not correspond to either declared partial unique index:
-- case-C04-no-match.sql
-- EXPECTED / NOT EXECUTED
INSERT INTO contact
(tenant_id, email, deleted_at, verified, payload)
VALUES
(10, '[email protected]', NULL, 0, 'x')
ON CONFLICT(tenant_id, email)
WHERE verified = 0
DO UPDATE SET payload = excluded.payload;There is no declared unique index on (tenant_id,email) WHERE verified = 0. The expected outcome is failure to resolve the named target rather than a silent fallback to an unrelated uniqueness rule.
Status: EXPECTED / NOT EXECUTED.
The second boundary should test a predicate rewrite rather than assume semantic equivalence is accepted:
-- case-predicate-rewrite.sql
-- EXPECTED / NOT EXECUTED
INSERT INTO contact
(tenant_id, email, deleted_at, verified, payload)
VALUES
(10, '[email protected]', NULL, 0, 'x')
ON CONFLICT(tenant_id, email)
WHERE NOT (deleted_at IS NOT NULL)
DO UPDATE SET payload = excluded.payload;The Boolean expression is logically intended to describe the same rows as deleted_at IS NULL, but this playbook does not claim SQLite 3.54.1 will treat the target as interchangeable without execution evidence. SQLite's internal representation explicitly stores a conflict-target predicate for identifying partial unique indexes, while its public partial-index documentation separately warns that SQLite does not generally perform algebraic theorem proving when reasoning about predicates.
That is exactly the sort of boundary that belongs in a versioned fixture rather than in prose presented as a guarantee.
A third failure boundary tests the DO UPDATE path itself:
-- case-C05-update-abort.sql
-- EXPECTED / NOT EXECUTEDCREATE UNIQUE INDEX ux_payload
ON contact(payload);DELETE FROM contact;INSERT INTO contact
(id, tenant_id, email, deleted_at, verified, payload)
VALUES
(1, 10, '[email protected]', NULL, 0, 'one'),
(2, 20, '[email protected]', NULL, 0, 'two');INSERT INTO contact
(tenant_id, email, deleted_at, verified, payload)
VALUES
(10, '[email protected]', NULL, 0, 'two')
ON CONFLICT(tenant_id, email)
WHERE deleted_at IS NULL
DO UPDATE SET payload = excluded.payload;SQLite explicitly documents that constraint handling inside the DO UPDATE portion is always ABORT: if the update violates another constraint, the entire INSERT statement is rolled back.
The expected final state is therefore row 1 still carrying payload='one' and row 2 carrying payload='two'.
Status: EXPECTED / NOT EXECUTED.
Preserve raw evidence per case instead of piping everything through a summarizer:
#!/bin/sh
# run-case.sh
# EXPECTED / NOT EXECUTEDset -uCASE="$1"
DB="runs/$CASE/fixture.db"
mkdir -p "runs/$CASE"cp pristine.db "$DB"sqlite3 -tabs "$DB" "
SELECT id, tenant_id, email, deleted_at, verified, payload
FROM contact ORDER BY id;
" > "runs/$CASE/before.tsv"set +e
sqlite3 -bail "$DB" < "cases/$CASE.sql" \
> "runs/$CASE/stdout.txt" \
2> "runs/$CASE/stderr.txt"
RC=$?
set -eprintf '%s\n' "$RC" > "runs/$CASE/exit-code.txt"sqlite3 -tabs "$DB" "
SELECT id, tenant_id, email, deleted_at, verified, payload
FROM contact ORDER BY id;
" > "runs/$CASE/after.tsv"sqlite3 "$DB" "PRAGMA integrity_check;" \
> "runs/$CASE/integrity.txt"PRAGMA integrity_check verifies low-level database consistency including missing or surplus index entries and uniqueness errors; when no such problems are found it returns the single value ok. It does not prove that the application chose the right conflict-target predicate, so it is a guardrail rather than the oracle.
A per-case evidence ledger should look like this before execution:
Case | Version | Target | Expected result | Expected state | Observed result | Observed state | Status |
C01 | 3.54.1 target | live | success/update | row 1 → after | Not observed | Not observed | EXPECTED / NOT EXECUTED |
C02 | 3.54.1 target | verified | success/update | row 1 → after | Not observed | Not observed | EXPECTED / NOT EXECUTED |
C03 | 3.54.1 target | live | success/insert | two tombstones | Not observed | Not observed | EXPECTED / NOT EXECUTED |
C04 | 3.54.1 target | none | target error | unchanged | Not observed | Not observed | EXPECTED / NOT EXECUTED |
C05 | 3.54.1 target | live + ux_payload | constraint error | statement rolled back | Not observed | Not observed | EXPECTED / NOT EXECUTED |
C06 | 3.54.1 target | negative control | insert | original unchanged | Not observed | Not observed | EXPECTED / NOT EXECUTED |
The test passes only when the original stdout, stderr, exit code, pre-state, post-state, schema capture, integrity output, and runtime identity remain available. A human-written “PASS” file without those artifacts is not adequate failure evidence.
Reconcile state, identity, documentation, and observation
A release reviewer should reconcile three things after each UPSERT: row identity, row membership in the relevant partial-index predicate, and the changed values.
Identity matters because DO UPDATE modifies the conflicting row; the result should not be accepted merely because a row with the requested values exists somewhere after the statement. SQLite documents that the DO UPDATE action applies to the single row that experienced the uniqueness conflict.
For the live-domain case:
-- reconciliation-C01.sql
-- EXPECTED / NOT EXECUTED
SELECT
id,
tenant_id,
email,
deleted_at,
deleted_at IS NULL AS in_live_domain,
verified,
verified = 1 AS in_verified_domain,
payload
FROM contact
ORDER BY id;The test oracle requires id=1, in_live_domain=1, and payload='after'. The verified domain should be controlled so the case does not accidentally prove both partial indexes at once.
The same principle appears in optimistic concurrency systems, but it is not the same mechanism. The HTTP If-Match article focuses on strong validators and atomically rejecting stale HTTP resource versions so concurrent edits do not overwrite each other. This SQLite experiment has no ETag, HTTP precondition, or concurrent-editor workflow; its narrower concern is mapping an UPSERT conflict target to a predicate-scoped uniqueness rule.
Documentation and observation must be recorded in separate columns.
Claim | Classification | Evidence |
A partial index includes only rows where its predicate is true | DOCUMENTED | SQLite partial-index documentation |
UNIQUE partial indexes enforce uniqueness among index entries | DOCUMENTED | SQLite partial-index / CREATE INDEX docs |
UPSERT conflict targets identify uniqueness constraints | DOCUMENTED | SQLite UPSERT documentation |
Target WHERE is represented internally for identifying partial unique indexes | DOCUMENTED IMPLEMENTATION DETAIL | SQLite source commentary |
SQLite 3.54.1 is the current release on Nov. 12, 2026 | VERIFIED PUBLIC BASELINE | Official release/download pages |
C01 updates row 1 on a particular workstation | OBSERVED | No observation available |
Predicate rewrite is rejected on 3.54.1 | OBSERVED/TEST REQUIRED | EXPECTED / NOT EXECUTED |
SQLite's release history says UPSERT entered SQLite in 3.24.0 in 2018; generalized UPSERT with multiple clauses and a final clause lacking a target arrived in 3.35.0 in 2021. Partial indexes have existed since 3.8.0. Those facts support the fixture's version requirements but do not prove that every historical build should be treated identically.
There is another subtle documentation boundary: if the final ON CONFLICT clause omits its conflict target, SQLite documents that it can catch a uniqueness failure not handled by prior target-specific clauses.
That is useful application syntax, but it is inappropriate as the primary probe in this acceptance test. A catch-all arm destroys evidence about which named partial uniqueness domain the developer intended to validate.
For example:
-- Do not use this as the primary acceptance probe.
-- EXPECTED / NOT EXECUTED
INSERT INTO contact(...)
VALUES(...)
ON CONFLICT DO UPDATE
SET payload = excluded.payload;A successful catch-all UPSERT may establish that some uniqueness rule fired; it does not, by itself, establish that ux_contact_live_email was the intended one.
A bounded repair therefore changes only the target definition or schema element demonstrated to be inconsistent with the contract. It does not rewrite unrelated conflict handling, replace UPSERT with INSERT OR REPLACE, or drop uniqueness rules merely to turn a failing acceptance test green.
Implement bounded repair and verify rollback and rerun safety
Suppose review finds application SQL using:
ON CONFLICT(tenant_id, email)
WHERE verified = 1
DO UPDATE ...while the written contract says “one live contact per tenant/email,” defined by deleted_at IS NULL.
The smallest repair is not “make the statement stop erroring.” It is to align conflict-target semantics with the declared live uniqueness rule:
-- bounded repair candidate
-- EXPECTED / NOT EXECUTED
INSERT INTO contact
(tenant_id, email, deleted_at, verified, payload)
VALUES
(:tenant_id, :email, :deleted_at, :verified, :payload)
ON CONFLICT(tenant_id, email)
WHERE deleted_at IS NULL
DO UPDATE SET
payload = excluded.payload,
verified = excluded.verified;Before release, compare that SQL with the stored schema:
-- EXPECTED / NOT EXECUTED
SELECT name, sql
FROM sqlite_schema
WHERE type='index'
AND name='ux_contact_live_email';The repair boundary is measurable:
PASS: only the target predicate or the explicitly reviewed corresponding index definition changes; all other UPSERT mutation semantics remain unchanged unless separately justified.
FAIL: the repair adds catch-all conflict handling, OR REPLACE, unrelated uniqueness changes, or data cleanup that masks whether the original target was wrong.
SQLite's REPLACE algorithm is particularly unsuitable as an invisible substitute. For uniqueness violations, SQLite documents REPLACE as deleting pre-existing conflicting rows before inserting or updating the new row, which has materially different identity and trigger implications from UPSERT DO UPDATE.
Rollback verification should execute a failing statement inside an explicit transaction and prove both the expected statement rollback and the controlled state of the transaction.
-- rollback-probe.sql
-- EXPECTED / NOT EXECUTEDBEGIN IMMEDIATE;SELECT 'before', id, payload
FROM contact
ORDER BY id;-- C05 statement goes here and is expected to fail.SELECT 'after-failure', id, payload
FROM contact
ORDER BY id;ROLLBACK;SELECT 'after-rollback', id, payload
FROM contact
ORDER BY id;Because SQLite documents the DO UPDATE part as using the ABORT conflict algorithm, a constraint violation inside that update backs out the current INSERT statement.
The rerun contract should make each case start from a pristine seed rather than rely on idempotence accidentally provided by previous output.
# EXPECTED / NOT EXECUTED
rm -f pristine.db
sqlite3 pristine.db < schema.sql
sqlite3 pristine.db < seed.sql
for case in C01 C02 C03 C04 C05 C06
do
./run-case.sh "$case"
doneA rerun passes when two independent runs from the same pristine seed produce the same normalized row-state evidence, error class, and decision. Timestamped filenames, SQLite-generated transient identifiers outside the asserted contract, or shell metadata should not be treated as semantic differences.
The CSS transition cancellation article uses a similar evidence discipline for transitionend versus transitioncancel: the final visual style alone is not sufficient proof of the lifecycle event that occurred. Its browser-event workflow remains separate; the shared principle is only that final state and causal mechanism must not be collapsed into one signal.
Operational ownership belongs to whoever can answer four questions with artifacts:
Who approves the target SQLite version?
Who owns the expected-case manifest?
Who investigates a target-resolution contradiction?
Who signs the release decision after state reconciliation?
The ownership gate passes only when all four roles are named in the release record, even if one person holds more than one role. An unexplained failure must not be converted into ACCEPT because the application “worked in manual testing.”
Decide ACCEPT, REPAIR, RERUN, or HOLD
The final decision is not a pass/fail boolean. Different evidence failures require different actions.
Outcome | Required evidence | Decision | Meaning |
All target, state, identity, negative-control, rollback and integrity assertions match manifest on approved runtime | Complete | ACCEPT | Evidence supports this bounded release |
SQL/schema target is demonstrably inconsistent with declared contract and fix is narrow | Complete enough to identify defect | REPAIR | Change contract implementation, then rerun |
Harness failure, incomplete files, wrong seed, transient execution problem, or wrong binary | Invalid/incomplete | RERUN | Result is not interpretable |
Contradictory target behavior, unapproved version, unexplained state, missing negative control, or ambiguous uniqueness domain | Insufficient or contradictory | HOLD | Do not approve |
For the unexecuted fixture in this report, the release decision is HOLD. The fixture design is reviewable, and the documented contracts are sourced, but no local SQLite 3.54.1 behavioral evidence has been produced. Calling the design ACCEPT would invent an execution result.
The complete pre-execution decision ledger is:
Case | Purpose | Expected outcome | Execution status | Current decision contribution |
C01 | Correct live target | Live row updated | EXPECTED / NOT EXECUTED | HOLD |
C02 | Wrong-domain success | Verified row updated, proving wrong semantic domain can still succeed | EXPECTED / NOT EXECUTED | HOLD |
C03 | Out-of-domain insert | Tombstoned duplicate inserts | EXPECTED / NOT EXECUTED | HOLD |
C04 | Missing target | Target-resolution failure | EXPECTED / NOT EXECUTED | HOLD |
C05 | DO UPDATE violation | Statement aborted and rolled back | EXPECTED / NOT EXECUTED | HOLD |
C06 | Negative control | No accidental live-domain conflict | EXPECTED / NOT EXECUTED | HOLD |
Integrity | Structural check | ok | EXPECTED / NOT EXECUTED | HOLD |
Version | Runtime pin | 3.54.1 | EXPECTED / NOT EXECUTED | HOLD |
A useful release rule is:
ACCEPT =
approved_runtime
AND all_required_cases_executed
AND manifest_matches_observation
AND negative_control_passes
AND state_identity_reconciles
AND rollback_probe_passes
AND integrity_check_is_ok
AND no_unresolved_contradictionThat formula is intentionally stricter than sqlite3_exit_code == 0.
A REPAIR decision is appropriate when evidence has isolated the problem, for example, the application names WHERE verified = 1 while the accepted schema contract names WHERE deleted_at IS NULL.
A RERUN decision is appropriate when the evidence is invalid rather than the software: wrong SQLite binary, contaminated database, missing seed, corrupted output capture, or a case that accidentally satisfies both predicates.
A HOLD decision is appropriate when the contradiction is real but not understood. Examples include version-dependent behavior not represented in the manifest, a target that unexpectedly resolves, or final state that disagrees with both the documented contract and the independent oracle.
The “successful API return” is therefore evidence of execution status, not a release verdict. SQLite's own documentation defines conflict targets and partial-index membership precisely enough to demand a stronger test.
Learning context and limitations
The focus here is the interaction between SQLite UPSERT conflict-target predicates and partial unique indexes, with independent proof that the intended predicate-scoped uniqueness domain, rather than merely some uniqueness failure, governed the statement.
A compact validation workflow is:

The diagram is explanatory only. Its nodes are not evidence that any fixture case has executed.
The Refonte Learning Database Administrator Essentials program page lists a three-month period, 12 to 14 hours/week, database design and architecture, SQL query optimization, backup and recovery, performance tuning, security, cloud database management, migration, disaster recovery, role-based access control, and monitoring and maintenance. It recommends basic programming knowledge and separately states an admission prerequisite of working toward a bachelor's degree or higher. The page also describes hands-on projects, personalized mentorship, and completion credentials.
The page does not establish that this exact SQLite conflict-target laboratory, SQLite 3.54.1, or SQLite-specific partial-index validation is taught. Engineers seeking structured study of database design, SQL optimization, recovery, security, and administration can review the program page, while treating this SQLite fixture as a separate reproducible exercise.
The limitations are material. No fixture command in this report was executed against SQLite 3.54.1, so every behavioral prediction remains EXPECTED / NOT EXECUTED. The current release number and downloadable artifact were verified from SQLite's official pages, but that verifies availability, not fixture behavior.
The fixture also does not claim to validate every legal indexed expression, collation, generated column, WITHOUT ROWID table, multi-row UPSERT, trigger interaction, virtual table, or historical SQLite release. SQLite explicitly states that UPSERT does not currently work for virtual tables, and its semantics have evolved since the original 3.24.0 implementation.
Finally, neither PRAGMA integrity_check nor a green process exit can answer the central semantic question alone. Integrity checking tests database consistency; successful UPSERT execution tests whether the engine accepted and completed a statement. The release claim requires a third piece: independently reconciled evidence that the conflict target corresponds to the intended partial uniqueness predicate.
