HyperNet Relay ChatDocumentation
stable / Version 0.1.0Project website
Reference library
Use and operate HRC
On this page
  1. Local state and reconnect
  2. Inspection and notification
  3. Confidential conversations
  4. Federation service selection

Shared local client#

The graphical and terminal interfaces use client::Controller. One background worker owns the endpoint's existing SQLCipher store. Opening the controller does not open HyperNet, sample the authority clock, or create a second store owner. The account configuration, database key, continuity guard and private paths still receive their normal validation. Explicit connection obtains a new verified session and resolves persisted operation identities before preparing new effects. There is no direct Internet fallback.

Online status follows successful initial refresh as well as session setup. Temporary pre-admission authority, rate or capacity refusals preserve their retry guidance and enter bounded reconnect backoff. Reconnect obtains fresh authority and resolves exact retained operations before retrying an absent effect. A durable rejection, invalid identity or malformed frame does not become an automatic retry. Readiness failure remains visible on the original command; later recovery does not rewrite that completion as success. Current-query errors remain explicit. The five-second metadata refresh interval starts after a successful full refresh finishes, including initial connection and commands that change membership or policy. Due metadata work runs between command turns, even with a busy queue. With the negotiated bounded-view capability, each periodic turn performs one finite group or continuation page before yielding to queued command work. A full metadata refresh cannot occupy every intervening command turn. Initial connection and membership or policy changes still complete their required refresh before reporting readiness. Room selection and targeted post-send reads do not postpone that deadline. A selected community page with authenticated has_more schedules a finite catch-up burst without waiting for the next metadata interval. Each turn reads one bounded grouped component, then yields to queued commands; due metadata has priority. Up to eight additional history pages share the first page's original ten-second admission and currentness end, including time spent on intervening work. Each newly dispatched read separately owns the existing ten-second exchange bound, captured before signing. Its exact retries cannot restart that bound. A read already in flight may finish after the view end, within its own original exchange bound; total completion can extend the logical view end only by that bounded in-flight read. Such a late reply is consumed and authenticated without publishing its content, advancing a cursor, installing filters or scheduling another continuation. No new request starts after the view end. Incomplete recipient policy cannot publish history. Each completed page advances the authenticated cursor; an unchanged position with has_more is rejected. Initial catch-up does not emit live notifications. A completed command pull supersedes matching partial work without extending its end or page allowance. Cancellation, disconnection, room or focused-context changes, gaps and failures stop continuation. A finite burst that exhausts its time or page allowance leaves has_more visible; the next ordinary refresh can resume it. No read grants authority to a subsequent read. A slow full refresh does not schedule an immediate second full refresh. A failed full attempt also waits that interval before another metadata attempt; transport or authority backoff can require a longer wait. Failure never makes a view current.

Snapshots distinguish updating from stale room or inspection state. The GUI and TUI show "refreshing views" while reads run or a committed community send has a bounded room update or selected-room catch-up pending. Pending work does not make retained policy current and does not extend the lifetime of any authority observation. Starting an ordinary refresh retains the last successfully synchronized view; it does not itself signal lost access. Cached or already-stale views remain stale until their required current reads succeed. A failed view scope marks its retained views stale, including local storage and invalid-response failures. An authenticated read refusal is published as stale before any bounded same-action retry wait. Temporary refusals of RoomInspect, EventsResume and ModerationRestrictions with a room target mark only that matching room view stale. They preserve unrelated inspection and transport privacy observations: a synchronized application refusal is not evidence of changed TLS or route properties. The completed room pull revalidates its room, history and restrictions before making that view current. It cannot clear already-stale account inspection. Restriction lists follow selected-room freshness and are cleared when selection changes. Other read kinds, including recipient filters, search and focused context, retain global failure handling; no room-only recovery is inferred for them. Exhausted retries and final view failures still invalidate the full view and privacy observation. Existing denial, expiry, history-gap and encrypted-history protections still apply. Neither a synchronized view nor a retained privacy observation grants authority: the service checks current authority on every read and effect.

