|
|
|
@@ -0,0 +1,409 @@
|
|
|
|
|
---
|
|
|
|
|
title: feat: Clarify project access and lifecycle management
|
|
|
|
|
date: 2026-10-19
|
|
|
|
|
type: feat
|
|
|
|
|
artifact_contract: ce-unified-plan/v1
|
|
|
|
|
product_contract_source: ce-brainstorm
|
|
|
|
|
execution: code
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
## Goal Capsule
|
|
|
|
|
|
|
|
|
|
- **Objective:** Make project access understandable and enforceable: administrator authority stays outside job roles; the sole role permission is project access, which permits project creation; project creators with that permission manage their own project; members and project states determine whether work can continue; all fixed company templates are available to projects.
|
|
|
|
|
- **Means:** Keep Backend authoritative for authenticated identity and job-role permission, and RDM authoritative for canonical project ownership, membership, project state, and template catalog. Recheck authorization at every read/write and asynchronous execution boundary.
|
|
|
|
|
- **Authority:** The user's request in this conversation. Preserve the existing distinction between system administrator and RDM domain administrator. Product rules below govern when existing implementation or older proposals differ.
|
|
|
|
|
- **Execution profile:** Split implementation into bounded Backend, RDM, and Frontend units, with host-owned integration, verification, review, and delivery under the repository's agent-per-unit rules.
|
|
|
|
|
- **Stop conditions:** Stop when role permissions show only project access, project creator and state gates work for synchronous and in-flight operations, the complete fixed-template catalog is available, and focused verification passes. Do not implement document-duty assignment, production data changes, deployment, or unrelated permission redesign.
|
|
|
|
|
- **Delivery owner:** Host owns cross-repository planning, scope review, authoritative verification, review, PR/CI, merge scheduling, and safe closure. Component work begins only after fresh source and branch checks.
|
|
|
|
|
|
|
|
|
|
## Product Contract
|
|
|
|
|
|
|
|
|
|
### Summary
|
|
|
|
|
|
|
|
|
|
The system's role editor exposes job-level system settings and user-management actions alongside project access, which makes role permission sound broader than the intended project boundary. In this product, administrator and super-administrator authority governs system settings, accounts, roles, and platform permissions. A job role has one product permission: project access. Users with effective project access may create projects, and only the creator with effective project access may administer a project. Project membership and project/member state separately govern conversation work. Projects expose the complete fixed company-template library; assignment of document authors, reviewers, and approvers is outside this increment.
|
|
|
|
|
|
|
|
|
|
### Problem Frame
|
|
|
|
|
|
|
|
|
|
Current code has a broader action catalog, Backend role-permission records, RDM membership rows, creator/owner checks, project archive/close fields, and a 44-item published DHF catalog. These mechanisms do not yet express one product rule: system administration is distinct from role permission; member removal is currently represented by deleting membership; project-wide and per-member work suspension are not the same as archival; and a complete template catalog is not the same as project-level template access. The result is confusing role configuration and inconsistent expectations about who can create or continue work.
|
|
|
|
|
|
|
|
|
|
### Actors
|
|
|
|
|
|
|
|
|
|
- **Super-administrator:** Holds the highest protected system authority according to the existing super-administrator contract.
|
|
|
|
|
- **System administrator:** Manages the system actions explicitly assigned by the existing administrator contract. System administrator status alone does not grant project content access or project management.
|
|
|
|
|
- **Project creator:** The immutable `createdBy` identity for one canonical RDM project. It can manage that project only while its effective project-access permission and account are valid.
|
|
|
|
|
- **Active project member:** Can discover the project and create/use personal conversations while both project and member states permit work.
|
|
|
|
|
- **Read-only former or suspended member:** Can read the historical material allowed by the applicable read boundary, but cannot create or continue work.
|
|
|
|
|
|
|
|
|
|
### Requirements
|
|
|
|
|
|
|
|
|
|
- **R1. Separate system authority from job roles.** Role configuration must not expose or grant system settings, account/user management, role administration, administrator appointment, or platform-permission management. Those actions remain in protected administrator/super-administrator authorization paths. Preserve the existing distinction between administrator levels; do not infer authority from an RDM domain administrator, project creator, or project member.
|
|
|
|
|
- **R2. Reduce role permissions to project access.** Each role has one boolean project-access setting, whose meaning is permission to create a project. Unknown, disabled, unassigned, or denied roles cannot create projects. System administrator status by itself does not substitute for project access.
|
|
|
|
|
- **R3. Enforce creator-scoped project management.** Project management requires a valid account, effective project access, and the exact authenticated actor matching the canonical project's immutable creator. These two project conditions are sufficient for the in-scope management actions: project settings, membership, and project/member work states. Existing per-action member/project overrides must not separately grant these management actions to another actor or block the eligible creator. A member with role `owner`, a system administrator, a caller-supplied owner field, or a host-project owner does not bypass the gate.
|
|
|
|
|
- **R4. Preserve active-member work.** An active project member can see the project and create personal conversations. Existing conversations remain private according to the read boundary; membership does not itself publish another user's private uploads or drafts.
|
|
|
|
|
- **R5. Make removal revoke work but retain allowed history.** Removing a member revokes project work immediately. The former member cannot create conversations, send messages, resume/retry work, approve an execution that would continue work, upload or mutate project data, or continue an existing conversation. The former member retains read-only access to historical material within the agreed historical visibility boundary. Preserve the revocation record so history remains auditable and re-adding does not erase prior removal.
|
|
|
|
|
- **R6. Add project-wide work state.** An active project permits work only for members whose member state is active. A closed project permits no member to create or continue conversation work; existing readable conversations and documents remain available. The creator can still use project-management actions needed to reopen or administer the project.
|
|
|
|
|
- **R7. Add per-member work state.** The creator can suspend or reactivate an individual member without removing membership. A suspended member remains discoverable/read-only within the same historical boundary but cannot create or continue conversation work. Project-wide closed state overrides an individually active state.
|
|
|
|
|
- **R8. Enforce gates at every execution boundary.** Authorization must be rechecked before writes and before queued, resumed, confirmed, or delayed work causes side effects. A permission or state change that wins the race prevents the later operation. Read-only access must not accidentally resume a stream, run, or HITL action.
|
|
|
|
|
- **R9. Integrate the complete fixed-template library.** Inventory and expose every fixed company template used in R&D and business phases, including the existing 44-item DHF source batch and any additional fixed-template source found during inventory. Preserve source identity, version/hash, phase, applicability, and format. A template can be selected and instantiated into a project where generation is supported; a project is not prepopulated with every template automatically.
|
|
|
|
|
- **R10. Defer document-duty assignment.** Do not add, connect, or change assignment of document author/reviewer/approver duties for these templates in this increment. Do not alter existing duty history or make a template unavailable solely because new duty UI is deferred. Keep any existing behavior outside the changed paths intact.
|
|
|
|
|
- **R11. Migrate without privilege expansion.** Existing administrator grants remain protected administrator authority. Existing role assignments that grant system/user actions cease to be effective through roles; they must not silently promote users to administrators. Existing valid project-access assignments are preserved. Any ambiguous legacy owner, membership, or history visibility remains explicit and fails closed rather than being guessed.
|
|
|
|
|
- **R12. Keep project data and lifecycle history.** Closing a project or suspending a member is reversible and does not delete projects, conversations, documents, or membership history. Removal is not archive or account deletion.
|
|
|
|
|
- **R13. Let authorized role managers configure a new role's project permission.** An actor allowed to manage roles can edit the role's single project-access permission immediately after creation. The role editor must not require the separate `system.permissions.manage` authority to set that one job-role permission. Actors without role-management authority remain read-only, and direct API writes remain protected. System grants and administrator-owned platform limits continue to require `system.permissions.manage`.
|
|
|
|
|
|
|
|
|
|
### Scope Boundaries
|
|
|
|
|
|
|
|
|
|
**In scope:** role editor and server role validation; system/admin action sources; project creation and creator authorization; creator-only project settings, membership, and work-state management; project membership active/suspended/removed states; project active/closed state; historical read-only boundary after suspension/removal; all fixed-template inventory and project availability; API, UI, migrations, audit, and tests required for these behaviors.
|
|
|
|
|
|
|
|
|
|
**Out of scope:** implementing or newly integrating document-duty assignment; redesigning document author/review/approval workflow; exposing private content to system administrators; changing archive/restore behavior; project transfer to another creator; project deletion; automatic creation of every template instance; changing global project-name uniqueness; production migration, release/tag publication, deployment, and live-data repair.
|
|
|
|
|
|
|
|
|
|
**Deferred to Follow-Up Work:** assigning author/reviewer/approver responsibilities per fixed template; transfer of project creator ownership; richer per-member project action matrices beyond active/suspended work state; template fidelity remediation beyond current supported generation contracts.
|
|
|
|
|
|
|
|
|
|
### Key Flows
|
|
|
|
|
|
|
|
|
|
- **F1. Create a project:** An enabled user with effective project access creates a canonical project. The server records the authenticated creator; the client cannot choose or replace the creator.
|
|
|
|
|
- **F2. Manage a project:** The creator with effective project access changes settings, membership, or state. A non-creator, a creator whose project access has been removed, or an administrator without project access is denied.
|
|
|
|
|
- **F3. Add a member:** The creator adds an enabled account. The member sees the project and can create personal conversations only when the project and member are active.
|
|
|
|
|
- **F4. Suspend a member:** The creator suspends the member. Reads remain within the historical boundary; every new or continued work action is denied. Re-activation restores the active-member path without erasing history.
|
|
|
|
|
- **F5. Remove a member:** The creator removes the member. The work gate closes and removal is retained as history; the former member can only read permitted historical material.
|
|
|
|
|
- **F6. Close or reopen a project:** The creator closes the project; all members become read-only for project work. Reopening restores work to members whose own state is active.
|
|
|
|
|
- **F7. Use a fixed template:** A project member browses the complete company-template catalog, selects a template, and creates an instance only through supported generation. Duty assignment is not part of this flow.
|
|
|
|
|
|
|
|
|
|
### Acceptance Examples
|
|
|
|
|
|
|
|
|
|
- **AE1.** A normal user without project access receives a denial when creating a project; a user with project access succeeds and is recorded as creator.
|
|
|
|
|
- **AE2.** A user with system-admin rights but without project access cannot create or administer a project. The same user can perform only the system actions allowed by the administrator contract.
|
|
|
|
|
- **AE3.** A member with project access but who did not create project A cannot manage A or project B. Project A's creator cannot manage B.
|
|
|
|
|
- **AE4.** An active member sees the shared project and creates a personal conversation. Other members do not gain access to that conversation merely through membership.
|
|
|
|
|
- **AE5.** After removal or suspension, a member can read allowed existing history but every new or continued work action is rejected, including retry, resume, queued continuation, and confirmation that would cause execution.
|
|
|
|
|
- **AE6.** Closing project A blocks work for all members and preserves read access; reopening A restores work only for active members.
|
|
|
|
|
- **AE7.** Suspending one member blocks only that member's work; other active members continue while the project is active. Closing the project blocks all members regardless of individual state.
|
|
|
|
|
- **AE8.** The project catalog accounts for every fixed company template from the approved source inventory, including all 44 DHF assets. Duplicate bytes with distinct source identities remain distinct catalog entries. No project is silently seeded with 44 document instances.
|
|
|
|
|
- **AE9.** Role configuration cannot set a system setting, user-management, administrator, or platform-permission action. These actions remain available only through their protected admin paths.
|
|
|
|
|
- **AE10.** SQLite and PostgreSQL produce equivalent authorization, concurrency, and migration outcomes; cross-project and post-revocation negatives remain denied.
|
|
|
|
|
- **AE11.** An authorized role manager creates a role and can immediately enable or disable its single project-access permission. A role manager who lacks `system.permissions.manage` still succeeds; an actor without `system.roles.manage` cannot edit the permission through the UI or API. System-grant and platform-limit writes remain denied without `system.permissions.manage`.
|
|
|
|
|
|
|
|
|
|
### Success Criteria
|
|
|
|
|
|
|
|
|
|
- Role configuration has one understandable project-access choice and no configurable system/user actions.
|
|
|
|
|
- A role manager can create a role and configure its project-access choice without a separate platform-permission-management grant.
|
|
|
|
|
- Project creation and management follow the exact effective-project-access plus creator rule.
|
|
|
|
|
- Project/member state transitions have predictable, reversible read-only behavior, including for in-flight and queued work.
|
|
|
|
|
- Every fixed company template is discoverable with traceable source/version/phase metadata; supported selection creates a project instance without introducing duty assignment.
|
|
|
|
|
- Existing private-content, project-isolation, system-admin, and super-admin boundaries remain intact.
|
|
|
|
|
|
|
|
|
|
## Planning Contract
|
|
|
|
|
|
|
|
|
|
### Key Technical Decisions
|
|
|
|
|
|
|
|
|
|
- **KTD1. Keep admin authority outside roles.** Keep super-administrator and system-administrator checks in the existing trusted system-authority path. Role permission APIs and UI expose only the project-access capability. Reuse current administrator-level distinctions rather than creating role-based substitutes.
|
|
|
|
|
- **KTD2. Define one effective project-access capability.** A single role boolean determines whether an enabled account with an enabled assigned role can create projects. The legacy `allowed`/`capAllowed` pair is only a storage compatibility shape for this action: normalize old records from their prior effective result (`allowed && capAllowed`), and write both fields from the new single boolean. Do not show or authorize an independent role cap for project creation. Administrator status alone is not an implicit project grant. The same effective capability and exact creator identity are the complete authorization rule for in-scope project management; existing per-action project overrides cannot add another manager or impose a second management gate. Preserve explicit deny/fail-closed behavior when role/provider data is missing or stale.
|
|
|
|
|
- **KTD3. Separate project membership, member work state, and project work state.** Retain canonical RDM ownership/membership as domain authority. Represent `active`, `suspended`, and `removed` member history separately from `active`/`closed` project work state. Effective work requires an enabled account, active membership, active member state, and active project state.
|
|
|
|
|
- **KTD4. Preserve read and work authorization as different checks.** Membership revocation/suspension and project closure block all work paths immediately while leaving only the explicitly allowed read paths. Recheck current state at execution/side-effect boundaries rather than relying on a UI state or a conversation's creation-time authorization.
|
|
|
|
|
- **KTD5. Use the published company-template catalog as the source of truth.** Include all inventoried fixed company templates in the project catalog. Keep source assets and template instances distinct. Instantiate on explicit selection, not by bulk-seeding every project. Preserve unsupported fidelity/generation states as visible limitations; catalog presence alone does not claim full-fidelity rendering.
|
|
|
|
|
- **KTD6. Use conservative historical visibility.** Unless the user chooses a broader boundary during this planning conversation, retain only the history the member could already read before suspension/removal; do not make another member's private conversation or upload newly visible. Capture the chosen boundary in the final plan and tests.
|
|
|
|
|
- **KTD7. Keep this increment reversible and local.** No deletion or destructive data migration is needed. Preserve audit/history, run local verification, and keep deployment and production data repair outside this plan.
|
|
|
|
|
|
|
|
|
|
### High-Level Technical Design
|
|
|
|
|
|
|
|
|
|
```mermaid
|
|
|
|
|
flowchart LR
|
|
|
|
|
A[Authenticated actor] --> B[Backend admin authority]
|
|
|
|
|
A --> C[Backend job role: project access]
|
|
|
|
|
C -->|create permitted| D[RDM canonical project]
|
|
|
|
|
C -->|plus exact createdBy| E[Project management]
|
|
|
|
|
D --> F[Member state: active / suspended / removed]
|
|
|
|
|
D --> G[Project state: active / closed]
|
|
|
|
|
F --> H{Work gate}
|
|
|
|
|
G --> H
|
|
|
|
|
H -->|allowed| I[Create or continue conversation work]
|
|
|
|
|
H -->|denied| J[Historical read-only projection]
|
|
|
|
|
D --> K[Complete fixed-template catalog]
|
|
|
|
|
K -->|explicit selection| L[Supported project document instance]
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Project-management authorization and project-work authorization are separate decisions. A closed project may still be administered by its eligible creator, while its members remain read-only. A suspended or removed member never gains creator-management capability through historical read access. Archival remains a separate existing lifecycle and is not changed by this plan.
|
|
|
|
|
|
|
|
|
|
### Implementation Notes
|
|
|
|
|
|
|
|
|
|
- Backend owns authenticated actor identity, role assignment, administrator actions, and effective project-access resolution. RDM owns canonical project creator, membership history, project/member work states, and template catalog consumption. Frontend is a projection, not an authorization source.
|
|
|
|
|
- Existing project and conversation data may live in different stores. Any write gate crossing Backend and RDM must use the established public extension contracts and preserve account-write fencing; do not assume one transaction spans both stores.
|
|
|
|
|
- RDM currently stores `rdm_members` rows by `(project_id, owner)` and removal deletes the row. It has creator checks, owner/member roles, archive/closed fields, and project action caps. The new contract must not mistake project owner role, archived state, or RDM domain-admin state for the requested rule.
|
|
|
|
|
- The RDM checkout inspected for this plan is 15 commits behind its remote-tracking `main`; the Backend RDM pin and fixed-template inventory must be refreshed before implementation. Current local source is planning evidence, not a delivery candidate.
|
|
|
|
|
|
|
|
|
|
### Sources & Research
|
|
|
|
|
|
|
|
|
|
- `modules/backend/internal/authz/catalog/catalog.go`, `modules/backend/internal/authz/service.go`, and `modules/backend/internal/server/server.go`: current catalog separates protected system actions from the special `project.create` role decision; authenticated system administrators currently bypass that decision, which this plan changes.
|
|
|
|
|
- `modules/backend/internal/store/role_policy.go` and `modules/frontend/src/components/RolePermissionsPanel.tsx`: current role policy storage and role-permission editor to be narrowed to project access.
|
|
|
|
|
- `modules/backend/internal/server/roles.go` and `modules/frontend/src/components/RolePermissionsPanel.tsx`: role creation/listing use `system.roles.manage` / `system.roles.view`, but role permission catalog and writes plus checkbox enablement currently require `system.permissions.view` and `system.permissions.manage`. This lets a delegated role manager create a role while leaving every permission checkbox disabled. This source path grounds R13; live account grants were not inspected.
|
|
|
|
|
- `modules/documents/docs/proposals/2026-10-13-system-project-membership.md`: prior approved boundary for RDM project identity, Backend projections, member-created private conversations, and project/resource privacy. Its privacy rules remain unless the user explicitly changes the historical scope in this plan.
|
|
|
|
|
- `modules/documents/docs/proposals/2026-10-15-iam-focused-role-permission-spec.md`: current administrator, role, and project permission contracts; the present role model is broader than the user's requested product model.
|
|
|
|
|
- `modules/documents/docs/records/2026-10-14-rdm-two-trees-latest-templates/rdm-two-trees-requirements-r1.md` and `modules/documents/docs/proposals/2026-10-14-rdm-two-trees-latest-templates.md`: 44-source DHF inventory and current known distinction between catalog coverage and rendering fidelity.
|
|
|
|
|
- `/home/weichen/projects/Agent-System-RDM/internal/members/members.go`, `internal/rdmapp/projects_api.go`, `internal/rdmapp/system_projects.go`, and `internal/rdmapp/templates/dhf/catalog.json`: inspected RDM membership deletion, creator management, active work checks, and template catalog. This checkout is behind remote `main` and must be refreshed before implementation.
|
|
|
|
|
- No external research was used; existing Backend and RDM authorization and template contracts provide direct local patterns.
|
|
|
|
|
|
|
|
|
|
### Alternatives Considered
|
|
|
|
|
|
|
|
|
|
- **Keep all existing system actions in the role matrix but lock them:** Rejected because it preserves the misleading product model and makes role configuration look capable of controlling admin authority.
|
|
|
|
|
- **Use project membership alone as management authority:** Rejected because a member or delegated project-owner role must not acquire the creator's project-management right.
|
|
|
|
|
- **Delete membership and infer history from conversation ownership:** Rejected because it loses explicit revocation history and cannot represent per-member suspension cleanly.
|
|
|
|
|
- **Close a project by archiving it:** Rejected because closure must be reversible and read-only while preserving a distinct archival lifecycle.
|
|
|
|
|
- **Instantiate every template at project creation:** Rejected because it creates unused documents and duties/approval expectations the user explicitly deferred.
|
|
|
|
|
|
|
|
|
|
### Deferred Planning Questions
|
|
|
|
|
|
|
|
|
|
- The user's answer on removed-member historical visibility is pending. The plan currently assumes only pre-revocation visible history remains readable. If the user wants all project conversations/documents visible after removal, update the privacy requirements and acceptance tests before implementation.
|
|
|
|
|
- Exact fixed-template source inventory beyond the 44-item DHF batch must be verified against the current RDM source and company template directory when component baselines are refreshed. Missing, duplicate, unsupported, or unreviewed entries must be listed rather than silently omitted.
|
|
|
|
|
- Implementation must verify how active runs, delayed commands, streamed events, uploads, and HITL confirmations map onto the current Backend/RDM public contracts; the required outcome is specified, but exact handler names are implementation-time discovery.
|
|
|
|
|
|
|
|
|
|
## Implementation Units
|
|
|
|
|
|
|
|
|
|
### U1. Restrict role permissions to project access
|
|
|
|
|
|
|
|
|
|
**Goal:** Remove system settings, account/user, administrator, and platform-permission actions from role configuration while preserving protected administrator behavior.
|
|
|
|
|
|
|
|
|
|
**Requirements:** R1, R2, R9, R11, R13
|
|
|
|
|
|
|
|
|
|
**Dependencies:** None
|
|
|
|
|
|
|
|
|
|
**Files:**
|
|
|
|
|
- `Agent-System-Dev/modules/backend/internal/authz/catalog/catalog.go`
|
|
|
|
|
- `Agent-System-Dev/modules/backend/internal/authz/service.go`
|
|
|
|
|
- `Agent-System-Dev/modules/backend/internal/store/role_policy.go`
|
|
|
|
|
- `Agent-System-Dev/modules/backend/internal/store/migrate.go`
|
|
|
|
|
- `Agent-System-Dev/modules/backend/internal/server/roles.go`
|
|
|
|
|
- `Agent-System-Dev/modules/backend/internal/server/role_authorization_test.go`
|
|
|
|
|
- `Agent-System-Dev/modules/frontend/src/components/RolePermissionsPanel.tsx`
|
|
|
|
|
- `Agent-System-Dev/modules/frontend/src/rolePermissions.ts`
|
|
|
|
|
- Related Backend and Frontend permission tests
|
|
|
|
|
|
|
|
|
|
**Approach:**
|
|
|
|
|
|
|
|
|
|
1. Keep protected system actions in admin/super-admin authorization. Restrict job-role permission read/write/catalog views to one project-access boolean and label it by its actual meaning. The UI has one checkbox, not separate default and cap controls.
|
|
|
|
|
2. Authorize this role field using role-view/manage authority. Do not require `system.permissions.manage` to edit a job-role definition. Keep system-grant and platform-limit writes under `system.permissions.manage`.
|
|
|
|
|
3. Enforce the same split in the Backend API: role managers can read the project-access descriptor and replace that role value; handcrafted writes to protected system/user actions remain rejected. Map the boolean to both legacy storage columns and authorize from the canonical boolean result.
|
|
|
|
|
4. Ensure system administrator status does not bypass the effective project-access check for project creation. Keep role/provider errors, disabled role/account, and unknown actions denied.
|
|
|
|
|
5. Migrate old role permission rows so system/user actions are ignored for role authorization and not shown as role capabilities. Do not convert them into administrator grants. Preserve the prior effective project-access result when normalizing `allowed` and `capAllowed`; retain explicit administrator grants unchanged.
|
|
|
|
|
|
|
|
|
|
**Test scenarios:**
|
|
|
|
|
|
|
|
|
|
- A role containing old system settings/user action rows cannot authorize those actions and the role API/UI omits them.
|
|
|
|
|
- An administrator without project access cannot create a project; an eligible role can.
|
|
|
|
|
- A system setting/user action grant through a role-permission write is rejected atomically.
|
|
|
|
|
- A user with `system.roles.manage` but without `system.permissions.manage` creates a role, enables its project access, saves successfully, reloads the role, and sees the saved value.
|
|
|
|
|
- A user with `system.roles.view` but without `system.roles.manage` can read the project-access value but sees it read-only; direct role-permission writes are rejected.
|
|
|
|
|
- A user without `system.permissions.manage` still cannot change system grants or platform limits.
|
|
|
|
|
- A legacy role with protected rows migrates without promoting its members or losing valid project access.
|
|
|
|
|
- An existing project role with `allowed=true, capAllowed=false` remains effectively denied after normalization; one with both fields true remains allowed.
|
|
|
|
|
- A missing/incompatible role provider denies project creation.
|
|
|
|
|
|
|
|
|
|
**Verification:** Backend role-policy/catalog/authorization migration tests and Frontend role editor tests prove the separated role-management and platform-permission gates; current admin and super-admin tests pass.
|
|
|
|
|
|
|
|
|
|
### U2. Enforce project creator management authority
|
|
|
|
|
|
|
|
|
|
**Goal:** Require effective project access and exact canonical creator identity for every project-management action.
|
|
|
|
|
|
|
|
|
|
**Requirements:** R2, R3, R11
|
|
|
|
|
|
|
|
|
|
**Dependencies:** U1
|
|
|
|
|
|
|
|
|
|
**Files:**
|
|
|
|
|
- `Agent-System-RDM/internal/rdmapp/projects_api.go`
|
|
|
|
|
- `Agent-System-RDM/internal/rdmapp/system_projects.go`
|
|
|
|
|
- `Agent-System-RDM/internal/perms/role_provider.go`
|
|
|
|
|
- `Agent-System-RDM/internal/perms/perms.go`
|
|
|
|
|
- Related project creator and permission tests
|
|
|
|
|
|
|
|
|
|
**Approach:**
|
|
|
|
|
|
|
|
|
|
1. Centralize a management check using authenticated actor, canonical project ID, immutable `createdBy`, current account/role project access, and project existence.
|
|
|
|
|
2. Apply that complete check to project settings, member management, and project/member work-state management. Existing per-action overrides cannot grant management to non-creators or further restrict the eligible creator. Do not change archive/restore, which remains a separate lifecycle.
|
|
|
|
|
3. Preserve separate project-resource authorization for ordinary member reads and conversation work. Do not grant management because a member has an `owner` membership label or an action override.
|
|
|
|
|
4. Keep account disable and project-access revocation race-safe using existing write fences or equivalent transactional rechecks.
|
|
|
|
|
|
|
|
|
|
**Test scenarios:**
|
|
|
|
|
|
|
|
|
|
- The creator with project access manages their own project.
|
|
|
|
|
- The creator after losing project access is denied management.
|
|
|
|
|
- A non-creator member, project `owner` role holder, system administrator, and RDM domain administrator are each denied unless they independently meet the exact creator rule.
|
|
|
|
|
- The eligible creator can manage in-scope project settings, membership, and state even when a legacy per-action override denies them; a non-creator cannot manage when an override allows them.
|
|
|
|
|
- Cross-project IDs, host/RDM ID confusion, and caller-supplied owner substitutions are denied.
|
|
|
|
|
- Concurrent account disable or permission revocation prevents a later management write from committing.
|
|
|
|
|
|
|
|
|
|
**Verification:** Focused RDM project authorization tests pass on SQLite and PostgreSQL; existing project privacy and host-projection tests remain green.
|
|
|
|
|
|
|
|
|
|
### U3. Preserve membership history and read-only removal
|
|
|
|
|
|
|
|
|
|
**Goal:** Make member removal and suspension revoke all project work immediately while retaining only authorized historical reads.
|
|
|
|
|
|
|
|
|
|
**Requirements:** R4, R5, R8, R12
|
|
|
|
|
|
|
|
|
|
**Dependencies:** U2. The historical visibility scope is a blocking product decision before U3 implementation; the current plan records KTD6 as the conservative default.
|
|
|
|
|
|
|
|
|
|
**Files:**
|
|
|
|
|
- `Agent-System-RDM/internal/members/members.go`
|
|
|
|
|
- `Agent-System-RDM/internal/rdmapp/projects_api.go`
|
|
|
|
|
- `Agent-System-RDM/internal/rdmapp/system_projects.go`
|
|
|
|
|
- `Agent-System-RDM/internal/rdmapp/private_doc_views.go`
|
|
|
|
|
- `Agent-System-RDM/internal/rdmapp/iam_i1_privacy_test.go`
|
|
|
|
|
- `Agent-System-Dev/modules/backend/internal/server/server.go`
|
|
|
|
|
- Relevant conversation read/write, resource authorization, and async-work tests
|
|
|
|
|
|
|
|
|
|
**Approach:**
|
|
|
|
|
|
|
|
|
|
1. Replace hard deletion as the authorization source with retained membership/revocation state and timestamps while preserving current member-list semantics for active members.
|
|
|
|
|
2. Implement the settled historical read boundary independently from work authorization. Do not expose another user's private conversation/upload unless the user explicitly chooses that scope.
|
|
|
|
|
3. Recheck current membership state for conversation creation, message writes, run/retry/resume, upload/mutation, HITL continuation, queued work, and streamed side effects.
|
|
|
|
|
4. On removal or suspension, invalidate or stop pending operations where they would otherwise continue producing side effects; reads must remain non-mutating.
|
|
|
|
|
5. Re-adding a member creates a new active period or reactivates with an auditable transition; preserve previous removal history.
|
|
|
|
|
|
|
|
|
|
**Test scenarios:**
|
|
|
|
|
|
|
|
|
|
- Removed/suspended actor can read allowed historical items but cannot create a conversation or mutate a prior conversation.
|
|
|
|
|
- Removed/suspended actor cannot retry, resume, upload, send, approve-to-execute, or cause a queued run to continue.
|
|
|
|
|
- An operation authorized before revocation but attempting its side effect after revocation is rejected.
|
|
|
|
|
- Another active member's private conversation and original upload remain hidden under the conservative visibility choice.
|
|
|
|
|
- Re-adding restores active work without deleting or rewriting prior membership history.
|
|
|
|
|
|
|
|
|
|
**Verification:** Backend and RDM read/write boundary tests cover the exact revocation race and preserve private-content negatives.
|
|
|
|
|
|
|
|
|
|
### U4. Add project-wide and per-member work states
|
|
|
|
|
|
|
|
|
|
**Goal:** Support reversible project closure and per-member suspension with consistent read-only behavior.
|
|
|
|
|
|
|
|
|
|
**Requirements:** R3, R6, R7, R8, R12
|
|
|
|
|
|
|
|
|
|
**Dependencies:** U2, U3
|
|
|
|
|
|
|
|
|
|
**Files:**
|
|
|
|
|
- `Agent-System-RDM/internal/projects/projects.go`
|
|
|
|
|
- `Agent-System-RDM/internal/members/members.go`
|
|
|
|
|
- `Agent-System-RDM/internal/rdmapp/projects_api.go`
|
|
|
|
|
- `Agent-System-RDM/internal/rdmapp/system_projects.go`
|
|
|
|
|
- `Agent-System-RDM/internal/perms/perms.go`
|
|
|
|
|
- Related project/member migration and state-transition tests
|
|
|
|
|
- Related Backend conversation/async execution authorization tests
|
|
|
|
|
|
|
|
|
|
**Approach:**
|
|
|
|
|
|
|
|
|
|
1. Add explicit reversible project work state `active|closed` and member work state `active|suspended`, leaving archival and historical removal distinct.
|
|
|
|
|
2. Define the work predicate as enabled account AND active member AND active member state AND active project state. Historical read access is evaluated separately.
|
|
|
|
|
3. Permit the eligible creator to reopen/manage a closed project while denying all member work. Per-member suspension affects only that member; project closure overrides every member state.
|
|
|
|
|
4. Enforce current state before every work side effect and on in-flight/queued continuations. Persist version/audit data so stale UI requests and delayed responses cannot restore old state.
|
|
|
|
|
5. Keep transitions idempotent and reversible. Do not delete or rewrite conversations, project data, or membership history.
|
|
|
|
|
|
|
|
|
|
**Test scenarios:**
|
|
|
|
|
|
|
|
|
|
- Closing a project blocks new and existing conversation work for every member while preserving existing reads.
|
|
|
|
|
- Reopening restores work only for active members.
|
|
|
|
|
- Suspending one member blocks only that member; other active members continue normally.
|
|
|
|
|
- Closing a project blocks a member even when their individual state is active.
|
|
|
|
|
- State changes concurrent with message send, queued execution, retry, and confirmation prevent post-close side effects.
|
|
|
|
|
- Creator management remains available on a closed project but is denied when creator permission/account is invalid.
|
|
|
|
|
|
|
|
|
|
**Verification:** RDM state and migration tests pass on SQLite/PostgreSQL; Backend integration tests prove the canonical RDM state gates all conversation work paths.
|
|
|
|
|
|
|
|
|
|
### U5. Expose the complete fixed-template library to projects
|
|
|
|
|
|
|
|
|
|
**Goal:** Ensure every fixed company template across business and R&D phases is cataloged and available for explicit project use without adding document-duty assignment.
|
|
|
|
|
|
|
|
|
|
**Requirements:** R9, R10
|
|
|
|
|
|
|
|
|
|
**Dependencies:** None for inventory; project access read boundary from U3/U4 for project exposure
|
|
|
|
|
|
|
|
|
|
**Files:**
|
|
|
|
|
- `Agent-System-RDM/internal/domain/template_asset.go`
|
|
|
|
|
- `Agent-System-RDM/internal/rdmapp/dhf_catalog.go`
|
|
|
|
|
- `Agent-System-RDM/internal/rdmapp/templates/dhf/catalog.json`
|
|
|
|
|
- `Agent-System-RDM/internal/rdmapp/dhf_template_instance.go`
|
|
|
|
|
- `Agent-System-RDM/internal/rdmapp/dhf_catalog_test.go`
|
|
|
|
|
- `Agent-System-RDM/internal/rdmapp/dhf_template_instance_test.go`
|
|
|
|
|
- Source inventory and generated catalog tests
|
|
|
|
|
|
|
|
|
|
**Approach:**
|
|
|
|
|
|
|
|
|
|
1. Refresh source inventory and verify the fixed-template set from company sources; retain all 44 DHF source identities and include other fixed templates if present.
|
|
|
|
|
2. Reconcile source path/hash, template ID/version, business/R&D phase, applicability, format, publication/readiness, and supported generation status. Do not replace templates with the 69 legacy skeleton types or infer missing mappings from similar names.
|
|
|
|
|
3. Connect the complete catalog to project-level browse/select behavior. Instantiate only a selected template and preserve exact source/version provenance.
|
|
|
|
|
4. Surface blocked or unsupported fidelity/generation status honestly. Catalog inclusion does not claim that every `.doc` or render profile is fully faithful.
|
|
|
|
|
5. Do not add or invoke assignment of author/reviewer/approver duties, approval flows, or new lifecycle transitions.
|
|
|
|
|
|
|
|
|
|
**Test scenarios:**
|
|
|
|
|
|
|
|
|
|
- The catalog has one traceable entry for every inventoried source, including duplicate-byte files with distinct source identities.
|
|
|
|
|
- All fixed business and R&D phase templates appear in the project template browser with source/version/phase metadata.
|
|
|
|
|
- An explicitly selected supported template creates one instance with exact source/version provenance.
|
|
|
|
|
- Unsupported/blocked templates are visible with their real state and cannot be represented as successfully generated.
|
|
|
|
|
- No project creation path automatically creates all template instances or duty assignments.
|
|
|
|
|
|
|
|
|
|
**Verification:** Template source-inventory, catalog, supported-generation, and project integration tests prove completeness and provenance for the refreshed source snapshot.
|
|
|
|
|
|
|
|
|
|
### U6. Present role, member, and project-state controls
|
|
|
|
|
|
|
|
|
|
**Goal:** Make the permission and read-only states clear in the existing admin, role, project, and member interfaces.
|
|
|
|
|
|
|
|
|
|
**Requirements:** R1-R10, R13
|
|
|
|
|
|
|
|
|
|
**Dependencies:** U1-U5 API contracts
|
|
|
|
|
|
|
|
|
|
**Files:**
|
|
|
|
|
- `Agent-System-Dev/modules/frontend/src/components/RolePermissionsPanel.tsx`
|
|
|
|
|
- `Agent-System-Dev/modules/frontend/src/components/AccountUsersPanel.tsx`
|
|
|
|
|
- `Agent-System-Dev/modules/frontend/src/components/TaskSidebar.tsx`
|
|
|
|
|
- Existing project settings/member components
|
|
|
|
|
- `Agent-System-Dev/modules/frontend/test/role-permissions*.test.ts`
|
|
|
|
|
- Relevant project access and browser tests
|
|
|
|
|
- `Agent-System-Dev/DESIGN.md`
|
|
|
|
|
|
|
|
|
|
**Approach:**
|
|
|
|
|
|
|
|
|
|
1. Role UI shows one project-access checkbox to authorized role managers. A newly created role is selected with an editable project-access checkbox when the actor has `system.roles.manage`; unrelated `system.permissions.manage` state does not disable it. Read-only users receive a clear reason.
|
|
|
|
|
2. System/admin actions appear only in the protected system-administration area and reflect the current super-admin/admin contract.
|
|
|
|
|
3. Project management controls are visible and accepted only for the creator with project access. The UI uses service-provided state; server authorization remains authoritative.
|
|
|
|
|
4. Show project closed, member suspended, and removed/read-only states distinctly, with write controls disabled or absent while read access remains.
|
|
|
|
|
5. Surface the fixed-template catalog and explicit selection state. Do not add document-duty assignment UI.
|
|
|
|
|
6. Follow the existing UI design tokens, responsive behavior, accessibility, and async sequence ownership in `DESIGN.md`.
|
|
|
|
|
|
|
|
|
|
**Test scenarios:**
|
|
|
|
|
|
|
|
|
|
- Role users see only the project-access control; admins see only their authorized admin actions.
|
|
|
|
|
- A role manager without `system.permissions.manage` sees an editable project-access checkbox after creating a role and can save/reload its value; a read-only role viewer gets a clear explanation and cannot submit a direct write.
|
|
|
|
|
- The role editor does not grant the same actor access to system-grant or platform-limit changes.
|
|
|
|
|
- A non-creator cannot discover active project-management controls, and a direct API request remains denied.
|
|
|
|
|
- Active project/member affordances work; suspended/closed/removed states show read-only behavior with all work actions blocked.
|
|
|
|
|
- A late response cannot restore active controls after account switch, state transition, or membership revocation.
|
|
|
|
|
- Template browsing shows all catalog entries while no duty-assignment control is introduced.
|
|
|
|
|
|
|
|
|
|
**Verification:** Frontend typecheck/unit tests and focused Playwright flows pass at desktop and narrow viewport sizes; design guard remains green.
|
|
|
|
|
|
|
|
|
|
## System-Wide Impact
|
|
|
|
|
|
|
|
|
|
- **Users:** Role editing becomes smaller; project creation and management become predictable; removed/suspended members retain read-only history but cannot resume work.
|
|
|
|
|
- **Administrators:** System/user duties remain in protected admin surfaces, separate from job-role permissions. System administrators do not gain project contents by virtue of their status.
|
|
|
|
|
- **RDM:** Remains authoritative for canonical projects, membership/state, template catalog, and domain content. Member deletion, project closure, and creator management checks require coordinated domain/API updates.
|
|
|
|
|
- **Backend:** Continues to own identity and role authority and must fence conversation writes and continuations using current authorization, not UI claims.
|
|
|
|
|
- **Compatibility:** Existing role data, active membership, project archive/close fields, host-project projections, conversation privacy, and template identities require explicit migration/compatibility tests. Dev's RDM pin must be aligned only through the normal reviewed cross-repository process.
|
|
|
|
|
|
|
|
|
|
## Verification Contract
|
|
|
|
|
|
|
|
|
|
| Scope | Verification | Proves |
|
|
|
|
|
|---|---|---|
|
|
|
|
|
| Backend role authority | Focused `go test` for `internal/authz`, `internal/store`, and `internal/server` role/authz tests | Protected system actions remain admin-only; role project access gates creation; migrations do not elevate users |
|
|
|
|
|
| RDM authorization and state | Focused tests for `internal/perms`, `internal/members`, `internal/projects`, and `internal/rdmapp` | Creator identity, member/project states, removal history, privacy and execution gates |
|
|
|
|
|
| Database portability | Existing isolated PostgreSQL test harness for affected Backend/RDM migration and concurrency tests | SQLite/PostgreSQL parity, conflict handling, and transaction fencing |
|
|
|
|
|
| Template inventory | Catalog/source/hash checks plus supported generation tests | Complete fixed-template coverage with exact source provenance and honest fidelity state |
|
|
|
|
|
| Frontend | Focused Vitest/typecheck and browser tests for role, project, member, status, and template flows | Correct affordances and read-only behavior across real UI transitions |
|
|
|
|
|
| Integrated candidate | `make test-worktree`, `scripts/check-pins.sh`, and the applicable Dev composition suite once on the final fixed candidate | Exact cross-repository composition is buildable and matches reviewed component pins |
|
|
|
|
|
| Delivery | Independent review, exact-head required CI, PR base/target checks and task evidence under `policy/delivery.md` and `policy/governance.md` | Reviewed candidate is deliverable; local SELF results are not presented as CI or runtime acceptance |
|
|
|
|
|
|
|
|
|
|
No deployment, production database migration, live permission rewrite, or business-account acceptance is included. Runtime behavior remains `NOT_RUN` until separately authorized and validated against the exact deployed composition.
|
|
|
|
|
|
|
|
|
|
## Definition of Done
|
|
|
|
|
|
|
|
|
|
- Role permission API and UI offer only project access; system settings, user/account, role, and platform-permission actions remain admin/super-admin controlled.
|
|
|
|
|
- Project creation requires effective project access; project management additionally requires exact canonical creator identity and current enabled state.
|
|
|
|
|
- Active members can see projects and create personal conversations. Suspended/removed members and closed projects reject all new and continued work while preserving the agreed read-only history.
|
|
|
|
|
- Authorization is rechecked for synchronous, queued, resumed, retried, streamed, and confirmation-triggered side effects.
|
|
|
|
|
- Every fixed company template is inventoried and available to projects with traceable identity, phase, version, and supported-generation status; specific template instances are created only on selection.
|
|
|
|
|
- No document-duty assignment functionality is added or newly connected; existing private data and duty history remain unchanged.
|
|
|
|
|
- Focused Backend, RDM SQLite/PostgreSQL, Frontend/browser, and exact Dev composition checks pass for the final candidate; independent review and required exact-head CI pass before merge.
|
|
|
|
|
- No deployment, production data change, release/tag publication, or live-user permission adjustment is performed under this plan.
|