| … | … | @@ -1,6 +1,6 @@ |
| 1 | 1 | --- |
| 2 | 2 | name: ap-bridge |
| 3 | | description: ActivityPub as a PROJECTION of the same canonical atproto record bytes — pure-JS RSA + HTTP Signatures (cavage-12) under Bare, WebFinger/actor, record→AS2, inbox Follow→Accept, firehose-driven delivery. Live at ap.7rnx.net. |
| 3 | description: ActivityPub as a PROJECTION of the same canonical atproto record bytes — pure-JS RSA + HTTP Signatures (cavage-12) under Bare, WebFinger/actor, record→AS2, inbox Follow→Accept, firehose-driven delivery. Also the OTA/control surface, `reproject` backfill, and the ⛔ Mastodon trap that an `Update` without an `updated` timestamp is silently discarded (2xx, no edit, no media re-fetch). Read before touching AP delivery, edits, media/attachments, or deploying ap-bridge. Live at ap.7rnx.net. |
| 4 | 4 | category: project |
| 5 | 5 | priority: high |
| 6 | 6 | location: hyper-fleeky/ap-bridge |
| … | … | @@ -11,7 +11,7 @@ updated: 2026-08-05 |
| 11 | 11 | |
| 12 | 12 | **v0.0.4** (M0→M3 shipped 2026-08-01; control surface + OTA 0.0.2, `reproject` 0.0.3, `updated` fix 0.0.4), runtime **Bare**, pgh app `ap-bridge`, |
| 13 | 13 | port **3400**, live at `https://ap.7rnx.net` (vhost → stortron:3400). |
| 14 | | 70 tests / 254 asserts, all offline. |
| 14 | 81 tests / 275 asserts, all offline. |
| 15 | 15 | |
| 16 | 16 | ## ★ The thesis: ActivityPub is a projection, not a bridge |
| 17 | 17 | |
| … | … | @@ -261,8 +261,27 @@ because sibling repos had **unpushed commits the outbox depended on**; and |
| 261 | 261 | `pgh publish` refusing because `npm install brittle` re-resolved the tree and deleted |
| 262 | 262 | the vendored siblings (`removed 1194 packages`). |
| 263 | 263 | |
| 264 | ★ **The vendor list is DERIVED from `package.json`'s `file:` deps (0.0.2)** — never |
| 265 | hardcoded. atproto-bridge kept it in three hardcoded places, one drifted when a sibling |
| 266 | was added, and `pgh publish` then failed on every build for ~10 days SILENTLY (a failed |
| 267 | publish records no version, so `pgh deploy log` simply shows nothing newer). Adding |
| 268 | `hyper-svc` for the control surface picked it up automatically. |
| 269 | |
| 270 | ⚠ The declare-deps guard checks the **declaration**, not `[ -d node_modules/$m ]` — disk |
| 271 | presence passes for anything hoisted in transitively, which is exactly the bug it exists |
| 272 | to catch. `bare-os` was undeclared and the old check waved it through. It still only sees |
| 273 | static `from '…'` imports, so a dynamic `await import()` remains invisible to it. |
| 274 | |
| 275 | **Deploys are OTA since 0.0.2 — no manual stop/install/start.** `pgh publish` → the |
| 276 | sidecar installs → `release-ready` → exit 75 → supervisor respawns. Verified twice |
| 277 | hands-off (0.0.3 and 0.0.4). The one exception was the 0.0.1→0.0.2 hop itself: the old |
| 278 | code had no handler for the sidecar to push to, so that upgrade needed a manual restart. |
| 279 | Any app being given a control surface for the first time has the same one-off. |
| 280 | |
| 264 | 281 | Deploy-shape gotchas: `readiness` takes **`port`, not `url`**; a missing `pgh.upgrade` |
| 265 | | means OTA can never work; `b4a`/`bare-fs` must be declared. |
| 282 | means OTA can never work; `b4a`/`bare-fs`/`bare-os` must be declared. ⚠ A UDS path is |
| 283 | capped near **107 bytes** — a long `AP_SOCK` fails to bind with `invalid argument`, and |
| 284 | the control surface then degrades silently to "unavailable" while HTTP keeps serving. |
| 266 | 285 | |
| 267 | 286 | ## Boot-order gotcha |
| 268 | 287 | |