diff --git a/Repo-docs-ACCESS-EXTRACTION-PLAN.-.md b/Repo-docs-ACCESS-EXTRACTION-PLAN.-.md new file mode 100644 index 0000000..731313e --- /dev/null +++ b/Repo-docs-ACCESS-EXTRACTION-PLAN.-.md @@ -0,0 +1,410 @@ + + +> Mirrored from `/mnt/DATA/git/govoplan-core/docs/ACCESS_EXTRACTION_PLAN.md`. +> Origin: `repository`. +> Active tasks and changing state belong in Gitea issues; this wiki page is durable project context. + +--- +# GovOPlaN Access Extraction Plan + +> Backlog state migrated to Gitea issues on 2026-07-06. Keep this document as +> durable extraction context and architecture notes. Track active tasks, +> decisions, blockers, and implementation state in `add-ideas/govoplan-core` +> issues with `module/access` and `source/backlog-import`. + +This plan describes how to extract access, authentication, RBAC, and related +administration behavior from the current compatibility core into a dedicated +`govoplan-access` platform module. + +The goal is not to make access optional in every real deployment. The goal is to +make ownership explicit: the kernel composes modules and exposes contracts; +`govoplan-access` owns identity, sessions, API keys, roles, groups, and access +administration. + +## Current Inventory + +### Existing Access Module Seed + +`govoplan-access` contains the extracted module-shaped seed package under +`src/govoplan_access/backend`. `govoplan-core` keeps compatibility import shims +under `src/govoplan_core/access`: + +- `manifest.py` declares `ModuleManifest(id="access")`. +- `db/models.py` defines access-owned model candidates. +- `auth/principals.py`, `auth/roles.py`, and `auth/tokens.py` contain auth + helper concepts. +- `permissions/definitions.py`, `permissions/evaluator.py`, and + `permissions/registry.py` contain permission catalogue/evaluation concepts. +- `tenancy/datastore.py` contains early tenancy access helpers. + +This seed package is now the starting point for the access module, but it is +not yet the full live source of truth for the running product. + +### Live Compatibility Ownership In Core + +The active implementation still uses core-owned models and services: + +- `src/govoplan_core/db/models.py` + - `Account` + - `Tenant` + - `User` + - `Group` + - `Role` + - `SystemSettings` + - `GovernanceTemplate` + - `GovernanceTemplateAssignment` + - `SystemRoleAssignment` + - `UserGroupMembership` + - `UserRoleAssignment` + - `GroupRoleAssignment` + - `ApiKey` + - `AuthSession` + - `AuditLog` +- `src/govoplan_core/auth/dependencies.py` +- `src/govoplan_core/security/api_keys.py` +- `src/govoplan_core/security/permissions.py` +- `src/govoplan_core/security/sessions.py` +- `src/govoplan_core/security/passwords.py` +- `src/govoplan_core/security/secrets.py` +- `src/govoplan_core/security/module_permissions.py` +- `src/govoplan_core/admin/service.py` +- `src/govoplan_core/admin/governance.py` +- `src/govoplan_core/api/v1/auth.py` +- `src/govoplan_core/api/v1/admin.py` +- `src/govoplan_core/api/v1/admin_schemas.py` +- `src/govoplan_core/api/v1/audit.py` +- `src/govoplan_core/db/bootstrap.py` + +Core also still hosts WebUI access/admin/auth surfaces. Those should become +access/admin module route contributions once the backend ownership split is +stable. + +### Current Module Consumers + +Feature modules currently depend on core compatibility access surfaces: + +- `govoplan-files` + - imports `govoplan_core.auth.dependencies` + - imports `Group` and `UserGroupMembership` for ACL decisions + - imports `Group`, `Tenant`, and `User` for file storage ownership/audit +- `govoplan-mail` + - imports `govoplan_core.auth.dependencies` + - imports `Group`, `Tenant`, `User`, and `UserGroupMembership` for mail + profile policy resolution + - imports core settings and secret helpers +- `govoplan-campaign` + - imports `govoplan_core.auth.dependencies` + - imports `Group`, `Tenant`, `User`, and `UserGroupMembership` for ownership + relationships and access decisions + - imports `govoplan_core.security.time.utc_now` + +These imports are valid compatibility dependencies today. They are also the +main extraction debt to remove. + +## Target Ownership + +### Kernel + +The kernel keeps only platform composition and stable contracts: + +- module discovery and registry validation +- route aggregation +- migration orchestration +- database engine/session lifecycle +- permission catalogue aggregation +- capability registry +- event/command envelopes +- dependency injection hooks +- health and diagnostics +- compatibility facades while modules migrate + +The kernel should not own account, tenant, role, group, session, or API-key +semantics. + +### `govoplan-access` + +`govoplan-access` owns: + +- accounts +- authentication routes +- session lifecycle +- API keys +- users +- groups and memberships +- roles and assignments +- principal resolution +- permission evaluation +- access administration routes +- access administration WebUI contributions +- access-related migrations +- access permissions and role templates + +### Later Platform Modules + +Some current access-adjacent behavior can remain in access initially, but should +have clean seams for later extraction: + +- `govoplan-tenancy`: tenants, tenant lifecycle, tenant switching, tenant + metadata, tenant settings boundaries. +- `govoplan-policy`: hierarchical policy/effective policy resolution and + provenance display contracts. +- `govoplan-audit`: audit log storage, audit routes, retention hooks, evidence + exports. +- `govoplan-admin`: generic administration shell contributions if they are not + owned by access/tenancy/policy/audit directly. + +## Kernel Contracts To Stabilize First + +Before moving live code, define contracts that feature modules can depend on +without importing access ORM models: + +- `PrincipalResolver` + - resolves the current actor from a request/session/API key. + - returns a stable DTO, not an ORM model. +- `AccessDirectory` + - resolves users, groups, memberships, and display labels by stable IDs. + - supports batch lookups for grids and policy screens. +- `TenantResolver` + - resolves current tenant context and tenant metadata by stable ID. +- `PermissionEvaluator` + - evaluates required scopes for a principal and resource. +- `ResourceAccessProvider` + - lets modules register resource ACL behavior without importing each other. +- `SecretProvider` + - encrypts/decrypts named secrets without tying consumers to access models. +- `AuditSink` + - records audit events without importing audit storage models. + +DTOs should be small and serializable: + +- `PrincipalRef` +- `AccountRef` +- `TenantRef` +- `UserRef` +- `GroupRef` +- `RoleRef` + +## Extraction Stages + +### Stage 0: Baseline Safeguards + +Status: started. + +- Document the kernel/platform module model. +- Add dependency-boundary checks. +- Add backend module permutation startup tests. +- Inventory access/auth/RBAC imports. +- Draft this extraction plan. + +Acceptance criteria: + +- `scripts/check_dependency_boundaries.py` passes. +- backend module permutation tests start every supported module combination. +- current direct imports are tracked as explicit transitional debt. + +### Stage 1: Contract Definitions + +Add kernel-owned protocols and DTOs for access-related interaction. + +Tasks: + +- Add protocol definitions under a kernel contract package. +- Add registry/capability names for access services. +- Keep existing core dependency functions as compatibility wrappers. +- Make wrappers resolve through capabilities when `govoplan-access` is present. +- Add tests for missing-capability behavior and clear error messages. + +Acceptance criteria: + +- Feature modules can receive principal/tenant/group/user references without + importing access ORM models. +- Existing routes continue to work through compatibility wrappers. + +### Stage 2: Create `govoplan-access` + +Create the new repository/package and move the access seed package into it. + +Tasks: + +- Create package metadata and entry points for `govoplan-access`. +- Move `govoplan_core/access` implementation into the new package. +- Publish `ModuleManifest(id="access")`. +- Register access permissions, role templates, routers, and migrations. +- Add compatibility imports in core where needed. +- Add release/dev dependency entries in core. + +Acceptance criteria: + +- `govoplan-core + govoplan-access` starts through normal module discovery. +- `govoplan-core` compatibility imports still work during transition. +- access manifest, migrations, and route contributions are discovered by core. + +### Stage 3: Move Live Models And Migrations + +Move active identity/access models out of `govoplan_core.db.models`. + +Tasks: + +- Decide the stable table naming strategy. +- Map legacy model names to access-owned model classes. +- Keep database table names where possible to avoid data migration churn. +- Add Alembic migration metadata owned by access. +- Keep compatibility aliases in core while modules migrate. +- Update bootstrap/create-all compatibility paths. + +Acceptance criteria: + +- Existing development databases migrate without data loss. +- New databases initialize with access-owned metadata. +- Core no longer owns live account/user/group/role/session/API-key model + definitions except compatibility aliases. + +### Stage 4: Move Auth Routes And Dependencies + +Move authentication, sessions, API keys, and principal dependencies. + +Tasks: + +- Move `/api/v1/auth/*` implementation to access. +- Move session/API-key services to access. +- Keep core route compatibility only if required by clients. +- Replace feature-module imports of core auth dependencies with stable kernel + contracts or access-provided capabilities. +- Add tests for login, session refresh, tenant selection, API-key auth, and + missing access capability failures. + +Acceptance criteria: + +- Auth behavior works through the access module. +- Feature modules do not import access internals. +- Core can explain startup failure clearly if auth-required routes are enabled + without the access capability. + +### Stage 5: Move Admin And WebUI Contributions + +Move access administration UI/API ownership into modules. + +Tasks: + +- Move users, groups, roles, API keys, and access settings pages into + `govoplan-access`. +- Move tenant-specific pages to `govoplan-tenancy` when that module exists, or + keep them temporarily in access with clear boundaries. +- Register admin navigation through module contributions. +- Keep core shell, layout, route rendering, and generic components only. + +Acceptance criteria: + +- Core WebUI shell renders admin/access pages from module contributions. +- Core does not import access page components directly. +- Module nav and route metadata remain serializable. + +### Stage 6: Decouple Feature Modules + +Remove direct ORM/model imports from files, mail, and campaign. + +Tasks: + +- Replace `Group`, `Tenant`, `User`, and `UserGroupMembership` imports with + directory/capability lookups. +- Replace direct cross-module cleanup/count queries with registered providers, + events, or module-owned API contracts. +- Replace mail-profile ownership resolution with stable owner references. +- Replace campaign/file access checks with resource ACL provider contracts. + +Acceptance criteria: + +- `govoplan-files`, `govoplan-mail`, and `govoplan-campaign` do not import + access implementation modules or sibling feature modules. +- Dependency-boundary allowlist shrinks after every replacement. + +### Stage 7: Remove Compatibility Debt + +Finalize the split. + +Tasks: + +- Remove obsolete core compatibility aliases. +- Remove remaining allowlist entries from the boundary checker. +- Update release dependency docs. +- Update operator migration notes. +- Add full module permutation tests including access-present and access-absent + behavior. + +Acceptance criteria: + +- Core is a composition kernel. +- Access behavior is owned by `govoplan-access`. +- Feature modules communicate through kernel contracts, capabilities, events, + and their own APIs. + +## Immediate Backlog + +- [x] Document kernel/platform module model. +- [x] Add dependency-boundary check. +- [x] Add backend permutation startup smoke checks. +- [x] Inventory access/auth/RBAC import debt. +- [x] Draft access extraction plan. +- [x] Define kernel access DTOs and protocols. +- [x] Add access capability registry names. +- [x] Register live access directory and tenant resolver capability + implementations backed by the current compatibility tables. +- [x] Replace `govoplan-files` direct user/group/tenant model imports with the + `access.directory` capability for group membership and share-target checks. +- [x] Create `govoplan-access` repository workspace and issue workflow scaffold. +- [x] Create `govoplan-access` repository/package skeleton. +- [x] Move `govoplan_core/access` seed package into `govoplan-access`. +- [x] Add compatibility wrappers in core for old import paths. +- [x] Route existing auth dependency wrappers through access principal/evaluator capabilities. +- [x] Move session, API-key, and password helper services into `govoplan-access`. +- [x] Move interactive auth/session routes behind access module manifest. +- [x] Move legacy admin/API-key routes behind access module manifest. +- [x] Move legacy admin service and governance helpers into `govoplan-access`. +- [x] Replace legacy access-to-files/campaign admin lookups with module + tenant-summary and group-delete veto providers. +- [x] Split legacy admin route contribution across `govoplan-admin`, + `govoplan-tenancy`, `govoplan-policy`, `govoplan-audit`, and + `govoplan-access` route slices. +- [x] Move legacy admin route-handler ownership out of the access compatibility + router into access, admin, tenancy, policy, and audit module routers. +- [x] Move shared system-settings, tenant-governance, slug/error, and + tenant-count helpers out of access internals into core settings/tenancy + helpers used by the split platform route modules. +- [ ] Move legacy admin service and model ownership out of the access + compatibility implementation into access, tenancy, policy, audit, and core + settings modules. +- [ ] Replace tenancy-to-access default role seeding with a tenant-created + lifecycle/event contract. +- [ ] Replace feature-module direct user/group/tenant model imports. + - [x] `govoplan-files` + - [ ] `govoplan-mail` + - [ ] `govoplan-campaign` +- [ ] Replace direct cross-module SQL lookups with provider/event contracts. +- [ ] Move access admin WebUI pages to module route contributions. +- [ ] Remove transitional boundary checker allowlist entries as each contract + lands. + +## Open Decisions + +- Is `govoplan-access` required for any authenticated deployment, while + core-only remains a diagnostics/settings shell? +- Should tenant models move with access first, or should `govoplan-tenancy` be + created before moving live models? +- Which table names must remain stable for painless migrations? +- Should secret encryption remain a kernel primitive or become an access-owned + capability? +- Should audit move before policy provenance, or after access/tenancy are split? +- How long should core keep compatibility route paths for existing clients? + +## Verification + +Use the following checks while extracting access: + +```bash +cd /mnt/DATA/git/govoplan-core +./.venv/bin/python scripts/check_dependency_boundaries.py +./.venv/bin/python -m unittest tests.test_module_system +``` + +For each removed dependency-boundary exception, add or update a focused test +that proves the replacement contract starts without the old direct import.