# Mode-transition matrix — ADR-0033. What an export inherits from its PREVIOUS mode when it
# switches to incremental (or keyset_incremental): a full pass (no cursor was stored), a
# continuation (same cursor identity), or a loud refusal (different identity). Each cell runs
# the previous mode over 10 rows, inserts 3 more, restages the same Rig to the new mode in the
# SAME destination and reads the parts that run added (tests/live/live_mode_transition.rs,
# `Stages`): an export that keeps a cursor is refused another destination
# (RIVET_STATE_CURSOR_DESTINATION_MISMATCH, docs/sabotage-matrix.yaml), so a stage is never
# given its own. A fresh destination appears only where no progress is left to continue: after
# a `state reset`, or under another export name.

engines: [postgres, mysql, mssql, mongo, oracle]

scenarios:
  - id: full_then_incremental
    what: "MT1 — mode: full stores no cursor; the first incremental run is a full pass"
    postgres: { test: full_then_incremental_postgres }
    mysql:    { test: full_then_incremental_mysql }
    mssql:    { test: full_then_incremental_mssql }
    mongo:    { test: full_then_resume_mongo }
    oracle:   { test: full_then_incremental_oracle }

  - id: time_window_then_incremental
    what: "MT1 — time_window stores no cursor; full pass"
    postgres: { test: time_window_then_incremental_postgres }
    mysql:    { test: time_window_then_incremental_mysql }
    mssql:    { test: time_window_then_incremental_mssql }
    mongo:    { na: "a Mongo export accepts only mode: full or cdc (validate_non_sql_source_modes, src/config/mod.rs:543-554), so there is no incremental / chunked mode to switch from or into; the switch Mongo has (into page_size + resume) is graded by the three *_then_resume_mongo cells" }
    oracle:   { test: time_window_then_incremental_oracle }

  - id: range_chunked_then_incremental
    what: "MT1 — range chunking (chunk_column + chunk_checkpoint) keeps chunk_task state, never a cursor; full pass"
    postgres: { test: range_chunked_then_incremental_postgres }
    mysql:    { test: range_chunked_then_incremental_mysql }
    mssql:    { test: range_chunked_then_incremental_mssql }
    mongo:    { na: "a Mongo export accepts only mode: full or cdc (validate_non_sql_source_modes, src/config/mod.rs:543-554), so there is no incremental / chunked mode to switch from or into; the switch Mongo has (into page_size + resume) is graded by the three *_then_resume_mongo cells" }
    oracle:   { test: range_chunked_then_incremental_oracle }

  - id: keyset_then_incremental_same_key
    what: "MT2 — keyset without chunk_checkpoint still records its final high-water; incremental on the key continues"
    postgres: { test: keyset_then_incremental_same_key_postgres }
    mysql:    { test: keyset_then_incremental_same_key_mysql }
    mssql:    { test: keyset_then_incremental_same_key_mssql }
    mongo:    { test: keyset_then_resume_mongo }
    oracle:   { test: keyset_then_incremental_same_key_oracle }

  - id: keyset_checkpoint_then_incremental_same_key
    what: "MT2 — keyset with chunk_checkpoint (the init default); incremental on the key continues"
    postgres: { test: keyset_checkpoint_then_incremental_same_key_postgres }
    mysql:    { test: keyset_checkpoint_then_incremental_same_key_mysql }
    mssql:    { test: keyset_checkpoint_then_incremental_same_key_mssql }
    mongo:    { na: "a Mongo export accepts only mode: full or cdc (validate_non_sql_source_modes, src/config/mod.rs:543-554), so there is no incremental / chunked mode to switch from or into; the switch Mongo has (into page_size + resume) is graded by the three *_then_resume_mongo cells" }
    oracle:   { test: keyset_checkpoint_then_incremental_same_key_oracle }

  - id: parallel_keyset_then_incremental_same_key
    what: "MT2 — parallel keyset records the highest range max; incremental on the key continues"
    postgres: { test: parallel_keyset_then_incremental_same_key_postgres }
    mysql:    { test: parallel_keyset_then_incremental_same_key_mysql }
    mssql:    { test: parallel_keyset_then_incremental_same_key_mssql }
    mongo:    { test: parallel_keyset_then_resume_mongo }
    oracle:   { test: parallel_keyset_then_incremental_same_key_oracle }

  - id: keyset_then_incremental_other_column
    what: "MT3 — keyset on id, then incremental on server_time: refused, nothing exported; full pass after state reset (the field case)"
    postgres: { test: keyset_then_incremental_other_column_postgres }
    mysql:    { test: keyset_then_incremental_other_column_mysql }
    mssql:    { test: keyset_then_incremental_other_column_mssql }
    mongo:    { na: "a Mongo export accepts only mode: full or cdc (validate_non_sql_source_modes, src/config/mod.rs:543-554), so there is no incremental / chunked mode to switch from or into; the switch Mongo has (into page_size + resume) is graded by the three *_then_resume_mongo cells" }
    oracle:   { test: keyset_then_incremental_other_column_oracle }

  - id: keyset_incremental_key_change
    what: "MT3 — keyset_incremental on id, then on another unique key: BOTH keyset runners (sequential, and parallel, which reads the anchor in its own call) refuse their own anchor"
    postgres: { test: keyset_incremental_key_change_postgres }
    mysql:    { test: keyset_incremental_key_change_mysql }
    mssql:    { test: keyset_incremental_key_change_mssql }
    mongo:    { na: "the Mongo keyset key is always _id (full_strategy, src/plan/build.rs) and chunk_by_key is refused outside mode: chunked (src/config/mod.rs:1360-1364), so the key cannot change" }
    oracle:   { test: keyset_incremental_key_change_oracle }

  - id: incremental_then_keyset_incremental_same_key
    what: "MT2 — incremental on id, then keyset_incremental on id: continues from the incremental cursor"
    postgres: { test: incremental_then_keyset_incremental_same_key_postgres }
    mysql:    { test: incremental_then_keyset_incremental_same_key_mysql }
    mssql:    { test: incremental_then_keyset_incremental_same_key_mssql }
    mongo:    { na: "a Mongo export accepts only mode: full or cdc (validate_non_sql_source_modes, src/config/mod.rs:543-554), so there is no incremental / chunked mode to switch from or into; the switch Mongo has (into page_size + resume) is graded by the three *_then_resume_mongo cells" }
    oracle:   { test: incremental_then_keyset_incremental_same_key_oracle }

  - id: incremental_cursor_change
    what: "MT3 — cursor_column changed without a reset: refused; full pass after state reset"
    postgres: { test: incremental_cursor_change_postgres }
    mysql:    { test: incremental_cursor_change_mysql }
    mssql:    { test: incremental_cursor_change_mssql }
    mongo:    { na: "a Mongo export accepts only mode: full or cdc (validate_non_sql_source_modes, src/config/mod.rs:543-554), so there is no incremental / chunked mode to switch from or into; the switch Mongo has (into page_size + resume) is graded by the three *_then_resume_mongo cells" }
    oracle:   { test: incremental_cursor_change_oracle }

  - id: incremental_single_to_coalesce
    what: "MT3 — single_column → coalesce on the same primary changes the identity: refused (rows with a NULL primary were never exported)"
    postgres: { test: incremental_single_to_coalesce_postgres }
    mysql:    { test: incremental_single_to_coalesce_mysql }
    mssql:    { test: incremental_single_to_coalesce_mssql }
    mongo:    { na: "a Mongo export accepts only mode: full or cdc (validate_non_sql_source_modes, src/config/mod.rs:543-554), so there is no incremental / chunked mode to switch from or into; the switch Mongo has (into page_size + resume) is graded by the three *_then_resume_mongo cells" }
    oracle:   { test: incremental_single_to_coalesce_oracle }

  - id: incremental_adding_settle
    what: "MT2 — adding settle keeps the identity: continues"
    postgres: { test: incremental_adding_settle_postgres }
    mysql:    { test: incremental_adding_settle_mysql }
    mssql:    { test: incremental_adding_settle_mssql }
    mongo:    { na: "a Mongo export accepts only mode: full or cdc (validate_non_sql_source_modes, src/config/mod.rs:543-554), so there is no incremental / chunked mode to switch from or into; the switch Mongo has (into page_size + resume) is graded by the three *_then_resume_mongo cells" }
    oracle:   { test: incremental_adding_settle_oracle }

  - id: legacy_keyset_state_then_other_column
    what: "MT5 — a pre-v26 keyset cursor (no identity) is attributed to the keyset run that wrote it: refused"
    postgres: { test: legacy_keyset_state_then_other_column_postgres }
    mysql:    { test: legacy_keyset_state_then_other_column_mysql }
    mssql:    { test: legacy_keyset_state_then_other_column_mssql }
    mongo:    { na: "a Mongo export accepts only mode: full or cdc (validate_non_sql_source_modes, src/config/mod.rs:543-554), so there is no incremental / chunked mode to switch from or into; the switch Mongo has (into page_size + resume) is graded by the three *_then_resume_mongo cells" }
    oracle:   { test: legacy_keyset_state_then_other_column_oracle }

  - id: legacy_incremental_state_then_other_column
    what: "MT6 — a pre-v26 incremental cursor is attributed to the column the run's key descriptor (export_metrics.key_descriptor_json, v18+) names: refused; a row older than v18 records no identity anywhere — reset when changing the cursor"
    postgres: { test: legacy_incremental_state_then_other_column_postgres }
    mysql:    { test: legacy_incremental_state_then_other_column_mysql }
    mssql:    { test: legacy_incremental_state_then_other_column_mssql }
    mongo:    { na: "a Mongo export accepts only mode: full or cdc (validate_non_sql_source_modes, src/config/mod.rs:543-554), so there is no incremental / chunked mode to switch from or into; the switch Mongo has (into page_size + resume) is graded by the three *_then_resume_mongo cells" }
    oracle:   { test: legacy_incremental_state_then_other_column_oracle }

  - id: resumed_parallel_keyset_then_incremental
    what: "P-22 — a parallel keyset run resumed after a crash records the run's highest key: incremental on the key delivers nothing again"
    postgres: { test: resumed_parallel_keyset_then_incremental_postgres }
    mysql:    { test: resumed_parallel_keyset_then_incremental_mysql }
    mssql:    { test: resumed_parallel_keyset_then_incremental_mssql }
    mongo:    { na: "a Mongo export accepts only mode: full or cdc (validate_non_sql_source_modes, src/config/mod.rs:543-554), so there is no incremental / chunked mode to switch from or into; the switch Mongo has (into page_size + resume) is graded by the three *_then_resume_mongo cells" }
    oracle:   { test: resumed_parallel_keyset_then_incremental_oracle }

  - id: incremental_source_url_respelled
    what: "P-18 — the same source spelled without its default port keeps its cursor: continues (the stored source key always names the port)"
    postgres: { test: source_url_without_its_default_port_continues_postgres }
    mysql:    { test: source_url_without_its_default_port_continues_mysql }
    mssql:    { test: source_url_without_its_default_port_continues_mssql }
    mongo:    { na: "a Mongo export accepts only mode: full or cdc (validate_non_sql_source_modes, src/config/mod.rs:543-554), so there is no incremental / chunked mode to switch from or into; the switch Mongo has (into page_size + resume) is graded by the three *_then_resume_mongo cells" }
    oracle:   { test: source_url_without_its_default_port_continues_oracle }

  - id: incremental_query_filter_edited
    what: "MT8 — an edited `query:` filter under the same FROM is another stream: refused twice (RIVET_STATE_CURSOR_STREAM_MISMATCH); the filter restored continues, `state reset` delivers the new filter's rows in full, `state accept` keeps the cursor (the new filter's rows above it only, journaled, and the run after it continues), another destination is refused again"
    postgres: { test: incremental_query_filter_edited_postgres }
    mysql:    { test: incremental_query_filter_edited_mysql }
    mssql:    { test: incremental_query_filter_edited_mssql }
    mongo:    { na: "a Mongo export accepts only mode: full or cdc (validate_non_sql_source_modes, src/config/mod.rs:543-554), so there is no incremental / chunked mode to switch from or into; the switch Mongo has (into page_size + resume) is graded by the three *_then_resume_mongo cells" }
    oracle:   { test: incremental_query_filter_edited_oracle }

  - id: incremental_query_filter_edited_refusal
    what: "MT8 — the edited-filter refusal alone, twice, nothing written; no remedy is walked, so a Postgres-state run grades it in full"
    postgres: { test: incremental_query_filter_edited_is_refused_twice_postgres }
    mysql:    { test: incremental_query_filter_edited_is_refused_twice_mysql }
    mssql:    { test: incremental_query_filter_edited_is_refused_twice_mssql }
    mongo:    { na: "a Mongo export accepts only mode: full or cdc (validate_non_sql_source_modes, src/config/mod.rs:543-554), so there is no incremental / chunked mode to switch from or into; the switch Mongo has (into page_size + resume) is graded by the three *_then_resume_mongo cells" }
    oracle:   { test: incremental_query_filter_edited_is_refused_twice_oracle }

  - id: incremental_query_cosmetic_edit_accepted
    what: "MT8 — a cosmetic edit of the text after FROM (an alias renamed, two predicates swapped) is refused twice like any other edit; `rivet state accept` keeps the cursor, the acceptance is in the journal, and the next two runs continue from it"
    postgres: { test: incremental_query_cosmetic_edit_is_refused_until_accepted_postgres }
    mysql:    { test: incremental_query_cosmetic_edit_is_refused_until_accepted_mysql }
    mssql:    { test: incremental_query_cosmetic_edit_is_refused_until_accepted_mssql }
    mongo:    { na: "a Mongo export accepts only mode: full or cdc (validate_non_sql_source_modes, src/config/mod.rs:543-554), so there is no incremental / chunked mode to switch from or into; the switch Mongo has (into page_size + resume) is graded by the three *_then_resume_mongo cells" }
    oracle:   { test: incremental_query_cosmetic_edit_is_refused_until_accepted_oracle }

  - id: incremental_query_param_value_changes
    what: "MT8 — a `${param}` in the filter whose value changes between runs (by --param, then by the environment) is the same stream: the run continues from the stored cursor with no refusal and no new WARN line; an edit of the query text around the placeholder is refused twice"
    postgres: { test: incremental_query_param_value_changes_between_runs_postgres }
    mysql:    { test: incremental_query_param_value_changes_between_runs_mysql }
    mssql:    { test: incremental_query_param_value_changes_between_runs_mssql }
    mongo:    { na: "a Mongo export accepts only mode: full or cdc (validate_non_sql_source_modes, src/config/mod.rs:543-554), so there is no incremental / chunked mode to switch from or into; the switch Mongo has (into page_size + resume) is graded by the three *_then_resume_mongo cells" }
    oracle:   { test: incremental_query_param_value_changes_between_runs_oracle }

  - id: incremental_other_schema_same_table_refusal
    what: "MT8 — the other-schema refusal alone, twice, nothing written; no remedy is walked, so a Postgres-state run grades it in full"
    postgres: { test: same_table_in_another_schema_is_refused_twice_postgres }
    mysql:    { na: "the schema an unqualified table resolves in is not a source-URL option on this engine (search_path is PostgreSQL's)" }
    mssql:    { na: "the schema an unqualified table resolves in is not a source-URL option on this engine (search_path is PostgreSQL's)" }
    mongo:    { na: "a Mongo export accepts only mode: full or cdc (validate_non_sql_source_modes, src/config/mod.rs:543-554), so there is no incremental / chunked mode to switch from or into; the switch Mongo has (into page_size + resume) is graded by the three *_then_resume_mongo cells" }
    oracle:   { na: "the schema an unqualified table resolves in is not a source-URL option on this engine (search_path is PostgreSQL's)" }

  - id: incremental_other_schema_same_table
    what: "MT8 — the same table name in another schema (search_path in the URL) is another stream: refused twice (RIVET_STATE_CURSOR_STREAM_MISMATCH); the source restored continues, `state reset` delivers the other schema's rows in full, `state accept` keeps the cursor (the other schema's rows above it only), another destination is refused again"
    postgres: { test: same_table_in_another_schema_is_another_stream_postgres }
    mysql:    { na: "the schema an unqualified table resolves in is not a source-URL option on this engine (search_path is PostgreSQL's)" }
    mssql:    { na: "the schema an unqualified table resolves in is not a source-URL option on this engine (search_path is PostgreSQL's)" }
    mongo:    { na: "a Mongo export accepts only mode: full or cdc (validate_non_sql_source_modes, src/config/mod.rs:543-554), so there is no incremental / chunked mode to switch from or into; the switch Mongo has (into page_size + resume) is graded by the three *_then_resume_mongo cells" }
    oracle:   { na: "the schema an unqualified table resolves in is not a source-URL option on this engine (search_path is PostgreSQL's)" }
  # Stream identity: the stored progress names the table / collection it was read from. Each cell
  # exports table A, switches the SAME export name and state to table B without a reset, requires the
  # refusal (exit 5, RIVET_STATE_CURSOR_STREAM_MISMATCH, nothing written) TWICE, then re-reads every
  # row of B after the remedy.

  - id: incremental_repointed_at_another_table
    what: "one config repointed in place (table:): refused twice; full pass of the new table after state reset"
    postgres: { test: incremental_repointed_at_another_table_postgres }
    mysql:    { test: incremental_repointed_at_another_table_mysql }
    mssql:    { test: incremental_repointed_at_another_table_mssql }
    oracle:   { test: incremental_repointed_at_another_table_oracle }
    mongo:    { na: "a Mongo export accepts only mode: full or cdc; its stored-cursor continuation (page_size + resume) is the keyset_incremental_repointed row" }

  - id: incremental_query_repointed_at_another_table
    what: "the rivet init shape (query:): a column added to the SELECT keeps the cursor; another FROM table is refused twice"
    postgres: { test: incremental_query_repointed_at_another_table_postgres }
    mysql:    { test: incremental_query_repointed_at_another_table_mysql }
    mssql:    { test: incremental_query_repointed_at_another_table_mssql }
    oracle:   { test: incremental_query_repointed_at_another_table_oracle }
    mongo:    { na: "a Mongo export names a collection, never a query" }

  - id: keyset_incremental_repointed_at_another_table
    what: "keyset_incremental high-water (Mongo: resume) repointed in place: refused twice"
    postgres: { test: keyset_incremental_repointed_at_another_table_postgres }
    mysql:    { test: keyset_incremental_repointed_at_another_table_mysql }
    mssql:    { test: keyset_incremental_repointed_at_another_table_mssql }
    oracle:   { test: keyset_incremental_repointed_at_another_table_oracle }
    mongo:    { test: resume_repointed_at_another_collection_mongo }

  - id: parallel_keyset_incremental_repointed_at_another_table
    what: "parallel keyset_incremental anchor repointed in place: refused twice"
    postgres: { test: parallel_keyset_incremental_repointed_at_another_table_postgres }
    mysql:    { test: parallel_keyset_incremental_repointed_at_another_table_mysql }
    mssql:    { test: parallel_keyset_incremental_repointed_at_another_table_mssql }
    oracle:   { test: parallel_keyset_incremental_repointed_at_another_table_oracle }
    mongo:    { na: "the parallel _id-range reader records no _id (parallel_keyset_then_resume_mongo), so it has no stored progress to inherit" }

  - id: shared_name_another_table
    what: "two configs, one export name, one state database, two tables: the second is refused twice until it has its own name (separate config files on a Postgres state; on SQLite the second config takes the first one's directory, where its state file lives)"
    postgres: { test: incremental_shared_name_another_table_postgres }
    mysql:    { test: incremental_shared_name_another_table_mysql }
    mssql:    { test: incremental_shared_name_another_table_mssql }
    oracle:   { test: incremental_shared_name_another_table_oracle }
    mongo:    { test: resume_shared_name_another_collection_mongo }

  # Record kind: a stream's stored record is either a committed high-water (any mode may meet it, MT2)
  # or an interrupted run owned by the mode that opened it. Each cell crashes a checkpointed run after
  # its first unit (ids 1..=4 of 10), switches to incremental without a reset, requires the refusal
  # (exit 5, RIVET_STATE_INTERRUPTED_RUN_OWNER_MISMATCH, nothing written) TWICE, executes one of the
  # two remedies the message names, and re-reads every source id from the destination.

  - id: crashed_keyset_then_incremental_finish_the_run
    what: "MT9 — crashed keyset checkpoint run, then incremental: refused twice; the keyset settings restored finish the run, and incremental then continues from its high-water"
    postgres: { test: crashed_keyset_then_incremental_finish_the_run_postgres }
    mysql:    { test: crashed_keyset_then_incremental_finish_the_run_mysql }
    mssql:    { test: crashed_keyset_then_incremental_finish_the_run_mssql }
    oracle:   { test: crashed_keyset_then_incremental_finish_the_run_oracle }
    mongo:    { na: "a Mongo export accepts only mode: full or cdc, so there is no incremental mode to switch into" }

  - id: crashed_keyset_then_incremental_reset
    what: "MT9 — crashed keyset checkpoint run, then incremental: refused twice; `rivet state reset` abandons the run and incremental does a full pass"
    postgres: { test: crashed_keyset_then_incremental_reset_postgres }
    mysql:    { test: crashed_keyset_then_incremental_reset_mysql }
    mssql:    { test: crashed_keyset_then_incremental_reset_mssql }
    oracle:   { test: crashed_keyset_then_incremental_reset_oracle }
    mongo:    { na: "a Mongo export accepts only mode: full or cdc, so there is no incremental mode to switch into" }

  - id: crashed_range_chunk_then_incremental_finish_the_run
    what: "MT9 — crashed range-chunk checkpoint run, then incremental: refused twice; the chunk settings restored finish the run, and incremental then does its MT1 full pass"
    postgres: { test: crashed_range_chunk_then_incremental_finish_the_run_postgres }
    mysql:    { test: crashed_range_chunk_then_incremental_finish_the_run_mysql }
    mssql:    { test: crashed_range_chunk_then_incremental_finish_the_run_mssql }
    oracle:   { test: crashed_range_chunk_then_incremental_finish_the_run_oracle }
    mongo:    { na: "a Mongo export accepts only mode: full or cdc, so there is no incremental mode to switch into" }

  - id: crashed_range_chunk_then_incremental_reset
    what: "MT9 — crashed range-chunk checkpoint run, then incremental: refused twice; `rivet state reset-chunks` abandons the run and incremental does a full pass"
    postgres: { test: crashed_range_chunk_then_incremental_reset_postgres }
    mysql:    { test: crashed_range_chunk_then_incremental_reset_mysql }
    mssql:    { test: crashed_range_chunk_then_incremental_reset_mssql }
    oracle:   { test: crashed_range_chunk_then_incremental_reset_oracle }
    mongo:    { na: "a Mongo export accepts only mode: full or cdc, so there is no incremental mode to switch into" }

  # The checkpoint is part of what continues an interrupted run. Each cell crashes a checkpointed run after
  # its first unit, removes the checkpoint setting (same mode, no reset), requires the refusal (exit 5,
  # RIVET_STATE_INTERRUPTED_RUN_OWNER_MISMATCH, nothing written) TWICE, executes one of the two remedies the
  # message names, changes source rows, and re-reads ids and values from the destination: first of the run
  # without the checkpoint, then of a fresh run with the checkpoint back.

  - id: crashed_range_chunk_then_checkpoint_removed_finish_the_run
    what: "MT10 — crashed range-chunk checkpoint run, then the same mode without `chunk_checkpoint` (Mongo: without `resume`): refused twice; the checkpoint restored finishes the run; the uncheckpointed run then delivers the source as it is, and the checkpoint back on starts a fresh run"
    postgres: { test: crashed_range_chunk_then_checkpoint_removed_finish_the_run_postgres }
    mysql:    { test: crashed_range_chunk_then_checkpoint_removed_finish_the_run_mysql }
    mssql:    { test: crashed_range_chunk_then_checkpoint_removed_finish_the_run_mssql }
    oracle:   { test: crashed_range_chunk_then_checkpoint_removed_finish_the_run_oracle }
    mongo:    { na: "a Mongo export has no range chunking (mode: full or cdc only)" }

  - id: crashed_range_chunk_then_checkpoint_removed_reset
    what: "MT10 — crashed range-chunk checkpoint run, then the same mode without `chunk_checkpoint` (Mongo: without `resume`): refused twice; `rivet state reset-chunks` abandons the run; the uncheckpointed run then delivers the source as it is, and the checkpoint back on starts a fresh run"
    postgres: { test: crashed_range_chunk_then_checkpoint_removed_reset_postgres }
    mysql:    { test: crashed_range_chunk_then_checkpoint_removed_reset_mysql }
    mssql:    { test: crashed_range_chunk_then_checkpoint_removed_reset_mssql }
    oracle:   { test: crashed_range_chunk_then_checkpoint_removed_reset_oracle }
    mongo:    { na: "a Mongo export has no range chunking (mode: full or cdc only)" }

  # The same two cells over a 3-row table (chunk_size 4): the planner runs the uncheckpointed stage as one
  # pass (`export_metrics.mode = full`, asserted), and the refusal must still be the checkpoint one. Open
  # defect (2026-10-09): that single pass names `full` as the owner of its progress and is told to restore
  # the `chunked` settings it still has. Acknowledged in dev/release_oracle/known_red.py.

  - id: a_one_chunk_range_run_without_its_checkpoint_is_refused_as_its_own_mode_finish_the_run
    what: "MT10 — crashed range-chunk checkpoint run over a table that fits in one chunk, then the same mode without `chunk_checkpoint` (planned as a single pass): refused twice with the checkpoint wording; the checkpoint restored finishes the run; the single pass then delivers the source as it is, and the checkpoint back on starts a fresh run"
    postgres: { test: a_one_chunk_range_run_without_its_checkpoint_is_refused_as_its_own_mode_finish_the_run_postgres }
    mysql:    { test: a_one_chunk_range_run_without_its_checkpoint_is_refused_as_its_own_mode_finish_the_run_mysql }
    mssql:    { test: a_one_chunk_range_run_without_its_checkpoint_is_refused_as_its_own_mode_finish_the_run_mssql }
    oracle:   { test: a_one_chunk_range_run_without_its_checkpoint_is_refused_as_its_own_mode_finish_the_run_oracle }
    mongo:    { na: "a Mongo export has no range chunking (mode: full or cdc only)" }

  - id: a_one_chunk_range_run_without_its_checkpoint_is_refused_as_its_own_mode_reset
    what: "MT10 — crashed range-chunk checkpoint run over a table that fits in one chunk, then the same mode without `chunk_checkpoint` (planned as a single pass): refused twice with the checkpoint wording; `rivet state reset-chunks` abandons the run; the single pass then delivers the source as it is, and the checkpoint back on starts a fresh run"
    postgres: { test: a_one_chunk_range_run_without_its_checkpoint_is_refused_as_its_own_mode_reset_postgres }
    mysql:    { test: a_one_chunk_range_run_without_its_checkpoint_is_refused_as_its_own_mode_reset_mysql }
    mssql:    { test: a_one_chunk_range_run_without_its_checkpoint_is_refused_as_its_own_mode_reset_mssql }
    oracle:   { test: a_one_chunk_range_run_without_its_checkpoint_is_refused_as_its_own_mode_reset_oracle }
    mongo:    { na: "a Mongo export has no range chunking (mode: full or cdc only)" }

  - id: a_one_chunk_auto_keyset_run_without_its_checkpoint_is_refused_as_its_own_mode_finish_the_run
    what: "MT10 — the same over MySQL's auto-selected keyset key (no `chunk_column`, no single-integer primary key): refused twice with the checkpoint wording; the checkpoint restored finishes the run; the single pass then delivers the source as it is"
    postgres: { na: "the planner pages a unique key by keyset on its own only on MySQL (ADR-0020); elsewhere a table with no single-integer primary key and no `chunk_column` is refused" }
    mysql:    { test: a_one_chunk_auto_keyset_run_without_its_checkpoint_is_refused_as_its_own_mode_finish_the_run_mysql }
    mssql:    { na: "the planner pages a unique key by keyset on its own only on MySQL (ADR-0020); elsewhere a table with no single-integer primary key and no `chunk_column` is refused" }
    oracle:   { na: "the planner pages a unique key by keyset on its own only on MySQL (ADR-0020); elsewhere a table with no single-integer primary key and no `chunk_column` is refused" }
    mongo:    { na: "a Mongo export has no `mode: chunked`" }

  - id: a_one_chunk_auto_keyset_run_without_its_checkpoint_is_refused_as_its_own_mode_reset
    what: "MT10 — the same over MySQL's auto-selected keyset key (no `chunk_column`, no single-integer primary key): refused twice with the checkpoint wording; `rivet state reset` abandons the run; the single pass then delivers the source as it is"
    postgres: { na: "the planner pages a unique key by keyset on its own only on MySQL (ADR-0020); elsewhere a table with no single-integer primary key and no `chunk_column` is refused" }
    mysql:    { test: a_one_chunk_auto_keyset_run_without_its_checkpoint_is_refused_as_its_own_mode_reset_mysql }
    mssql:    { na: "the planner pages a unique key by keyset on its own only on MySQL (ADR-0020); elsewhere a table with no single-integer primary key and no `chunk_column` is refused" }
    oracle:   { na: "the planner pages a unique key by keyset on its own only on MySQL (ADR-0020); elsewhere a table with no single-integer primary key and no `chunk_column` is refused" }
    mongo:    { na: "a Mongo export has no `mode: chunked`" }

  - id: crashed_keyset_then_checkpoint_removed_finish_the_run
    what: "MT10 — crashed keyset checkpoint run, then the same mode without `chunk_checkpoint` (Mongo: without `resume`): refused twice; the checkpoint restored finishes the run; the uncheckpointed run then delivers the source as it is, and the checkpoint back on starts a fresh run"
    postgres: { test: crashed_keyset_then_checkpoint_removed_finish_the_run_postgres }
    mysql:    { test: crashed_keyset_then_checkpoint_removed_finish_the_run_mysql }
    mssql:    { test: crashed_keyset_then_checkpoint_removed_finish_the_run_mssql }
    oracle:   { test: crashed_keyset_then_checkpoint_removed_finish_the_run_oracle }
    mongo:    { test: crashed_resume_then_resume_removed_finish_the_run_mongo }

  - id: crashed_keyset_then_checkpoint_removed_reset
    what: "MT10 — crashed keyset checkpoint run, then the same mode without `chunk_checkpoint` (Mongo: without `resume`): refused twice; `rivet state reset` abandons the run; the uncheckpointed run then delivers the source as it is, and the checkpoint back on starts a fresh run"
    postgres: { test: crashed_keyset_then_checkpoint_removed_reset_postgres }
    mysql:    { test: crashed_keyset_then_checkpoint_removed_reset_mysql }
    mssql:    { test: crashed_keyset_then_checkpoint_removed_reset_mssql }
    oracle:   { test: crashed_keyset_then_checkpoint_removed_reset_oracle }
    mongo:    { test: crashed_resume_then_resume_removed_reset_mongo }

  - id: crashed_parallel_keyset_then_checkpoint_removed_finish_the_run
    what: "MT10 — crashed parallel keyset checkpoint run, then the same mode without `chunk_checkpoint` (Mongo: without `resume`): refused twice; the checkpoint restored finishes the run; the uncheckpointed run then delivers the source as it is, and the checkpoint back on starts a fresh run"
    postgres: { test: crashed_parallel_keyset_then_checkpoint_removed_finish_the_run_postgres }
    mysql:    { test: crashed_parallel_keyset_then_checkpoint_removed_finish_the_run_mysql }
    mssql:    { test: crashed_parallel_keyset_then_checkpoint_removed_finish_the_run_mssql }
    oracle:   { test: crashed_parallel_keyset_then_checkpoint_removed_finish_the_run_oracle }
    mongo:    { na: "`source.mongo.resume: true` is refused together with `parallel` (src/config/mod.rs), so a parallel Mongo reader keeps no resumable run" }

  - id: crashed_parallel_keyset_then_checkpoint_removed_reset
    what: "MT10 — crashed parallel keyset checkpoint run, then the same mode without `chunk_checkpoint` (Mongo: without `resume`): refused twice; `rivet state reset` abandons the run; the uncheckpointed run then delivers the source as it is, and the checkpoint back on starts a fresh run"
    postgres: { test: crashed_parallel_keyset_then_checkpoint_removed_reset_postgres }
    mysql:    { test: crashed_parallel_keyset_then_checkpoint_removed_reset_mysql }
    mssql:    { test: crashed_parallel_keyset_then_checkpoint_removed_reset_mssql }
    oracle:   { test: crashed_parallel_keyset_then_checkpoint_removed_reset_oracle }
    mongo:    { na: "`source.mongo.resume: true` is refused together with `parallel` (src/config/mod.rs), so a parallel Mongo reader keeps no resumable run" }

  # A range-chunk run belongs to its source: config A crashes after chunk 0; config B (same export name,
  # table name and chunk settings, ANOTHER database on the same server) delivers all 30 of its own ids,
  # twice; A then resumes its own run and delivers its 10.

  - id: range_chunk_shared_name_another_source
    what: "two configs, one export name, one state database, two databases: neither adopts the other's interrupted chunk run"
    postgres: { test: range_chunk_shared_name_another_source_postgres }
    mysql:    { test: range_chunk_shared_name_another_source_mysql }
    mssql:    { test: range_chunk_shared_name_another_source_mssql }
    oracle:   { test: range_chunk_shared_name_another_source_oracle }
    mongo:    { na: "a Mongo export has no range chunking (mode: full or cdc only)" }
