carlos / platform Public

#162: spec — the flat layout cannot carry the siblings file safely

Summary

found building Task 9. A flat row writes to /data, which every
flat row on the box shares, so two flat hosts wanting a siblings file want
the same path and the loser reads another account's pair key. The writer
refuses both and decides per directory; the residual hole (a flat row
receiving a neighbour's path) is a contract on the reading app, which must
check the file's host field.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev 8682268b7a800d7148defd1423cfdb1ad6142d73 parent 7114b76
1 file changed, +23 −0
  • docs/superpowers/specs/2026-09-21-replica-placements-design.md +23 −0

CI passed — run details

diff --git a/docs/superpowers/specs/2026-09-21-replica-placements-design.md b/docs/superpowers/specs/2026-09-21-replica-placements-design.md
index 986ad702f..b2b2d7ed7 100644
--- a/docs/superpowers/specs/2026-09-21-replica-placements-design.md
+++ b/docs/superpowers/specs/2026-09-21-replica-placements-design.md
@@ -467,6 +467,29 @@ is **omitted** rather than written with an empty `addr`, and the file is
written for a home even when its `replicas` list is empty, so the app can
tell "no replicas" from "no file" **(fable B-6)**.
+**The flat layout cannot carry this file safely** (found in implementation,
+Task 9). A nested row writes to `/data/instances/<id>`, which is its own;
+a FLAT row writes to `/data`, which every flat row on the box shares. Two
+flat hosts that both want a siblings file want the same path, and the
+loser's app would read a key minted for another account's pair — and sign
+a lease call with it, which that pair's sibling would accept. So:
+
+- the writer refuses **both** when two flat hosts on a box would share one
+ directory, logs once naming them, and removes any stale file there;
+- the write and the removal decision are made **per directory**, never per
+ host, or removing one host's file would delete a flat neighbour's;
+- the residual hole is not the writer's to close: a flat row with no
+ replicas of its own still receives `CARLOS_SIBLINGS_FILE=/data/siblings.json`,
+ which may be a neighbour's file. **The reading app MUST check the file's
+ `host` field against its own host and ignore a file that names another.**
+ That is a contract on titogo, stated here and on #162.
+- Replica pairs want the nested layout. A deployment that puts a replica
+ on a flat row gets no file and a log line, which is the fail-closed
+ direction.
+
+**No mesh key, no file.** A file whose `keys` list is empty reads as
+"armed but unsignable"; the pass writes nothing until the edge has a key.
+
**The keys** are per *pair*: `HMAC(meshKey, "replica/" + account + "/" +
homeHost + "/" + replicaHost)` **(fable 5, adapted)**. Round 1 proposed
per-instance keys the home derives itself; the home cannot, because it must