Sub-scope 07 (mongo) schema + migration - execution probes
revision=a24ece9cf797f7ea647e33bf846b115208ed1ba5
generatedAt=2026-08-30T00:08:22+00:00

Two temporary probe classes were added, run, and removed:
  src/test/.../migration/Ss07FenceProbe.java        (@Tag mongodb-migration, real server)
  src/test/.../schema/Ss07SchemaProbe.java          (@Tag mongodb-contract, hermetic)
No production source was modified. git status after removal is shown at the end.

=== PROBE A: recordApplied under a stale fence (real MongoDB 8.0 replica set) ===
Scenario: the live runner holds fence 5 and has stored checkpoint o-900.
          the superseded runner still holds fence 1.

PROBE saveCheckpoint(fence=1 over stored 5) -> REFUSED MongoOperationRejectedException
PROBE recordApplied(fence=1 over stored 5)  -> ACCEPTED
PROBE ledger entry now = Document{{_id=6a937447a11d79601374fd73, migrationId=20260829-001,
        checksum=superseded, operator=stale-runner, appliedAt=Thu Jan 01 00:00:00 UTC 1970, fence=1}}
PROBE live checkpoint still = o-900
PROBE recordApplied(live fence=5, after stale wrote) -> REFUSED MongoWriteException:
        E11000 duplicate key error collection: ss07probe.mongoMigrationLedger
        index: migrationId_1 dup key: { migrationId: "20260829-001" }

Reading: saveCheckpoint honours the documented fence contract; recordApplied does not.
The superseded runner wins the ledger and the live runner receives a raw driver
duplicate-key error rather than the platform's lease sentence. This is the same shape
the codebase already fixed once inside saveCheckpoint (see its inline comment).

=== PROBE B: what the index diff cannot see (hermetic) ===
Declared: ix_ttl (expireAfter=30d), ix_active (sparse, partialFilter, collation, visible)
Observed: same names, same keys, same uniqueness; ix_active hidden on the server

PROBE diff.isClean() -> true
PROBE diff.render()  -> [] (empty)
PROBE MongoIndexManifest.expireAfter(1s) built -> PT1S isTtlIndex=true

Reading: a TTL retention change, a sparse/partialFilter/collation change and an index
hidden on the server but declared visible all render as no drift at all.

=== PROBE C: what the Flamingock lease can run (hermetic) ===
PROBE FlamingockLockAdapter.fence() = -1
PROBE runner.apply(NON-resumable migration, Flamingock lease) -> REFUSED
        MongoOperationRejectedException: this migration lease exposes no fencing token,
        so a stalled runner cannot be excluded; use a fenced lease or run the migration
        inside a maintenance window with the application stopped
        [operation=migration.fence ... category=OPERATION_REJECTED outcome=NOT_SENT]

Reading: the migration in this probe returns completed(0) and stores no checkpoint, so it
is not resumable. FlamingockLockAdapter's javadoc says the runner 'refuses resumable
migrations under an unfenced lease'; the runner refuses every migration.

=== 8.1c is the one production consumer of the manifest registry itself wired? ===
$ grep -n 'Geospatial\|geo\.' adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/autoconfigure/MongoPlatformAutoConfiguration.java
exit=1

$ git grep -n 'new SpringMongoGeospatialOperations' -- 'adapter/outbound/persistence-mongo/src/main'
exit=1

