Invariants
Eleven rules the database enforces, whatever the app or an agent tries.
These rules are enforced in Postgres, not only in the UI. Each one has a test that tries to break it and checks that the write is refused.
| # | Rule, in plain words | How it is enforced |
|---|---|---|
| 1 | Only the store can change a module's billing state, tier, AI add-on or period end. | Those columns can only be written with the service role; owners may only flip enabled. |
| 2 | New modules start locked, and a locked module cannot be switched on. | Column default plus a guard trigger on workspace modules. |
| 3 | A module that is locked, disabled or set to none for you shows no rows at all. | One access helper (so_can_access) in every read policy. |
| 4 | Approving, launching or aborting a mission needs publish. The approver and launcher are always recorded as the person doing it, and a launch needs an approval first. | Mission guard trigger. |
| 5 | No launch with a grounded unit, a battery reserve under 20 %, or an altitude above 120 m without a waiver. | Check constraints plus the mission guard trigger. |
| 6 | Vehicle commands need publish on Fleet, are recorded under the caller's own name, and agents can never send them. | Insert policy that pins issued_by to the caller, plus the agent cap. |
| 7 | Releasing a unit to service needs publish on Maintenance and must be done by someone other than the technician who did the work. | Work order guard trigger (four-eyes). |
| 8 | Flight logs are append-only: nobody can edit or delete one after it is written. | No insert, update or delete grants for signed-in users; the system writes them. |
| 9 | You can only mark your notifications as read; you cannot rewrite them. | Column-level grant on read_at only. |
| 10 | Audit entries are always written as the caller; nobody can forge one for another person, an agent or the system. | Insert policy. |
| 11 | Only owners and admins change module access, and agents never go above edit. | Policies plus a module access guard trigger. |
The limits in rule 5 come from the shared rules package (LIMITS). They are defaults, not legal advice; check the rules in your country.
See also Security.