CLI app for developers prototyping atproto functionality
1
fork

Configure Feed

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

Add report stage to test labeler conformance suite #2

open opened by str4d.xyz targeting main from labeler-report-stage

Summary#

Adds a new report stage to atproto-devtool test labeler that exercises the full com.atproto.moderation.createReport authenticated-write path. The stage emits exactly 10 checks in a stable canonical order covering contract-published advertisement, no-JWT negatives (unauth + malformed bearer), self-mint negatives (wrong aud / lxm / exp / shape), the self-mint positive commit path, and two PDS-mediated positive modes (service-auth JWT and proxied createReport).

  • 38 acceptance criteria (AC1.1–AC8.4) all covered by automated tests; 196 tests pass in debug mode.
  • 11 stable labeler::report::* miette diagnostic codes, each pinned by assertion + snapshot.
  • Pollution-avoidance helpers pick reasonOther + record subject for remote labelers, lex-first + own-DID for local ones, and always carry a sentinel reason "atproto-devtool conformance test <RFC3339> <run-id>".
  • Commit-gated: --commit-report required for any write-side check.
  • Locality gate: --force-self-mint overrides the is_local_labeler_hostname heuristic.
  • New CLI flags: --commit-report, --self-mint-curve <es256|es256k>, --force-self-mint, --report-subject-did, --handle, --app-password (symmetric requires).
  • New primitives: AnySigningKey, hand-rolled RFC 7515 compact JWS in src/common/jwt.rs (ES256/ES256K only — no JWT library dep), encode_multikey companion to parse_multikey, is_local_labeler_hostname, SelfMintSigner with an ephemeral did:web:127.0.0.1%3A{port} identity server.
  • New seams: CreateReportTee (production + fake), PdsXrpcClient (production + fake). No production network hop bypasses the seams.
  • getrandom = "0.2" added as a direct dep (the transitive rand_core inside elliptic-curve is built without the getrandom feature).
  • CLAUDE.md files updated at repo root, src/commands/test/labeler/, and src/common/.

Implementation plan and rationale: docs/implementation-plans/2026-04-17-labeler-report-stage/. Human test plan: docs/test-plans/2026-04-17-labeler-report-stage.md.

Test Plan#

  • cargo test — 196 passed / 1 ignored
  • cargo clippy --all-targets -- -D warnings — clean
  • cargo fmt --check — clean
  • cargo build --release — clean
  • Phase 2 (read-only) against a real labeler: 10 report::* rows emitted in canonical order; write-side rows [SKIP]
  • Phase 3 (self-mint against a localhost labeler) with --commit-report: self_mint_accepted produces exactly one moderation queue entry carrying the sentinel reason
  • Phase 5 (PDS modes) with --handle + --app-password + --commit-report: 2 additional queue entries, authored by the real DID
  • Phase 6 (exit codes): 0 for conformant, 1 for SpecViolation, 2 for NetworkError
  • Pre-release: replace CONFORMANCE_REPORT_SUBJECT_URI / _CID placeholders in src/commands/test/labeler/create_report/pollution.rs with real values

See the human test plan file for step-by-step verification.

🤖 Generated with Claude Code

Summary

  • Branch labeler-report-stage pushed to origin with 58 commits.
  • PR must be opened manually at the URL above (Tangled has no CLI integration in this environment).
  • Worktree preserved at /home/str4d/dev/ai/atproto-devtool/.worktrees/labeler-report-stage.
  • Reminder: human test plan at docs/test-plans/2026-04-17-labeler-report-stage.md documents end-to-end scenarios against a real labeler, the --commit-report sentinel grep-ability check, and the release-gate CONFORMANCE_REPORT_SUBJECT_URI placeholder replacement — review before considering this work fully complete.
Labels

None yet.

assignee

None yet.

Participants 1
AT URI
at://did:plc:bvdrfwiamgi5leqs63q2duro/sh.tangled.repo.pull/3mjtuo4eq2322
Diff #0

No differences found between the selected revisions.

History

1 round 0 comments
sign up or login to add to the discussion
str4d.xyz submitted #0
patch application failed: error: No valid patches in input (allow with "--allow-empty")
expand 0 comments