Skip to content

Native: reuse the claimed run's last history sequence for its first history page #1066

Closed

Description

@rmcdaniel

Delivered — Native Server3.3.0 (2026-11-08)

Implemented by #1093; qualified and published at release source 2a15179f29801eec9f2a2d4e6a9c5f93233f104e / indexcb4b11bd. Acceptance and scope limits. No benchmark speedup is claimed.

Original requirement and evidence

External performance report, topic 15. The reported timings and proposed fixes have not been independently reproduced. The supplied patches are reference drafts for review and current-source qualification.

Problem

A workflow claim reads the run under the transition lock. The first
history page then reads last_history_sequence again, though nothing in
between wrote that run's history.

Proposal

The first page reuses the claim's last_history_sequence.

Reported benchmark evidence

Reporter-supplied cumulative measurements, not an isolated-effect or independently verified performance claim: 200 sequentially started workflows, five sequential 20ms activities or five local activities each, six PHP worker processes, mean of three repetitions, one machine, fresh SQLite/MySQL8.0/PostgreSQL16 databases with default durability. "Five" and "local" below mean last-close wall time in seconds; S/M/P means SQLite/MySQL/PostgreSQL. Preserve regressions and noise in the reported results.

MySQL five-steps: 15.82 → 15.37. The full matrix at this stage: five
11.04 / 15.37 / 16.17, local 4.29 / 4.34 / 4.34.

Acceptance

  • Same pages.
  • A debug assertion checks that the run's sequence is unchanged
    between the claim's read and the page, so a later change that breaks the
    invariant fails in tests.

Implementation constraints

It rests on one invariant, which the assertion guards.

Dependencies

No new producer dependency is required for source investigation.

Related existing work: #325.

Draft patches and validation boundary

Current main was independently read as b8f4dd13623ce645de77ba5bd89ae8dd8eea2f7c. The supplied draft series targets 3d4d4afaf2b24aaa5443eac154e253b011924738; patches are cumulative reference material, not a current-main application or test result. Review and rebase on maintained source, preserve all existing tests and published compatibility, then establish causal controls and actual conformance before shipping. No patch was applied or executed during intake.

The following sanitized unified diffs identify proposed reference material:

  • 0024-t15-Reuse-the-claimed-run-s-last-history-sequence-for-it.patch — 4,066 bytes, SHA-256 06c1d6d23ce7fc7392e72ac38077fa277aef4d4f3984a002868c38d91cf074e3.

Next action: the owning maintainer reviews the candidate against current source and the acceptance criteria above. Preserve durability, lease/fencing, idempotency, fairness and whole-completion/history budgets. New producer capabilities need versioned schemas and real producer/consumer compatibility proof; historical/frozen evidence is not rewritten.

