Relationships
#3696 v3 join check refuses a fresh managedConfig checkout on S3/GCS: the datastore extension's auto-install writes the managed lockfile first (regression of #3690)
Opened by stack72 · 10/21/2026· Shipped 10/21/2026
Background
swamp-club#3690 (2d4b4e970, release 20261021.000812.0) added a join check: the first time a checkout opens a v3 datastore (no _read_model_v3 state yet), swamp refuses if the checkout's .swamp/ already holds records, because a v3 datastore starts empty. It runs in resolveDatastoreForRepo after the format guard, and in holdV3Writer and v3RepositoryFactoryConfig. Files a checkout keeps as its own are skipped (isCheckoutLocalKey in src/infrastructure/datastore_v3/record_path_guard.ts).
The bug (regression of #3690)
A fresh checkout of a managedConfig repo on an S3 or GCS v3 datastore is refused on its very first command. No user data is involved. The check counts a file swamp itself has just written.
Seen in swamp-uat: every Datastore UAT run since 20261021.000812.0-sha.2d4b4e97 fails all eight s3-v3 and gcs-v3 shards, 64 failures, for example run 39522050355 on 20261021.003131.0-sha.764fd4d5. The last green run was 20261020.231557.0-sha.bc7bbaa6. The filesystem, filesystem-v3, s3 and gcs shards stay green. Every failure is a managedConfig row (withClonePair managedConfig, every_mutation_syncs … [managed-config], managed_config_test), with:
Command "swamp datastore status" failed (exit 1):
Error: /tmp/swamp-uat-…/.swamp holds records (config), but .swamp.yaml now names a v3 datastore. A v3 datastore starts empty … Run `swamp doctor datastores --repair` …
Resolving @swamp/s3-datastore not found locally, searching registry...
Installing @swamp/s3-datastore@2026.10.20.2 …Why:
- In a fresh checkout the datastore extension isn't installed, so
resolveDatastoreForRepoauto-installs it from the registry before the join check runs. - With managedConfig, that install writes the managed lockfile
.swamp/config/upstream_extensions.json(paths.ts"Returns the .swamp/config/upstream_extensions.json path"). isCheckoutLocalKeyskipsconfig/pulled-extensions/…but not the lockfile, so the join check countsconfigas holding records and refuses.filesystem-v3doesn't auto-install anything, so it isn't hit. #3690's own bucket test registers the extension directly, so it never ran the auto-install.
Impact: every teammate joining a managedConfig repo on S3/GCS v3 is refused on their first command. Following the suggested doctor datastores --repair -y moves swamp's freshly installed lockfile aside for nothing, and the next command re-installs it and is refused again.
What to do
- Run the join check before anything swamp writes on that command, which means before the datastore extension's auto-install in
resolveDatastoreForRepo. The check needs only.swamp.yaml's format and namespace and the local.swamp/; it doesn't need the provider. Keep the later calls inholdV3Writerandv3RepositoryFactoryConfigas they are. - Count the managed lockfile (
config/upstream_extensions.json) as the checkout's own inisCheckoutLocalKey(or in the join check's own-file rule). swamp regenerates it, and on v3 the datastore holds its committed copy. That keeps any other early write of it from tripping the check. Check whether anything else swamp writes under.swamp/config/before the first open needs the same: the extension install's other files, the managed config's local index. - Leave genuine records refused. A checkout holding v2 definitions, workflows, vault configs or data is still refused, as #3690 intends.
Tests
Each must fail on main first.
- Integration: a fresh managedConfig checkout of a bucket v3 datastore, on the in-memory remote or the opt-in S3 run, with the datastore extension auto-installed rather than pre-registered. Its first command (
datastore status, then a write) succeeds, and its v3 state is created. - Unit:
isCheckoutLocalKey(["config", "upstream_extensions.json"])is true. Aconfig/file that is a real record (a definition or vault config under the managed config tier) is still counted. - The #3690 refusal still holds: a checkout with v2 records is refused, managedConfig or not.
- swamp-uat: the
s3-v3/gcs-v3Datastore UAT shards pass unchanged against a build of the fix.
Severity: high. A regression in a published release that blocks every new checkout of a managedConfig repo on v3 buckets. v3 is opt-in, so fix it promptly rather than as an emergency.
Blocked by: nothing.
Shipped
Click a lifecycle step above to view its details.
Sign in to post a ripple.