Skip to main content

Addendum · Remediation plan · September 2026

The Repair List

The essay listed what is wrong with my own stack. This is the order I am fixing it in, what you will be able to check from outside as each one lands, and what I cannot fix alone.

By Craig Merry September 12, 2026 14 min read The essay this follows

The essay before this one ends with a defect list. A list of defects with no plan under it is a confession, not engineering. This is the plan.

It covers 62 items across the registry, the protocol, the robot runtime, the gateway, the phone and pendant apps, PlatAtlas, PlatChat, the governance documents and the session recorder. Every item was checked against the code before it went on this list: the file exists and the function does what the item says. Most carry a test that fails today and passes after. A handful are documents or a fact to settle, and those say so in their own row rather than pretending to a test. Thirty-eight of the 62 are things the essay already told you about. The rest turned up while checking those.

One rule governs the whole thing. The essay does not get edited until the fix is deployed and re-tested against the live system. When a sentence in the essay stops being true, it gets a dated correction, not a quiet rewrite. The status log at the bottom of this page is where that happens.

How to read this

Each item has a priority. I am using four, in plain words.

  • P0 means a door is open or a stop lies. An endpoint that hands out a credential to anyone who asks, a local service that starts an agent turn without a credential, or a stop button that reports success without stopping anything. Thirteen items.
  • P1 means a record or a public claim that the code contradicts. Thirty-five items.
  • P2 means documents, labels and dead code. Eight items.
  • P3 means longer builds, or things that need someone other than me. Six items, three of which are phase six.

Each item also has a check you can run from outside. For a live service that means a status code or a published document. For code that runs only on my own hardware, there is nothing to poll, so the check is a dated line in the log and a link to the public commit. I would rather say “nothing observable, here is the commit” than pretend a private fix is a public one.

The order

Six phases. The first is a week. The last cannot be finished by me.

Phase one: close the doors, then make the stop real. Every P0, in one week. First I settle whether pushing to the registry’s repository actually publishes it, because a credential fix that silently fails to deploy is worse than no fix. Then the registry’s agent credential endpoints refuse callers with no valid credential, the keyless token signer is deleted, the open registration endpoint for signing authorities gets a cap, and the compliance record endpoints check who is asking before they answer or accept. On the evidence platform, only an administrator can mint an administrator key, and the granted scopes go into the audit record. On the robot side, the runtime’s fleet endpoints require the caller’s own credential instead of supplying one, an unconfigured robot refuses privileged commands instead of trusting everyone (on the hand-started path that the setup command never produces), and the benchmark helper that can start an agent turn gets a front door and a ceiling on how many children it can start. Then the stops. Every deployed robot exposes a stop, and the gateway logs a named error at start when a motion allowlist has no stop in it. The handheld pendant says stop-not-confirmed when it cannot stop, and reconnecting no longer clears a latched stop. The robot’s own safety stop reaches the motors and survives a restart. It is a best-effort software hold, not a hardware cut, and the tool that exposes it says so. And the cloud stop, the fleet stop and the phone stop only say acknowledged once the robot has actually received the command. The cross-registry safety exemption narrows to the stopping verbs, so a remote safety message can still stop a robot but can no longer resume one. Phone commands that change a robot’s settings travel through the server path that checks the owner and the pace. An unconfigured robot refuses investigator requests instead of accepting all of them, and files its own incidents from safety events instead of waiting for a hand. Last in this phase, each installation seals its own log with a key created at install time.

Phase two: make the evidence say only what it can prove. This is PlatAtlas and PlatChat, in a strict order. The write key that pushes evidence loses the ability to delete it (that one is in phase one, because it has to land before anything below). Both chat orchestrators run their model child with a short, explicit tool list and treat the channel transcript as data rather than as instructions (also phase one). Then the evidence chain publishes a head, so that truncating the newest entries contradicts something a reader already holds, and the offline checker learns to demand that head. The two compliance controls the code cannot back, anomaly detection and incident response, come out of the crosswalk. The label vocabulary that producers were choosing for themselves closes. An action’s own approval stops reading as a human approval, refusals get recorded and signed the way approvals are, and the checker recomputes a pack’s summary numbers instead of trusting them. A paused chat hub stops spending on its scheduled work instead of only refusing to post, and creating a channel becomes a gated, audited act. Pausing still tells no robot to stop, and the essay’s paragraph about it narrows rather than disappears.

Phase three: make the register countable, custodied and singular. The counting test the essay ran on its own register, closed. This is about whether the register can be inspected, not about anyone outside having done it. The register can count and page through its whole corpus. A facts page states what the register actually holds, with numbers that match the public interface, and the line telling regulators and insurers they can rely on the record comes down. A weekly signed snapshot goes off the account with a publicly pinned head, and the root signing key moves out of the storage namespace that a bulk delete empties. The transparency log gets real digests, a link from each entry to the one before, and a signed head. The root node publishes its keys or stops advertising what it cannot do. The older registry stops auto-granting a verification tier for any string that parses as a URL, and one identifier stops having two authoritative answers.

Phase four: records that can be contradicted, and keys the agent cannot read. Gateway receipts carry the caller’s identity and record a refusal as a refusal. The gateway writes what it is about to do before it does it, which is the protocol’s strongest sentence, finally implemented. The gateway’s records get a sequence number and a link to the previous record, and a copy leaves the robot. A published revocation reaches the robot inside the interval the registry advertises. The one request cap that actually runs fails closed and covers the arm. Unknown tools are denied by default. And one privileged command, run after setup rather than during it, moves the signing keys and the device out of the reach of the account the agent runs as. Setup itself stays inside its time budget and prints the one command that remains.

Phase five: formats other people’s tools can read, then the subtraction pass. A declared safety flag in a robot description reads as a declaration, not a verified fact. The protocol names which robot-to-robot channels are sanctioned, so that “unsanctioned” means something. A stop receipt gets published as a format with a verifier in both SDKs, so a third party could check a claimed stop without me. That one needs merge authority on a specification I do not own, and until a gateway emits one the schema will say plainly that nothing ships it yet. Evidence packs count stops ordered and stops confirmed separately. Then the honesty pass on my own documents: the gateway readme stops promising an enforcement guarantee, the canonical disclaimer gets reworded everywhere it appears, and the dead code that documents a relay gets deleted. This runs last on purpose, after the code has changed what is true.

Phase six: what one operator cannot close. Three items ship their half now and publish the gap plainly. A revocation procedure with notice, appeal and an error register, with the separation-of-duties role marked vacant until a second person holds it. A published monthly cost, a plain statement that no company has committed funding, and one real public deposit of a signed snapshot. And a chain head signed on a schedule by a key the platform does not hold, labeled producer-signed until a second custodian signs it.

Rules I am holding myself to

A few of the ordering rules came out of the review, and these are the ones a reader can hold me to.

  1. The registry’s deploy path is confirmed before any registry commit is pushed.
  2. The evidence delete path is closed before a chain head is published. A head that a deleter can still walk back is theater.
  3. The gateway’s records are not copied off the robot until the place they land cannot be emptied by the same class of credential that wrote them.
  4. The closed label vocabulary is agreed with every producer before the storage constraint that enforces it is applied, or the constraint rejects their records.
  5. The essay is edited per item, after that item is deployed and re-tested live, never before.
  6. One app release per app per working session. The phone work goes out as two builds, not a stream of them: the stop and command-routing fixes in one, the receipt and approval fixes in the other. The pendant is not an app and ships on its own.

What I cannot do alone

The essay asked for three things. The review turned them into eight, and I would rather list all eight than pretend the plan closes them.

  1. A second person to hold a key that is not mine. Until then, key custody is one person on separate hardware, and every page that touches it will say exactly that.
  2. A second operator willing to register one robot and run the setup on their own hardware, then tell me where the verification ladder and the ten-minute setup break.
  3. Someone in a regulator’s office or a standards body willing to run the open checker against one bundle or one evidence pack and report what it does not answer.
  4. An escrow agent, or any independent party, willing to hold signed snapshots under an agreement.
  5. A legal entity that can be served, with governance that is more than one seat.
  6. Merge authority on the normative protocol sections, which live in a repository I do not merge into. Every affected item ships its local half regardless and files the upstream proposal.
  7. Agreement from the other producers on the closed label set before the storage constraint goes in.
  8. Apple’s review queue, for the two app releases in this plan.

What will and will not change in the essay

Most of the defects the essay names will get a dated correction as their item ships. A few will not change from this plan alone, and I want to say which.

“No third party has ever registered a robot” and “nothing in my records shows a bundle verified by anyone other than the party that produced it” stay true until one of the people above acts. The plan makes both possible. It cannot make them happen.

“That enforcement is off by default,” about the roster gate that refuses unregistered agents, stays true on purpose. The fix arms it for my own organizations and leaves the shipped default alone, because a default that refuses strangers’ agents is a decision for the person deploying it, not for me.

“Sole custody of the root log-signing key, the administrative revocation token and the credential signing key” narrows but does not go away. After phase four the keys are out of the agent’s reach on any installation where that command has been run. They are still in one person’s custody, and no sentence here will be rewritten to imply two.

Progress

Update, September 13, 2026. Phase one is done. All seventeen rows in it carry a date and a link to the commit. The registry’s agent credential endpoints refuse a caller with no valid credential and the keyless signer is gone. The compliance record endpoints check who is asking. On the evidence platform only an administrator mints an administrator key, the write key can no longer delete attested evidence, and both chat orchestrators run their model child with an empty tool list. On the robots, the fleet endpoints refuse to lend the robot’s own credential, the owner role is split off the agent’s bearer, the benchmark helper has a front door and a child ceiling, the commitment chain no longer ships its key, the audit log has one absolute path and a verifier that tells no-log from intact, the investigator handler refuses every requester until an authority is listed, stops file their own incident records, and the arm’s stop is declared, allowlisted and proven through the gateway with a signed receipt. The pendant reports a stop it could not make as not confirmed. The phone says queued until the robot answers.

Three follow-ups landed the same week. A running stock server now reconciles its stop latch from disk every five seconds, so a pause typed at the robot reaches the process that is moving it, and a corrupt or deleted latch file never lifts a hold. The incident log is bounded, locked across processes, and has a link checker. The one gap I could not close from a keyboard is written on its row: the cloud bridge that carries a phone stop to a robot does not run on any robot of mine, so that fix rests on its tests.

The essay carries eleven dated corrections as a result. Nothing in it was rewritten silently. The two sentences the plan said would not change have not changed.

Update, September 14, 2026. Four more things since the note above. The incident log has a link checker of its own now, and it answered clean across the 79 records on my arm; a link check is not an outside party’s verification, and the tool says so. The car’s stop is proven: a generated runtime latched a sensor stop on the simulated car, posted its stop tool, and the signed receipt checks out offline against the car’s key. That proof turned up a defect on this essay’s own theme, a generated car carrying another car’s registration number as a literal, which is fixed and on the OC-05 row. And a near miss worth recording: a pairing tool’s force flag rotated the arm’s live signing key under the same key id while I was refreshing a network address; the tool’s own backup let me put the original key back and prove the receipts still verify, and the lesson, never rotate a registered key with a flag, is written down. Last, the machine under all of this: the computer that runs the arm negotiates a 15 watt supply and has rebooted under load twice this week. The stop latch is on disk and came back after a service restart, but a power cut is a different test and I have not passed it yet.

Update, September 14, 2026, evening. Phase two moved through the evidence platform, the chat hub and the registry today, and the rows carry the detail. The short version follows. The chain head is published, and the offline checker recomputes every summary number in a pack instead of trusting it, so a pack with one edited number now fails while every signature still checks out. The compliance export says in the file when it stopped short. Every approval the platform had ever recorded turned out to be signed by the action’s own host key. Those are now labelled as such, counted, and kept out of the control that asks for human oversight, and nothing is blocked. Refusals are signed and exported on the same path as approvals. Each new ledger entry commits to the signed bytes it names. The twenty-one older entries do not and never will, and the pack says so. Two deterministic checks run on the nightly job that already existed, writing one audit row per workspace per day. They detect nothing about unregistered agents. That is the chat hub’s roster gate, which is now armed on both of my workspaces by configuration while the code default stays off, so the sentence in the essay about the default is still true. Channel creation is pause-checked and audited. A paused workspace now stops the orchestrator’s turns and spend, not only its posts, and the claim that the budget counter persists is deleted because it does not. The verifier panel records that it is the same model as the generator, in the signed routing record and beside every verdict. The registry’s root node stopped advertising verify and delegate while it holds no key, its sync contract stopped documenting a signature it never checked, and every URL it hands out now points at a host that resolves. The trace viewer says what a file does not contain.

What I could not do today. Every check that needs a member session on the evidence platform is still pending, because my own session expired and only I can renew it. Those rows say deployed, live check pending, and the essay corrections for them wait. The root node’s key is not yet published; the fix today was to withdraw the claim, not to add the proof. The token issuer string still names the dead host on purpose, because the robots check it for equality and changing it is a coordinated release. The recorder’s half of the trace fix is merged and not released.

How to hold me to this

The table below has one row per item, in the order above. When an item ships, its row gets a date and a link to the commit or the public artifact, and the check column says what you can look at. If a date slips, the row will say so. If I learn that an item was wrong, it comes off the list with a note, not silently.

If you want to run any of the checks yourself and something does not match what this page says, email me. That is the third-party verification this whole thing is missing, and I will take it from anyone.

Status log

One row per item in the plan. The status changes here as fixes ship, with the date and the check anyone can run. Last updated 2026-09-15.

Shipped: 22 · In progress: 18 · Planned: 18 · Needs someone else: 4

