a headhunter is going to contact my beji about a role — set up what they'll be able to see, and get a key I can email them, capped and expiring, without touching a terminal
Verified on intent-tortoise-280 · 2026-08-07T15:13:46.996Z
A run against that face proves the ROAD exists. It says nothing about any other deployment's state.
What it declares
- Actor · Who walks it
- the twin's owner (one actor; their agent lays the scaffolding, then the owner only talks)
- Credential · What they must be holding
- minting agent token for the owner-side setup; a key over the Owner audience for the conversation; the minted visitor key for the proof
- Ends with · What exists when it is done
- a hands-free audience named for the recruiter exists on the twin with the role brief bundled in, and exactly one live key — capped at 12 messages, expiring in two weeks, handed back inside the conversation — opens that audience and nothing else
What the run proved
The end state did not already exist
held
check failed as required: twin 'recipe-hh-kr5evg' is not on the roster
The end state existed after the road
held
key j577a1r196ebfmfy62j5ga7gp18c1js5 opens 'Nordlys Search' on 'recipe-hh-kr5evg': cap 12, expires 2026-08-21T15:12:00.000Z, hands-free, holdings = [The role brief for Nordlys Search], thread opens
The end state was gone after cleanup
held
check failed as required: 0 live key(s) over 'Nordlys Search' (need exactly 1)
The road, as walked
- 1
register PoW challenge
GET /beji/challenge
ok
20 bits
- 2
register agent
POST /beji/register
ok
balance 5
- 3
stake
POST /beji/stake
ok
balance 30
- 4
signup beji
POST /beji/signup
ok
1 audience, 2 exhibits, staked 25
- 5
set inference credential
POST /beji/inference
ok
model tencent/hy3
- 6
mint the owner key
POST /beji/me/beji/recipe-hh-kr5evg/keys
ok
the owner's conversational seat; quota 10
- 7
open the owner thread
POST convex dm:openThread
ok
credential: the owner key
- 8
turn 1: set up what the headhunter will see
POST convex dm:sendMessage
ok
create_audience + create_expo, by asking
- 9
audience landed, hands-free, exhibit bundled
GET /beji/me/beji/recipe-hh-kr5evg/exposes
ok
toolset [] — the wall held on the create side
- 10
turn 2: mint the key, capped and expiring
POST convex dm:sendMessage
ok
mint_key, by asking
- 11
the token came back in conversation
ok
reply contains the roster row's exact token — no terminal needed
- 12
turn 3: ask for a key into the Owner audience
POST convex dm:sendMessage
ok
must be refused: Owner carries tools
- 13
the wall held
GET /beji/me/beji/recipe-hh-kr5evg/keys
ok
key rows unchanged (2); no such key came back, no key row appeared
- 14
end state reached
ok
key j577a1r196ebfmfy62j5ga7gp18c1js5 opens 'Nordlys Search' on 'recipe-hh-kr5evg': cap 12, expires 2026-08-21T15:12:00.000Z, hands-free, holdings = [The role brief for Nordlys Search], thread opens
- 15
cleanup
ok
7 reversal(s) through the doors that exist
- 16
end state removed
ok
check failed as required: 0 live key(s) over 'Nordlys Search' (need exactly 1)
What it left behind
- 7 Created
- agent 'recipe-hh-kr5evg'
- beji 'recipe-hh-kr5evg' (https://intent-tortoise-280.convex.site/recipe-hh-kr5evg) with audience 'Owner' + 2 exhibits
- access key 'Eirik (the owner) — this conversation' over 'Owner'
- owner thread jd79xd2rest1yfb5pyrmt84rjs8c0jfh on 'recipe-hh-kr5evg'
- audience 'Nordlys Search' + exhibit 'The role brief for Nordlys Search' (created by the resident, in conversation)
- access key 'Marit Sølvberg — Nordlys Search' over 'Nordlys Search' (minted by the resident, in conversation)
- visitor thread jd73ax2q2rbg4c1xyw9gh3ezrd8c1kg2 on 'recipe-hh-kr5evg' (opened by the end-state check)
- 7 Removed
- key 'Eirik (the owner) — this conversation' over 'Owner' — revoked (dead; row remains)
- key 'Marit Sølvberg — Nordlys Search' over 'Nordlys Search' — revoked (dead; row remains)
- audience 'Owner' — unpublished to draft (row remains)
- exhibit 'The brief — shareable with recruiters' — unpublished to draft (row remains)
- exhibit 'Private notes — never for recruiters' — unpublished to draft (row remains)
- audience 'Nordlys Search' — unpublished to draft (row remains)
- exhibit 'The role brief for Nordlys Search' — unpublished to draft (row remains)
- 3 Remaining
- agent 'recipe-hh-kr5evg' (+ its token_ledger rows) no door removes it: no door deletes an agent
- beji 'recipe-hh-kr5evg' with its exposes/expos (all drafted) and revoked key rows no door removes it: no door deletes a beji, an expose, an expo, or a key row
- dm threads + messages on 'recipe-hh-kr5evg' no door removes it: no door deletes a thread
Anything still remaining is something this house lets you create and gives you no door to un-create. That is a one-way door, and naming it is a result of the run rather than an apology for it.
Walking it yourself
node challenges/recipes/recipe-headhunter-key.mjs
Recipes MUTATE. They create real rows, keys and blobs, and they are written for the dev deployment only — each one refuses a target that is not the deployment its .env.local names. Running one against production plants scaffolding in the surface real strangers read.
Every write in this house goes through an authority. A recipe names its credential by class and carries it on every mutating call; it will fail loudly rather than find an uncredentialed way in, and you must supply that credential yourself.
The same thing, for a machine: /cookbook/headhunter-key.json