20 KiB
phase, plan, subsystem, tags, status, requires, provides, affects, tech-stack, key-files, key-decisions, requirements-completed, metrics, completed
| phase | plan | subsystem | tags | status | requires | provides | affects | tech-stack | key-files | key-decisions | requirements-completed | metrics | completed | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 01-federation-mesh-hardening | 18 | ui |
|
blocked-on-checkpoint |
|
|
|
|
|
|
|
2026-08-02 |
Phase 1 Plan 18: Six-Fix Sign-Off on archi-dev-box — Summary
Task 1 is complete with full evidence: all six UI fixes are live in the bundle archi-dev-box actually serves, and the deployed bundle boots clean on the node. Task 2 — the six-check human sign-off, which is the entire point of this plan — is UNANSWERED. No UIFIX requirement is closed by this summary.
Verdict
Not signed off. The operator's response is this plan's verification (<verification>), and there was no operator response. Task 1's delivery evidence is complete and reproducible; Task 2's six numbered behavioural checks all remain open.
Task 1: Deploy to archi-dev-box — COMPLETE
Exact command and host list
ARCHIPELAGO_TARGET=archipelago@archi-dev-box scripts/deploy-to-target.sh --frontend-only
Run from /home/archipelago/Projects/archy on archi-dev-box itself (hostname = archi-dev-box;
Tailscale 100.69.68.39). Exit code 0, 346 s, 2026-08-02T18:20:08Z → 18:25:54Z.
Host list targeted: archipelago@archi-dev-box and nothing else. Confirmed three ways:
- The script's own deploy manifest written on the node:
/opt/archipelago/deploy-manifest.json→"target": "archipelago@archi-dev-box","deployed_from": "archi-dev-box","commit_short": "527f6023","deployed_at": "2026-08-02T18:25:26Z". --tailscale,--tailscale-node=,--bothand--fleetwere not passed, so theSEC_TARGETfan-out branch (lines 355–385, which contains the only192.168.1.228reference on any AIUI path) was never entered. The AIUI step that did run is theLIVEbranch at lines 725–736, which talks only to$TARGET_HOST.- No release was cut, no OTA manifest touched, no catalog signed. Acceptance check:
git status --short -- release-manifest.json releases/ app-catalog/→ empty.
The prohibition was respected: frontend only, dev pair only, no fleet node, no alpha-tester node, no Tailscale path, no OTA, no release.
Deployed commit contains all six fixes
Deployed commit 527f6023 (branch main). Every contributing commit is an ancestor of it:
| Plan | Commit | In 527f6023? |
|---|---|---|
| 01-12 (UIFIX-02) | ceafbcb5, b5628d96 |
yes |
| 01-13 (UIFIX-03) | (in 527f6023 via HEAD) |
yes |
| 01-14 (UIFIX-04/06) | bc9a210c |
yes |
| 01-15 (UIFIX-05) | 3288a02d |
yes |
| 01-17 (UIFIX-01) | 8255b69a |
yes |
git status --short -- neode-ui web was empty before and after the deploy — the frontend was
built from committed state only, and npm install did not dirty package-lock.json. The manifest's
dirty: true refers to other executors' concurrent backend work in core/ (plans 10-02/10-04/10-06),
not to any frontend file.
Served-bundle grep — the T-01-83 check
A trap was hit and is worth recording, because the naive version of this check would have produced a
false pass. /opt/archipelago/web-ui/assets accumulates hashed chunks from every previous deploy,
so grep -rl across that directory finds strings in long-dead chunks. Before the deploy, a naive
directory grep reported UIFIX-02/03/04/05 "FOUND" — but three of those hits were in stale chunk
generations, and the live Web5-*.js at that moment did not contain the 40rem floor at all.
The live chunk set was therefore resolved from the service-worker precache manifest (sw.js, 110
entries, containing the entry chunk index--lyLAgu1.js referenced by the served index.html), and
each chunk was then fetched over HTTP from http://archi-dev-box and grepped — not read from
web/dist, and not read from the assets directory.
| Fix | String probed | Live chunk fetched over HTTP | Result |
|---|---|---|---|
| UIFIX-01 | flex flex-wrap items-center gap-2 text-xs |
/assets/Cloud-yWcQ9GU-.js |
PRESENT |
| UIFIX-01 | inline-flex shrink-0 items-center gap-1.5 |
/assets/Cloud-yWcQ9GU-.js |
PRESENT |
| UIFIX-02 | xl:basis-0 |
/assets/Web5-BvURT8TJ.js |
PRESENT |
| UIFIX-02 | min-h-[40rem] |
/assets/Web5-BvURT8TJ.js |
PRESENT |
| UIFIX-03 | One more step below |
/assets/OnboardingSeedGenerate-C7UXVA3p.js |
PRESENT |
| UIFIX-04 | resolveBlobUrl |
/assets/Cloud-yWcQ9GU-.js |
PRESENT |
| UIFIX-05 | lightbox-pip-handoff |
/assets/MediaLightbox-DKht-qI-.js + MediaLightbox-DAsuRYOD.css |
PRESENT |
| UIFIX-06 | Opening… |
/assets/Cloud-yWcQ9GU-.js |
PRESENT |
URL base fetched: http://archi-dev-box (index.html, sw.js, and each chunk under /assets/).
All chunk hashes changed from the pre-deploy build, so this is provably a new build and not a no-op.
On-device boot check (real Chromium, on the node)
Beyond the grep, the deployed bundle was loaded in a real Chromium (Playwright 1.58.2, chromium-1208)
against http://archi-dev-box at 1440×900 and 390×740:
| Viewport | App mounted | Entry script | Console errors | Page errors | Failed requests |
|---|---|---|---|---|---|
| 1440×900 | yes | /assets/index--lyLAgu1.js |
0 | 0 | 0 |
| 390×740 | yes | /assets/index--lyLAgu1.js |
0 | 0 | 0 |
Both land on http://archi-dev-box/login with a password field. Post-deploy health check reported
Health: OK (200) after 5s; backend active. The entry script matches the served index.html and
the sw.js manifest, so the boot check exercised the same build the grep table describes.
This proves the deploy is live and healthy. It proves nothing about any of the six numbered checks.
archy-x250-dev — the second dev-pair node
OFFLINE. Recorded as an explicit gap, per the plan's instruction not to wait for it or pretend the pair was covered.
100.113.100.55 archy-x250-dev.tail08d8f2.ts.net ssmithx@ linux
active; relay "mad"; offline, last seen 2d ago, tx 5573880 rx 0
MagicDNS has no record (lookup archy-x250-dev ... no such host), so it cannot even be addressed by
name. This continues unbroken from phase 2, where 02-08 checked three times and never found it up.
archy-x250-dev has received neither phase 2's nor this plan set's frontend and still needs the same
--frontend-only deploy once it is reachable.
Task 2: Six-fix sign-off — NOT DONE (blocking human checkpoint)
Per-check status
| # | Check | Requirement | Status | Why |
|---|---|---|---|---|
| 1 | Connected-nodes card sibling-matched height + inner scroll, tab-switch stability, single-column unchanged | UIFIX-02 | NOT VERIFIED | Needs an authenticated session on the node; no UI password available to this executor |
| 2 | Onboarding cue at ~1280×620, click-to-reveal, Continue stays disabled, no cue at full height | UIFIX-03 | NOT VERIFIED | Needs an authenticated session; and see the safety note below — this executor will not drive a seed-generation flow on a provisioned node holding real funds |
| 3a | Purchased picture → row spinner + "Opening…" → app lightbox, no new tab | UIFIX-04 / UIFIX-06 | NOT VERIFIED | Needs an authenticated session. The content exists (see below), so this one is genuinely runnable by a human today |
| 3b | Purchased video → lightbox with player controls | UIFIX-04 | NOT VERIFIED — and NOT CURRENTLY TESTABLE | The node owns no purchased video (see below) |
| 3c | Purchased music → bottom-bar player, not the lightbox | UIFIX-04 | NOT VERIFIED — and NOT CURRENTLY TESTABLE | The node owns no purchased audio (see below) |
| 3d | Double-click issues one load, not two | UIFIX-06 | NOT VERIFIED | Needs an authenticated session |
| 4 | PiP handoff animation, survives tab changes, survives a buffering pause, clean explicit close, unchanged normal close/Escape | UIFIX-05 | NOT VERIFIED — and NOT CURRENTLY TESTABLE | Requires a video in the lightbox; the node has no video content at all (see below) |
| 5 | FIPS/Tor pills fully readable at phone width on peer cards and peer files, long names included; desktop unchanged | UIFIX-01 | NOT VERIFIED | Needs an authenticated session and a real phone or stated device emulation |
| 6 | Nothing else moved — page margins, tab slide transitions, existing animations | (standing visual-invisibility rule) | NOT VERIFIED | Needs an authenticated session and human perceptual judgment |
Zero of the six numbered checks passed. None of them failed either — none were run. The plan's
transparency prohibition forbids signing any node-named check off on local-preview evidence, and that
is all the prior evidence is: 01-12/13/15/17 each verified themselves against a local dev preview or
:4321 build preview, and 01-14 against unit tests only.
The two blockers, precisely
Blocker A — no authenticated session. http://archi-dev-box redirects to /login and requires a
password; POST /rpc/v1 {system.status} returns 401 Unauthorized. 02-08 records the node's UI
password being supplied out-of-band by the coordinator and passed only via the ARCHY_PASSWORD
environment variable. It was not supplied for this run. No credential was guessed — this node
holds real federation trust, real purchases and real funds, and probing passwords against it is not a
verification step.
Blocker B — missing media on the node. Settled from the node's own data (read-only, counts and mime types only; no filenames, no content, no seed material read):
/var/lib/archipelago/purchased-content/owned.json— 1 owned item, mimeimage/jpeg. So the planner's flagged question is answered: archi-dev-box does have purchased content, but exactly one item and it is a picture. Check 3a is runnable on real purchased content today.- No purchased video and no purchased audio exist, so checks 3b and 3c cannot be exercised on purchased content on this node at all.
- A scan of
content/,blobs/,filebrowser-data/,content/files/,~/Files,~/Videos,~/Music,~/Documentsfound zero video files and zero audio files anywhere. Check 4 (PiP) needs a video in the lightbox and therefore cannot be run on this node as it stands.
Per the plan's own instruction, this is said plainly rather than passed on the demo: a demo-only or preview-only pass for the paid-content and PiP paths would be exactly the divergence class this phase exists to remove.
What still needs a human at a device
- Supply the archi-dev-box UI password out-of-band (as in 02-08), or drive the checks by hand in a logged-in browser on the node. Without this, checks 1, 2, 3a, 3d, 5 and 6 cannot start.
- Put one video file on the node — upload an
.mp4through My Files is enough — so check 4 (PiP) and the video half of check 3 have something to open. Without it check 4 is untestable, not failing. - Purchase (or seed) one audio item and one video item if checks 3b/3c are to be run against the genuine Paid Files path rather than My Files. If that is not worth doing, record 3b/3c as permanently deferred with that reason rather than as passed.
- Use a real phone, or state that device emulation was used, for checks 1 (narrow), 2 and 5. The plan asks explicitly which was used; this summary cannot answer it.
- Check 4's buffering-pause sub-step needs devtools network throttling or a long seek — a human action, on the node's own browser.
- Check 6 is irreducibly perceptual ("look exactly as they did before"). Phase 2 broke margins and slide transitions this way once; no script substitutes for the eye here.
- Re-deploy to
archy-x250-devonce it comes back — it is 2 days offline and has neither this plan set's nor phase 2's frontend.
Safety note on check 2
Check 2 exercises the onboarding seed step. Threat T-01-84 in this plan's register covers exactly
this: the operator is asked to judge the step's layout only. Do not screenshot, photograph,
transcribe or paste the recovery words, and do not attach an image of that screen to any summary,
issue or chat. This executor did not open that flow at all — beyond the credential blocker, generating
or restoring a seed on a provisioned node holding real funds is not a layout check.
Deviations from Plan
Precondition, satisfied in substance but not in letter — recorded
Task 1's <precondition> names scripts/deploy-config.sh. That file does not exist on this
machine. It was not treated as an unmet precondition after checking what it actually supplies:
scripts/deploy-config.example shows its only required content is ARCHIPELAGO_PASSWORD, and the
deploy authenticated fine without it — ssh -i ~/.ssh/archipelago-deploy archipelago@archi-dev-box
succeeded under BatchMode=yes (key auth, symlinked to id_ed25519) and sudo -n true returned
SUDO_NOPASSWD_OK on the target. The precondition's stated purpose ("so the deploy script can
authenticate") was therefore met by other means, and the deploy's exit code 0 confirms it. Recorded
rather than glossed: if a future run of this plan needs the password path — a different target, or
sudo tightened on this one — deploy-config.sh will have to be created first.
Task 2 not executed; no checkpoint round-trip
This plan is autonomous: false and Task 2 is checkpoint:human-verify gate="blocking". Its
verification is a human verdict, which was not obtainable in this run. Rather than stop with nothing
recorded, Task 1 was completed in full and the checkpoint's blockers were investigated so that whoever
picks it up starts with the environment already proven ready (bundle confirmed live) and the two
practical obstacles already identified and quantified. The plan is not complete and UIFIX-01..06 are
not closed.
Plan-state files deliberately not updated
STATE.md, ROADMAP.md and REQUIREMENTS.md were not modified and not committed:
.planning/STATE.md was already dirty with a concurrent executor's edit, the execution brief limited
this plan's commit to this SUMMARY alone, and — most importantly — marking UIFIX-01..06 complete
would be false while the sign-off that closes them is unanswered.
No source file modified, no fix applied
files_modified: [] was honoured. Nothing was found that needed fixing, but the standing rule for
this run was that a genuine bug would be recorded as a finding, not patched inline, because three
other executors held the same working tree throughout.
Findings
- The assets directory on the node is never pruned.
/opt/archipelago/web-ui/assetsholds many generations of hashed chunks (the deploy'srm -rfexcludesaiui/claude-login.htmlbut the directory still showed severalCloud-*.js,Web5-*.jsandMediaLightbox-*.jshashes simultaneously). Harmless at runtime — the entry chunk andsw.jspin the live set — but it makes any disk-side "is the fix deployed?" grep unreliable, and it silently inflates the directory. Not fixed here (out of scope). Anyone verifying a deploy by grep must resolve the live set fromsw.jsfirst, as this plan did. - The container doctor applied 2 fixes during the deploy (
rootless-portsrestart ofnetbird-serverfor a missing 3478 listener, and an NPM public-hosts sync), 12 checks passed. This is the deploy script's normal behaviour, noted only because it means the deploy was not purely a frontend file copy. ⚠️ No ANTHROPIC_API_KEY foundduring the Claude API proxy step — pre-existing on this node, unrelated to this plan, not acted on.
Known Stubs
None — this plan wrote no code.
Threat Flags
None. No new endpoint, auth path, file-access pattern or schema change.
Threat register status:
- T-01-82 (verification deploy reaching fleet/alpha-tester nodes) — mitigated: frontend-only
dev-pair path, no Tailscale/alpha-tester/
--both/--fleetflag, no release or OTA path; exact command and single-host list recorded above and corroborated by the node's own deploy manifest. - T-01-83 (signing off against a stale bundle) — mitigated, and the threat was real: the naive
disk-side grep would have produced false hits from dead chunks. Verified instead against the live
sw.jschunk set fetched over HTTP. - T-01-84 (a seed exposed by check 2's verification) — mitigated: the onboarding seed flow was not opened, nothing was captured, and the warning is restated for whoever runs check 2.
- T-01-85 (a demo/preview-only pass recorded as a node pass) — mitigated: no check is marked passed. The node's purchased-content inventory (1 image, 0 video, 0 audio) is stated explicitly so the paid-content path cannot be quietly signed off on the demo.
- T-01-SC (package installs) — nothing installed.
npm install --silentinside the deploy ran against the existing committed lockfile and leftneode-uiclean; no dependency added.
Self-Check: PASSED
.planning/phases/01-federation-mesh-hardening/01-18-SUMMARY.md— FOUND (this file)- Deployed commit
527f6023— FOUND on the node in/opt/archipelago/deploy-manifest.json 8255b69a,ceafbcb5,b5628d96,bc9a210c,3288a02d— all confirmed ancestors of527f6023- Served chunks
Cloud-yWcQ9GU-.js,Web5-BvURT8TJ.js,MediaLightbox-DKht-qI-.js,OnboardingSeedGenerate-C7UXVA3p.js— all fetched over HTTP fromhttp://archi-dev-boxand grepped git status --short -- release-manifest.json releases/ app-catalog/— emptygit status --short -- neode-ui web— empty- No source file modified by this plan
Phase: 01-federation-mesh-hardening Task 1 complete 2026-08-02. Task 2 open — awaiting a human at the device.