docs: plan node flows and record follow-up qualification

This commit is contained in:
archipelago
2026-10-05 19:53:05 -04:00
parent eaecab16ca
commit cfd9a596c0
3 changed files with 270 additions and 0 deletions
+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.
+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.
@@ -0,0 +1,103 @@
# 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.