For local nondelegated community views, bounded-client-views-v1 groups related reads through the same server policy owners. Account metadata and community-room synchronization have separate fixed contracts. Each group receives a fresh authority check and retains the summed operation costs and ordinary frame limit. Incomplete filter or restriction pages cannot admit history or notifications; changed context discards the partial assembly. Failures invalidate the requested view scopes. Remote, encrypted and delegated paths retain their existing reads. See bounded client views.

Recipient-filter freshness is separate from grant and agent metadata freshness. inspection.filters_stale remains true until complete current filter assembly; inspection.stale covers the metadata refresh. A grouped community-read failure invalidates filter-dependent room, search and notification state without making unrelated grant or agent metadata stale. Global terminal and transport failures invalidate both scopes. Current presentation and pilot readiness require both flags to be clear; completing filters alone cannot refresh metadata.

An explicitly authenticated community classification can supply private, in-memory room-mode evidence for an exact prepared message. It binds the room, home and pinned service key, and requires the negotiated immutable-mode contract. It is not an access grant. Current service authority and room or delegation checks remain mandatory on submission. A caller-supplied room summary, missing mode field or mutable prepared object cannot provide that evidence. Raw API submissions, unknown-room preparation, encrypted messages and persisted retries retain their validation paths.

Session setup allows at most three attempts within one original 30-second deadline. Each HyperNet preparation wait is at most 10 seconds; each HRC handshake is at most five seconds within that same deadline. Incomplete HRC handshakes and typed HyperNet Timeout, Unavailable, Closed, Capacity, Busy or NotActive preparation failures can obtain a fresh stream. An authenticated federation Unavailable, RateLimited or Overloaded response can also retry setup. Its retry guidance is a minimum wait; guidance outside the remaining original deadline returns the refusal without another attempt. These attempts share the same three-attempt ceiling. Explicit HyperNet Refused, federation denial or expiry, invalid protocol/frame/version, private-path or ownership failures are terminal; Controller and bot reconnect classification preserves that distinction. An authenticated Unavailable, RateLimited or Overloaded refusal from the service or origin forwarder leaves its current session synchronized. After a bounded read retry is exhausted, the Controller also retains that session, marks the view stale and honors its existing backoff. It resolves exact pending operations and refreshes through that session before reporting Online. Retaining the connection does not treat a refused operation as successful or preserve expired authority. Genuine transport failures still require reconnection; invalid frames and identities remain terminal. Disconnect stays available during the wait. Session reuse supplies no new authority, extends no operation window and cannot replace uncertain effects. No conversation operation is prepared or replayed by session setup. Preparation failure diagnostics contain only the static adapter category and boot-time start, finish and original deadline, without identities or credential data. They stop after 128 attempts per process. One process-lifetime writer receives at most 32 queued records, each at most 1,024 bytes including its newline. Saturated, closed or oversized output is discarded. Connection workers never wait for the output sink, and shutdown does not join the diagnostic writer. Unavailable diagnostic output does not change the connection outcome.

Controller and direct CLI/API reads share the same temporary-refusal recovery. An authenticated temporary read refusal retries the same signed bytes on the same session, at most five attempts within one original ten-second budget. This also covers room inspection before direct message preparation. Retry guidance must fit that budget. Each attempt requires a new service authority check; earlier successful refresh reads are not restarted. Permanent refusals, invalid responses and transport loss end the attempt. Controller disconnect and shutdown interrupt retry waiting; synchronous direct reads retain the same fixed budget. This read path cannot submit mutations or recreate a pending message. Room lists stop when the final partial page is received.

Periodic metadata, community catch-up and coalesced post-send reads retain their exact signed request and original deadlines while waiting for retry guidance. The worker can start queued commands between complete authenticated responses. A scheduled read does not hold the worker during its retry timer, consume another pagination allowance, or obtain an extra connection. An incomplete response still owns the stream until completion or transport failure. Synchronous initial readiness, explicit reads and unsupported view paths retain the same retry policy.

