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

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