diff --git a/.claude/rules/architecture.md b/.claude/rules/architecture.md index 7c2a645..486a49b 100644 --- a/.claude/rules/architecture.md +++ b/.claude/rules/architecture.md @@ -1,7 +1,30 @@ ## Architecture - +Headless Engine (PIP) for users, accounts, and memberships. Same +authoritative inputs yield the same result. `access-engine` (`flex-auth`) +is the only decision point; this service supplies claims and enforces +results on its own mutations (PEP-shaped, same layer). + +```text +verified IAM Profile claims + -> UserEngineService (domain facts, projections, outbox) + -> adapters: Postgres store, flex-auth /v1/check, tenant-engine, + provisioning, registration verification, event/mail delivery +``` + +- `domain/` — persistence-neutral schemas. No HTTP, DB, or SDK imports. +- `ports.py` — adapter protocols (store, identity claims, authorization, + provisioning, tenant management, secrets, outbox). +- `service.py` — headless API. Protected mutations go through `_authorize` + then `_record_mutation` in one store transaction. +- `adapters/` — Postgres, flex-auth (fail-closed), OIDC claims, HTTP + neighbors. `LocalAuthorizationCheckPort` is a standalone/test double. +- `runtime.py` / `web.py` — optional WSGI portal over the same APIs. +- `layer.yaml` + `pep-stance.yaml` — security-layer declaration and + unreachable-engine stance. + +Boundary contract: +`~/net-kingdom/canon/standards/user-engine-boundary-contract_v0.1.md`. ## Quick Reference diff --git a/.claude/rules/first-session.md b/.claude/rules/archived/first-session.md similarity index 92% rename from .claude/rules/first-session.md rename to .claude/rules/archived/first-session.md index 200b874..4953eee 100644 --- a/.claude/rules/first-session.md +++ b/.claude/rules/archived/first-session.md @@ -1,5 +1,8 @@ ## First Session Protocol +**Retired 2026-08-29.** Work is structured (USER-WP-0001–0024). Kept as +history; do not run. Active session flow is `session-protocol.md`. + Triggered when `get_domain_summary("communication")` shows **no workplans**. The project is registered but work has not yet been structured. diff --git a/.claude/rules/session-protocol.md b/.claude/rules/session-protocol.md index dc9e68e..d546088 100644 --- a/.claude/rules/session-protocol.md +++ b/.claude/rules/session-protocol.md @@ -52,7 +52,8 @@ For each file with `status: ready`, `active`, or `blocked`, note pending 4. **Suggested next action** — highest-priority open item 5. **SBOM status** — flag if `last_sbom_at` is unset for this repo -If no workplans: follow First Session Protocol (`first-session.md`). +Work is already structured (USER-WP-0001–0024). The first-session +protocol is archived at `.claude/rules/archived/first-session.md`. **During work:** `record_decision()` · `add_progress_event()` · `resolve_decision()` diff --git a/.claude/rules/stack-and-commands.md b/.claude/rules/stack-and-commands.md index dc53ac6..f0ed1be 100644 --- a/.claude/rules/stack-and-commands.md +++ b/.claude/rules/stack-and-commands.md @@ -1,19 +1,28 @@ ## Stack - -- **Language:** -- **Key deps:** +- **Language:** Python 3.12+ (`requires-python = ">=3.12"`) +- **Layout:** `pyproject.toml` + `src/user_engine/` + stdlib `unittest` +- **Runtime:** optional extras only — `psycopg[binary]` (Postgres store), + `PyJWT[crypto]` (OIDC). Core domain and in-memory adapters have no + third-party deps. +- **Entry point:** `user-engine-portal` → `user_engine.runtime:main` ## Dev Commands ```bash -# TODO: Fill in the standard commands for this repo +# Orient +cat .custodian-brief.md +cat INTENT.md +cat SCOPE.md +ls workplans/ -# Install dependencies +# Tests and layer check +make test +make check-layer -# Run tests +# Optional extras +pip install -e ".[runtime]" -# Lint / type check - -# Build / package (if applicable) +# After workplan or registry edits +statehub fix-consistency ``` diff --git a/CLAUDE.md b/CLAUDE.md index 9137fe6..f0605a0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -3,7 +3,6 @@ @SCOPE.md @.claude/rules/repo-identity.md @.claude/rules/session-protocol.md -@.claude/rules/first-session.md @.claude/rules/workplan-convention.md @.claude/rules/stack-and-commands.md @.claude/rules/architecture.md diff --git a/SCOPE.md b/SCOPE.md index 7abe43c..0cc2663 100644 --- a/SCOPE.md +++ b/SCOPE.md @@ -103,9 +103,10 @@ not become hidden sources of profile or identity-domain truth. user-engine must not become a hidden source of authorization truth. Memberships, hats, and access-control facts are claims. `access-engine` renders the decision. When `access-engine` is unreachable, shipped -behaviour is fail-closed for protected mutations; that stance still has -to be published, tested equal to the code, and recorded as stance -application rather than as a minted local decision id. +behaviour is fail-closed for protected mutations. That stance is published +in `pep-stance.yaml`, tested equal to `FlexAuthHTTPAdapter`, and recorded +as stance application (`decision_id` absent) rather than as a minted +local decision id. Governing published contracts: