Files
yidaima/RuoYi-Vue/docs/superpowers/plans/2026-07-11-plugin-separation-of-duties-approval.md

90 lines
4.0 KiB
Markdown
Raw Normal View History

# Plugin Separation-of-Duties Approval Implementation Plan
> **For agentic workers:** Implement task-by-task with tests first. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Replace the execution operator's inline approval assertion with persistent, independently approved, expiring, revocable, single-use evidence.
**Architecture:** A Transition-scoped approval journal freezes requester roles and routing identity. Decisions and executions share one Transition-first lock order. Execution copies a complete audit snapshot, atomically consumes the approved row, and only then creates receipts and Outbox work.
**Tech Stack:** Java 8, Spring Boot 2.5, Spring Security, MyBatis, MySQL 5.7-compatible SQL, JUnit 4, Vue 2, Element UI.
### Task 1: Policy And Identity
**Files:**
- Modify: `PluginExecutionProperties.java`
- Create: `PluginApprovalPolicy.java`
- Modify: `PluginExecutionRoutingPolicy.java`
- Test: approval and routing policy tests
- [x] Add bounded request and approved-evidence TTLs, separation switch, and role allowlists.
- [x] Canonicalize and freeze actor role snapshots.
- [x] Reject self-approval and disallowed roles.
- [x] Include all approval policy settings in routing identity.
- [x] Remove the direct execution-request approval shortcut.
### Task 2: Persistent Lifecycle
**Files:**
- Create: approval domain and request models
- Modify: execution domain audit snapshot
- Modify: `PluginTransitionExecutionMapper.java` and XML
- Modify: Factory full and upgrade SQL scripts
- [x] Add PENDING, APPROVED, REVOKED, CONSUMED, and EXPIRED states.
- [x] Persist request, decision, revocation, consumption, and expiry evidence.
- [x] Add immutable requester/approver snapshots to execution rows.
- [x] Add guarded lifecycle updates and single-execution uniqueness.
- [x] Keep schema upgrades compatible with MySQL 5.7.
### Task 3: Service And Concurrency
**Files:**
- Modify: `PluginTransitionExecutionService.java`
- Test: `PluginTransitionExecutionServiceTest.java`
- [x] Implement request, list, approve, and revoke operations under the Transition lock.
- [x] Bind approval to exact mode, Transition, routing, environment, and Executor.
- [x] Apply lazy request and evidence expiry.
- [x] Consume exactly one approved row before receipts and Outbox creation.
- [x] Expire sibling requests after consumption and reject post-consumption revocation.
- [x] Test expiry, self-approval, revocation, consumption races, and immutable audit snapshots.
### Task 4: API And Permissions
**Files:**
- Modify: `FeaturePluginController.java`
- Modify: Registry and delivery status models
- Modify: `sql/plugin_registry_menu.sql`
- Test: `FeaturePluginControllerTest.java`
- [x] Add Transition approval request, list, approve, and revoke endpoints.
- [x] Pass authenticated role keys into the policy layer.
- [x] Separate execute/request permission from approve/revoke permission.
- [x] Expose non-secret policy status without target credentials.
- [x] Add a reflection contract test for permission separation.
### Task 5: Dual-Person UI
**Files:**
- Modify: `ruoyi-ui/src/api/generator/plugin.js`
- Modify: Plugin and delivery verification views
- Modify: `ruoyi-ui/test/pluginRegistryView.test.mjs`
- [x] Add approval lifecycle API functions.
- [x] Add a Transition approval table with request, approve, revoke, expiry, and audit details.
- [x] Select only matching approved evidence for real execution.
- [x] Preserve dry-run confirmation without approval evidence.
- [x] Show consumed requester/approver evidence in execution history.
### Task 6: Documentation And Regression
**Files:**
- Create: this implementation plan and the matching design document
- Modify: AI Software Factory roadmap
- [x] Document identity, locks, expiry, revocation, consumption, and boundaries.
- [x] Run 162 focused Plugin tests.
- [x] Run 805 generator tests: 787 pass and the exact 18 known baseline failures remain.
- [x] Run 38 admin tests, four frontend static tests, and the production build.
- [x] Confirm the existing development endpoints return HTTP 200.