Skip to content

Conform to standard.site lexicon spec for publication + document records#407

Merged
coreyja merged 1 commit into
mainfrom
fix/standard-site-schema
Jun 5, 2026
Merged

Conform to standard.site lexicon spec for publication + document records#407
coreyja merged 1 commit into
mainfrom
fix/standard-site-schema

Conversation

@byte-the-bot

Copy link
Copy Markdown
Collaborator

The standard.site validator surfaced `required field missing: site` on document records. Investigation found multiple field-name deviations on both record types — we'd been emitting "close enough" shapes that lenient clients accepted but strict validation rejected.

Publication record fixes (spec: publication lexicon)

Was Now Reason
`title` `name` spec field name
`cover` `icon` spec field name
`createdAt` (removed) not in spec

Document record fixes (spec: document lexicon)

Was Now Reason
`publication: StrongRef` `site: String` spec uses a plain URI, NOT a strong-ref
`url: String` (required) `path: Option` spec has `path` (optional), not `url`
`cover` `coverImage` spec field name
`updatedAt: String` `updatedAt: Option` spec marks optional

The big design simplification

standard.site documents reference their publication via a plain URI string, not a StrongRef with cid. That means my `atproto_pub_cid` cascade work in #406 was solving a problem the spec doesn't have — when the publication content changes, document `site` strings stay valid because URIs are stable.

But the cascade machinery turns out to be exactly the right thing for this migration. Repurposed:

  • Old semantics: "strong-ref invariant — cascade re-puts when referent cid bumps"
  • New semantics: "trigger re-puts when publication record content changes (for any reason — schema, metadata edit, etc)"

Migration on merge

`publications.toml` flipped `cover_synced = false`. The next deploy:

  1. init sees `cover_synced = false` → re-puts publication with new spec-correct schema → new at_cid → committed
  2. sync walks 43 docs → all have stale `atproto_pub_cid` → drift detected → all re-put with new spec-correct schema
  3. Commit step pushes everything back

No manual steps. After this lands, run the standard.site validator against any `look-ma-no-ai` URL again and it should pass.

Out of scope (separate PR)

The Bluesky external-embed `associatedRefs` field still emits `StrongRef` shapes. That's a separate spec on the Bluesky side, not standard.site. Leaving it untouched until/unless validation flags it.

🤖 Generated with Claude Code

The validator at standard.site reported \`required field missing: site\`
on our document records. Investigation surfaced multiple field-name
deviations on both record types — we'd been emitting \"close enough\"
shapes that worked for lenient clients but failed strict validation.

\`site.standard.publication\` per <https://standard.site/docs/lexicons/publication/>:
  required: url, name
  optional: icon (blob), description, basicTheme, labels, preferences

Was emitting: title (s/b \`name\`), cover (s/b \`icon\`), createdAt (not
in spec at all). Fixed to spec; \`description\` is now \`Option<String>\`
to match \"optional\".

\`site.standard.document\` per <https://standard.site/docs/lexicons/document/>:
  required: site, title, publishedAt
  optional: path, description, coverImage, updatedAt, tags, ...

Was emitting: publication (s/b \`site\` AND as a plain URI string, not a
strong-ref), url (s/b \`path\`, optional), cover (s/b \`coverImage\`,
optional). Fixed: \`site: String\` holds the publication URI, \`path\` is
the URL segment relative to the publication URL (\`/<canonical>\`),
\`updatedAt\` made optional.

The \`atproto_pub_cid\` machinery from #406 stays — its semantics shift
from \"spec-correct strong-ref cascade\" to \"trigger doc re-emission
when publication record content changes.\" Useful in exactly this kind
of schema-migration scenario: the next deploy after this merges will
detect \`cover_synced = false\` → re-put publication with new schema →
new cid → all 43 docs detect drift → all re-put with new schema.

Also flips \`publications.toml\`'s \`cover_synced\` to \`false\` so the
migration triggers on the next deploy without manual intervention.

Bluesky external-embed \`associatedRefs\` still emits StrongRefs — that's
a separate spec on the Bluesky side and is out of scope for this PR.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@coreyja coreyja merged commit f9a486f into main Jun 5, 2026
6 checks passed
@coreyja coreyja deleted the fix/standard-site-schema branch June 5, 2026 14:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants