{ "assetKey": "a06-f016-flamingock-probe", "kind": "terminal", "command": "set -e\nD=$(mktemp -d)\ntrap 'rm -rf \"$D\"' EXIT\n\ncat > \"$D/FlamingockFenceProbe.java\" <<'JAVA'\nimport dev.caskeleton.adapter.outbound.mongo.security.admin.MongoAdminAuthorization;\nimport dev.caskeleton.adapter.outbound.mongo.security.admin.MongoAdminGateway;\nimport dev.caskeleton.adapter.outbound.mongo.security.admin.MongoAdminOperation;\nimport dev.caskeleton.adapter.outbound.mongo.security.admin.MongoAdminRuntimeGuard;\nimport dev.caskeleton.adapter.outbound.mongo.migration.MongoMigration;\nimport dev.caskeleton.adapter.outbound.mongo.migration.MongoMigrationChecksum;\nimport dev.caskeleton.adapter.outbound.mongo.migration.MongoMigrationContext;\nimport dev.caskeleton.adapter.outbound.mongo.migration.MongoMigrationId;\nimport dev.caskeleton.adapter.outbound.mongo.migration.MongoMigrationLedger;\nimport dev.caskeleton.adapter.outbound.mongo.migration.MongoMigrationLock;\nimport dev.caskeleton.adapter.outbound.mongo.migration.MongoMigrationPostcondition;\nimport dev.caskeleton.adapter.outbound.mongo.migration.MongoMigrationPrecondition;\nimport dev.caskeleton.adapter.outbound.mongo.migration.MongoMigrationResult;\nimport dev.caskeleton.adapter.outbound.mongo.migration.MongoMigrationRunner;\nimport dev.caskeleton.adapter.outbound.mongo.migration.flamingock.FlamingockLockAdapter;\nimport java.time.Clock;\nimport java.time.Duration;\nimport java.time.Instant;\nimport java.time.ZoneOffset;\nimport java.util.List;\nimport java.util.Optional;\nimport java.util.Set;\n\npublic final class FlamingockFenceProbe {\n\n private static final MongoMigrationId ID = new MongoMigrationId(\"20260829-001\");\n\n public static void main(String[] args) {\n FlamingockLockAdapter flamingock =\n new FlamingockLockAdapter(() -> true, extension -> {}, () -> {});\n System.out.println(\"FlamingockLockAdapter.held() = \" + flamingock.held());\n System.out.println(\"FlamingockLockAdapter.fence() = \" + flamingock.fence()\n + \" (UNFENCED = \" + MongoMigrationLock.UNFENCED + \")\");\n System.out.println();\n\n MongoMigrationRunner runner = new MongoMigrationRunner(new EmptyLedger());\n System.out.println(\"[검사가 마이그레이션을 보기 전에 걸린다]\");\n apply(\"마이그레이션 0건\", runner, List.of(), flamingock);\n apply(\"재개 불가 1건\", runner, List.of(nonResumable()), flamingock);\n System.out.println();\n\n System.out.println(\"[같은 마이그레이션, 펜스가 있는 리스]\");\n apply(\"재개 불가 1건\", runner, List.of(nonResumable()), new FencedLock(7L));\n System.exit(0);\n }\n\n private static void apply(\n String what, MongoMigrationRunner runner, List migrations,\n MongoMigrationLock lock) {\n try {\n List results = runner.apply(migrations, lock, template());\n System.out.println(\" \" + what + \" -> 실행, 결과 \" + results.size() + \"건\"\n + (results.isEmpty() ? \"\" : \" \" + results.get(0).status()));\n } catch (RuntimeException refused) {\n System.out.println(\" \" + what + \" -> 거절, \" + refused.getClass().getSimpleName());\n System.out.println(\" \" + refused.getMessage().split(\" \\\\[\")[0]);\n }\n }\n\n /** Completed in one call, so it never produces a checkpoint: not a resumable migration. */\n private static MongoMigration nonResumable() {\n return new MongoMigration() {\n @Override\n public MongoMigrationId id() {\n return ID;\n }\n\n @Override\n public MongoMigrationChecksum checksum() {\n return new MongoMigrationChecksum(\"abc\");\n }\n\n @Override\n public MongoMigrationPrecondition precondition() {\n return context -> true;\n }\n\n @Override\n public MongoMigrationResult execute(MongoMigrationContext context) {\n return MongoMigrationResult.completed(1L);\n }\n\n @Override\n public MongoMigrationPostcondition postcondition() {\n return (context, result) -> true;\n }\n };\n }\n\n private static MongoMigrationContext template() {\n MongoAdminGateway gateway =\n new MongoAdminGateway(\n new MongoAdminRuntimeGuard(true, \"app-credential\", \"migration-credential\"),\n MongoAdminAuthorization.routine(Set.of(MongoAdminOperation.APPLY_MIGRATION)),\n record -> {},\n Clock.fixed(Instant.EPOCH, ZoneOffset.UTC));\n return MongoMigrationContext.unleased(\n ID, gateway, null, 100, Duration.ZERO, Duration.ofMinutes(1), false, \"release-engineer\");\n }\n\n private static final class FencedLock implements MongoMigrationLock {\n\n private final long fence;\n\n private FencedLock(long fence) {\n this.fence = fence;\n }\n\n @Override\n public boolean held() {\n return true;\n }\n\n @Override\n public long fence() {\n return fence;\n }\n\n @Override\n public void refresh(Duration extension) {}\n\n @Override\n public void close() {}\n }\n\n private static final class EmptyLedger implements MongoMigrationLedger {\n\n @Override\n public Optional find(MongoMigrationId migrationId) {\n return Optional.empty();\n }\n\n @Override\n public void recordApplied(\n MongoMigrationId migrationId, MongoMigrationChecksum checksum, String operator,\n Instant appliedAt, long fence) {}\n\n @Override\n public Optional\n findCheckpoint(MongoMigrationId migrationId) {\n return Optional.empty();\n }\n\n @Override\n public void saveCheckpoint(\n dev.caskeleton.adapter.outbound.mongo.migration.MongoMigrationCheckpoint checkpoint,\n long fence) {}\n }\n}\nJAVA\n\nCACHE=/root/.gradle/caches/modules-2/files-2.1\nLOCK=src/adapter/outbound/persistence-mongo/gradle.lockfile\nCP=src/adapter/outbound/persistence-mongo/build/classes/java/main\nwhile IFS= read -r line; do\n coord=${line%%=*}; confs=${line#*=}\n case \",$confs,\" in *\",testRuntimeClasspath,\"*) ;; *) continue ;; esac\n g=${coord%%:*}; r=${coord#*:}; n=${r%%:*}; v=${r##*:}\n jar=$(find \"$CACHE/$g/$n/$v\" -name '*.jar' ! -name '*sources*' ! -name '*javadoc*' 2>/dev/null | head -1)\n [ -n \"$jar\" ] && CP=\"$CP:$jar\"\ndone < <(grep -E '^[a-zA-Z0-9._-]+:[^=]+=' \"$LOCK\")\n\njavac -encoding UTF-8 -cp \"$CP\" -d \"$D\" \"$D/FlamingockFenceProbe.java\"\njava -Dstdout.encoding=UTF-8 -cp \"$D:$CP\" FlamingockFenceProbe 2>&1 \\\n | grep -vE '^[0-9]{2}:[0-9]{2}:[0-9]{2}[.][0-9]{3} ' ", "cwd": "/shared/codebase/clean-architecture-backend-template", "exitCode": 0, "executedAt": "2026-09-02T07:44:36+00:00", "sourceRevision": "21234e38cdb9a926cbc92bb97a2aee2e4a7d2916", "raw": "evidence/raw/a06-f016-flamingock-probe.txt", "svg": "evidence/rendered/a06-f016-flamingock-probe.svg", "rawSha256": "2e858aaef023f1711122a8d67e9da6c74795abb9bab32d5fc7b57fdc8298ce70", "lines": 11, "redaction": "none — 밀폐 탐침 실행 출력, 자격증명 없음" }