perlsky is a Perl 5 implementation of an AT Protocol Personal Data Server.
13
fork

Configure Feed

Select the types of activity you want to include in your feed.

Cover prereference sync blob visibility

alice d1e34e37 e6db2f5e

+13 -1
+2 -1
docs/TEST_AUDIT.md
··· 13 13 The current baseline for saying "the audited suite is green" is: 14 14 15 15 - `prove -lr t` 16 - - latest full green result in the realigned Meridian worktree: `Files=61, Tests=3129` 16 + - latest full green result in the realigned Meridian worktree: `Files=61, Tests=3132` 17 17 - `prove -lv t/server-auth.t` 18 18 - `perl -c script/differential-validate` 19 19 - `PERLSKY_RUN_REFERENCE_DIFF=1 prove -lv t/reference-differential.t` ··· 78 78 - Remote `did:plc` DID docs should resolve through the PLC directory defaults even when `plc_url` is not explicitly configured; gating that path on local config silently breaks federated identity lookups. 79 79 - Missing-repo read paths now match the official runtime more closely: `describeRepo`, `sync.getLatestCommit`, `sync.getRecord`, `sync.getRepo`, `sync.getCheckout`, `sync.getHead`, `sync.getRepoStatus`, `sync.getBlocks`, `sync.getBlob`, and `sync.listBlobs` report `400 RepoNotFound`, while `listRecords` reports `400 InvalidRequest` / `Could not find repo: ...`. 80 80 - `com.atproto.sync.getBlob` needs two distinct not-found branches to stay reference-compatible: missing repos still report `400 RepoNotFound`, but blobs that are merely unreferenced for that repo report `400 InvalidRequest` / `Blob not found`, while moderation takedowns still hide them behind the moderation-layer `404 BlobNotFound` path. 81 + - Blob sync visibility is now pinned in three phases instead of one: prereference uploader reads fail with `400 InvalidRequest`, referenced same-repo reads succeed with blob bytes and hardening headers, and deduplicated uploads on another repo still fail until that repo actually references the blob. 81 82 - `com.atproto.repo.getRecord` must honor `cid` when present, and `putRecord` / `deleteRecord` must actually enforce `swapRecord`; those negative edges are now covered directly. 82 83 - `com.atproto.repo.createRecord` follows the reference runtime by ignoring a stray `swapRecord` field, and direct reference coverage now pins `putRecord` / `deleteRecord` `swapCommit` and `swapRecord` mismatch semantics explicitly. 83 84 - App-password sessions follow the official runtime more closely than the older local assumptions did: access-token scopes use the `com.atproto.appPass` / `com.atproto.appPassPrivileged` names, standard app-password sessions may list app passwords, privileged-only `getServiceAuth` failures report `InvalidRequest`, and revoked refresh tokens on `refreshSession` fail with `400 ExpiredToken`.
+5
script/differential-validate
··· 2105 2105 next unless $upload->is_success; 2106 2106 2107 2107 my $blob = ($upload->json || {})->{blob}; 2108 + my $preref_blob = get_form($server{$name}{origin}, 'com.atproto.sync.getBlob', { 2109 + did => $server{$name}{did}, 2110 + cid => $blob->{ref}{'$link'}, 2111 + }); 2108 2112 my $create = post_json( 2109 2113 $server{$name}{origin}, 2110 2114 'com.atproto.repo.createRecord', ··· 2154 2158 ok => $res->is_success ? 1 : 0, 2155 2159 returns_blob => (scalar grep { $_ eq $blob_cid } @{ $json->{cids} || [] }) ? 1 : 0, 2156 2160 cursor_matches_tail => (($json->{cursor} // q()) eq (($json->{cids} || [])->[-1] // q())) ? 1 : 0, 2161 + preref_blob => normalize_xrpc_error($preref_blob), 2157 2162 secondary_empty => @{ $secondary_json->{cids} || [] } ? 0 : 1, 2158 2163 missing_repo => normalize_xrpc_error($missing_repo), 2159 2164 };
+6
t/sync-blob-export-surfaces.t
··· 94 94 my $blob = $t->tx->res->json->{blob}; 95 95 my $blob_cid = $blob->{ref}{'$link'}; 96 96 97 + $t->get_ok(Mojo::URL->new('/xrpc/com.atproto.sync.getBlob')->query( 98 + did => $did, 99 + cid => $blob_cid, 100 + ))->status_is(400) 101 + ->json_is('/error' => 'InvalidRequest'); 102 + 97 103 $t->post_ok('/xrpc/com.atproto.repo.createRecord' => { 98 104 Authorization => "Bearer $access", 99 105 } => json => {