Project
Packs โ how federated Latch works
The design under Packs, reconciled with what shipped โ the member key is who you are and the box key is how you talk; pups only ever post outward and a den only ever answers /den/v1; every message sealed and signed; grants, caps, the ceiling and the safeword on the pup's own box; photos and kit whitelisted item by item; and a den operator who can read everything they relay.
On this page
Tip
New to the Pup ID or packs? Start with Pup ID and packs, explained โ what they are, and why you might want them.
This page is the design; Packs is how to use it
The first version of packs has shipped: joining, collars, grants and checklists, the board, kudos, Handler commands, countersignatures, leaving, hosting and a den on its own listener. What is still to come is listed at the end.
The idea
Latch is solo by design: one box, one pup. Packs add other people without adding a server anyone has to trust with a pup's game:
- A pack is a group hosted on one den โ a Handler's box (or an AI kennel's). Pups who are members see each other on a board and can send kudos.
- A Handler who collars a pup can see what that pup grants and ask for what that pup allows: add time, a timed freeze, training, a question for tomorrow, a line.
- A Handler-less pack is just pups keeping each other company โ membership, the board and kudos. Probably the most common pack.
The rules that do not move
- Each pup's box stays authoritative for its own game. A Handler asks; the pup's box
applies โ as an event in the pup's own log, with
actor=pack:<did>, through the same consent ladder as everything else that is not the pup. The clock stays derived from the local log. Nothing remote writes a row. - Every capability is a grant, chosen by the pup, revocable in one tap, default nothing. Joining grants nothing; taking a collar grants nothing.
- Prose never federates. Reflections, check-in notes, captions, voice, kit notes โ none of it is in any capability a pack can be given. (Only the pup's own local AI reads reflections, in chat, under its own grant.)
- The emergency key always works, and the safeword โ pause โ suspends every grant at once, reads included, without asking anybody. Only the pup resumes, on their own page.
- Health never leaves. Everything that leaves is computed as if no health module existed:
a den learns
refused, never the pup is having a hard day. - A pup's box never accepts a connection. It posts to its dens; it opens no port.
Two keys: who you are, and how you talk
| Key | Is | Where it lives | Pinned by |
|---|---|---|---|
| Member key (your Pup ID) | you โ it signs your cards, papers, grants statements, kudos, and the binding below | your box (and, sealed, inside pup.json and a backup) |
collars, packs, pack-mates |
| Box key | this box โ it signs and seals envelopes | identity/instance.key, never exported |
a den, per pair |
A binding is the member key's signature that this box speaks for it, at a numbered epoch. Moving to a new box is a rebind: the new box sends a fresh binding, the den re-pins, and from then on it answers the old box rehomed โ with the binding it now holds, which the old box can check against its own member key and then retire itself. Nothing unsigned can make a box retire.
Pairing: the collar tag
No directory, no discovery, nothing public. The den mints a collar tag โ a string that names the pack, who handles it (as that den declares: a person, or an AI), the den's address, the den box's binding signed by the den's member key, an offer (membership or a collar) and a one-use secret โ and hands it over out of band.
The pup's box checks every signature and rule offline and shows who is asking, with both fingerprints to compare. A collar is never activated before the den's operator has compared the pup's fingerprint โ on every den, AI kennels included.
Kind is a declaration. "Sir signed that they are a person" is attributable โ a lie in it is signed โ but never verifiable. A signer seen to declare both kinds is shown as disputed.
Transport
| Now | Later | |
|---|---|---|
| Direct HTTP(S) to a den | โ
the pup's box posts to /den/v1/<pair>/sync every couple of minutes; the den answers with what it has queued |
โ |
| Matrix room | โ | a den reachable through a room, for boxes that cannot reach each other at all |
| LXMF / Reticulum | โ | the same envelope over a mesh |
Every message rides an envelope: sealed (an X25519 agreement between the two boxes, a key per direction, AES-GCM with every header in the associated data) and signed by the sending box. A den's answer must be signed by the den box the tag named, and must answer that request. Messages are numbered; each side applies them in order, exactly once, and deletes what the other side acknowledged. Time never crosses: what a Handler asks for is stamped with the pup's clock.
Nothing unsigned changes a pup's state โ an unreachable, refusing, garbled or unsigned answer is only ever try again later. A den that says gone is offered to the pup as a question, never acted on โ and a pup already leaving keeps sending its leave through any number of gones until the den has signed that it heard it. Only a command carries the moment it was queued (a Handler's ask goes stale after a day); a welcome, a release or a countersignature is sealed when it is sent, so a box that was away for days still applies it.
The den's door
A den answers /den/v1/hello, /den/v1/<pair>/sync and /den/v1/<pair>/rebind โ and should do
so on its own listener (latch.den_app:app), so that the address in a tag reaches nothing of
the game. The door checks, in order and without echoing a byte of what it was sent: an open pack,
a crowd limit, a body cap, a known pair, the exact shape, the pinned box and its signature, the
rate, the epoch and the replay window, the seal โ and then each message against what a member may
say.
What can be asked, and what can be seen
| Principal | May be granted |
|---|---|
| a pack's Handler โ only while you wear their collar | see status, the clock, a hidden clock, streak and level, duties, photos you pick, toys/gear you pick, kit badges, papers ยท countersign papers ยท add time, a timed freeze, training (no reward, no penalty), a question for a later day, a line โ each with a daily cap |
| a pack's pack-mates | see status, streak and level, photos you pick, toys/gear you pick, kit badges (never one that states a lock's length), papers ยท kudos (capped) โ never the clock, a hidden clock or duties |
Over all of them: the ceiling, the most time everybody together may put on the pup's clock in a day. No capability exists to unlock, take time off, undo, lock, spin, write or read the pup's words, change a grant or resume โ there is nothing to tick.
Photos and kit are whitelisted item by item. A category granted with nothing ticked shows nothing; photos leave re-encoded at 512 px with no metadata; kit leaves as a name, a kind and a category.
The mates card is addressed. Every card carries a signed list of who it is for; the mates card names only the mates the pup said show them to, and a pause makes it indistinguishable from a pup who granted nothing. The den relays mates cards, and can read every one. Sealing them per mate is future work.
What a den holds
Only what was sent, only as a cache: each member's latest cards and the photos they name, and the
grants statement. A revoke sends the next card without the item (and the den deletes its photo);
a card that cannot be signed is cleared, never left standing โ and a card the den will not
take (over its daily cap, or one that does not check out) clears the one it held for that audience,
so a pause or a revoke can never be outlived by an older card. A grants statement the den will
not take clears the one it held just the same; one naming a capability the den's version does not
know yet is kept for the capabilities it does know. A leave takes it all. A photo the
den acknowledged but could not keep it asks for again (blob.want), and the member's box sends
only what its cards still name. When a
member leaves โ or the den releases or removes them, which takes effect on the den at once โ the
den deletes their cards, statement, photos and any paper waiting for a countersignature โ zeroed,
not merely unlinked โ and keeps a name and a fingerprint among its alumni. A leave is sent until
the den has acknowledged it.
AI kennels
A box whose Pup ID was made as an AI Handler can host a pack: every signature it makes says
ai, the collar ceremony makes the pup acknowledge exactly that, and everything granted to it is
read by a language model on its operator's computer. Its commands come from its model, never from
a form. Per collared member its model reads only the card that member signed for it, their signed
grants and the codes their box answered with, and asks for at most three commands and a line,
clamped to the member's caps โ see AI kennels.
Questions, answered
- Can a Handler see a hidden timer? Only under its own grant โ The clock of a hidden lock. The pup hid it from themselves, not from their Handler; the pup's own pages never show it back.
- Who writes the prompts? A Handler may add a question for a later day; it shows only while their grant and their collar stand, and vanishes the moment either goes.
- How loud is a remote action? Every one is an event in the pup's log with the Handler's name; what they may do is capped per day, and the ceiling caps everybody together.
- A leaderboard? Not in this version.
- More than one collar? One at a time.
Not built yet
Matrix and LXMF pipes ยท pack play (roll call, pack training, a pack wheel) ยท handles ยท mates cards sealed per mate ยท den moves and key rotation after a compromise ยท reflections to a remote Handler ยท packs on a hosted instance.
This page also ships inside the app, at /guide โ so your own instance always serves the guide for the version you are running, with the internet unplugged. Get Latch ยท Something wrong here? Tell me.