Outstanding requirements
12 open · 2 waiting · 0 closed by themselvesEverything JarvisOS cannot finish on its own, in one place, with the condition that closes it. Nothing here is a task: if automation could do it, it belongs in the remediation or deployment register. Every entry was already stated as a gap somewhere else in this repo — this file is what makes those gaps addressable to a person instead of merely recorded.
Nothing on this page is a task. Every entry is something JarvisOS cannot do at all — an account, a token, a
position, a euro, or somebody standing next to hardware. Closure is derived on every render from the condition
each requirement carries, so an ask disappears the moment it is met and a credential that lapses comes back on
its own. No credential value is held, rendered, logged or reported: presence is accessSync against
a path, never a read.
Mint the read-only Coolify API token
Coolify exposes no route for minting or revoking API tokens (gap coolify-no-token-api), so every token in this estate is created by hand in the UI. Without the read token the adapter cannot list servers, resources or deployment status, which means `jarvisos-estate.mjs reconcile` cannot run and the 26 live Coolify resources stay unclaimed by the inventory.
Blocks: Estate reconciliation, the catalogue's Coolify source, deployment status for every application, and gap estate-unclaimed, which is currently the largest crit in the repository.
Do this
- Open http://uk-james-home1.tail99ba7.ts.net:8000 from the tailnet and sign in.
- Keys & Tokens → API tokens → Create, name it jarvisos-read, and grant read only. Do not grant read:sensitive: the adapter is built to receive redacted env values and a token that can read them is a token that can leak them.
- Write it straight to the node, without pasting it into a chat, a commit or a task: install -m 0600 -o jarvis -g jarvis /dev/stdin /var/lib/jarvisos/secrets/coolify-read.token, then paste and Ctrl-D.
- Confirm with: sudo -u jarvis test -r /var/lib/jarvisos/secrets/coolify-read.token && echo present
Where it goes
- Name
COOLIFY_TOKEN_READ- Path
/var/lib/jarvisos/secrets/coolify-read.token- Mode
0600- Scope
- read, without read:sensitive
- Rotate every
- 365 days
Owned by the jarvis service account on the node that runs the adapter, mode 0600, never copied into this repository and never printed by any runner. config/coolify.json declares the same location; this register is what asks for it.
Open http://uk-james-home1.tail99ba7.ts.net:8000 Closes itself the moment /var/lib/jarvisos/secrets/coolify-read.token becomes readable or COOLIFY_TOKEN_READ is set. Presence only — nothing here will read it.
Then these
ranked by urgency, then by what they block, then by what they unblock| Ask | Kind | Urgency | State | Blocks | Age | Closes when |
|---|---|---|---|---|---|---|
|
Sign the Claude CLI in as the jarvis service account on home1
All engineering dispatch to home1. The node will onboard, heartbeat and advertise capacity without it — and every coding task will still land on VIN's single slot.
|
Node access | blocking | Open | Home1 | — | Closes itself on the next heartbeat in which home1 advertises worker-claude. |
|
Run the quarterly off-site restore drill, in person
Any claim that the estate survives losing the home rack. The data-resilience register's restore-drill evidence for gwscli-s3-offsite goes stale without it.
|
Physical | soon | Lapsed | Offsite backup replica NAS backup dataset | 120 d | No machine can close this: The passphrase is deliberately on no machine in this estate. That is the control that makes the off-site copy a disaster-recovery copy rather than a second thing an attacker on this network already has — and it is exactly what makes the drill unautomatable. It closes when somebody attests — "An object was restored from the off-site copy end to end and verified against the on-site original." |
|
Decide whether the estate gets a second public edge
The multi-node deployment register's edge layer, the second forward-auth upstream in the identity register, and any honest claim that this estate survives losing VIN.
|
Approval | soon | Open | Caddy (reverse proxy) JarvisOS Auth (SSO) | 1 d | No machine can close this: This is a question about what the owner is willing to pay for and lose. Nothing on this node can observe a preference, and inferring one from the current topology would just be reading the status quo back as consent. It closes when somebody attests — "The single-edge risk has been either accepted with a review date or funded with a named second edge." |
|
Create a jarvis service account on the NAS and authorise the control-plane key
Measured storage occupancy for nas-backups and nas-media, and therefore any honest 'days until full' figure. Also every future remediation that would touch the NAS, which currently cannot be attempted at all.
|
Node access | soon | Unverifiable here | NAS NAS backup dataset | 1 d | Closes when /home/jarvis/.ssh/authorized_keys exists on nas. This console cannot see that, so prove it with: ssh -o BatchMode=yes jarvis@10.10.0.20 'df -P /' && echo reachable |
|
Sign the Codex CLI in as the jarvis service account on home1
Independent review of work produced on home1.
|
Node access | soon | Open | Home1 | — | Closes itself on the next heartbeat in which home1 advertises worker-codex. |
Also open
past the register’s own shortlist of 6Demoted, never hidden. Only asks with nothing human in front of them are surfaced. A requirement waiting on another requirement is listed as waiting, not asked for: a list that mixes the two teaches its reader to skim both.
| Ask | Kind | Urgency | State | Blocks | Age | Closes when |
|---|---|---|---|---|---|---|
|
Enrol the node on the tailnet
Everything. Nothing else in the kit runs without the private plane.
|
Node access | soon | Open | Home1 | — | Closes itself on the next heartbeat in which home1 advertises private-mesh. |
|
Approve the elastic-compute spending ceiling
Every billable burst operation, and therefore the write-scoped Hetzner token that would carry one out.
|
Billing | soon | Open | — | 1 d | No machine can close this: No machine may consent to spending somebody else's money. This node is deliberately built so that it cannot: it holds no billing credential and the runner refuses every billable verb without a signed grant. It closes when somebody attests — "The owner has agreed the monthly and per-run burst ceilings, or set different ones." |
|
Write the tailnet ACL for tag:burst
Attaching any burst node to the mesh. It is a prerequisite of the write-scoped provider token, because the first thing that token would do is create a node that joins the tailnet.
|
Approval | soon | Open | — | 1 d | No machine can close this: This node holds no tailnet admin credential and by policy will not be given one: the ability to rewrite the ACL of the private plane is the ability to grant itself access to everything on it. It closes when somebody attests — "A tag:burst exists with a narrow ACL and an ephemeral, pre-authorised auth key." |
|
Give the NAS a stable name instead of a LAN literal
Nothing today, because nothing on VIN currently talks to the NAS. It blocks trusting the NAS address the first time something does — which is the moment when finding out is most expensive.
|
Information | whenever | Open | NAS | 1 d | No machine can close this: The question is which addressing scheme the estate should use, and no reading of the current one answers it — a literal that resolves today is exactly the state being complained about. It closes when somebody attests — "The NAS has a stable name, the inventory records it, and the note says what it was before." |
|
Mint the read-only Hetzner token for the burst-only project
Price verification (gap prices-unverified) and usage-against-ceiling reporting. Nothing spends money as a result of this token existing.
|
Credential | whenever | Open | — | 1 d | Closes itself the moment /var/lib/jarvisos/secrets/hetzner-read.token becomes readable or HCLOUD_TOKEN_READ is set. Presence only — nothing here will read it. |
|
Supply the actual VIN invoice figure
Nothing operational. It blocks the burst decision being evidence rather than an estimate — and the break-even line, which is the number at which the entire policy inverts.
|
Information | whenever | Open | — | 1 d | No machine can close this: The invoice is in the owner's mailbox and behind a billing login. This node holds no billing credential and by policy will not be given one — a console that can read invoices can be made to read everything else in that account. It closes when somebody attests — "The real monthly VIN cost has been read off an invoice and checked against the burst register." |
Waiting on another ask
not surfaced, and that is the pointThese are real requirements that nobody can start. Printing them next to the ones that can be started is how a register teaches its reader to skim — so they are listed here, with the thing they are behind.
| Requirement | Kind | Urgency | State | Blocks | Age | Waiting on |
|---|---|---|---|---|---|---|
|
Mint the deploy-scoped Coolify API token
Every automated recovery action that ends in a redeploy or a rollback. Until it exists, remediation for a wedged application stops at 'fetch a human'.
|
Credential | soon | Waiting | Home1 | 1 d | coolify-read-token |
|
Mint the read-write Hetzner token for the burst-only project
Provisioning any elastic capacity. Deliberately: with no write token, the burst plan is a plan and the estate's recurring cost stays at zero.
|
Credential | whenever | Waiting | — | 1 d | burst-spend-approval, tailnet-acl-burst, hetzner-read-token |
Closed before this register existed
kept as evidence that closure is real-
Enrol home1 on the tailnet 2026-08-16
Closed by: bootstrap evidence E6 — the MagicDNS name answered from VIN when the 10.10.0.10 literal did notClosed by evidence rather than by a tick. It is kept here because it is the case that proves the closure model: the requirement stopped being asked for when something observable became true, and the inventory entry was corrected in the same movement.
-
Issue home1 a node credential so it can heartbeat 2026-08-16
Closed by: the identity registry at /etc/jarvisos/node-identities.json carries a home1 entry; the console stores only its SHA-256 digestReplaced the shared ingest token. The console reports presence and lifecycle metadata and has never held the value.
Everything the register wants said
2 crit · 8 warn-
crit
Mint the read-only Coolify API token
Coolify exposes no route for minting or revoking API tokens (gap coolify-no-token-api), so every token in this estate is created by hand in the UI. Without the read token the adapter cannot list servers, resources or deployment status, which means `jarvisos-estate.mjs reconcile` cannot run and the 26 live Coolify resources stay unclaimed by the inventory. Blocks: Estate reconciliation, the catalogue's Coolify source, deployment status for every application, and gap estate-unclaimed, which is currently the largest crit in the repository.
-
crit
Sign the Claude CLI in as the jarvis service account on home1
Claude Code is the engineering worker. Its sign-in is an interactive OAuth device flow: it prints a URL, waits for a browser, and writes the credential itself. Nothing headless can complete it, and until it is done home1 can be dispatched planning work but no code. Blocks: All engineering dispatch to home1. The node will onboard, heartbeat and advertise capacity without it — and every coding task will still land on VIN's single slot.
-
warn
Decide whether the estate gets a second public edge
Gaps deployment-single-edge and estate-lifecycle-single-point say the same thing from two directions: one edge, one control plane, and every HA property in three registers is a plan rather than a fact until that changes. The auth register makes it sharper — one forward-auth upstream means an auth container failure reads as the whole estate being down. Blocks: The multi-node deployment register's edge layer, the second forward-auth upstream in the identity register, and any honest claim that this estate survives losing VIN.
-
warn
Create a jarvis service account on the NAS and authorise the control-plane key
The storage register places every byte on a tier and says when that tier runs out, but the numbers behind it are derived from what the register places, not from the pool. The measured answers are `df` and `du` on a machine this process has no account on. A NAS with no service account is a NAS whose occupancy is an estimate that will be believed. Blocks: Measured storage occupancy for nas-backups and nas-media, and therefore any honest 'days until full' figure. Also every future remediation that would touch the NAS, which currently cannot be attempted at all.
-
warn
Sign the Codex CLI in as the jarvis service account on home1
Codex is the reviewer in the dispatch model, so without it home1's work is written and merged by the same worker. Its sign-in is the same interactive OAuth flow and equally cannot be automated. Blocks: Independent review of work produced on home1.
-
warn
Enrol the node on the tailnet
Joining a private network is an act of enrolment. It needs an auth key or an interactive login from the admin console, and this kit deliberately has neither: an installer that can add machines to your private network is an installer that can add anyone's. Blocks: Everything. Nothing else in the kit runs without the private plane.
-
warn
Approve the elastic-compute spending ceiling
The burst register is adopted with zero recurring cost as the default and the rollback plan, and no billable operation is executable: the runner prints the provider request and refuses it. What it does not have is a person's agreement to the ceiling, and every grant in that register is issued against a budget this approval sets. Blocks: Every billable burst operation, and therefore the write-scoped Hetzner token that would carry one out.
-
warn
Write the tailnet ACL for tag:burst
Gap tailnet-acl-for-burst is a crit: the burst plan attaches rented nodes to the private mesh and no ACL for tag:burst exists. A burst node with the default policy is a machine somebody else's hypervisor is hosting, sitting on the same flat network as the Postgres primary. Blocks: Attaching any burst node to the mesh. It is a prerequisite of the write-scoped provider token, because the first thing that token would do is create a node that joins the tailnet.
-
warn
"Run the quarterly off-site restore drill, in person" has lapsed and is being asked for again
The inventory declares gwscli-s3-offsite's verification as a quarterly restore drill. A drill that happened once is a drill that proved the backup worked in April. It fell due on 2026-07-19, 31 day(s) ago. It closed itself once and it will close itself again.
-
warn
12 asks are open against a declared ceiling of 6
Either the estate genuinely needs that many decisions, or this register has stopped prioritising. Deliberately not fatal: a build that fails because the world has work in it is a build nobody trusts.
-
note
Give the NAS a stable name instead of a LAN literal
The NAS is registered at 10.10.0.20. Home1 was registered at 10.10.0.10 until 2026-08-16, and that literal answered nothing from VIN — bootstrap evidence E6. The same failure is sitting in the register unexercised, and it will be discovered during an incident rather than before one. Blocks: Nothing today, because nothing on VIN currently talks to the NAS. It blocks trusting the NAS address the first time something does — which is the moment when finding out is most expensive.
-
note
Mint the read-only Hetzner token for the burst-only project
The read credential is what turns the burst register's arithmetic from committed numbers into verified ones: it reads the provider's own price list, the server types and this month's usage. It is free, it cannot change anything, and the provider itself refuses it on every mutating route — which is why it is the credential every automatic operation uses. Blocks: Price verification (gap prices-unverified) and usage-against-ceiling reporting. Nothing spends money as a result of this token existing.
-
note
Supply the actual VIN invoice figure
Gap prices-unverified: every euro in the burst comparison is a number committed to a register, not one taken from an invoice. The comparison's whole claim is that renting is cheaper than upgrading, and that claim rests on what VIN actually costs today. Blocks: Nothing operational. It blocks the burst decision being evidence rather than an estimate — and the break-even line, which is the number at which the entire policy inverts.
-
note
"Mint the deploy-scoped Coolify API token" is not an ask yet
Waiting on coolify-read-token. Deliberately not surfaced: nobody can start it, and printing it would train its reader to skim the ones they can.
-
note
"Mint the read-write Hetzner token for the burst-only project" is not an ask yet
Waiting on burst-spend-approval, tailnet-acl-burst, hetzner-read-token. Deliberately not surfaced: nobody can start it, and printing it would train its reader to skim the ones they can.
How this register behaves
- Principle
- A requirement is a thing only a human can supply. Node access, a provider credential, an approval, a euro, or somebody standing next to hardware. If JarvisOS can do it, it is not a requirement, it is work.
- Closure
- Closure is derived on every render, never written down. A requirement carries the condition — a file becoming readable, a node advertising a capability, an entity appearing in the inventory — and stops being asked for the moment that condition holds. Where nothing can check, the register says why, and closure is a named person's attestation on the record rather than a tick.
- Custody
- No credential value appears in this file, in the API payload, in a page, in a log line or in a task report. A credential requirement carries a name, an absolute path outside this repository, and a rotation interval. Presence is established with accessSync — the file is asked whether it is readable, never what it contains — and a declared path inside this working tree is refused at load.
- Surfacing
- Only asks with nothing human in front of them are surfaced. A requirement waiting on another requirement is listed as waiting, not asked for: a list that mixes the two teaches its reader to skim both.
- Next review
- 2026-09-14
Machine-readable at /api/v1/requirements · narrative in
docs/REQUIREMENTS.md · node scripts/jarvisos-requirements.mjs next prints the same
single ask in a terminal, with the same derivation.