Sub-scope 03 (fileserver) publication - provider / adapter / journal / attestor / binding
revision=a24ece9cf797f7ea647e33bf846b115208ed1ba5
generatedAt=2026-08-30T01:19:02+00:00

=== OWNED FILES (19 main + 7 test) ===
c0ab08838529d6c1306aa74a4bcc342c67e131ad main/LocalPersistentPublicationProvider.java 896
471fe5a3c3431341e1e2a04df322129a38e71209 main/LocalFilePublicationAdapter.java 437
4cb369601458728aa95a3622ed67bcaeda0a9c85 main/RoutingFilePublicationAdapter.java 42
54233811ca6321c8f4d930e1d8992ea857cdde11 main/FilePublicationProvider.java 15
8b5f37749b3f01cc0dff9141ec319a8c8475134f main/LocalFilePublicationPolicy.java 25
b3f87f2cfbb778f4cde623a73ab2ecf764cce869 main/FilePublicationCanonicalDigests.java 201
129025a5b1de77098d60e3ee1d73a6d6d27d9f11 main/FilePublishRequestFingerprint.java 77
4289cbadde46c952b6d670fd0db1a77761f01803 main/DurablePublicationRecord.java 255
6061c91898c44220e24799ee0e2919c5bc986fbe main/PublishedReferenceRecord.java 48
a722a598a4913154c7f86f6f21bdd27f91bda96d main/R2PublishedReferenceCodec.java 79
3e8ddfe2536e32c78397d3606648690c31d42247 main/LocalPublicationJournal.java 294
a88c8957e6c5554fe46246d1184088225f828403 main/LocalPublicationJournalCodec.java 266
91795acbb44b33fc101403b9f1cc9d7d51dbaa27 main/LocalPublicationJournalRecord.java 145
fcc75af5de670326e0dcdd7045c3cece2540c0da main/LocalPublicationJournalException.java 15
ddeda2bbff614ef6eada17c6ce704cb6513d7d1e main/LocalPersistentRootAttestor.java 773
45347a6246fbbf6ce190bc254182b07d23a5a666 main/LocalPersistentRootEvidence.java 41
25527a723854d0aa5fc998a9ad2a20a1990f2d50 main/PrivateFileManifest.java 77
b121a7092f0f7edf537895f90adfdd805eb76e38 main/CompiledFileDestination.java 198
d6a89051f27b3ec02bd7940128ec935d7efac011 main/FileserverBindingCompiler.java 227
0b94b8585fb66dd609a4a1a9a81a18d728ee8202 test/LocalPersistentPublicationProviderTest.java 511
9400ea3df6f94194259b8defd7561d2f984bf241 test/LocalPersistentPublicationRecoveryTest.java 1121
f5895b81e9088db8a44133349bb98907ea0b0d9f test/LocalFilePublicationAdapterTest.java 235
2d2ed6023366c2f8bc382c3216dcef529f9173e9 test/LocalFilePublicationRecoveryTest.java 280
a13d78681d3d80651209f659d52499c3588df68a test/LocalPublicationJournalTest.java 147
a2c215e229a9490e36d491b8c6884f4806fad7c0 test/LocalPersistentRootAttestorTest.java 769
c5ad051249d1ab27e701c987169ef25cc210cc8e test/FileserverBindingCompilerTest.java 969

=== 8.1 reachability: which of the 19 escape the leaf? ===
$ git grep -rln 'LocalPersistentPublicationProvider\|LocalFilePublicationAdapter\|RoutingFilePublicationAdapter\|LocalPersistentRootAttestor\|FileserverBindingCompiler\|DurablePublicationRecord\|PrivateFileManifest\|PublishedReferenceRecord\|LocalPublicationJournal' -- . | grep -v "^adapter/outbound/fileserver/"
exit=1

