OverviewFilesCommitsIssuesDocsReleasesPeers

favela-bridge commits / 5416a2d

0.0.5: one copy of the peer client, and a default bsky sink
lib/peer.js was a second FavelaPeer implementation. ap-bridge needs the same reader to project favela records onto the fediverse, and a protocol client written twice drifts — this monorepo already carries six copies of one signing format, three of which eat the first character of a hash. It re-exports favela-identity's client now. The fail-closed reach() semantics are preserved by that client verbatim: a peer that cannot be asked yields { networks: [], unknown: true }, and the caller publishes nothing. Unknown consent is not consent, and this refactor was only safe because the shared client already had that property. BSKY_SOCK now defaults to hyper-proto-peer's control socket rather than null, which is where it always is on a host that runs one. Both tabertron and ashatron do. This was published and running on ashatron while uncommitted (hyper-social #66 §8.7). 17/17 tests pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
5416a2d40511c57581aca2cb4b07bfdfc5cffa76
by plankatron <fleeky@gmail.com> · 2026-09-09T21:52:12.000Z

Changed files (3) +159 -220

.pgh-lock.json +151 -136
……@@ -1,9 +1,9 @@
11{
22 "name": "favela-bridge",
3 "version": "0.0.2",
3 "version": "0.0.5",
44 "runtime": "bare",
5 "rootTreeHash": "664a0b81dd1e0e768f4182d9717c21bc5fed2f2d7223ea24cbd836c9e07d37df",
6 "publishedAt": "2026-09-08T01:01:45.792Z",
5 "rootTreeHash": "da2414349c19c0b60a4b6b82437320ea09caf5336a99c2ed766396ba8a585a3d",
6 "publishedAt": "2026-09-08T14:54:42.050Z",
77 "deps": [
88 {
99 "name": "atproto-store",
……@@ -98,9 +98,9 @@
9898 },
9999 {
100100 "name": "atproto-identity",
101 "version": "0.0.3",
102 "tree": "38f44af48b2d59b46f1b5db31b81d02f3ca8b8bad6bc0fb9fffff698241f5e37",
103 "normHash": "7fe50ec4bd511c4cceb5c3546534b1bb70903a8d999bcc85491d5b6220573abb",
101 "version": "0.0.4",
102 "tree": "4622ac9e189974583e9a16be390684676a5add245bd12d1715df940c7f9ea581",
103 "normHash": "5ac384671b39b5239043d9fed8e7b15dd032bd7b5a1246693dc1cf4409018a3e",
104104 "workspace": true
105105 },
106106 {
……@@ -1464,11 +1464,54 @@
14641464 "normHash": "4a14c82328c2df4d7d3f148d0bda5307d6ca1f9cb2d868d2464c4df06d9c6084",
14651465 "workspace": false
14661466 },
1467 {
1468 "name": "favela-identity",
1469 "version": "0.0.2",
1470 "tree": "7b3f314cf92558edbc90295c573885276a6add925318998c829c03d335edc765",
1471 "normHash": "764cabc80c7ebc250bf01507b94d7e0960fa26958305cae299a326913d716d5f",
1472 "workspace": true
1473 },
1474 {
1475 "name": "bare-fs",
1476 "version": "4.8.1",
1477 "tree": "3358c77ab49da8137602bca8d21e56bb0d90916a237250446d6ee7724d8b949e",
1478 "normHash": "f2b3a7815e91cca809e21c0056fb8c8f23c8ae5359aa0548f9b2f9d088b5378a",
1479 "workspace": false,
1480 "prebuilds": {
1481 "android-arm": "7c40adac563349c0985faf3a4d04f682877cf1ee2157be4cbe33baa317f2240f",
1482 "android-arm64": "58c24ee16452872806e837165aea4d563a9820a0e2ec566c19c4278e6e86245a",
1483 "android-ia32": "b92787572da0e5e4b3c76385eb0ca1766e849d4867981f3e5fa111673bca01ab",
1484 "android-x64": "3a8a79f9a33276c60c398e74691d1bcb19aa735efe3452608d4ef58a0a52e984",
1485 "darwin-arm64": "fc1c732873133a96325ff9a10b14a21fdcde5c1549a7e3175b81d28df3359c05",
1486 "darwin-x64": "388ecda9cdcb7b47460e21e2e9a546a583d279524cc02742c237a5a6579bab4c",
1487 "ios-arm64": "8d2351468c563a4d72c540d7be8a2e073375cb2614592be4a9362adc8dc50fdc",
1488 "ios-arm64-simulator": "29544890b0a934ed046d1864364447db228fa5585d5177d7fa9c355424f40c3d",
1489 "ios-x64-simulator": "0e7a0998e5bc78652d8e81578370fb8c7b0e367d8afd1e193a0e2c27ad13aa9b",
1490 "linux-arm64": "53394a0d1ece29f56ba630b838703fc92143859eb627f4f87b8eea2e3e3b2413",
1491 "linux-x64": "3521543382b3c7ac9e78cfd320def125162feb9fdabd3b2247e84033c5051e25",
1492 "win32-arm64": "9c87bd9ea1a923d6ca343f1f5a4cc1834103819710dcc4015096b5863b7d3738",
1493 "win32-x64": "9fc8d764c50165a654be9106514b09d5315e3dff87f00b3c09a3d03cf7b4e478"
1494 }
1495 },
1496 {
1497 "name": "brittle",
1498 "version": "4.1.1",
1499 "tree": "f45e18462b3c2a114bcba356f66bbeee1bbda2e5d912b3703a04b18398855877",
1500 "normHash": "532a238eeb5179255f945a4bf5b272dce3ad0f70f8938642583075c8ddf16b8c",
1501 "workspace": false
1502 },
1503 {
1504 "name": "compact-encoding",
1505 "version": "3.4.0",
1506 "tree": "7579a2d3581169529b52ec241bf982d2d0c1b2fe24f8b64873baed5e3595436f",
1507 "normHash": "eb94371b126a45f1412d386131f80530c95dbaac304bd2b0441ec5b2d5094b5a",
1508 "workspace": false
1509 },
14671510 {
14681511 "name": "favela-markdown",
1469 "version": "0.1.4",
1470 "tree": "e303eceac5fcb441423d31d16fd57d096491c8133d7b3b09d5979817a831e39a",
1471 "normHash": "efb446f13654a3b5c5271ce6c07ea60db76309018e12a630f03e8829965df6c7",
1512 "version": "0.1.6",
1513 "tree": "97d64cb2674377910d3ec28f3f4246d7e3fbc1b9b06b8b9d1ef6360cc0765569",
1514 "normHash": "853f6fe2c24cea0c956653eaa7d5a13b7feca966cad5c9a6164c2dc1ff324881",
14721515 "workspace": true
14731516 },
14741517 {
……@@ -1506,28 +1549,6 @@
15061549 "normHash": "a4dd692467e2e42d1e6d6a264a4f432d55afcba33063c50076d98e68659e892f",
15071550 "workspace": false
15081551 },
1509 {
1510 "name": "bare-fs",
1511 "version": "4.8.1",
1512 "tree": "3358c77ab49da8137602bca8d21e56bb0d90916a237250446d6ee7724d8b949e",
1513 "normHash": "f2b3a7815e91cca809e21c0056fb8c8f23c8ae5359aa0548f9b2f9d088b5378a",
1514 "workspace": false,
1515 "prebuilds": {
1516 "android-arm": "7c40adac563349c0985faf3a4d04f682877cf1ee2157be4cbe33baa317f2240f",
1517 "android-arm64": "58c24ee16452872806e837165aea4d563a9820a0e2ec566c19c4278e6e86245a",
1518 "android-ia32": "b92787572da0e5e4b3c76385eb0ca1766e849d4867981f3e5fa111673bca01ab",
1519 "android-x64": "3a8a79f9a33276c60c398e74691d1bcb19aa735efe3452608d4ef58a0a52e984",
1520 "darwin-arm64": "fc1c732873133a96325ff9a10b14a21fdcde5c1549a7e3175b81d28df3359c05",
1521 "darwin-x64": "388ecda9cdcb7b47460e21e2e9a546a583d279524cc02742c237a5a6579bab4c",
1522 "ios-arm64": "8d2351468c563a4d72c540d7be8a2e073375cb2614592be4a9362adc8dc50fdc",
1523 "ios-arm64-simulator": "29544890b0a934ed046d1864364447db228fa5585d5177d7fa9c355424f40c3d",
1524 "ios-x64-simulator": "0e7a0998e5bc78652d8e81578370fb8c7b0e367d8afd1e193a0e2c27ad13aa9b",
1525 "linux-arm64": "53394a0d1ece29f56ba630b838703fc92143859eb627f4f87b8eea2e3e3b2413",
1526 "linux-x64": "3521543382b3c7ac9e78cfd320def125162feb9fdabd3b2247e84033c5051e25",
1527 "win32-arm64": "9c87bd9ea1a923d6ca343f1f5a4cc1834103819710dcc4015096b5863b7d3738",
1528 "win32-x64": "9fc8d764c50165a654be9106514b09d5315e3dff87f00b3c09a3d03cf7b4e478"
1529 }
1530 },
15311552 {
15321553 "name": "bare-stream",
15331554 "version": "2.13.4",
……@@ -2964,34 +2985,38 @@
29642985 "tree": "b6396de092d11e559d109b0dea7995f340b7959c4efeb0baa06b091f99a43245"
29652986 }
29662987 ],
2967 "reason": "0.0.2 bare runtime + watch daemon",
2968 "acceptedAt": "2026-09-08T01:01:45.825Z"
2988 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
2989 "acceptedAt": "2026-09-08T14:54:42.064Z"
29692990 },
29702991 {
2971 "type": "BUILD_SKEW",
2992 "type": "VERSION_CONFLICT",
29722993 "dep": "atproto-identity",
2973 "newVersion": "0.0.3",
2974 "newTree": "38f44af48b2d59b46f1b5db31b81d02f3ca8b8bad6bc0fb9fffff698241f5e37",
2994 "newVersion": "0.0.4",
2995 "newTree": "4622ac9e189974583e9a16be390684676a5add245bd12d1715df940c7f9ea581",
29752996 "existing": [
29762997 {
29772998 "appName": "ap-bridge",
29782999 "version": "0.0.3",
2979 "tree": "a8cce432de1374051f5481059bbfc264b5eec47471a24faf9fbb0241625fa2b5"
3000 "tree": "38f44af48b2d59b46f1b5db31b81d02f3ca8b8bad6bc0fb9fffff698241f5e37"
29803001 },
29813002 {
29823003 "appName": "atproto-bridge",
29833004 "version": "0.0.3",
29843005 "tree": "a8cce432de1374051f5481059bbfc264b5eec47471a24faf9fbb0241625fa2b5"
29853006 },
3007 {
3008 "appName": "favela-web",
3009 "version": "0.0.3",
3010 "tree": "38f44af48b2d59b46f1b5db31b81d02f3ca8b8bad6bc0fb9fffff698241f5e37"
3011 },
29863012 {
29873013 "appName": "hyper-proto-peer",
29883014 "version": "0.0.3",
29893015 "tree": "1aa7863120ed4d861c4ba8230a8ba551d94d0a922e691697ff7ac77ec9ec7f9a"
29903016 }
29913017 ],
2992 "verdict": "code-differs",
2993 "reason": "0.0.2 bare runtime + watch daemon",
2994 "acceptedAt": "2026-09-08T01:01:45.825Z"
3018 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3019 "acceptedAt": "2026-09-08T14:54:42.064Z"
29953020 },
29963021 {
29973022 "type": "VERSION_CONFLICT",
……@@ -3005,8 +3030,8 @@
30053030 "tree": "6b8b5a11a8be2dd0ea1fb34391d0ca0b8f711c52776588382767f305433c68c4"
30063031 }
30073032 ],
3008 "reason": "0.0.2 bare runtime + watch daemon",
3009 "acceptedAt": "2026-09-08T01:01:45.825Z"
3033 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3034 "acceptedAt": "2026-09-08T14:54:42.064Z"
30103035 },
30113036 {
30123037 "type": "VERSION_CONFLICT",
……@@ -3025,8 +3050,8 @@
30253050 "tree": "5b662871145437a17e36c1dbebd64fc6e29be649b168ffb7638d3c5eaa781443"
30263051 }
30273052 ],
3028 "reason": "0.0.2 bare runtime + watch daemon",
3029 "acceptedAt": "2026-09-08T01:01:45.825Z"
3053 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3054 "acceptedAt": "2026-09-08T14:54:42.064Z"
30303055 },
30313056 {
30323057 "type": "VERSION_CONFLICT",
……@@ -3040,8 +3065,8 @@
30403065 "tree": "58c0bf8698af19464d0ee8354a77ed1ac96d3a5fa18aa4e794686cfbbf080e5d"
30413066 }
30423067 ],
3043 "reason": "0.0.2 bare runtime + watch daemon",
3044 "acceptedAt": "2026-09-08T01:01:45.825Z"
3068 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3069 "acceptedAt": "2026-09-08T14:54:42.064Z"
30453070 },
30463071 {
30473072 "type": "VERSION_CONFLICT",
……@@ -3055,8 +3080,8 @@
30553080 "tree": "a49b9c4ace4ade9435e530c82694bf39e10e0176475ae6b4270dec913bf6c5ef"
30563081 }
30573082 ],
3058 "reason": "0.0.2 bare runtime + watch daemon",
3059 "acceptedAt": "2026-09-08T01:01:45.825Z"
3083 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3084 "acceptedAt": "2026-09-08T14:54:42.064Z"
30603085 },
30613086 {
30623087 "type": "VERSION_CONFLICT",
……@@ -3070,8 +3095,8 @@
30703095 "tree": "6260923011112545fcd768b1c2013d6d3467277913acb90b11404fefd4ddab44"
30713096 }
30723097 ],
3073 "reason": "0.0.2 bare runtime + watch daemon",
3074 "acceptedAt": "2026-09-08T01:01:45.825Z"
3098 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3099 "acceptedAt": "2026-09-08T14:54:42.064Z"
30753100 },
30763101 {
30773102 "type": "VERSION_CONFLICT",
……@@ -3085,8 +3110,8 @@
30853110 "tree": "623bbbece48d0415c906980604a2d46515e0a7b1aeb63516eae5ceb981a27bdd"
30863111 }
30873112 ],
3088 "reason": "0.0.2 bare runtime + watch daemon",
3089 "acceptedAt": "2026-09-08T01:01:45.825Z"
3113 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3114 "acceptedAt": "2026-09-08T14:54:42.064Z"
30903115 },
30913116 {
30923117 "type": "VERSION_CONFLICT",
……@@ -3100,8 +3125,8 @@
31003125 "tree": "e6991084a57472974a7f19d371cdfa226c28bd92be2d3b5a7ba38eabba8b3bb5"
31013126 }
31023127 ],
3103 "reason": "0.0.2 bare runtime + watch daemon",
3104 "acceptedAt": "2026-09-08T01:01:45.825Z"
3128 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3129 "acceptedAt": "2026-09-08T14:54:42.064Z"
31053130 },
31063131 {
31073132 "type": "VERSION_CONFLICT",
……@@ -3115,8 +3140,8 @@
31153140 "tree": "ad81cb00dc100cbacbe692462fefc6cd1d676e4b6022e3b9fa2d9294a4461aac"
31163141 }
31173142 ],
3118 "reason": "0.0.2 bare runtime + watch daemon",
3119 "acceptedAt": "2026-09-08T01:01:45.825Z"
3143 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3144 "acceptedAt": "2026-09-08T14:54:42.064Z"
31203145 },
31213146 {
31223147 "type": "VERSION_CONFLICT",
……@@ -3130,8 +3155,8 @@
31303155 "tree": "5e9cf8230c28d6b667d121cb23a5202b5d5d44e12dbeef0a7d6fbcc55621bb3d"
31313156 }
31323157 ],
3133 "reason": "0.0.2 bare runtime + watch daemon",
3134 "acceptedAt": "2026-09-08T01:01:45.825Z"
3158 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3159 "acceptedAt": "2026-09-08T14:54:42.064Z"
31353160 },
31363161 {
31373162 "type": "VERSION_CONFLICT",
……@@ -3145,8 +3170,8 @@
31453170 "tree": "f43421419fb851f1bf8fd6f284e23d9f8b5ff2bcb320ac71dcf420b261dc7264"
31463171 }
31473172 ],
3148 "reason": "0.0.2 bare runtime + watch daemon",
3149 "acceptedAt": "2026-09-08T01:01:45.825Z"
3173 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3174 "acceptedAt": "2026-09-08T14:54:42.064Z"
31503175 },
31513176 {
31523177 "type": "VERSION_CONFLICT",
……@@ -3160,8 +3185,8 @@
31603185 "tree": "196ef311029d1ff5524e5c763f050d67c2db3e6c026a3b2c7262ff922f52c487"
31613186 }
31623187 ],
3163 "reason": "0.0.2 bare runtime + watch daemon",
3164 "acceptedAt": "2026-09-08T01:01:45.825Z"
3188 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3189 "acceptedAt": "2026-09-08T14:54:42.064Z"
31653190 },
31663191 {
31673192 "type": "VERSION_CONFLICT",
……@@ -3175,8 +3200,8 @@
31753200 "tree": "9386fa8b9509fda8b231ae9fd0d7672da1eab57959333e06ee29ba583e60bb5b"
31763201 }
31773202 ],
3178 "reason": "0.0.2 bare runtime + watch daemon",
3179 "acceptedAt": "2026-09-08T01:01:45.825Z"
3203 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3204 "acceptedAt": "2026-09-08T14:54:42.064Z"
31803205 },
31813206 {
31823207 "type": "VERSION_CONFLICT",
……@@ -3190,8 +3215,8 @@
31903215 "tree": "08013f3f76e93f236b04c5a804dfd12debdc44bc2b5a5a5010f190f96ad682ec"
31913216 }
31923217 ],
3193 "reason": "0.0.2 bare runtime + watch daemon",
3194 "acceptedAt": "2026-09-08T01:01:45.825Z"
3218 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3219 "acceptedAt": "2026-09-08T14:54:42.064Z"
31953220 },
31963221 {
31973222 "type": "VERSION_CONFLICT",
……@@ -3205,8 +3230,8 @@
32053230 "tree": "336bf1b134f4534c20b04e224211a4eda1dfb700abd3f8626fd08036d9df7b84"
32063231 }
32073232 ],
3208 "reason": "0.0.2 bare runtime + watch daemon",
3209 "acceptedAt": "2026-09-08T01:01:45.825Z"
3233 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3234 "acceptedAt": "2026-09-08T14:54:42.064Z"
32103235 },
32113236 {
32123237 "type": "VERSION_CONFLICT",
……@@ -3220,8 +3245,8 @@
32203245 "tree": "3dde067fd3ec455f2aafa0afda7cdfab8f96d439bb5cc4e221997909a755bb7d"
32213246 }
32223247 ],
3223 "reason": "0.0.2 bare runtime + watch daemon",
3224 "acceptedAt": "2026-09-08T01:01:45.825Z"
3248 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3249 "acceptedAt": "2026-09-08T14:54:42.064Z"
32253250 },
32263251 {
32273252 "type": "VERSION_CONFLICT",
……@@ -3245,8 +3270,8 @@
32453270 "tree": "bdebba5a532ce4846b49f1e5ffad774becfc44182d0c3737f7e441ab42f4c43d"
32463271 }
32473272 ],
3248 "reason": "0.0.2 bare runtime + watch daemon",
3249 "acceptedAt": "2026-09-08T01:01:45.825Z"
3273 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3274 "acceptedAt": "2026-09-08T14:54:42.064Z"
32503275 },
32513276 {
32523277 "type": "VERSION_CONFLICT",
……@@ -3265,8 +3290,8 @@
32653290 "tree": "d31788ffa334976153023c6de84e5020b2009f51f9d472d0c2f09a13a53fc2b6"
32663291 }
32673292 ],
3268 "reason": "0.0.2 bare runtime + watch daemon",
3269 "acceptedAt": "2026-09-08T01:01:45.825Z"
3293 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3294 "acceptedAt": "2026-09-08T14:54:42.064Z"
32703295 },
32713296 {
32723297 "type": "VERSION_CONFLICT",
……@@ -3280,8 +3305,8 @@
32803305 "tree": "6d6f0aff7bfff8b3693ddd00349d7aa296cfa35adc9abb0865fba66828814db5"
32813306 }
32823307 ],
3283 "reason": "0.0.2 bare runtime + watch daemon",
3284 "acceptedAt": "2026-09-08T01:01:45.825Z"
3308 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3309 "acceptedAt": "2026-09-08T14:54:42.064Z"
32853310 },
32863311 {
32873312 "type": "VERSION_CONFLICT",
……@@ -3295,8 +3320,8 @@
32953320 "tree": "e693499377f146eec5788fa2887c4e42614f7f2efd3d5848d9019deec86c6632"
32963321 }
32973322 ],
3298 "reason": "0.0.2 bare runtime + watch daemon",
3299 "acceptedAt": "2026-09-08T01:01:45.825Z"
3323 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3324 "acceptedAt": "2026-09-08T14:54:42.064Z"
33003325 },
33013326 {
33023327 "type": "VERSION_CONFLICT",
……@@ -3310,8 +3335,8 @@
33103335 "tree": "d99fbe108f5700f5e73d908e2d3d39ed44021b11bc74e1f152ebb493719b9eaa"
33113336 }
33123337 ],
3313 "reason": "0.0.2 bare runtime + watch daemon",
3314 "acceptedAt": "2026-09-08T01:01:45.825Z"
3338 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3339 "acceptedAt": "2026-09-08T14:54:42.064Z"
33153340 },
33163341 {
33173342 "type": "VERSION_CONFLICT",
……@@ -3325,8 +3350,8 @@
33253350 "tree": "4664a97e951dbbfc25e868cbdbec870de2682812c1c19fe7f6d3daf2fe33446a"
33263351 }
33273352 ],
3328 "reason": "0.0.2 bare runtime + watch daemon",
3329 "acceptedAt": "2026-09-08T01:01:45.825Z"
3353 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3354 "acceptedAt": "2026-09-08T14:54:42.064Z"
33303355 },
33313356 {
33323357 "type": "VERSION_CONFLICT",
……@@ -3345,8 +3370,8 @@
33453370 "tree": "4db5ae5fc0ad8552270405cd87877ac18d796bf082a05cb55e03a158af622290"
33463371 }
33473372 ],
3348 "reason": "0.0.2 bare runtime + watch daemon",
3349 "acceptedAt": "2026-09-08T01:01:45.825Z"
3373 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3374 "acceptedAt": "2026-09-08T14:54:42.064Z"
33503375 },
33513376 {
33523377 "type": "VERSION_CONFLICT",
……@@ -3360,8 +3385,8 @@
33603385 "tree": "91b555116e75b7bc6309063652b2de61264901fb1e9a0326886bf355acd0acd8"
33613386 }
33623387 ],
3363 "reason": "0.0.2 bare runtime + watch daemon",
3364 "acceptedAt": "2026-09-08T01:01:45.825Z"
3388 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3389 "acceptedAt": "2026-09-08T14:54:42.064Z"
33653390 },
33663391 {
33673392 "type": "VERSION_CONFLICT",
……@@ -3375,38 +3400,8 @@
33753400 "tree": "9c22db1f4e3137df4e44ba33887b65ce280bfc93454f8b91d2e41b458452e86b"
33763401 }
33773402 ],
3378 "reason": "0.0.2 bare runtime + watch daemon",
3379 "acceptedAt": "2026-09-08T01:01:45.825Z"
3380 },
3381 {
3382 "type": "VERSION_CONFLICT",
3383 "dep": "brittle",
3384 "newVersion": "4.0.2",
3385 "newTree": "027801001ac7f56c3fa5880ab3bea6d5ea9e44f805c52a5488c677b4dc4e0782",
3386 "existing": [
3387 {
3388 "appName": "favela-surface",
3389 "version": "4.1.1",
3390 "tree": "f45e18462b3c2a114bcba356f66bbeee1bbda2e5d912b3703a04b18398855877"
3391 }
3392 ],
3393 "reason": "0.0.2 bare runtime + watch daemon",
3394 "acceptedAt": "2026-09-08T01:01:45.825Z"
3395 },
3396 {
3397 "type": "VERSION_CONFLICT",
3398 "dep": "compact-encoding",
3399 "newVersion": "3.3.0",
3400 "newTree": "754944ca8ff184c8bdc55a8db26d1c1fcaf8f0fa855fd6779b3eb8c3ca3ec9e4",
3401 "existing": [
3402 {
3403 "appName": "favela-surface",
3404 "version": "3.4.0",
3405 "tree": "7579a2d3581169529b52ec241bf982d2d0c1b2fe24f8b64873baed5e3595436f"
3406 }
3407 ],
3408 "reason": "0.0.2 bare runtime + watch daemon",
3409 "acceptedAt": "2026-09-08T01:01:45.825Z"
3403 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3404 "acceptedAt": "2026-09-08T14:54:42.064Z"
34103405 },
34113406 {
34123407 "type": "VERSION_CONFLICT",
……@@ -3420,8 +3415,8 @@
34203415 "tree": "d7176ab113d79ab81c4a811285dcaca3948b5c822aac38968594d55904c0f243"
34213416 }
34223417 ],
3423 "reason": "0.0.2 bare runtime + watch daemon",
3424 "acceptedAt": "2026-09-08T01:01:45.825Z"
3418 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3419 "acceptedAt": "2026-09-08T14:54:42.064Z"
34253420 },
34263421 {
34273422 "type": "VERSION_CONFLICT",
……@@ -3435,8 +3430,8 @@
34353430 "tree": "4d8d5a7eb968560e887d7c9d097a5326b281b67b04e69a5e6b34514985e861ae"
34363431 }
34373432 ],
3438 "reason": "0.0.2 bare runtime + watch daemon",
3439 "acceptedAt": "2026-09-08T01:01:45.825Z"
3433 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3434 "acceptedAt": "2026-09-08T14:54:42.064Z"
34403435 },
34413436 {
34423437 "type": "VERSION_CONFLICT",
……@@ -3450,8 +3445,8 @@
34503445 "tree": "7236258ca920c2f9853c24ead4286ec92a5f709fdf0117f38257e9702752d3ce"
34513446 }
34523447 ],
3453 "reason": "0.0.2 bare runtime + watch daemon",
3454 "acceptedAt": "2026-09-08T01:01:45.825Z"
3448 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3449 "acceptedAt": "2026-09-08T14:54:42.064Z"
34553450 },
34563451 {
34573452 "type": "VERSION_CONFLICT",
……@@ -3465,8 +3460,8 @@
34653460 "tree": "955c2e26f31af120554761af5ea65e6773648f137083594bb888429432200344"
34663461 }
34673462 ],
3468 "reason": "0.0.2 bare runtime + watch daemon",
3469 "acceptedAt": "2026-09-08T01:01:45.825Z"
3463 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3464 "acceptedAt": "2026-09-08T14:54:42.064Z"
34703465 },
34713466 {
34723467 "type": "VERSION_CONFLICT",
……@@ -3480,8 +3475,8 @@
34803475 "tree": "a8699972843ff0e9e0b134447b71b055bbd8acd4a6ea3187624a7a52931ce10e"
34813476 }
34823477 ],
3483 "reason": "0.0.2 bare runtime + watch daemon",
3484 "acceptedAt": "2026-09-08T01:01:45.825Z"
3478 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3479 "acceptedAt": "2026-09-08T14:54:42.064Z"
34853480 },
34863481 {
34873482 "type": "VERSION_CONFLICT",
……@@ -3495,8 +3490,8 @@
34953490 "tree": "46b1c3d46b4bf7703f0baf537ffbb80489394e28737a5c2e1641ca94ac115c4c"
34963491 }
34973492 ],
3498 "reason": "0.0.2 bare runtime + watch daemon",
3499 "acceptedAt": "2026-09-08T01:01:45.825Z"
3493 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3494 "acceptedAt": "2026-09-08T14:54:42.064Z"
35003495 },
35013496 {
35023497 "type": "VERSION_CONFLICT",
……@@ -3510,8 +3505,28 @@
35103505 "tree": "db9a29b3a3c27cca5ad561f21995e04945465c98d438579beff71e029e662776"
35113506 }
35123507 ],
3513 "reason": "0.0.2 bare runtime + watch daemon",
3514 "acceptedAt": "2026-09-08T01:01:45.825Z"
3508 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3509 "acceptedAt": "2026-09-08T14:54:42.064Z"
3510 },
3511 {
3512 "type": "VERSION_CONFLICT",
3513 "dep": "favela-markdown",
3514 "newVersion": "0.1.6",
3515 "newTree": "97d64cb2674377910d3ec28f3f4246d7e3fbc1b9b06b8b9d1ef6360cc0765569",
3516 "existing": [
3517 {
3518 "appName": "ap-bridge",
3519 "version": "0.1.4",
3520 "tree": "e303eceac5fcb441423d31d16fd57d096491c8133d7b3b09d5979817a831e39a"
3521 },
3522 {
3523 "appName": "favela-peer",
3524 "version": "0.1.4",
3525 "tree": "e303eceac5fcb441423d31d16fd57d096491c8133d7b3b09d5979817a831e39a"
3526 }
3527 ],
3528 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3529 "acceptedAt": "2026-09-08T14:54:42.064Z"
35153530 },
35163531 {
35173532 "type": "VERSION_CONFLICT",
……@@ -3525,8 +3540,8 @@
35253540 "tree": "e92100a4f821a638ac99c1407e4c7e784f8eb9661e6d9119ecbec4faae77cc7e"
35263541 }
35273542 ],
3528 "reason": "0.0.2 bare runtime + watch daemon",
3529 "acceptedAt": "2026-09-08T01:01:45.825Z"
3543 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3544 "acceptedAt": "2026-09-08T14:54:42.064Z"
35303545 },
35313546 {
35323547 "type": "VERSION_CONFLICT",
……@@ -3545,8 +3560,8 @@
35453560 "tree": "f4e87130e4397b037b121356f2db0161fadd8f2c320f7042fa31f4b5308193ec"
35463561 }
35473562 ],
3548 "reason": "0.0.2 bare runtime + watch daemon",
3549 "acceptedAt": "2026-09-08T01:01:45.825Z"
3563 "reason": "version-splits only: dry-run reports 0 code-differs, 0 unclassified after atproto-identity 0.0.4",
3564 "acceptedAt": "2026-09-08T14:54:42.064Z"
35503565 }
35513566 ]
35523567}
index.js +2 -1
……@@ -33,7 +33,8 @@ const SEND = argv.includes('--send')
3333const WATCH = argv.includes('--watch')
3434const EVERY = Math.max(5, Number(process.env.FAVELA_BRIDGE_INTERVAL || 15)) * 1000
3535const PEER_SOCK = process.env.FAVELA_PEER_SOCKET || join(os.homedir(), '.config', 'favela-peer', 'favela.sock')
36const BSKY_SOCK = process.env.FAVELA_BSKY_SOCKET || null
36const BSKY_SOCK = process.env.FAVELA_BSKY_SOCKET ||
37 join(os.homedir(), '.config', 'hyper-proto-peer', 'data', 'control.sock')
3738
3839// ⚠ v1 assumes the node's own feed is a PUBLIC one-writer room. identity.md §7.6: "a personal feed
3940// is a one-writer room". That assumption is stated here rather than buried, because it is the input
lib/peer.js +6 -83
……@@ -1,84 +1,7 @@
1// The source: favela-peer, read over its local unix socket.
1// Re-exported from `favela-identity`, which is where the client lives now.
22//
3// ⛔ READ ONLY, AND PULL. The peer is never asked to push and never told a bridge exists — that is
4// the boundary its own test enforces (`favela-peer/test/boundary.test.js`, hyper-social #61 §10):
5// "the moment the daemon imports the projection the dependency has been inverted". So this reaches
6// in, takes records in favela's own vocabulary, and the peer stays ignorant of what happens next.
7//
8// It is also the shape every other bridge here already uses — ap-bridge's records.js: "replicate the
9// peer's cores over Hyperswarm, read records, project. No key involved." This does the same over a
10// socket instead of the swarm, because for a co-located bridge a DHT rendezvous buys nothing.
11//
12// ⚠ Its wire format is newline-delimited JSON, `{id, cmd, args}` → `{id, ok, value|error}`, NOT
13// hyper-svc. The two daemons in this path speak different protocols and that is not worth papering
14// over: favela-peer's is deliberately the smallest thing that works (its rpc.js says so).
15
16import net from 'bare-net'
17
18export class FavelaPeer {
19 constructor (sock) {
20 if (!sock) throw new Error('FavelaPeer: a socket path is required')
21 this.sock = sock
22 }
23
24 /** One request, one connection. There is no session to keep and no benefit to holding one open. */
25 call (cmd, args = {}) {
26 return new Promise((resolve, reject) => {
27 const c = net.connect(this.sock)
28 let buf = ''
29 let done = false
30 const finish = (fn, v) => { if (!done) { done = true; try { c.destroy() } catch {} ; fn(v) } }
31 c.on('error', (err) => finish(reject, err))
32 c.on('connect', () => c.write(JSON.stringify({ id: 1, cmd, args }) + '\n'))
33 c.on('data', (d) => {
34 buf += d
35 const i = buf.indexOf('\n')
36 if (i < 0) return
37 let r
38 try { r = JSON.parse(buf.slice(0, i)) } catch (err) { return finish(reject, err) }
39 if (r.ok) finish(resolve, r.value)
40 else finish(reject, new Error(r.error || 'favela-peer refused ' + cmd))
41 })
42 // ⚠ A peer that accepts the connection and never answers would hang the bridge for ever.
43 setTimeout(() => finish(reject, new Error('favela-peer timed out on ' + cmd)), 30000)
44 })
45 }
46
47 async whoami () { return this.call('whoami') }
48
49 /**
50 * Which networks this identity has turned on, from the peer's own feed.
51 *
52 * ⛔ READ EVERY CYCLE, never cached. A person who unticks bsky in settings has withdrawn consent
53 * to publish, and a bridge holding a stale copy would keep publishing until someone restarted it.
54 *
55 * ⛔ AND A FAILURE READS AS OFF. If the peer cannot be asked, the answer is not "carry on with
56 * what we had" — it is publish nothing. Unknown consent is not consent.
57 */
58 async reach () {
59 try {
60 const r = await this.call('reach')
61 return {
62 networks: Array.isArray(r && r.networks) ? r.networks : [],
63 credential: (r && r.credential) || null
64 }
65 } catch {
66 return { networks: [], credential: null, unknown: true }
67 }
68 }
69
70 /**
71 * This node's own posts, newest last.
72 *
73 * ⚠ OUR OWN ONLY. A bridge projects what its identity wrote; forwarding a followed feed's posts
74 * under our DID would be republishing someone else's words as ours, which is a different act with
75 * a different name and is not this.
76 */
77 async ownPosts () {
78 const me = await this.whoami()
79 const rows = await this.call('posts-by', { feed: me.feed })
80 return { feed: me.feed, rows: Array.isArray(rows) ? rows : [] }
81 }
82}
83
84export default { FavelaPeer }
3// ⛔ ONE COPY OF THE WIRE FORMAT. ap-bridge needs the same reader to project favela records onto the
4// fediverse, and a protocol client written twice drifts — this monorepo already carries six copies
5// of one signing format, three of which eat the first character of a hash.
6export { FavelaPeer } from 'favela-identity/lib/peer-client.js'
7export { default } from 'favela-identity/lib/peer-client.js'