Activity

  1. added
    kind:featureA public product capability or experience is requested
    priority:P0Immediate release or data-integrity risk
    repo:serverOwned by the standalone server repository
    on Nov 6, 2026
  2. rmcdaniel commented on Nov 6, 2026

    @rmcdaniel
    MemberAuthor

    Sanitized reference diff 0024-t15-Reuse-the-claimed-run-s-last-history-sequence-for-it.patch, part 1/1.

    This is an unverified, cumulative draft from the external report. Mail author/date/commit-message metadata was removed; the unified-diff hunks were retained. No patch was applied or executed, and no build/test or compatibility result is implied. The known gaps and acceptance criteria in this issue remain mandatory.

    Complete sanitized patch: 4,066 bytes, SHA-256 06c1d6d23ce7fc7392e72ac38077fa277aef4d4f3984a002868c38d91cf074e3. This part: 4,066 bytes, SHA-256 06c1d6d23ce7fc7392e72ac38077fa277aef4d4f3984a002868c38d91cf074e3. Parts concatenate in order; a part boundary is between complete file diffs.

    diff --git a/rust/src/runtime/store.rs b/rust/src/runtime/store.rs
    index 3ccf5ff3..a416da1c 100644
    --- a/rust/src/runtime/store.rs
    +++ b/rust/src/runtime/store.rs
    @@ -2704,17 +2704,15 @@ where
                             }
                         }
                     }
    +                // The run was read in this transaction, which holds the
    +                // transition lock, and nothing since has written its history.
    +                let last_sequence = DB::number(&run, "last_history_sequence")?;
                     let (mut events, next) = match page {
    -                    Some(size) => Self::history_page_connection(&mut **tx, &run_id, 0, size).await?,
    -                    None => (Self::whole_history(&mut **tx, &run_id).await?, None),
    +                    Some(size) => Self::history_page_known(&mut **tx, &run_id, 0, size, Some(last_sequence)).await?,
    +                    None => (Self::whole_history(&mut **tx, &run_id, last_sequence).await?, None),
                     };
                     Self::with_signal_sequences(&mut **tx, &run_id, &mut events).await?;
    -                let budget = Self::workflow_history_budget(
    -                    tx,
    -                    &run_id,
    -                    DB::number(&run, "last_history_sequence")?,
    -                )
    -                .await?;
    +                let budget = Self::workflow_history_budget(tx, &run_id, last_sequence).await?;
                     budget.write_task(&mut claim);
                     claim["history_events"] = json!(events);
                     claim["next_history_page_token"] = json!(next);
    @@ -5098,11 +5096,12 @@ where
             Ok(())
         }
     
    -    async fn whole_history(connection: &mut DB::Connection, run_id: &str) -> Result<Vec<Value>> {
    +    /// A run's whole history, whose last sequence is `last_sequence`.
    +    async fn whole_history(connection: &mut DB::Connection, run_id: &str, last_sequence: i64) -> Result<Vec<Value>> {
             let mut events = Vec::new();
             let mut after = 0;
             loop {
    -            let (page, next) = Self::history_page_connection(&mut *connection, run_id, after, 1000).await?;
    +            let (page, next) = Self::history_page_known(&mut *connection, run_id, after, 1000, Some(last_sequence)).await?;
                 if let Some(last) = page.last() {
                     after = last["sequence"].as_i64().unwrap_or(after);
                 }
    @@ -5118,6 +5117,19 @@ where
             run_id: &str,
             after_sequence: i64,
             page_size: i64,
    +    ) -> Result<(Vec<Value>, Option<String>)> {
    +        Self::history_page_known(connection, run_id, after_sequence, page_size, None).await
    +    }
    +
    +    /// `history_page_connection` for a caller that has read the run's
    +    /// `last_history_sequence` in this transaction, or `None` to read it
    +    /// after the page.
    +    async fn history_page_known(
    +        connection: &mut DB::Connection,
    +        run_id: &str,
    +        after_sequence: i64,
    +        page_size: i64,
    +        last_sequence: Option<i64>,
         ) -> Result<(Vec<Value>, Option<String>)> {
             use base64::{Engine, engine::general_purpose::STANDARD};
             // Bound serialized history bytes before hydrating JSON. SQLite executes
    @@ -5128,11 +5140,16 @@ where
                 .bind(page_size)
                 .fetch_all(&mut *connection)
                 .await?;
    -        let row = Self::query("SELECT last_history_sequence FROM workflow_runs WHERE id=$1")
    -            .bind(run_id)
    -            .fetch_one(connection)
    -            .await?;
    -        let total = DB::number(&row, "last_history_sequence")?;
    +        let total = match last_sequence {
    +            Some(total) => total,
    +            None => {
    +                let row = Self::query("SELECT last_history_sequence FROM workflow_runs WHERE id=$1")
    +                    .bind(run_id)
    +                    .fetch_one(connection)
    +                    .await?;
    +                DB::number(&row, "last_history_sequence")?
    +            }
    +        };
             let last = match rows.last() {
                 Some(row) => DB::number(row, "sequence")?,
                 None => after_sequence,
  3. rmcdaniel commented on Nov 6, 2026

    @rmcdaniel
    MemberAuthor

    Sanitized rebased reference for report topic 15: 0024-t15-Reuse-the-claimed-run-s-last-history-sequence-for-it.patch.

    The supplied revision targets Server b8f4dd13623ce645de77ba5bd89ae8dd8eea2f7c. It is cumulative external reference material, not independently qualified against today's maintained source. Mail headers and commit-message/application instructions were removed; the unified diff is retained. The reporter now claims every rebased commit builds and the tip passes SQLite/MySQL/PostgreSQL tests. Those are attributed claims, not a new maintainer test result. Existing acceptance criteria, security findings and completed implementation receipts remain authoritative. Earlier attached patches are retained as historical references.

    Sanitized patch: 4,066 bytes, SHA-256 63e5ab2031ef626e77531144cd488a4a720af20dc5965d396fcbb61b64ff61ad. Original-base sanitized identity: 06c1d6d23ce7fc7392e72ac38077fa277aef4d4f3984a002868c38d91cf074e3. No patch was applied or executed during this update.

    diff --git a/rust/src/runtime/store.rs b/rust/src/runtime/store.rs
    index 495695d3..54fc7896 100644
    --- a/rust/src/runtime/store.rs
    +++ b/rust/src/runtime/store.rs
    @@ -2717,17 +2717,15 @@ where
                             }
                         }
                     }
    +                // The run was read in this transaction, which holds the
    +                // transition lock, and nothing since has written its history.
    +                let last_sequence = DB::number(&run, "last_history_sequence")?;
                     let (mut events, next) = match page {
    -                    Some(size) => Self::history_page_connection(&mut **tx, &run_id, 0, size).await?,
    -                    None => (Self::whole_history(&mut **tx, &run_id).await?, None),
    +                    Some(size) => Self::history_page_known(&mut **tx, &run_id, 0, size, Some(last_sequence)).await?,
    +                    None => (Self::whole_history(&mut **tx, &run_id, last_sequence).await?, None),
                     };
                     Self::with_signal_sequences(&mut **tx, &run_id, &mut events).await?;
    -                let budget = Self::workflow_history_budget(
    -                    tx,
    -                    &run_id,
    -                    DB::number(&run, "last_history_sequence")?,
    -                )
    -                .await?;
    +                let budget = Self::workflow_history_budget(tx, &run_id, last_sequence).await?;
                     budget.write_task(&mut claim);
                     claim["history_events"] = json!(events);
                     claim["next_history_page_token"] = json!(next);
    @@ -5112,11 +5110,12 @@ where
             Ok(())
         }
     
    -    async fn whole_history(connection: &mut DB::Connection, run_id: &str) -> Result<Vec<Value>> {
    +    /// A run's whole history, whose last sequence is `last_sequence`.
    +    async fn whole_history(connection: &mut DB::Connection, run_id: &str, last_sequence: i64) -> Result<Vec<Value>> {
             let mut events = Vec::new();
             let mut after = 0;
             loop {
    -            let (page, next) = Self::history_page_connection(&mut *connection, run_id, after, 1000).await?;
    +            let (page, next) = Self::history_page_known(&mut *connection, run_id, after, 1000, Some(last_sequence)).await?;
                 if let Some(last) = page.last() {
                     after = last["sequence"].as_i64().unwrap_or(after);
                 }
    @@ -5132,6 +5131,19 @@ where
             run_id: &str,
             after_sequence: i64,
             page_size: i64,
    +    ) -> Result<(Vec<Value>, Option<String>)> {
    +        Self::history_page_known(connection, run_id, after_sequence, page_size, None).await
    +    }
    +
    +    /// `history_page_connection` for a caller that has read the run's
    +    /// `last_history_sequence` in this transaction, or `None` to read it
    +    /// after the page.
    +    async fn history_page_known(
    +        connection: &mut DB::Connection,
    +        run_id: &str,
    +        after_sequence: i64,
    +        page_size: i64,
    +        last_sequence: Option<i64>,
         ) -> Result<(Vec<Value>, Option<String>)> {
             use base64::{Engine, engine::general_purpose::STANDARD};
             // Bound serialized history bytes before hydrating JSON. SQLite executes
    @@ -5142,11 +5154,16 @@ where
                 .bind(page_size)
                 .fetch_all(&mut *connection)
                 .await?;
    -        let row = Self::query("SELECT last_history_sequence FROM workflow_runs WHERE id=$1")
    -            .bind(run_id)
    -            .fetch_one(connection)
    -            .await?;
    -        let total = DB::number(&row, "last_history_sequence")?;
    +        let total = match last_sequence {
    +            Some(total) => total,
    +            None => {
    +                let row = Self::query("SELECT last_history_sequence FROM workflow_runs WHERE id=$1")
    +                    .bind(run_id)
    +                    .fetch_one(connection)
    +                    .await?;
    +                DB::number(&row, "last_history_sequence")?
    +            }
    +        };
             let last = match rows.last() {
                 Some(row) => DB::number(row, "sequence")?,
                 None => after_sequence,
  4. rmcdaniel commented on Nov 7, 2026

    @rmcdaniel
    MemberAuthor

    The independent history-total implementation is prepared as 0457f986e14b4749ad2fd816fb9f13393e8b1042, tree b4c5a7a310a7c8025be43d4439aaad3bd5c8cc7c, from accepted main dc2a9d1050e9ebb15b6a1ffaf2dce667b292bd7d. Full own-authored delta below; it has no public branch or overlapping CI train. It remains behind #1064 in the active P0 order and does not inherit the earlier combined #1088 results.

    The first history page reuses the run row already read by the claim. Subsequent pages and callers without a known total retain the original lookup. Debug builds independently reread the counter and assert equality. Shared SQLite/PostgreSQL/MySQL controls compare pages/cursors and statement counts, and deliberately append an intervening event to prove the assertion fires. These controls are not yet executed on this isolated current head; normal repository/backend qualification remains required.

    The printed Some(5) versus Some(4) assertion in the earlier #1088 PostgreSQL logs is the intentional caught negative control. For example, the retained ffd PG17 final summary names only qualification_candidates_keep_index_order_without_run_scans as failed (32 passed / one failure). The guard is preserved, not waived; that clarification is not a pass for this new isolated head.

    Full diff SHA-256 b5b1310643d55c363ebc120c8b0e1447bddc3265af79262d42f06cacb50d7495, 8908 bytes. Server retains normal PR/check/integration and later published-artifact ownership after its source slot opens. No new backend, installed or benchmark run is claimed.

    diff --git a/rust/src/runtime/mysql.rs b/rust/src/runtime/mysql.rs
    index dfd5cda6..6f1f8f81 100644
    --- a/rust/src/runtime/mysql.rs
    +++ b/rust/src/runtime/mysql.rs
    @@ -1224,6 +1224,7 @@ mod tests {
             let db = Database::new().await;
             let store = super::super::store::Store::new(MySqlStorage::open(db.options.clone()).await.unwrap().into_pool());
             store.qualify_workflow_poll_transactions().await;
    +        store.qualify_claim_history_sequence().await;
             store.qualify_query_poll_transactions().await;
             store.close().await;
             db.remove().await;
    diff --git a/rust/src/runtime/poll_transaction_tests.rs b/rust/src/runtime/poll_transaction_tests.rs
    index 7e0ea138..c0288087 100644
    --- a/rust/src/runtime/poll_transaction_tests.rs
    +++ b/rust/src/runtime/poll_transaction_tests.rs
    @@ -4,6 +4,8 @@ use crate::codec::{Value as Payload, ValueCodec};
     use serde_json::{Value, json};
     use std::{collections::BTreeMap, sync::{Arc, atomic::Ordering}, time::Duration};
     use tokio::sync::Semaphore;
    +#[cfg(debug_assertions)]
    +use futures_util::FutureExt;
     
     fn input() -> Value {
         json!({"codec":"avro","blob":ValueCodec::new().unwrap().encode(&Payload::Array(vec![])).unwrap()})
    @@ -134,6 +136,47 @@ store_methods! {
             }
         }
     
    +    pub(super) async fn qualify_claim_history_sequence(&self) {
    +        let started = self.count_start("claimed-history-total").await;
    +        let run_id = started["run_id"].as_str().unwrap();
    +        let mut tx = self.begin().await.unwrap();
    +        for sequence in 1..=2 {
    +            Self::append(&mut tx,run_id,"SideEffectRecorded",json!({"sequence":sequence,"result":null}),None,None)
    +                .await.unwrap();
    +        }
    +        let run = Self::query("SELECT last_history_sequence FROM workflow_runs WHERE id=$1")
    +            .bind(run_id).fetch_one(&mut *tx).await.unwrap();
    +        let last = DB::number(&run,"last_history_sequence").unwrap();
    +        assert_eq!(last,4);
    +        for (after,size) in [(0,1),(1,2),(0,1000),(last,1)] {
    +            let (reference, reference_count) = super::sql_counts::measure(
    +                Self::history_page_connection(&mut *tx,run_id,after,size),
    +            ).await;
    +            let (known, known_count) = super::sql_counts::measure(
    +                Self::history_page_connection_with_total(&mut *tx,run_id,after,size,Some(last)),
    +            ).await;
    +            assert_eq!(known.unwrap(),reference.unwrap(),"after={after}, size={size}");
    +            let query = "SELECT last_history_sequence FROM workflow_runs WHERE id=$1";
    +            assert_eq!(reference_count.count(query),1);
    +            assert_eq!(known_count.count(query),usize::from(cfg!(debug_assertions)),
    +                "only debug builds re-read the claimed history total");
    +        }
    +        #[cfg(debug_assertions)]
    +        {
    +            Self::append(&mut tx,run_id,"SideEffectRecorded",json!({"sequence":3,"result":null}),None,None)
    +                .await.unwrap();
    +            let refused = std::panic::AssertUnwindSafe(
    +                Self::history_page_connection_with_total(&mut *tx,run_id,0,1,Some(last)),
    +            ).catch_unwind().await.expect_err("an intervening history write must trip the debug assertion");
    +            let message = refused.downcast_ref::<String>().map(String::as_str)
    +                .or_else(|| refused.downcast_ref::<&str>().copied()).unwrap_or("");
    +            assert!(message.contains("claimed run history sequence changed before its first page"),"{message}");
    +        }
    +        tx.rollback().await.unwrap();
    +        Self::query("UPDATE workflow_tasks SET status='completed' WHERE workflow_run_id=$1")
    +            .bind(run_id).execute(&self.pool).await.unwrap();
    +    }
    +
         pub(super) async fn qualify_query_poll_transactions(&self) {
             self.count_worker().await;
             let workflow_id = "counted-query-workflow";
    @@ -199,6 +242,7 @@ async fn sqlite_workflow_and_query_poll_transaction_counts() {
         let dir = tempfile::tempdir().unwrap();
         let store = Store::<sqlx::Sqlite>::new(super::sqlite::open(dir.path().join("counts.sqlite").to_str().unwrap()).await.unwrap());
         store.qualify_workflow_poll_transactions().await;
    +    store.qualify_claim_history_sequence().await;
         store.qualify_query_poll_transactions().await;
         store.close().await;
     }
    diff --git a/rust/src/runtime/postgres.rs b/rust/src/runtime/postgres.rs
    index ffecee93..777e0982 100644
    --- a/rust/src/runtime/postgres.rs
    +++ b/rust/src/runtime/postgres.rs
    @@ -743,6 +743,7 @@ mod tests {
             let db = Database::new().await;
             let store = super::super::store::Store::new(PostgresStorage::open(db.options.clone()).await.unwrap().into_pool());
             store.qualify_workflow_poll_transactions().await;
    +        store.qualify_claim_history_sequence().await;
             store.qualify_query_poll_transactions().await;
             store.close().await;
             db.remove().await;
    diff --git a/rust/src/runtime/store.rs b/rust/src/runtime/store.rs
    index 27e33c23..fc4f3f72 100644
    --- a/rust/src/runtime/store.rs
    +++ b/rust/src/runtime/store.rs
    @@ -2669,15 +2669,16 @@ where
                             }
                         }
                     }
    +                let last = DB::number(&run, "last_history_sequence")?;
                     let (mut events, next) = match page {
    -                    Some(size) => Self::history_page_connection(&mut **tx, &run_id, 0, size).await?,
    -                    None => (Self::whole_history(&mut **tx, &run_id).await?, None),
    +                    Some(size) => Self::history_page_connection_with_total(&mut **tx, &run_id, 0, size, Some(last)).await?,
    +                    None => (Self::whole_history(&mut **tx, &run_id, last).await?, None),
                     };
                     Self::with_signal_sequences(&mut **tx, &run_id, &mut events).await?;
                     let budget = Self::workflow_history_budget(
                         tx,
                         &run_id,
    -                    DB::number(&run, "last_history_sequence")?,
    +                    last,
                     )
                     .await?;
                     budget.write_task(&mut claim);
    @@ -4946,11 +4947,13 @@ where
             Ok(())
         }
     
    -    async fn whole_history(connection: &mut DB::Connection, run_id: &str) -> Result<Vec<Value>> {
    +    async fn whole_history(connection: &mut DB::Connection, run_id: &str, last: i64) -> Result<Vec<Value>> {
             let mut events = Vec::new();
             let mut after = 0;
             loop {
    -            let (page, next) = Self::history_page_connection(&mut *connection, run_id, after, 1000).await?;
    +            let (page, next) = Self::history_page_connection_with_total(
    +                &mut *connection, run_id, after, 1000, (after == 0).then_some(last),
    +            ).await?;
                 if let Some(last) = page.last() {
                     after = last["sequence"].as_i64().unwrap_or(after);
                 }
    @@ -4966,6 +4969,16 @@ where
             run_id: &str,
             after_sequence: i64,
             page_size: i64,
    +    ) -> Result<(Vec<Value>, Option<String>)> {
    +        Self::history_page_connection_with_total(connection, run_id, after_sequence, page_size, None).await
    +    }
    +
    +    pub(super) async fn history_page_connection_with_total(
    +        connection: &mut DB::Connection,
    +        run_id: &str,
    +        after_sequence: i64,
    +        page_size: i64,
    +        known_total: Option<i64>,
         ) -> Result<(Vec<Value>, Option<String>)> {
             use base64::{Engine, engine::general_purpose::STANDARD};
             // Bound serialized history bytes before hydrating JSON. SQLite executes
    @@ -4976,11 +4989,20 @@ where
                 .bind(page_size)
                 .fetch_all(&mut *connection)
                 .await?;
    -        let row = Self::query("SELECT last_history_sequence FROM workflow_runs WHERE id=$1")
    -            .bind(run_id)
    -            .fetch_one(connection)
    -            .await?;
    -        let total = DB::number(&row, "last_history_sequence")?;
    +        // A workflow claim already read this run under the transition lock.
    +        // No intervening history write is allowed before its first page.
    +        let observed_total = if known_total.is_none() || cfg!(debug_assertions) {
    +            let row = Self::query("SELECT last_history_sequence FROM workflow_runs WHERE id=$1")
    +                .bind(run_id).fetch_one(connection).await?;
    +            Some(DB::number(&row, "last_history_sequence")?)
    +        } else { None };
    +        let total = match known_total {
    +            Some(total) => {
    +                debug_assert_eq!(observed_total, Some(total), "claimed run history sequence changed before its first page");
    +                total
    +            }
    +            None => observed_total.expect("an unknown history total was read"),
    +        };
             let last = match rows.last() {
                 Some(row) => DB::number(row, "sequence")?,
                 None => after_sequence,
    
  5. rmcdaniel commented on Nov 7, 2026

    @rmcdaniel
    MemberAuthor

    The preparation 0457f986 is rebased without conflict onto main 1c34f3b7 as local 3d2eac17b7bc6331113111d3736594e02e358cc0 (branch feat/server-1066-known-history-total, not pushed yet). Local SQLite checks in CI's pinned Rust image pass:

    • runtime library: 413 passed;
    • sqlite_workflow_and_query_poll_transaction_counts, including the new qualify_claim_history_sequence: page/cursor equality, statement counts, and the deliberate intervening-write debug assertion;
    • full execution suite: 738 passed, 1 existing ignore.

    PostgreSQL/MySQL coverage comes from the normal PR checks.

    Next action (Server): push and open its own draft PR once the #325 qualifier window ends. Runner, main and Source writes are frozen until then. It overlaps #1092 only in adjacent test-registration lines, so whichever PR merges second gets a trivial rebase. Owner: Server.

  6. rmcdaniel commented on Nov 8, 2026

    @rmcdaniel
    MemberAuthor

    Published-artifact reconciliation: delivered in Native Server3.3.0.

    Implementation #1093 is an ancestor of immutable release source 2a15179f29801eec9f2a2d4e6a9c5f93233f104e. Its accepted source checks are62success/1intended skip. The integrated #1098 source head 5f937ec8f385c71dc781875f2f38026b63277faa has a byte-identical rust/ tree to this release. I independently read its successful SQLite, MySQL8.0, MariaDB10.11 and PostgreSQL17 native-test job commands: they run the registered all-targets/ignored qualification suites (only the unrelated MySQL bootstrap child is skipped). This supports the specific source controls below; it is not a new benchmark run.

    All-backend page/cursor equality and statement-count controls cover the reused first-page total. The deliberate intervening history write is caught by the debug assertion; its printed panic is an intentional negative control, not a failed test.

    The 3.3.0 release is public at index sha256:cb4b11bd6235a551cf51e7dc6342504fbbcef19959618b376fb5648ca00fc388, with provenance binding M. Published SQLite corpus acceptance passed, as did four-cell MySQL Compose acceptance, the no-input default, and the release’s SQLite/PostgreSQL/MySQL startup/identity/stop smokes. Both registries’3.3/3/latest aliases resolve to D.

    The issue’s functional/source acceptance and release follow-through are met. Closing as completed. No isolated speedup, reporter benchmark reproduction, all-backend installed corpus or installed EXPLAIN rerun is claimed. Earlier rejected/combined subjects remain attributed. Remaining P0 work, including #1099, is excluded from this3.3.0 cut. Schema11 and rollback constraints remain in the tagged release notes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent:serverkind:featureA public product capability or experience is requestedpriority:P0Immediate release or data-integrity riskrepo:serverOwned by the standalone server repository

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions