| … | … | @@ -197,6 +197,54 @@ The DID is resolved at **projection** time; with no designated atproto credentia |
| 197 | 197 | dropped and the text kept, fail-closed. `did:` targets remain accepted as legacy (§8 is |
| 198 | 198 | forward-only). See `markdown-strip.md` §3.4. |
| 199 | 199 | |
| 200 | ### 3.5 Embeds — one URI form, and quotes are just links |
| 201 | |
| 202 | `markdown-strip.md` §3.5 already settles that `` produces **no text and no facet** and that |
| 203 | the embed pipeline consumes images separately, in source order. What was open is what the reference |
| 204 | *is*, and how it maps outward. |
| 205 | |
| 206 | **A blob reference is a content hash, because a blob is immutable.** Records are mutable and so are |
| 207 | addressed by position (§3.1); a blob is not, so it is addressed by its bytes — the same split |
| 208 | `NAMING.md` §2 makes between keys and names. |
| 209 | |
| 210 | ```markdown |
| 211 |  |
| 212 | ``` |
| 213 | |
| 214 | - **`<oid>`** is the **hyper-overlay** hash, ours. The atproto blob **CID** is a *different hash* |
| 215 | (raw codec vs blake2b) and is resolved at **projection** time through the `__blob__/<cid>` pointer, |
| 216 | exactly as a mention's DID is resolved at projection time (§3.4). Canonical names ours; the |
| 217 | projection resolves theirs. |
| 218 | - **The oid names the LEVEL MANIFEST, always** — not a level (`SOCIAL-MODEL.md` §6.6.1). A |
| 219 | single-level image gets a one-entry manifest of ~100 bytes. Uniform beats conditional: a shape that |
| 220 | is *sometimes* a manifest costs every consumer a branch, forever, to save one small file once. |
| 221 | - **Alt text is already in the markdown** and maps directly: atproto `embed.images[].alt`, AS2 |
| 222 | `attachment[].name`. |
| 223 | |
| 224 | **The three representations:** |
| 225 | |
| 226 | | | atproto | ActivityPub | |
| 227 | |---|---|---| |
| 228 | | image | `embed.images[]` — `{$type:'blob', ref:{$link:cid}, mimeType, size}` + `alt`, **bsky caps at 4** → `embed-truncated` in `loss[]` | `attachment[]` — `{type:'Document', url, mediaType, name}` | |
| 229 | | level choice | the bridge **selects** the level nearest its ceiling (§6.6.1) and reports it | same | |
| 230 | | quote | `embed.record` | a link in `content` (AS2 has no quote) | |
| 231 | | link card | `embed.external`, **derived by the consumer** | — | |
| 232 | |
| 233 | **Two things deliberately have no canonical form:** |
| 234 | |
| 235 | - ⛔ **Link cards are not authored.** `embed.external` is a *rendering* choice made by whoever |
| 236 | displays a link; inventing a canonical representation would put a consumer's presentation decision |
| 237 | into the author's bytes. |
| 238 | - ⛔ **A quote is a link, not a new syntax.** `[see this](favela://<roomKey>/<collection>/<position>)` |
| 239 | is a quote; the bsky projection turns a link to a record into `embed.record`. `recordWithMedia` |
| 240 | falls out of having both and needs no rule of its own. |
| 241 | |
| 242 | ⚠ **Extraction is `parse()`'s job, not `strip()`'s.** The strip is specified to *ignore* images |
| 243 | (§3.5), so embeds are yielded by the parse alongside `text`/`facets` — there is nothing for the strip |
| 244 | vectors to cover here. |
| 245 | |
| 246 | --- |
| 247 | |
| 200 | 248 | --- |
| 201 | 249 | |
| 202 | 250 | ## 4. The P2P side is the rich side |
| … | … | @@ -645,14 +693,13 @@ Honest gaps. This design is not complete until these are closed. |
| 645 | 693 | written afterwards. `test/strip-vectors.test.mjs` validates the vectors themselves; no stripper |
| 646 | 694 | exists yet. |
| 647 | 695 | |
| 648 | | 1b. **What signs a markdown record.** With the canonical record no longer a DAG-CBOR entry in a |
| 649 | | signed atproto commit chain (§0), authorship and integrity need their own mechanism — a detached |
| 650 | | per-record signature, or a native append-only log of `{rkey, contentHash, sig}` that peers |
| 651 | | replicate. Mutability is not an obstacle: the signature covers the current bytes and is |
| 652 | | re-issued on edit, exactly as atproto re-signs a commit on edit. **This is the next thing to |
| 653 | | settle; everything in §9 (read path) hangs off it.** |
| 654 | | 2. **Embed/attachment mapping** across three representations (atproto blob refs, AS2 `attachment`, |
| 655 | | markdown image syntax) is not worked through. |
| 696 | 1b. ~~**What signs a markdown record.**~~ **CLOSED — see `design.md` §4** (was hyper-social #57 B3, |
| 697 | stale since 2026-08-31). Nothing new is required: **authorship** is the pointer written into an |
| 698 | attestation-gated multi-writer autobase, **integrity** is the pointer's `$oid`, and `ensureLocal` |
| 699 | already refuses bytes that mismatch it. No detached per-record signature, no second log. The |
| 700 | atproto commit signature stays exactly where it is, as a projection artifact for consumers who |
| 701 | cannot see the room. |
| 702 | 2. ~~**Embed/attachment mapping**~~ **CLOSED 2026-09-05 — §3.5 below.** |
| 656 | 703 | 3. ~~**The extension dialect** (§4.1) names candidates but does not pin a set.~~ **CLOSED** — |
| 657 | 704 | pinned in `markdown-strip.md` §2.1 (CommonMark 0.31.2 + six named extensions). |
| 658 | 705 | 4. **Community/list URIs** — ~~the URI form for a favela community room~~ **ANSWERED 2026-09-05** |