Skip to content

Commit 5ca380b

Browse files
tuanngocptnclaude
andcommitted
docs: nport-api is deleted from staging
The pre-rename node script (ADR-0049) had sat unrouted since 2026-08-06, holding dead SubdomainLease / Registry / SourceQuota objects. Checked before deleting, because deletion destroys those Durable Objects and a tunnel they still owned would be stranded if nothing else could see it. Nothing is stranded: `apps/node/src/reconcile.ts` sweeps the *account's* tunnel list rather than its own records, the `nport-` prefix is what marks them, and both scripts shared one account. So deleting the Worker turns its leases into orphans that `nport-node` reaps with the CNAME ownership proof intact (invariant 8) — the outcome, not a leak. Also confirmed it existed only on staging; the production account has no such Worker, so there was no chance of deleting the wrong one. Verified after: the four remaining Workers are present, `/v1/health` answers, `/v1/meta` still crosses the service binding, and the site serves. The OPERATIONS entry keeps the reasoning rather than just recording the deletion — the next rename will face the same question. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017ND8DWQLFchUayY5xeP6vb
1 parent 378561c commit 5ca380b

2 files changed

Lines changed: 18 additions & 10 deletions

File tree

docs/OPERATIONS.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,10 +106,14 @@ For a fresh deployment (also the basis of `docs/SELF_HOSTING.md`):
106106
The registry resolves it on **every** registration, so deleting it delists the node within
107107
`NODE_DELIST_AFTER_SECONDS` rather than at the next deploy. That is the intended way to withdraw a
108108
node from the directory.
109-
8. **`nport-api` on staging is an orphan** — the pre-rename node script (ADR-0049), still deployed,
110-
no route, holding dead `SubdomainLease` / `Registry` / `SourceQuota` objects. Safe to delete, and
111-
deleting it destroys those Durable Objects, which is why it is a decision rather than a deploy
112-
step. Nothing routes to it and nothing reads it.
109+
8. **`nport-api` was deleted from staging on 2026-08-09**, and the reasoning is worth keeping for
110+
the next rename. It was the pre-rename node script (ADR-0049): no route, holding dead
111+
`SubdomainLease` / `Registry` / `SourceQuota` objects, which deletion destroys — so it was the
112+
operator's call rather than a deploy step. What made it safe is that **reconciliation is
113+
account-wide**: `apps/node/src/reconcile.ts` lists the *account's* tunnels and reaps any named
114+
`nport-*` with no live lease, so anything the old script left behind falls to `nport-node`'s sweep
115+
with the CNAME ownership proof intact (invariant 8). Deleting the Worker turned its leases into
116+
orphans that the surviving one cleans up, which is the outcome, not a leak.
113117
9. Zone rate-limiting rule on `api.<domain>``infra/terraform` applies it: 600 requests / 60 s per IP per colo, blocked for 10 minutes. Deliberately well above the **gateway's** own 60/min per-source limiter, which it sits outside rather than replaces. The node and the registry have no limiter of their own; applying one twice would charge a caller against two counters for one request.
114118
8. Verify `api` and the rest of the reserved list cannot be claimed.
115119

docs/ROADMAP.md

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1385,12 +1385,16 @@ what `nodeProofRecordName`/`nodeProofRecordValue` produce, and every environment
13851385
to serve because it could not get itself listed — trades a working tunnel for a tidy directory. What was
13861386
missing was not an exception; it was a record nothing created, and now something does.
13871387

1388-
**One thing the deploy left behind.** Renaming the Worker did not delete the old one: `nport-api` is
1389-
still deployed on the staging account with its Durable Objects, and Cloudflare reassigned
1390-
`api.nport.online` to `nport-gateway` without complaint — so the concern that the rename would collide
1391-
on the custom domain did not materialise. What remains is an unrouted script holding dead lease state.
1392-
Deleting it also deletes those DOs, which is fine here and is **the operator's call, not a deploy
1393-
step**: `docs/OPERATIONS.md` § Inventory is where it belongs, and nothing depends on it in the meantime.
1388+
**One thing the deploy left behind, now cleared.** Renaming the Worker did not delete the old one:
1389+
`nport-api` stayed on the staging account with its Durable Objects, while Cloudflare reassigned
1390+
`api.nport.online` to `nport-gateway` without complaint — so the feared custom-domain collision never
1391+
materialised. **Deleted 2026-08-09** on the operator's instruction, after checking the one thing that
1392+
made it a decision rather than a deploy step: deletion destroys those DOs, and any tunnel they still
1393+
owned would be stranded if nothing else could see it. Nothing is stranded, because
1394+
`apps/node/src/reconcile.ts` sweeps the **account's** tunnel list rather than its own records — the
1395+
`nport-` prefix is what marks them, both scripts shared one account, and an orphan with no live lease
1396+
is exactly what that sweep exists to remove. Verified after: the four remaining Workers are present,
1397+
`/v1/health` answers, and `/v1/meta` still crosses the service binding.
13941398

13951399
**Still not proved: failover.** G5 wants a *second* node on a second account and domain, with a client
13961400
moving to it when the first stops mid-run. One node in the directory cannot demonstrate that, and

0 commit comments

Comments
 (0)