diff --git a/.github/agents/copilot-instructions.md b/.github/agents/copilot-instructions.md index 8b0d2d7..7847cb9 100644 --- a/.github/agents/copilot-instructions.md +++ b/.github/agents/copilot-instructions.md @@ -96,6 +96,7 @@ ## Active Technologies - PostgreSQL with new tenant-owned exception tables and JSONB-backed supporting metadata (001-finding-risk-acceptance) - PHP 8.4, Laravel 12, Livewire 4, Filament 5 + Filament resources/pages/actions, Eloquent models, queued Laravel jobs, existing `EvidenceSnapshotService`, existing `ReviewPackService`, capability registry, `OperationRunService` (155-tenant-review-layer) - PostgreSQL with JSONB-backed summary payloads and tenant/workspace ownership columns (155-tenant-review-layer) +- PostgreSQL-backed existing domain records; no new business-domain table is required for the first slice; shared taxonomy reference will live in repository documentation and code-level metadata (156-operator-outcome-taxonomy) - PHP 8.4.15 (feat/005-bulk-operations) @@ -115,8 +116,8 @@ ## Code Style PHP 8.4.15: Follow standard conventions ## Recent Changes +- 156-operator-outcome-taxonomy: Added PHP 8.4.15 + Laravel 12, Filament v5, Livewire v4, PostgreSQL, Laravel Sail, Pest v4 - 155-tenant-review-layer: Added PHP 8.4, Laravel 12, Livewire 4, Filament 5 + Filament resources/pages/actions, Eloquent models, queued Laravel jobs, existing `EvidenceSnapshotService`, existing `ReviewPackService`, capability registry, `OperationRunService` - 001-finding-risk-acceptance: Added PHP 8.4.15 + Laravel 12, Filament v5, Livewire v4, Pest v4, existing Finding, AuditLog, EvidenceSnapshot, CapabilityResolver, WorkspaceCapabilityResolver, and UiEnforcement patterns -- 153-evidence-domain-foundation: Added PHP 8.4.15 + Laravel 12, Filament v5, Livewire v4, Pest v4, existing `StoredReport`, `Finding`, `OperationRun`, and `AuditLog` infrastructure diff --git a/.specify/memory/constitution.md b/.specify/memory/constitution.md index 81e72a5..b8476e1 100644 --- a/.specify/memory/constitution.md +++ b/.specify/memory/constitution.md @@ -3,12 +3,17 @@ - Version change: 1.11.0 → 1.12.0 - Modified principles: - - Scope & Ownership Clarification (SCOPE-001) -- Added sections: - None +- Added sections: + - Operator Surface Principles (OPSURF-001) - Removed sections: None - Templates requiring updates: - - None + - ✅ .specify/templates/spec-template.md + - ✅ .specify/templates/plan-template.md + - ✅ .specify/templates/tasks-template.md + - ✅ docs/product/principles.md + - ✅ docs/product/standards/README.md + - ✅ docs/HANDOVER.md - Follow-up TODOs: - None. --> @@ -330,6 +335,65 @@ ### Operator-facing UI Naming Standards (UI-NAMING-001) - The visible run label for that action MUST be `Policy sync`. - The audit prose for that action MUST be `{actor} queued policy sync`. +### Operator Surface Principles (OPSURF-001) + +Goal: operator-facing surfaces MUST optimize for the primary working audience rather than raw implementation visibility. + +Operator-first default surfaces +- `/admin` is operator-first. +- Default-visible content MUST use operator-facing language, clear scope, and actionable status communication. +- Raw implementation details MUST NOT be default-visible on primary operator surfaces. + +Progressive disclosure for diagnostics +- Diagnostic detail MAY be available where needed, but it MUST be secondary and explicitly revealed. +- JSON payloads, raw IDs, internal field names, provider error details, and low-level technical metadata belong in diagnostics surfaces, drawers, tabs, accordions, or modals rather than primary content. +- A surface MUST NOT require operators to parse raw JSON or provider-specific field names to understand the primary state or next action. + +Distinct status dimensions +- Operator-facing surfaces MUST distinguish at least the following dimensions when they all exist in the domain: + - execution outcome + - data completeness + - governance result + - lifecycle or readiness state +- These dimensions MUST NOT be collapsed into a single ambiguous status model. +- If a surface summarizes multiple status dimensions, the default-visible presentation MUST label each dimension explicitly. + +Explicit mutation scope +- Every action that changes state MUST communicate before execution whether it affects: + - TenantPilot only + - the Microsoft tenant + - simulation only +- Mutation scope MUST be understandable from the action label, helper text, confirmation copy, preview, or nearby status copy before the operator commits. +- A mutating action MUST NOT rely on hidden implementation knowledge to communicate its blast radius. + +Safe execution for dangerous actions +- Dangerous actions MUST follow a consistent safe-execution pattern: + - configuration + - safety checks or simulation + - preview + - hard confirmation where required + - execute +- One-click destructive actions are not acceptable for high-blast-radius operations. +- When a full multi-step flow is not feasible, the spec MUST document the explicit exemption and the replacement safeguards. + +Explicit workspace and tenant context +- Workspace and tenant scope MUST remain explicit in navigation, actions, and page semantics. +- Tenant-scoped surfaces MUST NOT silently expose workspace-wide actions. +- Canonical workspace views that reference tenant-owned records MUST make the workspace and tenant context legible before the operator acts. + +Page contract requirement +- Every new or materially refactored operator-facing page MUST define: + - primary persona + - surface type + - primary operator question + - default-visible information + - diagnostics-only information + - status dimensions used + - mutation scope + - primary actions + - dangerous actions +- This page contract MUST be recorded in the governing spec and kept in sync when the page semantics materially change. + Spec Scope Fields (SCOPE-002) - Every feature spec MUST declare: @@ -387,4 +451,4 @@ ### Versioning Policy (SemVer) - **MINOR**: new principle/section or materially expanded guidance. - **MAJOR**: removing/redefining principles in a backward-incompatible way. -**Version**: 1.11.0 | **Ratified**: 2026-01-03 | **Last Amended**: 2026-03-10 +**Version**: 1.12.0 | **Ratified**: 2026-01-03 | **Last Amended**: 2026-03-21 diff --git a/.specify/templates/plan-template.md b/.specify/templates/plan-template.md index da2e36b..b8326be 100644 --- a/.specify/templates/plan-template.md +++ b/.specify/templates/plan-template.md @@ -50,6 +50,12 @@ ## Constitution Check - Data minimization: Inventory stores metadata + whitelisted meta; logs contain no secrets/tokens - Badge semantics (BADGE-001): status-like badges use `BadgeCatalog` / `BadgeRenderer`; no ad-hoc mappings; new values include tests - 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 diff --git a/.specify/templates/spec-template.md b/.specify/templates/spec-template.md index aed1ef7..0d96318 100644 --- a/.specify/templates/spec-template.md +++ b/.specify/templates/spec-template.md @@ -17,6 +17,14 @@ ## Spec Scope Fields *(mandatory)* - **Default filter behavior when tenant-context is active**: [e.g., prefilter to current tenant] - **Explicit entitlement checks preventing cross-tenant leakage**: [Describe checks] +## Operator Surface Contract *(mandatory when operator-facing surfaces are changed)* + +If this feature adds a new operator-facing page or materially refactors one, fill out one row per affected page/surface. + +| Surface | Primary Persona | Surface Type | Primary Operator Question | Default-visible Information | Diagnostics-only Information | Status Dimensions Used | Mutation Scope | Primary Actions | Dangerous Actions | +|---|---|---|---|---|---|---|---|---|---| +| e.g. Tenant policies page | Tenant operator | List/detail | What needs action right now? | Policy health, drift, assignment coverage | Raw payloads, provider IDs, low-level API details | lifecycle, data completeness, governance result | TenantPilot only / Microsoft tenant / simulation only | Sync policies, View policy | Restore policy | + ## User Scenarios & Testing *(mandatory)*