* feat(b3-6): contract drift — generated route, table and config-key indexes B3-6 item 9 (workstream 10). `check:server` already diffs the two generators; this adds a third for the three server contracts that only prose described until now. `Server/cmd/gendocs` rewrites one marked block per document: - `docs/api.md` "Route index (generated)" — 111 rows from `chi.Walk` over the production router built with uploads, voice and the GIF proxy on, the same scaffolding `api/absence_contract_test.go` uses. Carries that test's vacuity guards: fewer than 100 routes, or no `/admin/` route, fails the run. - `docs/schema.md` "Table index (generated)" — 34 rows from `sqlite_master` and `pragma_table_info` on an in-memory database with the migrations applied. sqlc exposes no catalog, so the migrated schema is the catalog. - `docs/server-configuration.md` "Key index (generated)" — 56 keys from the koanf struct tags, each mapped to the `###` section of the hand-written reference that names it. A key documented nowhere fails the run by name. Output is padded exactly the way Prettier formats a table, so the drift check and the hygiene gate agree instead of undoing each other. Wiring, copied from protocol-verify: `make docs-generate` / `make docs-verify`, a `DOCS_VERIFY` step in `check:server` and the generator in `generate` (`scripts/run.mjs`), a CI step on the ubuntu leg of `server-build-test`, and a `.githooks/pre-commit` block on router, handler, migration, config and generator paths. Everything hand-written in the three documents is untouched. The new `cmd/gendocs` file imports `db` for the catalog, so it takes a boundary row in the B3-0 inventory and `server-boundaries.md` is regenerated with it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KmiqjgTuov1stBTB6uGkvo * docs(b3-6): evidence block for item 9 (machine-readable contract drift) Records the three RED controls and their restore, the counts (111 routes, 34 tables, 56 config keys, 0 undocumented), and two corrections to the item's spec: the configuration reference table lives in docs/server-configuration.md, not docs/deployment.md, and sqlc exposes no catalog — the migrated in-memory schema is the catalog. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KmiqjgTuov1stBTB6uGkvo * fix(b3-6): gendocs — exclude ANALYZE artifacts, honest hook message, admin routes trigger the hook, generate order, width ceiling Review findings on item 9. 1. The table index dropped `sqlite_stat1` / `sqlite_stat4`. `db.Migrate` runs ANALYZE after applying migrations, so those hold planner statistics, not schema — and `sqlite_stat4` exists only because the current modernc.org/sqlite build has STAT4, so a driver bump would have failed the docs drift check on an unrelated dependency PR. Filtered with GLOB (LIKE's `_` is a wildcard), block regenerated, header line's justification corrected: 34 -> 32 tables. 2. The pre-commit message now covers both failure modes — stale blocks are regenerated and staged, a key the tool named as undocumented is documented in docs/server-configuration.md. 3. `Server/admin/.*\.go` added to the hook's trigger: the 34 `/admin/api/*` routes are registered there, not in api/router.go, so a new admin route could commit stale docs locally. 4. `run.mjs` `generate` runs gendocs after `sqlc generate` — gendocs compiles the api package, which imports db/dbgen. 5. The vacuity guard now requires a traversed `/admin/api/` subroute rather than any `/admin/` path, which the per-method mount catch-alls satisfied on their own, so its message is true. `writeTable` gained a comment naming its ceiling: padding counts runes, Prettier counts display width, so a full-width cell would diverge — none exists in the generated content. Evidence block updated for the new table count. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KmiqjgTuov1stBTB6uGkvo * fix(b3-6): gendocs — generate the route index from the full-tag build with telemetry on; the hook triggers on every api/ and admin/ Go file (Codex P2s on #1456) 1. `/metrics` was missing from the route index. It mounts only when `telemetry.PrometheusHandler()` returns non-nil (api/router.go:431-437), which needs the otel build tag AND telemetry enabled at runtime; the generator ran in the default build with telemetry unset, so the index omitted a production route. The route index is now the superset build. The scaffold config enables telemetry with the Prometheus exporter and the tool calls telemetry.Init the way main.go does, and every invocation passes -tags otel,wazero: Makefile docs-generate/docs-verify, scripts/run.mjs (DOCS_VERIFY and generate), .githooks/pre-commit, the regenCmd quoted into all three block header lines, and the CLAUDE.md row. ci.yml inherits it through `make docs-verify`. The route block's header line now says which build it came from and what is enabled. Rather than a build-tag constant, the tool checks the condition that actually gates the route: if telemetry.Init leaves no Prometheus handler it exits non-zero naming the tags, so the default build cannot quietly generate a short index. Nothing under Server/api or Server/admin carries a build constraint, so wazero adds and removes no route; it rides along so one build serves the whole repository. Route count 111 -> 121 (ten per-method rows for the /metrics mount, the same shape chi gives /admin and /livekit). 2. The pre-commit trigger named individual api/ files and missed client_update.go, whose MountClientUpdateRoute registers a route directly. It is now the whole of Server/api/ and Server/admin/ — naming files individually is how a trigger goes stale — plus the existing migrations/, config/config.go and cmd/gendocs/ patterns. Evidence block updated: route count and the tagged-build decision. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KmiqjgTuov1stBTB6uGkvo --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
OwnCord Architecture Blueprints
Verified against: commit 5630aa1, 2026-08-04
Companion audits: docs/audit-2026-08-04-docs-and-coverage.md (docs & coverage),
docs/audit-2026-08-04.md (security),
docs/audit-2026-07-19.md (architecture)
This directory is the curated architectural map of OwnCord — the "blueprints" for the whole system. Every diagram is a Mermaid fenced block (GitHub renders these natively) followed by a prose explanation and a Source of truth file list.
Index
| Doc | Diagrams | Covers |
|---|---|---|
| system-overview.md | D1 System context, D8 Deployment topology | All processes, trust boundaries, ports, single-instance constraints |
| server.md | D2 Server package map, D3 REST request lifecycle | Go package structure, DB-access styles, middleware chain |
| websocket.md | D4 WS connect / replay / dispatch | Real-time engine: auth handshake, 3-tier reconnect replay, backpressure, typed dispatch |
| data-model.md | D5 Entity-relationship overview | All 26 tables from migrations 001–028, grouped by domain |
| voice-e2ee.md | D6 Voice + E2EE flow | LiveKit token flow, loopback TLS tunnel, ECDH key-holder relay |
| client.md | D7 Client module map | Tauri client: bootstrap, dispatcher, stores, Rust sidecars (structure, as-built) |
| ux/ | UX flow + state diagrams | Client behavior spec (target state): what every view does and how it reacts to events, permissions, and failure |
| platform-contracts.md | — | Desktop/browser seam (target state): where native dependencies will be isolated, and the three that have no browser equivalent |
| server-boundaries.md | — | B3-0 inventory: every file above the domain layer that imports db, with a disposition and target family; hub setters, locks and the start/stop defer stack; the auth slice's before-graph. Generated table, enforced by db-import-boundary |
| plugins.md | — | Experimental WASM plugin boundary: off twice and compiled out of releases, no API promise, post-beta candidates, core that never moves |
Structure vs. behavior
client.md maps the client as-built (modules, stores, wiring). The ux/ set is the complementary behavior spec — prescriptive (to-be) flows for every view, with per-view state matrices and event→reaction maps. Where today's code diverges from the target, the UX docs carry dated ⚠ Current gap callouts, so the set doubles as a UX improvement backlog.
platform-contracts.md is a third kind again: a target seam map. It records where the desktop/browser boundary will be drawn and what crosses it, measured against today's code. The seam does not exist yet — B7 builds it — so read that document as a decision record, not as structure.
Maintenance rule
These documents are curated, not generated. The rule that keeps them honest:
If a PR changes the structure of anything listed in a diagram's Source of truth list (new package, new table, new message type, changed flow), that PR updates the corresponding diagram in the same change.
Diagrams reference stable identifiers (package names, table names, message-type strings) rather than line numbers wherever possible. Line-number evidence lives in the dated audit reports, which are point-in-time snapshots by design.
Relationship to other docs
docs/api.md,docs/protocol.md,docs/schema.mdare the reference specs (request/response shapes, wire formats, DDL). These blueprints describe structure and flow, not payload shapes. Known drift between the specs and the code is catalogued in the dated audit reports (latest: audit-2026-08-04-docs-and-coverage.md).docs/client-architecture.mdis a redirect stub kept for old links; client.md is the client architecture document.