Plan scoped Mesh file selection and durable paid delivery
This commit is contained in:
@@ -0,0 +1,106 @@
|
|||||||
|
# Mesh node/computer sharing: implementation plan
|
||||||
|
|
||||||
|
Status: source-grounded preparation for backlog task22, after task21. No new
|
||||||
|
sharing behaviour is enabled. Existing IndeeHub/payment/media work remains first.
|
||||||
|
|
||||||
|
## Existing implementation and gaps
|
||||||
|
|
||||||
|
`neode-ui/src/views/Mesh.vue` currently accepts one browser File. It reads the
|
||||||
|
whole file for inline transfer or uploads it to `/api/blob`, then sends a
|
||||||
|
`mesh.send-content` reference. Transport advice distinguishes inline/Reticulum
|
||||||
|
resource, choice, Tor-only and impossible states. Preserve this advice for small
|
||||||
|
free attachments; do not assume radio messaging is a bulk-file transport.
|
||||||
|
|
||||||
|
`stores/mesh.ts` and `api/rpc/mesh/typed_messages.rs` implement ContentRef messages
|
||||||
|
with CID, metadata, sender onion and expiring recipient-scoped capability. The
|
||||||
|
recipient fetch path supports a locally cached blob. This payload is an immediate
|
||||||
|
blob capability, not a durable paid-content offer: never put paid bytes through
|
||||||
|
it before entitlement validation.
|
||||||
|
|
||||||
|
The current view resolves federation onion addresses by fuzzy display-name
|
||||||
|
matching. That cannot establish the recipient identity for the new paid/private
|
||||||
|
flow. Use a verified mesh-key-to-node-DID binding and authenticated transport
|
||||||
|
route; missing binding must be an explicit connection-required state, never a
|
||||||
|
best-guess match or silently created peer relationship.
|
||||||
|
|
||||||
|
`api/filebrowser-client.ts` provides authenticated directory listing and resumable
|
||||||
|
upload. It has no whole-library search operation. A recursive walk in the browser
|
||||||
|
would be slow, incomplete on partial failures, and unbounded for large libraries.
|
||||||
|
A scoped backend search/index or verified provider-native search is required.
|
||||||
|
Task5's external source connectors are not yet implemented: do not imply their
|
||||||
|
files are included in the first picker.
|
||||||
|
|
||||||
|
## Proposed user flow
|
||||||
|
|
||||||
|
1. Share file opens From node / From computer. Retain the intended recipient and
|
||||||
|
caption while choosing, returning or cancelling.
|
||||||
|
2. From node uses a reusable owned-library picker: lazy folder tree, breadcrumbs,
|
||||||
|
global-search results with full paths, loading/error/empty states. Search is
|
||||||
|
scoped to the signed-in user's accessible library, not the current folder.
|
||||||
|
3. Keep a selection map by immutable source identity and file revision, independent
|
||||||
|
of the displayed folder/query. Bottom selection tray shows count, removable
|
||||||
|
entries, and Send. Deleted/inaccessible/stale revisions require review, not a
|
||||||
|
silent substitution. Folders navigate; recursive directory sending is not
|
||||||
|
implied by this file-only task.
|
||||||
|
4. From computer supports multiple files and resumable private staging on the
|
||||||
|
sender node, with bounded streaming, per-file progress and stable upload IDs.
|
||||||
|
Reopening/retrying reuses staged bytes; cancelled staging has a defined expiry.
|
||||||
|
5. Reuse the usual pricing component for each paid offer (or explicit selected
|
||||||
|
group operation), retaining each file's existing policy. Sending does not
|
||||||
|
publish globally or alter unrelated recipients' access.
|
||||||
|
6. Show per-file free/paid price and delivery state in the outgoing batch. A
|
||||||
|
successful send means message accepted/queued, not recipient download complete.
|
||||||
|
Partial success keeps failed selections and retries only their message IDs.
|
||||||
|
|
||||||
|
## Transport and payment decisions
|
||||||
|
|
||||||
|
Use an authenticated, versioned attachment-offer message containing a stable
|
||||||
|
message/item ID, seller DID, content ID/revision, safe display metadata and an
|
||||||
|
optional price/method summary. Treat price text as advisory: opening revalidates
|
||||||
|
the authenticated current offer. Never include file paths, local credentials,
|
||||||
|
prepayment media capabilities or a transferable paid unlock in the message.
|
||||||
|
|
||||||
|
Bulk bytes use the existing authenticated content transport and durable purchase
|
||||||
|
journal. Prefer the required FIPS path where supported; do not silently downgrade
|
||||||
|
a required transport to unauthenticated HTTP or the older blob endpoint. A node
|
||||||
|
with only radio connectivity may receive the offer but cannot be promised bulk
|
||||||
|
retrieval. Preserve existing explicitly selected small free inline attachments.
|
||||||
|
|
||||||
|
Paid open routes into the normal purchase interface. It must reuse seller/content/
|
||||||
|
revision/purchase identity and settlement records, including cross-rail admission,
|
||||||
|
lost-response recovery and cached delivery. Sending/selecting/previews never pay.
|
||||||
|
Reopening an existing entitlement never creates another payment. Fresh Fedimint
|
||||||
|
file purchase is currently disabled by the payment-safety patch and must not be
|
||||||
|
reintroduced through Mesh.
|
||||||
|
|
||||||
|
Message outbox retry/deduplication is separate from file-transfer retry and payment
|
||||||
|
recovery. Sender offline means pending/unavailable download, recipient offline
|
||||||
|
means durable queued delivery where supported, expired private access offers a
|
||||||
|
new authorization request without a new charge for an existing entitlement.
|
||||||
|
Withdrawn/deleted sources display an explicit state; previously delivered bytes
|
||||||
|
cannot be retroactively revoked. Mixed free/paid batches retain per-file outcomes.
|
||||||
|
|
||||||
|
## Implementation order and acceptance
|
||||||
|
|
||||||
|
- Define verified identity binding, offer schema/version handling and owned-library
|
||||||
|
search/revision semantics before wiring Send. Older recipients get a truthful
|
||||||
|
unsupported-offer state, never an insecure legacy fallback.
|
||||||
|
- Build source-choice and reusable picker with keyboard focus return, labelled
|
||||||
|
tree navigation, cancellable search and retained selection on narrow screens.
|
||||||
|
- Add private resumable staging and durable batch/outbox IDs, then recipient offer
|
||||||
|
rendering and normal purchase/download entry. Keep selection and payment state
|
||||||
|
separate; avoid one whole-batch payment without supported atomic semantics.
|
||||||
|
- Qualify two owned nodes: free and mixed paid offers, duplicate names/paths,
|
||||||
|
forbidden paths/symlinks, global search beyond current folder, pagination,
|
||||||
|
partial errors, changed source revisions, cancelled/retried uploads, duplicate
|
||||||
|
messages, wrong recipient, forged identity/price, sender/recipient restart,
|
||||||
|
expired access, source withdrawal and interrupted cached download.
|
||||||
|
- Verify no payment on selection/send/preview, no paid plaintext capability before
|
||||||
|
settlement, no repayment after lost replies, no global visibility change, and
|
||||||
|
explicit incomplete indexing. Run meaningful handler/UI tests and responsive
|
||||||
|
browser checks; real spending requires the existing bounded authorization.
|
||||||
|
|
||||||
|
Open decisions: authenticated identity binding UX for radio-only contacts;
|
||||||
|
provider-backed global search/index ownership; durable staging retention/quota;
|
||||||
|
attachment-offer protocol version negotiation. These block claiming a finished
|
||||||
|
implementation, not preparation of the picker design.
|
||||||
@@ -654,6 +654,8 @@ previously deferred work. Status: queued; no public visibility has been changed.
|
|||||||
|
|
||||||
Added by the operator after task21 on 2026-10-07. Append after public sharing;
|
Added by the operator after task21 on 2026-10-07. Append after public sharing;
|
||||||
status: queued. Plan the node-to-node sharing design before implementation.
|
status: queued. Plan the node-to-node sharing design before implementation.
|
||||||
|
Preparation: [source-grounded sharing plan](mesh-node-file-sharing-plan-20261007.md);
|
||||||
|
no implementation or public visibility change is enabled.
|
||||||
|
|
||||||
- Clicking **Share file** in Mesh opens a source-choice modal with **From node**
|
- Clicking **Share file** in Mesh opens a source-choice modal with **From node**
|
||||||
and **From computer**. From computer opens the local device file picker;
|
and **From computer**. From computer opens the local device file picker;
|
||||||
|
|||||||
Reference in New Issue
Block a user