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.

Split uncovered endpoints safety net into focused suites

alice 29e57196 bfd1c080

+72 -24
+1 -1
docs/ENDPOINT_CONFORMANCE.md
··· 38 38 - `com.atproto.sync.requestCrawl` 39 39 The reference runtime still drives crawler notices internally, but the current official build does not expose the endpoint directly as a comparable external surface. 40 40 - `com.atproto.sync.notifyOfUpdate` 41 - Locally covered in `t/uncovered-endpoints.t`; not wired as a comparable public surface in the current official runtime. 41 + Locally covered in `t/crawler-status-surfaces.t`; not wired as a comparable public surface in the current official runtime. 42 42 - `com.atproto.admin.updateAccountSigningKey` 43 43 Locally covered in `t/admin-account-surfaces.t` and aligned to lexicon-void response semantics; no matching official external endpoint wiring was found in the current reference build. 44 44 - `com.atproto.admin.searchAccounts`
+6 -8
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=59, Tests=3057` 16 + - latest full green result in the realigned Meridian worktree: `Files=60, Tests=3061` 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` ··· 116 116 Current suite counts by bucket: 117 117 118 118 - `direct reference differential`: `5` 119 - - `audited local regression`: `41` 119 + - `audited local regression`: `42` 120 120 - `local correctness/infrastructure`: `13` 121 121 122 122 | Test file | Bucket | Current note | ··· 135 135 | `t/catalog.t` | local correctness/infrastructure | lexicon/catalog exposure smoke | 136 136 | `t/cors.t` | local correctness/infrastructure | CORS and preflight behavior | 137 137 | `t/crawlers.t` | audited local regression | outbound crawl notification semantics | 138 + | `t/crawler-status-surfaces.t` | audited local regression | isolated local crawler host notification/status endpoint coverage for `notifyOfUpdate` and `getHostStatus` | 138 139 | `t/crypto-interop.t` | direct reference differential | pinned upstream crypto fixture coverage | 139 140 | `t/delete-account.t` | audited local regression | reference-style account deletion flow using DID, password, and action token without a live bearer session | 140 141 | `t/discovery-surfaces.t` | audited local regression | isolated local discovery-surface coverage for endpoint catalog wiring, lexicon lookup, handle availability, and `listReposByCollection` | 142 + | `t/describe-repo-surfaces.t` | audited local regression | isolated `describeRepo` correctness coverage for collection listing and DID-doc-derived `handleIsCorrect` semantics | 141 143 | `t/email-confirmation.t` | audited local regression | intentionally testing-friendly email flow plus strict missing-email and invalid-email validation semantics | 142 144 | `t/email-update-helper.t` | audited local regression | shared email-update helper normalization, token revocation, and duplicate-email error semantics | 143 145 | `t/event-stream.t` | audited local regression | wire-format, malformed frame, and event decoding coverage | ··· 179 181 | `t/store-sqlite.t` | audited local regression | store-level session, invite, label, and repo persistence behavior | 180 182 | `t/temp-endpoints.t` | audited local regression | isolated local coverage for `com.atproto.temp.*` semantics and admin credential revocation behavior | 181 183 | `t/tid-repair.t` | local correctness/infrastructure | TID repair and recovery helpers | 182 - | `t/uncovered-endpoints.t` | audited local regression | now a very small pragmatic safety-net for `describeRepo` correctness and crawler host notification/status edges that still do not have a better thematic home | 183 - 184 184 ### Broad Mixed Suites 185 185 186 - The broadest suites are green and audited, but they still mix several categories of behavior inside the same file: 186 + The broadest suites are green and audited, but a small number still mix several categories of behavior inside the same file: 187 187 188 188 - `t/extended-api.t` 189 189 Carries real conformance value for `applyWrites`, but it is now much narrower and mostly acts as a focused repo-write regression suite. 190 190 - `t/external-surface.t` 191 191 Carries strong external-surface coverage for repo/blob export and missing-blob listing. It is cleaner after moving discovery, label-RPC, and account-status checks into dedicated suites, but still remains broader than a single-endpoint conformance file. 192 - - `t/uncovered-endpoints.t` 193 - Exists specifically to stop a few lesser-used local endpoints from falling out of coverage; it is much narrower now that the temp, invite, and admin-account blocks have moved into dedicated suites, but it should still be read as a pragmatic safety net, not as a pure reference-alignment suite. 194 192 195 193 ## What This Audit Does Not Yet Claim 196 194 ··· 213 211 4. decide whether to tighten admin auth to reference semantics or document the bearer shortcut as a permanent extension 214 212 5. keep local testing-only toggles, like the email-confirmation bypass, pinned in focused suites instead of letting broad mixed suites depend on them implicitly 215 213 6. keep narrowing the local `ServiceProxy` surface until every locally answered `app.bsky.*` field is either authoritative or explicitly documented as a local-only extension 216 - 7. keep documenting broad suites like `t/extended-api.t`, `t/external-surface.t`, and `t/uncovered-endpoints.t` as mixed conformance-plus-product coverage rather than over-claiming that every assertion is a pure reference check 214 + 7. keep documenting broad suites like `t/extended-api.t` and `t/external-surface.t` as mixed conformance-plus-product coverage rather than over-claiming that every assertion is a pure reference check 217 215 218 216 ## Practical Reading Of The Current Status 219 217
+63
t/crawler-status-surfaces.t
··· 1 + use v5.34; 2 + use warnings; 3 + 4 + use Config (); 5 + use File::Spec; 6 + use File::Temp qw(tempdir); 7 + use FindBin qw($Bin); 8 + use MIME::Base64 qw(encode_base64); 9 + use Test::More; 10 + 11 + BEGIN { 12 + require lib; 13 + my $root = File::Spec->rel2abs(File::Spec->catdir($Bin, '..')); 14 + lib->import( 15 + File::Spec->catdir($root, 'lib'), 16 + File::Spec->catdir($root, 'local', 'lib', 'perl5'), 17 + File::Spec->catdir($root, 'local', 'lib', 'perl5', $Config::Config{archname}), 18 + ); 19 + } 20 + 21 + use Test::Mojo; 22 + use ATProto::PDS; 23 + 24 + my $root = File::Spec->rel2abs(File::Spec->catdir($Bin, '..')); 25 + my $tmp = tempdir(CLEANUP => 1); 26 + 27 + my $app = ATProto::PDS->new( 28 + project_root => $root, 29 + settings => { 30 + base_url => 'http://127.0.0.1:7755', 31 + service_handle_domain => 'example.test', 32 + service_did_method => 'did:web', 33 + jwt_secret => 'crawler-status-secret', 34 + admin_password => 'admin-secret', 35 + testing_auto_confirm_email => 1, 36 + data_dir => $tmp, 37 + db_path => File::Spec->catfile($tmp, 'perlsky.sqlite'), 38 + }, 39 + ); 40 + 41 + my $t = Test::Mojo->new($app); 42 + my $admin_auth = 'Basic ' . encode_base64('admin:admin-secret', q()); 43 + 44 + $t->post_ok('/xrpc/com.atproto.sync.notifyOfUpdate' => json => { 45 + hostname => 'crawler.example.test', 46 + })->status_is(200) 47 + ->content_is(q()); 48 + 49 + $t->get_ok('/xrpc/com.atproto.sync.getHostStatus' => form => { 50 + hostname => 'crawler.example.test', 51 + })->status_is(200) 52 + ->json_is('/hostname' => 'crawler.example.test') 53 + ->json_is('/status' => 'active'); 54 + 55 + $t->get_ok('/xrpc/com.atproto.sync.getHostStatus' => { 56 + Authorization => $admin_auth, 57 + } => form => { 58 + hostname => 'crawler.example.test', 59 + })->status_is(200) 60 + ->json_is('/hostname' => 'crawler.example.test') 61 + ->json_is('/status' => 'active'); 62 + 63 + done_testing;
+2 -15
t/uncovered-endpoints.t t/describe-repo-surfaces.t
··· 5 5 use File::Spec; 6 6 use File::Temp qw(tempdir); 7 7 use FindBin qw($Bin); 8 - use MIME::Base64 qw(encode_base64); 9 8 use Test::More; 10 9 11 10 BEGIN { ··· 19 18 } 20 19 21 20 use Test::Mojo; 21 + use JSON::PP (); 22 22 use ATProto::PDS; 23 23 24 24 my $root = File::Spec->rel2abs(File::Spec->catdir($Bin, '..')); ··· 30 30 base_url => 'http://127.0.0.1:7755', 31 31 service_handle_domain => 'example.test', 32 32 service_did_method => 'did:web', 33 - jwt_secret => 'uncovered-endpoints-secret', 33 + jwt_secret => 'describe-repo-secret', 34 34 admin_password => 'admin-secret', 35 - self_service_invite_codes => 1, 36 35 testing_auto_confirm_email => 1, 37 36 data_dir => $tmp, 38 37 db_path => File::Spec->catfile($tmp, 'perlsky.sqlite'), ··· 40 39 ); 41 40 42 41 my $t = Test::Mojo->new($app); 43 - my $admin_auth = 'Basic ' . encode_base64('admin:admin-secret', q()); 44 42 45 43 $t->post_ok('/xrpc/com.atproto.server.createAccount' => json => { 46 44 handle => 'alice.example.test', ··· 88 86 ->status_is(200) 89 87 ->json_is('/handleIsCorrect' => JSON::PP::false) 90 88 ->json_is('/didDoc/alsoKnownAs/0' => 'at://wrong.example.test'); 91 - 92 - $t->post_ok('/xrpc/com.atproto.sync.notifyOfUpdate' => json => { 93 - hostname => 'crawler.example.test', 94 - })->status_is(200) 95 - ->content_is(q()); 96 - 97 - $t->get_ok('/xrpc/com.atproto.sync.getHostStatus' => form => { 98 - hostname => 'crawler.example.test', 99 - })->status_is(200) 100 - ->json_is('/hostname' => 'crawler.example.test') 101 - ->json_is('/status' => 'active'); 102 89 103 90 done_testing;