Skip to content

Seed loader never removes rows, so switching a stack's active locale leaves the previous locale's dataset resident alongside the new one #16596

Description

@hotlong

Blocked-by: #16510

Symptom

Every seed is upsert and the loader only ever writes. Once #16510's locale axis exists, switching
a stack from one locale to another on a non-empty database loads the new locale's dataset and
leaves the previous one in place — both resident, both queryable, neither marked stale.

This is not hypothetical. It is the shape the consuming app documents today for its own
env-var-selected profiles: objectstack-ai/kpi's README tells operators that switching demo profiles
requires a fresh database file, precisely because the loader only writes. The locale axis inherits
that property unchanged.

Why the loader is the layer

The dev that built the locale axis put the reasoning plainly in its report on #16510, and it is the
part that decides this card's home rather than leaving it an open question:

the loader is the only layer that could do it, since it holds externalId and the _packageId /
_provenance keys.

An app cannot do it — it does not know which rows a previous load wrote. The loader does: the
external-id key identifies the row, and the provenance keys identify what wrote it. No other layer
holds both.

What needs deciding before this is buildable

This card is not "make the loader delete rows". It is filed to force the decision it depends on,
and whoever picks it up should expect to answer these before writing code:

  1. Is reconciliation the loader's job at all, or the operator's? A loader that deletes rows is a
    materially different contract from one that only writes, and the blast radius is data. "Document
    that switching locale needs a fresh database" is a legitimate answer, and if it is the answer this
    card closes not_planned with that reasoning recorded rather than staying open forever.
  2. If it is the loader's job, what is the scope of a removal? Rows carrying this package's
    provenance and a locale that is no longer active is the narrow reading. Anything wider reaches
    rows a human may have edited since.
  3. Opt-in or default? A default that silently deletes seeded rows on a locale switch would be a
    behaviour change for every existing stack, not just locale-scoped ones.

Not to be conflated with

#16595 — wiring config.locale at the runtime call sites so the axis is live at all. That one is
about making the feature work; this one is about what happens to what it replaces. Both are blocked
on #16510 and they are independent of each other.

Origin

Second of two follow-ups the dev on #16510 (PR #16592) asked the PM to file. Filed by the PM seat
that dispatched it. The dispatch order had named this as a genuine follow-up and explicitly told the
dev not to attempt it.

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