Commit Graph

2 Commits

Author SHA1 Message Date
knacky
48a1c756bf feat(backend): add USER_MANAGE permission + delta migration (D-015)
Adds `Permission.USER_MANAGE = "user.manage"` to the F11 matrix. rt_lead
already holds ALL_PERMISSIONS so GROUP_PERMISSIONS is unchanged — rt_lead
gets the new permission automatically, rt_operator and soc_analyst get 403.

Alembic migration `202605230001_add_user_manage_permission`:
- inserts the `user.manage` row into `permission`,
- inserts the `(rt_lead, user.manage)` link into `group_permission`,
- exposes `_DELTA_PERMISSIONS` / `_DELTA_GROUP_PERMISSIONS` for parity tests.

The previous `test_frozen_*_matches_runtime` invariant (MA3) is generalised
to "runtime = initial frozen ∪ deltas of every migration in `_DELTAS`". New
migrations register themselves there without editing the historical one.

Verbatim wording from spec-analyst is recorded as D-015 in
`tasks/spec-decisions.md` (separate commit).
2026-05-23 15:52:47 +02:00
knacky
36c1ed5ffb fix(backend): freeze F11 matrix inline in the initial migration (MA3)
Code-review MAJOR MA3. The initial Alembic migration imported the live
`mimic.rbac.matrix.GROUP_PERMISSIONS` to seed the `permission` / `group` /
`group_permission` rows. That breaks the Alembic invariant "a migration
produces the same schema regardless of when you replay it": a future tweak
to the runtime matrix would silently change the seeded baseline on a fresh
DB.

Two changes:

1. The migration now carries an *inline frozen snapshot* of the F11 matrix
   (`_PERMISSIONS_FROZEN`, `_GROUP_PERMISSIONS_FROZEN`, `_GROUP_DESCRIPTIONS`).
   The seed reads from these tuples/dicts only. If the canonical matrix
   evolves, the next migration is responsible for the delta.

2. A new unit test `test_migration_seed_matches_current_matrix` enforces
   that the frozen seed equals the runtime `Permission` enum and
   `GROUP_PERMISSIONS` mapping. Drift now fails CI loudly with a hint to
   write a new migration instead of editing the existing one.

Also: docstring no longer mentions `ttp_version` (M8 follow-up).
2026-05-22 05:24:37 +02:00