identity: membership state machine + per-app grant projection (17 tests)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 28s

membership.sx — coop membership as a guarded state machine
(none→pending→active→lapsed⇄active, any→revoked terminal); invalid
transitions return explicit {error, CurrentStatus}, never silent no-ops.
project(Subject, App) renders the one canonical state into a per-app claim
({member,Tier,App} / {pending,App} / {lapsed,App} / {denied,App} /
{non_member,App}) — identity reports what the membership is; acl decides
whether the app should honour it. New tests/membership.sx. 92/92.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-07 00:54:51 +00:00
parent 56cf920041
commit dc00ed9786
6 changed files with 206 additions and 6 deletions

View File

@@ -19,7 +19,7 @@ through the event log, all authorization questions delegated to `acl-on-sx`.
## Status (rolling)
`bash lib/identity/conformance.sh`**75/75** (Phases 12 + silent SSO)
`bash lib/identity/conformance.sh`**92/92** (Phases 12 + SSO + membership)
## Ground rules
@@ -69,7 +69,7 @@ lib/identity/api.sx ── (identity/login) (identity/grant?) (identity/revoke)
## Phase 3 — Silent SSO + membership
- [x] `prompt=none` cross-app login (one session, many clients)
- [ ] membership state + per-app grant projection
- [x] membership state + per-app grant projection
- [ ] grant verification delegated cache (mirror Redis-cache pattern)
## Phase 4 — Audit + federation
@@ -78,6 +78,13 @@ lib/identity/api.sx ── (identity/login) (identity/grant?) (identity/revoke)
- [ ] tests: audit completeness, cross-instance subject mapping
## Progress log
- 2026-06-07 — `membership.sx`: coop membership as a guarded state machine
(none→pending→active→lapsed⇄active, any→revoked terminal); invalid
transitions are explicit `{error, CurrentStatus}`. `project(Subject, App)`
renders the one canonical state into a per-app claim
({member,Tier,App}/{pending,App}/{lapsed,App}/{denied,App}/{non_member,App})
— identity reports what; acl decides whether. New tests/membership.sx (17).
+17 → 92/92.
- 2026-06-07 — silent SSO (`prompt=none`, OIDC §3.1.2.1): `oauth.sx` now owns
a session registry; `establish` creates a subject session, `silent_authorize`
asks "does this subject have a live session?" → mints a code (skipping