A read or logical view budget that ends before dispatch or after a complete verified response reports ReadDeadlineExpired. Late content cannot make a view current. The Controller retains the synchronized session and marks affected views stale. If an already-online background or post-send view expires, the next periodic view attempt waits the ordinary five-second interval. Other commands can proceed through their current service checks without connection backoff or outcome replay. This does not change initial readiness or recovery of uncertain effects. Terminal refusals retain their authority meaning; an incomplete exchange at its own read deadline or actual socket failure still requires reconnection. A logical view deadline never shortens an already dispatched frame exchange. Neither deadline grants authority or permits mutation retries.

The command queue contains at most 32 bounded commands. Dispatch returns a local request number. Immutable snapshots carry that number on command status and operation delivery records. A frontend can distinguish the exact submitted text from later typing. Historical recovered operations have no local request number. When connection is still desired, the worker can retain one unstarted state-changing command ahead of that queue while the connection recovers. Its 30-second admission deadline starts at dispatch, including queue time. The worker honours existing reconnect backoff and checks the original deadline again before starting any effect, even when synchronous reconnection finishes late. The same request and command are consumed once; this mechanism never reruns a started command or prepares a replacement effect identity. CommandWaitingForConnection shows the pending request; CommandAdmissionExpired reports expiry without a delivery identity or a changed connection retry schedule. Deliberate offline mode retains normal refusal and local-draft behaviour. Reserved disconnect and shutdown controls remain available while a command is held. Read-only commands retain their existing explicit current-read failures and offline cache behaviour. Local draft/preference writes, retry abandonment and search close use a local lane sharing that same 32-item queued budget. At most four local commands run per worker turn, so they remain responsive during reconnect backoff without starving an eligible effect. Shutdown atomically closes queue admission, then drains accepted local work only; it does not execute queued network effects. Local persistence errors remain visible on their original completions. Effect completion succeeds only after every requested effect and its required local persistence succeeds. A later room, grant or inspection refresh can fail without changing that confirmed outcome or replaying the effect. The original durable delivery is published before follow-up view reads start. A normal send refreshes recipient filters, the affected room and the companion privacy observation. Direct committed sends to the selected, unfocused local community room may share this work when bounded views are negotiated and no history gap is present. The first pending update's one-second age is never reset by newer sends; the next background turn starts at that age or after the second commit. Idle time starts it sooner. Each turn reads at most one complete page response. Further commits share the pending work and request one later pull if they arrived after its assembly began. They never extend that assembly's deadline. A different operation or room context discards unfinished background work and leaves the old view stale before performing its own current operation. Disconnect and shutdown also discard pending work; none of these paths replays committed effects. Delegated and approval sends, confidential conversations, focused history, background-room sends and unsupported view paths retain their immediate refresh. The existing finite metadata turns and five-second cadence continue between commands, and a targeted pull supersedes its matching partial room assembly. Unrelated room-list, account, service, grant and agent metadata wait until the existing full-refresh deadline. The affected-room pull retains current room authorization, filtered history and restriction inspection; focused history also receives its current context check. Membership and policy mutations still invalidate their retained views and perform a full refresh. The command completion and exact committed delivery remain successful; the affected views, inspection and privacy become stale. ViewRefreshFailed reports the separate view failure without attributing it to the effect request, and normal connection failure and reconnect rules still apply. The warning clears when a current online view is restored. Partial failure of a compound command remains an error, with each earlier confirmed delivery retained independently. Network and database work never run in a widget or terminal input callback. Disconnect closes the active stream and publishes Offline with stale room and inspection state and no active privacy badge, even when the worker is idle. Shutdown joins the bounded worker.

Local state and reconnect#

Drafts preserve text and up to 16 stable mention spans in one guarded transaction. Saving a draft does not require current authority. A mention contains an account identity and UTF-8 byte range, aligned to complete Unicode graphemes. Sending checks the current room membership and exact nickname represented by that span. A renamed account causes an explicit conflict; text does not retarget another account with the old nickname. Plain unselected @text has no notification power.

Received events and their verified room/access cursor commit atomically. The local archive holds at most 4,096 events and 16 MiB of encoded event data, with a seven-day content retention window. A selected snapshot contains at most 256 events. The archive is a bounded local copy, not a complete service backup. Conflicting event identities or ordering positions fail without advancing the cursor. Preferences and candidate approvals share the encrypted store. Community search results are bounded transient views. Encrypted conversations use a local index inside the endpoint SQLCipher store; the service receives no plaintext index.

