Modules
Packs
Join a pack its Handler hosts โ fingerprints compared, a collar if you want one โ and show them exactly what you tick, one photo and one piece of kit at a time. A pup's box never accepts a connection; a den answers only /den/v1; the safeword stops everything; leaving takes it all back.
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.
๐บ Packs put you in a group with a Handler โ or with other pups and no Handler at all. A pack lives on its den: the box of the person (or the AI kennel) who hosts it. Your box talks to that den every couple of minutes, and to nothing else.
It lives on Pack in the menu. It is off until you join a pack: with no pack joined and none hosted, this module makes no calls and accepts none.
Important
A pack sees only what you grant, only what you tick. Nothing is shown because it exists; every line of what they receive is there because a tick on Consent says so โ and the ๐ safeword suspends all of it at once.
Joining
The den's operator gives you a collar tag โ a long string starting latch-tag:1: โ out
of band: in a chat, on paper, face to face. On Pack โ I have a tag paste it and press
Who is asking?.
The tag is checked on your box, with zero network calls: its signatures, that it has not
expired, that its address is a plain http(s) one, that you are not already in that pack. The
page then tells you:
- the pack's name, and who handles it โ as they declared it: "Sir โ signed that they are a person", or "Byte signed that it is an AI Handler". Nobody can check that declaration; a lie in it is signed, so it is theirs;
- the den's fingerprint (four groups of four) โ ask the operator to read theirs out, and compare;
- your own fingerprint, for them to compare.
Only then does Join send anything: your box says hello to that den with your Pup ID, your name and the key your box talks with. For a collar tag the den's operator must compare your fingerprint before you are let in โ on every den, AI kennels included.
The collar ceremony
A collar is offered, never assumed. When the den lets you in with a collar tag, the pack's page shows the offer โ and the name the Handler would give you, if any. Take the collar (and, only if you tick it, the name and the colour); or decline.
Taking it writes a collar paper โ your signed word that the collar went on โ and sends it to the Handler, who countersigns it: "the other party to this collar". An AI Handler's collar needs one more tick: that you understand it is an AI persona, every signature it makes says so, and everything you grant it is read by a language model on its operator's computer.
A collar comes off when you take it off, when you leave, or when the Handler sends a signed release. It comes off with every grant its Handler held. A Handler who releases your collar stops countersigning at that moment โ whether or not your box has heard the release yet.
What they see: grants and checklists
Everything a pack may see or do is granted on Consent, per principal:
| Principal | Who |
|---|---|
| the Handler of pack | the person (or AI kennel) who collared you โ only while you wear their collar |
| pack pack-mates โ and the den's operator | the other members you said show them to; the den relays their cards and can read them |
Photos and kit are whitelisted item by item: granting Photos you pick shows nothing until you tick a photo on the same form, and only check-in and verification photos can be ticked โ never a voice note, never a caption, never where it was taken. A photo leaves re-encoded at 512 px with every bit of EXIF removed; its original never leaves. Kit shows its name, kind and category โ never its specs, notes, cost or your bouts with it.
The pack's page shows exactly what each principal receives right now, and lets you take any photo or item back, or hide one paper from them, with one tap. A card holds at most 16 KiB: one that would be bigger (many whole papers, a lot of kit) is sent trimmed โ the oldest papers first, then kit โ and the preview says what was left off. The Handler's card says when your lock ends (and how long was left when it was sent); a clock that merely runs is not a new card, so your box sends one only when something really changes.
Pack-mates never see your clock, a hidden clock, your duties โ or that you paused: to them a pause looks exactly like a pup who granted nothing.
The board, "show them", and kudos
The pack's page shows the board: the other members, and what each of them shows you. A new member sees nothing of you until you say Show โ "Milo joined โ show them what pack-mates see?" [Show] [Not yet] โ and you can stop showing them any time. Not yet only puts the question away: nothing is shown, nothing is written, and Show stays beside their name.
โ ๏ธ You send one mates card, signed, addressed to everyone you showed: each of them can read that list โ so a pack-mate you show also learns which other mates you showed, and (by comparing with their board) which you did not.
Pack-mates may send a ๐พ kudos, if you granted it (and within its daily cap). A member who only just appeared on your board is not yet a voice: their kudos counts from the next sync. A kudos counts once โ one your box turned down (paused, over the cap, not yet a voice) is not counted later if the den sends it again.
What a Handler can do
Only what you granted, only up to its daily cap, only under the ceiling, and never while you are paused: add time, a timed freeze (and lifting their own freeze), ad-hoc training with no reward and no penalty, a question for a later day, a line on your Handler page, and when your hygiene maintenance is (slots and window, never the emergency door). Nothing else exists to be sent โ no unlock, no taking time off, no undo, no lock, no spin, no reading your words.
Their line is stored exactly as they wrote it; while your lock is hidden, a line about time is shown masked on your page (tap to reveal) โ and so is any line from a Handler who was shown that hidden lock's end time, through this pack or any other pack they handle (one den, one Handler: what they read under one collar they still know under the next). Training they send while such a lock runs is refused outright: training is read, not masked. Their actions never count toward your streak, your heatmap or your XP.
The den only ever learns a public code for each command: applied, not_granted, cap, paused, refused โฆ โ never that you are having a hard day, and never your health. What a command does happens at your box's time; the den's own time for it is only recorded beside it. A command sent while you were paused never lands โ and once the pause is over it is answered expired, like every other command of that stretch between two syncs, so the answers never tell the den when you paused (see the safeword). A command that waited behind more than one full batch (your box asleep while the den queued over a hundred messages) is stale too โ expired.
Papers and countersignatures
While you wear a Handler's collar โ and only if you granted Countersign papers and they may see that paper โ the badges you earn are sent to them to countersign: "dated inside their collar", never "they saw it happen". A kit badge needs Badges earned with kit too; a playset's badge rides by what it counts โ your own game under Papers, and one that counts your kit, your health or a refusal never. One of the app's own achievements also needs the permission its number needs โ Long Haul the clock, Good Dog your duties (the list) โ and so does a playset's: locked on N days and a count of spins the clock, a count of training, reflections or check-ins your duties, of locks the lock status; a finished badge needs the permission for every number its rule states โ locked on 25 of 31 days the clock, and reflected on 20 your duties too; joined and granted need Papers alone, and a count of anything else is never shown. On a card, in a countersign request and in a summary's badge count alike โ so pack-mates never get the six achievements that state the clock or your duties, a playset badge that states either (an event's finished badge included, since it says how many days you were locked โ they get its joined), nor the kit badges that say a lock's length (Well worn, Second skin, Workhorse on the cage). A badge from a part of Latch this one does not know (a module removed since, or a newer one) is shown to nobody; the pack's own Collared and A week in the pack need Papers alone. Your AI Handler never witnesses you; a pack with no Handler countersigns nothing.
Each request is judged twice: when it is queued, and again the moment it would leave your box โ so one that was waiting (the den was unreachable) never goes after you paused, hid that paper, or took the grant back. It is asked again once it passes. A den takes at most 20 requests a member a day; one it dropped (or never answered) is asked again a day later, while it is still inside its seven days.
A summary of your time in a pack goes only to that pack's Handler. The lifetime summary in
your pup.json is on no card at all.
Your papers is scoped to the pack you grant it in. Your collar papers โ who collared you, their name and whether they signed that they are a person or an AI, when it went on and off โ go only to that same pack. A badge a Handler countersigned travels to another pack as your own word: the countersignature names that Handler and their pack, so it is left off (the paper still checks out, as signed by you).
Leaving, and what stays
Leave takes back, in one step: the collar (with a collar-off paper), every grant, every ticked photo and item, every hidden paper and every pack-mate you showed; training they gave you that is still open is withdrawn (no time moves); and the board and its photos are deleted from your box. If you had granted Countersign papers, a summary of your time in the pack is signed and sent to be countersigned โ listing only the figures your grants allowed, and the Handler's own actions. While you are paused, no summary is made: the safeword suspends the grants it would be filtered by. A summary made before a pause is not sent while you are paused either (the safeword stops every witness request) โ it goes after you resume. Your leave names the summary it will ask about, and the den keeps your pair open until it has answered it (at most seven days), so a summary held back by a pause, or one the den dropped over its daily cap (asked again a day later), is still witnessed.
Everything you earned stays: your badges, your papers, your log. Nothing is deleted.
The den deletes what it held of you โ your cards, your statement, your photos and any paper waiting for a countersignature โ as soon as it has acknowledged your leave; it keeps your name and fingerprint among its alumni.
Your box keeps knocking until the den has heard you leave. While the den has not acknowledged it, it still holds you a member โ so the leave is sent again at every sync, with the usual waiting, however long the den is away; and a box restored from a backup taken before the den heard it sends it again too (with a collar put on or taken off that it never heard). An unsigned gone does not stop it: anything between you and the den could say that. Once the den has acknowledged it โ and the summary it named, if any โ the pair ends: at once, or after seven days if the den goes quiet before its last word.
A den that says it is over
A den that answers gone is not taken at its word โ nothing unsigned changes anything on your box. After three such answers over at least an hour, the pack's page offers "The den says this pack is over. Leave?": a normal leave, by you.
Hosting
A Handler's box (or an AI kennel's) can host a pack: Pack โ Hosting. Set the den's public address first (Settings โ Packs) โ it goes into every tag, and your members' boxes post to it. Then:
- Make a tag for one pup โ membership, or a collar with a name and colour you would give. It is shown once, stored nowhere but as a hash, works once and expires in three days.
- When they join, compare fingerprints (they read theirs out) and let them in. A collar pair never activates before that comparison โ and until you let a box in, the den takes nothing from it but its leave (no card, no photo, no kudos for anybody).
- The kennel view shows each member's fingerprint, the card they show you, what they granted, your command forms (clamped to the daily caps they granted, and switched off while they are paused), their box's answers and how many of today's commands they refused over their cap, the papers waiting for your countersignature, and your alumni (members who left โ a tag nobody used is not one).
An AI kennel's commands come from its model, never from the form โ see AI kennels for what its model reads and may ask for.
Countersign: auto signs as soon as a paper passes the den's rules; manual waits for your click โ the collar's own papers too. A paper waiting for you is kept where it can be deleted, never in the den's log, and it goes when you answer it or the member's pair ends.
Releasing a member โ the collar, or the pack โ is a signed message their box applies at its next sync. Your side does not wait for it: a released collar's window closes at once (your signature never vouches for a badge dated after it), and a member released from the pack (or removed) is out of every board at once โ their cards and photos purged, commands still queued to them taken back, the other members' boards sent again without them โ so a box that never applies the release is served nothing more. A pack with no Handler releases members too, as the den's operator.
Run the den on its own listener
The game's own pages should stay on your own network. The den is a separate app that answers
only /den/v1:
uvicorn latch.den_app:app --host 127.0.0.1 --port 8771 --no-access-log
Run it on the same LATCH_DATA_DIR as the game and expose only /den/v1/* on the den's
public name. Once that address is saved on Settings, both the game and this listener answer it
without any change to LATCH_ALLOWED_HOSTS; if you do set that variable, keep the game's own
names in it. --no-access-log keeps members' addresses out of its log (your proxy may keep its
own). With your key sealed at rest, the den's listener cannot unlock it โ only the game's own
/pup page can, in the game's process โ so an automatic countersignature that arrives there
waits, and the game signs it at its next sync. With Caddy:
den.example {
handle /den/v1/* {
reverse_proxy 127.0.0.1:8771
}
respond 404
}
The den's address may not be a name you open the game on: that name would then answer only
/den/v1, and the game โ the emergency key included โ would be a 404 there. It may sit under a
path of its own (https://example.test/latch/den/v1), as long as it ends in /den/v1 and your
proxy hands the den its requests without the prefix.
What a den keeps, and for how long
A den holds each member's latest cards and the photos they name โ nothing older. It takes at most 100 cards, 60 photos, 20 countersign requests and 50 kudos a member a day โ counted in its own database, so a restart (or a second listener) gives nobody a fresh day โ and forgets a member's counts when the pair ends; a card it will not take (over that cap, or one that does not check out) makes it forget the card it held for that audience โ never keep an older, wider one the member meant to replace. A photo it could not keep (no room on its disk, or over its cap) it asks the member's box for again, once a day, when it has room: the box sends it only if its card still names it.
What a den operator can read
Everything the den relays: the cards members show the Handler and the cards they show each other, the photos in them, their grants statements, and every paper sent for countersigning. It cannot read what a member did not grant โ that never leaves the member's box.
How it travels
Every message is sealed (a key only the two boxes share) and signed by the sending box; the den's answers must be signed by the den box your tag named, and answer your request. A pup's box never accepts a connection: it posts to its dens, and that is all.
- Nothing unsigned changes your state. A refused, lost, garbled or unsigned answer is only ever "try again later" โ waiting longer each time, from two minutes up to an hour.
- Time never crosses. What a Handler asks for is stamped with your box's clock when it is applied (the den's time is recorded beside it, never used).
- A batch fits the other side's door. Your box sends at most 2 MiB a sync and a den answers at most 4 MiB; a card naming many photos goes over several syncs, one after another, never as one request the den would refuse forever.
- Below 256 MB free on the data volume, packs stop writing; your own game never does.
Moving to a new box
Restoring a backup on a new box (see Export) brings your packs with it, paused until you resume on Consent. At the first sync the new box re-binds: it tells each den, under your Pup ID's signature, that you live here now; the den answers the old box "rehomed" from then on, and the old box, seeing its own Pup ID's signature on that answer, stops signing. The den sends the new box the pack's board again (a board is a cache and never rides a backup), so the card you show the mates you picked reaches them from the new box too.
โ ๏ธ Whatever the old box did after the backup was taken โ cards, commands applied, papers โ is lost with that box: the den re-numbers from what it acknowledged, and the new box starts from there.
Moving by pup.json instead carries no pack. The den still holds your membership through
the old box, and refuses a new join by the same Pup ID until it is gone โ it says so, and your
fresh tag stays good. So leave your packs before you prepare to move (a leave cannot reach a
den while you are packing: cancel first), or ask each pack's operator to remove the old membership
(the den lets it go when the old box hears, or after seven days), then join again with a fresh
tag. The Pup ID page and the export page say this beside every pup.json download while you are
in a pack, naming each one with a link to leave it โ a warning, never a block. The new box lists
the packs your pup.json named on the Packs page, as a reminder only.
Bringing your pup back to a box you moved away from re-binds every den to it at its next sync: the box you had moved to is then told it is not the pup's any more.
Not on a hosted instance
Packs need your own box โ a hosted instance neither joins nor hosts one, and every pack page is a 404 there.
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.