Decisions¶
Dated records of design choices: what was decided, what was tried first, and why. They explain the code as it is and stop settled questions from being reopened by accident. Read the record for an area before changing it, and before rebuilding anything a record says was retired.
A record describes the moment it was written. When a later decision replaces it, the old record stays and gains a link to the new one. How to write one is in Writing documentation.
Platform and tooling¶
- JavaScript ships without a build step (2026-02-28)
- Ruff replaces black, isort, pycln and flake8 (2026-03-10)
ENVis a switch of its own, notDEBUG(2026-06-24)- Local storage by default, media unrouted, the logo excepted (2026-08-03)
- Shared state lives in the database cache, not the default one (2026-08-17)
- Civil dates come from
timezone.localdate()(2026-08-25) - A failing queue task stops after ten attempts (2026-08-25)
- Schema the migrations do not own (2026-09-30)
- Reference pages are generated and drift-tested (2026-10-01)
- Three branches, and the checks run locally (2026-10-05)
Front-end conventions¶
- Visibility and polling inside htmx swaps (2026-07-29)
- A list's sort key is checked on write and again on read (2026-10-02)
- How a modal closes and how toasts stack (2026-10-05)
- Yes/No selects, not checkboxes, over one
YESNO_CHOICES(2026-10-05)
Access, matters and contacts¶
- The in-form client wizard keeps its draft in the session (2026-07-01)
- The matter owns the client relationship (2026-07-02)
- Closing a matter unlinks its mirrors and starts the chat clock (2026-08-01)
- Drive folder mappings replace the per-proceeding folder link (2026-08-21)
- Matter membership is enforced from the URL (2026-10-01)
- Wrong sign-in codes are counted on the code, not the session (2026-10-01)
- The last active administrator cannot be demoted or deactivated (2026-10-02)
- The Reports permission alone opens the reports, and starts off (2026-10-02)
- What deleting a matter or a contact removes (2026-10-02)
- The "two shells" redesign is abandoned (2026-10-05)
- Sign in by email, an authenticator app in place of the emailed code, a cooldown per address, and no Django admin (2026-10-08)
Tasks, calendar, email and intakes¶
- An event's location is one short line (2026-07-07)
- Client forms replace the website questionnaire (2026-07-25)
- Intake email: forwarding rules and canned replies (2026-07-28)
- The Gmail mirror: one mailbox per user, Gmail is the archive (2026-07-31)
- Quick add never guesses a matter, and AI entry is a firm opt-in (2026-08-04)
- Tasks panel retired, user chips stay (2026-08-04)
- Date presets are re-derived from their label on every read (2026-08-07)
- Google Calendar sync: Kosmos wins on conflicts (2026-10-02)
Billing and trust¶
- Online payments: provisional until settled, and the processor switch (2026-06-25)
- Trust available: client-level, pending, computed in one place (2026-07-03)
- Invoice emails carry a link, and the stored PDF is what the link serves (2026-07-10)
- One category per time entry, folder-style, not labels (2026-07-16)
- Work on a draft invoice is work in progress, not unbilled (2026-10-02)
- Fee-agreement wording lives on the Firm record, not in templates (2026-10-02)
- A payment's side effects are changed through the payment, never by cascade (2026-10-02)
- Retainer plans are abandoned; the billing arrangement stays per matter (2026-10-05)
AI and research¶
- Scheduled AI jobs run only when ENV is prod (2026-07-30)
- AI writes are fenced blocks, applied at once (2026-08-09)
- Effort tiers and answer streaming, tried and reverted (2026-08-14)
- AI chat runs on threads, research runs on the queue (2026-08-17)
- The user picks which cases a research run reads (2026-08-18)
- The token estimate is 2.5 characters per token (2026-08-20)
- What the AI says about money follows what the screens show (2026-10-02)
- The Plan chat and the nightly auto threads are retired (2026-10-06)
- The Research tab is retired (2026-10-06)
- AI is optional (2026-10-06)
- Claude Desktop: packaging roadmap
- Research Chat (retired 2026-08-16)