Files
archy/docs/security/2.1-peer-request-storage.md

3.5 KiB

Peer request storage and retry policy

Signed connection requests change trust only after owner approval or a matching live outbound correlation. All incoming request list/accept/reject operations and outbound acceptance use one mutation lock. Acceptance rereads and validates the record under that lock, then claims it before changing the peer inventory. Accepted, expired and archived records are never searched as authorizations.

Retries of an identical outbound request reuse its ID while it remains live. Incoming redelivery is acknowledged only when the authenticated sender, ID and hash of the complete canonical JSON payload match the original. This neither rewrites the stored bytes nor extends the seven-day lifetime. Changed fields, including extension fields, fail. Legacy records without a payload hash cannot establish exact-redelivery equivalence. A failed best-effort acceptance notification may still require owner approval of the sender's retried request; there is no automatic trust based on a prior archived request.

Requests are capped at 128 active records per direction and 16 KiB per record. On list/creation/owner acceptance, expired records leave the active quota:

  • connection_request_archive/<direction>/expired/ retains at most 256 validated expired records (4 MiB) per direction, oldest first. Records are also removed after 30 days past their seven-day active lifetime. Compaction runs during request processing, not a background timer.
  • connection_request_archive/<direction>/evidence/ preserves interrupted .accepted claims, staging files, malformed records and invalid future dates. Its limit is 128 records (2 MiB) per direction. Evidence is never automatically deleted. At the limit, mutation fails with an operator-maintenance error and leaves the original input untouched. Oversized files, non-files and damaged archives also fail without deleting the original.

An operator reaching this maintenance condition must inspect the evidence and move any retained forensic copies to separately managed storage before resuming. Never restore archived/claimed records to an active directory. The two active queues and archives together normally remain within 16 MiB, excluding temporary publication files and any pre-existing damaged or oversized operator data.

peers.json mutations share a separate lock and use a private temporary file, file sync, atomic rename and directory sync. Malformed or non-file inventories are refused and preserved. If a peer write fails after a request has been claimed, the claim stays closed: a failure after rename can be ambiguous, so retrying must use a fresh owner request rather than reopening an authorization.

Source regressions cover exact retry and changed-payload rejection, active and archive limits, retained evidence, expired/rejected/consumed owner requests, malformed peer storage, concurrent peer additions/removals and complete old bytes for readers during replacement. They must run through scripts/test-backend-isolated.sh; authored tests and formatting are not runtime or release acceptance.

Maintainer UAT: on the network/peer screen, send the same request repeatedly to an offline peer, then bring it online and accept it; inspect empty, pending, error and success states. Verify changed messages are separate requests, expired rows disappear, rejecting a listed request prevents its later acceptance, and an operator-maintenance error is visible without losing peers. Check desktop/phone width and light/dark themes. No real payments or deployment are needed.