Files
member-console/docs
cgalo5758 e52fdb37c8 Build every advisory key from its family, and take locks only through the helpers
Second of two changes for #186; closes it. Each kind of object the
console serializes on now has a family, and every advisory key is built
one way: hashtextextended('<family>:<id>', 0), with a UUID written in
canonical form. db.Lock and db.LockShared (internal/db/locks.go) build
the key and take the lock on a *sql.Tx only, and each family's
statement begins with a name line, so pg_stat_activity and the test
traces show which family a backend waits on.

Families, in the order a transaction takes them: materialization,
domains-registry, fedwiki-workspace, lifecycle, stripe-subscription,
stripe-invoice, stripe-product-sync, desired-state. The lifecycle and
desired-state keys are unchanged byte for byte; the other six change.
Migration 00040 replaces core.assert_rendezvous to look for the new
materialization key (owner, grants, SECURITY DEFINER and search_path
kept; Down restores migration 18's body), and both seeds take the new
key right after BEGIN.

docs/database-locks.md lists the families in a table and writes one
order every path keeps: the materialization lock first, then the
families in table order, then rows. The project lint gains
advisory-lock-site (an advisory lock function named in a Go string or
in SQL or shell code outside the helpers, the test kit's probe, the
migrations that name the rendezvous and the rule's own tests; a seed
taking any other key, or the rendezvous anywhere but first after
BEGIN), pool-lock-site (a core.resource_pools row lock outside
LockResourcePool and LockGrantPool, or a call or method value of those
outside entitlements/tx.go) and lock-families (the doc's table against
the code). The walk covers cmd/, scripts/, internal/, test/ and the
root's Go files, and skips testdata and directories whose name begins
with a dot, as the go tool does. Tests take a family's lock through the
same helpers and probe one with dbtest.TryLock.

Recording a lifecycle request comes in two forms:
RecordLifecycleRequest opens its own transaction on a database or a
pinned connection, and RecordLifecycleRequestInTx runs in the caller's
*sql.Tx, so a connection is never used outside a transaction (which
released the instance lock at once) and does not compile in the second.
The same holds for RecordFirstLifecycleRequest.

docs/production-deployment.md now states the upgrade order for every
upgrade: stop every process of the running release, run migrate up if
migrations run separately, then start the new release; two releases
running at once can build different keys for one lock and share none.
docs/go-conventions.md, docs/testing.md and
docs/building-an-integration.md follow the code. The lint command's
help text names the files the lock rules read. 202 golden lines in 109
files change their statement text.

Deploy: stop every process of the previous release first. Rollback:
stop this release; as the migration user, in one transaction, run
00040's Down section and DELETE FROM goose_db_version_core WHERE
version_id = 40; start the previous release (migrate down rolls back
the last integration stream first). A deployment using console_reader
re-runs scripts/db-reader-role.sql.

Break list: 35 records, 35 CAUGHT. Named without a record: the *sql.Tx
parameters of the helpers and the -InTx forms (a break that passes a
connection does not compile, and the build is the check), and the
comments. Full suite on reset databases: 5727 passed, 16 skipped, none
failed.
2026-10-31 04:03:32 -05:00
..
2026-09-07 21:32:14 -05:00

title, audience, summary
title audience summary
Documentation index
developer
admin
user
Index of member-console documentation, grouped by audience, plus the front-matter convention every doc follows.

Documentation

Every document in this directory carries YAML front matter declaring its audience, so readers can find what's for them and contributors know who they're writing for.

Front-matter convention

Start each doc with a front-matter block:

---
title: "Human-readable title"
audience: [admin, developer]   # one or more of: developer, admin, user (primary first)
summary: "One sentence describing what the doc covers."
---

The three audiences:

  • developer — contributing to or understanding the codebase: architecture, design decisions, dev setup, testing, UX research and conventions, the provider-extension contract.
  • admin — hosting and operating an instance: installing, configuring an identity provider, building the image, generating secrets, running the service.
  • user — the general public or a member using a running service. (None yet — the tag is reserved for member-facing docs.)

List the primary audience first; a doc may name more than one.

For administrators — hosting & operating

For developers — contributing & internals

  • Database Management — goose migrations and sqlc.
  • Database Locks — every advisory and serializing row lock, how each key is built, and the order each path takes them in.
  • Design System — UI conventions.
  • Domain Model Cards — the model catalog: one card per domain model with invariants, dimensions, and traps.
  • FedWiki Integration — provisioning via the FarmManager API.
  • Go Conventions — where a rule and an act live, transactions and locks, services that answer after the listener opens, output order, error handling, and dead code.
  • HTMX Setup — HTMX under a strict CSP.
  • Identifiers — IDs, names, and keys: which entities carry a key, its grammar and scope, and how seeds and lookups use it.
  • Operator Information Architecture — the operator panel's IA contract.
  • Operator UX Conventions — form and action conventions.
  • First-Contact UX Walk Process — the repeatable method for walking the console as a stranger.
  • First-Contact UX Rubric — the instrument that method scores with: the A–G question bank, the walker protocol, and the screen coverage checklist.
  • Agent Runner — how an agent from another model family reviews or ideates on the code inside a disposable copy: what contains it, how a task is shaped, and what a finding must carry before it counts.
  • Operator UI Accessibility Baseline — what operator-UI changes are diffed against.
  • Building an Integration — adding a new integration.
  • Testing — the test taxonomy and how to run each kind, plus the gates: make lint (page-anatomy rules and the Go static checks) and make screens (contact sheets at two widths).

For users

No member-facing documentation yet.

One page per rule

A rule is written on the one page that owns it. Another page that needs the rule links to that page instead of restating it, because two copies of a rule are edited separately and drift apart.

Where things are not

Research, drafts, audits, walkthrough evidence, and other records of how a decision was reached are not documentation; they stay in a local notebook that git ignores, so a clone never carries them. When a decision lands, whatever a reader still needs is written into this directory, which holds the result without the history. The rule for every kind of file is in status/MAINTAINING.md.