NodeLink console polish: friction found during epic
Itemized fixes noticed while verifying the NodeLink epic (5686) on app.dev.jaah.ai, from the UI child (5733) and the swarm-proof child (5734) reports. Each item is one small requirement; do them all, each with a web/API unit test.
## Directory › Machines › NodeLink
1. Plan off: hide the disabled store form and show only the "NodeLink is not on your plan · Change plan" notice. Disabled fields with placeholders read like a broken form.
2. The storage card needs its own heading. Its only status today is a bare "ready" chip.
3. Add "Refresh from AWS" to the store card. Today an adopted store recorded without an ARN has no console repair: Save is dirty-gated and the card sits on "Reading EFS…".
4. Add "Repair policy" to the store card or row, so the EFS policy can be rewritten for a `ready` NodeLink. Today Retry only appears on pending/failed rows.
5. A NodeLink that is `ready` but not in the file-system policy shows "Not mounted — The NodeLink is ready." on every node (`apps/api/app/routes/nodelinks.py` `_mount_of`). Say "Not in the file-system policy" and offer Retry/Repair.
6. A general NodeLink parked `pending` says "storage is not ready yet" next to a `ready` store. Name what is actually missing (for example, no file-system ARN).
7. A NodeLink stuck in `provisioning` should re-poll itself, as `deleting` rows already do.
8. The NodeLink "Nodes" picker offers hosts ("runs no work") and macOS nodes that cannot mount. List only nodes that can mount, or disable the rest and show the reason.
9. In Accounts NodeLink › Details, a host still "Waiting for you" shows as "Unknown — hasn't reported". Say "Not set up yet".
10. An attached node that is missing from the roster shows a bare uuid in row details. Show its name or "deleted node".
11. Row details make one request per attached node. Serve per-node mount state in one org-level request.
12. A plan-lapsed org cannot finish a stuck delete or detach nodes from this page, although the server allows both. Keep those two controls when the plan is off.
13. At 360px the "Get started" card covers the bottom of long lists.
## Node detail
14. The NodeLinks tab says only "The node reports it isn't mounted." for a co-located node. Carry the host helper's reason there (today the reason appears only on the HOST page, e.g. "accounts: unreachable …").
15. The tab shows "Accounts root: …/auth/.shared" while Accounts reads "Not mounted". Show the root only while that mount is up, or mark it stale.
16. Config snapshot shows `nodelinks` as raw JSON and `nodelink: mounted (file system unknown)`. Render name/state/path rows and drop "file system unknown".
## Add-node wizard and accounts copy
17. The wizard's NodeLink list offers NodeLinks that are not `ready` and shows no status. Show the status, or disable those rows.
18. Account copy still describes the retired switch ("any node with NodeLink on", "re-authenticate on a node with NodeLink on") in `accountModel.tsx`, `Accounts.tsx` and `AccountEditPage.tsx`. Say "a node with the Accounts NodeLink attached".
## API leftovers
19. A node group cannot say "no NodeLinks": `[]` is refused because no column stores it. Add the column and accept `[]` as "none".
20. Retire the legacy `nodelink` boolean on node orders and vnode creates. The web app now sends only `nodelinks`.
21. Add delete-path tests for the file-system ARN backfill (a minor code-review finding on PR #5049).
22. Operators cannot pick NodeLinks for another org's node or group, because the list route serves only the caller's org. Let an operator list the target org's NodeLinks.
Out of scope: the vnode NodeLink visibility defect and the swarm-proof rerun (both separate follow-ups of Task 5735). Do NOT change NodeLink provisioning or delete semantics, the EFS policy model, or shared-account rules. Do NOT add per-NodeLink uids, exec options or project binding.
Done means:
- Every numbered item is implemented, and each has a unit test that would fail without it. Cite test names per item in the report.
- On app.dev.jaah.ai, items 1–6, 8, 14–17 are observed in the console in Gmind (plan on) and TimeSaver2 (plan off), at 1280px and 360px. Cite a screenshot per item.
- `./dc check full` is green, the PR is merged to develop, and the PR's Jaah Deploy succeeded. Cite the PR number, merge sha and deploy run.
Outcome
All 22 NodeLink polish items merged (PR #5097, merge c9ab03c9), each unit-tested; Jaah Deploy 38184896423 succeeded and dev (v1.1.9185) was checked at 1280/360. Deferred: 5 small UI nits listed in the report. Swarm proof stays with 5862/5863.
Artifacts
Activity
- Ready
- Runner started
- Runner ended (done)