[READ-ONLY] Mirror of https://github.com/flo-bit/contrail. atproto backend in a bottle flo-bit.dev/contrail

feat(contrail): community DID provisioning on stock PDS (#31) master

* feat(contrail-community): provision schema, types, adapter CRUD * feat(contrail-community): PDS + PLC + service-auth helpers * feat(contrail-community): provision orchestrator + XRPC route + session cache * feat(contrail-community): reap CLI for stuck provisioning rows * test+docs(contrail): provision e2e, docs, changeset, deps * fix(contrail-community): harden provision allowlist + reap (PR #31 review) Security/review follow-ups on the community DID provisioning feature: - Provisioning fails closed: with allowProvisioning=true, an empty/undefined allowlist no longer accepts any caller pdsEndpoint (fail-open). Require a non-empty allowlist, or the explicit, loud allowAnyProvisionPdsEndpoint. Renamed allowedPdsEndpoints -> allowedProvisionPdsEndpoints to scope it to provisioning (Contrail still reads/indexes from every PDS). - reap --all-stuck gains a mandatory age floor (listStuckAttempts(olderThanMs) + --older-than <minutes>, default 30) so a bulk run can't tombstone an in-flight provision. --attempt-id still targets a known row regardless. - reap is reachable: ship it as a contrail-community bin (under pnpm the core contrail CLI can't resolve the community package; the dynamic import there now logs instead of an empty catch). Adds Postgres support via --db/DATABASE_URL alongside the D1 binding. - archiveStuckAttempt is now atomic (db.batch) + idempotent (ON CONFLICT DO NOTHING), so a retry after a partial failure can't PK-conflict. - Minor: export bytesToB64url from plc and reuse in service-auth; drop the duplicate reap mutual-exclusion validator. mint-route allowlist gap (pre-existing on main) tracked separately in om-vyok. * test(contrail-community): drop tautological builder-shape assertions Remove the 'buildTombstoneOp produces the expected shape' case and the two pass-through type/prev assertions in the update-op test: both assert literals the builder just set or args just passed in, exercising object-literal semantics rather than runtime behavior. The real signing behavior (signTombstoneOp / signUpdateOp base64url sig) and the live-PLC CID round-trip remain covered. * docs(contrail-community): document SSRF exposure of allowAnyProvisionPdsEndpoint The accept-any escape hatch bypasses endpoint validation: the caller-supplied pdsEndpoint reaches describeServer + createAccount fetches with no private-IP/metadata guard. Note inline that it must be paired with trusted auth + egress network policy + IMDSv2; the default allowlist path contains this by construction. No behavior change.