#ItemWherePriorityStatusCheck from outsideDate
1 Confirm that pushing a change actually publishes the registry
Settled 2026-09-12: a push to main publishes through the repository's existing deploy workflow, and a local wrangler upload is the by-hand path. Every registry fix below was confirmed live after deploy.
registry P1 Shipped Nothing public changes here. What gets published instead is a dated line on this page recording how the registry is deployed and how every later fix was confirmed live. 2026-09-12
2 The registry's agent credential endpoints refuse callers with no valid credential · in the essay
Live 2026-09-12: a request with an invalid credential to the token endpoint now answers 401 (it answered 404 before). Tokens are standard JWS; the keyless fallback is gone; authority registration is capped per day.
registry P0 Shipped A request to the register, consent, token and revoke endpoints that carries no valid credential is refused rather than answered; a token the registry issues can be checked against the public key it publishes using any standard verifier; the change is named in the public changelog. 2026-09-12
3 Compliance record endpoints check who is asking before answering or accepting · in the essay
Live 2026-09-12: the incident-report and FRIA reads answer 401 with no credential and 403 with an invalid one; SBOM and firmware-manifest submissions must be signed by the key on record. The IFU and safety-benchmark routes are unchanged and stay on the list.
registry P0 Shipped The sensitive compliance read endpoints refuse an invalid credential instead of answering as though the record did not exist, and a submission that is not signed by the key on record is rejected. The commit is public. 2026-09-12
4 The chat assistant runs with a short, explicit list of allowed tools
Both orchestrators restarted 2026-09-12 on the fenced argv (restricted, manual permission mode, empty tool list, no session persistence, scratch cwd). The local gate ops/check-seat-argv.sh exits 0. Both rooms came back online with no seat exit.
PlatChat P0 Shipped Nothing is observable from outside; both orchestrators run on the operator's own hardware. A dated line here and a link to the public commit. 2026-09-12
5 Only an administrator can mint an administrator key, from a fixed list
Deployed 2026-09-12 with PA-03. Live: an unauthenticated mint answers 401. The closed scope set and the admin-only rule for the admin scope are covered by the worker test suite; the console form shows only read, ingest, write and admin.
PlatAtlas P0 Shipped Any signed-in member sees only the documented scopes offered on the key form, and key creation records the granted scopes in the audit log. 2026-09-12
6 The key that writes evidence can no longer delete it
Deployed 2026-09-12 (worker version b95770ff). Live: DELETE on an attested trace over the org host answers 401 with no credential and 401 with a junk key. Write-key 403, admin-key 409 and the partial-purge count are covered by the worker test suite; no active API key exists to exercise them live.
PlatAtlas P0 Shipped The interface is customer-gated, so the observable artifact is the public commit: attested evidence cannot be removed by the credential that wrote it, and removal now requires administrative scope. 2026-09-12
7 The robot stops lending its own admin credential to machines it finds nearby
Merged to main and live on my arm's runtime since the 2026-09-12 restart. Live: a fleet status request with the robot's own bearer and no peer credential answers 401 with the reason no_peer_credential; the robot never lends its own token to a discovered peer.
robot runtime P0 Shipped The runtime is not reachable from the internet, so there is no status code to poll. The artifact is the public commit and changelog entry stating that the fleet endpoints now require the caller's own credential. 2026-09-12
8 An unconfigured robot refuses privileged commands instead of trusting everyone
Live on my arm's runtime since the 2026-09-12 restart. The runtime bearer is now an operator: clearing a stop with it answers 403 insufficient_role, a request with no credential answers 401 on the privileged routes, and the owner token is minted by the generator and kept only as a digest on the robot. Champion documents that touch the consent threshold are refused.
robot runtime P0 Shipped Public commit and changelog stating that the runtime's static credential no longer carries the administrative role and that an unconfigured runtime refuses privileged routes, plus the corrected sentence in the published safety document. 2026-09-12
9 The benchmark helper needs a credential and cannot start unlimited agent turns
Merged to main 2026-09-12. The benchmark helper mints a per-run token, refuses unauthenticated calls with 401, and caps concurrent model children at two. Re-measured 2026-09-13 on the arm's virtual easel, started from the console the way the phone starts it: 50 model calls and 117 moves in ten and a half minutes, exit 0, no refusals from the helper, ceiling of two held; the last such run before the change took 31 minutes for 52 calls. Nothing to observe from outside; the helper is loopback-only and starts per run.
robot runtime P0 Shipped Nothing is observable from outside; the helper is local-only and never published. A dated line here and a link to the public commit. 2026-09-12
10 Every deployed robot exposes a stop, and refuses to start without one · in the essay
Live on my arm since 2026-09-12. Through the gateway: the stop executes and returns a signed receipt, a motion while latched is refused with the reason estop_latched, the read tier cannot clear, the commission tier can, and the gateway's startup log carries no missing-stop error. The arm's signed capability manifest now declares both the stop and the clear (added with the manifest subcommand and re-signed), and the gateway was restarted to read it. Actuator commits: so-arm101 ac23214 and rc-car b35f6e3.
gateway P0 Shipped Anyone can read in the public repositories that the arm and the vehicle list a stop among their capabilities and that the gateway logs a named error at start when a motion allowlist contains no stop. The essay's published sentence about an arm with no stop tool can then be dated as closed. 2026-09-12
11 The handheld stop button says stop not confirmed when it cannot stop
Main at 92176f5 (pushed 2026-09-12): the pendant reports stop-not-confirmed when it cannot stop, reconnecting no longer clears a latched stop, the WebSocket binds loopback by default and requires a token on the LAN, and the handheld firmware no longer paints the STOP banner before the Pi confirms. Nothing observable from outside; the pendant is not a hosted service.
pendant P0 Shipped The public commit showing the stop-not-confirmed path, and that reconnecting no longer clears a latched stop by itself. 2026-09-12
12 A robot's own safety stop reaches the motors and survives a restart · in the essay
Live on my arm since the 2026-09-12 restart: a stop latches to disk, survived a service restart, and clears only with the owner token plus the e-stop code. Follow-ups on 2026-09-13: the stock server reconciles the latch file every five seconds (a pause typed at the shell reached the running server in four seconds, observed live), a corrupt or deleted latch file never lifts a hold, one resolver finds the clear code for both the API and the command line, and the rover proof is done: a generated runtime pointed at my simulated car's gateway latched a sensor stop, posted the car's stop tool, and the signed receipt validated offline against the car's public key, while the same latch refused a network clear and cleared only at the robot (commit 8d15155). That proof found and fixed a real defect: the generated car runtime carried the first car's identity as a literal, so every later car would have signed its stops under another robot's number. It is a best-effort software hold, not a hardware cut; the car's wheels are simulated and nothing here is safety rated.
robot runtime P0 Shipped The released command-line tool's help lists the new pause and resume commands, and the published robot template constructs the safety monitor it used to skip. Both are readable from the published package. 2026-09-12
13 A stop is only acknowledged once the robot has actually received it · in the essay
Both halves merged 2026-09-12. Runtime half: the cloud stop posts to the route the runtime actually serves, and the acknowledgement is written only from the robot's answer, or recorded as not confirmed after the deadline; 20 tests, full suite green. Phone half: the web client says queued until that answer lands; the Swift phone app already reported from the robot's reply. Not live-tested: no robot of mine runs the cloud bridge and no bridge credentials exist on the Pi, so this row rests on tests, not on a live stop.
robot runtime P0 Shipped The shipped phone app says queued rather than halted until the robot answers, and the public commit moves the acknowledgement behind the dispatch result. The essay's manufactured stop-acknowledged sentence can be dated as closed. 2026-09-12
14 Each installation seals its own log with a key that was not shipped · in the essay
Live on my arm since the 2026-09-12 restart. The commitment chain no longer ships a key; the generator minted one at install and the unit names it. The audit log has one absolute path under the robot home, a missing previous hash is a break, and the verifier answers no-log with exit 2 (observed before the first write) and links-check-out with exit 0 (observed after). The word tamper-evident is gone from the runtime source. The old hand-written hook script on my arm carries no version marker, so it was left alone and still writes its own file.
robot runtime P0 Shipped The published release notes record that the seal is disabled unless a key is created at install time, that the checker now tells no log apart from chain intact, and that the phrase tamper-evident no longer appears in the source or the documentation. 2026-09-12
15 A cross-registry safety exemption covers stopping only, never resuming
rcan 3.5.0 on PyPI 2026-09-12: the cross-registry exemption covers stopping verbs only, and a command with no consent record is refused. The runtime's pin bump is a separate step.
protocol P1 Shipped A new protocol SDK release whose changelog records that the cross-registry exemption now covers only the stopping verbs and that a cross-registry command with no consent record is refused. 2026-09-12
16 Phone commands travel through the server that checks owner and pace
Shipped 2026-09-12 in three steps: the relay function first, then the web client at app.opencastor.com, then the tightened Firestore rules. A signed-in client can now create only chat and observe commands, and only with its own identity as the issuer; everything that can change or move a robot goes through the server callable. The phone app people install is the Swift OpenCastor app, which never wrote to this queue, and the older Flutter phone build expired from TestFlight in July, so the rules broke no installed client.
phone app P1 Shipped The published rules file shows that a phone cannot create a system-scope command directly, and the release note records that those commands now go through the server-side path that carries the owner check, the pacing control and an attributed issuer. 2026-09-12
17 An unconfigured robot refuses investigator requests and files its own incidents · in the essay
Live on my arm since the 2026-09-12 restart. With no trusted authority set the handler refuses every requester and the conformance row fails until one is listed; the generated config now carries the empty list. A stop filed its own incident record within the same second (observed). The reported flag is set only by a submission that succeeded, the article label is corrected, and the signed submitter reads the log rather than a hand-supplied list. Follow-ups 2026-09-13 (commits 5d00127 and 8948545): the incident log keeps its chain tail in memory, takes a cross-process lock, rotates at a size bound with a carry-over line so the chain crosses the rotation, and has its own link checker, which answered exit 0 across the 79 records on my arm's log; one reader answers whether the robot can accept an authority everywhere that question is asked; both submit commands share one path. A link check is not an outside party's verification.
robot runtime P1 Shipped Public commit and release notes stating that the investigator-access path refuses every requester unless an allowlist is configured, that the conformance row no longer passes on a configuration flag, that incidents are filed by the system rather than by hand, and that signed submissions are derived from the log. Two published essay sentences can be dated. 2026-09-12
18 New actors are counted and flagged, and the roster gate is switched on · in the essay
Hub half live 2026-09-14: the declared-roster gate is armed for both live orgs by deployment configuration, not by a code default (the default stays off, so the essay sentence stands); a rostered id is accepted, an unlisted id gets 403 with the roster reason and an audited attempt. Worker half deployed 2026-09-14: first-seen actor counts on the health and pulse surfaces, and two deterministic rules (a missing ledger sequence number, a step change in new identities) on the nightly run that already existed, writing one audit row per org per day. Nothing here detects an unregistered agent and nothing blocks. First nightly run and live surface checks pending.
PlatChat P1 In progress The detection rules ship as a public, unit-tested file. The published sentence that this enforcement is off by default stays true and is deliberately not edited; what changes is that the operator's own organizations no longer run with it off. link
19 Creating a channel is gated and recorded as an audited fact · in the essay
Deployed 2026-09-14 (PlatChat hub). Channel creation now makes the same paused-workspace check the message and action routes make, before it reads the body; an agent must be on the org's declared roster and an org with no roster refuses the agent by name; a real channel mint and a real participant change are each one hash-chained audit row naming the acting principal, and a re-open adds nothing. Checked live on both orgs after the restart: the rostered agent re-opens its channel, an unlisted id is refused and mints nothing, both orchestrators kept their sessions. Admin-session mint and chain check pending a member session. The hub refuses on its own surface; nothing is enforced on anyone else.
PlatChat P1 In progress Nothing is observable from outside; the hub is organization-gated. A dated line here and the public commit adding the gate and its chained audit record. link
20 Pausing the agent hub stops its work, not only its speech · in the essay
Deployed 2026-09-14 (hub and both orchestrators restarted). A paused workspace now stops the orchestrator's turns and the nightly job's spend, not only its posts: the room hears the refusal, polls the policy once a minute, suspends its timers, and logs a heartbeat so paused reads differently from crashed; an unreadable policy spends nothing. The false claim that the budget counter persists is deleted; it is per-instance and resets on restart. An unanswered escalation is filed as an assist request through the hub, which is off until an atlas is chosen. PlatChat pauses itself; nothing is enforced on anyone else. Live pause test on a quiet org pending.
PlatChat P1 In progress Nothing is observable from outside. A dated line here and the public commits; the essay's paragraph about a pause that is only a mute is then narrowed to what stays true. link
21 The evidence chain publishes a head, so later truncation contradicts a public record · in the essay
Deployed 2026-09-14 (worker version 2e3ea13f, no migration needed). The platform publishes its ledger head at a member route and a grant route, the pack seals its own head, the offline checker takes an expected head and fails when the carried chain does not reach it, and all seven over-claims about order and completeness were rewritten. Live so far: the head route answers the same 404 to a stranger whether the org exists or not. Still to run with a member session: read the head, pull a pack, and re-run the tail-truncation experiment against it. The row gets its date after that.
PlatAtlas P1 In progress A member or a granted auditor can fetch the chain head and pin it; the published verifier's help lists the option that demands a head; the commit removing the completeness wording from the customer-facing note is public. link
22 Evidence packs stop claiming anomaly detection and incident response that do not exist · in the essay
Deployed 2026-09-14 with PA-05. The two statements were narrowed to what the evidence backs: CC7.2 now says logging only and that the service does not itself flag unusual activity; MANAGE 4.1 no longer names incident response. Both rows stay backed, because the evidence behind them did not change. Still to run: read a fresh pack with a member session and confirm the wording.
PlatAtlas P1 In progress Any customer or auditor who exports an evidence pack sees the two control statements narrowed to what the code does. This is the one item here that changes what an auditor is told directly. link
23 Producers can no longer invent the labels the compliance mapping reads · in the essay
Deployed 2026-09-14 with PA-05 (migration 0037, an additive column). The vocabulary is a published closed set; an unknown label is stored under a bucket that lights no control, the producer's original string is kept beside it, and every bucketed record is itemised in the pack. Nothing is refused. Live: the production table holds no bucketed rows and the column is present. Found on the way: the crosswalk keyed on config.change while the producer has only ever emitted config.changed, so every recorded configuration change lit no control; settled on the producer's spelling, with the old one disclosed as an alias. Still to run: ingest an unknown label with a credential and read it back bucketed.
PlatAtlas P1 In progress The allowed label list ships as a published constant, and an exported pack names any unrecognised label in its exceptions instead of quietly scoring it. link
24 An action and its own approval no longer read as a human approval
Deployed 2026-09-14 with migration 0039 applied first: all 47 recorded approvals were signed by the action's own host key and are now labelled host-attested, itemised in the pack's exceptions and counted; key role and custodian are declared at registration and verified by nobody; the SOC 2 oversight control no longer answers with a human approval for a host-attested record. Nothing is blocked. Live check of a fresh pack pending a member session.
PlatAtlas P1 In progress An exported pack shows what class of key signed each approval and lists machine-signed approvals in its exceptions, so a reader can tell a co-resident signature from a person's. link
25 Refusals are recorded and signed, not only approvals
Deployed 2026-09-14 (worker + PlatChat hub). A refusal is now signed and exported on the same path as an approval, stored with its decision verbatim, and the pack carries denied_count. Live check of one denied action pending a member session.
PlatAtlas P1 In progress An exported pack contains refused records and a refusal count, which no earlier pack could show at all. link
26 The offline checker recomputes a pack's summary numbers instead of trusting them · in the essay
Deployed 2026-09-14 (worker + verifier fixes through 6a4eb4a). The checker now recomputes coverage, exceptions, approval binding and action class per record and fails on a mismatch; a same-key approval is reported as self-signed. Live tamper re-run against a fresh production pack pending a member session.
PlatAtlas P1 In progress The published checker prints a field-by-field agree or disagree table, and a fresh pack names where its keys can be resolved, so an outside reader can check the summary without anything supplied out of band. link
27 The compliance export states in the file whether it is complete
Deployed 2026-09-14 with the composite index (migration 0038) applied first. JSON pages on a (ts, id) cursor with has_more; the CSV carries an X-Audit-Truncated header and a marker row when it stopped at its limit; the legacy before parameter now says it cannot page. Live check of the header on a real export pending a member session.
PlatAtlas P1 In progress A customer downloading the compliance export sees completeness declared in the file itself; the commit is public. link
28 Each chain entry commits to the content of the record it covers · in the essay
Deployed 2026-09-14 with migration 0040 applied first. Ledger entries written from today carry hash_version 2 and commit a digest of the signed attestation bytes; the 21 entries written before it stay version 1, bind identifiers and timestamps only, and are never rewritten. The pack's ledger note now says what the digest buys, where the signature already does the work, that approvals are not in the chain, and that PlatAtlas still holds the key that writes it. Live check of a fresh entry pending a member session.
PlatAtlas P1 In progress The published checker accepts packs whose chain rows carry a content digest and rejects one whose content was edited afterwards. The migration and the rule are visible in the public repository. link
29 Every link the registry hands out resolves to a real address · in the essay
Live 2026-09-14: every URL the registry returns now points at robotregistryfoundation.org, which resolves; the dead hostname no longer appears in any handler. The token issuer string deliberately still names the old host because the robot runtime checks it for equality; changing it is a coordinated release, not a rename, and is tracked separately.
registry P1 Shipped A reader following any link out of a registry response reaches a host that answers, instead of a hostname with no address record. 2026-09-14
30 The register can count and page through its whole corpus · in the essay registry P1 Planned The registry index reports a number equal to what a reader gets by paging the list to exhaustion, and returns a cursor so the whole corpus can be walked. The public dashboard shows the same number.
31 A public facts page states what the register actually holds today · in the essay registry P1 Planned A live facts page states the corpus size, the single-operator concentration, the empty revocation list, the one-node federation and the May 2026 reset, with numbers that match the public interface, and the line telling regulators and insurers they can rely on the record is gone.
32 A weekly signed snapshot is stored off the account and publicly pinned · in the essay registry P1 Planned A dated, signed snapshot head is published every week where any reader can pin it and compare later, so a future rewrite contradicts a record already in third-party hands.
33 The transparency log carries real digests, links each entry, signs its head · in the essay registry P1 Planned The log publishes a signed head anyone can verify against the published root key, and every entry after the change links to the entry before it.
34 The root node publishes its keys or stops advertising what it cannot do · in the essay
Live 2026-09-14: the root node manifest now advertises only the verbs its configured key material supports. No key is configured yet, so it serves register and resolve, three null keys, and an unsigned block that names the missing variables; verify and delegate return only when a key is published and a self-signature proves control of that key and nothing about the operator's independence. The published schema was relaxed to allow the null it had been failing on. Publishing the key is a separate operator step, not yet done.
registry P1 Shipped The root node's published manifest either carries its public keys with a self-signature anyone can check, or no longer advertises the verify and delegate capabilities. A federation peer reading it can tell which. 2026-09-14
35 The federation endpoint stops documenting a signature it never checks · in the essay
Deployed 2026-09-14: the signature field is gone from the push-sync contract, the endpoint states that an admin token plus the delegation allowlist is all that authenticates a push, a node with zero delegations answers 501 rather than a 403 that implies a list, and the federation page states the live facts (one node, zero delegations, resolve responses unsigned). Checked live: page copy and the unauthenticated 401. The 501 check needs the admin token, pending.
registry P1 In progress The sync endpoint no longer documents a signature field it discards, a caller is told plainly that federation is not enabled on this node, and the federation pages state one node and zero delegations. link
36 One identifier gets one authoritative answer, and no tier is auto-granted · in the essay registry P1 Planned An upgrade request on the older registry is refused with a not-implemented status and a pointer to the endpoint that actually verifies, every public record there reads at the lowest tier, and the same identifier no longer resolves to two different authoritative answers.
37 Watermark checks recompute the mark instead of asking the robot · in the essay protocol P1 Planned The protocol site and both published SDKs cite the same section number as the normative text, the SDKs ship a check that recomputes the mark with its limits stated, and an upstream proposal for the key-separation amendment is visible.
38 A published table says which version each protocol section is at · in the essay protocol P2 Planned The protocol site publishes a per-section version table matching the stamps on the published sections, and says in its own words that the sections do not share a version and that two of them currently disagree.
39 The robot stops describing its own state as verified or enforced · in the essay robot runtime P1 Planned Anyone reading the published runtime can see that no code path writes the word verified into a status answer, and the released package's watermark endpoint documentation says what it actually proves. This turns the essay's caveat that nothing here is verified by software from a claim into a property of the code.
40 The one request cap that runs fails closed and covers the arm · in the essay
Live 2026-09-15 on both robots. The pacing cap refuses when it cannot run instead of admitting, and writes a named reason; no role is unlimited; the arm commands cross the cap at the one point every arm dispatch passes through, with the eleven entry points named in the change. The review found that the console and the phone bring the wheels to zero with a zero-velocity move, not a stop, and that move was paced; both spellings of a halt are exempt now, and the limits were sized to the runtime's own motor ceiling so a held joystick no longer trips the cap. Checked live on the arm's computer after a clean restart: the cap refuses at exactly its limit with a machine-readable reason, the refusal is a row in the safety log, the hold view names the reason, and a stop goes through while over budget. The first restart hid a defect the tests could not see: the runtime's file-system facade forwards to the safety layer by a hand-written list, the new checks were not on it, and every arm command would have failed with a server error; fixed, and the test now goes through the real object. The item's premise about the role names was backwards: owner and leasee are the current names.
robot runtime P1 Shipped Public commit and changelog stating that the per-role request cap refuses on error instead of allowing, that it now covers the arm endpoints, and that the deleted role names are gone. The essay's pacing paragraph states all four facts and can be dated. 2026-09-15
41 Unknown tools are denied by default, and physical ones ask a person robot runtime P1 Planned The public commit showing that a tool not on the list is refused rather than allowed, that physical capability is a registration property, and a released command that lists the human approvals waiting.
42 Movement budgets are capped per window and cannot be quietly widened · in the essay robot runtime P1 Planned The public commit fencing the tuning job away from the pacing settings, a changelog line that either records a compute cap or states plainly that there is none, and a released vehicle driver carrying a per-window movement ceiling.
43 Gateway receipts name the caller and record refusals as refusals
Gateway half live 2026-09-14 on both robots. A receipt now names which credential acted, never which person, inside the signed bytes: checked live, a fresh receipt from each robot verifies, an edited credential fails, and a receipt signed before the change still verifies. The gateway's own report now files a refusal as a refusal, so a tripped stop no longer reads as evidence in its favour. The replay window evicts the oldest id instead of an arbitrary one, and the freshness claim in the README is now true with its limit stated: neither check runs until envelope signatures are turned on, and they are off on both robots today. Phone half, the cross-check against the gateway's record, rides the next app build.
gateway P1 In progress The published gateway release names the receipt version bump and the caller field, and a standalone receipt checker sits in the public repository that any third party can run against a receipt handed to them. link
44 The gateway records what it is about to do before doing it · in the essay
Live 2026-09-14 on both robots. The gateway now writes a signed intent record after every gate passes and before it calls the actuator, and keeps the outcome record after, linked to the intent by hash; an intent with no outcome is reported by the offline checker as a dispatch that never reported, never as a gap and never as an action that happened. The record path stays best effort: a failed evidence write neither blocks nor alters actuation. The review found and fixed a defect older than this item: concurrent requests could fork the in-memory audit chain, and the new trace writer could drop lines under load; both are locked and tested now. Measured cost on the arm's computer: about 17 milliseconds of blocking disk writes per command, roughly half of it before dispatch.
gateway P1 Shipped The public commit and release note show an intent record written before dispatch and an outcome record that refers back to it, and the conformance row for the protocol's strongest rule moves from specification text to implemented. 2026-09-14
45 Gateway records are numbered, linked, and copied off the robot
Half live 2026-09-14 on both robots: every new trace line carries a sequence number and the hash of the line before it, with the head kept in a sibling file written first, so a cut or reordered file is visible to anyone holding it; the checker walks a whole file and names the first gap, the first broken link, a torn last line, and the older unnumbered history, which binds nothing and never will. The other half is not live: a shipper unit is now generated when an ingest key is configured, but no shipper has ever run on either robot, no ingest key is configured, and not one signed record has left the box. A rotated or truncated file now stops the shipper with a named finding instead of re-sending from the start.
gateway P1 In progress The published release adds a sequence number and a link to the previous record, and the public checker gains a mode that walks a handed-over file for gaps, so a reader can check for missing records without trusting the operator. link
46 A published revocation reaches the robot inside the advertised deadline · in the essay gateway P1 Planned The release note states that the key cache expires within the interval the registry publishes, the revocation resolver is present in the public repository, and a reader can confirm from the public registry that a shipped consumer now honours that interval.
47 Benchmark results carry an anchor the robot cannot rewrite afterwards robot runtime P1 Planned A verify command in the published tool's help, and a published benchmark bundle that a third party can check offline with the released checker without asking the operator for anything.
48 Signing keys and the device move out of the agent's reach · in the essay gateway P1 Planned Public commits showing the installed services carrying hardening settings and the gateway bound locally by default, a harden command in the released tool's help, and the key custody posture readable from the gateway's own status so any operator can see which posture theirs is in.
49 A shared recording states its own gaps instead of implying completeness
Viewer half live 2026-09-14 on mcpreplay.dev: the page now says a trace is an honest record as far as the file goes; the meta strip says when a file has no session start, when it is a rotated tail and how many malformed lines were skipped; the format document marks the attestation and provenance sections as specified and emitted by no producer today. Recorder half merged the same day: a rotated trace now opens with a line saying it is a tail and what is missing; it reaches users with the next mcp-tape release, not yet published.
recorder P1 In progress The live replay site no longer calls the recording the only honest record, its documentation marks unimplemented format sections as specification only, and a rotated file carries its own incompleteness line. Anyone who opens the site can see all three. link
50 A declared safety flag reads as a claim, not a verified fact · in the essay protocol P2 Planned The published robot description schema describes its safety flags as author declarations rather than verified properties, ships a machine-checkable safety manifest schema, and the release records the strict-mode evidence requirement.
51 The protocol names which robot-to-robot channels are sanctioned · in the essay protocol P2 Planned The published schema carries a declared peer and shared-store allowlist, the conformance suite ships a runnable case in which a command to an undeclared peer is refused, and the upstream proposal for the normative prohibition is visible.
52 A hardware driver enforces the tier it accepts or stops advertising it protocol P2 Planned A new driver SDK release whose changelog records either a real driver-level tier refusal or the removal of the parameter that was never read, so the public signature no longer advertises a check the code does not perform.
53 Redaction counts and refusal wording appear in what customers receive
Deployed 2026-09-14. Four comments that contradicted the code they sat in are corrected (retention horizon, rate limiting enforced, the sign-in allowlist still in place, the bundle export shipped and hashed rather than signed); revoking an agent is now documented and reported as an annotation that closes no credential, because none is stored; a trace ingest now returns how many values redaction replaced, never what they were. Live check of the count on a real ingest pending an API key.
PlatAtlas P2 In progress The ingest answer and the evidence pack state how many values were redacted, which any customer pushing a record can see for themselves. link
54 A machine authorization stops being labelled a human decision
The gate's check is now named for what it is, a test that an approval reference is present, and its allow reason no longer says human-approved; it says the approval was declared by an authenticated session. The robot motion path, dark today, now requires an approval signed by a registered key other than the sender's for control-scope commands and refuses otherwise. A signature from a second key shows a second key signed, not that a person was present. No outside-visible surface; dated on the repository.
PlatAtlas P2 Shipped Nothing is observable from outside; this is library code. The renamed check and the reason text that no longer asserts a human signature are visible in the public repository. 2026-09-14
55 A reviewing panel records that it is the same model reviewing itself
Deployed 2026-09-14 (both orchestrators restarted, hub redeployed). The harness can no longer fall through to plain completion by omission; every routing decision now records the generator model, the verifier model and whether they differ, inside the signed payload and on the org's hash chain, and the verdict line in chat says when the verifier is the same model as the generator. A second local model is an option, off by default, and is only recorded when the backend can actually switch models. Live check of one architect turn pending.
PlatChat P2 In progress Nothing is observable from outside; the hub is organization-gated. The commit making the review step an explicit choice rather than a silent default, and recording the panel composition, is public. link
56 The register shows when each registered machine last reported in registry P3 Planned A public liveness view shows, per registered entity, when it last self-asserted and whether that is stale against a published threshold, so a third party can see that something registered has gone quiet.
57 A stop produces a signed receipt anyone can check without the operator · in the essay protocol P3 Needs someone else A stop-receipt format published on the protocol site with a verifier in both SDKs, so a third party can check a claimed stop without trusting the operator, plus a visible upstream proposal for the normative clause. This is the concrete form of the essay's fourth rule.
58 Stops ordered and stops confirmed are counted separately in evidence packs
Deployed 2026-09-15 with its migration applied first. The evidence platform now has a record class for a stop order paired with a gateway-signed proof, and a pack reports how many stops were ordered and how many were confirmed, itemising each one that reads ordered, not confirmed; the order is an index row the host wrote, the proof's authority is the gateway key's, and the platform never holds the stop. An incident report is a signed record class on the same path that lands in the append-only ledger, cannot be deleted through the trace route, and renders with a deadline counted from the reporter's declared discovery time; an empty section says plainly that it proves nothing. The robot side can file a byte-identical signed report from the command line. Honest gaps: nothing yet emits a stop receipt and nothing carries an order's id to a robot, so every order reads ordered, not confirmed until both exist; the live checks need a member session or an ingest key, neither of which is active.
PlatAtlas P3 In progress An evidence pack can show an auditor how many stops were ordered and how many were confirmed by a signed receipt, and that an incident record exists with its own clock, both readable from the pack without the vendor's help. link
59 Public documents stop promising guarantees the code does not provide · in the essay gateway P2 Planned The rewritten public gateway readme leads with what the gateway is for instead of with a guarantee, the canonical disclaimer's new wording appears in every published copy including the documentation sites, and the dead relay code is gone from the published package.
60 A published revocation procedure with notice, appeal and an error register · in the essay governance P3 Needs someone else A published procedure stating grounds, notice, appeal and publication; a history view listing every revocation and reversal with its reason; and an error register naming the May 2026 reset and the identifiers re-issued after it. The separation-of-duties role is published as vacant until a second person holds it.
61 The register publishes its running cost, funding status and a real deposit · in the essay governance P3 Needs someone else A published monthly cost of operation with the month it was measured, the unfunded roles named as costs, a plain statement that no company has committed funding, one real public deposit of a signed snapshot, and charter commitments marked with their live status.
62 A signed chain head is posted on a schedule by a separate key · in the essay PlatAtlas P3 Needs someone else A granted auditor can fetch the signed head and re-verify it against the published key list, and the pack carries the signed heads. Every rendering says producer-signed, not independent, until a second custodian signs.
Craig Merry

Craig Merry is a hard-of-hearing systems engineer in Sacramento, California. He builds PlatAtlas and its open-source OpenCastor robotics edition, pairing with Claude Code, and operates the registry and the runtime this plan repairs.