Here's what landed since the last update.

Todos

I need to start exercising the code with a dummy product feature, so I added a todo list feature to apps/demo. Lists group items. Items have a title, notes, status (open, in_progress, done), and an optional assignee who must be a tenant member. Lists and items each have their own capability set.

Trace Logging

core/tracelog collects JSON log lines and renders them as request-grouped traces:

2026-07-06 12:29:20  req-06FKH...  POST /Identity_Login  500  1ms
  +0s      INFO   http request  agent=curl/8.7.1  remote=[::1]:52161
  +638µs   ERROR  invalid credentials
  +638µs   ERROR  http response  error=invalid credentials  written=34

cmd/dev starts the server and tails its logs as traces in the same terminal. cmd/traces reads log files and renders them the same way. Dev and production see identical output.

Bot Bearer Keys

Bots now use a bearer token in the format <keyID>.<secret>. Only the SHA-256 hash of the secret is stored at rest. Keys expire after 24 hours by default.

Data Model Generator

apps/demo/tools/datamodel.go runs the migration stack against a throwaway database, introspects the resulting schema, and writes docs/data_model.md plus a Mermaid ER diagram. The output reflects what the migrations actually produce, not a hand-maintained description.

Tenant Members → Grants

The tenant_members table is gone. Tenant membership is now expressed through grants — no separate concept, no separate code. About 1,400 lines removed.