NodeLink list, dialogs and node attach UI
## Context
Epic: refactor NodeLink into many shared filesystems per org (PRD Task 5687, Architecture Task 5688). The original request, verbatim:
> Refactor NodeLink to:
> - NodeLink is a way to share a file system between multiple nodes (self-hosted, cloud, Jaah hosted, etc.)
> - Any tenant (that has NodeLink feature enabled) can create one or more NodeLinks - it is just an EFS with a default mount point
> - Org can have multiple NodeLinks
> - Any node can have multiple NodeLinks associated with it
> - Shared accounts as we have them now - turns into a one instance of NodeLink with mount point at {jaah-home}/auth . This is the only thing that has an effect of sharing accounts between nodes
> - Main purpose is to have a swarm of agents operating on a shared file system
The Architect's **C5** (web console). Depends on the live routes of the core child (org NodeLink CRUD, provision, `PUT …/{id}/nodes`), the agent-wire child (per-node mount state via the snapshot ingest), and the attach-doors child (node routes, create-door `nodelinks`).
## Acceptance criteria this child carries (PRD, verbatim)
- **AC1.1** "Directory › Machines › NodeLink shows the org's EFS (configure via Create new / Use existing as today) and a **list of NodeLinks** with, per row: name, kind (accounts / general), mount path, attached-node count, status. Names are fully readable (no truncation to a few characters at ≥ 360 px viewport; wraps or ellipsizes only after ≥ 20 visible characters with full name on hover/title). *Verify:* dev CP, open the page; observe EFS card + list; resize to 360 px and observe readable names."
- **AC1.2** "\"New NodeLink\" creates a general NodeLink with name, optional description, and mount path pre-filled `{jaah-home}/nodelink/<slug>` (editable). … Status progresses to `ready`; AWS errors shown verbatim (never a secret) and re-runnable." (UI half.)
- **AC1.4** "States: page renders a correct, non-empty-looking state for each of: plan feature off (page explains feature is off, no write controls), no EFS yet (prompt to configure EFS; New NodeLink disabled with reason), EFS provisioning/failed, EFS ready with only the accounts NodeLink, with general NodeLinks. *Verify:* web unit tests per state + dev CP visual check of the ready states."
- **AC2.1** "Node detail shows a **NodeLinks** section listing attached NodeLinks with per-node mount status (mounted / not mounted + reason) and an Attach/Detach control offering only the node's own org's NodeLinks. The old \"NodeLink\" on/off switch in Properties is gone (replaced by the accounts NodeLink's attachment)."
- **AC2.2** "The NodeLink page lets the admin attach/detach nodes (multi-select of the org's nodes) with the same live effect."
- **AC2.5** "Node wizard (every create door …) offers the org's NodeLinks to attach; the accounts NodeLink is checked by default when the org has the feature (today's behaviour) …" (UI half.)
- **AC5.1** "Delete requires an explicit, irreversible-action confirmation naming the NodeLink …" — **as narrowed by operator answer A3: the access point is deleted, the files stay in the EFS and are still billed; the confirmation must say exactly that.**
- **AC5.2** "A failure mid-delete leaves a visible, retryable state (never a silent half-delete)." (UI half: `deleting` + last error + Retry + "Delete anyway".)
- **AC6.1** "… Orgs without it see no write controls …"
## How (Architecture §5 C5 row, §3.3b, §3.4)
- Directory › Machines › NodeLink (`apps/web/src/pages/nodes/nodeLinkStore/NodeLinkStoreSection.tsx`): the **EFS card** (today's Create new / Use existing, unchanged) + a **NodeLink list** (name, kind, path template, attached count, status) + New / Edit / Delete dialogs + attach-nodes multi-select + a **row-details view**: access point id, root directory, "in file-system policy", per-node mount state, last error with Retry. On an adopted EFS, before the first general NodeLink, state that Jaah will own the file-system policy (replacing the org's own statements) and that the credential needs `CreateAccessPoint`, `DeleteAccessPoint`, `DescribeAccessPoints`, `PutFileSystemPolicy`, `TagResource`.
- New/Edit: mount path pre-filled `{jaah-home}/nodelink/<slug>`, slug following the name until edited; when `shadows_existing` (outside `{jaah-home}/nodelink/`) show the warning: what is there is hidden while mounted, a remount on edit lazily unmounts under live runners, and `noexec` applies. Accounts row: no delete, no path edit.
- Delete: type-the-name confirmation stating "files stay in your EFS and are still billed"; `deleting` state shows the last error with Retry and "Delete anyway" (whose confirmation states nodes that never reported may keep a stale mount until their next converge).
- 409 messages rendered inline on the field they concern: duplicate name, path overlap, Accounts managed by Jaah.
- Node detail: a **NodeLinks** section (attached NodeLinks, per-node state `mounted` / `not mounted` + reason incl. `unsafe_path` / `unreachable` / `helper_missing`, the effective accounts root) with Attach/Detach; REMOVE the Properties NodeLink switch.
- Add-node wizard and node-group form: NodeLink multi-select, accounts pre-checked when the org has the feature.
- Follow `docs/standards/ui-copy-standards.md` (short labels, one word where one does) and the supported viewport widths in `docs/standards/product-testing-requirements.md`.
- Project instruction: when testing in the UI, notice anything broken, inconvenient, unfriendly, suboptimal or done better elsewhere — file ONE follow-up task with itemized 1–2 sentence suggestions.
Quality bar (beyond geometry): a NodeLink name like "Research swarm shared workspace" must be identifiable at 360 px (≥20 visible characters, full name on hover) — a row that fits by shredding names to a few characters FAILS. Each state of AC1.4 must look intentional (explanation + next action), never a blank or spinner-forever. Error text is the server's human message, not a status code.
Credentials & reach:
- `jaah/debug/main/operator-login` — console login, dev CP https://app.dev.jaah.ai — **verified** (lands in TimeSaver2 whose Machines › NodeLink tab is shown). Use `app.dev.jaah.ai`.
- Unit tests — **verified**: worktree only.
Out of scope: Do NOT change the Cloud Connections dialog beyond keeping its read-only store reference correct. Do NOT add a second EFS per org or a NodeLink-picks-EFS choice. Do NOT add an EFS teardown control. Do NOT add per-NodeLink exec/read-only options, per-node path overrides, usage metrics, or project/task binding. Do NOT advertise or allow editing of the accounts NodeLink's path. Do NOT change API semantics (sibling children own them; file a follow-up if one is missing).
Done means:
- Every AC1.4 state — web unit tests: plan off (explanation, no write controls), no EFS (configure prompt, New NodeLink disabled with reason), EFS provisioning, EFS failed, ready with accounts only, with general NodeLinks.
- Readable names — web test (or Playwright at 360 px) with a 40-char name: ≥20 characters visible and the full name in `title`; dev CP screenshot at 360 px cited.
- Create / edit / delete flows — web tests: path prefilled from slug; shadow warning appears for `{jaah-home}/auth/abc123`; inline 409 messages on the right field; delete confirmation requires the typed name and states files stay and are billed; `deleting` shows last error + Retry + Delete anyway; accounts row has no delete/path edit.
- Attach both sides — web tests: NodeLink page multi-select sends `PUT …/{id}/nodes`; Node detail section lists attached NodeLinks with per-node state and Attach/Detach offering only the node's org's NodeLinks; Properties switch is gone.
- Wizard — web test: NodeLink multi-select present, accounts pre-checked, request carries `nodelinks`.
- Dev CP visual check — on https://app.dev.jaah.ai, TimeSaver2: the ready states render; cite screenshots in the report.
- `./dc check full` green; PR merged to develop; Jaah Deploy of the PR succeeded — cite PR number, merge sha, deploy run.
Outcome
NodeLink list/dialogs/attach UI, node NodeLinks tab, wizard+group picker: PR #5025 (6420d2f5b) + 360px tab fix #5035; Jaah Deploy 38161515657/38164065623 ok. Gate green except unrelated e2e flakes. 9 follow-ups in report (task create 403).
Artifacts
Activity
- Draft
- Ready
- Runner started
- Runner ended (done)