$ git grep -n 'MongoManifestRegistry\|MongoCollectionManifest' -- 'adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/geo'
adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/geo/SpringMongoGeospatialOperations.java:10:import dev.caskeleton.adapter.outbound.mongo.schema.manifest.MongoManifestRegistry;
adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/geo/SpringMongoGeospatialOperations.java:29:  private final MongoManifestRegistry manifests;
adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/geo/SpringMongoGeospatialOperations.java:32:      DefaultMongoImperativeExecutor executor, MongoManifestRegistry manifests) {
exit=0

=== 8.1d the migration package's cross-package production consumers ===
$ git grep -n 'import dev.caskeleton.adapter.outbound.mongo.migration' -- 'adapter/outbound/persistence-mongo/src/main' | grep -v '/migration/'
adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/advanced/tenancy/database/MongoTenantMigrationCheckpointStore.java:3:import dev.caskeleton.adapter.outbound.mongo.migration.MongoMigrationCheckpoint;
adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/advanced/tenancy/database/MongoTenantMigrationCoordinator.java:6:import dev.caskeleton.adapter.outbound.mongo.migration.MongoMigrationCheckpoint;
exit=0

$ grep -n 'MongoMigrationCheckpoint\|MongoMigrationLedger\|MongoMigrationLock\|MongoMigrationRunner' adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/advanced/tenancy/database/MongoTenantMigrationCoordinator.java adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/advanced/tenancy/database/MongoTenantMigrationCheckpointStore.java
adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/advanced/tenancy/database/MongoTenantMigrationCoordinator.java:6:import dev.caskeleton.adapter.outbound.mongo.migration.MongoMigrationCheckpoint;
adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/advanced/tenancy/database/MongoTenantMigrationCoordinator.java:73:  public void recordCheckpoint(String tenantKey, MongoMigrationCheckpoint checkpoint) {
adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/advanced/tenancy/database/MongoTenantMigrationCoordinator.java:85:  public Optional<MongoMigrationCheckpoint> checkpointFor(String tenantKey) {
adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/advanced/tenancy/database/MongoTenantMigrationCoordinator.java:98:    private final Map<String, MongoMigrationCheckpoint> byTenant =
adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/advanced/tenancy/database/MongoTenantMigrationCoordinator.java:105:    public Optional<MongoMigrationCheckpoint> find(String tenantKey) {
adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/advanced/tenancy/database/MongoTenantMigrationCoordinator.java:110:    public void save(String tenantKey, MongoMigrationCheckpoint checkpoint) {
adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/advanced/tenancy/database/MongoTenantMigrationCheckpointStore.java:3:import dev.caskeleton.adapter.outbound.mongo.migration.MongoMigrationCheckpoint;
adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/advanced/tenancy/database/MongoTenantMigrationCheckpointStore.java:21:  Optional<MongoMigrationCheckpoint> find(String tenantKey);
adapter/outbound/persistence-mongo/src/main/java/dev/caskeleton/adapter/outbound/mongo/advanced/tenancy/database/MongoTenantMigrationCheckpointStore.java:24:  void save(String tenantKey, MongoMigrationCheckpoint checkpoint);
exit=0

=== 8.4b migration lane test count at HEAD ===
$ ls adapter/outbound/persistence-mongo/build/test-results/mongoMigrationTest/*.xml | head -20
adapter/outbound/persistence-mongo/build/test-results/mongoMigrationTest/TEST-dev.caskeleton.adapter.outbound.mongo.migration.Ss07FenceProbe.xml
exit=0

$ grep -ho 'tests="[0-9]*" skipped="[0-9]*" failures="[0-9]*" errors="[0-9]*"' adapter/outbound/persistence-mongo/build/test-results/mongoMigrationTest/*.xml
tests="1" skipped="0" failures="0" errors="0"
exit=0

=== source tree after probe removal ===
$ git status --short | wc -l
0
exit=0

$ git status --short
exit=0


=== 8.4b RE-RUN: full mongoMigrationTest lane at HEAD (after probe removal) ===
$ ./gradlew :adapter:outbound:persistence-mongo:mongoMigrationTest --rerun-tasks
> Task :adapter:outbound:persistence-mongo:testClasses
> Task :adapter:outbound:persistence-mongo:mongoMigrationTest

BUILD SUCCESSFUL in 30s
13 actionable tasks: 13 executed
Consider enabling configuration cache to speed up this build: https://docs.gradle.org/9.0.0/userguide/configuration_cache_enabling.html

classes: 1
tests="8" skipped="0" failures="0" errors="0"

git status --short: 0 entries