Cached views explicitly show stale status until current filtered history is read. Resume uses the service's current membership, grant, retention and recipient filter checks. An expired or changed community cursor can reacquire one current cursorless page within the original ten-second read deadline. The old community cache, focused view, search and queued room notifications are cleared before that read; catch-up does not emit live notifications. Every attempt checks current authority. A second context change, missing retained history, an impossible position, or an unclassified persisted gap remains explicit and needs recovery. Disappeared or unjoined rooms lose cached events. A transport failure keeps drafts, retained history, its signed cursor and exact uncertain outbox bytes. A transient authority/availability refusal cannot fabricate an access-withdrawal gap; only explicit denied, expired or resynchronisation outcomes invalidate the current cached presentation. Reconnect uses capped exponential backoff with jitter, fresh permission, and original operation resolution.

A committed effect clears a draft only when the stored draft still belongs to that exact operation ID and action digest. Every later draft save removes that binding, including a save with identical text or an empty draft. A held send cannot overwrite a newer acknowledged draft. Rejected and unknown effects retain the draft. An approval candidate persists its exact signed bytes before exposure. The owner's inspection exposes its action digest, content, scope and validity. Submission uses those same bytes; changing content or scope requires another approval.

Inspection and notification#

Account inspection, room inspection, owned filters, active room restrictions, owned or assigned grants, and owned eligible agent endpoints have typed operations. Private inspection requires the authenticated account's own target. Delegated actors cannot use private account inspection to expand their grant. Room details require current membership and show moderator attribution and expiry. Lists use bounded pages and explicit continuation positions; these positions confer no permission.

Preferences include dark/light theme, compact/comfortable density, text scale from 0.75 to 2, quiet mode, sound, terminal ambiguous character width, and per-room all/mentions/off notifications. Mentions use stable account bindings. Ignored or muted actors produce no local notification. Catch-up after connection does not emit notification bursts. Sounds are emitted only when both global and room preferences permit them. A current filter update immediately refilters live and focused history, search results and queued notifications, even if a later view read fails. Muting suppresses notifications without hiding retained history. Explicit denial of a focused context removes that context; a temporary failure retains it with stale status.

Search cancellation uses the existing authenticated stream. One query can be in flight, with at most one exact correlated cancel request. The service registers that query before execution, verifies the control's signature and transport permission, and checks current account authority before returning its result. The query worker observes a cancellation token. A request without a matching active query does not report success. The single client reader consumes both signed responses under the original bounded query deadline, and ignores a result that the user cancelled. No extra persistent companion connection is required. Cancellation shares the service's bounded FIFO authority admission with ordinary actions. Later requests cannot overtake it; it receives no permission bypass. Both its initial transport check and its subsequent Home admission retain the original query deadline, and no authority slot is held while Home work executes.

The cache schema uses version 2, migrating version-1 filters into the original local service. Draft migrations preserve text and add an empty mention list to the known earlier three-column table. The independent HRC.ClientDraftBinding.Schema.1 migration adds a nullable exact-send binding. Older drafts remain unbound; resolving an old outbox action cannot claim ownership of them. Unknown schema or corrupt encrypted state is refused; opening never resets a database or guard.

hrc service init --motd 'Welcome to this service.' stores an optional message of the day in the private service configuration. The default is empty; the maximum is 1,024 bytes of validated protocol text. Authenticated ServiceInspect returns this text only, without automatic platform, version, clock or address disclosure. The controller exposes the authenticated value as Snapshot.motd.

Snapshot.completions retains the last 64 queued command completions. Each entry binds the local request number to success or its stable error. A draft save can therefore be acknowledged before switching rooms or closing an interface without confusing it with message delivery. Shared presentation tracks each edit revision and retires completed save requests. A delayed save or send acknowledgement cannot claim a later revision, even when text or selected mention spelling is identical. Room and event-context navigation waits for the latest old-room draft to be saved. The composer visibly pauses only while the dispatched navigation is pending, then resumes on success or failure. Disconnect and search cancellation use their reserved control flags rather than waiting behind the normal command queue.

