OverviewFilesCommitsIssuesDocsReleasesPeers

ap-bridge commits / 455555b

0.10.4: recover an item stored before it could say whose it was
⛔ THE SCOPE HID THE ONE THING THE PAGE EXISTS TO SHOW. 0.10.3 made an inbound Like showable and it still did not appear: stored before `recipient` existed, it belongs to nobody, and a per-peer feed correctly refuses an item that cannot say whose it is. But the OBJECT URI can say. `/ap/objects/<rkey>` is the primary's flat path and `/ap/users/<name>/objects/<rkey>` is that user's — the same pairing that made the bare form the legacy shorthand. Reading it recovers addressing that was never lost, rather than inventing addressing that was. ⚠ OUR HOST ONLY, and only the primary may claim a bare `/ap/objects/` path. Another server's path structure is not ours to interpret, and a guess there puts a stranger's interaction on somebody's page. 1184/1184 pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
455555bb1e5fe4ba712ed05139ccf4c046ac876e
by plankatron <fleeky@gmail.com> · 2026-09-15T16:04:21.000Z

Changed files (5) +164 -97

.pgh-lock.json +93 -93
……@@ -1,9 +1,9 @@
11{
22 "name": "ap-bridge",
3 "version": "0.10.2",
3 "version": "0.10.3",
44 "runtime": "bare",
5 "rootTreeHash": "7e5aa041b30466190a4247b4bac3cdf98a1d4cf4663c83f0ec1b0f48c3962e6d",
6 "publishedAt": "2026-09-15T15:32:24.187Z",
5 "rootTreeHash": "28f51ee7726afd01990551b3289e297cfb7e7c1fa420c3e4cf2250becad116ac",
6 "publishedAt": "2026-09-15T16:01:47.807Z",
77 "deps": [
88 {
99 "name": "@hyperswarm/secret-stream",
……@@ -4004,8 +4004,8 @@
40044004 "tree": "38f44af48b2d59b46f1b5db31b81d02f3ca8b8bad6bc0fb9fffff698241f5e37"
40054005 }
40064006 ],
4007 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4008 "acceptedAt": "2026-09-15T15:32:24.222Z"
4007 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4008 "acceptedAt": "2026-09-15T16:01:47.824Z"
40094009 },
40104010 {
40114011 "type": "VERSION_CONFLICT",
……@@ -4019,8 +4019,8 @@
40194019 "tree": "ee91b6bd77101e3404ca571b2e5adf0f47029d174398a05f50294fc207e39d99"
40204020 }
40214021 ],
4022 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4023 "acceptedAt": "2026-09-15T15:32:24.222Z"
4022 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4023 "acceptedAt": "2026-09-15T16:01:47.824Z"
40244024 },
40254025 {
40264026 "type": "VERSION_CONFLICT",
……@@ -4034,8 +4034,8 @@
40344034 "tree": "3bb78d8f06263a549bd1077f37a7df257b1d557e44608631435af625f05a9c11"
40354035 }
40364036 ],
4037 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4038 "acceptedAt": "2026-09-15T15:32:24.222Z"
4037 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4038 "acceptedAt": "2026-09-15T16:01:47.824Z"
40394039 },
40404040 {
40414041 "type": "VERSION_CONFLICT",
……@@ -4054,8 +4054,8 @@
40544054 "tree": "58c0bf8698af19464d0ee8354a77ed1ac96d3a5fa18aa4e794686cfbbf080e5d"
40554055 }
40564056 ],
4057 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4058 "acceptedAt": "2026-09-15T15:32:24.222Z"
4057 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4058 "acceptedAt": "2026-09-15T16:01:47.824Z"
40594059 },
40604060 {
40614061 "type": "VERSION_CONFLICT",
……@@ -4069,8 +4069,8 @@
40694069 "tree": "da4c6b2654e9d66f10b0faa989311cf182878c24ab51b1c41458cfbf37ad29cd"
40704070 }
40714071 ],
4072 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4073 "acceptedAt": "2026-09-15T15:32:24.222Z"
4072 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4073 "acceptedAt": "2026-09-15T16:01:47.824Z"
40744074 },
40754075 {
40764076 "type": "VERSION_CONFLICT",
……@@ -4084,8 +4084,8 @@
40844084 "tree": "40be8f559a13b54ebf0689e63e6c70f0d218035359e17c497ed7bc8a85c3cc95"
40854085 }
40864086 ],
4087 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4088 "acceptedAt": "2026-09-15T15:32:24.222Z"
4087 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4088 "acceptedAt": "2026-09-15T16:01:47.824Z"
40894089 },
40904090 {
40914091 "type": "VERSION_CONFLICT",
……@@ -4099,8 +4099,8 @@
40994099 "tree": "3eae85efce82299769898c8151b5ed0a94e5a5ebdbcdee2105b815ca733a61cb"
41004100 }
41014101 ],
4102 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4103 "acceptedAt": "2026-09-15T15:32:24.222Z"
4102 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4103 "acceptedAt": "2026-09-15T16:01:47.824Z"
41044104 },
41054105 {
41064106 "type": "VERSION_CONFLICT",
……@@ -4114,8 +4114,8 @@
41144114 "tree": "8d9e01d443a127781773598d2e77c3f372334fad09e20623a819dabe49b22e1a"
41154115 }
41164116 ],
4117 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4118 "acceptedAt": "2026-09-15T15:32:24.222Z"
4117 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4118 "acceptedAt": "2026-09-15T16:01:47.824Z"
41194119 },
41204120 {
41214121 "type": "VERSION_CONFLICT",
……@@ -4129,8 +4129,8 @@
41294129 "tree": "dc1ad6c999fe90d946ba0ef34698ea9af451b639be2ad1c5b61eabb08337a6ca"
41304130 }
41314131 ],
4132 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4133 "acceptedAt": "2026-09-15T15:32:24.222Z"
4132 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4133 "acceptedAt": "2026-09-15T16:01:47.824Z"
41344134 },
41354135 {
41364136 "type": "VERSION_CONFLICT",
……@@ -4144,8 +4144,8 @@
41444144 "tree": "88b4779570e5113aa21b204989ac018d1628b387681f7e53428a7c99114fb701"
41454145 }
41464146 ],
4147 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4148 "acceptedAt": "2026-09-15T15:32:24.222Z"
4147 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4148 "acceptedAt": "2026-09-15T16:01:47.824Z"
41494149 },
41504150 {
41514151 "type": "VERSION_CONFLICT",
……@@ -4159,8 +4159,8 @@
41594159 "tree": "720b867ec4300a3caa2325eb1449499f9940bfb88341ecceb5992fa0fdf5f37d"
41604160 }
41614161 ],
4162 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4163 "acceptedAt": "2026-09-15T15:32:24.222Z"
4162 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4163 "acceptedAt": "2026-09-15T16:01:47.824Z"
41644164 },
41654165 {
41664166 "type": "VERSION_CONFLICT",
……@@ -4174,8 +4174,8 @@
41744174 "tree": "b697fe174482a708b49d0764cd4786291845f0034a31e0699381ca7e7b269d04"
41754175 }
41764176 ],
4177 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4178 "acceptedAt": "2026-09-15T15:32:24.222Z"
4177 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4178 "acceptedAt": "2026-09-15T16:01:47.824Z"
41794179 },
41804180 {
41814181 "type": "VERSION_CONFLICT",
……@@ -4189,8 +4189,8 @@
41894189 "tree": "767f07242277ae80bd395de5a4969fcdbf956c216158ae517fb2b562558ac1a4"
41904190 }
41914191 ],
4192 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4193 "acceptedAt": "2026-09-15T15:32:24.222Z"
4192 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4193 "acceptedAt": "2026-09-15T16:01:47.824Z"
41944194 },
41954195 {
41964196 "type": "VERSION_CONFLICT",
……@@ -4204,8 +4204,8 @@
42044204 "tree": "de7deed21f587ffc8bde4971abe00fca77bb6c71c4e7effb31ad34ee330815df"
42054205 }
42064206 ],
4207 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4208 "acceptedAt": "2026-09-15T15:32:24.222Z"
4207 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4208 "acceptedAt": "2026-09-15T16:01:47.824Z"
42094209 },
42104210 {
42114211 "type": "VERSION_CONFLICT",
……@@ -4219,8 +4219,8 @@
42194219 "tree": "2df42517ebf73cd9c11f2f652f75e87401fd4ed7b856c0adc15c33baf1d4f1ad"
42204220 }
42214221 ],
4222 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4223 "acceptedAt": "2026-09-15T15:32:24.222Z"
4222 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4223 "acceptedAt": "2026-09-15T16:01:47.824Z"
42244224 },
42254225 {
42264226 "type": "VERSION_CONFLICT",
……@@ -4234,8 +4234,8 @@
42344234 "tree": "325aca171cbff560487177584078c8066133e91176639ca47c98d70e195aa92e"
42354235 }
42364236 ],
4237 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4238 "acceptedAt": "2026-09-15T15:32:24.222Z"
4237 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4238 "acceptedAt": "2026-09-15T16:01:47.824Z"
42394239 },
42404240 {
42414241 "type": "VERSION_CONFLICT",
……@@ -4264,8 +4264,8 @@
42644264 "tree": "89a40400106bf4fef95fb5c44a66ee29aada6f76c7740bfba09d8aeeb841f39c"
42654265 }
42664266 ],
4267 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4268 "acceptedAt": "2026-09-15T15:32:24.222Z"
4267 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4268 "acceptedAt": "2026-09-15T16:01:47.824Z"
42694269 },
42704270 {
42714271 "type": "VERSION_CONFLICT",
……@@ -4279,8 +4279,8 @@
42794279 "tree": "1bd0eb382789c62cd4622d47bffb60984fdd766260c79f73a2fc7a136f3edbe9"
42804280 }
42814281 ],
4282 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4283 "acceptedAt": "2026-09-15T15:32:24.222Z"
4282 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4283 "acceptedAt": "2026-09-15T16:01:47.824Z"
42844284 },
42854285 {
42864286 "type": "VERSION_CONFLICT",
……@@ -4294,8 +4294,8 @@
42944294 "tree": "4526fe9dc5468264c7171ec16e9303726674b7b44ca0b3e09cb8b9a6a1be6169"
42954295 }
42964296 ],
4297 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4298 "acceptedAt": "2026-09-15T15:32:24.222Z"
4297 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4298 "acceptedAt": "2026-09-15T16:01:47.824Z"
42994299 },
43004300 {
43014301 "type": "VERSION_CONFLICT",
……@@ -4309,8 +4309,8 @@
43094309 "tree": "32b291cd756e142da18a6ed01c351e024fcedc3e2b1ecfbfb85f3106ada4419b"
43104310 }
43114311 ],
4312 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4313 "acceptedAt": "2026-09-15T15:32:24.222Z"
4312 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4313 "acceptedAt": "2026-09-15T16:01:47.824Z"
43144314 },
43154315 {
43164316 "type": "VERSION_CONFLICT",
……@@ -4324,8 +4324,8 @@
43244324 "tree": "4a8cd3b0093092b33088617dc0415e8179882d7f2f13b7649962ca20b08beeed"
43254325 }
43264326 ],
4327 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4328 "acceptedAt": "2026-09-15T15:32:24.222Z"
4327 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4328 "acceptedAt": "2026-09-15T16:01:47.824Z"
43294329 },
43304330 {
43314331 "type": "VERSION_CONFLICT",
……@@ -4339,8 +4339,8 @@
43394339 "tree": "4f63f165ee6a581f689b40c4a40df4df01ab6fba17d46bd29e40ef5bbdd9884f"
43404340 }
43414341 ],
4342 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4343 "acceptedAt": "2026-09-15T15:32:24.222Z"
4342 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4343 "acceptedAt": "2026-09-15T16:01:47.824Z"
43444344 },
43454345 {
43464346 "type": "VERSION_CONFLICT",
……@@ -4354,8 +4354,8 @@
43544354 "tree": "735109c736c0bd3413ab47414fd8b6ea9a99c401fe8e6d608459c79293806754"
43554355 }
43564356 ],
4357 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4358 "acceptedAt": "2026-09-15T15:32:24.222Z"
4357 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4358 "acceptedAt": "2026-09-15T16:01:47.824Z"
43594359 },
43604360 {
43614361 "type": "VERSION_CONFLICT",
……@@ -4369,8 +4369,8 @@
43694369 "tree": "b32b75bf1b2acdd18ed0cc370d01d477fba42ba09fd1f2f78af3ebad925e72d5"
43704370 }
43714371 ],
4372 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4373 "acceptedAt": "2026-09-15T15:32:24.222Z"
4372 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4373 "acceptedAt": "2026-09-15T16:01:47.824Z"
43744374 },
43754375 {
43764376 "type": "VERSION_CONFLICT",
……@@ -4389,8 +4389,8 @@
43894389 "tree": "189397178121e9a18430943345dab820691648a324229071ceb980bbb77a7393"
43904390 }
43914391 ],
4392 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4393 "acceptedAt": "2026-09-15T15:32:24.222Z"
4392 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4393 "acceptedAt": "2026-09-15T16:01:47.824Z"
43944394 },
43954395 {
43964396 "type": "VERSION_CONFLICT",
……@@ -4404,8 +4404,8 @@
44044404 "tree": "3bedca5287a9041fc2fd5ec5ace4df1fa86240e6afec0a105ba67398bafc09a5"
44054405 }
44064406 ],
4407 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4408 "acceptedAt": "2026-09-15T15:32:24.222Z"
4407 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4408 "acceptedAt": "2026-09-15T16:01:47.824Z"
44094409 },
44104410 {
44114411 "type": "VERSION_CONFLICT",
……@@ -4419,8 +4419,8 @@
44194419 "tree": "b9ca9b272008bd67672a1b252390e8b527095c46b46cf6b6725a7a187eb038b6"
44204420 }
44214421 ],
4422 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4423 "acceptedAt": "2026-09-15T15:32:24.222Z"
4422 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4423 "acceptedAt": "2026-09-15T16:01:47.824Z"
44244424 },
44254425 {
44264426 "type": "VERSION_CONFLICT",
……@@ -4434,8 +4434,8 @@
44344434 "tree": "7793645d7d4248d6d6533e3cbcd4bf40bed4f38c678b0ca0606c15640ba5e7b9"
44354435 }
44364436 ],
4437 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4438 "acceptedAt": "2026-09-15T15:32:24.222Z"
4437 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4438 "acceptedAt": "2026-09-15T16:01:47.824Z"
44394439 },
44404440 {
44414441 "type": "VERSION_CONFLICT",
……@@ -4449,8 +4449,8 @@
44494449 "tree": "79447513d4ac0357c8d60bdc7b81b3c5143d761b26700340cba266c4d1cb77b0"
44504450 }
44514451 ],
4452 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4453 "acceptedAt": "2026-09-15T15:32:24.222Z"
4452 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4453 "acceptedAt": "2026-09-15T16:01:47.824Z"
44544454 },
44554455 {
44564456 "type": "VERSION_CONFLICT",
……@@ -4464,8 +4464,8 @@
44644464 "tree": "279d4e0447eb79fd75816864ba7f41f2df03080c9da69ea4603fe2900c8d9e53"
44654465 }
44664466 ],
4467 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4468 "acceptedAt": "2026-09-15T15:32:24.222Z"
4467 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4468 "acceptedAt": "2026-09-15T16:01:47.824Z"
44694469 },
44704470 {
44714471 "type": "VERSION_CONFLICT",
……@@ -4479,8 +4479,8 @@
44794479 "tree": "ed4e0b480417610e195ff0b59e5b9a453abbf2db6d6ce72d7cd522269f835e9a"
44804480 }
44814481 ],
4482 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4483 "acceptedAt": "2026-09-15T15:32:24.222Z"
4482 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4483 "acceptedAt": "2026-09-15T16:01:47.824Z"
44844484 },
44854485 {
44864486 "type": "VERSION_CONFLICT",
……@@ -4499,8 +4499,8 @@
44994499 "tree": "a9e07d54e526c838dfe5e27df33936682aefb218f61a45b6c15289243999f648"
45004500 }
45014501 ],
4502 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4503 "acceptedAt": "2026-09-15T15:32:24.222Z"
4502 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4503 "acceptedAt": "2026-09-15T16:01:47.824Z"
45044504 },
45054505 {
45064506 "type": "VERSION_CONFLICT",
……@@ -4514,8 +4514,8 @@
45144514 "tree": "9d84c86441fe138b227c4fd01d1e948aa83bf8d13cfb1aa957838feea05fbb57"
45154515 }
45164516 ],
4517 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4518 "acceptedAt": "2026-09-15T15:32:24.222Z"
4517 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4518 "acceptedAt": "2026-09-15T16:01:47.824Z"
45194519 },
45204520 {
45214521 "type": "VERSION_CONFLICT",
……@@ -4529,8 +4529,8 @@
45294529 "tree": "4a3afbe2fc7a882e24454eb2e7e7cfe6816811ee5d73ae0f92e8b9ea9cfb8c78"
45304530 }
45314531 ],
4532 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4533 "acceptedAt": "2026-09-15T15:32:24.222Z"
4532 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4533 "acceptedAt": "2026-09-15T16:01:47.824Z"
45344534 },
45354535 {
45364536 "type": "VERSION_CONFLICT",
……@@ -4544,8 +4544,8 @@
45444544 "tree": "1e5c5810d8971a3c27fde7fb0e4d633dcabbe2cf98d8df86b473f8d67eead8b9"
45454545 }
45464546 ],
4547 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4548 "acceptedAt": "2026-09-15T15:32:24.222Z"
4547 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4548 "acceptedAt": "2026-09-15T16:01:47.824Z"
45494549 },
45504550 {
45514551 "type": "VERSION_CONFLICT",
……@@ -4559,8 +4559,8 @@
45594559 "tree": "e3478f50e85ba0ac288efed83e84c992483904897dc39ccf243d20a4ea25d972"
45604560 }
45614561 ],
4562 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4563 "acceptedAt": "2026-09-15T15:32:24.222Z"
4562 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4563 "acceptedAt": "2026-09-15T16:01:47.824Z"
45644564 },
45654565 {
45664566 "type": "VERSION_CONFLICT",
……@@ -4574,8 +4574,8 @@
45744574 "tree": "c05d8bf7eab5024ea98140f78c84d12fb494b4b7b10c7eedeb50b2be842fa519"
45754575 }
45764576 ],
4577 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4578 "acceptedAt": "2026-09-15T15:32:24.222Z"
4577 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4578 "acceptedAt": "2026-09-15T16:01:47.824Z"
45794579 },
45804580 {
45814581 "type": "VERSION_CONFLICT",
……@@ -4589,8 +4589,8 @@
45894589 "tree": "0697bb338bbcec517353cffcdb2345a8232b9b90cc627a549a306f0323576390"
45904590 }
45914591 ],
4592 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4593 "acceptedAt": "2026-09-15T15:32:24.222Z"
4592 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4593 "acceptedAt": "2026-09-15T16:01:47.824Z"
45944594 },
45954595 {
45964596 "type": "VERSION_CONFLICT",
……@@ -4604,8 +4604,8 @@
46044604 "tree": "a366a73e74f8d80f106465058083b62bb70b833c721047124e99c89880e5c706"
46054605 }
46064606 ],
4607 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4608 "acceptedAt": "2026-09-15T15:32:24.222Z"
4607 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4608 "acceptedAt": "2026-09-15T16:01:47.824Z"
46094609 },
46104610 {
46114611 "type": "VERSION_CONFLICT",
……@@ -4619,8 +4619,8 @@
46194619 "tree": "7912e790c9e87e9829a6daa037c5f5da0cc4355214f51d334f96e57678dfddeb"
46204620 }
46214621 ],
4622 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4623 "acceptedAt": "2026-09-15T15:32:24.222Z"
4622 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4623 "acceptedAt": "2026-09-15T16:01:47.824Z"
46244624 },
46254625 {
46264626 "type": "VERSION_CONFLICT",
……@@ -4634,8 +4634,8 @@
46344634 "tree": "003ac841449fcdda1abc3c87fee291a5d9596d245925a7298bd8ef5f8e423eae"
46354635 }
46364636 ],
4637 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4638 "acceptedAt": "2026-09-15T15:32:24.222Z"
4637 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4638 "acceptedAt": "2026-09-15T16:01:47.824Z"
46394639 },
46404640 {
46414641 "type": "VERSION_CONFLICT",
……@@ -4654,8 +4654,8 @@
46544654 "tree": "7b3f314cf92558edbc90295c573885276a6add925318998c829c03d335edc765"
46554655 }
46564656 ],
4657 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4658 "acceptedAt": "2026-09-15T15:32:24.222Z"
4657 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4658 "acceptedAt": "2026-09-15T16:01:47.824Z"
46594659 },
46604660 {
46614661 "type": "VERSION_CONFLICT",
……@@ -4669,8 +4669,8 @@
46694669 "tree": "c486fe73805bf013e9c5de91b5780d1aa5d2b2295306f411f7863757aaa05e60"
46704670 }
46714671 ],
4672 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4673 "acceptedAt": "2026-09-15T15:32:24.222Z"
4672 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4673 "acceptedAt": "2026-09-15T16:01:47.824Z"
46744674 },
46754675 {
46764676 "type": "VERSION_CONFLICT",
……@@ -4684,8 +4684,8 @@
46844684 "tree": "10193a86e2c6f80c2d4377379a0aae4a959f8a40fd9e852b85fee081bfe6675a"
46854685 }
46864686 ],
4687 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4688 "acceptedAt": "2026-09-15T15:32:24.222Z"
4687 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4688 "acceptedAt": "2026-09-15T16:01:47.824Z"
46894689 },
46904690 {
46914691 "type": "VERSION_CONFLICT",
……@@ -4699,8 +4699,8 @@
46994699 "tree": "20b1ecd2937f3e35102892288234b86a8ec6deb3711016d96ff3509474ac465b"
47004700 }
47014701 ],
4702 "reason": "0.10.2 feed: 45 conflicts, all version-splits/docs/packaging, 0 code-differs per pgh's own classification",
4703 "acceptedAt": "2026-09-15T15:32:24.222Z"
4702 "reason": "0.10.3 feed images + interaction visibility; conflicts are the same 45 version-splits/docs/packaging, 0 code-differs",
4703 "acceptedAt": "2026-09-15T16:01:47.824Z"
47044704 }
47054705 ]
47064706}
lib/feed.js +35 -2
……@@ -56,6 +56,30 @@ export function handleOf (actorUri) {
5656// remote server choose this page's layout.
5757const textOf = (html) => String(html == null ? '' : html).replace(/<[^>]*>/g, ' ').replace(/\s+/g, ' ').trim()
5858
59/**
60 * Whose item is this, when nothing on it says so?
61 *
62 * ⛔ FROM THE OBJECT URI, WHICH IS STILL THERE. `/ap/objects/<rkey>` is the primary's flat path and
63 * `/ap/users/<name>/objects/<rkey>` is that user's — the legacy shorthand and the scoped form. Items
64 * stored before `recipient` existed belong to nobody, which is right when nothing can say whose they
65 * were; this reads addressing that was never lost rather than inventing addressing that was.
66 *
67 * ⚠ OUR HOST ONLY. Another server's path structure is not ours to interpret, and a guess there would
68 * put a stranger's interaction on somebody's page.
69 */
70export function recipientFromObject (uri, host) {
71 if (!host || typeof uri !== 'string') return null
72 let u
73 try { u = new URL(uri) } catch { return null }
74 if (u.host !== host) return null
75 const p = u.pathname.split('/').filter(Boolean)
76 // /ap/users/<name>/...
77 if (p[0] === 'ap' && p[1] === 'users' && p[2]) return p[2]
78 // /ap/objects/<rkey> — the primary's, by the same rule that made the bare form its shorthand.
79 if (p[0] === 'ap' && p[1] === 'objects') return '__primary__'
80 return null
81}
82
5983const timeOf = (i) => i.published || (i.receivedAt ? new Date(Number(i.receivedAt)).toISOString() : '')
6084
6185// ⛔ BOUNDED, AND ONLY WHAT CAN BE SHOWN. The list comes from a remote server on the inbound side, so
……@@ -81,7 +105,7 @@ const pickAttachments = (list) => (Array.isArray(list) ? list : [])
81105 * own OUR interactions, from RecordSource.listInteractions()
82106 * recipient which peer's page this is; null means the primary's flat paths
83107 */
84export function buildFeed ({ self = {}, notes = [], inbound = [], own = [], recipient = null } = {}) {
108export function buildFeed ({ self = {}, notes = [], inbound = [], own = [], recipient = null, host = null, isPrimary = true } = {}) {
85109 const rows = []
86110
87111 for (const n of notes || []) {
……@@ -139,7 +163,16 @@ export function buildFeed ({ self = {}, notes = [], inbound = [], own = [], reci
139163 // DM arrives at this inbox through the same handler. `showableStored` widens this for a Like or a
140164 // Follow only, where a stored `false` is the old rule mistaking "no audience" for "not public".
141165 if (!showableStored(i)) continue
142 if (recipient && i.recipient !== recipient) continue
166 if (recipient) {
167 // An item that says whose it is is believed. One that does not is recovered from the object
168 // path, and dropped when that cannot answer either.
169 let owner = i.recipient || null
170 if (!owner) {
171 const derived = recipientFromObject(i.inReplyTo || i.objectId, host)
172 owner = derived === '__primary__' ? (isPrimary ? recipient : null) : derived
173 }
174 if (owner !== recipient) continue
175 }
143176
144177 let kind, verb
145178 if (i.type === 'Create' || i.type === 'Update') {
lib/router.js +5 -1
……@@ -358,7 +358,11 @@ async function feedPage (query, ctx) {
358358 notes,
359359 inbound: inboundItems,
360360 own,
361 recipient
361 recipient,
362 // For recovering an item stored before `recipient` existed: the object URI still says whose it
363 // was, and the bare `/ap/objects/` form is the PRIMARY's — so only the primary may claim one.
364 host: ctx.config.host,
365 isPrimary: !ctx.user || !ctx.users || ctx.users.primary === ctx.user
362366 })
363367
364368 const { publicTimeline } = await import('./public-timeline.js')
package.json +1 -1
……@@ -1,6 +1,6 @@
11{
22 "name": "ap-bridge",
3 "version": "0.10.3",
3 "version": "0.10.4",
44 "description": "ActivityPub membrane \u2014 a second projection of the self-custody atproto peer",
55 "type": "module",
66 "main": "index.js",
test/feed.test.js +30 -0
……@@ -173,3 +173,33 @@ test('⛔ an attachment with no url is dropped, and the count is bounded', (t) =
173173 t.absent(rows[0].attachments.some((a) => !a.url), 'nothing without a url')
174174 t.ok(rows[0].attachments.length <= 8, 'a remote server does not get to decide how tall our page is')
175175})
176
177// ── recovering an unattributed item ───────────────────────────────────────────────────────────────
178//
179// ⛔ THE SCOPE HID THE ONE THING WE WANTED TO SEE. Items stored before `recipient` existed belong to
180// nobody, which is right when nothing can say whose they were. But the OBJECT URI can: `/ap/objects/x`
181// is the primary's flat path and `/ap/users/<name>/objects/x` is that user's. Reading it is recovering
182// addressing that is still present, not guessing at addressing that was lost.
183
184test('★★ an unattributed item is recovered from the object path when it names our host', (t) => {
185 const rows = buildFeed({
186 self: {}, recipient: 'p2p', host: 'ap.7rnx.net',
187 inbound: [{ id: 'l', type: 'Like', actor: 'https://prsm.space/users/fleeky', objectId: 'https://ap.7rnx.net/ap/objects/3mvks7khp3u6w', public: false, published: '2026-09-14T00:00:00Z' }]
188 })
189 t.is(rows.length, 1, 'the flat object path is the primary, so this is the primary\'s')
190 t.is(rows[0].verb, 'liked your post')
191})
192
193test('★★ and it goes to the RIGHT user, not just the primary', (t) => {
194 const item = { id: 'l', type: 'Like', actor: 'https://prsm.space/users/x', objectId: 'https://ap.7rnx.net/ap/users/ashatron/objects/9', public: false, published: '2026-09-14T00:00:00Z' }
195 t.is(buildFeed({ self: {}, recipient: 'ashatron', host: 'ap.7rnx.net', inbound: [item] }).length, 1, "ashatron's")
196 t.is(buildFeed({ self: {}, recipient: 'p2p', host: 'ap.7rnx.net', inbound: [item] }).length, 0, 'and not the primary\'s')
197})
198
199test('⛔ an object on somebody else\'s host recovers nothing and stays unattributed', (t) => {
200 const rows = buildFeed({
201 self: {}, recipient: 'p2p', host: 'ap.7rnx.net',
202 inbound: [{ id: 'l', type: 'Like', actor: 'https://m.example/users/x', objectId: 'https://elsewhere.net/ap/objects/1', public: true, published: 'z' }]
203 })
204 t.is(rows.length, 0, 'we cannot read another server\'s paths, and will not pretend to')
205})