TenantAtlas/specs/389-governance-inbox-resolution-intake-v1/plan.md
ahmido 9912d94563 feat: add governance inbox resolution intake (#460)
Automated PR created by Codex via Gitea API.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #460
2026-06-20 07:46:12 +00:00

310 lines
22 KiB
Markdown

# Implementation Plan: Governance Inbox Resolution Intake v1
**Branch**: `389-governance-inbox-resolution-intake-v1` | **Date**: 2026-06-19 | **Spec**: `specs/389-governance-inbox-resolution-intake-v1/spec.md`
**Input**: Feature specification from `/specs/389-governance-inbox-resolution-intake-v1/spec.md`
## Summary
Add active Review Publication Resolution Cases to the existing Governance Inbox as a concrete, read-only source family. The inbox should show operator-friendly review publication work items, map existing case/step/proof state into conservative viewer-relative statuses, and navigate only to existing authorized Resolution, Review, or Operation pages. It must reuse Spec 388 proof/currentness semantics or fail closed to `Needs re-check`, and it must not introduce a generic workflow/task engine, inline execution, publish action, customer-facing leakage, or a second proof evaluator.
## Technical Context
**Language/Version**: PHP 8.4.15
**Primary Dependencies**: Laravel 12.52.0, Filament 5.2.1, Livewire 4.1.4, Pest 4.3.1, Laravel Sail
**Storage**: PostgreSQL; no migration expected for v1
**Testing**: Pest 4 Feature, Filament/Livewire Feature, optional Browser smoke
**Validation Lanes**: fast-feedback + confidence; browser when UI smoke is available; PostgreSQL only if a later spec update adds schema/index work
**Target Platform**: Laravel monolith under `apps/platform`, Sail-first locally, Dokploy/container deployment for staging/production
**Project Type**: Web application, existing Filament admin panel
**Performance Goals**: Governance Inbox list rendering remains DB-only and bounded to the existing inbox page limit/profile; no per-row Graph/provider calls
**Constraints**: Read-only intake, no inline mutations, no raw payloads, no customer leakage, no unvalidated operation IDs or links, no generic registry/engine
**Scale/Scope**: One concrete Review Publication Resolution intake source over existing workspace/environment-scoped cases
## UI / Surface Guardrail Plan
- **Guardrail scope**: changed existing operator-facing Governance Inbox surface.
- **Affected routes/pages/actions/states/navigation/panel/provider surfaces**:
- `apps/platform/app/Filament/Pages/Governance/GovernanceInbox.php`
- `apps/platform/app/Support/GovernanceInbox/GovernanceInboxSectionBuilder.php`
- `apps/platform/resources/views/filament/pages/governance/governance-inbox.blade.php` only if the existing rendering shape cannot express required labels/actions
- Existing Environment Review Resolution Page links through `EnvironmentReviewResource::environmentScopedUrl('resolve-publication', ...)`
- Existing OperationRun detail links through `OperationRunLinks` after validation
- **No-impact class, if applicable**: N/A.
- **Native vs custom classification summary**: Existing custom Governance Inbox Blade page using Filament components; reuse current layout and source-family/lanes pattern.
- **Shared-family relevance**: Governance Inbox source family, status messaging, action links, OperationRun links, review/evidence status summaries.
- **State layers in scope**: page source-family data, lane classification, source-detail disclosure, environment filter, query/provider mapping.
- **Audience modes in scope**: operator-MSP, read-only operator/inspector, customer-safe negative boundary.
- **Decision/diagnostic/raw hierarchy plan**: default item copy answers what/why/where/next safe action; operation/proof/source details stay collapsed or linked to existing authorized pages; raw payloads are absent.
- **Raw/support gating plan**: no raw/support detail in inbox. Use existing source detail pages for authorized technical depth.
- **One-primary-action / duplicate-truth control**: each item has one dominant primary action: `Continue preparation`, `Inspect preparation`, or in narrowly validated waiting cases `Open operation`.
- **Handling modes by drift class or surface**: review-mandatory for operation-link disclosure; hard-stop if inline mutation or customer leakage appears.
- **Repository-signal treatment**: existing Governance Inbox and Resolution Page are repo-real; no new navigation/page report unless implementation materially changes UI patterns.
- **Special surface test profiles**: governance workbench / standard-native-filament; browser smoke for representative states where harness exists.
- **Required tests or manual smoke**: functional-core mapping, RBAC/scope negative cases, operation-link disclosure, no inline mutation, no customer leakage, mobile/readability smoke where available.
- **Exception path and spread control**: none. A concrete provider class is allowed; a generic registry is not.
- **Active feature PR close-out entry**: Guardrail + Smoke Coverage if browser smoke runs.
- **UI/Productization coverage decision**: existing strategic surface changed; update audit registry only if runtime implementation materially changes page archetype, route, or design coverage beyond a source-family extension.
- **Coverage artifacts to update**: no coverage artifact update is required during preparation because Spec 389 reuses the existing Governance Inbox route, archetype, and source-family pattern. Implementation must re-check `docs/ui-ux-enterprise-audit/route-inventory.md` and `design-coverage-matrix.md` and update them if runtime work materially changes page archetype, route inventory, strategic-surface classification, or design coverage.
- **No-impact rationale**: N/A.
- **Navigation / Filament provider-panel handling**: no panel provider or navigation registration changes.
- **Screenshot or page-report need**: screenshots recommended under this spec if browser harness is available; no new page report by default.
## Shared Pattern & System Fit
- **Cross-cutting feature marker**: yes.
- **Systems touched**:
- Governance Inbox page and source-family builder.
- Review Publication Resolution case/step/proof state.
- Environment Review resource URLs.
- OperationRun link and policy systems.
- Capability-first RBAC and workspace/environment scope enforcement.
- **Shared abstractions reused**:
- Existing `GovernanceInboxSectionBuilder` entry shape and `GovernanceInbox` lane normalization.
- Existing `ReviewPublicationResolutionCasePolicy`.
- Existing `ReviewPublicationResolutionStepAuthorizer`.
- Existing Spec 388 `ResolutionProofEvaluation`/currentness metadata.
- Existing `OperationRunLinks` and `OperationRunPolicy`.
- **New abstraction introduced? why?**: Prefer a small concrete `ReviewPublicationResolutionInboxProvider` if direct builder growth would make scope/currentness mapping hard to review. It must not be a registry, interface hierarchy, or generic adapter framework.
- **Why the existing abstraction was sufficient or insufficient**: Existing Governance Inbox builder is sufficient for rendering and lane normalization; it lacks only a concrete source of Review Publication Resolution Cases.
- **Bounded deviation / spread control**: provider may return normalized display arrays or a lightweight DTO only for this source family. Future adapters need separate specs.
## OperationRun UX Impact
- **Touches OperationRun start/completion/link UX?**: yes, link display only.
- **Central contract reused**: `OperationRunLinks` for labels/URLs and `OperationRunPolicy` for authorization after additional context/currentness validation.
- **Delegated UX behaviors**: tenant/workspace-safe URL resolution only; no queued toast, artifact link, browser event, dedupe/start failure, or terminal notification changes.
- **Surface-owned behavior kept local**: deciding whether a validated operation link is shown for an inbox item.
- **Queued DB-notification policy**: N/A.
- **Terminal notification path**: N/A.
- **Exception path**: none.
## Provider Boundary & Portability Fit
- **Shared provider/platform boundary touched?**: no new shared provider boundary.
- **Provider-owned seams**: existing report/evidence/review-pack preparation remains owned by Review Publication Resolution and source services.
- **Platform-core seams**: Governance Inbox consumes safe work item summaries and links only.
- **Neutral platform terms / contracts preserved**: workspace, environment, review, operation, proof, preparation, governance inbox.
- **Retained provider-specific semantics and why**: required report dimensions may originate in Microsoft/Entra workflows, but the inbox presents human labels only and does not expose provider payloads.
- **Bounded extraction or follow-up path**: future restore/provider/baseline/report delivery intakes are follow-up specs only.
## Constitution Check
*GATE: Must pass before implementation. Re-check after implementation design is finalized.*
- Inventory-first: N/A for new inventory; consumes existing review/resolution artifacts only.
- Read/write separation: PASS. Governance Inbox remains read-only; all writes stay on source-owned Resolution/Review pages with existing confirmation/audit.
- Graph contract path: PASS. No Graph calls may occur during inbox render.
- Deterministic capabilities: PASS. Use existing capability resolvers/policies; no raw role strings.
- RBAC-UX: PASS. Workspace membership, environment entitlement, review/case permission, 404/403 semantics, and server-side policies stay authoritative.
- Workspace isolation: PASS. Queries must scope by workspace before mapping.
- Tenant/environment isolation: PASS. Environment-specific cases must not appear outside authorized environments or another environment filter.
- Run observability: PASS. No new operation starts; linked OperationRuns remain execution truth.
- OperationRun start UX: PASS. Only safe links are displayed; no start UX added.
- Ops-UX lifecycle: PASS. No OperationRun status/outcome changes.
- Summary counts contract: N/A.
- Ops-UX guards: N/A unless implementation touches operation guard patterns.
- Data minimization: PASS. Safe metadata is display-only and excludes raw payloads/secrets/tokens/exceptions/fingerprints/reason codes by default.
- Test governance: PASS if tasks add focused Feature/Filament/browser tests with explicit lane classification.
- Proportionality: PASS. One concrete provider/mapping is justified by an existing workflow visibility gap.
- No premature abstraction: PASS. No registry/engine/generic adapter is approved.
- Persisted truth: PASS. No new persistence.
- Behavioral state: PASS. Inbox status is derived viewer-relative display only.
- UI semantics: PASS if direct mapping from canonical case/step/safe proof state is used without a new taxonomy framework.
- Shared pattern first: PASS. Existing Governance Inbox and OperationRun links are reused.
- Provider boundary: PASS. No platform-core provider coupling added.
- V1 explicitness / few layers: PASS. Direct source-specific mapping preferred.
- Spec discipline / bloat check: PASS. Scope is one coherent, narrow spec.
- Filament-native UI: PASS. Existing Filament primitives and page pattern reused.
- Decision-first operating model: PASS. Existing Governance Inbox remains the primary decision surface; no new navigation.
- Audience-aware disclosure: PASS. Customer-facing surfaces do not receive internal resolution intake.
- UI/Productization coverage: PASS. Existing strategic surface change is classified.
## Test Governance Check
- **Test purpose / classification by changed surface**: Feature for mapping and RBAC/scope; Filament/Livewire Feature for page rendering; Browser for representative visual/user workflow and mobile/customer no-leakage if harness exists.
- **Affected validation lanes**: fast-feedback, confidence, optional browser.
- **Why this lane mix is the narrowest sufficient proof**: Runtime change is read-only mapping/UI. It does not need PostgreSQL unless indexes/migrations are later added.
- **Narrowest proving command(s)**:
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/GovernanceInbox/Spec389GovernanceInboxResolutionIntakeTest.php`
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/EnvironmentReview/Spec386ReviewPublicationResolutionWorkflowTest.php tests/Feature/EnvironmentReview/Spec387ReviewPublicationResolutionDecisionUxTest.php tests/Feature/EnvironmentReview/Spec388ReviewPublicationProofCurrentnessTest.php`
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser/Spec389GovernanceInboxResolutionIntakeTest.php` if added
- `cd apps/platform && ./vendor/bin/pint --dirty --format agent`
- `git diff --check`
- **Fixture / helper / factory / seed / context cost risks**: Review/resolution/operation fixtures can be expensive. Keep helpers explicit and local; do not broaden global defaults.
- **Expensive defaults or shared helper growth introduced?**: no planned shared default growth.
- **Heavy-family additions, promotions, or visibility changes**: optional browser smoke must be explicit in file name and validation notes.
- **Surface-class relief / special coverage rule**: existing governance workbench surface; browser only for representative states and mobile clarity.
- **Closing validation and reviewer handoff**: verify no inline mutation, no publish, no generic engine, no operation ID leakage, no customer leakage, and correct needs-recheck fallback.
- **Budget / baseline / trend follow-up**: none expected; document-in-feature if browser fixture scope grows materially.
- **Review-stop questions**: Did every operation link pass more than permission? Did stale state fail closed? Did read-only users avoid execution? Did customers see nothing internal?
- **Escalation path**: document-in-feature for contained fixture cost; follow-up-spec for repeated generic-intake pressure.
- **Active feature PR close-out entry**: Guardrail / Smoke Coverage.
- **Why no dedicated follow-up spec is needed**: v1 is source-specific and bounded. Generic intake for future adapters is explicitly rejected.
## Project Structure
### Documentation (this feature)
```text
specs/389-governance-inbox-resolution-intake-v1/
|-- artifacts/
| `-- current-governance-inbox-inventory.md
|-- checklists/
| `-- requirements.md
|-- contracts/
| |-- review-publication-resolution-inbox-item.md
| `-- status-mapping.md
|-- plan.md
|-- spec.md
`-- tasks.md
```
### Source Code (repository root)
Likely runtime surfaces for later implementation:
```text
apps/platform/
|-- app/
| |-- Filament/
| | |-- Pages/Governance/GovernanceInbox.php
| | `-- Resources/EnvironmentReviewResource/
| | `-- Pages/ResolveReviewPublication.php
| |-- Models/
| | |-- ReviewPublicationResolutionCase.php
| | `-- ReviewPublicationResolutionStep.php
| |-- Policies/
| | |-- OperationRunPolicy.php
| | `-- ReviewPublicationResolutionCasePolicy.php
| `-- Support/
| |-- GovernanceInbox/
| | |-- GovernanceInboxSectionBuilder.php
| | `-- ReviewPublicationResolutionInboxProvider.php (candidate)
| |-- OperationRunLinks.php
| `-- ReviewPublicationResolution/
| |-- ReviewPublicationProofResolver.php
| |-- ReviewPublicationResolutionCaseStatus.php
| |-- ReviewPublicationResolutionStepAuthorizer.php
| `-- ReviewPublicationResolutionStepStatus.php
|-- resources/views/filament/pages/governance/governance-inbox.blade.php
`-- tests/
|-- Feature/GovernanceInbox/Spec389GovernanceInboxResolutionIntakeTest.php
`-- Browser/Spec389GovernanceInboxResolutionIntakeTest.php (if browser coverage is added)
```
## Technical Approach
1. Extend the existing Governance Inbox data pipeline with a concrete Review Publication Resolution source family.
2. Query `ReviewPublicationResolutionCase` records scoped by workspace and authorized environment IDs before any item mapping.
3. Eager-load only display-safe relationships: `tenant`, `environmentReview`, `assignee`, `creator`, `steps.operationRun`, and current step data as needed.
4. Map each visible case into the existing Governance Inbox entry shape or a lightweight display DTO that is immediately normalized by the existing page.
5. Add bounded status, environment, type/source-family, and updated-date filtering using the existing Governance Inbox query-string and filter conventions. Updated-date v1 presets are `Any time`, `Last 24 hours`, `Last 7 days`, and `Last 30 days`.
6. Compute viewer-relative inbox status from existing case status, current step status, StepAuthorizer result, and Spec 388 proof/currentness metadata.
7. Revalidate any OperationRun link with:
- same workspace
- same environment
- same EnvironmentReview context where available
- same Resolution Case and current Step
- expected operation/action type for the step
- Spec 388 currentness/usability/visibility rules
- `OperationRunPolicy::view`
8. If validation cannot be done cheaply and safely in list rendering, show `Needs re-check` and link to the Resolution Page.
9. Render default item copy through existing Governance Inbox lanes/source detail without exposing internal keys or raw metadata.
## Domain / Model Implications
- No new persisted model is planned.
- `ReviewPublicationResolutionCase` remains workflow state, not inbox truth.
- `ReviewPublicationResolutionStep` remains step/proof state, not inbox truth.
- Inbox status is derived per viewer and must not be written back.
- `completed`, `cancelled`, and `superseded` are hidden by default.
- Existing `assigned_to_user_id`, `status`, `updated_at`, and `managed_environment_id` indexes from Spec 386 should be used before adding schema churn.
## UI / Filament Implications
- Livewire v4.0+ compliance: the app runs Livewire 4.1.4 and no Livewire v3 APIs are planned.
- Provider registration location: no panel provider changes; Laravel 12 panel providers remain in `apps/platform/bootstrap/providers.php`.
- Global search: no new Resource and no new global-search surface. Existing global search rules remain unchanged.
- Destructive/high-impact actions: none added to Governance Inbox. Existing Resolution Page actions keep confirmation, authorization, audit, and tests.
- Asset strategy: no new registered Filament assets expected; `filament:assets` is not newly required by this spec.
- Testing plan: Feature/Filament tests for the Governance Inbox item mapping/rendering and optional browser smoke for representative states.
## RBAC / Policy Implications
- Use existing workspace membership and environment entitlement patterns.
- Use `ReviewPublicationResolutionCasePolicy::view` for case visibility.
- Use `ReviewPublicationResolutionStepAuthorizer` only to derive viewer-relative `ready_to_continue` versus `blocked`/inspection behavior.
- Use `OperationRunPolicy::view` as necessary but not sufficient for operation disclosure.
- Hide inaccessible rows instead of exposing counts.
- Preserve read-only inspection behavior for users who can view cases but cannot execute steps.
## Audit / Logging / Evidence Implications
- Inbox list rendering does not emit audit events.
- Clicking a navigation link may rely on existing page-level behavior; no new audit event is required unless implementation adds persisted state, which is not planned.
- No raw provider, Graph, evidence, report, exception, token, secret, readiness fingerprint, proof reason code, or operation metadata should be logged or rendered from the inbox.
## Data / Migration Implications
- Preferred: no migration.
- Existing Spec 386 migration already added:
- `review_publication_cases_status_idx`
- `review_publication_cases_review_action_idx`
- `review_publication_cases_assigned_to_idx`
- step `operation_run_id` index
- active-current partial unique index
- summary GIN indexes
- A new index may be considered only if implementation proves the current query path is too slow and the spec/plan are updated first.
## Performance Plan
- Scope by workspace first.
- Filter active statuses by default.
- Filter environment IDs before mapping.
- Eager-load required references in one query path.
- Avoid per-row Graph/provider/API calls.
- Avoid full readiness recomputation for every row.
- Limit default result count to the existing inbox pattern or 25 if a new provider pagination boundary is required.
- Use `Needs re-check` when currentness validation would be expensive or unsafe.
## Implementation Phases
### Phase 1 - Inventory and Contract Verification
Re-read the existing Governance Inbox, Review Publication Resolution, policy, OperationRun link, and Spec 388 proof/currentness surfaces. Verify the mapping contracts in this package match current repo truth before code edits.
### Phase 2 - Provider / Mapping Core
Implement a concrete provider or builder extension that queries visible active cases, maps case/step/proof state into inbox entries, hides default inactive states, and sorts by severity/status.
### Phase 3 - Operation Link and Currentness Hardening
Add operation-link validation beyond `OperationRunPolicy::view`, including scope/context/current step/expected type/currentness checks. Fall back to `Needs re-check` when unsafe.
### Phase 4 - Governance Inbox UI Integration
Add the source family/filter/section to the existing inbox rendering with decision-first labels and existing lane/source-detail behavior. Keep customer-facing surfaces untouched.
### Phase 5 - Tests, Browser Smoke, and Close-Out
Add focused Feature/Filament tests, optional browser smoke/screenshots, run focused regression commands, run Pint/diff checks, and record implementation close-out without claiming unrun suite coverage.
## Risk Controls
- **Generic engine risk**: only one concrete item type and provider/family; no registry.
- **Inline action risk**: no step/publish/cancel actions in inbox; links only.
- **Currentness risk**: use Spec 388 semantics or `Needs re-check`.
- **Operation ID disclosure risk**: hide ID/link unless every validation passes.
- **Customer leakage risk**: add negative tests; customer workspace remains separate.
- **Performance risk**: DB-only scoped query, eager loading, no full recomputation loop.
- **Viewer-relative confusion risk**: never persist inbox status; label read-only users as inspect/blocked where appropriate.
## Spec Readiness Gate
This plan is ready for a later implementation loop when:
- `spec.md`, `plan.md`, `tasks.md`, contracts, checklist, and inventory artifacts exist.
- No unresolved clarification markers remain.
- The tasks cover mapping, UI integration, RBAC/scope, operation-link hardening, currentness fallback, safe metadata, empty states, tests, browser smoke, and validation.
- The implementation scope remains a bounded source-specific intake over existing Review Publication Resolution truth.