A Ruling Before the Move
On 2026-10-19 a design note about running the family from somewhere other than its usual machines listed eight places that could not be redirected from outside: addresses written as constants, a data root derived from a home folder, guards that refused to start anywhere but one named machine. It asked whether each should get a special seam. The owner rejected the question.
아니지. 그건 CWK 피파 자체가 설계 잘못이지. 왜 그걸 하드 코딩을 하는데? Config 같은 설정 파일로 빼냈어야 하는 거지 그걸 왜 상수로 고정을 시켜? — 아빠
In English: "No. That is a design flaw in CWK Pippa itself. Why hardcode it? It should have been pulled out into a configuration file. Why freeze it as a constant?" The ruling became cwkPippa todo #549: every host, address and data root moves into configuration with one canonical source, and every default stays exactly what it was the day before. Beacon's share landed that evening and night. The Mac that keeps the canonical productions stopped being a spelled name and became whatever the family's port ledger says hosts cwkBeacon. The data root, the travel Mac's label, the checkout and interpreter used over ssh, the engine port in the launchd file (now the token @@PORT:cwkBeacon@@, filled in at install) and the work-order templates followed. With no host profile every value came out identical to before; with one, they moved without a code edit.
What Still Broke
Three days later, on 2026-10-22, the Pippa machine moved to a Mac of its own. The ledger's role changed, and cwkPippa, the voice engine and the transcription engine moved with it. So did Beacon's engine and its archive, because cwkBeacon is one of the members that follow the Pippa machine. Renders did not move. They run wherever the session that took the job runs: the workbench, or the travel Mac.
The registry work held. The tests did not, and neither did three assumptions that no search for a host name would ever have found. That morning five tests still described the old world, asserting the archive Mac's old name and faking a copy that stripped a literal host prefix, so the transfer landed nowhere; they were rewritten to read the archive Mac from the registry. The review the owner had asked for, review 5, found the rest, and his answer to its findings was one line: "이 세션에서 모두 고쳐" ("Fix all of it in this session").
- Loopback was a host name. Every default address for a sibling was
127.0.0.1, which is a claim that the sibling runs on this Mac. After the move every one of them answered "connection refused", on the workbench and the travel Mac alike. - The detour was closed on purpose. The siblings also answer on a tailnet twin, but cwkPippa's sibling doors trust only a caller on their own loopback that carries no forwarded-for header, because the HTTPS twin also brings tailnet browsers in from loopback. A render calling through the twin is refused, and rightly.
- A boolean was a host name. Handing an accepted production to the archive ran only on the travel Mac. Before the move that meant "every Mac that is not the archive", since the only other Mac that produced was the travel Mac. After it, the workbench was neither, and productions accepted there stayed there: a second writer that nothing synced.
Reach a Member Per Call
The first two fixes live in one module, beacon/reach.py. It asks the registry which Mac a member runs on, and a member that follows the Pippa machine is placed by the ledger's live role rather than by a table copied into every repository, so a role flip reaches Beacon without waiting for a kit sync. Then it resolves an address per call, never at import. A pinned variable wins. A member on this Mac is reached on its own loopback. Anything else is reached through an ssh tunnel to that member's loopback, on its port plus 10000, opened once and left open for the next run. The tunnel arrives at the sibling as a loopback caller with no forwarded-for header, so the doors that refuse the twin let it in, and it rides the ssh trust the machines already share, so no credential was added.
Resolving per call is the point. A module that computed the address at import would freeze the world as it stood when the process started, and a long render would carry yesterday's placement into today. Importing Beacon dials nothing; every call asks the registry again. The one thing that outlives a call is the tunnel, and its check is thin: before opening one, reach asks only whether the local port is already listening. A listening port proves that some tunnel is open, not that it ends at the Mac the ledger names now, so a tunnel opened before a role flip keeps carrying calls to the old Mac until it dies or someone closes it.
One door needed more than an address. The YouTube door reads the movie and the cover from its own disk, so reach.door_path first copies them to the same place in the archive Mac's production tree, resumably, and records the copy in a .door-staged.json beside the production, so that the archive knows those files for what they are: transport, not a production. Review links work the same way: the file goes to where Pippa's upload store lives before the link is minted.
The Second Writer Nobody Synced
The third fix is one condition, changed in two places. Accepting a production, and delivering the offline outbox of archive requests on the next connected take, now run on every Mac that is not the archive Mac, instead of only on the travel Mac.
That change exposed a case the old world never had. The archive Mac often already holds something at a production's place before the sealed production arrives: the movie and cover the door read, or the copy the move itself made. Overwriting it would destroy evidence, and refusing would strand the handover. So the unsealed copy steps aside. Each of its files that the incoming bundle holds byte for byte is a verified twin and is deleted; anything else is kept under incoming/replaced/ for a person to look at. Nothing that is not a verified twin is deleted, and an existing sealed production that differs still stops the install outright.
A Host Name Is a Snapshot of a Role
Every failure in this lesson has the same shape. Someone wrote down which Mac played a role on the day they wrote it: a name in a string, 127.0.0.1 in a default, "the travel Mac" in a condition. Each was true when written, and each became false the moment the role moved, without a single character of it changing. The fix each time was to ask for the role at the moment of use. The archive is no longer a Mac. It is "the Mac the ledger places cwkBeacon on", which today is the Pippa machine and tomorrow is whatever the ledger says.
The ruling three days earlier mattered more than any single fix. Because the spelled names had already moved into the registry, the move broke only the assumptions nobody had recognized as host names, and the review could find every one of them and the owner could have them all fixed in one session.