This repository has no description
ideonomics.app docs 03-data.md
4.9 kB
Markdown
at dev

03 · Data Architecture (AT Protocol) #

Why atproto #

Three reasons beyond fashion. First, ownership matching the philosophy: a user's completions are their testimony, so they live in the user's own PDS, portable and app-independent. Second, the public-corpus property: all app.ideonomics.* records are on the open firehose, so rival analyses of the same data are possible — which is honest, given that our interpreter has a quilt too (01, 04). Third, the protocol's own three-layer pattern (PDS → firehose → AppView) exactly matches the instrument's separation of testimony, ingestion, and inference.

The governing principle #

Repos hold things the user said; the AppView holds things the system concluded. Derived state is never written to a user's repo — it goes stale on their next completion, forcing either repo-churning machine commits or silent misrepresentation. The one exception is deliberate: see snapshots below.

Lexicon namespace: app.ideonomics.* #

User-authored (user's PDS) #

app.ideonomics.completion — the atomic datum.

  • square — strongRef (AT-URI + CID) to the square record
  • slot — which position was open (a | b | c | d)
  • text — the free-text entry (absent for non-completions)
  • mode — completed | refused | noparse | joke (self-declared or inferred later; the record stores the user's own framing)
  • chain — optional: strongRef to the parent completion in this session's chain, plus depth
  • latencyBucket — coarse time-to-respond
  • createdAt

app.ideonomics.resonance — reaction to a rival completion.

  • completion — strongRef to the rival completion (or to a square + inline archetype text if the rival was generated)
  • reaction — lands | funny | irritates | flat
  • createdAt

app.ideonomics.snapshot — the only derived-looking record in the user's repo, and it isn't derived: it is a speech act. Created only by explicit user action ("publish this reading of myself"), it freezes a citable constellation at a fixed AT-URI: the rendered term-graph, the model/gloss-ensemble versions that produced it, and a content-addressed reference to the exact input set. Semantically "I publish this," not "the system computed this." No automatic creation, ever.

App-authored (app account's repo) #

app.ideonomics.square — the prompt.

  • a, b, c, d — three terms present, one absent; openSlot marks which
  • provenance — bank (curated/generated item, with generation metadata) or chained (strongRef to the user completion whose text was folded in)
  • discrimination — optional cached metadata: which quilt-pairs this item was selected to separate, generator version

Squares are records (not ephemeral) so that completions can strongRef them and third parties can audit exactly what was asked. Chained squares are reified only when actually served, bounding bloat.

app.ideonomics.gloss — an interpretive reading of a completion.

  • completion — strongRef
  • readings — array of { relation: free-text gloss, canonicalRelation: cluster ID, weight }
  • interpreter — model ID, prompt version, ensemble member, temperature
  • createdAt

Glosses are records so analysis is reproducible and auditable: anyone can check how a completion was read, by which model, under which prompt. Open question, deliberately unresolved: whether glosses should instead (or additionally) be surfaced into the user's view as a transparency right — "see how you were read." The AppView must expose this regardless of which repo stores it.

The three layers #

PDS layer — source of truth. The app writes user records via OAuth to the user's own PDS; app records to its own.

Ingestion — a Jetstream consumer tails the firehose filtered to app.ideonomics.*, hydrating the index. Idempotent, resumable by cursor; handles deletes and account migrations (records are keyed by DID, not handle).

AppView — SQLite (→ Postgres at scale) index owning: the term-graph per user, gloss aggregates, posterior state from inference (04), precomputed discrimination tables for adaptive selection, and constellation layout caches (06). All UI reads and all inference run here; nothing reads PDSes directly except the write-path's own read-after-write needs. Constellation history (drift over time) lives here cheaply as index rows — versioning of the self is an AppView concern, not a repo concern.

A user deleting a completion from their repo propagates through Jetstream; the AppView hard-deletes the row and marks dependent glosses orphaned (retained only in aggregate statistics, per a documented policy). Comparison features are consent-gated by pairing rather than by data publicity (06): the data is public by protocol; the social act of juxtaposition is opt-in in our AppView. Rival AppViews may be ruder; ours needn't be.