merge: reuse accepted AI provider setup in publishing worktree

This commit is contained in:
archipelago
2026-10-08 12:24:43 -04:00
70 changed files with 3180 additions and 499 deletions
+49
View File
@@ -0,0 +1,49 @@
# AIUI provider setup follow-up
Status: implementation in progress; not deployed or accepted.
The app's browser key vault did not configure the node's authoritative Claude
ledger. Embedded chat delegates to the node's tool loop, whose provider selection
also ignored the frontend's Claude/OpenRouter picker. The backend retired the
OpenRouter relay while that picker still offered it. Generic502/503 errors were
classified as missing keys and sent users back to settings.
Implementation scope: offer setup in trusted dashboard chrome before first use;
keep credentials out of the iframe's chat, prompts, history and browser storage;
use private atomic node credential writes; persist an explicit provider choice;
retain the existing tool permissions and outbound privacy screen. Explicit
provider selection must not silently send a failed request to a different cloud
provider. Routstr funding and allowance remain separate, deliberate actions.
OpenAI support uses its standard API key, not a presumed Codex subscription key.
For the existing node tool loop, the Chat Completions API retains the same
message/tool-result representation and existing egress checks. This is an
intentional integration choice, not a claim that it is the newer Responses API.
The HTTP adapter has a fixed HTTPS destination, no redirects or retries, a bounded
completion and response, store:false, and errors that do not echo upstream bodies.
The operator supplies the model ID; no inference is issued merely by saving a key.
Official documentation checked2026-10-06:
- https://developers.openai.com/api/reference/overview (server-side bearer credentials)
- https://developers.openai.com/api/reference/resources/chat/subresources/completions/methods/create
(max_completion_tokens, tool calls, store)
- https://developers.openai.com/api/docs/guides/streaming-responses
(Responses recommendation and distinction from Chat Completions)
Qualification so far: all 1,244 dashboard tests and 363 AIUI tests pass before
final toolbar placement/funding refinements; latest focused checks pass 15
dashboard and 24 AIUI tests. Both production bundles build. Chromium390/1440px
verifies first-use setup, private fixture key/model save, no key in localStorage,
retained unsent draft and no page errors. Visual review found an overlapping
mobile setup button; moved setup into the existing model menu. That final layout
still needs rebuilt-browser qualification. No fixture key reached a real provider.
Explicit local selection now stays local; Claude/OpenAI selection cannot silently
fall through. Routstr selection persists and retains the existing budget checks.
Payment-required responses request the funding view, while temporary502/503 and
rate limits do not claim credentials are missing. Reopening ecash funding reloads
the address, including repeated opens on the same tab.
Remaining: isolated backend results, final browser/funding/key-error checks,
actual provider compatibility and node deployment. No paid inference tests or new
wallet spending have been performed or authorized by this implementation work.
+63
View File
@@ -0,0 +1,63 @@
# Fleet metric repair — qualification in progress
## Confirmed cause
The federation.get-state handler passed literal zero values for CPU, RAM, disk
and uptime into build_local_state. Peers therefore received a valid signed RPC
response containing fabricated measurements. Fleet also turned absent fields
into zeroes and treated a newly added peer's registration time as a report.
Read-only live inspection on the dev node found fifteen federation reports with
zero resource values, alongside two nonzero collector reports. Yaya has no
Trusted fleet reports; peer (Observer) access is deliberately distinct.
## Candidate change
- Use the existing minute MetricsStore sample, avoiding expensive per-peer probes.
- Samples older than three minutes or ahead of the local clock are unavailable.
- Read uptime from the host uptime source; errors remain unavailable.
- Preserve optional measurements through federation and the Fleet response.
- Display unavailable measurements separately from valid zeroes; average only
valid measurements from reporting online nodes.
- Do not infer contact from when a peer was added. Invalid/future report dates
show unknown status; offline cards state when the last report arrived.
- Keep existing trust restrictions and signed FIPS-preferred federation transport.
This change does not claim FIPS media-stream acceptance or fix stalled peering.
## Qualification
All 1,684 backend tests pass (four ignored), including actual-handler fresh,
absent, stale and future sample coverage. All 11 Fleet helper/component tests
pass, including real-zero versus missing values, malformed/future dates,
ordering, averages and rendered unavailable/offline states. Frontend typecheck
passes. The first component assertion incorrectly expected spaces between
separate elements; it was corrected to inspect those elements. No deployment
or live metric repair acceptance yet.
Required: actual-handler fresh/absent/stale/future samples; full relevant suites;
mobile/desktop browser layout; upgraded sender and receiver comparing local
Monitoring to received Fleet values; restart/reconnect, offline ageing and real
transport evidence. Legacy senders still advertising zeros need the sender fix;
the receiver cannot reliably distinguish a legacy fabricated zero from idle CPU.
## Dev deployment and collector follow-up
Dev qualification deployment uses backend041f1fa2 (SHA256
11b62f697a71b762bf8638063d1a858a68eea6d7268e300f6320c99068efa78a)
and frontend3d0c67eb. Health and unchanged app-container identities/start times
pass. Live federation CPU/memory/disk values exactly match local Monitoring;
Web5 mobile390px/desktop1440px checks pass. Rollback retained on the node at
/var/lib/archipelago/support/followup-20261005-2120. Yaya remains on the prior
backend; no receiver/fleet-wide acceptance is claimed.
Live testing caught an unbounded podman stats subprocess delaying the first
snapshot, and a300-second collection interval conflicting with180-second Fleet
freshness. The next candidate starts after5seconds and collects once per minute,
with3-second df and8-second podman deadlines and kill-on-drop cleanup. Failed
system reads no longer become invented zero samples. Container-stat failure
leaves container readings unavailable while retaining valid system readings.
The actual subprocess timeout/reaping regression passes; all1,686 backend tests
pass (four ignored). This collector correction is not deployed yet.
Framework SSH and backend health work, but its stored dashboard session returns
401. Authenticated Framework Monitoring acceptance remains open. No authentication
boundary was bypassed to produce an apparent pass.
@@ -0,0 +1,73 @@
# IndeeHub distribution: current implementation design
Status: design for the post-1.9 follow-up, not implemented/accepted. Earlier
swarm plans describe historical experiments and must not be read as live proof.
## Standards checked on 2026-10-05
- Nostr [NIP-71](https://github.com/nostr-protocol/nips/blob/master/71.md)
defines video metadata, including addressable normal-video kind34235. Use a
stable producer/project identifier for revisions. This does not define paid
viewing rights. Hash/media metadata follows
[NIP-94](https://github.com/nostr-protocol/nips/blob/master/94.md).
- [NIP-98](https://github.com/nostr-protocol/nips/blob/master/98.md) authenticates
HTTP requests; it is not proof of payment or permission to another creator's
project. Keep the existing verified app session and project ownership checks.
- [Cashu NUT-18](https://github.com/cashubtc/nuts/blob/main/18.md) supplies payment
request negotiation. [NUT-04](https://github.com/cashubtc/nuts/blob/main/04.md)
covers mint quotes/issuance; method-specific current specifications and older
deployed mint responses must both be capability-tested. Keep quote identifiers
private to the receiving wallet. Payment settlement must be correlated to the
purchase, never inferred from a change in wallet balance.
- [NUT-19](https://github.com/cashubtc/nuts/blob/main/19.md) provides mint-side
cached responses where supported. It supplements a durable local payment
journal; it does not replace one or make an arbitrary retry safe.
- [LNURL-pay](https://github.com/lnurl/luds/blob/luds/06.md) supports an invoice
handoff. A Lightning address by itself is not a signed settlement receipt.
## Required implementation contract
1. Backstage publishes only the selected, owned project. Announcements contain
public metadata, producer identity, node identity, content hashes, current
price/window and accepted-method capabilities. Never publish Cloud paths,
mint quotes, tokens, paid media keys or private management addresses.
2. Each instance's Archipelago source verifies signatures, identity bindings and
monotonic event revisions. Persist discovery so a relay outage does not empty
an existing library. Keep other sources and the current default intact.
3. A purchase binds buyer identity, publisher, project revision, amount, currency,
selected payment method and an unpredictable idempotency identifier. Persist
the quote before requesting payment. Snapshot the offer so later edits cannot
silently change the purchased terms.
4. Reuse file-payment capability negotiation and proven settlement primitives.
Existing file Lightning invoices currently require LND; therefore adding
first-use Lightning-to-Cashu receiving is real work, not a display label. The
receiver must verify a correlated invoice/mint receipt and recover issuance
after a lost response before granting access. Its provisioned ecash address
must map to the actual receiving wallet. No new real payment is authorized by
this design; use isolated fixtures until a bounded payment is approved.
5. A paid purchase creates one durable entitlement. Default demo window proposal:
start at the first successfully authorized media response; persist start and
expiry atomically. Retries, seek and reconnect reuse it without another
payment. Check the entitlement for every media/range/key request. Clock
rollback must not extend an already-started window.
6. Browser/companion playback remains ordinary authenticated local HTTP. Actual
inter-node media bytes use FIPS, with a bound node identity and authenticated
purchase capability. No silent Tor/LAN/iroh fallback for required FIPS media.
Show a recoverable unavailable route without requesting another payment.
7. Range/segment serving streams bounded buffers with backpressure and cancel
propagation. Do not read an entire paid film into a Vec before serving it.
Verify length/hash/revision, reject malformed ranges and path escapes, and
keep cache access subject to the same entitlement. Delivered plaintext cannot
be made impossible to copy; expiry controls subsequent authorized delivery.
## Qualification that remains required
Publisher/receiver integration must cover altered metadata, forged identities,
wrong mint, rejected/late/duplicate payment, missing transaction response, restart,
clock change, expired window, revocation, missing FIPS route, seek and disconnect.
Measure real media-byte transport and memory use. Test the actual Backstage,
Archipelago listing, purchase and player on mobile/desktop and companion.
Use only the operator-designated Yaya Cloud video, preserve the source, and
publish the IndeeHub app image/catalog update at the end of qualification.
One working fixture is not acceptance of the complete distributed flow.
+82
View File
@@ -0,0 +1,82 @@
# IndeeHub distributed viewing: protocol review
Status: preliminary design, 2026-10-05. Not implemented or qualified. Reconcile
with actual IndeeHub source before selecting the final event/API contract.
## Updated constraints
The older `phase4-streaming-ecash-plan.md` mixes producer content sales with
bandwidth resale and an optional iroh swarm. Its implementation assertions are
historical. The operator now requires FIPS for inter-node media bytes, producer
payments, timed viewing, and an Archipelago catalog across instances. A successful
bandwidth payment alone must not unlock a producer's protected film.
The old document also describes a fail-open paid-serving path. Audit the current
implementation; never adopt fail-open behavior for paid media or key delivery.
Keep free software updates outside any paid-content gate.
## Primary specifications checked
- [NIP-71 video events](https://github.com/nostr-protocol/nips/blob/master/71.md):
defines ordinary and addressable video metadata, including variants. Evaluate
addressable normal-video events for stable film identity and metadata updates.
This is a draft optional specification, not a complete rental/access protocol.
- [NIP-94 file metadata](https://github.com/nostr-protocol/nips/blob/master/94.md):
describes file hashes, MIME types, sizes and locations. Reuse compatible fields
rather than inventing incompatible meanings for standard tags.
- [Blossom BUD-01](https://github.com/hzrd149/blossom/blob/master/buds/01.md):
specifies SHA256-addressed HTTP blob retrieval. Its public cross-origin server
conventions must not be copied onto dashboard/RPC authentication boundaries.
Hash addressing can complement a FIPS-backed gateway; Blossom alone does not
establish payment or timed viewing rights.
- [Cashu NUT-18](https://github.com/cashubtc/nuts/blob/main/18.md): receiver requests
can describe amount, unit, accepted mints and token delivery. Reconcile supported
mint preferences/methods with our deployed wallets, not just the latest schema.
- [NUT-04](https://github.com/cashubtc/nuts/blob/main/04.md) and
[NUT-23](https://github.com/cashubtc/nuts/blob/main/23.md): verify current mint
quote/payment accounting and BOLT11 behavior against supported mints. Keep quote
identifiers private. Successful invoice payment and successful token issuance
are distinct recovery steps; never repeat payment to recover an issuance reply.
These are source/specification findings. Compatibility with existing clients and
mints remains to be tested. Pin specification revisions when implementing so a
moving document cannot silently change the wire contract.
## Proposed separation of responsibilities
1. **Discovery:** publisher-authorized signed metadata; stable film/version ID,
public title/artwork/teaser and explicit supported paid-content extension.
Deduplicate, reconcile updates/deletions and recover missed events. Do not put
private viewing keys, receipts, quotes or wallet credentials on public relays.
2. **Producer offer and settlement:** reuse recipient-capability negotiation from
file purchases. Bind amount, recipient, content version and duration to one
durable purchase ID. Verify settlement at the seller before issuing access.
Support the existing Lightning-to-ecash-address flow without requiring LND.
3. **Viewing entitlement:** a versioned authenticated grant with content, buyer,
validity and replay rules. This is application-specific until interoperability
is demonstrated; do not present it as defined by the metadata/payment NIPs.
4. **Playback gateway:** browser/companion use normal authenticated media requests
to their node. The node obtains protected segments over FIPS and verifies
content integrity and entitlement. Seek/retry/resume reuse the purchase.
5. **Caching:** peers may cache authorized ciphertext. Key delivery and subsequent
segment access remain gated. Already delivered plaintext or keys cannot be
made uncopyable or retroactively revoked; do not promise DRM guarantees.
No silent media fallback to Tor/LAN/iroh satisfies the operator's FIPS requirement.
If FIPS is unavailable, retain paid ownership and explain retry/recovery rather
than charge again. Separate routing diagnostics from normal playback controls.
## Decisions and proofs required before publishing the test film
Identify the exact Yaya Cloud video, preserve its original and obtain the intended
price and viewing-window semantics. Define activation versus expiry, clock skew,
multiple devices, publisher outage, refund policy and content-version replacement.
Use isolated/regtest funds for automated tests; new real payments require a bounded
amount authorization. Publish no unrelated Cloud file.
Qualification must cover settlement with lost replies, duplicate payment callbacks,
wrong mint/recipient/content, denied keys, expired grants, FIPS outage and recovery,
range/HLS seek, mobile background/resume, source/peer restart and storage recovery.
Verify actual transport and producer balance changes rather than relying on UI
labels. Include fresh/upgrade tests and any required IndeeHub image/catalog update
at the end of the implementation.
+64
View File
@@ -0,0 +1,64 @@
# IndeeHub native signer follow-up
## Reproduced on Yaya
The installed app and dashboard have the same provider SHA256
`529fe82e7c16b51c62678427f565048c3dd93ca28320bd8494c17236ff57bb81`.
A clean mobile Chromium session opens the identity picker. After selecting the
existing profile and Authenticate, the picker disappears but the broker stays
full-screen (`aria-hidden=false`, 390 by 844). Its document has no visible text
or buttons, and the app still shows Sign In. The trace contains signer-ready and
signer-show but no signer-identity or signer-hide through 18 seconds.
The picker emits an entry from a Vue reactive array. NostrTabSigner passes that
proxy object directly to cross-frame postMessage after hiding the picker.
Structured cloning rejects reactive proxies, interrupting the handoff before
it schedules the broker hide. Reload uses the already-serialized identity from
localStorage, explaining why refresh can appear to repair the problem.
## Candidate fix
Send an explicit plain object containing only the selected public identity
fields. The private signer remains on the node; unrelated metadata is excluded.
Consent behavior and the existing green completion animation are unchanged.
A regression uses a real Vue reactive identity and structuredClone, verifies
that the proxy itself is rejected, the public handoff is cloneable, metadata is
excluded, and the overlay closes. Eleven focused signer/provider tests pass,
and frontend typecheck passes. A browser qualification using candidate dashboard
assets with the actual Yaya app/auth backend is in progress. No deployment or
actual companion acceptance is claimed yet.
## App source and further review
The canonical app is the Vite/Vue source in the separate IndeeHub repository,
not the obsolete Next.js Dockerfile under apps/indeedhub. Its existing local
nginx edit and untracked workflow documentation were preserved; new app work
uses a separate worktree.
Review found additional app-side concerns to test: production network failures
can flip the app into mock mode and fabricate subscribed users, and the header
can discard a valid backend Nostr session when the local signer account has not
been restored. Do not claim these repaired by the broker object-cloning fix.
## Live candidate qualification and restored-session prompting
2026-10-05: actual Yaya NIP-98 session exchange returns201 and authenticated
profile returns200 using candidate dashboard and app assets. The overlay hides;
a full refresh reuses the session and profile without another auth exchange.
Evidence: /tmp/archy-indeehub-full-candidate-2.log. This uses headless Chromium
390x844, real cookies/signatures/RPC/API, with only static candidate assets routed
locally. Initial asset-routing attempts hit Chromium private-network checks;
forwarding real API requests in the fixture resolved that test harness failure.
No backend authentication was mocked or bypassed.
Public-key lookups can inherit transient activation from the identity-picker
click/reload. The provider now avoids interpreting a restored-session hint or
already selected identity as a new account-switch request. Requests still pass
to the authenticated broker; the hint grants no signature permission. Explicit
selectIdentity remains available. Twelve provider/tab-signer regressions pass.
The combined frontend production check found strict TypeScript nullability
errors in Fleet test array indexing; the fixture now asserts both cards exist
and uses non-null indexing. No production Fleet behavior changed in that repair.
Actual deployment, companion lifecycle and the remaining recovery cases stay open.
+85
View File
@@ -0,0 +1,85 @@
# Node connection flow plan
Status: proposal for the post-1.9.0 work. Uses existing components, colors,
spacing, glass cards, typography and motion. No broad navigation redesign has
been deployed. Connection reliability must be qualified before this flow ships.
## Entry and return paths
- Web5 always exposes **Connect with Nodes**, including when mobile quick actions
are collapsed. Keep **Connected Nodes** beside the entry or directly below it.
- Cloud peer files links to the same connection flow and retains its return
location. Successful connection returns to that peer's files when appropriate.
- Fleet provides the same connection entry, with an explicit distinction between
connecting to another person's node and linking a node the operator owns.
- Open the route immediately with cached safe summaries or a loading state;
discovery and transport checks run after navigation. Do not await remote calls
before rendering the destination. Cancel obsolete work on navigation away.
## Connect with Nodes
Use one page with existing tabs: **Discover**, **Requests**, **Connected**.
On mobile keep tabs in one horizontally scrollable row. Preserve the selected
view, search and scroll position when opening a node and returning.
Discover shows the existing opt-in Nostr presence results and an explicit invite
entry. Search updates locally; refresh provides immediate progress, timeout and
retry feedback. Distinguish stale advertisements from recently contacted nodes.
A presence event is discovery information, not authorization or proof of reachability.
Each node has a single clear action: Request connection, View request, or Open
node according to its actual state. Explain what information the request shares.
Avoid duplicate requests on repeated taps or when responses arrive late.
## Requests and approval
Display incoming and sent Nostr requests in the same Requests view, with counts
and a readable node identity/name. Incoming requests offer Approve or Reject;
sent requests offer Cancel. Keep completed history available but secondary.
An approval progresses through distinct states:
1. Request sent / Awaiting approval.
2. Approved / Connecting — authenticated invitation accepted, join not confirmed.
3. Connected — persisted relationship and authenticated reciprocal confirmation.
4. Connection delayed — show bounded retry and a useful error; retain the approved
operation so restart, lost acknowledgement or transient outage can recover.
Do not label relay acceptance as peer connection. A retry must reuse the same
logical operation, prevent duplicate peers and retain the operator's trust choice.
Cancellation/rejection delivery failures must be visible rather than reported as
successfully notified. Define recovery for already-approved legacy requests.
Normal discovery connections grant Observer access. **Link your own nodes** must
be a separate explicit flow with existing ownership/authentication requirements;
being reachable over FIPS never grants Trusted access or remote management rights.
## Connected nodes and Fleet
Show actual connection state and last successful authenticated contact. Distinguish
**Offline**, **Connecting**, **Unknown** and **Metrics unavailable**. Last report
age alone does not establish when a node went offline. Future/skewed timestamps
must not make a node permanently online.
Default ordering: online, connecting, unknown, confirmed offline; stable ordering
within groups. Honor manually selected sorting/filtering and do not disrupt the
user's selection while metrics update. Offline rows show last contact; show an
"offline for" duration only when an observed transition supports it.
The existing network map uses matching status labels and accessible details;
color alone is insufficient. Node detail keeps Connect/Retry, Files and permitted
management actions together. Do not add duplicate connection mechanisms.
## Acceptance before deployment
- Two real nodes: request, approval, reciprocal connection and persisted lists.
- Retry after lost reply, duplicate/reordered events, restart on each side,
unavailable relay, FIPS outage and supported transport recovery.
- Invalid signatures, unsolicited invites, wrong identities, stale/cancelled
requests and blocked peers cannot gain access or elevate trust.
- Desktop and actual companion: first connection, revisit, back navigation,
search, tab switching, refresh, background/resume and interrupted network.
- Measure tap-to-feedback, first usable content, discovery completion and
approval-to-confirmed-connection before and after. Preserve unknown data.
- Operator UAT gives exact nodes, steps and expected states; no extra payment or
wallet/channel changes are needed for connection testing.
+64
View File
@@ -0,0 +1,64 @@
# Peer requests, delivery, and availability follow-up
Status: implementation under qualification. Not a claim of reciprocal live-node
acceptance or completion of the post-1.9 backlog.
## Confirmed failures
Yaya retained the dev node's approved inbound request while the dev node retained
its outbound Sent request, without reciprocal federation membership. Approval
previously had no durable delivery/retry record. Configured managed relays were
also omitted from reply publication; that separate repair is in 9a041bed.
The Connected Nodes card cached untimestamped reachability booleans, with cached
results overriding the shared store. A failing RPC was rendered as an offline
route. Nostr requests were absent from its Requests tab and badge.
## Changes
- Persist the approval decision and a node-key-encrypted reply before delivery.
Retry the same invite with bounded exponential backoff, at most four eligible
replies per background pass. Relay acknowledgement alone does not remove it;
reciprocal membership does. Removed peers and expired requests are excluded.
- Recover legacy Approved rows through the same supported delivery path. Do not
edit peer files by hand or elevate Observer relationships to Trusted.
- Serialize pending-store mutations and replace its private file atomically.
Malformed storage is preserved and fails explicitly. Conflicting decisions
cannot both win. Approved requests expire after 30 days to permit reconnect.
- Validate the invite's DID and key against the requested identity, normalize
discovery trust to Observer before acceptance and callback.
- Poll in the background every 30 seconds, skipping missed ticks.
- Show Nostr requests in Connected Nodes with a direct link to review them.
Preserve pending rows on failed refresh, and surface partial failures.
- Render independently arriving node lists, limit reachability probes to four,
ignore superseded replies and age timestamped reachability after 90 seconds.
An RPC failure is unknown; an explicit failed reachability check is unreachable.
Report last successful contact without inventing continuous offline duration.
- Place online nodes first, then unknown and unreachable, preserving order within
each group. Fleet describes stale reports as Not reporting. Map labels include
last contact and dashed links indicate no recent contact, not a live route.
## Evidence so far
- Original full backend candidate: 1,693 passed, 4 ignored, no failures, through
the isolated runner (`/tmp/archy-peering-full-backend.log`).
- Additional review added recovery-through-real-relay and retry-backoff checks;
all 50 focused federation tests pass, including actual encrypted relay delivery
for legacy Approved rows and suppression of duplicate attempts during backoff.
Final formatted source also passes all 1,693 backend tests (4 ignored).
- Connected Nodes: 9 focused tests pass, including independent rendering,
mixed failed/negative/successful probes, Nostr requests, cache age and clock skew.
- Fleet/request display: 13 focused tests pass.
- Type checking and production UI build pass. Final frontend suite: 1,238 tests
in 153 files pass (`/tmp/archy-peering-full-ui-final.log`).
- Yaya Chromium at 390 and 1440px passes candidate-asset browser checks with
deterministic peer RPC fixtures: availability text/order, approved Nostr requests,
connection navigation and no page errors (`/tmp/archy-peering-browser-candidate-7.log`).
Fixture checks are not evidence of actual reciprocal membership.
- Clean backend artifact at 10d31ae1: SHA256
`120bd0f51fbceafeceb5557117a442fffc432a7b4d5115da1a163e472f7160da`.
Actual-node deployment and reciprocal membership checks remain required.
The prior reply-rejection test expected a Pending row. This revision deliberately
supersedes that behavior: the decision remains Approved with delivery pending,
so a relay outage does not undo an operator decision or require reapproval.
@@ -0,0 +1,123 @@
# Post-1.9.0 reliability investigation
Status: implementation and qualification in progress. These changes are on
`work/post-190-reliability`, separate from the published 1.9.0-alpha artifacts.
Nothing here constitutes live acceptance or permission to change peer trust.
## Peering: approved request does not establish a relationship
Read-only inspection on 2026-10-05 reproduced the operator's report: the receiving
node retains an approved inbound request while the requesting node retains its
outbound request in Sent state; neither has the reciprocal federation entry.
Both have discoverability enabled. FIPS is running on both (different service
names); checking only `fips.service` would incorrectly report one as inactive.
Source discrepancy: request publication and polling use `handshake_relays()`,
which combines managed relays and configured defaults. Approval, rejection and
cancellation instead use only configuration defaults. Align all three reply
paths with the shared resolver. Add an actual-handler integration test with a
UI-configured local WebSocket relay, signed event verification, recipient-only
NIP-44 decryption, reply types, persisted request states and Observer-only approval.
The isolated test passes: all three reply types reach the managed-only relay,
and a rejected approval remains Pending with no peer added. The complete backend
suite is running; actual-node handshake recovery remains outstanding.
This discrepancy is not yet a proven complete explanation of the live failure.
Read-only relay queries are being checked. Other source risks requiring separate
qualification include best-effort peer-joined callbacks without durable retry,
five-minute background polling, latest-50-event fetching without a cursor, and
pending-file read/modify/write operations without serialization. Do not manually
mark requests completed or elevate trust to make the UI appear connected.
## Web5 navigation cleanup
The Wallet quick-action only toggles a local disconnected flag and refreshes LND
information. Remove it and its independent LND polling; wallet interfaces remain
elsewhere. Rename Find Nodes to Connect with Nodes, including English/Spanish
translations and existing navigation assertions. Four focused component tests
pass. Full frontend tests, type checking and mobile/desktop rendering checks are
still required; no deployment or operator acceptance is claimed.
## Fleet findings to investigate
`normalizeFleetNode` substitutes zero for absent metrics, and timestamp age alone
is interpreted as online/offline. Missing values must not be presented as real
zero measurements, and stale reporting must not be treated as a measured offline
transition. Trace telemetry collection and transport before changing presentation.
## V4V source and demo catalog located
The existing Gitea repository is `v4v/v4v`, branch `demo-portainer`, at
`3ae171d6b0c728665a860520fe393c0abb772798`. The earlier `lfg2025/v4v`
location does not resolve on that server. Read-only inspection of the actual
Portainer documentation confirms a sanitized demo catalog with 52 entries and
47 playable tracks: 21 bundled demo WAVs and 26 publisher-hosted entries. These
counts describe the documented seed, not a fresh playback acceptance result.
Its importer is designed to back up existing state, merge by ID and retain
accounts, payment records and edits. Qualify those behaviors before deployment.
The source explicitly keeps private catalog/media archives out of public source
publication. Preserve that boundary when packaging the Yaya-only demo: hiding a
card is not sufficient protection for private media or credentials. Inspect the
existing node's state and exact deployed revision before modifying its stack.
## Qualification results so far
Frontend type checking passes. Full suite: 1,221 passed, one unchanged paid-file
case hit its 20-second test timeout under concurrent build/upload load. That
file's six tests all passed when rerun alone. Retain the original failure; do not
rewrite it as an entirely green full-suite run. Four targeted navigation tests
passed separately. Mobile/desktop browser acceptance remains outstanding.
The first new Rust test compile exposed two fixture-only String/&str mismatches.
Corrected them and added rejected-relay coverage: failed delivery must leave the
request Pending and must not add a peer. Isolated compilation/execution now passes (one integration test covers four
scenarios). No live peering repair or deployment is claimed.
Public relay queries found no matching reply on the managed relays that completed
the query; some endpoints were unavailable. The default Damus relay requires
authentication for this filter, so its unauthenticated rejection is not evidence
of a missing event. The installed SDK already enables automatic authentication.
Do not infer that the node has the same rejection without authenticated evidence.
### Completed source-test runs
The second full frontend run, limited to two workers, passes all1,222 tests across
150 files. Type checking passes. The first full backend run exposed a real
pre-existing bug: encrypted chat/contact nonces starting with `{` or `[` were
misclassified as legacy JSON. This is not dismissed as a flaky test.
Replace prefix-only classification with full JSON object/array validation using
`IgnoredAny` to avoid building another object tree. Deterministic valid encrypted
fixtures cover both prefixes; existing pre-migration ciphertext compatibility
and tamper/wrong-key tests remain. Full isolated backend rerun passes1,683 tests,
zero failures, four existing ignored. Logs are retained in
`/tmp/archy-followup-backend-suite-2.log` and
`/tmp/archy-followup-ui-suite-2.log`.
Published1.9.0 artifacts remain unchanged, and their release page discloses this
newly discovered issue. Private snapshots were attempted on all four authorized
nodes before further restarts: only Shorty had an affected message store at the
expected paths; its bytes were verified after backup. No message contents or
wallet data were exported. Actual candidate build/deployment and store reload
acceptance still remain; do not equate source-test success with delivery.
## Production storage candidate qualification
The cfd9a596 production binary (SHA256
3d720c6ddb2622ddef956b5ef0d54ecef64617e4bd16d07327b55ac737d00fe7)
was exercised in the disposable installed-system VM. Independent Python
ChaCha20-Poly1305 fixtures used the guest's key locally, without exporting it.
Encrypted nonces starting with `{` and `[` loaded through the real message RPC,
retained their exact ciphertext, and survived a second service restart. Legacy
JSON with leading whitespace migrated to authenticated ciphertext and survived
another restart with all message fields intact.
Fixture corrections were required: the first root-owned 0600 file was unreadable
by the service; the next legacy assertion omitted optional fields that serde
normally emits as null. Both initial failures remain in the qualification logs.
The corrected run passed all three data cases. SSH disconnected during final
cleanup, so restoration was completed as a guest systemd job and independently
checked: original 560aa600 backend, active service, and original absent message
store restored. The VM was then shut down. This is not live-fleet deployment or
proof of every corrupt-store recovery path.
+12 -3
View File
@@ -1,8 +1,17 @@
# Work requested after 1.9.0-alpha
Status: queued by the operator on 2026-10-05. Complete the current release first;
these requests do not silently expand its artifact scope. No implementation or
acceptance is claimed by this backlog.
Status: implementation and qualification in progress. 1.9.0-alpha was published
separately; these follow-ups are not in its immutable artifacts. The list below
remains the complete acceptance scope, not a claim that every item is finished.
Current evidence is recorded in [Fleet metrics](fleet-metrics-followup.md),
[peering reliability](peering-reliability-followup.md), and the
[IndeeHub design review](indeehub-distribution-current-design.md). Monitoring and
the tested signer/dashboard candidate are deployed to dev and Yaya with rollback
backups; actual IndeeHub image publication is deferred until the end as requested.
Framework's authenticated Monitoring check awaits an operator dashboard login.
Streaming, storage-source integrations, AIUI setup, V4V packaging/player,
companion hardware checks and the full Fleet acceptance matrix remain open.
## 1. Distributed IndeeHub publishing and paid viewing