OpenEvent requests HistoryContext from the service under current room, delegation, retention and recipient-filter rules. The response contains the requested event and up to two neighbouring ordering positions on either side; representation bounds may omit neighbours but never the requested event. The selected view exposes focus and shows this authenticated context. Selecting the room again returns to its live/resume view. Context reads do not rewind the persisted resume cursor or fabricate surrounding messages from the cached tail.

An unresolved effect can be explicitly abandoned with its exact operation ID and action digest. This stops automatic resubmission; it does not retract a message, erase its immutable request, or assert rejection. The outbox exposes abandoned: true and retains the unknown outcome. ResolvePending can still query that identity and record a later authoritative result without resubmitting it. Reconnect automatically resolves active retries only. Active retries remain limited to 32, abandoned unresolved records to 256, and their combined exact-byte storage to 8 MiB. Exhaustion is explicit. CLI abandon --profile ... --window ... --operation ... --action-digest ... performs the same local transition.

The deterministic service bot uses the same current session, signed operations and exact outbox. Its separate durable trigger cursor and planned reply commit atomically, so transient interface notifications are never used as persistent automation progress.

Confidential conversations#

prepare_send first reads current room metadata. Community text and encrypted messages take distinct typed paths before any content is transmitted. Encrypted sends verify pinned contacts and the current endpoint roster, then atomically persist the MLS sender state, exact ciphertext Action and ordinary outbox. The internal prepare_send_with also accepts a transaction-local finalizer for the bot's cursor/plan. It cannot perform network I/O. Preparing a candidate with an approval ID marks its outbox record held: reconnect never submits it automatically. submit_candidate requires the exact currently approved digest and grant before releasing that held record. Explicit abandonment retains an honest unknown outcome.

CryptoEnrol, CryptoPublish, CryptoInitialise, CryptoCommit, CryptoSync and CryptoInspect operate through the same current session and guarded store. Private groups and confidential direct rooms have explicit invitations; membership alone does not import prior keys. Each explicit package publication creates a fresh one-use package, bounded to 64 unused local packages. Exact uncertain publications are resolved before another is prepared. Successful MLS transitions and their verified rosters share one commit; a missing future epoch produces an explicit gap. Epoch-ready acknowledgement is sent only for the selected latest epoch and an endpoint currently eligible for live content.

Encrypted history can restart one stale access cursor within its existing eight-request catch-up bound. A missing-history or impossible-position gap stays explicit and does not trigger that restart. Cursor gaps and explicit resynchronisation retain MLS state, pending transitions and already decrypted local content under the local retention policy. Current history windows and filters still govern presentation; acknowledging a gap cannot recover missing keys or confer access.

The shared Client::resynchronise_history(room) operation explicitly clears a local history gap and continuation. It preserves encrypted archives, MLS state, drafts and exact pending effects; it does not fetch content or authorize access. Controller Resynchronise, /resync and bot --resynchronise use that operation. For CLI encrypted history, use hrc crypto sync --profile PATH --room ROOM --resynchronise. Omit the flag for ordinary synchronization. Resumed reads still check current room, grant, device and transport authority. A failed explicit CryptoSync exposes any persisted gap in the selected view and its recovery control.

The selected room exposes an encryption view, exact roster, pending packages, barrier and contact trust status. TrustContact accepts an exact displayed anchor and its legacy/nonlegacy classification. New registration anchors require explicit acceptance too. Public continuity records are replayed cryptographically; a pinned anchor and prior head cannot be replaced by a home-only assertion. Historical transition evidence permits verification of former participants within current history rights. Separate MLS keys are generated for each enrolled endpoint.

RoomView.content, SearchView.content and ConversationPage.content hold local plaintext or a precise rejection separately from the unchanged authenticated Event. Serialized content maps use the original message ID as a hex text key. Encrypted approvals use the same principle, keyed by exact candidate action digest. Inspection decrypts a candidate once; approval requires inspectable valid content. Matching delivery consumes the saved preview rather than advancing the receive ratchet a second time.

