Skip to content

Engine fallback autonumber: counter seeds once and never resyncs; collisions burn numbers with no recheck (residual split from #5495) #6806

Description

@claude

Split out of #5495 as its 2026-08-07 12:16Z lane disposition requested (the triage seat files the residual back to engine-core; #5495 itself re-anchored to domain:drivers where the observed storm actually ran).

The residual, on the engine fallback path

packages/objectql/src/engine.ts, applyAutonumbers — the path serving only drivers that do NOT declare supports.autonumber (if (driverOwnsAutonumber) return; guard verified on origin/main @ 9b86cf6). Verified at the same ref, post-#6249:

  1. Seeding runs once per counter key and never resyncs. applyAutonumbers seeds via if (next == null) next = await this.seedAutonumber(...) keyed on object.field.scope (engine.ts, counterKey block at ~:2380-2384), then increments purely in memory. Rows inserted by an exempt writer (isSystem seed replay, preserveAudit import, hook-stamped values) after the seed never lift the counter — the same warm-DB shape Autonumber counter neither syncs to MAX(existing) per tenant nor re-checks on collision — warm-DB creates 409 in bursts, each failure burning a number (25 retries observed) #5495 measured on the SQL side (PROBE1 in its thread, measured 2026-08-07).
  2. No collision recheck. There is no unique-violation handling anywhere in the fallback path: a collision surfaces as the driver's raw error to the caller, and the in-memory counter has already advanced — each failed create burns a number (PROBE3 in Autonumber counter neither syncs to MAX(existing) per tenant nor re-checks on collision — warm-DB creates 409 in bursts, each failure burning a number (25 retries observed) #5495's thread).

#6249 (closed completed) fixed only the seeding scan (5000-row cap became a paging walk); it did not touch resync-after-seed or collision semantics — both residual holes are live at the current ref.

Scope (per the parked ruling in #5495's thread — do not relitigate)

Blast radius (why pm:queue without target:v17)

The fallback path serves exactly two in-repo drivers: driver-memory (no uniqueness constraints — collisions cannot fail, only silent duplicates in the rendered field) and driver-mongodb (single-tenant by #3724, global unique index — warm-DB storms possible but the family is under the maintainer's 2026-08-05 investment freeze). Not the four-class release-blocker shape; the shipped SQL-side storm is #5495's half and keeps its target:v17.

Hard acceptance conditions carried over from #5495's disposition, verbatim in intent: read-failures during seeding must keep #6114's isMissingTableError type discrimination (never swallow a read failure into 0/stale — #5979 family regression line); and any retry predicate goes through #6250's surface.

Refs: #5495 (parent thread, PROBE measurements), #6249 (scan fix, closed), #6250 (conflict predicate surface), #6114 (outage semantics), #6555 (render-shape divergence on the same two paths — independent, domain:spec).


Generated by Claude Code

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions