An ATProto Powered Reputation Network
provenance docs design.md
4.9 kB
Markdown

Provenance #

Services #

Browser -> UI HTTP -> UI service -> ATProto adapter -> PDS
                         |
                         v
                   Appview client
                         |
                         v
                   Appview HTTP -> Appview service -> Storage interface -> SQLite
                                         |
                                         v
                                    Trust graph

The UI owns OAuth sessions and writes public vouches to the PDS. The appview owns participant indexes and private thresholds. Each participant opts in through login. The appview imports participant records once from their PDS. Microcosm Jetstream supplies later record updates, record deletion, and account lifecycle events. The appview uses Slingshot only for missing record payloads. Public instances are the defaults. Operators can select self-hosted instances through configuration. Explicit recovery can replace a participant's records through a PDS snapshot. The appview never schedules periodic PDS reads.

Microcosm Jetstream -> Stream adapter -> Appview service -> Storage interface -> SQLite
                            |
                            v
                       Slingshot cache

Initial backfill / explicit recovery -> PDS snapshot adapter

The stream cursor and each event update share one database transaction. Reconnects rewind the cursor by five seconds. Per-record timestamps and deletion tombstones reject duplicate or older events. Bootstrap holds the ingest lock and records a timestamp watermark before the PDS read. Events before that watermark cannot overwrite the snapshot. This rule assumes synchronized clocks between the appview and the stream source. Account deactivation hides outgoing and incoming graph edges for participating accounts. Account deletion removes authored records. Reactivation restores retained records for other account statuses.

Trust #

Assertions use integers from -3 through 2. The value -3 means blocked. Self trust uses 3 and is not an assertion about another identity. For each path, the raw score equals its minimum assertion minus the hop penalty for each additional edge. The initial hop penalty is 0.1. The graph selects the path with the maximum raw score. Calculated scores stay within [-2, 2]. The querying user's direct block overrides all paths and returns -3 with trusted=false. Other block assertions participate in path calculations as -3. Self queries return status self, score 3, and trusted=true. Unknown targets return status unknown, score null, and trusted=false. Other targets are trusted when their score equals or exceeds the user's private threshold. The initial threshold is 1. Queries omit paths for untrusted results unless the caller explicitly requests a path. The trusted endpoint returns only trusted. Traversal has resource limits. An incomplete calculation returns an error, not a partial score.

Tags #

Tags are case-sensitive strings of at most 128 Unicode code points. The empty string identifies the default namespace. Fallback selects the tagged assertion for each author-target pair. If that assertion is absent, fallback selects the default assertion. A tagged block or zero assertion does not trigger fallback.

Protocol #

The collection is computer.ngp.provenance.vouch. The namespace authority is provenance.ngp.computer. A deterministic record key identifies each target and tag pair. Records contain subject (DID), score, tag, and createdAt. The appview derives authorship from the participant repository, never from a record field.

ATProto OAuth requires PKCE, PAR, DPoP, issuer validation, and DID validation. It is not a standard OIDC flow. The UI requests only atproto and repository permissions for the vouch collection. OAuth secrets use encrypted storage. The encryption key stays outside SQLite. The UI and appview use a private service key for authenticated internal requests. The appview accepts caller identity only through this authenticated service boundary. Public endpoints cannot access thresholds or register participants.

Dependencies #

  • github.com/mattn/go-sqlite3 v1.14.52: native SQLite through CGO, MIT.
  • github.com/bluesky-social/indigo v0.0.0-20261006083258-ae9297b7d0f4: ATProto support, Apache-2.0/MIT.
  • sqlc: SQL code generation, MIT.
  • github.com/coder/websocket v1.8.15: Jetstream client, MIT.

References #