Files
archy/docs/post-1.8.22-regressions-20261001.md
T

1545 lines
97 KiB
Markdown

# Post-1.8.22 regressions and retained release checklist
Release target: **1.9.0**, as requested by the operator. Supersedes the provisional 1.8.23-alpha target.
Status: OPEN. New regressions reported after publication on 2026-10-01.
Do not mark complete from source changes alone. Preserve wallets, app state and
operator uninstall decisions. Never send a second payment to recover delivery.
The earlier Framework startup incident remains separately closed with operator
acceptance; this is a new paid-file incident.
## Latest deployment checkpoint
- Framework physical radio investigation is **operator-deferred**, not passed.
- Unpublished candidate backend/UI deployed on dev and yaya with backups;
management health passed and native Bitcoin/LND stayed running.
- Actual yaya startup exposed missing HTTPS ACME in the shipped template.
Template and narrowly recognized legacy migration are fixed; 28 Python checks,
120 isolated public-security cases, and the ISO overlay check passed.
Live yaya exact-token and missing-token checks passed over HTTP/HTTPS and
public HTTP; existing public-site TLS/authentication remain intact.
- Latest embedded helper/template rebuilt and deployed on dev/yaya; full isolated
backend suite passed 1,651 tests, zero failed, four explicit ignores. Helper
bytes match source after management restart and live ACME/security probes
pass. Full-machine reboot and signed catalog migration remain unverified.
- Operator signed the candidate catalog; exact reviewed contents and release-root
signature verified on dev/yaya. Only NPM and Angor indexer changed. An explicit
signed local-candidate selector is implemented because mirror ordering always
prioritizes the public origin. Full isolated suite now passes 1,653 tests; its
optimized build completed and the signed candidate is active on dev/yaya.
Live NPM migration found a further compatibility failure: existing saved
upstreams use the former host gateway, which default slirp cannot reach.
A disposable namespace verified preservation using an explicit slirp subnet;
live qualification repair now passes saved-upstream, database/certificate
preservation, bridge, ACME and public HTTPS checks. Durable source/catalog
correction and removal of the temporary qualification network override remain
mandatory before release. See the acceptance document for details.
- Shorty's containment is untouched. Its manual shop HTTPS route versus NPM
certificate ownership remains a blocker. Paid-file regression acceptance,
physical companion uploads, Angor's 34 missing announcements/full-chain
acceptance, and exact OTA/raw-ISO acceptance remain open.
- No new catalog, OTA or ISO has been published.
## Current tasks
- [x] Yaya App Store component/alias regression (reported 2026-10-02): one
Cuprate entry (hide Cuprate UI companion), one BTCPay Server in Commerce
with its icon (merge legacy btcpay pins), one NetBird entry (hide server
and dashboard components). Apply to fresh signed/community catalogs,
persisted caches and installed Apps/Services; preserve actual components,
data, dependencies and legacy-only installations. Source fix and 34
focused tests pass; production build and yaya live browser checks at
mobile/desktop widths, including hard reload, pass. Actual new installs
of these three products were not performed during this UI acceptance.
- [ ] **2026-10-02 operator requirement for the next update: Fast by default for
on-chain transactions**, including sends and cooperative channel closes;
users can explicitly select slower or custom fees. This supersedes the
earlier instruction to leave defaults unchanged. Implement dynamic
next-block targeting, not a fixed sat/vB default. Cover initial form state,
reset/reopen, preview, submission and backend omitted-fee defaults; preserve
explicit user selections. Audit channel opens and other on-chain entry
points for the same policy. Force-close commitment fees and subsequent
sweeps require separate supported LND handling, not cooperative-close
parameters or a promise of immediate spendability. Implementation and
actual-node acceptance remain pending; no default was changed by the
manual acceleration below.
- [ ] **Speed up interface:** implement the plan in the fee-acceleration section
below, with explicit additional/total fee preview, budget, live eligibility,
RBF/CPFP distinction and durable operation tracking. Include in next-update
scope alongside Fast defaults; do not infer completion from this plan.
- [x] Resolve the tester's missing-file recovery request: operator confirmed on
2026-10-02 that the tester received the file from Amish Paradise and accepts
closure of this individual recovery. No seller access or further payment
is required. This is operator-confirmed receipt, not independent byte
verification or proof that the candidate fix delivered it. The durable
payment/delivery fixes and regression acceptance below remain required.
- [x] Correct seller settlement verification when local-node payment skips polling.
- [x] Durable seller entitlements and safe buyer retry after navigation/restart;
do not issue another payment on an uncertain or successful attempt.
- [ ] Cache Lightning purchases, preserve ownership, optional Files copy, free repeat.
Exact bytes, ownership and free repeat passed; optional Files-copy acceptance
must be located or repeated before closing this combined checkbox.
- [ ] Diagnose mobile companion uploads on the affected route/device.
- [x] Real progress in the existing compact upload bar; no increased height.
Actual browser uploads verified a 44px bar; physical companion remains separate.
- [x] Preserve uploads/progress across screens and original batch destination.
Actual browser batch destination and cross-screen persistence verified.
- [x] Cancel active transfer and queued files; truthful partial/error/server-save status.
- [x] Transparent transaction-filter container; single horizontal scrolling mobile row.
Actual served desktop/mobile styles and geometry verified; retain in final artifact checks.
- [ ] Immich displayed as one app, internal components hidden; diagnose restarting services.
- [x] Diagnose unwanted CryptPad after upgrade, failed uninstall, and persistent removal.
- [x] Identify the other removed unexpected service: Core Lightning, confirmed
in the original node investigation and its retained uninstall markers.
- [ ] Upgrade regression matrix: installed/stopped/restarting/removed/legacy apps,
aliases, dependencies, inventory, desired-state reconciliation and data preservation.
- [x] Portainer duplicate-network migration: retire the redundant managed repair
override, preserve operator settings/state, verify generated command,
actual request namespace, dashboard readiness and repeated reconciliation.
- [ ] Lightning cooperative-close fees: Standard/Medium/Fast/Custom selection,
explicit default target, strict backend validation and forwarding, error
handling, mobile layout and no real channel closure during tests.
- [x] Apps search clear control: My Apps, Services and App Store, desktop/mobile,
existing design tokens, right-aligned icon, no size change, keyboard focus.
## Fee acceleration and Fast-default handoff — 2026-10-02
Operator explicitly authorized accelerating the latest outgoing Bitcoin payment
and subsequently requested Fast defaults for all on-chain transactions in the
next update, with slower options. The later instruction supersedes the earlier
no-default-change restriction. This is independent of paid-file recovery and
does not authorize another purchase payment.
Live Framework evidence, checked through the existing SSH connection with
hostname verification (not the development node):
- Original transaction:
`ad3c2ffd14f35e0508045f538b0046876cfeddc732ed8c1f49771c219f2f2b42`.
Recipient 161,650 sats; original fee 144 sats; vsize 142; no unconfirmed
ancestors or descendants before submission. Wallet-owned output 0 was
unspent and worth 21,126 sats. It did not signal BIP125 replacement.
- LND next-block estimate: 2 sat/vB. Bitcoin conservative estimator returned
2.255 sat/vB (effective target 2 blocks). Mempool/relay floor: 1 sat/vB.
- Submitted exactly one `wallet bumpfee` for original output 0, using
`--sat_per_vbyte 3 --budget 650 --deadline_delta 1 --immediate`.
This registers a CPFP child, not a replacement of the recipient payment.
The budget was explicit; no implicit 50%-of-change budget was used.
- Actual child broadcast and accepted in the node's mempool:
`e04aec1dfbc16043611411de83201a32f7ffdcb9e8bb362c281cf967ee4bdd69`.
Its only input is the specified change output; output 20,476 sats;
fee 650 sats; vsize 111. Parent plus child: 794 sats / 253 vB =
approximately 3.138 sat/vB. Recipient output remains unchanged.
- At the post-submit check, node tip was 969564, both transactions remained
unconfirmed, and child `unbroadcast=false`. LND recorded one broadcast
attempt, budget 650 and deadline height 969565. RPC success is not
confirmation; next-block inclusion is not guaranteed. Do not repeat the
bump blindly if resuming: inspect original, child, sweeper and chain first.
- Bitcoin CLI works with `-conf=/tmp/rpc.conf` inside `bitcoin-knots`.
Do not print/copy that configuration or its credentials. No default settings,
wallets, channels or services were changed/restarted by this acceleration.
Final confirmation check: **both original and CPFP child confirmed in block
969565**, the next block after submission. LND reports one confirmation for
each, with fees still 144 and 650 sats respectively. The authorized acceleration
is complete. This outcome does not guarantee next-block results for future sends.
Implementation plan for the next agent:
1. **Fast default:** update initial/reset states in `SendBitcoinModal.vue` and
`LightningChannelsPanel.vue`, plus their fallback targets and backend
omitted-fee behavior in `lnd/wallet.rs` and `lnd/channels.rs`. Existing Fast
presets already target 1 block; current initial/reset states select Standard
and cooperative-close backend defaults to 6. Preserve explicit slower/custom
settings. Quote a fresh fee and show total cost before confirmation; never
silently substitute a stale/cheap estimate after estimator failure. Explain
that next block is a target, not a guarantee. Audit channel opening and other
on-chain call sites, distinguishing force-close and sweep semantics.
2. **Flow:** transaction details → Speed up → Next block / Custom → review
additional fee, resulting total fee, maximum additional-fee budget and
recipient amount → Confirm. Custom specifies a target package rate in
sat/vB for CPFP, or replacement rate for RBF. Clearly identify the method:
RBF replaces a transaction; CPFP spends wallet-owned change to accelerate
the original. Only expose methods supported for that specific transaction
by the installed wallet; do not infer direct RBF capability from a flag.
3. **Read-only quote RPC:** return eligibility/reason, chosen method, original
txid/outpoint, live chain/mempool status, rate, transaction/package sizes,
existing fee, estimated additional fee, resulting total fee, explicit hard
budget, expiry and a server-bound quote ID. Verify ownership, spendability,
leases, dust, ancestors/descendants, sweep membership and relay/replacement
rules. CPFP fee calculation must cover the ancestor package, not just the
child's vsize. Distinguish estimated spend from maximum approved spend;
LND can consume its entire budget at the deadline (as happened here).
4. **Submit RPC:** require wallet authorization and quote ID/idempotency key;
serialize by affected transaction/outpoint and persist operation state before
calling LND. Revalidate confirmation, conflict, output availability, topology,
fee estimate and policy at Confirm. Invalidate materially changed/expired
quotes for another review; never raise the approved budget silently. A
timeout is an unknown outcome to reconcile, not permission to pay again.
Repeated/restarted submissions return the existing operation.
5. **Track results:** distinguish requested, registered, broadcast, mempool
accepted, confirmed, rejected and unknown. Link original/replacement/child
txids and subsequent child replacements durably. Preserve recipient amount
and original identity; present one payment with fee history, not a second
outgoing payment. Current `lnd.gettransactions` drops output ownership and
input relationships and uses absolute wallet delta as amount; extend the
normalized model deliberately to avoid counting the CPFP fee as a new send.
Home and its transaction-detail component need live refresh and reorg handling.
6. **Acceptance:** default/reset/explicit-slower UI and omitted-fee backend
tests; package math, budget and dust boundaries; stale/confirmed/conflicted
quotes; concurrent submits, timeout and restart reconciliation; unsupported
RBF, CPFP child replacement and history grouping; estimator outage; mobile
review. Run backend tests only through `scripts/test-backend-isolated.sh`.
Use regtest for broadcast/confirmation scenarios; do not close real channels
or send real payments merely to test defaults. Record source results separately
from deployed UI and live-node acceptance before OTA/ISO publication.
Upstream semantics: [LND BumpFee API](https://lightning.engineering/api-docs/api/lnd/wallet-kit/bump-fee/)
and [LND unconfirmed transactions guide](https://docs.lightning.engineering/lightning-network-tools/lnd/unconfirmed-bitcoin-transactions).
No fee-bump interface or Fast-default source change is implemented by this
handoff. Both remain required next-update work.
### Bump interface implementation and operator UI review — 2026-10-02
This checkpoint supersedes the preceding statement that the interface is only
planned. The operator requested a small **Bump** button on pending on-chain
transactions, asked for a Framework/yaya preview before release handover, and
approved the layout. They then requested the existing glowing green transaction
success animation and approved that addition as well.
- Implemented `BumpFeeModal.vue` and a small Bump action in `TransactionsModal.vue`;
Home refreshes wallet history after a verified update. Next block is selected
initially; Custom invalidates the previous quote. The review shows recipient
amount, current fee, additional fee cap, resulting total cap and package rate.
- Implemented authenticated/CSRF-protected `lnd.bump-quote`, `lnd.bump-submit`
and `lnd.bump-status` in `lnd/fee_bump.rs`, with submit/quote rate limits.
Quotes expire after 60 seconds and are revalidated before submission. A
synced write-ahead receipt under `wallet/fee-bumps/<txid>.json`, a submission
lock and create-new semantics prevent blindly retrying a possibly accepted
mutation after timeout/restart. Unknown outcomes remain blocked for recovery.
- Method is selected from live wallet evidence, not chosen by the user:
CPFP uses spendable/unleased native wallet change on a simple pending outgoing
payment. RBF is limited to LND's existing single-input wallet CPFP sweeps,
with a verified pending input, wallet-owned output and simple parent package.
Arbitrary payment replacement, anchor/HTLC/batched sweeps and complex ancestor
chains are explicitly unsupported. LND 0.21+ is required for the exact
budget/deadline API used. No default wallet fee setting is changed.
- Every mutation supplies an explicit budget below the selected input value
and a one-block deadline; the review explains that the full budget may be
consumed. Node mempool acceptance and LND confirmation evidence drive status.
The shared `PaymentSuccessPane` displays its existing green glow/check only
after acceptance: **BUMP BROADCAST / Awaiting confirmation**, then **CONFIRMED**.
RPC registration alone never triggers the success animation.
- Standalone preview deployed to Framework at `/fee-bump-preview/index.html`.
Its CPFP/RBF buttons are sample scenarios for review, not product method
choices. It compiles the actual components with an isolated mock RPC module;
browser checks verified zero wallet RPC calls. No test payment was sent.
Source: `neode-ui/previews/fee-bump/` and `vite.bump-preview.config.ts`.
- Initial UI verification: eight focused Bump tests, 12 existing Home wallet
freshness tests, TypeScript check and production build passed. Playwright
exercised 390px and 1440px preview, Custom, Confirm, success animation and
Done with no browser errors or wallet RPC requests. An initial stacking
defect was found visually and fixed with explicit dialog z-order; mobile
transaction amounts now stay on one line, with wrapping badges.
- Latest backend validation and actual wallet deployment are still in progress
at this checkpoint. Do not claim regtest or real-wallet RBF/CPFP acceptance
from unit tests or the static preview. The earlier manual CPFP and confirmation
above remain separate evidence.
**Retain for the next release:** Fast defaults are still an unfinished requirement
from the operator; this interface work does not implement those defaults. Preserve
all other checklist tasks. Broader RBF support and grouping fee-only child rows
with their original payment remain limitations to assess explicitly. No fleet
OTA/catalog/ISO publication is authorized by this preview deployment alone.
### Release-agent handover: approved Bump UI, production deployment blocked
Operator approved the design and the added shared glowing green success animation.
The last request was to finish and provide the next-release agent a handover.
**Verified complete:**
- The interactive sample preview is deployed on the actual Framework:
`http://100.65.115.109/fee-bump-preview/index.html`. Select a sample scenario,
then Bump → Next block / Custom → preview → Confirm. It cannot send funds.
CPFP/RBF scenario buttons exist only in this preview; the actual wallet chooses
the supported method. The production dialog is not a method-selection menu.
- Eight focused frontend tests passed, including the real shared success badge
appearing only after mempool acceptance/confirmation; 12 existing Home wallet
freshness tests passed. TypeScript check and production UI build passed.
- Seven focused backend tests passed; the full isolated backend run subsequently
passed **1,660 tests, zero failed, four explicit ignores**. No additional live
payment, bump, channel closure or wallet setting change was made for testing.
- Desktop 1440px and mobile 390px browser tests exercised the deployed sample
review, custom fees, Confirm, green animation and Done with zero browser errors
and zero wallet RPC requests. The user approved both design and animation.
**Deployment boundary and blocker (2026-10-02 10:23 UTC):**
- Only the standalone sample preview is deployed. The actual dashboard/backend
fee-bump feature is NOT deployed yet. No management/native service was restarted
by this feature work. Framework's existing backend SHA256 was
`8fb6249d1869bb8c9aea26d0f846de5b3eec328113a5c7f573628306e26e652e`.
- The session changed to a restricted sandbox while the release backend was
compiling. The original build process/session is gone. The existing
`core/target/release/archipelago` still had the pre-feature 04:42 local timestamp
at the checkpoint; **do not deploy that stale artifact as this feature**.
- SSH now fails with `Control socket connect(...): Operation not permitted` and
`socket: Operation not permitted`. This is an execution permission blocker,
not another Framework password failure. Approval mode is never, so this session
cannot request an elevated network operation. Resume deployment from a session
with authorized network access; do not alter node credentials to solve it.
- A local offline release-build retry was started after the interruption; its
completion must be checked before using any backend artifact.
**Exact source scope (uncommitted, mixed workspace; preserve unrelated edits):**
- New backend: `core/archipelago/src/api/rpc/lnd/fee_bump.rs`.
- Wiring: `api/rpc/lnd/mod.rs`, `api/rpc/dispatcher.rs`,
`api/rpc/bitcoin.rs` (shared read-only Bitcoin RPC helper visibility), and
`core/archipelago/src/rate_limit.rs`.
- UI: `neode-ui/src/components/BumpFeeModal.vue`, `TransactionsModal.vue`,
`neode-ui/src/views/Home.vue`, and
`neode-ui/src/components/__tests__/BumpFeeModal.test.ts`.
- Preview-only files: `neode-ui/previews/fee-bump/` and
`neode-ui/vite.bump-preview.config.ts`; keep its mock RPC alias out of the
production build. The regular production build uses the real RPC client.
**Staged artifacts and next steps:**
1. Finish the release backend build and record its SHA256. Production UI archive
`/tmp/archy-bump-ui.tar.gz` SHA256 is
`d0e253aba09ad257136e3feb5b63176c388f3bb968f560702eefb768d29e494d`;
its `index.html` SHA256 is
`9fef18c8c1c9bc21f43c3635b747dfcfbea965b096867b454bbf608121715438`.
This UI contains the approved green animation.
2. With access restored, verify hostname `framework-pt`. The UI archive and
`/tmp/archy-deploy-bump-framework.py` were staged on Framework; the same script
exists locally. Review it, stage the correct backend as `/tmp/archy-bump-backend`,
then supply the exact backend/archive hashes as its two arguments. It prepares
a rollback under `/var/lib/archipelago/support/framework-fee-bump-20261002`,
checks manager health, and compares native container identity/start times,
wallet identity, channels and balances. It has NOT been executed yet; the
rollback directory is therefore planned, not a verified backup.
3. Verify served production assets and authenticated quote/status behavior after
deployment. The previously saved dashboard session returned 401 during
preflight; use a normal fresh login. Do not fabricate authenticated acceptance
from the sample preview. No funded UI transaction test has been authorized.
4. Keep the documented support limits: simple outgoing native-change CPFP and
RBF of LND's single-input CPFP sweeps; no general payment replacement, incoming
payment bumps, batched/channel sweeps or complex unconfirmed ancestry. Quote
expiry, persisted ambiguous outcomes and fee budgets must remain intact.
Full regtest mutation/confirmation/reorg acceptance is still outstanding.
5. Implement the separately authorized **Fast default** for sends/cooperative
closes and audit other on-chain entry points; preserve slower/custom choices
and distinguish force-close semantics. That change remains required for the
next release and is not implemented by this Bump work. Preserve all other
regression/release blockers and the separately closed startup incident.
## Retained release work (previous acceptance is not new-regression acceptance)
- Mempool patched image/catalog version agreement, update-button clearing, one card.
- Minibits PR160, Lightning address availability, concise single-column backup copy.
- Framework LND startup/Receive and unknown-vs-zero balance behavior.
- Friendly Bitcoin warmup; LND waiting for install/sync; Bitcoin UI during IBD;
headless Phoenixd without self-waiting or bogus launch action.
- Cashu same-mint paid files, exact amounts/change/refund, errors, stored bytes,
Files copy and repeat access without re-payment.
- mempool.space public explorer fallback, preserving local/custom configuration.
- Optional install pruning and consistent automatic-pruning policy.
- X250 kiosk version picker layering/contrast and pruning layout.
- AIUI single desktop/mobile background, transparent embedded layers,
preserved standalone wallpaper.
- PR review/fixes/tests and normal merge/closure (160 previously shipped;
161/162 merged and included in 1.8.22).
- Installed inventory retained during app restart/hard-refresh.
- Correct iframe/browser launch readiness, useful errors and delayed startup.
- GitWorkshop payload/build contexts, progress and persistence after refresh.
- Gitea/Portainer same-server Git from actual request namespace; URLs, auth,
fresh installation in either order, migration/rollback, restart/reboot,
Git/SSH/LFS/registry/browser compatibility and data/stack preservation.
- NPM correct admin port/URL, malformed URL behavior, bind-aware readiness,
persistent backed-up tunnel/LND port-conflict repair on OTA and ISO.
- Angor headless indexer on DEV BOX only, full unpruned Bitcoin/Mempool/ElectrumX
prerequisites, optional separate relay, official icon with green white areas.
- Compact named readiness messages and bottom-aligned app-card actions.
- Remove unused integration/build fixtures from Apps/Services, preserve app data.
- Safe network doctor, no all-app stop/reset on failed egress probe.
- No orphan companion resurrection; retain existing companion security repairs.
- Current companion image registry, build contexts, runtime asset promotion order,
generated-service argument quoting and graceful Bitcoin/LND shutdown.
- OTA + RAW ISO, root signatures/catalog compatibility/checksums, independently
verified public files, Git/ngit source/releases and fleet discovery.
- Correct LAN SCP command for the new ISO.
## Explicit boundaries/follow-ups
- Full-chain Angor indexing awaits development Bitcoin IBD.
- Primal automatic comment exceeding Minibits metadata limit: previously accepted
upstream limitation, no unsupported local identity/metadata rewrite.
- Lost-response ecash seller receipt redesign is a separately accepted follow-up;
do not claim an uncertain refund completed or automatically pay twice.
- Optional external-provider/hardware tests must be labelled if not exercised.
## Initial source evidence
`PeerFiles.vue::payWithLightning` immediately downloaded after buyer payment,
while only seller `handle_content_invoice_status` marked a pending invoice paid.
Seller download checked only that cached flag. This matches the reported error
and is supported by source inspection. An earlier diagnostic's HTTP 404 is not
valid confirmation: it incorrectly base64-decoded lncli's already-hex payment
hash. The corrected live diagnostic recognizes the settled invoice on the
candidate; do not cite the earlier 404 as proof of the original failure sequence.
`content_invoice.rs` stored all entitlements only in process memory with a
one-hour TTL, losing both pending and paid access on restart/expiry.
Lightning download returned transient base64 without the Cashu ownership cache.
CloudFolder's view-local spinner had no byte progress/cancel; batch upload read
`currentPath` independently for each file, allowing navigation to move destinations.
Immich's underscore dependencies are scanner-excluded; hyphen manifest IDs are
not. Live inventory confirmed both hyphenated synthetic entries while the
actual underscore-named containers had remained running for nine days.
## Access / acceptance
Operator provided updated Framework SSH authentication privately in chat.
Do not put credentials or deployment addresses in this public document.
Framework was reached over SSH. Native Bitcoin, LND and all three Immich
container identities/start times were recorded before candidate deployment.
The kiosk is at its login page. Dashboard password authentication succeeds but
requires the operator's second factor; normal uninstall acceptance remains pending.
Confirmed live evidence:
- A 10,000-sat peer-file invoice settled at 12:19:29 UTC. The original status
diagnostic used an incorrectly decoded hash; see the correction above. Buyer
identity and confirmation that this is the reported sale remain pending.
- The matching item currently allows free access; preserve that operator setting.
- CryptPad has no container but remains in installed-apps metadata. Uninstall
repeatedly aborts because the removed catalog ID has no manifest.
- Immich server/database/cache are running; synthetic hyphenated dependencies
appear stopped and the recovery overlay briefly advertises restarting.
- The other removed service was Core Lightning; uninstall tombstones exist.
- No Android resource-upload POST appears in the inspected recent nginx log.
This does not establish why the affected companion failed.
## Candidate implementation and validation
Source changes persist seller entitlements with atomic writes, verify settlement
at delivery, recover older Lightning entitlements from the seller's LND invoice,
perform the status handshake for older sellers, and cache delivered Lightning
files. Buyer purchase bytes and the shared ownership index now use atomic,
synced writes and a serialized read/modify/write transaction; a corrupt index
fails the write instead of silently replacing existing ownership. The browser saves the invoice before payment and retries delivery without
another payment. Browser receipts are not yet a node-wide recovery store.
The upload queue now belongs to the shared Cloud store, captures its original
folder, reports actual sent bytes and server completion, and cancels its active
XHR and remaining queue. The fixed-height bar remains available across routes.
Transaction filters use a transparent container and one scrollable row. Immich
aliases normalize to their real component names and internal cards are hidden.
Unknown catalog entries no longer prevent the regular uninstall flow.
Validation so far (additional acceptance still pending):
- Final isolated backend suite: **1,631 passed**, zero failed, four optional
tests ignored. This includes invoice settlement/amount boundaries, durable
seller records, concurrent buyer ownership, damaged-index preservation,
Portainer override retirement/idempotence/customization/backup failures,
recovery overlays and channel-close fee forwarding/validation.
- Final frontend suite: **1,157 passed** across 142 files. Production build
passed. Six payment-recovery and twelve channel-close tests are included.
- Real FileBrowser uploads at 1440px and 390px: exact bytes and original folder
verified after navigation, 44px bar, cancellation and queue stop passed.
- Mobile viewport acceptance is not physical Android companion acceptance.
- Final release backend build passed. Candidate backend and dashboard are now
deployed on dev and Framework. Another OTA/ISO remains pending; published
1.8.22 artifacts remain unchanged.
Release gates still include actual-node payment recovery/delivery, durable
CryptPad removal through normal controls, Immich inventory after refresh/restart,
physical companion diagnosis, and remaining upgrade regression acceptance.
No new payments, native-service restarts or wallet changes were used in testing.
## Additional live Portainer regression
The X250 user service exited 125 because the generated command supplied
`--network slirp4netns` twice. The manifest already supplies the network, while
an older Archipelago-created `archy-same-node-network.conf` drop-in adds it
again. Quadlet's Network directives accumulate; they do not override each other.
This repair artifact should have been retired when the declarative fix shipped.
The live repair backed up the override and Portainer state, removed only the
exact redundant override, reloaded user systemd and restarted Portainer. API
status returned HTTP 200 with version 2.45.0; the actual kiosk's package state
reported running and UI-ready. Bitcoin/LND and the production site's container
identities/start times remained unchanged. The source migration now detects
this exact managed override before preparing the persistent restart obligation,
backs up app state, retires the redundant file with a retained copy, and reloads
and restarts through normal reconciliation. Custom overrides are preserved.
Automated migration coverage passed; candidate is now deployed on dev and
Framework. The X250 retains its verified live repair pending the next OTA.
## Channel-close fee selection
The existing close UI sent only the channel point, and the backend forwarded
only `force=false`. LND therefore used its lax default confirmation target.
The candidate reuses the channel-opening fee choices (six/three/one block target,
or custom target/rate), explicitly sends six blocks for legacy clients that omit
fees, and validates query parameters before accessing the wallet. Cooperative
fees are never silently applied to force closes. Close RPC retries are disabled
so a timeout cannot silently repeat this mutation.
Protocol reference: [LND CloseChannel](https://lightning.engineering/api-docs/api/lnd/lightning/close-channel/).
Fee targets are estimates, not guaranteed confirmation times. Tests use mocked
requests; no production channel is closed to verify the feature.
Additional browser acceptance:
- Transaction filters at 390px: computed transparent background, one row and
horizontal overflow verified.
- Close-channel selector at 1440px and 390px: preset/custom controls visible,
no overflow, custom 25 sat/vB forwarded. The close request was intercepted;
no real channel closure or wallet mutation occurred.
- All three Apps search screens at both widths: clear icon stays inside the
field; click/Escape clear; input retains focus; desktop 40px/mobile 52px heights
stay unchanged. Shared design-system search-field classes are retained.
- Portainer remained active with zero service restarts and no pending marker.
Its real network namespace read smart HTTP Git refs and the Compose file.
Original persistent mounts were unchanged. The old integration test containers
are absent from dev, Framework and X250. One leftover upload-test folder was
removed after checking it contained only this task's test files.
## Build resource observation
The final optimized compile coincided with heavy memory/disk pressure and local
Bitcoin/LND RPC timeouts on the development node. After pausing the compiler,
both authenticated RPCs responded again; Bitcoin reported height 506400 and
19.6% verification progress, with LND waiting for chain sync. No native service
was restarted. Compilation resumed in a separate user scope limited to one CPU,
with nice 19 and idle I/O priority. This is evidence of resource contention,
not proof of a new wallet or startup defect. Verify native RPC health again
before candidate deployment.
## Candidate deployment and live acceptance — 2026-10-01
Source: `f4d34554` (later commits update this checklist only).
Backend SHA-256:
`8fb6249d1869bb8c9aea26d0f846de5b3eec328113a5c7f573628306e26e652e`.
- Backed up backend, dashboard and app metadata on both nodes under the root-only
support directory `post1822-regressions-20261001`. Deployed assets before
promoting the dashboard entry point; manager health passed first.
- Only the Archipelago manager restarted. Bitcoin/LND IDs and start times stayed
unchanged; Framework's three Immich containers also stayed unchanged.
- Dev authenticated Bitcoin/LND RPCs responded after deployment. Bitcoin IBD
continued above height 513000; LND correctly reported not yet chain-synced.
- Both nodes serve dashboard entry bytes identical to the production build.
All six search-clear cases passed against the live dev dashboard (three
screens, desktop/mobile), including focus, Escape and unchanged field size.
- Framework's stale CryptPad installed claim was removed while the manager was
stopped; both legacy IDs were recorded as user-uninstalled. Data was preserved.
Removal remained after another management restart. Dashboard uninstall-flow
acceptance still awaits authentication; this repair was performed over SSH.
- Corrected invoice diagnostic recovered the settled seller entitlement, returned
HTTP 200 with `paid: true`, and saved a mode-0600 record. A different item was
rejected. Paid status survived another manager restart without native restarts
or a second payment.
- Delivery acceptance remains OPEN: the catalog's file is absent from both its
dedicated content path and FileBrowser path; a privileged filename search of
those trees found no copy. Its free-access setting was preserved. Buyer and
reported-purchase identity still need confirmation; do not claim the actual
buyer received the file.
- The malformed-hash diagnostic also exposed that invoice-status currently
propagates validation errors as a closed connection. Before release, return a
structured 400 for malformed hashes and an explicit retryable response for
settlement-service errors, with endpoint coverage.
Physical companion upload diagnosis and remaining release acceptance stay OPEN.
This is a candidate deployment, not a newly signed OTA or ISO.
## Release authorization — 2026-10-01
The operator authorized preparing the next OTA and raw ISO after completing all
checks available here. Keep the missing original file/buyer confirmation,
physical companion upload and full-chain Angor indexing as explicit follow-ups;
this authorization does not establish that those scenarios passed. Complete
the known invoice-status HTTP error fix and available automated release gates
before requesting the offline signatures. Angor Indexer and the optional relay
are already present in the current signed catalog and remain included.
Shorty's Mempool report was inspected read-only: frontend/API had been running
for over two weeks, systemd reported zero restarts, and the API was processing
current blocks. The operator said it looked normal after applying the latest
update. No Mempool repair or native-service restart was performed in this check.
## Mandatory release control — operator reiterated 2026-10-01
Every task in Current tasks and Retained release work above remains in scope.
Use this document as the master coverage map, with detailed evidence in
`release-1.8.23-acceptance.md` and `npm-certificate-handoff-20261001.md`.
Distinguish source implementation, automated tests, live acceptance, packaged
artifact tests and publication verification. An implementation or passing unit
suite alone must not check off end-to-end acceptance. Keep earlier accepted
limitations explicit; never relabel an unavailable check as passed.
### Newly required NPM/security gates — publication blocked
- [ ] One authoritative active NPM data/certificate path; fresh, legacy nested
and current flat layouts, ambiguous/corrupt DB and permission errors.
- [ ] Preserve hosts, accounts, certificates/private keys, renewal files,
custom settings, permissions and uninstall decisions; backups/rollback
and repeated migration tested.
- [ ] Default and named HTTP challenge routes follow the active mount, including
first issuance and renewal under forced HTTPS.
- [ ] Automatic host/certificate create/edit/delete/disable/replacement routing
and renewal reload; no manual repair required for each host.
- [ ] NPM access lists, custom locations, multiple domains and WebSocket routes
remain enforced; host bridge must never bypass NPM security settings.
- [ ] Injection/invalid DB data, concurrent sync, failed syntax/reload, delayed
startup and certificate failures retain safe service and clear diagnostics.
- [ ] Public unknown HTTP Host, TLS SNI, raw public IP and forged Host/XFF cannot
serve management login/UI/assets/RPC/WebSockets, for IPv4 and IPv6.
- [ ] Private LAN/tailnet access works; public ACME issuance/renewal works without
opening management; trusted proxy/tunnel paths and spoofed headers tested.
- [ ] Named indexer and relay route to their actual services with verified TLS;
relay WebSocket upgrade and Nostr REQ/EOSE verified separately from certs.
- [ ] Manager/NPM/nginx restart, reconciliation, disposable VM reboot, legacy
upgrade, flat upgrade, fresh ISO and rollback preserve these protections.
- [ ] Exact OTA and raw ISO payloads contain the same correction; required
candidate tests pass before signatures, feed promotion or publication.
The release owner acknowledged both handoffs in
`/tmp/npm-release-handoff-ack.txt`. Investigator-reported Shorty containment is
recorded separately from release tests. Do not modify Shorty nginx concurrently
or overwrite its containment until an equivalent fix is tested. Known failures
and unverified required security gates block publication.
### Latest completed release harness
The pre-NPM candidate's complete release harness passed: 1,633 backend tests
(zero failed, four optional exclusions), 1,157 frontend tests, Rust checks,
formatting, type checking, catalog/trust, runtime build contexts, doctor safety,
pruning, readiness, tunnel migration and ISO overlay regressions. This does not
cover the new NPM bridge/security implementation, which requires its own tests
and relevant repeat gates after changes. No new release has been published.
### Final handoff additions — all retained
- [ ] Investigate the existing public website TLS hostname mismatch independently;
preserve unrelated sites and establish a baseline before attributing cause.
- [ ] Verify actual Angor client/version discovery with our indexer and relay
settings end-to-end. New relay kind3030 zero-events versus five on the
original Angor relay is a data/discovery difference, not API health proof.
- [ ] Resolve/document the client's actual project-query API contract, including
the observed legacy `/api/v1/query/Angor/projects` 404.
- [ ] Retain original discovery relays alongside an empty self-hosted relay;
do not imply that running a new relay automatically replicates projects.
Final investigator security evidence is now available in the NPM handoff. It
confirms the reported live containment but does not replace IPv6, reboot, fleet
or packaged-release tests. All those required gates remain open.
### Angor ownership and evidence correction
The operator retained the original relays alongside the new relay. Do not
attribute missing projects to the empty new relay, and do not treat the legacy
specialized-query 404 as a proven cause: current browser logs do not call it,
and sampled transaction IDs/status match the reference indexer. The Angor
investigator owns `apps/angor-*` and scoped tests/docs and will provide verified
project-flow results. This release session owns NPM, the management guard and
packaging; Angor acceptance stays open until that handoff passes.
### Transactions rail correction — operator report
The earlier computed-background check missed `backdrop-blur-md`: the rail still
painted a blurred surface even with a transparent background. Remove that effect;
only filter buttons should have visual styling. Verify background color/image,
backdrop filter, border and shadow at mobile and desktop widths, retain the
single scrolling row, then promote the corrected dashboard on the dev box.
This correction is required in the next OTA and ISO.
### Final Angor handoff retained
Read `angor-client-acceptance-20261001.md` and the 35-project recovery inventory;
receipt saved to `/tmp/angor-final-handoff-ack.txt`. Investigator verified one
complete Explore/detail/statistics flow and all 35 chain commitments. Recovery
of 34 original signed announcements remains open; queried sources did not yield
them, which does not prove global loss. Retain the upstream discovery defect
and full-recovery gate; repeat the scoped browser test after NPM migration and
OTA, preserve relay data, and include the app README corrections.
Transactions correction is now deployed on the dev dashboard (static assets
only; no service restart). Production build/type check passed. Both source and
served production browser checks at 390px and 1440px report transparent color,
no background image, no backdrop filter, no shadow and zero borders. Mobile
rail: 324px visible, 419px scroll width, one row. Testing used a disposable
browser profile with layout-only cached transactions; no wallet state changed.
A root-only dashboard backup was taken before promotion. Served index SHA-256:
`670c89a0ceb9d1e64e7460c554c642353a7e1f5bdaff1ec7d2a524135bd82f7f`.
### Reconfirmed NPM handoff and Framework deferral
The operator explicitly requested and received another receipt acknowledgement
in `/tmp/npm-release-handoff-ack.txt`. NPM certificate issuance remains a required
release gate: resolve the active flat/nested/custom data mount, preserve the
existing database/hosts/certificates, and verify fresh and legacy installation,
initial issuance, staging renewal, restart/reboot and OTA/raw ISO persistence.
The legacy shell bridge's nested-path assumptions are included in this repair.
Framework work is explicitly deferred for this task. Do not concurrently alter
Shorty's NPM/nginx or overwrite its live containment. Retain later evidence and
security gates; this repeated earlier handoff does not reset their status.
### Added requirement: Mempool UI on the Angor indexer domain
- [ ] Serve the existing Mempool explorer UI at the Angor indexer's public
hostname root, with working assets, deep links and live WebSocket updates.
- [ ] Preserve Angor API aliases, CORS, transaction broadcast, readiness and
verified project flow at the same origin.
- [ ] Reuse the existing Mempool stack; do not create a duplicate explorer,
database or node, or expose dashboard/Bitcoin RPC credentials.
- [ ] Update app documentation, interface metadata, dependencies and appropriate
versioned image/catalog entries when the implementation changes.
- [ ] Verify public HTTPS desktop/mobile UI, API, WebSockets, upgrade/restart,
NPM routing and exact OTA/ISO contents before marking this complete.
Confirmed against the pinned official deployment guide linked in the Angor app
README: its public indexer endpoint includes Mempool frontend plus API; standard
Mempool images are supported without a custom Angor fork or ANGOR_ENABLED flag.
Our current 1.0.1 adapter instead returns service JSON at `/` and 404 for frontend
paths. Therefore UI exposure is a real missing feature, not currently implemented.
This supersedes the earlier API-only/headless requirement for the public endpoint.
### Deployment order reconfirmed
Operator requires completing fixes and available acceptance, then deployment and
verification on the dev box and yaya before release. Framework is only a fallback
when a required check cannot be established on those nodes. Yaya address and an
unused public staging-ACME hostname have been requested; dependent checks remain
pending, while source and disposable integration work continues. Release includes
OTA, catalog/app updates and raw ISO only after required gates pass.
Angor candidate 1.0.2 now proxies the existing Mempool UI and WebSocket feed.
Disposable image checks passed root/assets/deep links, actual WebSocket upgrade
and frame, API aliases/query/body, CORS/credential stripping, method/size limits,
frontend outage with API preserved, and DNS recovery after frontend/backend
recreation. This is candidate implementation, not deployed fleet acceptance.
### Further NPM qualification findings
Real same-node routing failed inside the existing pasta namespace even when the
host could reach the LAN upstream. Disposable probes using the proposed explicit
slirp network succeeded through both LAN and host-alias addresses. The manifest,
Quadlet, Podman API and first-boot paths now express that mode, with legacy drift
checks. First initialization retains a 180-second readiness budget independent of
the network driver. The full disposable NPM proxy test passed with an actual LAN
upstream, including TLS/WSS, ACLs, certificate replacement and restart. Production
NPM and its emergency routes remain unchanged pending migration acceptance.
The dev node uses a copied enabled nginx site. The initial guard edit reached
only sites-available; a live public-ingress-marker test exposed the omission.
Both helper scripts now resolve the active copy or symlink target. After repair,
dev private HTTP returns 200 and public-proxy-marked management requests 404.
Backups stay outside active nginx include directories. Do not claim the earlier
inactive-file edit as successful protection. Focused Python coverage now includes
this layout and pre-render crash recovery, with 26 tests passing.
### Added release requirement: LoRa flasher and UK MeshCore acceptance
Operator reports `esptool write_flash failed`, with both attempts failing to start
the subprocess (`No such file or directory`, OS error 2). This is an additional
release requirement; it does not replace the existing tasks or publication gates.
- [ ] Diagnose executable discovery, installation/runtime packaging, service PATH,
missing interpreter and permissions; fail before changing the device when
required tooling is unavailable. Do not retry a missing executable as though
it were a transient serial fault.
- [ ] Verify board/chip identity and select the correct official MeshCore image;
validate downloads and offsets and preserve readable device configuration.
- [ ] Test missing tool/module, incompatible version, permission denied, busy or
disconnected serial device, timeout, flash failure and recovery reporting.
- [ ] User explicitly authorizes flashing radios attached to the dev box and
Framework with MeshCore UK settings. Identify each radio before writing;
retain backups where supported and verify flash, reboot, serial handshake,
firmware identity and actual UK radio parameters on both devices.
- [ ] Verify application reconnect and communication, and ship required tools and
fixes consistently in fresh ISO and OTA upgrades. Record physical tests
separately from mocked coverage; no universal-success claim.
Framework deferral is lifted specifically for this requested radio diagnosis and
flash acceptance; wallet/native service work remains outside this new action.
Operator additionally reports that both Framework and dev have trouble connecting
to their radios. Add connection/reconnection diagnosis and acceptance on both
nodes: USB enumeration, udev permissions/stable paths, exclusive serial ownership,
protocol detection, listener recovery after failures/unplug/replug, and correct
visible connection state. Successful firmware writing alone does not close this
task; verify subsequent serial handshake and communication on each physical radio.
LoRa investigation update: dev's existing firmware responds as Reticulum/RNode.
After confirming no flash was active, an explicit mesh-listener disable/enable
restored connection without a firmware write or native-service restart. Candidate
code fixes unchanged-settings reconnect after a stopped/finished listener, checks
tooling before disconnection, serializes probes/configuration with flash jobs,
and retains writer ownership through timeout and post-flash cleanup. Downloads
now complete before listener shutdown. MeshCore release size/SHA-256 checks apply
to fresh and cached images; the existing V3 cache matches the official release.
The packaged flasher passes its self-check and version command on both dev and
Framework without a system esptool module. Its OTA and ISO inclusion is mandatory.
Two UI board-selection/preflight tests and type checking passed; final backend
and release-suite results are still pending. Neither radio has been flashed.
### Latest acceptance checkpoint: radio connection and release status
The complete frontend suite passed: 143 files, 1,159 tests. Type checking and
both new radio setup tests also passed. The final isolated backend build/test
run is still pending; the previous run exposed an NPM/Router port collision,
which was corrected by assigning NPM's local HTTP listener port 8088. Do not
report the previous run as fully passing or the final run as completed.
Yaya's identity has been confirmed. Its existing managed web-tunnel drop-in
clears manifest port publications and supplies private tunnel HTTP/HTTPS ports
plus the local admin port. This would suppress the candidate bridge's new
loopback HTTP/TLS listeners. Migration must preserve the working tunnel/site,
add the required local listeners, validate the managed firewall/lifecycle,
retain custom overrides, and cover repeat upgrade and rollback. The current
bridge rejects non-loopback listeners, so the supported tunnel topology also
needs explicit qualification. No tunnel or NPM runtime change was applied to
yaya during this diagnosis. Its management source guard was applied and tested:
private dashboard HTTP 200, public-ingress-marked request 404.
Dev radio connection has been restored on its existing Reticulum firmware.
Framework still does not enumerate a USB serial radio. Both nodes now have the
self-tested packaged flasher, but physical MeshCore UK flashing, post-flash
handshake and reconnect acceptance remain open pending board identification and
Framework USB detection. No device firmware has been written.
OTA, app catalog and raw ISO publication remain held. Outstanding acceptance
includes NPM migration/renewal/reboot and exact artifacts, end-to-end delivery
of the reported paid file, physical companion uploads, full Angor discovery
(the 34 missing original announcements), radio hardware tests, and the final
dev/yaya candidate deployment checks. Retained tasks above remain in scope.
### Radio models confirmed and additional serial ownership fault
Operator confirmed dev Heltec V3 and Framework Heltec V4, authorizing the already
requested MeshCore UK flashing on those models. Framework is physically connected
according to the operator but Linux still enumerates no USB serial radio; manual
USER/BOOT plus RST bootloader entry has been requested. Do not assume a missing
serial node is an application-only failure.
Dev chip query confirms ESP32-S3 with 8 MB flash. Initial read-only backup attempts
failed while a surviving Reticulum sidecar held the serial port despite disabled
mesh status. The exact owning sidecar process group was identified and terminated
gracefully; the subsequent exclusive backup progresses normally. Source review
found that cancelling the asynchronous sidecar startup before its ready event
bypassed ordinary error cleanup. A new owning startup guard terminates the group
on cancellation as well as error, with an isolated real-child regression. Final
validation of this additional fix is running; it was not in the prior passing run.
The preceding full backend run passed 1,647 tests with zero failures and four
ignored. Complete frontend suite passed 1,159 tests. Added an explicitly named
EU/UK Narrow preset (869.618 MHz, BW62.5, SF8, CR4/8), retaining existing plans;
these parameters match the MeshCore app maintainer's presets in upstream
MeshCore discussion 1650. Neither physical flashing nor reconnect acceptance
is complete at this checkpoint.
### Dev Heltec V3 physical flashing result
Full 8 MiB pre-flash backup saved privately with mode 0600 and checksum. After
removing the confirmed stale radio sidecar, the exclusive read completed.
The normal mesh.flash-device RPC then flashed the official Heltec V3 Companion
USB v1.17.1-d929643 merged image successfully (100%, no error). The image's
size and SHA-256 were checked against the official GitHub release metadata.
Independent serial protocol queries confirmed model Heltec V3, firmware
v1.17.1-d929643 and actual RF readback: 869618 kHz, 62500 Hz bandwidth, SF8,
CR8 (EU/UK Narrow). This is device readback, not merely saved host settings.
The listener was then re-enabled and reported connected as meshcore. No wallet
or native Bitcoin/LND service restart was used. MeshCore remote reboot is not
supported by the current API; that attempted check returned an explicit error.
Physical unplug/replug and communication to Framework remain pending.
Live qualification additionally found incorrect binary DEVICE_INFO/SELF_INFO
parsing and a stale host-side RF-applied marker after full-chip flashing.
Candidate changes decode the current official binary layout, query the actual
firmware version during initialization, and invalidate the RF marker after a
successful flash. The dev marker was backed up and cleared before provisioning;
the independent readback above confirms settings applied. New parser, startup
cancellation and marker lifecycle regressions are queued/running; the prior
1,647 passing tests do not cover these later changes.
Framework's V4 official USB image has been downloaded and verified. Despite the
operator confirming it is plugged in, repeated sysfs/device checks show no
ESP32 USB or serial port. USER/BOOT plus RST bootloader entry was requested;
Framework has NOT been flashed and the two-device acceptance remains open.
### Operator deferral and latest qualification
Operator explicitly deferred Framework radio/hardware work and instructed us to
continue all other release tasks. Framework V4 flashing, USB reconnect and
radio-to-radio acceptance remain UNVERIFIED / OPERATOR-DEFERRED; this is not a
pass. Do not request further Framework radio operations unless needed and the
operator resumes that work. Dev V3 acceptance and durable fleet fixes remain.
The final radio backend suite passed 1,650 tests, zero failed, four ignored,
including sidecar-startup cancellation, current MeshCore metadata parsing, and
post-flash RF-marker invalidation. Frontend baseline remains 1,159 passed.
Correction to the earlier yaya tunnel concern: direct inspection of the active
Quadlet and all drop-ins confirms web-tunnel.conf ADDS private tunnel ports; it
does not contain an empty PublishPort reset. The earlier statement that it
cleared manifest listeners was incorrect. The new loopback publications therefore
coexist declaratively without editing that working tunnel drop-in. The bridge
validator now permits only the known HTTP/TLS tunnel ports bound to a currently
assigned RFC1918 address on an actual WireGuard interface named wg-web; it still
requires a separate loopback upstream, and rejects wildcard/public/unassigned
bindings and any admin-port exception. Python bridge/guard tests: 27 passed.
Actual yaya candidate upgrade and public route acceptance remain pending.
### NPM public certificate and restart qualification checkpoint
- Main backend: 1,651 passed, zero failed, four explicitly ignored hardware /
external integration tests. Container runtime library: 80 passed, zero failed.
- Bridge/management guard Python suite: 27 passed. Shell syntax and actual ISO
overlay-content test passed.
- Candidate validator inspected yaya's real runtime/WireGuard interface and
accepted its existing web tunnel publications while selecting proposed
loopback HTTP/TLS upstreams. This was read-only, not a runtime upgrade.
- Existing yaya public HTTP ACME route returned the exact random token body
written inside NPM. Lets Encrypt STAGING initial issuance and renewal dry run
succeeded using separate temporary account/config/work/log storage. Current
production certificate and host records were not replaced. Public site HTTP
and trusted HTTPS retain their authentication requirement (401).
- First renewal harness timed out while Certbot used a 292.7-second randomized
delay; the remote log confirmed successful simulated renewal. A deterministic
rerun with --no-random-sleep-on-renew returned exit 0 and success confirmation.
Only the temporary staging directory was removed afterward.
- Real disposable NPM nested-layout test completed: namespace LAN upstream,
API host creation, custom locations, client-IP spoof rejection, exact ACME
token, trusted TLS/WSS, certificate replacement, password/network ACLs,
enable/disable/delete, and restart with retained DB. Latest restart took 7.6s.
Earlier rerun exceeded the fixture's 90-second restart window; the test now
uses the manifest's 180-second budget and records both route/admin statuses
and container state on failure. Do not erase that earlier observed failure.
- Cleanup was hardened to continue cleaning other fixtures after a timeout.
Two early test runs passed functional assertions but failed cleanup; their
leftover disposable containers/networks were explicitly removed. The latest
full run exited successfully.
Legacy non-Quadlet repair now retains the old container for rollback, restores
it after replacement failure, preserves its exact image and environment values,
and waits for HTTP API readiness. Environment values use an exclusive mode0600
file cleaned on drop, not argv or the host process environment. Invalid/multiline
entries fail before stopping the original. An occupied rollback slot is preserved
for review rather than deleting an unknown container. Live interrupted-migration,
additional operator-override and rollback acceptance remain OPEN; unit success
is not proof of those deployment paths.
The deployment backend and frontend build are in progress. Full candidate dev/
yaya upgrade acceptance, reboot, exact signed OTA/catalog and booted raw ISO
remain open. Framework radio is operator-deferred, not passed. The original paid
file bytes, physical companion upload and 34 missing Angor announcements remain
separately tracked.
### Further completed acceptance
The complete disposable NPM test now includes a deliberately failed replacement
with an occupied host port. Restoring the retained container preserved its exact
container ID, database, configured hosts and authenticated API access; the test
exited successfully and cleaned its fixtures. This verifies the Podman rollback
mechanism, not yet the full installed backend's legacy-repair entry point.
Dev frontend build completed and was deployed with a separate rollback backup.
Served production Transactions layout passed at widths 390 and 1440: transparent
background, no image/blur/shadow/border, nowrap and exactly one row. Mobile rail
is 324px wide with 419px scroll content. Backend candidate compilation is still
in progress, so the latest backend changes are not yet deployed.
Dev Bitcoin remains unpruned and in IBD (observed block543676/header969495,
verification progress0.2284). This is not full-chain Angor acceptance. The operator
has been asked which seller and filename identify the failed Lightning purchase;
the earlier recovered Framework-seller invoice is not confirmed as that purchase.
### Read-only Shorty migration preflight: remaining ownership conflict
Preflight found both flat and nested NPM databases. The live container's explicit
/data mount identifies the active one, so the candidate resolver now uses that
verified mount (or its saved validated receipt after a managed stop), preserves
both databases, and still refuses multiple databases without an authoritative
selection. Python coverage verifies both explicit choices and unchanged bytes.
This helper update occurred after the deployment binary build started; a final
release rebuild must include it. Do not claim the in-progress binary contains it.
After resolving storage, the two Angor emergency routes match the exact known
handoff templates. Another existing file, shop-btcpay.conf, conflicts with an
enabled NPM record: the manual route supplies HTTPS using certificate10, while
the NPM host currently has certificate_id0 and SSL forcing disabled. The manual
route and NPM record cover the same two public names and backend web port. Blindly
retiring the route would break its HTTPS. No database, host, certificate, route
or runtime was changed on Shorty. The bridge correctly refuses this ownership
conflict and now names its configuration file in the diagnostic. Align TLS/route
ownership and verify the public shop before retiring that manual configuration;
Shorty's full migration acceptance remains OPEN. Preserve live containment.
### Candidate deployment and additional real-upgrade ACME regression
The operator explicitly deferred Framework's physical radio investigation and
requested continuation of all other work. Framework radio remains unverified.
Dev and yaya now run the backed-up unpublished backend candidate SHA256
4c47269b3480ca0362df18dae160c073a19ea33507e04cacdad5b96837990ca6 and production
frontend index 3099c4ba44528a4a4c524f9a26159414558efa16abdd12cc7bfd64376cbb6089.
Both management health checks passed; native Bitcoin/LND container identities
and start times were unchanged. Yaya public site retains trusted TLS and its
401 authentication requirement; NPM admin API200, private dashboard200 and
public-ingress-marked dashboard404. The first yaya staging attempt stopped
before binary replacement because rsync was absent; deployment now uses Python
copying without that dependency and completed successfully.
Actual startup exposed an additional regression: the canonical nginx template
had only HTTP ACME, while the bridge demanded two locations. Startup rewrote the
previously repaired config and the bridge rejected it before fixing the nested
root. Source now adds HTTPS ACME to the shipped template and migrates the exact
recognized legacy default-server layout; custom/ambiguous layouts still fail
closed. The missing-token route must return404 rather than the dashboard SPA.
28 Python checks passed. The real isolated nginx suite now starts from the
legacy missing-HTTPS layout, applies the migration, and passes all120 public
negative cases plus HTTP/TLS exact-token, private-access and reload checks.
Applied the latest helper and its atomic ACME-only repair to yaya: actual token
written inside NPM returned exact200 over host HTTP, host HTTPS and public HTTP;
missing tokens returned404 for allthree. Public site trustedTLS/auth preserved.
Local self-signed host HTTPS was tested with certificate verification disabled;
public site HTTPS used normal certificate verification. Shorty was not modified.
The running backend still embeds the older helper/template; final rebuild is
REQUIRED before restart/reboot/persistent upgrade acceptance can pass.
The prepared unsigned catalog validates with zero metadata drift and trusted
registry hosts. Its only changed entries are NPM and Angor indexer1.0.2. It has
not been signed, installed or published. Yaya's current signed catalog retains
NPM's old pasta network/tunnel-only HTTP+TLS listeners; full NPM runtime/bridge
migration acceptance awaits the reviewed signed catalog. Do not mistake the
backend/UI deployment or ACME-only fix for completed catalog migration.
### 2026-10-02: rebuilt candidate deployed; private catalog qualification prepared
Release-profile candidate build completed successfully. SHA256:
af0648ad4ef8b6183d3c1ff485721fa40b12bb730c6e0322bc5f209ed06fce39.
Focused bootstrap tests:10 passed. Full isolated backend rerun:1651 passed,
zero failed, four explicit hardware/external ignores. Python guard/bridge28
passed again. No new source changes occurred between these checks and deployment.
Deployed this rebuilt backend on dev and yaya, with private previous-binary,
nginx and native-container baselines. Both manager health checks passed. A later
post-startup comparison confirmed Bitcoin/LND identities/start times unchanged.
The installed bridge helper now matches latest source bytes after restart.
Private UI200, marked-public HTTP/HTTPS404 and missing HTTPS challenge404 passed.
Dev HTTPS intentionally binds its LAN/WireGuard addresses, not127.0.0.1; an
initial loopback probe got connection refused, corrected to the actual listener.
This was a test-address error, not a product outage. Local self-signed HTTPS
checks skip certificate verification; public-site TLS checks use normal trust.
Full-machine reboot qualification is still pending.
Prepared a fresh candidate catalog with only NPM and Angor indexer entries changed.
Metadata drift0; registry trust check passed. Unsigned SHA256:
5801309bf21d3f6fd03ce5702d68b383a518f734092bf265f5e0ad243095a25e.
NPM's new manifest is capability-gated by runtime-migration-backup-v1; older
nodes retain the original manifest. This candidate is for private qualification,
not fleet publication. An operator-only hidden-input signer validates the exact
catalog and binary hashes, checks the pinned release root and restores the
unsigned original on failure. Its noninteractive refusal was tested. Signature
is required before testing through the nodes' normal trusted-catalog path.
No catalog, app image, OTA or ISO was published. Framework remains deferred;
all other open requirements retain their previous status.
### Signed catalog and private qualification selector
The operator signed the qualification catalog. Cryptographic release-root
verification passed locally and on yaya; after removing signature envelope fields,
its contents exactly match the reviewed unsigned candidate. No publication.
The catalog is staged under /var/lib/archipelago/qualification on both test nodes,
with previous catalog/app metadata and container identities privately backed up.
Normal mirror loading deliberately forces the public origin first, so simply
prepending a private mirror cannot reliably test an unpublished candidate.
Implemented ARCHY_APP_CATALOG_CANDIDATE as an explicit absolute-file selection:
requires an anchored release-root signature, validates before cache replacement,
retains exact signed bytes, does not alter mirrors/trust, and fails without
public fallback when the selected file is invalid. Added unsigned, tampered,
wrong-key, malformed, missing, oversized, relative-path, valid and idempotent
coverage. Full isolated backend suite:1653 passed,0 failed,4 explicit ignores.
The optimized selector build is still in progress; selection is not enabled yet.
See docs/candidate-catalog-qualification.md for activation and mandatory removal
once the tested public catalog is available. Do not leave test nodes pinned.
Yaya NPM preflight:8088/8444 are free, active public host has no conflicting
host-nginx ownership, database tables and certificate-file hashes saved privately.
No Shorty mutation. Dev public Angor reference acceptance passed TLS/WSS, exact
funding commitment, official Explore and detail/statistics again; this still
checks only the known original project, not all35. Dev Bitcoin continues syncing
(reported sync_progress approximately0.307); full-chain acceptance remains open.
Current tested hardware product codes:dev20CLS7S900 and yaya20CLS6BH00, both Podman
5.4.2; kernels6.12.74+deb13+1-amd64 and6.12.107+deb13-amd64 respectively. Framework
remains deferred. No Docker or new ISO-boot acceptance is implied.
## Live Lightning purchase: Framework to Shorty — 2026-10-02
Operator explicitly authorized a very small new test purchase, then performed
it from Framework. This is separate from recovering the Amish Paradise sale.
Fixture: `archy-lightning-delivery-test-20261002.txt`, price 1 sat, Lightning only.
Read-only checks confirmed one matching seller invoice, SETTLED for exactly
1 sat, and Framework payment SUCCEEDED for 1 sat with 1 sat routing fee
(1,000 msat). Total spent was 2 sats. The assistant sent no payment.
Framework has exactly one durable purchased-content ownership entry for the
fixture, with backend `lightning`, paid_sats=1 and size_bytes=121. Its cached
file SHA256 equals the original seller fixture:
`d55f7a6acd77bdc3c35c65ecac6d1492096e99252d07d433e6286544540cde7e`.
**PASS: actual node-wallet payment, seller settlement, delivered bytes and
persisted buyer ownership/cache.** Framework runs the candidate backend
`8fb6249d1869bb8c9aea26d0f846de5b3eec328113a5c7f573628306e26e652e`;
Shorty runs `e108b78bbbd21cb7d5d47c8d0b7b9b19b63fb0c44678773603202440ec7d6f5b`.
This also exercises the candidate buyer against the existing seller version.
Live reopen without payment and restart acceptance are not established by
this check. Shorty had no matching durable entitlement JSON in the inspected
location; do not attribute the candidate seller persistence implementation to
this older seller binary. No node or wallet was restarted. The tiny fixture
remains available for a free cached reopen check; remove only its catalog
entry/source file afterwards, preserving buyer ownership and payment records.
### Operator-confirmed free reopen — 2026-10-02
After the verified one-sat purchase, the operator reopened the file on Framework
and confirmed it worked without another payment. **PASS: live paid delivery,
durable buyer ownership/cache, and free repeat access**, with independent
settlement/byte checks above and operator confirmation of the reopen UI.
This closes that specific live acceptance check; it does not establish an
untested restart, outage, or seller-upgrade scenario.
The temporary seller catalog entry and source fixture were removed after
acceptance. Buyer purchased bytes/ownership and all payment records were preserved.
## Release-agent continuation: Bump production deployment — 2026-10-02
Authorized network access was restored without changing credentials. The
previously running optimized build completed; its Bump implementation was
verified present and artifact frozen separately from subsequent Fast-default
and NPM source edits. Backend SHA256:
`af0cf7bd8bdc60c7b29976c11cbc002c46979be5120909f169856f8bd6e71058`.
The approved production archive retained SHA256
`d0e253aba09ad257136e3feb5b63176c388f3bb968f560702eefb768d29e494d`.
The reviewed staged rollback deployment ran successfully on Framework. Manager
health200, native Bitcoin/LND container IDs and start times unchanged, LND
wallet identity/channels/balance unchanged. Actual rollback files now exist
under `support/framework-fee-bump-20261002`. Served UI index SHA256:
`9fef18c8c1c9bc21f43c3635b747dfcfbea965b096867b454bbf608121715438`.
The approved Bump layout and shared green animation were preserved. No bump,
channel operation or payment was submitted. Normal authenticated quote/status
acceptance needs a fresh dashboard TOTP login; requested from the operator.
Later source work, NOT in that deployed artifact: Fast defaults for send,
channel open/cooperative close, reset/reopen and hardware PSBT estimates.
97 focused frontend/client tests and three isolated fee-policy tests passed.
Full integration/release validation remains pending. NPM legacy gateway support
was added across runtime paths with a separate catalog capability, but the
real integration test exposed lost client-IP preservation on that subnet;
this remains an explicit blocker until corrected and retested. Neither the
new catalog nor these later backend changes has been deployed or published.
### Combined continuation validation checkpoint
Fast-default, Bump and App Store UI changes pass the complete frontend suite:
1,176 tests in146 files, zero failures. Production TypeScript/Vite build passed.
The App Store change filters Cuprate/NetBird implementation parts from signed,
community and persisted catalogs, collapses BTCPay aliases onto the canonical
Commerce app, and keeps installed legacy-only BTCPay visible. Thirty-four
focused grouping/launch checks passed; actual yaya browser acceptance is running.
NPM legacy host gateway correction now passes the complete disposable integration:
LAN/host alias/old gateway requests from its namespace; forwarded client IP;
spoofed headers; custom paths; real HTTP/TLS/WSS; ACME exact file; password/network
ACLs; certificate replacement; restart; forced-failure rollback; disable/delete.
The trusted rootless forwarding source is169.254.1.100, added as one managed block
through NPM's supported custom http_top.conf include. Existing custom directives
are preserved with a private pre-change copy; symlink/modified managed blocks
fail for review. A read-only bind under conf.d was rejected during qualification
because NPM's startup mutates that directory; it is absent from the final source.
Twenty-three Python bridge checks pass. Older gateways and manifests still need
the new signed capability variant and actual upgrade acceptance; no fleet release.
### Yaya App Store grouping deployed — 2026-10-02
The dashboard fix is now deployed on the affected yaya-server. Actual served
index SHA256 is `076290e992a18fe418ea5ad411007cffe3280608c63576da2587d1cc371a50e4`.
The previous dashboard is backed up under
`/var/lib/archipelago/support/app-grouping-ui-20261002`. Every container ID and
start time matched before/after; this UI deployment did not recreate apps.
Authenticated live Chromium checks at 390px and 1440px show exactly one Cuprate,
one NetBird and one BTCPay Server, with loaded icons. Repeated checks after a
hard reload pass at both widths. Acceptance used the actual served dashboard,
backend and signed catalog. The earlier local asset-overlay attempt caused a
Chromium private-network classification error and is not counted as acceptance.
Installed-component hiding and legacy-only BTCPay preservation have automated
coverage; these browser checks did not install these products on yaya.
The latest strict custom-fee validation adds eleven invalid-input cases;
95 focused SendBitcoinModal/RPC tests pass after that change. The subsequent
TypeScript/Vite production build passes. Prior full frontend suite: 1,176 passed.
Combined optimized backend and final-source isolated backend rerun remain in
progress. No public release, catalog update or ISO has been published.
Follow-up audit: Marketplace.vue still uses plain desktop/mobile search inputs;
extend the existing shared clear-search control to this category view before
claiming the earlier all-App-Store search requirement complete.
Additional live category checks pass: BTCPay Server appears in Commerce and is
absent from Money. The final browser run passed all listing, icon, hard-reload
and category assertions; its trailing optional screenshot timed out after font
loading. This capture failure is recorded separately, not reported as a fully
successful harness exit. Earlier actual-node desktop/mobile screenshots exist.
### 1.9.0 continuation checkpoint
See [the current 1.9.0 acceptance summary](release-1.9.0-acceptance.md).
The category-view clear-search gap is fixed and verified on yaya at 390/1440px:
click and Escape clear, focus is retained, button remains inside the field,
heights 52/40px. Dev mobile passed; a companion introduction and then resource
alerts obscured the desktop test, and a later navigation timed out under build
load. Dev desktop must be repeated after the build; these attempts are not passes.
Read-only Framework recheck: CryptPad/Core Lightning containers remain absent,
uninstall markers retained, all three real Immich containers running continuously
since 2026-09-21. The duplicate Immich entries were synthetic inventory, not actual
restarting databases. Rendered Framework inventory still requires normal dashboard
authentication. No Framework native service was changed by this check.
### Verified ledger reconciliation — 2026-10-02
Completed checkboxes above now reflect the retained source, automated, live-node
and operator evidence rather than leaving those accepted tasks apparently open.
Seller settlement/persistence and buyer exact-byte one-sat purchase/free reopen
are recorded separately; no additional payment was sent. CryptPad removal and
uninstall markers survive the recorded manager restart. Actual Portainer namespace
smart HTTP and Compose access passed after the current combined deployment.
The installed/stopped/removed upgrade matrix, physical companion route, Framework
rendered Immich inventory, final Fast-default acceptance, NPM signed migration and
final artifacts remain open. No artifact-wide reboot acceptance is inferred.
Dev category search now passes 390px and1440px, including click/Escape, retained
focus and40/52px field heights. The earlier build-load timeouts remain recorded.
The final audit found the fee-only child grouping requirement still outstanding.
A source correction now groups only a recorded simple CPFP child verified against
wallet ownership, input relationship, fee-only delta and current chain/mempool
state. It preserves recipient amount, excludes replaced fees from the total,
exposes linked fee history and targets the current child for another Bump.
Focused UI tests pass; new backend and real-regtest history checks are pending.
### Signed qualification — 2026-10-05
See the current1.9.0 acceptance record for exact hashes/evidence. Signed catalog
and final payment/history corrections are deployed on dev/yaya; actual regtest
with grouped history passes. Yaya NPM's managed gateway works without its
temporary override, with preserved DB/certificates, actual upstream access and
manager-restart/reconciliation stability. ACME/public application and Portainer
checks pass. Full-machine reboot, final artifacts and remaining operator/Angor
gates are still open; nothing published.
## Operator checks accepted; upload UX amendment — 2026-10-05
Operator reports the requested human checks worked perfectly: Shorty shop SSL,
physical upload flow and Framework dashboard/purchased-file checks. This is
operator acceptance, not a claim of newly independent device testing. Read-only
Shorty verification confirms shop certificate_id12 and Force SSL enabled.
Remaining migration/artifact/security and Angor requirements still apply.
Operator supersedes the globally persistent upload-bar requirement: keep the
bar only on the screen where the batch originated, continue transfers across
navigation, show explicit Complete on successful server save, and use a
completion notification elsewhere. Source now retains the originating route,
removes the global floating bar, keeps the original44px inline bar, and reports
success/error/cancellation distinctly.25 focused store/component/notification
tests pass. The subsequent full frontend suite passed1,193 tests; production
build and actual served desktop/mobile real-upload checks passed. Deployed to
dev/yaya with index SHA256
`86bb728017b118d8e98f032419e7fbfd6ecd78b7e464c982a2075cc38c582814`;
no apps or backend services restarted. Retain this as the preceding UI evidence,
not evidence for the later resumable-upload implementation. No new payment was requested or performed.
### Resumable upload addition — 2026-10-05
Operator requests recovery after a background pause or connection loss. The
installed File Browser identifies as2.63.23/e8a388f8 and supports TUS. Cloud now
has a candidate chunked upload implementation: random same-folder staging path,
server-offset reconciliation, transient retry/online/visibility recovery,
cancellation, final SHA256 verification and rename. Lost final chunk/rename
responses are reconciled without restarting or accepting a same-size old file.
The original-screen-only44px bar, Complete label and off-screen notification
remain. Fifteen focused protocol tests pass; full build/deployed fault injection
are in progress. This is not yet live acceptance.
Recovery requires the selected File to remain available in the running page.
An OS-killed app or expired server upload session may require reselecting the
file. Do not promise uninterrupted background execution or restart persistence.
This gate is additional to the already accepted physical upload flow.
## ngit PR integration — 2026-10-05
Both requested proposals are merged and pushed to Gitea and ngit main at
`2c1bcacf`; ngit independently reports both as `applied`.
- `494d2483`: opt-in NODE_IDENTITY_PUBKEYS for app owner allow-lists. Review
corrected ECMAScript/Rust whitespace differences and added strict public-key
validation. Appliance identity excluded; no private keys or signing capability
given to apps. Existing manifests and the native signing flow are unchanged.
Documentation explicitly describes linking all offered user identities.
- `c18ebd7f`: nostr0.44.7 and nostr-relay-pool0.44.3. The standalone relay pool's
maintenance advisory remains; SDK0.45 migration is a separate follow-up.
- Combined isolated backend suite:1,678 passed, zero failed,4 explicit ignores.
Real loopback hostile-relay test rejects altered content, author and signature
reusing a known DB event ID while accepting a valid event. NIP04/NIP44 normal
encryption and hostile/oversized payload tests pass. The initial relay harness
returned before connection establishment; corrected to wait for an actual
connection before fetch, and the complete rerun passes.
- Evidence: /tmp/archy-190-ngit-complete-tests.log, origin/ngit push logs and
/tmp/archy-190-ngit-postmerge.json. This is source publication, not OTA/ISO or
catalog publication. Later File Browser credential changes need a new suite.
## File Browser secure automatic login — NEW REQUIRED GATE
Operator requests unique per-node credentials, working Cloud from first launch,
no admin/admin and fleet-wide testing. Framework's reported authentication issue
recovered, which is not proof that this gate is fixed. Yaya rejects the saved
password with403 despite healthy File Browser2.63.23. Never count that as a
passed upload test.
Confirmed source issues: first-boot paths still try noauth/admin defaults; the
post-install hook assumes admin/admin and uses an incompatible password-change
request shape; the generated ISO path updates a running DB and uses a different
DB filename; Cloud hardcodes admin and invents admin/admin on missing secrets.
Candidate scripts/filebrowser-credentials.py now provisions a random username
and256-bit password offline with the pinned app image, backs up the selected
DB/config, preserves custom accounts, tests automatic login plus folder access
in a network-isolated container, rejects unauthenticated access, rotates only a
proven admin/admin login, and atomically publishes a0600 credential record.
Fresh real-image acceptance passes. Legacy/default/custom/restart/rollback,
first-boot/Quadlet/runtime wiring, live yaya/dev/Framework qualification and final
artifacts remain OPEN. No live File Browser account or DB has been modified.
Upload resume: source/build/full frontend1,208 tests passed; subsequent48 focused
protocol/client tests passed after filename escaping correction. UI deployed on
dev/yaya index SHA256
`31ac7bcc704c18f88a8b9800fb46bc7941651983e1a99b97d036a8d9e95a58b5`.
Actual dev1440/390px real-server fault injection passed partial offset123456,
offline reconnect, lost final PATCH and rename replies, exactSHA256, encoded
filenames, original-screen-only44px bar, notification, cancel and empty files.
Yaya is blocked at the credential gate above. Physical suspended/killed-app
acceptance is not inferred from these viewport tests.
## 2026-10-05 resumed release qualification
- Latest full frontend: 1,210 tests passed across 148 files. Production Cloud UI
and AIUI builds passed. Dev and yaya serve index SHA256
`3e10a25db75e4712310eb34c98bf7595ad5db3a444f9126a73715b1d40493a33`;
UI archive SHA256 `586d1864c5c4027086194f6b5951a9b770c4e7ce9ba9ec3128e2ac0c1bde55e7`.
Private UI backups: `/var/lib/archipelago/support/cloud-auth-20261005`.
- Real dev browser upload tests pass at 1440/390px, including interrupted JWT
refresh, partial write, offline recovery, lost final PATCH/rename responses,
exact SHA256, encoded filenames, cancellation, empty file, origin-only 44px
bar and completion notification. Initial run overlapped UI deployment and
failed navigation/bar timing; kept as failed evidence. Clean rerun explicitly
verifies successful navigation and passes both viewports. Physical OS suspension
and yaya authentication/upload acceptance remain separate gates.
- Real File Browser image matrix passed fresh, legacy-default, legacy-custom,
legacy-noauth and forced-failure exact DB rollback. Existing file bytes and
user IDs/permissions preserved; custom credentials preserved; admin/admin and
anonymous access rejected. Actual disposable Quadlet pre-start and restart
also pass, with stable managed credentials. Four Python unit tests pass.
- File Browser startup integration now covers the direct runtime, Quadlet,
first boot and ISO script. Binary bootstrap installs its matching helper before
reconciliation. Fixed bundled first-boot missing NET_BIND_SERVICE and duplicate
creation attempt for a stopped File Browser. Live credential migration is still
pending the optimized backend build; no production DB/account modified yet.
- Final combined isolated backend suite: 1,681 passed, zero failed, four ignored.
An earlier run failed the Nostr relay fixture after a normal ping closed its
text-only receive loop. Fixed the fixture to answer pings; the complete rerun
passes. No failed run is counted as acceptance.
- NPM: 23 Python tests pass, including exact emergency BTCPay route recognition,
operator edit preservation, missing certificate/alias refusal and transactional
rollback. Existing emergency Angor routes now also require complete TLS
replacements before retirement. Actual disposable flat-layout NPM integration
passed namespace reachability, legacy gateway, ACME exact bytes, forced HTTPS,
WSS, certificate replacement, password/network ACLs and forged-header rejection,
restart, disable/delete, and forced bind-failure restoration. This is not a
staging-CA issuance/renewal or ISO/reboot pass.
- Shorty read-only inspection confirms shop certificate12 and Force SSL with both
hostname aliases; old manual shop route still uses certificate10. No live
Shorty routing change in this qualification. Migration remains pending.
- Evidence logs: `/tmp/archy-190-final-combined-backend.log`,
`/tmp/archy-190-cloud-auth-ui-dev-live-2.log`,
`/tmp/archy-190-filebrowser-final-integration.log`,
`/tmp/archy-190-filebrowser-quadlet.log`,
`/tmp/archy-190-npm-final-integration.log`.
- OTA/catalog/raw ISO publication remains held. Framework radio deferred;
Angor 34 unrecovered original announcements and dev full-chain acceptance
remain open. README alpha/funds notice is separately published to both remotes.
## Live File Browser ownership regression — publication hold
2026-10-05 dev candidate backend SHA256
`3e01da72fcea0a61852f3d9038e67630e328c65d6433da749671d60b91c37ffa`
built successfully, then failed live credential migration before DB mutation.
The helper could not create its private backup under the legacy data-directory
owner (host UID100000). The original real-image fixtures aligned data ownership
to the image UID and therefore missed the shipped manifest's different mapping.
The managed File Browser has DAC_OVERRIDE for that layout; the helper did not.
Restored prior backend SHA256
`cfddec834a53609f8bef924f3905da76df45f22426cac2628c4c2cb06bea5d09`
and original File Browser Quadlet with the staged rollback script. Both services
are active. Yaya backend was not changed. No candidate credential record was
published; failed setup stopped at backup-directory creation before DB changes.
Source helper now includes the managed server's DAC_OVERRIDE storage capability;
new real-image legacy-owner and actual-Quadlet fixtures reproduce that mapping.
Rollback fixture now forces an account-policy failure after noauth migration so
it still verifies restoration after a real DB mutation. These revised tests and
combined backend validation are in progress. A corrected embedded-helper build
and new live qualification remain required. Do not reuse the failed binary as
final release or mark the credential gate passed from earlier fixture results.
Release-note drift corrected to1.9.0/current upload behavior and File Browser/
Nostr additions. The checker now rejects stale descriptions/dates for an existing
version; its regression passes. Latest notes UI built and deployed dev/yaya index
SHA256 `97aab07e67eccc1bb3d215534b537b83e1372bf5c36b505b6127a24a2b629e23`.
Phone background/reconnect acceptance question is pending, not passed.
## Mobile Cloud media viewer — 2026-10-05 release addition
Operator screenshot shows the filename behind the companion status bar and a
cramped video viewer. Confirmed mobile CSS positioned every toolbar button at the
same coordinates; fullscreen was only attached to a video double-click, and the
viewer ignored the companion's `--safe-area-top/bottom` values. Legacy global
lightbox maximum dimensions also constrained the component unexpectedly.
The viewer now reserves separate safe-area-aware title, media and action rows on
phones, keeps each action at least44px without shrinking, and places previous/next
beside the action row rather than over the media. Videos retain their intrinsic
picture ratio with native playback controls. Photos and videos have a labeled
fullscreen action: standard fullscreen where supported, native Safari video
fallback, and an expandable in-page viewer when embedded browsers deny it.
Escape/exit and keyboard focus remain usable. Decode failures offer retry, and
late media requests cannot replace a newly selected file or leak their blob URL.
Validation:11component tests pass, including existing PiP handoff, fullscreen
success/denial/Safari fallback, decode retry, fetch ordering and focus restoration.
Real Chromium checks at320x568,390x844,844x390 and1440x900 pass safe-area/control
geometry, fullscreen and exit, generated video playback and close. Screenshots
were inspected. This does not claim physical companion/Safari acceptance.
Evidence: `/tmp/archy-190-lightbox-focused.log`,
`/tmp/archy-190-lightbox-browser.log`; repeatable browser fixture
`tests/lifecycle/media-lightbox-browser.cjs`.
The operator separately accepted both physical phone upload background/reconnect
and Framework Cloud folder/upload/open checks. Those upload manual gates are
closed; this newly reported media viewer gate is separate. The ongoing candidate
ISO and staged OTA predate this addition and must not be published as final;
regenerate final artifacts and hashes after this fix is qualified.
### Permanent file menus and companion fullscreen follow-up
The operator additionally reported that touch users cannot reach hover-only file
actions without opening the file. Grid and list cards now have a permanent44px
translucent ellipsis action, and owned-file lightboxes expose the same menu.
Share/download/delete are available without opening the underlying file; delete
requires a separate explicit confirmation. Unsupported actions are omitted for
non-owned callers. The menu stays within the viewport, participates in native
fullscreen, traps keyboard focus, dismisses on Escape/outside tap and restores
focus. Cloud-folder delete failures now remain visible instead of becoming an
unhandled rejected promise.
Sixteen focused component tests pass. Real Chromium grid/list touch checks pass
at320,390and1440px, covering permanent visibility, unclipped menus, share and
cancelled delete with no preview triggered. Lightbox action access also passes
inside fullscreen at all four prior viewport sizes. The actual deployed dev
Cloud screenshot and3840x2160video decode successfully (75.633seconds, no media
error); native Chromium fullscreen/exit/close pass. No operator files changed.
The Android companion has no existing `onShowCustomView` implementation. Added a
shared fullscreen host to both dashboard and app WebViews: retains the current
WebView, accepts Chromium's custom view, hides system bars with swipe escape,
handles Back and Chromium exit, restores prior bars, releases the view on screen
disposal and rejects duplicate/reparented requests. Kotlin compilation passes.
Companion version0.5.33/build53 is reserved for this change. Lifecycle tests,
clean signed APK build and physical companion acceptance remain required; the
web fallback is not evidence of native Android fullscreen acceptance.
Updated qualification: all **1,222 frontend tests / 150 files** pass, production
build passes, and the permanent menus are deployed on the dev box. Live browser
checks pass for real Cloud photo/video decode, card-menu access without preview,
cancelled deletion, and the viewer's action menu during fullscreen. No files were
deleted or shared by the tests. Android's three lifecycle tests pass (zero errors
or failures). The clean APK build initially failed because the expected signing
keystore was absent. Recovered the existing local key after matching its public
certificate exactly to the currently served APK; a clean packaging retry is in
progress. No replacement signing identity was generated, and no private signing
material is included in this change.
Companion packaging exposed an additional release-script defect: noisy successful
`apksigner` output caused `printf | grep -q` under `pipefail` to return141/SIGPIPE,
rejecting an APK whose v1/v2/v3 verification results were all true. The publisher
now uses input redirection for these checks and additionally pins the existing
companion certificate, protecting in-place update compatibility. Four executable
regressions exercise the actual verification block: large valid output, missing
signature schemes, wrong signer and verifier failure. All pass; the test is
included in `tests/release/run.sh`. A fresh canonical clean/package/sign run is
required after this script fix; no failed packaging attempt is marked published.
### Companion download regression — operator report after build53
The operator accepted the improved viewer, then reported Download did nothing,
confirmed companion-only. Real Chromium downloaded the exact Cloud screenshot
bytes (202,648 bytes; matching SHA256), so this is separate from the web menu.
Both companion WebViews lack a general DownloadListener. Added a shared native
Save dialog/download handler, with bounded streaming, existing WebView cookies,
progress, cancellation and deletion of the newly created incomplete destination
on failure. Redirects retain cookies only for the starting origin, HTTPS
downgrades are rejected, and authentication/login-page failures do not save an
error page as the user's file. TLS verification stays enabled. No broad storage
permission is introduced. Blob/data URLs currently report unsupported instead of
silently doing nothing; own Cloud files use authenticated HTTP(S) raw URLs.
Companion0.5.34/build54 is reserved for this repair. Compile, network regression
suite, canonical clean signing, dev deployment and a real phone download remain
required. Build53 must not be described as having working companion downloads.
The existing fullscreen suite also passed its Android28+35 matrix: six cases,
zero failures/errors. No release or APK fleet publication has occurred.
Download validation update: the sequential clean Android build and all12tests
pass (six network-download cases plus six fullscreen lifecycle cases across
Android28/35). Tests cover exact authenticated bytes/progress, same-origin versus
cross-origin redirects, bounded redirects, unsupported URLs, auth failure,
cancellation, destination failure, TLS downgrade refusal and login HTML rejection.
XML evidence was preserved before packaging in
`/tmp/archy-190-companion-download-test-results/`. The canonical clean0.5.34/build54
APK package passes v1/v2/v3 verification and the existing signing-certificate pin;
the APK contains the new download handler. Fleet publication remains held pending
physical save/open acceptance and the existing release gates.
2026-10-05 operator acceptance: companion0.5.34/build54 phone download check
(save/open/cancel) accepted: “works, we can proceed”. Viewer and physical upload
acceptance retained. Close this manual gate; other release/security/Angor gates
remain open. No fleet OTA, ISO or public demo publication inferred.