Repository navigation
Conversation
Adds docs/README.md as the single entry point to the repository's documentation. Every .md file in the repo (excluding generated output and dependency directories) is listed exactly once with a one-line description. Documents are grouped by reader intent rather than by directory: new contributor, backend developer, frontend developer, contract developer, operator, security reviewer, and AI/data developer. A document needed by two roles is listed under both, since each section is meant to stand alone. Includes a "Start here" path for first-time contributors that ends at the contribution guidelines, and a maintenance section stating that the index must be updated whenever a document is added, moved, or removed. The root README now links to the index and to the architecture overview. Note: the issue refers to a top-level CONTRIBUTING.md and a docs/adr/ directory. Neither exists in this repository, so the "Start here" path ends at the Contributing section of the root README and calls out that it should be repointed if a dedicated CONTRIBUTING.md is added.
Adds docs/architecture-overview.md as the orientation entry point for the system: one Mermaid diagram showing all four apps, the stateful infrastructure (Postgres, Redis, object storage, Weaviate), the Stellar network, and the external LLM provider, plus a table naming the protocol on every edge. Each component gets a short paragraph covering its responsibility and, explicitly, what it must never do — the invariants that are easy to break accidentally (the gateway must not acquire a decryption path, Redis must not be treated as durable, the AI agent must not gate a transfer). Two end-to-end paths are traced concretely against the current code: sending an encrypted message (per-device envelope encryption through deliveryPipeline fan-out to delivery receipts) and executing a treasury withdrawal (on-chain propose/vote/execute with the listener maintaining an off-chain mirror). The document is explicitly scoped as orientation only and defers to the per-app documents, which it links throughout. Notes a real defect found while tracing path 2: the backend listener subscribes to a `proposal_executed` topic that no contract publishes — `proposals` emits the truncated symbols `executed` and `execut`. The per-event detail belongs in the contract events reference (codebestia#581); this document links to it. The issue refers to IMPLEMENTATION_DOCS.md as the existing long-form design spec. No such file exists in this repository, so this document links to the per-app docs as the deeper reference instead.
Adds contracts/docs/concepts-upgrades.md covering token_transfer's upgrade(env, new_wasm_hash) entrypoint end to end. - Authorization: the single admin.require_auth() gate, that the admin is fixed at initialize with no rotation path, and what a compromised admin key means (total, unrecoverable loss of control over the contract). - Procedure: build with the pinned release profile, upload to obtain the wasm hash, verify that hash locally with sha256sum and via an independent reproduction, invoke as the admin, then confirm by reading state back. - Storage compatibility: soroban-sdk encodes contracttype enums by variant-name symbol and structs as name-keyed sorted maps, so renames and type changes corrupt or orphan state while reordering is harmless. Tables split safe from unsafe changes on that basis, and note the rename of DataKey::Admin as the unrecoverable case. - Records that only token_transfer is upgradeable; group_treasury and proposals have no upgrade entrypoint, so changing them means a fresh deployment and repointing every consumer. - Notes the absence of any version() entrypoint or upgrade event: the wasm hash is the only on-chain version identifier.
Adds contracts/docs/contracts-events.md documenting all sixteen env.events().publish(...) call sites across token_transfer, group_treasury and proposals: topic tuple, data payload field by field, the state change each event signals, and whether the publish happens before or after the corresponding storage write. Emission order is called out per event because two of them — group_treasury's proposal_approved and proposal_rejected — publish before the proposal is persisted, setting the status on the in-memory struct first. Not observable to an off-chain consumer given transaction atomicity, but relevant when reading the contract. A summary table marks each event as consumed or unconsumed by the backend listener, and a dedicated section collects the five consumption gaps found while cross-referencing the contracts against stellarListener.ts: - the listener subscribes to `proposal_executed`, a topic no contract publishes. proposals emits `executed` and `execut` instead, so the status map entry is unreachable and a proposal never reaches the executed status in the off-chain mirror via the listener - group_treasury has no execution event tying a fund movement back to the proposal that authorised it - deposit and withdraw, the two value-movement events, have no consumer - only one contract id is watched for treasury topics, and both contracts publish a `proposal_created` with different payloads and different id widths (u32 vs u64) - vote-level events are unconsumed; on-chain votes are invisible to the backend until a transition event fires Also documents two payload gaps (DepositEvent and WithdrawEvent omit the token address despite per-token balance tracking) and notes that the proposer's auto-approval emits no withdraw_vote, so counting those events undercounts approvals by one. The `executed` / `execut` split is flagged as a naming defect rather than a constraint: symbol_short! permits 9 characters and "executed" is 8, so the truncation is unforced. Cross-links the backend chain listener source, the treasury API doc, and the deployment doc.
Adds docs/api-versioning.md. States the current position plainly: REST routes are mounted unprefixed in app.ts, socket events are addressed by bare name with no version in the payload or handshake, and no deprecation machinery exists anywhere in apps/backend/src. Records the three breaking changes that already shipped without one - sequenceNumber dropped from GET /sync envelopes, device made required on POST /auth/verify, and JWT-only registration retired at POST /devices. Defines what breaks for REST responses, socket payloads, and database-backed shapes, including the case where a migration changes a response without any route being edited, and the asymmetry that strict request schemas make an added optional field breaking in the other direction. Gives the deprecation procedure: announce with a sunset date, mark per surface, ship the replacement first, hold the window, then retire behind an explicit error naming the replacement. The retired POST /devices handler, which still answers 403 pointing at the link-challenge flow, is the precedent the procedure generalises. Sets a 90-day minimum window, derived from the 7-day envelope retention floor plus stale tabs and cached service workers. Documents device capability negotiation as the mechanism that already ships protocol changes without breaking older clients, and names the properties that make it work: a universal sealed_box baseline, absence normalising to that baseline rather than erroring, unknown values preserved and ignored, and pairwise per-message selection.
Adds contracts/docs/concepts-resource-budget.md covering the deployed size constraint and the wider resource picture around it. Documents the gate as CI actually implements it: 102,400 bytes per contract, enforced in the "Report WASM binary sizes" step of contracts-ci.yml, run per-contract across a fail-fast:false matrix, measured against the raw cargo build output with no wasm-opt step, and posted to the PR as an update-in-place comment keyed on a marker comment. Notes that the gate is per-contract rather than cumulative and that the step reports the full table before failing. Records current sizes measured from a local release build, with headroom: group_treasury 31,843 B (31.1% of gate), proposals 25,931 B (25.3%), token_transfer 10,539 B (10.3%). Includes the command to reproduce them, since sizes drift with soroban-sdk upgrades. Documents each [profile.release] setting and the cost of changing it, including that overflow-checks = true costs size deliberately and should not be traded away in contracts that move funds. Gives concrete size-reduction techniques in effort order: profile with twiggy first, run stellar contract optimize, replace panic string literals with a #[contracterror] enum, keep formatting machinery out of the shipped path, deduplicate generic instantiations, split along a real boundary, and only then raise the threshold. Closes with the resources beyond raw size — CPU instructions, memory, ledger entry reads/writes, events, rent/TTL, and transaction size — and identifies the constraint that actually binds first in this codebase: all three contracts keep per-proposal and per-voter data in instance storage, which grows unbounded and is read and written whole on every call, and several functions do linear scans over it.
Adds apps/ai_agent/docs/configuration.md. Documents that OPENAI_API_KEY is the only environment variable main.py reads, with required status, no default, and no .env loading, and lists the variables the service does not read - model selection, Weaviate host/port/key, HOST and PORT - since setting those silently does nothing. The model choices, bind address, collection name, search limit, high-value threshold and per-call timeouts are tabulated as hardcoded values, with the note that the 0.0.0.0:8000 literals only apply to direct python main.py execution and not to fastapi/uvicorn launches. Documents the missing-API-key behaviour precisely: the key is read per-request inside _openai_client(), so the process starts clean, /health returns 200 and every OpenAI-backed endpoint returns 500. Both halves are pinned by tests. Spells out the load-balancer consequence - an instance with a bad key passes its liveness probe, joins the pool and serves nothing but 500s - and records the endpoint-by-endpoint matrix, including the high-value /transfers/analyse branch that answers 200 without ever constructing a client. Documents the Weaviate connection as an unconfigurable per-request connect_to_local() on the client's localhost defaults, the 503 failure mode, that infra/docker-compose.yml ships no Weaviate service, and that a containerised agent cannot reach a sibling container over loopback. Cross-links the repo-wide .env.example as the single environment reference.
Adds apps/web/docs/styling.md. Documents the Tailwind v4 setup: no tailwind.config file, the single @tailwindcss/postcss plugin, and globals.css as the only global stylesheet - with the distinction between its :root variable block and its @theme inline mapping, which is why both bg-card and bg-[var(--card)] compile. Gives guidance on which idiom to use, since the arbitrary-value form is roughly twice as common and is the only one that takes an opacity modifier. Documents the seven colour tokens with their roles and how heavily each is used, the spacing ladder and typography scale the existing screens actually follow, and the Badge tinted-surface recipe that stands in for absent status tokens. Records the ~30 off-token gray/slate and raw-hex occurrences as drift rather than precedent. Covers breakpoints - defaults, mobile-first, only sm/md/lg in use with zero xl or 2xl - and the hand-followed class order, noting that nothing enforces it since there is no prettier-plugin-tailwindcss and no Tailwind ESLint rule. States extraction rules in both directions, anchored on the three- occurrence threshold, variants, accessibility behaviour and non-utility CSS, and notes the absence of any cn/clsx helper. Records that dark mode does not exist: one :root palette that is itself dark, no prefers-color-scheme block, no darkMode config, no theme provider or toggle. The single dark: variant in CopyButton can never activate, so nobody should assume dark-mode support works or write new dark: variants.
…s-web-reference docs: contract upgrades, API versioning, AI agent config, and styling conventions
docs: documentation index, architecture overview, contract events reference, and resource budget
Documents the standard Soroban test scaffolding, the three levels of auth mocking and the risk of blanket mock_all_auths() hiding a missing require_auth(), how to test expiry via the virtual ledger clock, and the proposals -> group_treasury cross-contract test setup.
Documents sw.js registration/update lifecycle via skipWaiting + clients.claim, the content-free push handler, click-to-route focusing an existing tab instead of opening a duplicate, and what does and does not work offline today (no precaching, no fetch interception, no background sync).
Documents the toast API vs inline error state, maps backend error responses (REST schema error format, per-endpoint docs) onto user-facing messages, states the hard rule that decryption failures render as UnavailableMessagePlaceholder rather than a generic crash, and covers current send-failure/offline behaviour including known gaps (silent socket errors, no send retry or offline queue).
States the WCAG 2.1 AA target and that conformance is currently checked manually (no automated a11y tooling in the repo yet). Documents keyboard navigation for the conversation list and composer, contrasts Modal's full focus-trap/restore implementation against the safety-number panel's current gap, explains the aria-live approach for incoming messages without stealing focus, flags the low-opacity text contrast risk, and gives a pre-merge checklist. Also registers all four new docs (contract testing, service worker, error handling, accessibility) in the documentation index.
docs: add contract testing guide, service worker, error handling, and accessibility docs
Adds docs/monorepo.md (workspace layout, Turbo task graph, shared tooling), apps/web/docs/components-ui.md (shared UI primitives reference), apps/web/docs/concepts-state-management.md (provider tree, Auth/Wallet contexts, ProtectedRoute), and apps/web/docs/testing.md (Vitest setup, fake-indexeddb, WebCrypto, socket mocking). Closes codebestia#544 Closes codebestia#568 Closes codebestia#572 Closes codebestia#573 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R8SebNynWtmCebVq8tpgxS
docs: add monorepo, UI components, state management and testing guides
…-docs-5qhb7p Claude/ci cd glossary docs 5qhb7p
Adds three documents covering gaps in the contributor-facing documentation, plus the matching rows in the documentation index. docs/testing.md - cross-app testing philosophy and conventions: - States the no-external-services rule explicitly, with the reasoning and the approved substitute for each dependency (ioredis-mock for Redis, a hand-built db mock for Postgres, LocalDiskObjectStore for S3/MinIO, fake-indexeddb and the web setup shims, pytest-mock fixtures for the AI agent, and the Soroban Env harness for contracts). - Documents the per-app runners and commands: vitest for backend and web, pytest for the AI agent, cargo test for contracts, plus the include and exclude patterns that decide which files are collected. - Explains the established Drizzle mocking pattern, including why the module under test is imported with a dynamic import after the mocks, and why .values() sometimes has to be both thenable and expose .returning(): the message insert chains .returning() for the generated id while the envelope insert only awaits .values(), so a stub supporting one shape silently records nothing for the other. - Documents that socket handlers must be driven through the enveloped dispatch event rather than a raw socket.on listener, since there is no raw listener and grabbing one bypasses envelope validation, the auth gate, and eventId idempotency. - Notes the shared in-process rate-limit counters that leak between tests, with the reset hooks for that and the other module-level state. apps/backend/docs/migrations.md - drizzle-kit migration workflow: - Establishes schema.ts as the source of truth and migrations as generated output, never hand-written first, with the one documented exception. - Documents the drizzle/ layout and meta/_journal.json as the file that decides what actually runs, and that a .sql file missing from it is silently skipped. - Documents the merge hazard concretely against the incident already in this repository's history: seven colliding 0001_* files and a journal entry with duplicate JSON keys, which left nine migrations unlisted and forced a squash back to a single baseline. - Gives the recommended conflict-resolution procedure - merge schema.ts, take the base branch's drizzle/ wholesale, drop your own migration, and regenerate - plus the checks that catch a collision before it lands. - Notes that drizzle/meta/ is Prettier-ignored because it is generated output. SECURITY.md - vulnerability disclosure policy: - Gives GitHub private vulnerability reporting as the private channel, with acknowledgement, triage, update, and fix windows. - States explicitly that vulnerabilities must not be reported through public issues, pull requests, or discussions, and why. - Defines scope across the backend, web client crypto, contracts, AI agent, and supply chain, with an explicit out-of-scope list and testing rules. - Cross-links docs/threat-model.md so reporters can tell an accepted residual metadata risk from a real finding. - Adds a contract-specific path: only token_transfer is upgradeable, so a bug in group_treasury or proposals cannot be fixed by a redeploy and funds already in a vulnerable instance may be unrecoverable. Closes codebestia#545 Closes codebestia#546 Closes codebestia#548
Adds apps/backend/docs/contracts-error-catalog.md, cataloguing every error shape the backend returns across both transports, plus the matching rows in the documentation index. Contents: - One REST table, deduplicated to a row per distinct (status, error) pair, listing the extra fields each carries and every route that emits it. Middleware-level errors are split into their own table since they can accompany any authenticated route. - The dynamic REST statuses that do not appear as literal res.status calls: the validateMessagePayload results behind POST /messages, and the checkEnvelopeProtocols 400/409 pair with its violations array. - Rate-limit responses, which do not have one shape: the standard rateLimit() middleware sets RateLimit-Limit/Remaining/Reset plus Retry-After, the upload byte quota sets only Retry-After, and the group-invite throttle sets no headers at all. Documents the safe client rule for reading a backoff from any of the three. - Socket errors, keyed by the emitted event value, including the condition-valued ones: device_set_mismatch, protocol_mismatch, rate_limited, envelope_too_large, device_revoked, and payload_too_large. Notes that rate_limited carries the throttled event in limitedEvent rather than event, and that envelope_too_large is a code value rather than an event value. - The two distinct socket error payload shapes: the dispatcher wraps its rejections in the standard event envelope, while the security middleware and every messaging handler emit a bare payload. Includes the normalising snippet a client needs to handle both. - Handshake failures, which arrive on connect_error as a plain Error rather than as an error event, so a client listening only on error sees nothing. - A retryable/terminal breakdown, including the cases where a naive retry is actively wrong: an auth nonce is single-use so a 401 there means restarting from the challenge, a message retry must reuse the same messageId to stay idempotent, and an MLS epoch conflict must be rebuilt against the returned currentEpoch. Two findings surfaced while cataloguing, documented rather than changed: there is no global Express error handler, so an exception escaping a route returns Express's HTML page instead of a JSON body; and auditLogsRouter is defined and tested but never mounted in app.ts, so its two errors are currently unreachable over HTTP. Closes codebestia#555
Documents every scheduled cleanup pass (device/key GC, envelope GC, file cleanup, and the push-subscription backoff re-enable) with schedule, retention window, and configuring env var per job, plus the crash-safe hard-delete ordering, the reference-counting check, and the implications of every job running unguarded on every gateway node.
Documents seed.ts and run.ts (flags, required local topology), the recorded metrics and pass/fail thresholds, what baseline.json represents and how to refresh it, and how to triage a failed nightly loadtest-nightly run.
Documents five failures contributors actually hit: pnpm install failing on the repo's mixed npm/pnpm and nested-workspace lockfiles, migrations silently not applying because the drizzle journal omits them, floating Node/Rust toolchains causing works-locally-fails-in-CI, tests interfering through shared module-level counters, and web build failures from the same lockfile drift. Grounded in real commits (46eee04, d60b648) and the actual repo state rather than hypotheticals.
Documents lib/logger.ts's pino configuration, level control via LOG_LEVEL, the redact-list backstop, and states the no-content rule explicitly with safe vs. unsafe logging examples. Documents the correlation fields available for tracing a request/socket event, and notes that logger.ts currently has zero import sites — all existing logging goes through console.* or a hand-rolled wrapper, and new code should use the structured logger instead of adding more console.* calls.
…ns-security docs: add testing strategy, migration workflow, error catalog, and security policy
docs: add GC jobs, load-testing, troubleshooting, and logging conventions guides
…s references Adds four reference documents: - apps/backend/docs/concepts-crypto-invariants.md covering lib/ciphertextInvariant.ts and lib/signalInvariants.ts, the forbidden field lists, the pre-database rejection ordering in the WebSocket handlers, why the Zod schemas are .strict(), and the security-ci regression job that keeps all of it enforced. - apps/backend/docs/concepts-nonce-lifecycle.md covering lib/nonce.ts: creation, single-use consumption and TTL for both the sign-in and the device-link challenge, why the two use separate namespaces, where the stores live across restarts and multiple nodes, and the replay resistance this provides and its limits. - apps/web/docs/components-treasury-wallet.md documenting ProposalCard, ProposeWithdrawalModal and WalletConnectButton with props, expected data, which actions hit the backend REST API versus Freighter and in what order, the wallet states a user can be in, and cross-links to the contracts docs for on-chain semantics. - apps/web/docs/hooks.md documenting useSocket, useInboundPipeline, useMessageHistory, useLocalSearch, useMessageSearchIndex and usePushSubscription with arguments, return shapes, side effects and cleanup, the single-owner versus multi-mount rules, the ordering dependency between useSocket and useInboundPipeline, and the SSR constraint on hooks touching window, IndexedDB or WebCrypto. Documentation only. No source or configuration changes.
…ts-nonce-frontend-reference docs: server-side crypto invariants, nonce lifecycle, treasury/wallet components and hooks reference
…and testing guides Adds four backend documents and indexes them in docs/README.md. concepts-protocol-negotiation.md (codebestia#557): the device capability payload shape, the sealed_box BASELINE_PROTOCOL applied to clients predating the field, how selectProtocol picks a mutually supported protocol, why the protocol is recorded per envelope rather than per device, the protocol_mismatch rejection and the client recovery steps, and how the whole mechanism supports a staged sealed_box to Signal rollout. concepts-replay-protection.md (codebestia#558): the two distinct layers of duplicate suppression - transport-level eventId dedup and message-level messageId idempotency - the device-scoped Redis key, the env-configurable TTL and its fail-open behaviour, the dispatch_ack duplicate flag, and the dispatcher path that applies the check to every registered handler. concepts-caching.md (codebestia#567): the conversation-list cache key, TTL and payload, every invalidateConversationCaches call site with its trigger, the degraded behaviour when Redis is unavailable, and the per-device scoping hazard created by a device-specific preview under a key that does not name the device. testing.md (codebestia#566): the backend companion to the cross-app testing guide - the standard route-test mock set with a copyable skeleton, the Drizzle chain-mocking traps, driving socket handlers through the enveloped dispatch event, adding service mocks when a route gains a dependency, and resetting shared in-process state between tests.
Adds four reference documents covering the AI agent service and the Soroban contract failure surface. apps/ai_agent/docs/operations.md (codebestia#586) - Production uvicorn command and worker sizing; why `python main.py` is the development path only. - /health semantics for orchestrators: liveness, not readiness. It stays 200 with no API key and with Weaviate down, so it must not gate a deploy. - Weaviate dependency: per-request connect/close, and the full behaviour matrix when it is unreachable. - Records the absence of rate limiting, auth, spend caps and max_tokens as a known operational risk, with the deployment-level mitigations required until controls exist in the application. apps/ai_agent/docs/concepts-prompts-and-models.md (codebestia#585) - Each prompt reproduced verbatim from main.py with the behaviour it is designed to produce. - Model per endpoint, and how to change one safely — including why changing the embedding model is a corpus migration, not a redeploy. - Output parsing per endpoint, with the transfer analyser's missing confidence/flagged defaults as the worked example, and why the two defaults deliberately fail in opposite directions. - States the privacy boundary: what is sent to OpenAI and what never leaves the system. apps/ai_agent/docs/testing.md (codebestia#584) - Each conftest fixture, what it patches and what it returns by default, including why mock_openai patches main.OpenAI. - Worked example adding an endpoint test using the fixtures. - Coverage configuration and how to read the report. - Notes the /index/message coverage gap with a case table so a contributor can pick it up. contracts/docs/contracts-errors.md (codebestia#580) - Every panic and error path across token_transfer, group_treasury and proposals, grouped by function. - Separates authorization, validation and state-machine violations (voting twice, approving after expiry, executing an unfinalised proposal). - Documents what a failure looks like from the frontend and how lib/soroban.ts callers should map it, branching on invocation stage rather than parsing panic strings. - Cross-links the frontend Soroban client doc. Verified against the source: the ai_agent suite was run to confirm the documented behaviour (35 passed, 82% coverage), and the coverage report and uncovered line range are the measured values. Testing the documented /index/message cases surfaced that a missing OPENAI_API_KEY returns 503 rather than 500 on both Weaviate endpoints, because the broad `except Exception` swallows the helper's HTTPException; all three affected docs record the actual behaviour.
…-replay-caching-testing docs(backend): protocol negotiation, replay protection, caching, and testing guides
…ontract-errors docs: AI agent operations, prompts/models, testing guide, and contract error reference
…bestia#556 codebestia#559 codebestia#561 Surface-level docs for configuration load order, Stellar listener reconciliation, backpressure tiers as actually wired, and the six already-made architecture decisions, so operators and reviewers have one place to look without duplicating the env-var catalog. Co-authored-by: Cursor <cursoragent@cursor.com>
…nd contribution workflow Closes codebestia#469 Closes codebestia#564 Closes codebestia#471 Closes codebestia#540
…59-561-backend-concepts docs: backend configuration, backpressure, Stellar listener, and ADR index
…store-contributing docs: group_treasury storage/multisig, local object store, and contribution workflow
Document every public function in group_treasury/src/lib.rs with full signatures, auth requirements, and panic conditions, plus a worked propose_withdraw -> approve_withdraw x N multisig example end-to-end. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Document the Redis presence key structure, the 30s/90s heartbeat timing contract, multi-device aggregation, and the debounced offline-broadcast behavior in services/presence.ts and services/heartbeat.ts, including verified caveats around the presence hash's lack of its own TTL. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Document the backend's role in device identity, prekey upload/consumption, key-bundle fetch, and revocation as one coherent lifecycle, including the two distinct device-registration paths (auth/verify vs. devices/link) and the verified gap that deviceKeyHistory is never written despite having a read route. States explicitly what the server can and cannot see. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Document every table, column, index, check constraint, and FK relation in db/schema.ts, with a mermaid ER diagram and a dedicated section on where Drizzle's relations() blocks diverge from actual DB constraints, plus verified schema gaps (unindexed conversation_members, unused content_type enum, non-unique files.sha256, FK-less audit_logs actor/subject columns). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
👋 Hi @Dannyorji, thanks for your contribution! Pull requests from contributors must target the This PR is being closed automatically. Please open a new PR (or retarget this one by reopening it after editing the base branch) against |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds four verified reference documents covering previously undocumented
surfaces of the contracts and backend codebases:
contracts/docs/api-group-treasury.md — full function-by-function API
reference for the
group_treasurySoroban contract (initialize,membership, deposit/withdraw, and the propose/approve/reject multisig
voting flow), including a worked end-to-end multisig example and an
explicit callout of the known off-by-one in
list_proposals/get_pending_proposals.apps/backend/docs/concepts-presence-heartbeat.md — the Redis presence
key structure, the 30s/90s heartbeat timing contract, multi-device
aggregation, and the debounced offline-broadcast behavior in
services/presence.tsandservices/heartbeat.ts, including a verifiedcaveat that the per-user presence hash has no TTL of its own.
apps/backend/docs/concepts-e2ee-key-management.md — the backend's role
in the E2EE key lifecycle end-to-end: the two distinct device-registration
paths (
auth/verifyvs.devices/link), prekey upload/consumption,key-bundle fetch, revocation, and GC, with an explicit "what the server
can and cannot see" statement and a verified finding that
device_key_historyis read but never written anywhere in the codebase.apps/backend/docs/contracts-database-schema.md — every table, column,
index, check constraint, and FK relation in
db/schema.ts, with a mermaidER diagram and a dedicated section distinguishing Drizzle's
relations()query helpers from actual DB constraints, plus several verified schema
gaps (unindexed
conversation_members, unusedcontent_typeenum,non-unique
files.sha256, FK-lessaudit_logsactor/subject columns).All four docs are cross-linked to each other and to the existing docs they
build on, and are indexed in
docs/README.mdper the repo's documentationmaintenance convention.
Closes #441
Closes #445
Closes #447
Closes #465