ARCH-01 — Concurrency-safe platform.bootstrap grant succession #823

Open
opened 2026-07-22 19:41:36 -05:00 by jcwalker3 · 0 comments
Owner

Candidate architecture requiring executable validation; not yet approved, production-ready, or certified.

Parents: #820, #821. Depends on: #822 (kernel + platform_active_invariant).

1. Summary / objective

Define and implement concurrency-safe succession of platform.bootstrap grants: grant, replace, (optionally) suspend, (optionally) expire, and revoke, such that at least one active grant always remains and no two concurrent transactions can drive the active count to zero.

2. Security/correctness problem

The platform root is the top of the authority lattice. If succession is not serialized on a shared invariant, two transactions can each observe two active grants and revoke different ones (write-skew), leaving zero active roots and bricking all authority. Expiry/suspension add the same hazard.

3. Threat model / failure modes

Write-skew last-grant revocation; concurrent replacement; expiry firing to zero; suspension of the last active grant; grantor-revocation cascade; raw-write reactivation of a revoked grant; resurrection via UPDATE.

4. In-scope behavior

  • Define "active grant" precisely, including whether expiry and suspension exist. Recommended baseline: grants do not silently expire; suspension is explicit and blocked when it would zero the active set.
  • Serialize every state change on the singleton platform_active_invariant row (or an equivalent global lock), maintaining active_count transactionally. [SCHEMA] for the active_count>=1 CHECK; [TRUSTED-SERVICE]/[SCHEMA] for the serialization.
  • Exact replacement transaction: grant-new then revoke-old within one serialized transaction; never revoke-then-grant.
  • Grantor-revocation effects: revoking a grantor does not retroactively invalidate grants it already made (they are separate rows), but is audited.
  • Self-delegation (platform.bootstrap → platform.bootstrap) permitted only to preserve authorized succession (seeded immutable lattice edge from #822).
  • Historical grants immutable and append-only (no_grant_resurrection, no_grant_delete).

5. Exclusions

No supervisor-grant succession (separate), no project.admin (ARCH-03), no evidence, no workspaces.

6. Schema/operation contracts

platform_bootstrap_grants (from #822) + platform_active_invariant singleton. Operations: grant_platform_bootstrap, revoke_platform_bootstrap, replace_platform_bootstrap, optional suspend_platform_bootstrap/resume. Each updates active_count under the invariant lock.

7. SQLite behavior

BEGIN IMMEDIATE; read-modify-write active_count on the singleton row; revoke/suspend rejected when result <1.

8. PostgreSQL behavior

SELECT active_count FROM platform_active_invariant FOR UPDATE; SERIALIZABLE with retry; losing transaction returns LAST_PLATFORM_GRANT or SERIALIZATION_RETRY. Backend-specific expected errors documented.

9. Concurrency / transaction requirements

Two concurrent revocations that each saw two active grants: exactly one succeeds, the other returns LAST_PLATFORM_GRANT. No interleaving reaches zero active grants.

10. Structured results

GRANTED, REVOKED, REPLACED, SUSPENDED, RESUMED, LAST_PLATFORM_GRANT, SERIALIZATION_RETRY, GRANT_RESURRECTION_FORBIDDEN, AUTHORIZATION_DENIED.

11. Enforcement classification

active_count>=1 CHECK and append-only immutability [SCHEMA]; serialization discipline [TRUSTED-SERVICE] on SQLite / [SCHEMA]-adjacent via FOR UPDATE on PG.

12. Acceptance criteria

  1. Grant succeeds and increments active_count.
  2. Revoke of a non-final grant succeeds and decrements.
  3. Revoke of the final active grant → LAST_PLATFORM_GRANT.
  4. Concurrent last-grant revokes → one success, one LAST_PLATFORM_GRANT (no zero state).
  5. Replacement is atomic; no window with zero active grants.
  6. Suspension/expiry cannot zero the active set.
  7. Revoked grant cannot be reactivated (raw UPDATE fails).
  8. Grants cannot be deleted.
  9. All grant/replace/suspend/expire/revoke events audited.

13. Named tests

t_grant(+), t_revoke_nonfinal(+), t_revoke_final(−), t_concurrent_last_revoke(concurrency/write-skew, both backends), t_replace_atomic(concurrency), t_suspend_last(−), t_grant_resurrect(raw-bypass), t_grant_delete(raw-bypass), t_audit_succession(+).

14. Audit events / evidence

platform_grant_granted, platform_grant_revoked, platform_grant_replaced, platform_grant_suspended, platform_grant_expired. Test-run output is durable evidence.

15. Dependencies / parent

Parents #820, #821; depends on #822.

16. Definition of done

Executable on SQLite and PostgreSQL; ACs pass incl. write-skew on both backends; bounded PR; author does not self-review/merge.

17. Known limitations / deferred

Supervisor-grant and project.admin succession are out of scope. If expiry is adopted, a scheduled reaper is a separate concern and must itself honor the invariant.

**Candidate architecture requiring executable validation; not yet approved, production-ready, or certified.** Parents: #820, #821. Depends on: #822 (kernel + `platform_active_invariant`). ## 1. Summary / objective Define and implement concurrency-safe succession of `platform.bootstrap` grants: grant, replace, (optionally) suspend, (optionally) expire, and revoke, such that **at least one active grant always remains** and no two concurrent transactions can drive the active count to zero. ## 2. Security/correctness problem The platform root is the top of the authority lattice. If succession is not serialized on a shared invariant, two transactions can each observe two active grants and revoke different ones (write-skew), leaving zero active roots and bricking all authority. Expiry/suspension add the same hazard. ## 3. Threat model / failure modes Write-skew last-grant revocation; concurrent replacement; expiry firing to zero; suspension of the last active grant; grantor-revocation cascade; raw-write reactivation of a revoked grant; resurrection via UPDATE. ## 4. In-scope behavior - Define "active grant" precisely, including whether expiry and suspension exist. Recommended baseline: grants do **not** silently expire; suspension is explicit and blocked when it would zero the active set. - Serialize every state change on the singleton `platform_active_invariant` row (or an equivalent global lock), maintaining `active_count` transactionally. `[SCHEMA]` for the `active_count>=1` CHECK; `[TRUSTED-SERVICE]`/`[SCHEMA]` for the serialization. - Exact replacement transaction: grant-new then revoke-old within one serialized transaction; never revoke-then-grant. - Grantor-revocation effects: revoking a grantor does not retroactively invalidate grants it already made (they are separate rows), but is audited. - Self-delegation (`platform.bootstrap → platform.bootstrap`) permitted only to preserve authorized succession (seeded immutable lattice edge from #822). - Historical grants immutable and append-only (`no_grant_resurrection`, `no_grant_delete`). ## 5. Exclusions No supervisor-grant succession (separate), no project.admin (ARCH-03), no evidence, no workspaces. ## 6. Schema/operation contracts `platform_bootstrap_grants` (from #822) + `platform_active_invariant` singleton. Operations: `grant_platform_bootstrap`, `revoke_platform_bootstrap`, `replace_platform_bootstrap`, optional `suspend_platform_bootstrap`/`resume`. Each updates `active_count` under the invariant lock. ## 7. SQLite behavior `BEGIN IMMEDIATE`; read-modify-write `active_count` on the singleton row; revoke/suspend rejected when result `<1`. ## 8. PostgreSQL behavior `SELECT active_count FROM platform_active_invariant FOR UPDATE`; `SERIALIZABLE` with retry; losing transaction returns `LAST_PLATFORM_GRANT` or `SERIALIZATION_RETRY`. Backend-specific expected errors documented. ## 9. Concurrency / transaction requirements Two concurrent revocations that each saw two active grants: exactly one succeeds, the other returns `LAST_PLATFORM_GRANT`. No interleaving reaches zero active grants. ## 10. Structured results `GRANTED`, `REVOKED`, `REPLACED`, `SUSPENDED`, `RESUMED`, `LAST_PLATFORM_GRANT`, `SERIALIZATION_RETRY`, `GRANT_RESURRECTION_FORBIDDEN`, `AUTHORIZATION_DENIED`. ## 11. Enforcement classification `active_count>=1` CHECK and append-only immutability `[SCHEMA]`; serialization discipline `[TRUSTED-SERVICE]` on SQLite / `[SCHEMA]`-adjacent via `FOR UPDATE` on PG. ## 12. Acceptance criteria 1. Grant succeeds and increments active_count. 2. Revoke of a non-final grant succeeds and decrements. 3. Revoke of the final active grant → `LAST_PLATFORM_GRANT`. 4. Concurrent last-grant revokes → one success, one `LAST_PLATFORM_GRANT` (no zero state). 5. Replacement is atomic; no window with zero active grants. 6. Suspension/expiry cannot zero the active set. 7. Revoked grant cannot be reactivated (raw UPDATE fails). 8. Grants cannot be deleted. 9. All grant/replace/suspend/expire/revoke events audited. ## 13. Named tests `t_grant`(+), `t_revoke_nonfinal`(+), `t_revoke_final`(−), `t_concurrent_last_revoke`(concurrency/write-skew, both backends), `t_replace_atomic`(concurrency), `t_suspend_last`(−), `t_grant_resurrect`(raw-bypass), `t_grant_delete`(raw-bypass), `t_audit_succession`(+). ## 14. Audit events / evidence `platform_grant_granted`, `platform_grant_revoked`, `platform_grant_replaced`, `platform_grant_suspended`, `platform_grant_expired`. Test-run output is durable evidence. ## 15. Dependencies / parent Parents #820, #821; depends on #822. ## 16. Definition of done Executable on SQLite and PostgreSQL; ACs pass incl. write-skew on both backends; bounded PR; author does not self-review/merge. ## 17. Known limitations / deferred Supervisor-grant and project.admin succession are out of scope. If expiry is adopted, a scheduled reaper is a separate concern and must itself honor the invariant.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Scaled-Tech-Consulting/Gitea-Tools#823