TenantAtlas/.specify/templates/plan-template.md
ahmido 55aef627aa feat: harden finding governance health surfaces (#197)
## Summary
- harden findings and finding-exception Filament surfaces so workflow state, governance validity, overdue urgency, and next action are operator-first
- add tenant stats widgets, segmented tabs, richer governance warnings, and baseline/dashboard attention propagation for overdue and lapsed governance states
- add Spec 166 artifacts plus regression coverage for findings, badges, baseline summaries, tenantless operation viewer behavior, and critical table standards

## Verification
- `vendor/bin/sail bin pint --dirty --format agent`
- `vendor/bin/sail artisan test --compact`

## Filament Notes
- Livewire v4.0+ compliance: yes, implementation stays on Filament v5 / Livewire v4 APIs only
- Provider registration: unchanged, Laravel 12 panel/provider registration remains in `bootstrap/providers.php`
- Global search: unchanged in this slice; `FindingExceptionResource` stays not globally searchable, no new globally searchable resource was introduced
- Destructive actions: existing revoke/reject/approve/renew/workflow mutations remain capability-gated and confirmation-gated where already defined
- Asset strategy: no new assets added; existing deploy process remains unchanged, including `php artisan filament:assets` when registered assets are used
- Testing plan delivered: findings list/detail, exception register, dashboard attention, baseline summary, badge semantics, and tenantless operation viewer coverage

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #197
2026-03-28 10:11:12 +00:00

12 KiB

Implementation Plan: [FEATURE]

Branch: [###-feature-name] | Date: [DATE] | Spec: [link] Input: Feature specification from /specs/[###-feature-name]/spec.md

Note: This template is filled in by the /speckit.plan command. See .specify/scripts/ for helper scripts.

Summary

[Extract from feature spec: primary requirement + technical approach from research]

Technical Context

Language/Version: [e.g., Python 3.11, Swift 5.9, Rust 1.75 or NEEDS CLARIFICATION]
Primary Dependencies: [e.g., FastAPI, UIKit, LLVM or NEEDS CLARIFICATION]
Storage: [if applicable, e.g., PostgreSQL, CoreData, files or N/A]
Testing: [e.g., pytest, XCTest, cargo test or NEEDS CLARIFICATION]
Target Platform: [e.g., Linux server, iOS 15+, WASM or NEEDS CLARIFICATION] Project Type: [single/web/mobile - determines source structure]
Performance Goals: [domain-specific, e.g., 1000 req/s, 10k lines/sec, 60 fps or NEEDS CLARIFICATION]
Constraints: [domain-specific, e.g., <200ms p95, <100MB memory, offline-capable or NEEDS CLARIFICATION]
Scale/Scope: [domain-specific, e.g., 10k users, 1M LOC, 50 screens or NEEDS CLARIFICATION]

Constitution Check

GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.

  • Inventory-first: clarify what is “last observed” vs snapshots/backups
  • Read/write separation: any writes require preview + confirmation + audit + tests
  • Graph contract path: Graph calls only via GraphClientInterface + config/graph_contracts.php
  • Deterministic capabilities: capability derivation is testable (snapshot/golden tests)
  • RBAC-UX: two planes (/admin vs /system) remain separated; cross-plane is 404; tenant-context routes (/admin/t/{tenant}/...) are tenant-scoped; canonical workspace-context routes under /admin remain tenant-safe; non-member tenant/workspace access is 404; member-but-missing-capability is 403; authorization checks use Gates/Policies + capability registries (no raw strings, no role-string checks)
  • Workspace isolation: non-member workspace access is 404; tenant-plane routes require an established workspace context; workspace context switching is separate from Filament Tenancy
  • RBAC-UX: destructive-like actions require ->requiresConfirmation() and clear warning text
  • RBAC-UX: global search is tenant-scoped; non-members get no hints; inaccessible results are treated as not found (404 semantics)
  • Tenant isolation: all reads/writes tenant-scoped; cross-tenant views are explicit and access-checked
  • Run observability: long-running/remote/queued work creates/reuses OperationRun; start surfaces enqueue-only; Monitoring is DB-only; DB-only <2s actions may skip runs but security-relevant ones still audit-log; auth handshake exception OPS-EX-AUTH-001 allows synchronous outbound HTTP on /auth/* without OperationRun
  • Ops-UX 3-surface feedback: if OperationRun is used, feedback is exactly toast intent-only + progress surfaces + exactly-once terminal OperationRunCompleted (initiator-only); no queued/running DB notifications
  • Ops-UX lifecycle: OperationRun.status / OperationRun.outcome transitions are service-owned (only via OperationRunService); context-only updates allowed outside
  • Ops-UX summary counts: summary_counts keys come from OperationSummaryKeys::all() and values are flat numeric-only
  • Ops-UX guards: CI has regression guards that fail with actionable output (file + snippet) when these patterns regress
  • Ops-UX system runs: initiator-null runs emit no terminal DB notification; audit remains via Monitoring; tenant-wide alerting goes through Alerts (not OperationRun notifications)
  • Automation: queued/scheduled ops use locks + idempotency; handle 429/503 with backoff+jitter
  • Data minimization: Inventory stores metadata + whitelisted meta; logs contain no secrets/tokens
  • Proportionality (PROP-001): any new structure, layer, persisted truth, or semantic machinery is justified by current release truth, current operator workflow, and why a narrower solution is insufficient
  • No premature abstraction (ABSTR-001): no new factories, registries, resolvers, strategy systems, interfaces, type registries, or orchestration pipelines before at least 2 real concrete cases exist, unless security, tenant isolation, auditability, compliance evidence, or queue correctness require it now
  • Persisted truth (PERSIST-001): new tables/entities/artifacts represent independent product truth or lifecycle; convenience projections and UI helpers stay derived
  • Behavioral state (STATE-001): new states/statuses/reason codes change behavior, routing, permissions, lifecycle, audit, retention, or retry handling; presentation-only distinctions stay derived
  • UI semantics (UI-SEM-001): avoid turning badges, explanation text, trust/confidence labels, or detail summaries into mandatory interpretation frameworks; prefer direct domain-to-UI mapping
  • V1 explicitness / few layers (V1-EXP-001, LAYER-001): prefer direct implementation, local mappings, and small helpers; any new layer replaces an old one or proves the old one cannot serve
  • Spec discipline / bloat check (SPEC-DISC-001, BLOAT-001): related semantic changes are grouped coherently, and any new enum, DTO/presenter, persisted entity, interface/registry/resolver, or taxonomy includes a proportionality review covering operator problem, insufficiency, narrowness, ownership cost, rejected alternative, and whether it is current-release truth
  • Badge semantics (BADGE-001): status-like badges use BadgeCatalog / BadgeRenderer; no ad-hoc mappings; new values include tests
  • Filament-native UI (UI-FIL-001): admin/operator surfaces use native Filament components or shared primitives first; no ad-hoc status UI, local semantic color/border decisions, or hand-built replacements when native/shared semantics exist; any exception is explicitly justified
  • UI naming (UI-NAMING-001): operator-facing labels use Verb + Object; scope (Workspace, Tenant) is never the primary action label; source/domain is secondary unless disambiguation is required; runs/toasts/audit prose use the same domain vocabulary; implementation-first terms do not appear in primary operator UI
  • Operator surfaces (OPSURF-001): /admin defaults are operator-first; default-visible content avoids raw implementation detail; diagnostics are explicitly revealed secondarily
  • Operator surfaces (OPSURF-001): execution outcome, data completeness, governance result, and lifecycle/readiness are modeled as distinct status dimensions when all apply; they are not collapsed into one ambiguous status
  • Operator surfaces (OPSURF-001): every mutating action communicates whether it changes TenantPilot only, the Microsoft tenant, or simulation only before execution
  • Operator surfaces (OPSURF-001): dangerous actions follow configuration → safety checks/simulation → preview → hard confirmation where required → execute, unless a spec documents an explicit exemption and replacement safeguards
  • Operator surfaces (OPSURF-001): workspace and tenant context remain explicit in navigation, actions, and page semantics; tenant surfaces do not silently expose workspace-wide actions
  • Operator surfaces (OPSURF-001): each new or materially refactored operator-facing page defines a page contract covering persona, surface type, operator question, default-visible info, diagnostics-only info, status dimensions, mutation scope, primary actions, and dangerous actions
  • Filament UI Action Surface Contract: for any new/modified Filament Resource/RelationManager/Page, define Header/Row/Bulk/Empty-State actions, ensure every List/Table has a record inspection affordance (prefer recordUrl() clickable rows; do not render a lone View row action), keep max 2 visible row actions with the rest in “More”, group bulk actions, require confirmations for destructive actions (typed confirmation for large/bulk where applicable), write audit logs for mutations, enforce RBAC via central helpers (non-member 404, member missing capability 403), and ensure CI blocks merges if the contract is violated or not explicitly exempted
  • Filament UI UX-001 (Layout & IA): Create/Edit uses Main/Aside (3-col grid, Main=columnSpan(2), Aside=columnSpan(1)); all fields inside Sections/Cards (no naked inputs); View uses Infolists (not disabled edit forms); status badges use BADGE-001; empty states have specific title + explanation + 1 CTA; max 1 primary + 1 secondary header action; tables provide search/sort/filters for core dimensions; shared layout builders preferred for consistency

Project Structure

Documentation (this feature)

specs/[###-feature]/
├── plan.md              # This file (/speckit.plan command output)
├── research.md          # Phase 0 output (/speckit.plan command)
├── data-model.md        # Phase 1 output (/speckit.plan command)
├── quickstart.md        # Phase 1 output (/speckit.plan command)
├── contracts/           # Phase 1 output (/speckit.plan command)
└── tasks.md             # Phase 2 output (/speckit.tasks command - NOT created by /speckit.plan)

Source Code (repository root)

# [REMOVE IF UNUSED] Option 1: Single project (DEFAULT)
src/
├── models/
├── services/
├── cli/
└── lib/

tests/
├── contract/
├── integration/
└── unit/

# [REMOVE IF UNUSED] Option 2: Web application (when "frontend" + "backend" detected)
backend/
├── src/
│   ├── models/
│   ├── services/
│   └── api/
└── tests/

frontend/
├── src/
│   ├── components/
│   ├── pages/
│   └── services/
└── tests/

# [REMOVE IF UNUSED] Option 3: Mobile + API (when "iOS/Android" detected)
api/
└── [same as backend above]

ios/ or android/
└── [platform-specific structure: feature modules, UI flows, platform tests]

Structure Decision: [Document the selected structure and reference the real directories captured above]

Complexity Tracking

Fill when Constitution Check has violations that must be justified OR when BLOAT-001 is triggered by new persistence, abstractions, states, or semantic frameworks.

Violation Why Needed Simpler Alternative Rejected Because
[e.g., 4th project] [current need] [why 3 projects insufficient]
[e.g., Repository pattern] [specific problem] [why direct DB access insufficient]

Proportionality Review

Fill when the feature introduces a new enum/status family, DTO/presenter/envelope, persisted entity/table/artifact, interface/contract/registry/resolver, taxonomy/classification system, or cross-domain UI framework.

  • Current operator problem: [What present-day workflow or risk requires this?]
  • Existing structure is insufficient because: [Why the current code cannot serve safely or clearly]
  • Narrowest correct implementation: [Why this shape is the smallest viable one]
  • Ownership cost created: [Maintenance, testing, cognitive load, migration, or review burden]
  • Alternative intentionally rejected: [Simpler option and why it failed]
  • Release truth: [Current-release truth or future-release preparation]