Files
archy/.planning/phases/01-federation-mesh-hardening/01-18-SUMMARY.md
T

20 KiB
Raw Blame History

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
verification
deploy
dev-pair
on-device
checkpoint
gap-closure
blocked-on-checkpoint
phase plan provides
01-federation-mesh-hardening 12 UIFIX-02 connected-nodes sibling-matched scroll contract
phase plan provides
01-federation-mesh-hardening 13 UIFIX-03 onboarding scroll cue
phase plan provides
01-federation-mesh-hardening 14 UIFIX-04/UIFIX-06 paid-item lightbox + Opening… loader
phase plan provides
01-federation-mesh-hardening 15 UIFIX-05 PiP custodial-host handoff
phase plan provides
01-federation-mesh-hardening 17 UIFIX-01 transport-pill wrap fix + pin test
All six UIFIX fixes delivered to archi-dev-box and proven present in the bundle the node actually serves, fetched over HTTP and matched against the live service-worker chunk manifest
An on-device boot check of the deployed bundle at 1440x900 and 390x740 — zero console errors, zero page errors, zero failed requests
Two of the planner's flagged open questions settled from the node's own data: it HAS one purchased image, and it has NO purchased video and NO audio/video content at all
A per-check VERIFIED / NOT VERIFIED table with the exact human action each unverified check still needs
cloud
web5
onboarding
media-viewer
added patterns
Served-bundle verification must resolve the live chunk set first: /opt/archipelago/web-ui/assets accumulates every prior deploy's hashed chunks, so a naive `grep -rl` across the directory returns hits from dead chunks. The service-worker precache manifest (sw.js) is the authoritative list of the chunks the current build actually loads — grep only those, and fetch them over HTTP rather than off disk.
created modified
.planning/phases/01-federation-mesh-hardening/01-18-SUMMARY.md
No source file was modified and no fix was made. This is a verification plan (files_modified: []) and three other executors were live in the same working tree on plans 10-02/10-04/10-06 for its whole duration; anything found here is recorded as a finding, not patched inline.
Task 2's six numbered checks are recorded NOT VERIFIED. Every one of them requires an authenticated session on archi-dev-box, and the node's UI password was not available to this executor (02-08 records it being supplied out-of-band by the coordinator and passed only via ARCHY_PASSWORD). No credential was guessed against a live node holding real federation trust and real funds.
STATE.md/ROADMAP.md/REQUIREMENTS.md were deliberately NOT updated and NOT committed. .planning/STATE.md was already dirty with another agent's in-flight edit, and the execution brief restricted this plan's commit to the SUMMARY alone. UIFIX-01..06 must NOT be marked complete until the Task 2 checkpoint is answered.
duration tasks files-changed
~20min 1 of 2 (Task 2 is a blocking human checkpoint, unanswered) 0 source files
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:

  1. 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".
  2. --tailscale, --tailscale-node=, --both and --fleet were not passed, so the SEC_TARGET fan-out branch (lines 355385, which contains the only 192.168.1.228 reference on any AIUI path) was never entered. The AIUI step that did run is the LIVE branch at lines 725736, which talks only to $TARGET_HOST.
  3. 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.json1 owned item, mime image/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, ~/Documents found 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

  1. 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.
  2. Put one video file on the node — upload an .mp4 through 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.
  3. 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.
  4. 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.
  5. Check 4's buffering-pause sub-step needs devtools network throttling or a long seek — a human action, on the node's own browser.
  6. 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.
  7. Re-deploy to archy-x250-dev once 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

  1. The assets directory on the node is never pruned. /opt/archipelago/web-ui/assets holds many generations of hashed chunks (the deploy's rm -rf excludes aiui/claude-login.html but the directory still showed several Cloud-*.js, Web5-*.js and MediaLightbox-*.js hashes simultaneously). Harmless at runtime — the entry chunk and sw.js pin 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 from sw.js first, as this plan did.
  2. The container doctor applied 2 fixes during the deploy (rootless-ports restart of netbird-server for 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.
  3. ⚠️ No ANTHROPIC_API_KEY found during 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/--fleet flag, 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.js chunk 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 --silent inside the deploy ran against the existing committed lockfile and left neode-ui clean; 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 of 527f6023
  • Served chunks Cloud-yWcQ9GU-.js, Web5-BvURT8TJ.js, MediaLightbox-DKht-qI-.js, OnboardingSeedGenerate-C7UXVA3p.js — all fetched over HTTP from http://archi-dev-box and grepped
  • git status --short -- release-manifest.json releases/ app-catalog/ — empty
  • git 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.