cb9752b1a2
Co-authored-by: ayattara <alassane.yattara@savoirfairelinux.com> Co-authored-by: Carlos Florencio <carlosmflorencio@gmail.com>
106 lines
4.1 KiB
Markdown
106 lines
4.1 KiB
Markdown
---
|
|
created: 2026-09-07
|
|
status: done
|
|
requirements:
|
|
- REQ-PLUGINS-CAPABILITY-APPROVAL-001
|
|
- REQ-PLUGINS-CAPABILITY-APPROVAL-002
|
|
- REQ-PLUGINS-CAPABILITY-APPROVAL-003
|
|
- REQ-PLUGINS-CAPABILITY-APPROVAL-004
|
|
- REQ-PLUGINS-CAPABILITY-APPROVAL-005
|
|
- REQ-PLUGINS-CAPABILITY-APPROVAL-006
|
|
system_design:
|
|
- ../../specs/plugins/system-design/capability-approval.md
|
|
legacy_specs: []
|
|
---
|
|
|
|
# Implementation Plan: Generic Plugin Capability Approval and Audit (H6)
|
|
|
|
## Overview
|
|
|
|
Add the generic plugin capability-approval substrate as one vertical work
|
|
order: host-minted installation identity, the workspace-scoped approval ledger
|
|
with exact-revision admission, the append-only event trail, the fail-closed
|
|
authorization decision with typed deny reasons, uninstall tombstones with
|
|
reinstall identity, the legacy `v1` fence, and the audit receipt primitives.
|
|
Scope is the substrate only: no approval UI, no coordinator surface, and no
|
|
host receipt persistence.
|
|
|
|
## Scope
|
|
|
|
### In scope
|
|
|
|
- `installation_id` minting and persistence on the plugin store record.
|
|
- One current `CapabilityApproval` per `(installation_id, workspace_id)`.
|
|
- Grant, narrow, revoke, and upgrade-review events in an append-only ledger.
|
|
- Exact-revision admission and audit-id idempotency.
|
|
- Fail-closed `AuthorizeCapability` with stable typed deny reasons.
|
|
- Uninstall tombstone and reinstall identity mints.
|
|
- The `host.v2` exact-capability fence for legacy `v1` declarations.
|
|
- `ApprovalReceipt` and canonical digest primitives.
|
|
|
|
### Out of scope
|
|
|
|
- Approval or review UI, coordinator surfaces, dashboards.
|
|
- Host adapter persistence of audit or read/write receipts.
|
|
- Changes to legacy `v1` runtime behavior beyond fencing it from approval
|
|
authority.
|
|
- H1-H5 plugin capabilities; this initiative is substrate only.
|
|
|
|
### No UI changes
|
|
|
|
This package does not create or change rendered UI, so no ASCII UI preview is
|
|
included.
|
|
|
|
## Technical approach
|
|
|
|
The ledger (`approvals.json` under the plugins directory) owns approvals,
|
|
events, tombstones, and idempotency inputs. One current approval per
|
|
installation/workspace pair is stored keyed by the pair with exact next
|
|
revision admission; every mutation appends an event carrying before/after
|
|
revisions and digests. `installation_id` is minted at install time and
|
|
attached to the store record; reinstall mints fresh identity and tombstones
|
|
block the old identity permanently.
|
|
|
|
The authorization path (`approval_service.go`) is a pure decision function
|
|
that evaluates in a fixed order — malformed request, human-reserved, missing
|
|
approval (including the foreign-workspace alias), revoked or tombstoned,
|
|
stale revision, manifest intersection, approved list — and returns a typed
|
|
decision carrying the audit identity and a bounded receipt. Legacy `v1`
|
|
declarations keep their behavior but are fenced from approval admission and
|
|
authorization.
|
|
|
|
## Tests
|
|
|
|
- `approval_test.go`, `approval_store_test.go`, `approval_service_test.go`:
|
|
canonicalization, exact-revision admission, idempotency, tombstone, and
|
|
reinstall-identity coverage.
|
|
- `approval_api_test.go`, `approval_query_test.go`: API list/get, grant, and
|
|
revoke flows including conflict semantics.
|
|
- `approval_dto_test.go`: DTO shape and receipt bounds.
|
|
- Store install/sync tests: `installation_id` minting and persistence.
|
|
|
|
## E2E tests
|
|
|
|
No new E2E is required: the substrate exposes no UI surface. Go unit and
|
|
integration tests exercise the full ledger and decision matrix; a browser
|
|
duplicate of that matrix would add cost without observable UI coverage.
|
|
|
|
## Work orders
|
|
|
|
- [x] [Task 01: Capability approval substrate](task-01-capability-approval-substrate.md)
|
|
|
|
## Verification results
|
|
|
|
- `cd apps/backend && go build ./...` passed on the H6 head and was
|
|
re-verified on the merged head.
|
|
- `cd apps/backend && go test ./internal/plugins/...` passed in 10 packages
|
|
on the H6 head and was re-verified on the merged head.
|
|
|
|
## Risks
|
|
|
|
- Ledger file corruption must not grant authority: unknown fields decode
|
|
forward-compatibly and missing maps initialize empty, but any decode failure
|
|
must fail closed at lookup.
|
|
- A future policy revision must not silently reinterpret stored approvals:
|
|
the per-row human policy version is the stability point.
|