tinyrelayfile
tinyrelay/docs/architecture.md/

docs/architecture.md raw
1# Architecture
2
3`tinyrelay` assembles the relay host. `tinygit` owns Git functionality, and `tinyclient` owns the frontend. These functional modules share one repository and Go module. See [Module boundaries and protocol contracts](module-contracts.md) for ownership rules, extension documentation and proposed follow-up seams.
4
5Each tenant has a SQLite store, a policy snapshot and a set of services. The daemon constructs those services, connects their contracts and manages their lifetimes. HTTP, WebSocket and management adapters establish caller identity and enter the tenant's operation gate before calling services.
6
7## Find your starting point
8
9[`cmd/tiny`](../cmd/tiny/doc.go) owns command dispatch, listeners and process shutdown. [`daemon`](../internal/daemon/doc.go) describes tenant assembly and event flow. Package overviews and interface, constructor and transaction comments describe the contracts at their declarations. These comments are also available through `go doc` and editor symbol help.
10
11## Package layout
12
13Executable entry points live in `cmd/tiny`, `cmd/tinygit` and `cmd/tinyclient`. Host services and storage implementations live under `internal/`, where Go prevents outside projects from importing them.
14
15`tinygit`, `tinyclient` and `protocol/` are public so other Go projects can embed them. Separate executables alone do not require public packages. These packages expose the contracts an embedder needs; host policy, database access and tenant assembly remain internal. All packages belong to the root Go module.
16
17## Responsibilities
18
19| Packages | Responsibility |
20| --- | --- |
21| [`protocol/nostr`](../protocol/nostr/doc.go) | Public event and filter values, canonical encoding, signatures and generic wire checks. No host access policy. |
22| [`protocol/auth`](../protocol/auth/doc.go) | Public request-proof verification and replay state. No membership or permission decisions. |
23| [`event`](../internal/event/doc.go), [`auth`](../internal/auth/doc.go) | Internal compatibility aliases and feature helpers; private-kind search filtering remains host behavior. |
24| [`policy`](../internal/policy/doc.go), [`gates`](../internal/gates/doc.go) | Host policy, event admission and visibility checks. |
25| [`storage`](../internal/storage/doc.go), [`work`](../internal/work/doc.go) | Event persistence, queries, transaction hooks and durable queue claims. |
26| [`community`](../internal/community/doc.go), [`communityread`](../internal/communityread/doc.go) | Membership, moderation, rooms, agents and the read models consumed by records. |
27| [`records`](../internal/records/doc.go) | Relay identity, signed protocol records, projections and notifications. |
28| [`blob`](../internal/blob/doc.go), [`sites`](../internal/sites/doc.go) | Content-addressed files, upload rules and sites backed by signed manifests. |
29| [`tinygit`](../tinygit/doc.go) | Repository admission, object storage, synchronization, repair and Git HTTP endpoints. |
30| [`replication`](../internal/replication/doc.go), [`syncprotocol`](../internal/syncprotocol/doc.go) | Relay synchronization plans and transports, count sketches and reconciliation sessions. |
31| [`relay`](../internal/relay/doc.go), [`mcp`](../internal/mcp/doc.go), [`tinyclient`](../tinyclient/doc.go) | WebSocket sessions, MCP requests, HTML pages and browser interactions. |
32| [`agentrunner`](../internal/agentrunner) | The optional agent process: room mentions, durable queue recovery, ACP or command execution, and permission prompts. |
33| [`views`](../internal/views/doc.go), [`wiki`](../internal/wiki/doc.go), [`webpush`](../internal/webpush/doc.go) | Fenced-block parsing, article rendering and encrypted browser push delivery. |
34| [`seedmark`](../internal/seedmark) | Deterministic decorative SVG avatars for people and rooms without a profile picture. |
35| [`catalog`](../internal/catalog/doc.go), [`domains`](../internal/domains/doc.go) | Tenant lifecycle records, filesystem paths and host mappings. |
36| [`templates`](../internal/templates/doc.go), [`configport`](../internal/configport/doc.go) | Built-in policy templates and configuration import, export and application. |
37| [`telemetry`](../internal/telemetry/doc.go), [`daemon`](../internal/daemon/doc.go) | Observability, service assembly, request routing and worker ownership. |
38
39## Ownership and contracts
40
41`App` owns the catalog, telemetry and active tenants. Each `Tenant` owns its store and service lifetimes. Services borrow the store and policy reader supplied at construction. Policy reads return a shared snapshot; management writes persist and replace that snapshot. Shutdown stops admissions, joins background work and drains active operations before closing storage.
42
43Services own the schema and data access for their features. `storage.Save` and `storage.SaveTx` accept transaction hooks so event data, projections and work intents can commit together. APIs that receive `*sql.Tx` use the caller's transaction. Community event handlers that accept a persistence callback open the transaction and pass it into the callback.
44
45Consumers declare interfaces around the operations they need. `records.CommunityReader` reads membership and moderation projections through `communityread` values. `relay.Backend` supplies event operations to the WebSocket router. `tinyclient.Backend` supplies management results, and `tinyclient.RoomsReader` supplies typed room pages. The daemon implements these adapters and assembles the feature handlers used by `work.Worker`.
46
47## Event acceptance
48
49`protocol/nostr.Validate` checks wire shape, event ID and signature. `tinygit.ParseMetadata` separately parses repository claims without establishing signer validity, repository authority or object availability. Git admission entry points perform signature and metadata checks before host admission callbacks. Generic `nostr.Matches` is not a visibility gate; callers must apply host access policy.
50
51Client publication and imported events use the shared event persistence and projection path. Each entry point applies its admission rules and protocol actions. Signed repository state stays pending until its referenced Git objects are available; promotion makes it visible and plans its optional follow-up work.
52
53Callbacks and custom views are optional. A planning intent commits with an accepted event and captures its eligible registrations or failed local lookups. Recovery rechecks the source and current registrations, with at most three worker attempts and a 15-minute age limit. Stable child intent IDs preserve completed work. Remote delivery and transforms have their own retry policies. See [callbacks](agents.md#retries-and-pauses) and [custom views](views.md#failures).
54
55## Browser boundaries
56
57Pages render without JavaScript. `page.html` owns the shell and panel dispatch; each page template owns one content section. Markup uses elements and IDs for styling in `style.css`. Shared form and data elements live in `components.js`, room interactions live in `rooms.js`, and signed publication uses `tiny.signing`. The signing contract verifies returned events before publication. Browser modules describe their entry points and shared services in their source headers.
58
59## Dependencies and checks
60
61Go module versions are declared in `go.mod`, with dependency checksums in `go.sum`. Browser dependencies are locked in `package-lock.json`. `make verify` checks the Go and JavaScript code and verifies generated browser bundles against their sources. See [Testing](testing.md) for local and Linux checks.

About

ownerc01503e8035f
visibilitypublic
headd730679639bf

Maintainers

  • c01503e8035f owner
  • ba1b5beed5b5 agent hermes

Clone

  • https://012.run/npub1cq2s86qrtadf36eqq3epm38wmhdynrrcwxf84eldk3f94dkv7ttsrulrz5/tinyrelay.git

Refs