Online history_messages, search_messages and message_context apply current room/grant/filter rules. Search and context use only already decrypted local copies, including permitted past-only grants, without requiring current live admission or new history keys. search_retained is an explicit offline operation with stale status. Results retain the original authenticated event and message identity. The local FTS index, plaintext and consumed delivery copy expire with the event. Unresolved outbox/approval records have bounded explicit retention until resolution; no expiry is reported as successful delivery or authoritative rejection.

The private encryption-view cache stores the remote snapshot and each contact as separately bounded canonical objects. A full 256-entry filter list can coexist with 256 contact views without exceeding the protocol parser's recursive-node budget. The aggregate cache record remains bounded to 256 KiB; each contact is bounded to 2 KiB. Capacity is checked before dependent contact or crypto effects. The public view remains structured data for the interfaces.

CLI history and search return ConversationPage with original events, separate local content, cursor and access state. Agent inspection returns GrantPreview with its grant inspection, exact candidates and decrypted proposal content. Preflight permission failures report OperationDenied or OperationExpired; temporary non-admission reports OperationTemporarilyUnavailable. These failures do not claim that a message was committed or delivered.

Federation service selection#

An endpoint keeps its original account, signing key, recovery model and HyperNet companion. Selecting a foreign room home first authenticates the endpoint to its origin service. The origin then forwards a separate signed bootstrap through an independently admitted destination companion. The client verifies the remote home signature, exact request digest, endpoint binding and home retry window. A foreign home cannot replace the endpoint's origin account or key.

Import the two service descriptors through a deliberate trusted exchange. The agreement's embedded keys do not establish those trust pins. Both administrations must sign the same agreement. The following command stores those signatures and selects the foreign home for subsequent CLI, GUI, TUI and bot sessions:

sh
hrc federation client-select --directory PROFILE \
  --home-descriptor HOME_DESCRIPTOR --origin-descriptor ORIGIN_DESCRIPTOR \
  --home-signature HOME_SIGNATURE --origin-signature ORIGIN_SIGNATURE

Use --trust-only on a home-side client to verify the remote participants' origin continuity without selecting a foreign home. At most two bilateral agreements are retained in one profile. Profile input is bounded to 1 MiB, including encoded signatures; each agreement retains the ordinary wire bounds. Registration profiles without federation fields remain compatible.

The GUI connection details list the configured conversation services. The TUI and GUI accept /network local and /network AGREEMENT_ID; /who lists the choices. Switching services closes the current stream, preserves drafts and uncertain operations under their original home, and authenticates a fresh session for the selected service. CLI clients can select their origin again with hrc federation client-local --directory PROFILE. Origin-owned account and endpoint administration use the local selection. No network route is inferred from an account identifier or silently replaced by a direct connection.

Room caches, active ignore/mute lists and retry selection are scoped to the home service. Switching does not erase another home's retained rooms or drafts. The aggregate cache and outbox limits still apply. The filter-schema migration moves existing filters into the original local service exactly once.

Privacy details distinguish the endpoint's transport observation from the source and destination leg observations verified at remote admission. Admission is a historical observation; both current permissions are checked again for every forwarded action. Disconnect clears the displayed admission observations. The client does not assert physical relay-operator independence from these receipts. hrc profile session includes the signed remote-admission fields as structured output alongside the ordinary endpoint transport properties.

A remote query owns one serial gateway stream. Cancelling it closes that stream and propagates bounded cancellation to the home query. The client discards that query result and reconnects with current permission; it does not report a home-signed cancellation outcome or replay the query as a mutation. Other clients retain their own streams. Pending sends keep their exact durable identities and are resolved separately after reconnect.

Encrypted remote contacts require independently pinned origin service evidence and the same explicit contact-anchor acceptance as local contacts. A foreign owner's grant proof selects its signed origin continuity head. The home grant position is never compared with an unrelated origin history position. Origin assertions and exact owner-signed grant bytes remain bound to that checkpoint.

HyperNet Relay Chat / DocumentationBack to top

Search documentation

Press Escape to close

Loading search...

    Reading appearance

    Choose colours, surfaces and text independently. These settings are saved for this documentation site in this browser.

    Flat surfaces remove decorative materials. Typography is a separate choice. Increased contrast uses the Contrast palette. System forced colours always take precedence.