Finalize user-engine contracts and operability

This commit is contained in:
2026-05-22 21:45:30 +02:00
parent b81a9e05da
commit ce2d620f4e
12 changed files with 392 additions and 15 deletions

49
docs/contracts.md Normal file
View File

@@ -0,0 +1,49 @@
# Public Contracts
## Headless Service Surface
`UserEngineService` is the stable in-process API for the current MVP. Future
HTTP or RPC adapters should preserve these operation names:
- `health`, `readiness`, `operability_snapshot`, `outbox_diagnostics`
- `me`, `create_user`, `set_account_status`, `link_identity`
- `resolve_tenant_context`, `set_tenant_account_status`, `add_membership`,
`tenant_diagnostics`
- `register_application`, `publish_catalog`
- `set_profile_value`, `effective_profile`, `projection`
- `audit_records`, `outbox_events`
## Error Taxonomy
- `ValidationError`: caller supplied an invalid shape, state transition, or
catalog/profile value.
- `AuthorizationDenied`: the authorization port or tenant boundary denied the
operation.
- `NotFoundError`: a requested user, account, or active attribute is missing.
- `ConflictError`: uniqueness or ownership would be violated.
## Catalog Contract
Catalogs are active by namespace and owning application. Attribute keys must
use the namespace prefix. Active namespace ownership cannot move to another
application. Catalog updates cannot move versions backwards or downgrade
attribute sensitivity.
## Projection Contract
Application runtime, agent-context, and claims-enrichment projections require
an `application_id` and are filtered to that application's active catalogs.
Sensitive and secret values are redacted outside admin, audit, and
self-service projections.
## Audit And Event Contract
Every mutating service operation appends an audit record and outbox event with
the same correlation id and resolved tenant. Authorization denials are audited
without emitting outbox events.
## Migration Contract
The isolated store exposes `SCHEMA_VERSION = 0001_initial` and a `migrate`
hook. Database-backed stores must expose equivalent readiness semantics before
they are accepted by platform adapters.

37
docs/final-assessment.md Normal file
View File

@@ -0,0 +1,37 @@
# Implementation Assessment
## Implemented
- Headless service API for users, accounts, identity links, applications,
catalogs, profiles, projections, audit records, and outbox events.
- Tenant context enforcement, tenant account state, memberships, tenant
profile precedence, tenant diagnostics, and cross-tenant denial.
- Multi-application catalog ownership, namespace collision protection,
semantic version checks, sensitivity downgrade prevention, app-filtered
projections, and claims-enrichment projection caching.
- Scenario fixtures and conformance-style tests for positive and negative
standalone, tenant, multi-app, redaction, audit, event, and cache paths.
## Boundary Verification
User-engine does not issue tokens, verify MFA, store credentials, act as the
policy decision point, own deployment, or provide a UI. It consumes verified
claims through an identity adapter, asks authorization through a port, emits
audit/outbox records, and exposes backend contracts for future UIs.
## Accepted Deviations
- The first persistence adapter is in-memory. It carries schema and migration
semantics but is not durable.
- The first API surface is in-process Python. HTTP/RPC transport adapters are
still future work.
- Metrics and cache diagnostics are local snapshots, not platform telemetry.
## Follow-Up Work
- Add a durable database adapter and migration tests.
- Add transport adapters with request/response contract tests.
- Add platform authorization, audit sink, secret provider, and outbox drain
adapters.
- Add release automation for SBOM, package build, static checks, and
deployment handoff.

39
docs/operability.md Normal file
View File

@@ -0,0 +1,39 @@
# Operability
## Diagnostics
Use `readiness()` for dependency checks and `operability_snapshot()` for
runtime counters and invariant checks. The snapshot currently reports store
readiness, audit correlation completeness, outbox diagnostic availability, and
counts for users, accounts, tenant accounts, memberships, applications,
catalogs, profile values, audit records, and pending outbox events.
## Structured Logs
Use `structured_log_context(correlation_id=..., tenant=..., actor=...)` as the
base log envelope. Adapters should add transport details around that envelope
without dropping correlation id or tenant.
## Outbox Drain
`outbox_diagnostics()` reports pending event count, event type counts, and the
oldest pending correlation id. A real outbox drain adapter should publish
events idempotently by `event_id`, retain `correlation_id`, and only mark
delivery after the sink acknowledges receipt.
## Cache Status
`ClaimsEnrichmentProjectionCache.status()` reports entry count and cached
tenant, application, and user keys. Token issuers must invalidate affected
users after profile, membership, or catalog changes before minting enriched
claims.
## Runbook Checks
1. Run `make test-conformance`.
2. Confirm `readiness().ready` is true.
3. Confirm `operability_snapshot().issues` is empty.
4. Confirm pending outbox events are either drained or expected for the local
environment.
5. Confirm production identity adapters reject local, expired, and
missing-tenant claims.

37
docs/release.md Normal file
View File

@@ -0,0 +1,37 @@
# Release And Compatibility
## Version
The current implementation is `0.1.0`: a headless MVP with standard-library
runtime behavior, local adapters, and conformance-style tests. Until `1.0.0`,
schema and service contracts may evolve, but changes should include migration
notes and scenario test updates.
## Packaging
The package uses a `src/` layout with setuptools metadata in `pyproject.toml`.
Build artifacts should be created from clean commits after `make test`,
`make test-scenarios`, `make test-integration`, and `make test-conformance`
pass.
## Security And SBOM
The current runtime has no third-party dependencies. Release automation should
still generate an SBOM for the Python package and run static/security scans
before publishing or deploying a platform adapter.
## Migration Policy
Persistence adapters must expose a schema version, readiness check, and
forward migration hook. Catalog updates must not move versions backwards or
downgrade sensitivity.
## Compatibility Guarantees
- Identity, authorization, secret, deployment, and UI ownership remain outside
user-engine.
- Application runtime projections require explicit application ids.
- Tenant-scoped operations require explicit tenant context once exposed over a
transport adapter.
- Outbox and audit correlation ids are part of the public integration
contract.

32
docs/ui-contracts.md Normal file
View File

@@ -0,0 +1,32 @@
# UI Handoff Contracts
Future self-service and scope-admin UIs should consume user-engine through a
transport adapter that preserves the service shapes below.
## Self-Service Account UI
Required backend operations:
- `me` to resolve the current actor, user, account, and identity links.
- `effective_profile` with the actor tenant and optional application id.
- `projection` with `SELF_SERVICE` for editable user-visible fields.
- `set_profile_value` for fields whose catalog mutability includes `USER`.
- `audit_records` or a filtered audit transport for recent user-visible
account activity.
## Scope Admin UI
Required backend operations:
- `resolve_tenant_context` before all tenant-scoped screens.
- `set_tenant_account_status` for in-scope account state.
- `add_membership` for tenant/team membership changes.
- `projection` with `ADMIN` or a future admin transport projection.
- `tenant_diagnostics` for onboarding and support readiness checks.
## Fixtures
Use `user_engine.testing.scenarios` for human, tenant admin, platform
operator, delegated agent, invalid, expired, local issuer, and missing-tenant
fixtures. UIs should keep fixtures at the transport boundary and avoid
embedding identity-provider logic.