Add SP2 lexicon + two-record publish
Define and document the SkyPress content lexicon and implement the core
publish mechanic: write the writer's article to their PDS as a
site.standard.document (block tree in content + de-facto-required textContent),
ensure their site.standard.publication exists, and post a companion
app.bsky.feed.post linking to the public article (POSSE).
- lexicons/: blog.skypress.content.gutenberg.json + a README documenting every
record SkyPress writes (verified site.standard.* shapes, ours, app.bsky).
- src/lib/publish/records.ts: pure record/URL/slug builders + normalizeBlocks
(strips clientId, JSON-normalises rich-text) — unit-tested.
- src/lib/publish/publisher.ts: ensurePublication (matches OUR publication by
url, so we never attach to another tool's standard.site publication) -> create
post -> create document with bskyPostRef. Order avoids a circular dependency.
- PublishPanel: title + publish with an unmistakable "this also posts to
Bluesky" confirmation (brief §10).
- Dev loopback client now requests `atproto transition:generic` so createRecord
is authorized (one re-auth; handle now resolves via appview).
Verified end-to-end against a real account: records fetched back from the PDS
confirm the block tree stored as clean JSON, correct textContent, a real
Bluesky post with an external embed, and bskyPostRef. The live test caught a bug
(reusing a foreign publication) which is fixed by matching on url.