$ grep -n 'public\|^final class\|^record\|^interface' adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/RoutingFilePublicationAdapter.java adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/FilePublicationProvider.java adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/CompiledFileDestination.java | head
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/RoutingFilePublicationAdapter.java:3:import dev.caskeleton.application.filepublication.FileDestinationId;
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/RoutingFilePublicationAdapter.java:4:import dev.caskeleton.application.filepublication.FilePublicationException;
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/RoutingFilePublicationAdapter.java:5:import dev.caskeleton.application.filepublication.FilePublicationPort;
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/RoutingFilePublicationAdapter.java:6:import dev.caskeleton.application.filepublication.FilePublishReceipt;
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/RoutingFilePublicationAdapter.java:7:import dev.caskeleton.application.filepublication.FilePublishRequest;
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/RoutingFilePublicationAdapter.java:8:import dev.caskeleton.application.filepublication.TabularRowProducer;
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/RoutingFilePublicationAdapter.java:13:final class RoutingFilePublicationAdapter implements FilePublicationPort {
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/RoutingFilePublicationAdapter.java:25:  public FilePublishReceipt publish(FilePublishRequest request, TabularRowProducer producer) {
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/RoutingFilePublicationAdapter.java:27:      throw invalidRequest("file publication request must be non-null");
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/RoutingFilePublicationAdapter.java:30:      throw invalidRequest("file publication producer must be non-null");
exit=0

=== 8.2 R1 journal vs R2 control plane: the same job at two rigor levels ===
--- (a) decoding strictness
$ grep -n 'new String(bytes, StandardCharsets.UTF_8)\|onMalformedInput' adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPublicationJournalCodec.java adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/FileserverControlRecordCodec.java
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPublicationJournalCodec.java:82:          .onMalformedInput(CodingErrorAction.REPORT)
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPublicationJournalCodec.java:156:      input = new String(bytes, StandardCharsets.UTF_8);
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/FileserverControlRecordCodec.java:846:            .onMalformedInput(CodingErrorAction.REPORT)
exit=0

$ grep -n 'static LocalPublicationJournalRecord decode\|decodeCanonical' adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPublicationJournalCodec.java
53:  static LocalPublicationJournalRecord decode(byte[] bytes) {
78:  static LocalPublicationJournalRecord decodeCanonical(byte[] bytes) {
exit=0

$ git grep -n 'LocalPublicationJournalCodec.decode' -- 'adapter/outbound/fileserver/src/main'
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPersistentControlPlane.java:634:        LocalPublicationJournalRecord r1 = LocalPublicationJournalCodec.decodeCanonical(encoded);
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPublicationJournal.java:52:          LocalPublicationJournalCodec.decode(Files.readAllBytes(record));
exit=0

--- (b) control-character escapes: R1 escapes them, R2 forbids them
$ grep -n "case 'b', 'f', 'n', 'r', 't'" -A 2 adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/FileserverControlRecordCodec.java
786:          case 'b', 'f', 'n', 'r', 't' ->
787-              throw new IllegalArgumentException("control characters are forbidden");
788-          default -> throw new IllegalArgumentException("invalid JSON escape");
exit=0

$ grep -n "case 'b' ->" -A 6 adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPublicationJournalCodec.java
214:          case 'b' -> value.append('\b');
215-          case 'f' -> value.append('\f');
216-          case 'n' -> value.append('\n');
217-          case 'r' -> value.append('\r');
218-          case 't' -> value.append('\t');
219-          case 'u' -> value.append(unicode());
220-          default -> throw new IllegalArgumentException("invalid escape");
exit=0

--- (c) POSIX permission enforcement
$ grep -n 'UnsupportedOperationException ignored' -B 4 -A 2 adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPublicationJournal.java
191-          Set.of(
192-              PosixFilePermission.OWNER_READ,
193-              PosixFilePermission.OWNER_WRITE,
194-              PosixFilePermission.OWNER_EXECUTE));
195:    } catch (UnsupportedOperationException ignored) {
196-      // Deployment qualification owns non-POSIX permission evidence.
197-    }
--
200-  private static void restrictFile(Path path) throws IOException {
201-    try {
202-      Files.setPosixFilePermissions(
203-          path, Set.of(PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE));
204:    } catch (UnsupportedOperationException ignored) {
205-      // Deployment qualification owns non-POSIX permission evidence.
206-    }
exit=0

$ grep -n 'must have exact private mode 0700\|PRIVATE_DIRECTORY_PERMISSIONS.equals' adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPersistentRootAttestor.java
404:    if (!PRIVATE_DIRECTORY_PERMISSIONS.equals(attributes.permissions())) {
405:      throw failure("internal directory must have exact private mode 0700: " + directory);
exit=0

--- (d) filesystem access primitive
$ grep -c 'SecureDirectoryStream' adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPersistentControlPlane.java adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPublicationJournal.java
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPersistentControlPlane.java:17
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPublicationJournal.java:0
exit=0

$ grep -n 'Files.exists\|Files.readAllBytes\|Files.isRegularFile' adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPublicationJournal.java
43:    if (!Files.exists(record, LinkOption.NOFOLLOW_LINKS)) {
47:      if (!Files.isRegularFile(record, LinkOption.NOFOLLOW_LINKS)
52:          LocalPublicationJournalCodec.decode(Files.readAllBytes(record));
73:      if (Files.exists(lockPath, LinkOption.NOFOLLOW_LINKS)
74:          && !Files.isRegularFile(lockPath, LinkOption.NOFOLLOW_LINKS)) {
175:    if (Files.exists(directory, LinkOption.NOFOLLOW_LINKS)) {
exit=0

=== 8.2b where the two meet: the R2 control plane reading an R1 journal ===
$ grep -n 'LocalPublicationJournalCodec.decodeCanonical' -B 6 -A 6 adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPersistentControlPlane.java
628-
629-  private StoredOperationRecord decodeStoredOperation(byte[] encoded) {
630-    try {
631-      return new R2StoredOperationRecord(codec.decodeOperation(encoded));
632-    } catch (RuntimeException versionTwoFailure) {
633-      try {
634:        LocalPublicationJournalRecord r1 = LocalPublicationJournalCodec.decodeCanonical(encoded);
635-        if (r1.state() != LocalPublicationJournalRecord.State.PUBLISHED) {
636-          throw new IllegalArgumentException(
637-              "R1 compatibility operation must be terminal PUBLISHED");
638-        }
639-        return new R1StoredOperationRecord(r1);
640-      } catch (RuntimeException versionOneFailure) {
exit=0

=== 8.3 duplicate mechanism: two reference formats, two lock implementations ===
$ grep -n 'filepub:' adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPersistentPublicationProvider.java adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalFilePublicationAdapter.java
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPersistentPublicationProvider.java:310:            "filepub:" + request.destinationId().value() + ":" + operationToken),
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalFilePublicationAdapter.java:243:            "filepub:" + policy.destinationId().value() + ":" + operationToken),
exit=0

$ grep -n 'VERSION = ' adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/R2PublishedReferenceCodec.java
14:  private static final String VERSION = "fsr1";
exit=0

$ grep -n 'class OperationLock' adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPersistentControlPlane.java adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPublicationJournal.java
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPersistentControlPlane.java:1377:  static final class OperationLock implements AutoCloseable {
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPublicationJournal.java:252:  static final class OperationLock implements AutoCloseable {
exit=0

$ grep -n 'Semaphore\[\]\|ReentrantLock\[\]' adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPublicationJournal.java adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPersistentControlPlane.java
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPublicationJournal.java:29:  private static final Semaphore[] JVM_LOCK_STRIPES = createLockStripes();
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPublicationJournal.java:233:  private static Semaphore[] createLockStripes() {
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPublicationJournal.java:234:    Semaphore[] locks = new Semaphore[JVM_LOCK_STRIPE_COUNT];
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPersistentControlPlane.java:43:  private static final ReentrantLock[] OPERATION_LOCK_STRIPES = createOperationLockStripes();
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPersistentControlPlane.java:44:  private static final ReentrantLock[] IMMUTABLE_LOCK_STRIPES = createOperationLockStripes();
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPersistentControlPlane.java:870:  private static ReentrantLock[] createOperationLockStripes() {
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPersistentControlPlane.java:871:    ReentrantLock[] stripes = new ReentrantLock[OPERATION_LOCK_STRIPE_COUNT];
exit=0

=== 8.4 doc claims about R1 restore and guarantee non-promotion ===
$ grep -n 'PROCESS_LOCAL_SYNC' adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPersistentPublicationProvider.java adapter/outbound/fileserver/README.md adapter/outbound/fileserver/CLAUDE.md
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPersistentPublicationProvider.java:323:        DurabilityGuarantee.PROCESS_LOCAL_SYNC,
adapter/outbound/fileserver/README.md:111:matching root-level artifact, R2 may restore its original `PROCESS_LOCAL_SYNC` receipt read-only.
adapter/outbound/fileserver/CLAUDE.md:53:  `PROCESS_LOCAL_SYNC`; R2 writes schema v2 only.
exit=0

$ grep -n 'never writes schema v1\|never promotes' adapter/outbound/fileserver/README.md
112:It never writes schema v1, creates an R2 manifest/reference for that artifact, or promotes its
exit=0

$ grep -n 'CURRENT_SCHEMA_VERSION' adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/DurablePublicationRecord.java adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPublicationJournalRecord.java
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/DurablePublicationRecord.java:34:  static final int CURRENT_SCHEMA_VERSION = 2;
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/DurablePublicationRecord.java:37:    if (schemaVersion != CURRENT_SCHEMA_VERSION) {
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPublicationJournalRecord.java:22:  static final int CURRENT_SCHEMA_VERSION = 1;
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPublicationJournalRecord.java:25:    if (schemaVersion != CURRENT_SCHEMA_VERSION) {
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPublicationJournalRecord.java:60:        CURRENT_SCHEMA_VERSION,
adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/LocalPublicationJournalRecord.java:86:        CURRENT_SCHEMA_VERSION,
exit=0

$ grep -n 'routeToken(String effectivePolicyDigest)' -A 5 adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/FilePublicationCanonicalDigests.java
108:  static String routeToken(String effectivePolicyDigest) {
109-    String validated =
110-        FileserverR2Validation.requireSha256("effectivePolicyDigest", effectivePolicyDigest);
111-    return "r" + validated.substring(0, 31);
112-  }
113-
exit=0

$ grep -n 'deriveUniqueRouteTokens' -A 4 adapter/outbound/fileserver/src/main/java/dev/caskeleton/adapter/outbound/fileserver/FileserverBindingCompiler.java | head -12
89:    Map<FileDestinationId, String> routeTokens = deriveUniqueRouteTokens(policyDigests);
90-    compiled.forEach(
91-        (destinationId, destination) -> {
92-          if (!destination.routeToken().equals(routeTokens.get(destinationId))) {
93-            throw new IllegalStateException("compiled route token differs from route registry");
--
99:  static Map<FileDestinationId, String> deriveUniqueRouteTokens(
100-      Map<FileDestinationId, String> policyDigests) {
101-    Objects.requireNonNull(policyDigests, "policyDigests must be non-null");
102-    Map<String, FileDestinationId> routeOwners = new LinkedHashMap<>();
103-    Map<FileDestinationId, String> routeTokens = new LinkedHashMap<>();
exit=0

