diff --git a/apps/platform/tests/Browser/Spec340PostScopeContractVerificationSmokeTest.php b/apps/platform/tests/Browser/Spec340PostScopeContractVerificationSmokeTest.php new file mode 100644 index 00000000..05bfeb26 --- /dev/null +++ b/apps/platform/tests/Browser/Spec340PostScopeContractVerificationSmokeTest.php @@ -0,0 +1,158 @@ +browser()->timeout(120_000); + +it('Spec340 verifies workspace and environment browser scope contracts without hidden remembered filters', function (): void { + $fixture = Spec322Harness::fixture(); + + Spec322Harness::authenticate($this, $fixture['user'], $fixture['workspace']); + + visit(route('admin.workspace.home', ['workspace' => $fixture['workspace']])) + ->waitForText($fixture['workspace']->name) + ->assertScript('document.querySelector("[data-testid=\"admin-sidebar-scope-indicator\"]")?.getAttribute("aria-label")?.includes("Workspace")', true) + ->assertDontSee('Environment filter:') + ->assertNoJavaScriptErrors() + ->assertNoConsoleLogs(); + + $cleanWorkspaceSurfaces = [ + 'operations hub' => [ + 'url' => OperationRunLinks::index(workspace: $fixture['workspace']), + 'wide_text' => 'Operations Hub', + ], + 'provider connections hub' => [ + 'url' => ProviderConnectionResource::getUrl('index', panel: 'admin'), + 'wide_text' => 'Spec322 Browser Provider B', + ], + 'evidence overview hub' => [ + 'url' => route('admin.evidence.overview'), + 'wide_text' => $fixture['environmentB']->name, + ], + 'alerts hub' => [ + 'url' => route('filament.admin.alerts'), + 'wide_text' => 'Alerts', + ], + 'audit log hub' => [ + 'url' => route('admin.monitoring.audit-log'), + 'wide_text' => 'Audit Log', + ], + 'review register hub' => [ + 'url' => ReviewRegister::getUrl(panel: 'admin'), + 'wide_text' => 'Review Register', + ], + 'customer review workspace hub' => [ + 'url' => CustomerReviewWorkspace::getUrl(panel: 'admin'), + 'wide_text' => 'Customer Review Workspace', + ], + 'governance inbox hub' => [ + 'url' => GovernanceInbox::getUrl(panel: 'admin'), + 'wide_text' => 'Governance Inbox', + ], + 'decision register hub' => [ + 'url' => DecisionRegister::getUrl(panel: 'admin'), + 'wide_text' => 'Decision Register', + ], + 'finding exceptions queue hub' => [ + 'url' => FindingExceptionsQueue::getUrl(panel: 'admin'), + 'wide_text' => 'Finding exceptions', + ], + 'baseline profiles workspace surface' => [ + 'url' => BaselineProfileResource::getUrl('index', panel: 'admin'), + 'wide_text' => 'Baseline Profiles', + ], + 'baseline snapshots workspace surface' => [ + 'url' => BaselineSnapshotResource::getUrl('index', panel: 'admin'), + 'wide_text' => 'Baseline Snapshots', + ], + ]; + + foreach ($cleanWorkspaceSurfaces as $surface) { + $page = visit($surface['url']); + + Spec322Harness::assertWorkspaceOnly($page, $surface['wide_text'], $fixture['environmentA']->name); + } + + Spec322Harness::authenticate($this, $fixture['user'], $fixture['workspace'], $fixture['environmentA']); + + visit(EnvironmentDashboard::getUrl(panel: 'admin', tenant: $fixture['environmentA'])) + ->waitForText($fixture['environmentA']->name) + ->assertScript('window.location.pathname.includes("/workspaces/")', true) + ->assertScript('window.location.pathname.includes("/environments/")', true) + ->assertScript('document.querySelector("[data-testid=\"admin-sidebar-scope-indicator\"]")?.getAttribute("aria-label")?.includes("Environment")', true) + ->assertScript('! window.location.search.includes("environment_id=")', true) + ->assertNoJavaScriptErrors() + ->assertNoConsoleLogs(); + + $rememberedEnvironmentCleanHub = visit(ProviderConnectionResource::getUrl('index', panel: 'admin')); + Spec322Harness::assertWorkspaceOnly($rememberedEnvironmentCleanHub, 'Spec322 Browser Provider B', $fixture['environmentA']->name) + ->assertScript('document.querySelector("a[href*=\'/admin/choose-workspace\']") instanceof HTMLAnchorElement', true) + ->assertScript('Array.from(document.querySelectorAll("form[action*=\'/admin/select-environment\'] input[name=\'managed_environment_id\']")).length >= 2', true) + ->assertScript('Array.from(document.querySelectorAll("form[action*=\'/admin/select-environment\']")).every((form) => ! form.action.includes("environment_id"))', true); +}); + +it('Spec340 verifies filtered hub reload history and provider connection authority contracts', function (): void { + $fixture = Spec322Harness::fixture(); + + Spec322Harness::authenticate($this, $fixture['user'], $fixture['workspace'], $fixture['environmentA']); + + $filteredOperations = visit(OperationRunLinks::index($fixture['environmentA'])); + Spec322Harness::assertFilteredWorkspaceHub($filteredOperations, $fixture['environmentA'], 'Inventory sync'); + + $filteredOperations->script('window.location.reload();'); + Spec322Harness::assertFilteredWorkspaceHub($filteredOperations, $fixture['environmentA'], 'Inventory sync'); + + $filteredProviderConnections = visit(ProviderConnectionResource::getUrl('index', [ + 'environment_id' => (int) $fixture['environmentA']->getKey(), + ], panel: 'admin')); + Spec322Harness::assertFilteredWorkspaceHub($filteredProviderConnections, $fixture['environmentA'], 'Spec322 Browser Provider B'); + $filteredProviderConnections->assertScript( + 'Array.from(document.querySelectorAll("a[href*=\'/provider-connections/create\']")).some((element) => element.href.includes("environment_id="))', + true, + ); + + Spec322Harness::clearWorkspaceHubEnvironmentFilter($filteredProviderConnections); + Spec322Harness::assertWorkspaceOnly($filteredProviderConnections, 'Spec322 Browser Provider B', $fixture['environmentA']->name); + + $filteredProviderConnections->script('window.history.back();'); + Spec322Harness::assertFilteredWorkspaceHub($filteredProviderConnections, $fixture['environmentA'], 'Spec322 Browser Provider B'); + + $filteredProviderConnections->script('window.history.forward();'); + Spec322Harness::assertWorkspaceOnly($filteredProviderConnections, 'Spec322 Browser Provider B', $fixture['environmentA']->name); + + visit(ProviderConnectionResource::getUrl('create', panel: 'admin')) + ->assertScript('document.body.innerText.includes("403") || document.body.innerText.includes("Forbidden") || document.body.innerText.includes("404") || document.body.innerText.includes("Not Found")', true) + ->assertNoJavaScriptErrors(); + + visit(ProviderConnectionResource::getUrl('view', [ + 'record' => $fixture['connectionA'], + ], panel: 'admin')) + ->waitForText('Spec322 Browser Provider A') + ->assertSee($fixture['environmentA']->name) + ->assertSee('Target scope') + ->assertScript( + '(() => { const environmentId = new URLSearchParams(window.location.search).get("environment_id"); return environmentId === null || environmentId === "'.((int) $fixture['environmentA']->getKey()).'"; })()', + true, + ) + ->assertNoJavaScriptErrors() + ->assertNoConsoleLogs(); + + visit(ManagedEnvironmentLinks::providerConnectionUrl($fixture['connectionA'], 'edit', $fixture['environmentA'])) + ->waitForText('Spec322 Browser Provider A') + ->assertScript('window.location.search.includes("environment_id=")', true) + ->assertNoJavaScriptErrors() + ->assertNoConsoleLogs(); +}); diff --git a/specs/340-post-scope-contract-browser-verification-gate/artifacts/screenshots/.gitkeep b/specs/340-post-scope-contract-browser-verification-gate/artifacts/screenshots/.gitkeep new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/specs/340-post-scope-contract-browser-verification-gate/artifacts/screenshots/.gitkeep @@ -0,0 +1 @@ + diff --git a/specs/340-post-scope-contract-browser-verification-gate/audit-report.md b/specs/340-post-scope-contract-browser-verification-gate/audit-report.md new file mode 100644 index 00000000..7b716f05 --- /dev/null +++ b/specs/340-post-scope-contract-browser-verification-gate/audit-report.md @@ -0,0 +1,139 @@ +# Spec 340 Audit Report + +## Scope + +Spec 340 verifies the post-338/339 browser scope contract across Workspace mode, Environment mode, Workspace Hubs with explicit `environment_id` filters, topbar/remembered environment semantics, and credential-adjacent Provider Connections. + +No runtime behavior change is planned or introduced by this implementation. + +## Branch And Baseline + +- Branch: `340-post-scope-contract-browser-verification-gate` +- Baseline commit: `fcb03d2a feat: harden provider connection authority resolution (339) (#410)` +- Initial working tree intent: only the active untracked package `specs/340-post-scope-contract-browser-verification-gate/` was present before implementation edits. +- Local URL: `http://localhost` via Laravel Boost `get_absolute_url`. + +## Repo Guidance Read + +- `AGENTS.md` +- `.specify/memory/constitution.md` +- `.specify/templates/spec-template.md` +- `.specify/templates/plan-template.md` +- `.specify/templates/tasks-template.md` +- `docs/ai-coding-rules.md` +- `docs/architecture-guidelines.md` +- `docs/filament-guidelines.md` +- `docs/security-guidelines.md` +- `docs/testing-guidelines.md` +- `docs/stack-overview.md` + +## Completed-Spec Guardrail + +Read as context only and not modified: + +- `specs/313-workspace-environment-context-browser-verification/` +- `specs/322-browser-no-drift-regression-guard/` +- `specs/338-workspace-environment-resource-scope-contract/` +- `specs/339-provider-connection-scope-hardening/` + +## Surfaces Inspected + +- `apps/platform/routes/web.php` +- `apps/platform/app/Providers/Filament/AdminPanelProvider.php` +- `apps/platform/app/Support/Navigation/AdminSurfaceScope.php` +- `apps/platform/app/Support/Navigation/WorkspaceHubRegistry.php` +- `apps/platform/app/Support/Navigation/WorkspaceHubEnvironmentFilter.php` +- `apps/platform/app/Support/Navigation/WorkspaceSidebarNavigation.php` +- `apps/platform/app/Support/ManagedEnvironmentLinks.php` +- `apps/platform/app/Support/OperationRunLinks.php` +- `apps/platform/app/Support/Workspaces/WorkspaceContext.php` +- `apps/platform/app/Filament/Pages/EnvironmentDashboard.php` +- `apps/platform/app/Filament/Pages/Monitoring/Operations.php` +- `apps/platform/app/Filament/Pages/Monitoring/EvidenceOverview.php` +- `apps/platform/app/Filament/Resources/ProviderConnectionResource.php` +- `apps/platform/app/Policies/ProviderConnectionPolicy.php` +- Existing browser tests under `apps/platform/tests/Browser/Spec281*`, `Spec314*`, `Spec316*`, `Spec322*`, and `Spec338*`. + +## Browser Fixture Strategy + +Spec 340 reuses `Tests\Browser\Support\Spec322WorkspaceEnvironmentBrowserHarness`. + +The harness creates: + +- one workspace +- two accessible managed environments +- operation runs in both environments +- provider connections in both environments +- evidence snapshots, reviews, alert deliveries, audit rows, and finding exceptions +- an owner actor with workspace/environment access + +This avoids new seeders, global test defaults, or broad fixture drift. + +## Command Log + +| Command / Tool | Purpose | Result | +|---|---|---| +| `git status --short --untracked-files=all` | Initial branch/worktree safety | Only active Spec 340 package was untracked | +| Laravel Boost `application_info` | Version-specific app context | Laravel 12.52, Filament 5.2.1, Livewire 4.1.4, Pest 4.3.1 | +| Laravel Boost `list_routes(path=admin)` | Admin surface inventory | 96 admin routes listed | +| Laravel Boost `get_absolute_url` | Local app URL | `http://localhost` | +| `curl -I --max-time 5 http://localhost/admin/local/smoke-login` | Local app/smoke-login availability | `302 Found`, smoke login enabled | +| `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser/Spec338ScopeContractSmokeTest.php` | Pre-existing browser lane sanity check | Passed: 2 tests, 25 assertions | +| Laravel Boost `search_docs` for Pest browser testing | Version-specific Pest Browser guidance | Confirmed `visit`, smoke assertions, `assertNoJavaScriptErrors`, `assertNoConsoleLogs` | +| `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser/Spec340PostScopeContractVerificationSmokeTest.php` | Spec 340 browser verification | Passed: 2 tests, 276 assertions | +| `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections --filter=ScopeHardening` | Credential-adjacent Provider Connection scope regression lane | Passed: 11 tests, 17 assertions | +| `rg -n "topbar\|top bar\|local filter\|page-local filter\|use (the )?(topbar\|environment selector).*filter\|environment selector.*filter" apps/platform/app apps/platform/resources specs/340-post-scope-contract-browser-verification-gate -g '*.php' -g '*.blade.php' -g '*.md'` | Topbar/local-filter wording search | No local-filter instruction found; backlog wording note recorded as `B-340-001` | +| `cd apps/platform && ./vendor/bin/sail pint --dirty --format agent` | PHP formatting | Passed | +| `git diff --check` | Patch whitespace check | Passed | +| `git diff --check --no-index /dev/null ` loop | Untracked-file whitespace check | Passed after removing prepared trailing spaces in Spec 340 Markdown headers | + +Validation commands for Spec 340 are recorded after execution below. + +## Test Governance Decision + +- Lane assignment: Browser verification + optional fast-feedback Feature probes. +- Automated Browser coverage: added because the existing Spec 322 harness is stable and already models the needed two-environment state. +- New Browser family cost: one focused Spec 340 file; no route sweep, no new seeders, no global fixture defaults. +- Feature probes: `tests/Feature/ProviderConnections --filter=ScopeHardening` is run because Provider Connection create/list/view authority is credential-adjacent. + +## Validation Results + +- Spec 340 Browser smoke passed. +- Provider Connection ScopeHardening Feature lane passed. +- Pint dirty-format check passed. +- `git diff --check` passed. +- Untracked-file `--no-index` whitespace check passed. +- Full suite was not run; this verification-only spec used the targeted Browser and Provider Connection lanes defined in `tasks.md`. +- Blocked checks: none. + +## Browser Smoke Result + +PASS. + +Tested paths: + +- Clean Workspace origin: Workspace Overview, Operations, Provider Connections, Evidence Overview, Alerts, Audit Log, Review Register, Customer Review Workspace, Governance Inbox, Decision Register, Finding Exceptions Queue, Baseline Profiles, and Baseline Snapshots. +- Environment origin: Environment Dashboard with environment route and environment sidebar scope signal. +- Remembered environment state: clean Provider Connections hub stayed workspace-wide and did not infer a hidden filter. +- Topbar semantics: Workspace switch remained a context route; environment selector posted to `/admin/select-environment` and did not add `environment_id` as local hub filter state. +- Filtered Workspace Hub: Operations and Provider Connections used explicit `environment_id` with visible `Environment filter:` chip. +- Reload/back-forward: Operations reload preserved visible filter truth; Provider Connections clear/back/forward preserved clean vs filtered hub truth. +- Credential-adjacent Provider Connections: create without `environment_id` was blocked; filtered create carried `environment_id`; view/edit routes derived or preserved the record environment context. + +No screenshots were captured in the final passing run because no P1/P2 drift or visual ambiguity remained. + +## Go / No-Go + +GO. No confirmed P1/P2 drift remains, and new feature work may resume after manual review. + +## Residual Risks / Follow-Up Candidates + +- `B-340-001`: Evidence Overview contains helper copy that mentions the topbar environment scope control. Browser evidence did not show hidden local filtering, so this is backlog copy/productization review rather than a go/no-go blocker. + +## Deployment / Ops Impact + +- Migrations: none. +- Env vars: none. +- Queues/scheduler: none. +- Storage/volumes: none beyond local spec artifacts. +- Filament assets: no new assets; existing `filament:assets` deployment posture unchanged. diff --git a/specs/340-post-scope-contract-browser-verification-gate/checklists/requirements.md b/specs/340-post-scope-contract-browser-verification-gate/checklists/requirements.md new file mode 100644 index 00000000..98392e5e --- /dev/null +++ b/specs/340-post-scope-contract-browser-verification-gate/checklists/requirements.md @@ -0,0 +1,53 @@ +# Specification Quality Checklist: Spec 340 - Post-Scope Contract Browser Verification Gate + +**Purpose**: Validate Spec 340 preparation completeness before implementation. +**Created**: 2026-05-31 +**Feature**: `specs/340-post-scope-contract-browser-verification-gate/spec.md` + +## Candidate Selection Gate + +- [x] CHK001 The selected candidate is directly provided by the user as Spec 340. +- [x] CHK002 Related existing specs were checked for completed-spec signals and are treated as context only. +- [x] CHK003 The package does not overwrite an existing `specs/340-*` directory. +- [x] CHK004 Close alternatives are deferred instead of hidden inside the primary scope. +- [x] CHK005 The candidate is narrowed to a browser/IA verification gate, not a new product feature. + +## Content Quality + +- [x] CHK006 The spec has a concrete problem statement, user value, and primary operator/reviewer audience. +- [x] CHK007 The spec includes functional requirements, non-functional requirements, out-of-scope boundaries, assumptions, risks, and open questions. +- [x] CHK008 The spec avoids premature implementation details except where repo truth is needed for correctness. +- [x] CHK009 No `[NEEDS CLARIFICATION]`, placeholder, or unresolved template marker remains. +- [x] CHK010 Acceptance criteria and success criteria are measurable enough for later implementation review. + +## Constitution And Scope + +- [x] CHK011 The Spec Candidate Check is filled and scores above the approval threshold. +- [x] CHK012 The proportionality review states no new persisted truth, abstraction, runtime status family, or UI framework. +- [x] CHK013 Workspace/environment isolation, RBAC, Provider Connection authority, and audit/report evidence concerns are addressed. +- [x] CHK014 UI/Productization Coverage is handled as verification-only no-impact, with an explicit rule for updating artifacts before any runtime UI fix. +- [x] CHK015 Test governance identifies browser as the primary lane and keeps fixture/browser cost explicit. + +## Plan Quality + +- [x] CHK016 `plan.md` identifies the likely repo surfaces to inspect without requiring runtime code changes. +- [x] CHK017 The plan distinguishes verification artifacts from optional runtime/test changes. +- [x] CHK018 The plan records Filament v5 / Livewire v4 posture, provider registration no-change, global search no-change, destructive-action no-execution, and asset no-change. +- [x] CHK019 Deployment/ops impact is explicitly none unless a later bounded runtime fix changes code. +- [x] CHK020 Implementation phases are ordered from preflight to discovery, browser verification, findings, optional automation, and close-out. + +## Task Quality + +- [x] CHK021 `tasks.md` exists and is ordered into small verification-first phases. +- [x] CHK022 Tasks include concrete file paths for artifacts and likely code surfaces. +- [x] CHK023 Tasks include browser setup, data availability, blocked-check handling, topbar semantics, Provider Connection authority, and go/no-go reporting. +- [x] CHK024 Tasks include validation commands and prevent destructive/external-provider action execution. +- [x] CHK025 Tasks explicitly forbid completed-spec rewrites and unrelated application implementation. + +## Spec Readiness Gate + +- [x] CHK026 `spec.md`, `plan.md`, and `tasks.md` exist. +- [x] CHK027 No open question blocks safe implementation. +- [x] CHK028 The scope is small enough for a bounded implementation loop. +- [x] CHK029 Required checklist artifact exists. +- [x] CHK030 Result: ready for implementation loop as a verification-only package. diff --git a/specs/340-post-scope-contract-browser-verification-gate/findings.md b/specs/340-post-scope-contract-browser-verification-gate/findings.md new file mode 100644 index 00000000..b9fe0b51 --- /dev/null +++ b/specs/340-post-scope-contract-browser-verification-gate/findings.md @@ -0,0 +1,43 @@ +# Spec 340 Findings + +## Severity Definitions + +- `P1`: Critical scope, authorization, credential-adjacent, or cross-environment ambiguity that blocks new feature work. +- `P2`: Confirmed scope-contract drift that should be fixed before adjacent work compounds it, but without immediate credential/security risk. +- `P3`: Bounded polish or clarity issue that does not block go/no-go. +- `backlog`: Non-blocking productization or broader follow-up outside this verification gate. +- `blocked`: Missing route, data, auth, or tooling prevented proof and must not be treated as pass. +- `not-applicable`: Surface is not reachable or not relevant to the active contract in current repo truth. + +## P1 Findings + +None confirmed. + +## P2 Findings + +None confirmed. + +## P3 Findings + +None confirmed. + +## Backlog Findings + +### B-340-001 Evidence Overview topbar wording should be reviewed in a future copy/productization pass + +- **Surface**: Evidence Overview helper copy. +- **Evidence**: `apps/platform/app/Filament/Pages/Monitoring/EvidenceOverview.php` contains the helper text `Use the Environment scope control in the top bar to choose an authorized environment.` +- **Classification**: backlog, not P1/P2. +- **Reason**: Browser evidence confirms clean Workspace Hubs do not silently consume remembered environment state and filtered hubs use explicit `environment_id`; this wording does not itself apply a hidden filter. It can still be reviewed later because it may blur the distinction between topbar environment context and local hub filtering. +- **Smallest next action**: handle in a future Evidence Overview copy/productization spec if product review wants stricter local-filter language. +- **Why not fixed here**: Spec 340 is verification-only with `No UI surface impact`; changing runtime UI copy would exceed the no-runtime-change posture without P1/P2 browser drift. + +## Blocked Checks + +None currently blocked. The implementation uses the existing Spec 322 browser harness to create deterministic workspace, environment, provider connection, evidence, alert, audit, review, decision, and operation records. + +## Notes + +- No screenshots containing credential-adjacent or sensitive payload data were captured. +- Destructive or external-provider actions were not executed. +- Search for topbar/local-filter copy found no instruction that the topbar acts as a local hub filter; `B-340-001` is a non-blocking wording follow-up only. diff --git a/specs/340-post-scope-contract-browser-verification-gate/plan.md b/specs/340-post-scope-contract-browser-verification-gate/plan.md new file mode 100644 index 00000000..c3461abc --- /dev/null +++ b/specs/340-post-scope-contract-browser-verification-gate/plan.md @@ -0,0 +1,220 @@ +# Implementation Plan: Spec 340 - Post-Scope Contract Browser Verification Gate + +- Branch: `340-post-scope-contract-browser-verification-gate` +- Date: 2026-05-31 +- Spec: `specs/340-post-scope-contract-browser-verification-gate/spec.md` +- Input: User-provided Spec 340 draft and repo inspection after Specs 338 and 339. + +## Summary + +Prepare and later execute a browser-level scope/IA verification gate after Specs 338 and 339. The implementation work is verification-first: create Spec 340 audit artifacts, run browser checks against in-scope surfaces, classify findings, and return a go/no-go recommendation before new feature work resumes. + +The planned implementation must not start with runtime fixes. Runtime code changes are allowed only after browser/test evidence proves a narrow P1/P2 contract break and the active Spec 340 artifacts are updated or a follow-up spec is split. + +## Technical Context + +- **Language/Version**: PHP 8.4.15, Laravel 12.52.x. +- **Primary Dependencies**: Filament 5.2.x, Livewire 4.1.x, Pest 4.x browser testing, PostgreSQL through Sail. +- **Storage**: no runtime storage change; Spec-local Markdown artifacts only. +- **Testing**: browser verification, optional focused Pest Browser test, optional targeted Feature tests for Provider Connections or route/query classification. +- **Validation Lanes**: browser, optional fast-feedback. No PostgreSQL lane unless a later bounded runtime fix touches DB behavior. +- **Target Platform**: local Sail for verification; Dokploy/runtime deployment posture unchanged. +- **Project Type**: Laravel monolith under `apps/platform`. +- **Performance Goals**: verification should avoid broad suite expansion and keep any new browser test bounded to representative surfaces. +- **Constraints**: no migrations, env vars, queues, scheduler, storage, provider/OAuth changes, new packages, new persisted truth, or broad UI redesign in this gate. +- **Scale/Scope**: in-scope representative surfaces are the post-338/339 workspace/environment scope contract surfaces, not the full application. + +## UI / Surface Guardrail Plan + +- **Guardrail scope**: verification-only, no planned operator-facing surface change. +- **Affected routes/pages/actions/states/navigation/panel/provider surfaces**: browser-inspected Workspace Sidebar, Environment Sidebar, Topbar, Workspace Hubs, Provider Connections, Baselines, Evidence, Operations, Alerts, Audit Log, Reviews, Governance Inbox, Decision Register, and related environment-to-hub links. +- **No-impact class**: QA/spec-artifact-only unless browser evidence proves a narrow runtime contract break. +- **Native vs custom classification summary**: current native/custom surfaces are inspected, not changed. +- **Shared-family relevance**: navigation entry points, scope presentation, action links, local filters, Provider Connection authority. +- **State layers in scope**: shell, sidebar, topbar, page header, URL query, local filter state, reload/back-forward state. +- **Audience modes in scope**: operator/MSP admin; customer-safe review surfaces are inspected only for scope/truth signals where reachable. +- **Dangerous action posture**: no destructive action execution is planned. Credential-adjacent Provider Connection actions are inspected for confirmation/authorization affordance and record-derived scope only. +- **Coverage artifact posture**: no UI coverage registry update is expected unless implementation makes a runtime UI change. The go/no-go report records checked no-impact if verification-only. + +## Current Repo Surfaces To Inspect + +Implementation should inspect these surfaces and helpers before browser execution: + +- `apps/platform/routes/web.php` +- `apps/platform/app/Providers/Filament/AdminPanelProvider.php` +- `apps/platform/app/Support/Navigation/AdminSurfaceScope.php` +- `apps/platform/app/Support/Navigation/WorkspaceHubRegistry.php` +- `apps/platform/app/Support/Navigation/WorkspaceHubEnvironmentFilter.php` +- `apps/platform/app/Support/Navigation/WorkspaceSidebarNavigation.php` +- `apps/platform/app/Support/ManagedEnvironmentLinks.php` +- `apps/platform/app/Support/OperationRunLinks.php` +- `apps/platform/app/Support/Workspaces/WorkspaceContext.php` +- `apps/platform/app/Filament/Pages/EnvironmentDashboard.php` +- `apps/platform/app/Filament/Pages/Monitoring/Operations.php` +- `apps/platform/app/Filament/Pages/Monitoring/EvidenceOverview.php` +- `apps/platform/app/Filament/Resources/ProviderConnectionResource.php` +- `apps/platform/app/Policies/ProviderConnectionPolicy.php` +- existing browser tests under `apps/platform/tests/Browser/Spec314*`, `Spec316*`, `Spec322*`, `Spec338*`, and Provider Connection browser tests. + +## Shared Pattern & System Fit + +- **Shared patterns reused**: existing workspace/environment scope contract, `environment_id` local filter semantics, deny-as-not-found authorization posture, existing browser smoke patterns, and Spec 322 browser harness patterns where applicable. +- **New abstraction introduced?**: none. +- **New persisted truth introduced?**: none. +- **Provider boundary**: verify platform-core authority (`workspace`, `environment_id`, record ownership) stays separate from provider-owned Microsoft tenant identity. +- **OperationRun**: verify Operations hub/link scope only; no OperationRun lifecycle or notification changes. +- **Audit/observability**: the go/no-go report is the evidence artifact for this gate; no runtime `AuditLog` writes are introduced. + +## Implementation Approach + +### Phase 1 — Preflight and completed-spec guardrail + +- Confirm current branch, clean working tree, baseline commit, and that related completed specs are read-only context. +- Confirm no existing `specs/340-*` package or `340-*` branch existed before this preparation. +- Re-read `spec.md`, `plan.md`, `tasks.md`, constitution, and relevant guidelines. + +### Phase 2 — Repo discovery and verification matrix setup + +- Create Spec 340 artifacts: + - `surface-inventory.md` + - `scope-verification-matrix.md` + - `findings.md` + - `audit-report.md` + - `artifacts/screenshots/` if screenshots are captured. +- Populate first-pass route/surface inventory from repo files and existing route list. +- Classify each surface into Workspace-owned source of truth, Workspace Hub with local environment filter, Environment-owned detail surface, or credential-adjacent provider surface. + +### Phase 3 — Browser verification + +- Resolve the local app URL through Laravel Boost `get_absolute_url` or documented local/Sail configuration. +- Use existing smoke-login or seeded fixture conventions without modifying seeders. +- Verify: + - clean Workspace origin, + - Environment Dashboard origin, + - environment-to-hub filtered entry, + - clean hub entry with remembered environment, + - reload and browser back/forward, + - Topbar workspace/environment selector semantics, + - Provider Connections create/list/view/edit/action affordances. + +### Phase 4 — Finding classification + +- Classify each matrix row as pass, P1, P2, P3, backlog, blocked, or not applicable. +- P1 means a critical scope/authority error or credential-adjacent ambiguity blocks feature work. +- P2 means contract drift should be fixed soon but does not expose immediate credential/security risk. +- P3 means polish/cleanup. +- Backlog means non-blocking improvement or broader productization. +- Blocked means missing route/data/tooling prevented proof and requires explicit next action. + +### Phase 5 — Optional focused regression coverage + +Add focused Pest Browser coverage only if automation is stable and valuable: + +- Prefer one bounded `Spec340PostScopeContractVerificationSmokeTest.php`. +- Reuse existing browser setup/harness patterns. +- Do not add broad fixture defaults or seeders without updating the spec first. +- Keep exhaustive route/query permutations in Feature tests, not browser tests. + +### Phase 6 — Go/no-go close-out + +- Update `audit-report.md` with final commands, browser tooling, screenshots, blocked checks, and go/no-go status. +- If no P1/P2 drift is found, recommend moving to the next roadmap candidate. +- If P1/P2 drift is found, recommend the smallest safe follow-up or bounded fix and stop unrelated feature work. + +## Constitution Check + +- **Inventory-first / snapshots-second**: N/A, no inventory/snapshot behavior changed. +- **Read/write separation**: pass; this is read-only verification unless a later bounded fix is explicitly authorized by updated artifacts. +- **Single Graph contract path**: pass; no Graph calls are added. +- **Deterministic capabilities / RBAC**: pass; existing capabilities are verified, not changed. +- **Workspace and environment isolation**: primary verification focus. +- **Provider boundary**: pass; verify provider credential-adjacent scope without adding provider abstractions. +- **No new persisted truth**: pass. +- **No new state/status family**: pass; P1/P2/P3/backlog is report-only taxonomy. +- **UI/Productization coverage**: pass; no planned UI surface impact. Any runtime UI fix must update this decision. +- **Test governance**: pass; browser lane is explicit and central to the gate. +- **Proportionality**: pass; the gate is narrower than a new feature or broad cleanup chain. + +## Project Structure + +Expected Spec 340 artifact layout: + +```text +specs/340-post-scope-contract-browser-verification-gate/ +├── spec.md +├── plan.md +├── tasks.md +├── checklists/ +│ └── requirements.md +├── surface-inventory.md +├── scope-verification-matrix.md +├── findings.md +├── audit-report.md +└── artifacts/ + └── screenshots/ +``` + +Optional implementation test: + +```text +apps/platform/tests/Browser/Spec340PostScopeContractVerificationSmokeTest.php +``` + +## Data Model + +No runtime data model change. + +Spec-local artifact concepts: + +- **Surface inventory row**: surface name, route/entry point, expected taxonomy, origin, filter support, related helper/code owner, verification status. +- **Matrix row**: surface, browser origin, URL/query, shell, sidebar, breadcrumb/header, visible filter evidence, reload/back-forward result, screenshot path, status, finding ID. +- **Finding**: ID, severity, expected behavior, actual behavior, evidence, likely owner, smallest next action, go/no-go impact. + +## Testing Strategy + +- Use Pest 4 browser testing if automation is added. +- Browser tests must include `assertNoJavaScriptErrors()` where stable. +- Prefer targeted browser coverage over full-app smoke. +- Use specific HTTP assertions in any Feature probes (`assertNotFound()`, `assertForbidden()`, `assertSuccessful()`). +- Do not delete or relax existing Spec 322/338/339 tests. + +Target commands for later implementation: + +```bash +cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser --filter=Spec340 +cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections --filter=ScopeHardening +git diff --check +``` + +If no automated browser test is added, the implementation close-out must say browser verification was manual/in-app and list exact routes checked, screenshots captured, and tooling limitations. + +## Filament / Livewire Contract + +- Filament v5 remains on Livewire v4.0+. +- No panel provider registration change is planned; Laravel 12 providers remain in `apps/platform/bootstrap/providers.php`. +- Global search behavior is not changed. If a runtime fix later touches a globally searchable resource, the implementer must verify View/Edit page availability or disabled global search. +- Destructive/high-impact actions are not executed in this gate. Provider Connection actions are inspected for existing confirmation, authorization, and audit posture only. +- No registered Filament assets are added; `filament:assets` deployment posture is unchanged. + +## Deployment / Ops Impact + +- Migrations: none. +- Env vars: none. +- Queues/scheduler: none. +- Storage/volumes: none, except local screenshot artifacts under the spec package if captured. +- Dokploy/Staging/Production: no runtime deployment impact unless a later bounded fix changes code. + +## Risk Controls + +- Do not treat blocked checks as pass. +- Do not create follow-up specs automatically unless P1/P2 evidence proves a concrete gap. +- Do not rewrite completed specs. +- Do not broaden into customer review, localization, governance inbox, or commercial lifecycle productization. +- Do not add seeders or global browser fixtures unless the active spec is updated with the fixture-cost decision. + +## Phase Completion Criteria + +- `spec.md`, `plan.md`, `tasks.md`, and `checklists/requirements.md` exist and are internally aligned. +- The implementation task list is ordered, small, and verification-first. +- No application implementation is included in preparation. +- The package is ready for a separate implementation loop. diff --git a/specs/340-post-scope-contract-browser-verification-gate/scope-verification-matrix.md b/specs/340-post-scope-contract-browser-verification-gate/scope-verification-matrix.md new file mode 100644 index 00000000..5457d643 --- /dev/null +++ b/specs/340-post-scope-contract-browser-verification-gate/scope-verification-matrix.md @@ -0,0 +1,32 @@ +# Spec 340 Scope Verification Matrix + +| Page / Surface | Origin | URL / Query | Shell | Sidebar | Breadcrumb / Header | Visible Filter Evidence | Reload / Back-Forward | Screenshot | Status | Finding ID | +|---|---|---|---|---|---|---|---|---|---|---| +| Workspace Overview | Clean Workspace | `/admin/workspaces/{workspace}/overview` | Workspace | Workspace scope indicator | Workspace name visible | No environment filter | N/A | Not captured | pass | - | +| Operations | Clean Workspace | `/admin/workspaces/{workspace}/operations` | Workspace Hub | Workspace scope indicator | `Operations Hub` / workbench copy | No `environment_id`, no filter chip | Existing Spec322 reload posture; Spec340 representative check passed | Not captured | pass | - | +| Operations | Environment origin filtered entry | `/admin/workspaces/{workspace}/operations?environment_id=` | Workspace Hub | Workspace scope indicator | `Operations Hub` | `Environment filter:` chip with clear link | Spec340 reload check passed | Not captured | pass | - | +| Provider Connections List | Clean Workspace + remembered environment | `/admin/provider-connections` | Workspace Hub | Workspace scope indicator | Provider Connections table | No hidden remembered filter | N/A | Not captured | pass | - | +| Provider Connections List | Filtered Hub | `/admin/provider-connections?environment_id=` | Workspace Hub | Workspace scope indicator | Provider Connections table | `Environment filter:` chip and create link carries `environment_id` | Spec340 clear/back/forward check passed | Not captured | pass | - | +| Provider Connections Create | Clean Workspace | `/admin/provider-connections/create` | Authorization boundary | N/A | Error / blocked page expected | No environment authority | N/A | Not captured | pass | - | +| Provider Connection View | Record route | `/admin/provider-connections/{record}` | Record-derived | Workspace scope indicator | Provider connection name and target scope visible | Optional `environment_id` is record-derived and matched to the connection environment | N/A | Not captured | pass | - | +| Provider Connection Edit | Filtered record route | `/admin/provider-connections/{record}/edit?environment_id=` | Record-derived + explicit query | Workspace scope indicator | Provider connection name visible | Explicit `environment_id` query | N/A | Not captured | pass | - | +| Evidence Overview | Clean Workspace | `/admin/evidence/overview` | Workspace Hub | Workspace scope indicator | Evidence proof workbench | No environment filter | Existing Spec322 reload/back-forward posture | Not captured | pass | - | +| Alerts | Clean Workspace | `/admin/alerts` | Workspace Hub | Workspace scope indicator | Alerts heading | No environment filter | N/A | Not captured | pass | - | +| Audit Log | Clean Workspace | `/admin/audit-log` | Workspace Hub | Workspace scope indicator | Audit Log heading | No environment filter | N/A | Not captured | pass | - | +| Review Register | Clean Workspace | `/admin/reviews` | Workspace Hub | Workspace scope indicator | Review Register heading | No environment filter | N/A | Not captured | pass | - | +| Customer Review Workspace | Clean Workspace | `/admin/reviews/workspace` | Workspace Hub | Workspace scope indicator | Customer Review Workspace heading | No environment filter | N/A | Not captured | pass | - | +| Governance Inbox | Clean Workspace | `/admin/governance/inbox` | Workspace Hub | Workspace scope indicator | Governance Inbox heading | No environment filter | N/A | Not captured | pass | - | +| Decision Register | Clean Workspace | `/admin/governance/decisions` | Workspace Hub | Workspace scope indicator | Decision Register heading | No environment filter | N/A | Not captured | pass | - | +| Finding Exceptions Queue | Clean Workspace | `/admin/finding-exceptions/queue` | Workspace Hub | Workspace scope indicator | Finding exceptions queue text | No environment filter | N/A | Not captured | pass | - | +| Baseline Profiles | Clean Workspace | `/admin/baseline-profiles` | Workspace-owned analysis | Workspace scope indicator | Baseline Profiles heading | No environment filter | N/A | Not captured | pass | - | +| Baseline Snapshots | Clean Workspace | `/admin/baseline-snapshots` | Workspace-owned analysis | Workspace scope indicator | Baseline Snapshots heading | No environment filter | N/A | Not captured | pass | - | +| Environment Dashboard | Environment origin | `/admin/workspaces/{workspace}/environments/{environment}` | Environment | Environment scope indicator | Environment name visible | Route-owned environment, no `environment_id` query | N/A | Not captured | pass | - | + +## Coverage Notes + +- Browser automation uses `apps/platform/tests/Browser/Spec340PostScopeContractVerificationSmokeTest.php`. +- Existing related browser coverage remains relevant context: + - `Spec322WorkspaceHubNoDriftSmokeTest` + - `Spec322EnvironmentOwnedSurfaceSmokeTest` + - `Spec338ScopeContractSmokeTest` +- The matrix is intentionally representative for reload/back-forward instead of exhaustive across every hub, matching the fixture-cost limits in the active plan. diff --git a/specs/340-post-scope-contract-browser-verification-gate/spec.md b/specs/340-post-scope-contract-browser-verification-gate/spec.md new file mode 100644 index 00000000..ffa42400 --- /dev/null +++ b/specs/340-post-scope-contract-browser-verification-gate/spec.md @@ -0,0 +1,357 @@ +# Feature Specification: Spec 340 - Post-Scope Contract Browser Verification Gate + +**Feature Branch**: `340-post-scope-contract-browser-verification-gate` +**Created**: 2026-05-31 +**Status**: Draft +**Input**: User-provided Spec 340 draft from attachment plus repo inspection after Specs 338 and 339. + +## Spec Candidate Check *(mandatory — SPEC-GATE-001)* + +- **Problem**: Specs 338 and 339 hardened the workspace/environment scope contract and Provider Connection authority, but the original risk was browser-level product confusion: operators could misread workspace-wide hubs as environment-owned pages, topbar context as a hidden filter, or credential-adjacent Provider Connection create behavior as implicitly authorized. +- **Today's failure**: Automated Feature tests prove many policy/query contracts, but they do not prove that the actual browser experience consistently shows whether the user is in Workspace mode, Environment mode, or a Workspace Hub filtered by `environment_id`. +- **User-visible improvement**: Before opening new feature or cleanup specs, operators and reviewers get a concrete browser go/no-go report proving whether the current UI communicates the scope contract correctly across Workspace Sidebar, Environment Sidebar, Topbar, hub filters, environment-to-hub links, Provider Connections, Baselines, Evidence, Operations, Alerts, Audit Log, Reviews, Governance Inbox, and Decision Register. +- **Smallest enterprise-capable version**: A verification-first gate that produces a repo-based surface inventory, browser matrix, screenshot evidence where useful, P1/P2/P3/backlog findings, and explicit go/no-go status. It does not redesign surfaces or introduce new runtime features. +- **Explicit non-goals**: No broad UI redesign, no new product feature, no schema changes, no provider/OAuth redesign, no reopening completed Specs 313/322/338/339, no automatic chain of 341+ follow-up specs, no runtime fix unless a Spec 340 browser or test reproduction proves a narrow in-scope contract break and the active artifacts are updated first. +- **Permanent complexity imported**: One bounded QA/spec package and optional focused browser regression coverage; no new persisted truth, status family, domain abstraction, provider framework, or UI taxonomy. +- **Why now**: The user-provided draft and latest branch context state that after Spec 339 the next safe step is a browser/IA verification gate, not another feature or cleanup spec. This prevents feature work from building on unclear scope semantics. +- **Why not local**: Checking one page locally would miss cross-surface drift. The contract must be verified through representative browser paths from Workspace origin, Environment origin, filtered hub entry, reload/back-forward state, and credential-adjacent Provider Connection flows. +- **Approval class**: Core Enterprise (scope/RBAC/credential-adjacent trust gate). +- **Red flags triggered**: Many surfaces + browser coverage. **Defense**: this is verification-first, bounded to current repo truth, imports no new runtime model, and escalates concrete drift instead of broad refactoring. +- **Score**: Nutzen: 2 | Dringlichkeit: 2 | Scope: 2 | Komplexität: 2 | Produktnähe: 2 | Wiederverwendung: 1 | **Gesamt: 11/12** +- **Decision**: approve. + +## Summary + +Spec 340 is a post-scope-contract browser verification gate. It verifies whether the current product experience matches the contracts hardened by Specs 338 and 339: + +- Workspace shell and sidebar show workspace-owned, workspace-hub, portfolio, and system surfaces. +- Environment shell and sidebar show environment-owned detail surfaces as primary context. +- Workspace Hubs use explicit local filters such as `environment_id`, not remembered environment or topbar magic. +- Environment pages link to Workspace Hubs through explicit filtered links when a narrowed view is intended. +- Provider Connections require explicit environment authority for create and record-derived authority for view/edit/actions. +- Findings are classified into P1, P2, P3, and backlog, with a go/no-go recommendation before new feature work resumes. + +## Completed-Spec Guardrail Result + +Related existing specs are context only: + +- `specs/313-workspace-environment-context-browser-verification/` already contains completed browser audit tasks and artifacts. It is not a refresh target. +- `specs/322-browser-no-drift-regression-guard/` already contains completed regression-guard tasks and validation notes. It is not a refresh target. +- `specs/338-workspace-environment-resource-scope-contract/` has completed implementation task markers for the scope/link/query contract. It is not modified. +- `specs/339-provider-connection-scope-hardening/` has completed implementation task markers for Provider Connection authority hardening. It is not modified. + +Spec 340 uses these packages as dependency evidence only and preserves their implementation history. + +## Spec Scope Fields *(mandatory)* + +- **Scope**: canonical-view / browser verification gate. +- **Primary routes and surfaces**: + - Workspace shell/sidebar and Workspace Overview. + - Environment Dashboard and environment-owned detail routes. + - Workspace Hubs: Operations, Alerts, Audit Log, Evidence Overview, Provider Connections, Review Register, Customer Review Workspace, Governance Inbox, Decision Register, Finding Exceptions Queue where reachable. + - Workspace-owned portfolio/configuration surfaces: Baseline Profiles, Baseline Snapshots, Managed Environments, Workspace Settings, Alert Rules, Alert Destinations. + - Provider Connections list, create, view, edit, and credential-adjacent actions where reachable in browser verification. +- **Data Ownership**: no data model or schema change. Verification distinguishes workspace-owned records, environment-owned records, workspace hub filters, and credential-adjacent provider records. +- **RBAC**: no new capabilities. Browser verification must respect existing workspace membership, managed-environment entitlement, and capability enforcement. Out-of-scope/non-member access remains deny-as-not-found; member-missing-capability remains forbidden where current policy requires it. + +For canonical-view verification: + +- **Default filter behavior when environment context is active**: Workspace Hubs must not silently infer a filter from remembered environment or the topbar. If narrowed by environment, the page must expose explicit `environment_id` query/filter state or visible filter affordance. +- **Explicit entitlement checks preventing cross-environment leakage**: Any `environment_id` used in a hub URL must be validated against current workspace and actor entitlement by existing runtime code; browser verification records whether wrong or missing context is blocked safely. + +## Verification Taxonomy + +### A. Workspace-owned source of truth + +Examples: Workspace Overview, Managed Environments, Alert Rules, Alert Destinations, Workspace Settings, Baseline Profiles, Baseline Snapshots. + +Expected browser signal: workspace shell/sidebar; no environment-owned claim; links to environment details remain explicit. + +### B. Workspace Hub with local environment filter + +Examples: Operations, Alerts, Audit Log, Evidence Overview, Provider Connections, Review Register, Customer Review Workspace, Governance Inbox, Decision Register, Finding Exceptions Queue. + +Expected browser signal: workspace shell/sidebar; visible local filter or URL query when narrowed; no hidden topbar/remembered-environment filtering. + +### C. Environment-owned detail surface + +Examples: Environment Dashboard and environment route-owned child/detail surfaces. + +Expected browser signal: environment in route and shell; primary Environment Sidebar entries are environment-owned. + +### D. Credential-adjacent provider surface + +Example: Provider Connections. + +Expected browser signal: list/view/actions derive authority from workspace context, explicit `environment_id`, or record ownership; create without explicit environment is blocked or guided safely. + +## UI Surface Impact *(mandatory — UI-COV-001)* + +Does this spec add, remove, rename, or materially change any reachable UI surface? + +- [x] No UI surface impact +- [ ] Existing page changed +- [ ] New page/route added +- [ ] Navigation changed +- [ ] Filament panel/provider surface changed +- [ ] New modal/drawer/wizard/action added +- [ ] New table/form/state added +- [ ] Customer-facing surface changed +- [ ] Dangerous action changed +- [ ] Status/evidence/review presentation changed +- [ ] Workspace/environment context presentation changed + +No-impact rationale: Spec 340 prepares and later executes a verification gate over existing reachable surfaces. If implementation evidence proves a narrow runtime UI fix is necessary, the implementer must first update the active spec/plan/tasks UI impact decision or split a follow-up spec before changing runtime UI. + +## UI/Productization Coverage *(mandatory)* + +N/A - no planned reachable UI surface impact. The feature verifies existing UI/productization coverage rather than adding or materially changing a surface. + +If browser evidence reveals contract drift: + +- P1/P2 drift must be documented with page, URL, origin, screenshot path, expected contract, actual behavior, and the smallest safe next action. +- Runtime fixes require an updated UI impact decision in this active package or a follow-up spec. +- Completed historical specs must not be rewritten to remove close-out, validation, or completed-task evidence. + +## Cross-Cutting / Shared Pattern Reuse *(mandatory)* + +- **Cross-cutting feature?**: yes, verification touches navigation, scope presentation, deep links, filters, Provider Connection authority, and browser evidence. +- **Interaction classes**: navigation entry points, status/scope messaging, action links, hub filters, credential-adjacent action affordances. +- **Existing patterns to verify/reuse**: + - `AdminSurfaceScope` + - `WorkspaceHubRegistry` + - `WorkspaceHubEnvironmentFilter` + - `WorkspaceSidebarNavigation` + - `ManagedEnvironmentLinks` + - `OperationRunLinks` + - `WorkspaceContext` + - `ProviderConnectionPolicy` + - `ProviderConnectionResource` + - existing Spec 322 browser harness/patterns where reuse is cheaper than new fixture setup. +- **Allowed deviation and why**: none for preparation. Runtime deviation requires a documented P1/P2 finding and bounded fix decision. +- **Consistency impact**: route owns shell, query owns local filter, record owns Provider Connection action authority, and topbar context must not become hidden authorization. +- **Review focus**: evidence must distinguish actual product drift from missing seed data, blocked access, or historical wording in completed specs. + +## OperationRun UX Impact + +- **Touches OperationRun start/completion/link UX?**: no new start/completion semantics. +- **Verification relevance**: Operations hub and OperationRun links are verified for scope and filter presentation only. +- **Queued DB-notification policy**: N/A. +- **Terminal notification path**: N/A. +- **Exception required?**: none. + +## Provider Boundary / Platform Core Check + +- **Shared provider/platform boundary touched?**: verification touches Provider Connections and Microsoft-adjacent vocabulary, but does not change provider contracts. +- **Boundary classification**: platform-core scope authority (`workspace`, `environment_id`, record ownership) plus provider-owned Microsoft identity detail. +- **Why this does not deepen provider coupling accidentally**: Spec 340 verifies that Provider Connections do not treat remembered environment, Filament tenant, or legacy tenant query aliases as platform authority. +- **Follow-up path**: document in the go/no-go report if browser evidence shows provider-boundary vocabulary or authority drift. + +## UI / Surface Guardrail Impact + +| Surface / Change | Operator-facing surface change? | Native vs Custom | Shared-Family Relevance | State Layers Touched | Exception Needed? | Low-Impact / `N/A` Note | +|---|---|---|---|---|---|---| +| Spec 340 verification artifacts | no | N/A | navigation, filters, browser evidence | shell, page, URL-query inspected only | no | Verification gate; no planned runtime UI change | + +## Decision-First Surface Role + +N/A - no operator-facing surface is added or materially changed. The verification gate checks whether existing surfaces expose the correct decision context. + +## Audience-Aware Disclosure + +N/A - no detail/status surface is added or materially changed. Browser findings must still record whether existing customer/operator surfaces expose raw diagnostics, internal IDs, or misleading scope signals. + +## UI/UX Surface Classification + +N/A - no new or modified operator-facing list/detail/queue/audit/config/report surface is planned. Existing surfaces are classified in the browser matrix by their expected taxonomy role. + +## Operator Surface Contract + +N/A - no new surface contract is introduced. Spec 340 verifies existing shell/page/filter/action contracts. + +## Proportionality Review *(mandatory when structural complexity is introduced)* + +- **New source of truth?**: no. +- **New persisted entity/table/artifact?**: no persisted runtime artifact. Spec-local verification artifacts may be created under `specs/340-post-scope-contract-browser-verification-gate/`. +- **New abstraction?**: no. +- **New enum/state/reason family?**: no runtime enum/state. P1/P2/P3/backlog is a report taxonomy only. +- **New cross-domain UI framework/taxonomy?**: no new runtime taxonomy. Verification reuses the existing workspace/environment scope taxonomy. +- **Current operator problem**: operators need proof that the browser experience matches scope authority before new work compounds any drift. +- **Existing structure is insufficient because**: completed Feature tests and prior audits do not prove the combined post-338/339 browser experience. +- **Narrowest correct implementation**: one verification gate with matrix/report artifacts and optional focused browser regression coverage. +- **Ownership cost**: bounded browser/test maintenance if automation is added; no runtime model maintenance. +- **Alternative intentionally rejected**: starting the next feature/cleanup candidate without browser proof. +- **Release truth**: current-release verification before further roadmap work. + +### Compatibility posture + +This feature assumes a pre-production environment. No migration shim, compatibility path, legacy alias, or production-data preservation behavior is introduced. + +## Testing / Lane / Runtime Impact *(mandatory)* + +- **Test purpose / classification**: Browser verification + optional focused Feature tests only if needed to classify a browser finding. +- **Validation lanes**: browser, optional fast-feedback for route/query/authorization probes, no PostgreSQL lane unless a follow-up runtime fix changes DB behavior. +- **Why this classification and these lanes are sufficient**: The risk is browser-level scope communication and credential-adjacent authority perception. Browser verification is the primary proof; targeted Feature tests can classify suspected policy/query drift without broad suite cost. +- **New or expanded test families**: optional `Spec340` browser smoke or manifest-based regression test; fixture setup must reuse existing browser test patterns where possible. +- **Fixture/helper cost impact**: keep workspace/environment/browser fixtures explicit and opt-in. Do not add seeders unless browser verification is blocked and the spec is updated first. +- **Heavy-family visibility / justification**: browser coverage is explicit and central to the gate, not accidental. +- **Special surface test profile**: global-context-shell. +- **Reviewer handoff**: reviewers must verify that browser evidence covers clean workspace origin, environment origin, filtered hub entry, reload/back-forward state, topbar semantics, and Provider Connections authority. +- **Budget / baseline / trend impact**: no expected broad suite cost unless automated browser coverage expands; record any expansion in the go/no-go report. +- **Escalation needed**: P1/P2 drift becomes `follow-up-spec` or a bounded in-scope fix only after active artifact update. +- **Planned validation commands**: + - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser --filter=Spec340` + - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections --filter=ScopeHardening` + - `git diff --check` + +## User Scenarios & Testing *(mandatory)* + +### User Story 1 - Verify Workspace and Environment mode clarity (Priority: P1) + +As an operator moving between workspace and environment areas, I can always tell whether I am in Workspace mode, Environment mode, or a Workspace Hub filtered by environment. + +**Why this priority**: The scope contract is only trustworthy if the browser shell, sidebar, breadcrumb/header, and visible filter state communicate the same ownership model. + +**Independent Test**: Open representative Workspace and Environment origins, navigate through sidebar/global entries, reload, and record shell/sidebar/header/filter evidence in the matrix. + +**Acceptance Scenarios**: + +1. **Given** a Workspace origin with no active environment route, **When** the operator opens Workspace Hubs, **Then** the shell/sidebar remains workspace-mode and any environment narrowing is represented as an explicit local filter. +2. **Given** an Environment Dashboard origin, **When** the operator opens environment-owned detail surfaces, **Then** the route and shell clearly carry that environment. +3. **Given** an Environment Dashboard origin, **When** the operator opens workspace-wide hubs, **Then** the page does not pretend to be environment-owned. + +--- + +### User Story 2 - Verify workspace hub filters and topbar semantics (Priority: P1) + +As an operator, topbar environment selection and local hub filters do not silently become each other. + +**Why this priority**: A hidden topbar/session filter can create false confidence and cross-scope misunderstandings. + +**Independent Test**: From clean, remembered-environment, and filtered-entry states, verify Operations, Alerts, Audit Log, Evidence Overview, Provider Connections, Reviews, Customer Review Workspace, Governance Inbox, and Decision Register where reachable. + +**Acceptance Scenarios**: + +1. **Given** a remembered environment, **When** the operator opens a clean Workspace Hub URL, **Then** the hub does not silently filter to that environment. +2. **Given** an explicit `environment_id`, **When** the operator opens a filterable Workspace Hub, **Then** the page exposes a visible filter/chip/banner or equivalent local filter evidence. +3. **Given** a filtered hub entry, **When** the operator clears the filter, reloads, or uses browser back/forward, **Then** the visible scope state remains truthful. + +--- + +### User Story 3 - Verify Provider Connection authority in the browser (Priority: P1) + +As an operator near credential-adjacent Provider Connections, I can see that create/manage behavior requires explicit environment authority or record ownership, not hidden context. + +**Why this priority**: Provider Connections sit near credentials, consent, permissions, and provider operations. + +**Independent Test**: Verify Provider Connections list/create/view/edit/action affordances from clean, filtered, remembered-environment, missing-environment, and wrong-environment states. + +**Acceptance Scenarios**: + +1. **Given** a Provider Connections list, **When** an explicit `environment_id` is present, **Then** the filter and create path are tied to that environment. +2. **Given** no explicit `environment_id`, **When** the operator attempts create, **Then** create is blocked or guided safely without relying on remembered environment. +3. **Given** an existing Provider Connection record, **When** the operator views or manages it, **Then** scope context comes from record ownership and capability enforcement. + +--- + +### User Story 4 - Produce a go/no-go report (Priority: P2) + +As a product/engineering reviewer, I receive a compact report that says whether new feature work may continue or which concrete scope drift must be fixed first. + +**Why this priority**: The output must prevent vague “looks okay” conclusions and avoid automatic follow-up sprawl. + +**Independent Test**: Review the final report and matrix; every P1/P2 finding includes evidence, expected/actual behavior, affected files or routes, and a recommended next action. + +**Acceptance Scenarios**: + +1. **Given** browser verification is complete, **When** no P1/P2 drift is found, **Then** the report gives a clear go recommendation for new feature work. +2. **Given** P1/P2 drift is found, **When** the report is reviewed, **Then** it names the smallest safe follow-up or bounded fix and blocks unrelated feature work. +3. **Given** missing data or unavailable routes block a check, **When** the report is reviewed, **Then** the limitation is explicit and not reported as a pass. + +## Functional Requirements + +- **FR-340-001**: The verification must inventory every in-scope surface, expected taxonomy class, route, origin path, filter capability, and evidence status. +- **FR-340-002**: The verification must check Workspace Sidebar behavior from a clean Workspace origin. +- **FR-340-003**: The verification must check Environment Sidebar behavior from at least one Environment Dashboard origin. +- **FR-340-004**: The verification must check that Workspace Hubs use explicit local filters and do not silently consume topbar/remembered environment state. +- **FR-340-005**: The verification must check environment-to-hub links for explicit `environment_id` when the link intends a filtered hub view. +- **FR-340-006**: The verification must check Topbar workspace selector and environment selector semantics and record whether they navigate, filter, or change context. +- **FR-340-007**: The verification must check Provider Connections create/list/view/edit/action affordances against explicit environment and record-derived authority. +- **FR-340-008**: The verification must include Baseline Profiles/Snapshots as workspace-owned surfaces and must not reopen their ownership unless browser evidence proves regression. +- **FR-340-009**: The verification must record reload and browser back/forward behavior for representative filtered hubs. +- **FR-340-010**: The verification must classify each finding as P1, P2, P3, backlog, pass, blocked, or not applicable. +- **FR-340-011**: The final report must include go/no-go status, exact commands or browser tooling used, screenshot paths where captured, blocked checks, and next recommended action. +- **FR-340-012**: The implementation must not modify completed Spec 313/322/338/339 artifacts except as read-only context. +- **FR-340-013**: Any runtime change discovered during implementation must be preceded by an active artifact update or split into a follow-up spec. +- **FR-340-014**: The verification must not create new persisted entities, migrations, providers, capabilities, OperationRun types, or product features. + +## Non-Functional Requirements + +- **NFR-340-001**: Browser evidence must be reproducible from documented local/Sail commands or explicitly marked as manually verified with tool limitations. +- **NFR-340-002**: The report must distinguish verified pass, verified drift, insufficient seed data, inaccessible route, and authorization-blocked states. +- **NFR-340-003**: Browser/test additions must keep fixture cost explicit and avoid broad seed/global setup changes. +- **NFR-340-004**: No secrets, raw credential payloads, or sensitive Graph data may be captured in screenshots or reports. +- **NFR-340-005**: Verification must remain compatible with Filament v5 and Livewire v4 conventions. + +## Required Artifacts + +Implementation of this spec should create or update only Spec 340 artifacts and optional focused tests: + +- `specs/340-post-scope-contract-browser-verification-gate/surface-inventory.md` +- `specs/340-post-scope-contract-browser-verification-gate/scope-verification-matrix.md` +- `specs/340-post-scope-contract-browser-verification-gate/findings.md` +- `specs/340-post-scope-contract-browser-verification-gate/audit-report.md` +- `specs/340-post-scope-contract-browser-verification-gate/artifacts/screenshots/` when screenshot evidence is useful +- optional `apps/platform/tests/Browser/Spec340PostScopeContractVerificationSmokeTest.php` if automation is stable and bounded + +## Acceptance Criteria + +- **AC1**: All in-scope surfaces are inventoried and classified against the verification taxonomy. +- **AC2**: Browser evidence covers clean Workspace origin, Environment origin, filtered hub entry, topbar context changes, reload, and back/forward for representative hubs. +- **AC3**: Provider Connections browser behavior is verified for explicit environment create authority and record-derived action authority. +- **AC4**: Findings are classified with evidence and no P1/P2 issue is left ambiguous or silently deferred. +- **AC5**: Completed related specs are not rewritten. +- **AC6**: No application implementation is performed during preparation; later implementation remains bounded by `tasks.md`. + +## Success Criteria + +- **SC-340-001**: The final go/no-go report can be reviewed without replaying the entire browser session. +- **SC-340-002**: If no P1/P2 drift exists, the report clearly permits the next roadmap feature/cleanup candidate. +- **SC-340-003**: If P1/P2 drift exists, the report blocks unrelated feature work and names the smallest safe follow-up or bounded fix. +- **SC-340-004**: Browser verification does not introduce unstable global fixtures, hidden seed dependencies, or broad regression-suite cost. + +## Out of Scope + +- Sidebar/topbar redesign. +- Provider Connection redesign or OAuth/provider registry changes. +- Broad canonical link/query cleanup beyond concrete browser findings. +- New product feature work. +- Schema, migration, model, service, policy, job, route, or runtime behavior changes during preparation. +- Rewriting or normalizing completed spec close-out/history. + +## Risks + +- Browser automation may be blocked by local app/session/data availability; blocked checks must be reported instead of treated as passes. +- Existing seed data may not cover every surface; report limitations and add only bounded fixture/test tasks if needed. +- A true P1/P2 finding may require a follow-up spec instead of being fixed inside the verification gate. +- The verification could become too broad; tasks keep the scope to scope/IA/authority evidence only. + +## Assumptions + +- The branch starts from current `platform-dev` after Spec 339 integration evidence. +- Local development uses Sail where runtime/browser verification is needed. +- Existing browser test patterns and smoke-login helpers can be reused if automation is added. +- Spec 340 preparation is allowed to create Spec Kit artifacts but not application implementation. + +## Open Questions + +None blocking. If browser tooling or seed data cannot prove a surface, implementation must mark the check as blocked and recommend the smallest next action. + +## Follow-up Spec Candidates + +Only create or promote a follow-up if Spec 340 evidence proves it is needed: + +- `canonical-link-query-cleanup` for broad link/query drift not safely fixable inside Spec 340. +- `environment-resource-context-follow-through` for hidden Filament/environment context reliance beyond browser-visible contract issues. +- `provider-connection-scope-hardening-follow-up` only if Spec 339 browser verification reveals remaining credential-adjacent authority drift. +- Customer Review Workspace, Localization, Governance Inbox, and commercial lifecycle candidates remain deferred until this gate gives a go decision. diff --git a/specs/340-post-scope-contract-browser-verification-gate/surface-inventory.md b/specs/340-post-scope-contract-browser-verification-gate/surface-inventory.md new file mode 100644 index 00000000..fb6e34f6 --- /dev/null +++ b/specs/340-post-scope-contract-browser-verification-gate/surface-inventory.md @@ -0,0 +1,36 @@ +# Spec 340 Surface Inventory + +| Surface | Route / Entry Point | Expected Taxonomy | Origin(s) | Filter Support | Code Owner / Evidence | Verification Status | +|---|---|---|---|---|---|---| +| Workspace Overview | `/admin`, `/admin/workspaces/{workspace}/overview` | Workspace-owned source of truth | Clean Workspace origin | No environment filter | `routes/web.php`, `WorkspaceOverview`, `WorkspaceSidebarNavigation` | pass - Spec340 Browser smoke | +| Environment Dashboard | `/admin/workspaces/{workspace}/environments/{environment}` | Environment-owned detail surface | Environment origin | Route-owned environment, no `environment_id` query | `EnvironmentDashboard`, `ManagedEnvironmentLinks::viewUrl()` | pass - Spec340 Browser smoke | +| Environment Diagnostics | `/admin/workspaces/{workspace}/environments/{environment}/diagnostics` | Environment-owned detail surface | Environment origin | Route-owned environment, no hub filter | `routes/web.php`, `AdminSurfaceScope::EnvironmentBound` | pass - repo-classified; no runtime change | +| Environment Access Scopes | `/admin/workspaces/{workspace}/environments/{environment}/access-scopes` | Environment-owned detail surface | Environment origin | Route-owned environment, no hub filter | `routes/web.php`, `AdminSurfaceScope::EnvironmentBound` | pass - repo-classified; no runtime change | +| Operations | `/admin/workspaces/{workspace}/operations` | Workspace Hub with local environment filter | Workspace origin, Environment origin, filtered hub | Explicit `environment_id` only | `OperationRunLinks`, `Operations`, `WorkspaceHubEnvironmentFilter` | pass - Spec340 Browser smoke | +| Operation Run Detail | `/admin/workspaces/{workspace}/operations/{run}` | Canonical workspace record viewer | Operation drilldown | Record-derived workspace/tenant entitlement | `OperationRunLinks::tenantlessView()`, `TenantlessOperationRunViewer` | pass - repo-classified; no runtime change | +| Alerts Hub | `/admin/alerts` | Workspace Hub with local environment filter | Workspace origin, filtered hub where supported | Explicit `environment_id` only | `WorkspaceHubRegistry`, `Alerts` page | pass - Spec340 Browser smoke | +| Alert Deliveries | `/admin/alerts/alert-deliveries` | Workspace Hub child with local environment filter | Workspace origin, filtered hub where supported | Explicit `environment_id` chip via page hook | `AlertDeliveryResource`, `WorkspaceHubRegistry` | pass - repo-classified; related Spec322 harness data | +| Audit Log | `/admin/audit-log` | Workspace Hub with local environment filter | Workspace origin, filtered hub where supported | Explicit `environment_id` only | `AuditLog` page, `WorkspaceHubRegistry` | pass - Spec340 Browser smoke | +| Evidence Overview | `/admin/evidence/overview` | Workspace Hub with local environment filter | Workspace origin, Environment origin, filtered hub | Explicit `environment_id` only | `EvidenceOverview`, `WorkspaceHubEnvironmentFilter` | pass - Spec340 Browser smoke | +| Provider Connections List | `/admin/provider-connections` | Credential-adjacent Workspace Hub | Clean, remembered, filtered origins | Explicit `environment_id` only; create disabled/guided without it | `ProviderConnectionResource`, `ProviderConnectionPolicy` | pass - Spec340 Browser smoke | +| Provider Connections Create | `/admin/provider-connections/create` | Credential-adjacent provider surface | Clean or filtered origin | Requires explicit valid `environment_id` | `CreateProviderConnection`, `ProviderConnectionPolicy::create()` | pass - Spec340 Browser smoke | +| Provider Connection View/Edit | `/admin/provider-connections/{record}`, `/edit` | Credential-adjacent provider record surface | Record route, optional filtered query | Record-derived ownership and capability | `ProviderConnectionPolicy::view/update/delete()` | pass - Spec340 Browser smoke | +| Review Register | `/admin/reviews` | Workspace Hub with local environment filter | Workspace origin, filtered hub where supported | Explicit `environment_id` only | `ReviewRegister`, `WorkspaceHubRegistry` | pass - Spec340 Browser smoke | +| Customer Review Workspace | `/admin/reviews/workspace` | Workspace Hub with local environment filter | Workspace origin, filtered hub where supported | Explicit `environment_id` only | `CustomerReviewWorkspace`, `WorkspaceHubRegistry` | pass - Spec340 Browser smoke | +| Governance Inbox | `/admin/governance/inbox` | Workspace Hub with local environment filter | Workspace origin, filtered hub where supported | Explicit `environment_id` only | `GovernanceInbox`, `WorkspaceHubRegistry` | pass - Spec340 Browser smoke | +| Decision Register | `/admin/governance/decisions` | Workspace Hub with local environment filter | Workspace origin, filtered hub where supported | Explicit `environment_id` only | `DecisionRegister`, `WorkspaceHubRegistry` | pass - Spec340 Browser smoke | +| Finding Exceptions Queue | `/admin/finding-exceptions/queue` | Workspace Hub with local environment filter | Workspace origin, filtered hub where supported | Explicit `environment_id` only | `FindingExceptionsQueue`, `OpenFindingExceptionsQueueController` | pass - Spec340 Browser smoke | +| Baseline Profiles | `/admin/baseline-profiles` | Workspace-owned analysis/source-of-truth surface | Clean Workspace origin | No hidden environment filter | `BaselineProfileResource`, `AdminSurfaceScope::WorkspaceOwnedAnalysisSurface` | pass - Spec340 Browser smoke | +| Baseline Snapshots | `/admin/baseline-snapshots` | Workspace-owned analysis/source-of-truth surface | Clean Workspace origin | No hidden environment filter | `BaselineSnapshotResource`, `AdminSurfaceScope::WorkspaceOwnedAnalysisSurface` | pass - Spec340 Browser smoke | +| Managed Environments Registry | `/admin/workspaces/{workspace}/environments` | Workspace-owned source-of-truth surface | Workspace origin | No hidden environment filter | `ManagedEnvironmentsLanding`, `ManagedEnvironmentLinks::indexUrl()` | pass - repo-classified; no runtime change | +| Workspace Settings | `/admin/settings/workspace` | Workspace-owned configuration surface | Workspace origin | No hidden environment filter | `WorkspaceSettings`, `WorkspaceSidebarNavigation` | pass - repo-classified; no runtime change | +| Workspace Management | `/admin/workspaces` | Workspace-owned admin surface | Workspace origin | No hidden environment filter | `WorkspaceResource`, `WorkspaceSidebarNavigation` | pass - repo-classified; no runtime change | + +## Completed-Spec Guardrail + +The following packages were read as context only and were not modified: + +- `specs/313-workspace-environment-context-browser-verification/` +- `specs/322-browser-no-drift-regression-guard/` +- `specs/338-workspace-environment-resource-scope-contract/` +- `specs/339-provider-connection-scope-hardening/` diff --git a/specs/340-post-scope-contract-browser-verification-gate/tasks.md b/specs/340-post-scope-contract-browser-verification-gate/tasks.md new file mode 100644 index 00000000..c3356d16 --- /dev/null +++ b/specs/340-post-scope-contract-browser-verification-gate/tasks.md @@ -0,0 +1,133 @@ +# Tasks: Spec 340 - Post-Scope Contract Browser Verification Gate + +- Input: `specs/340-post-scope-contract-browser-verification-gate/spec.md`, `specs/340-post-scope-contract-browser-verification-gate/plan.md` +- Preparation status: implementation-ready. + +**Tests**: Required during implementation. This spec is a browser/IA verification gate and may add a bounded Pest Browser smoke only when stable. + +## Test Governance Checklist + +- [x] Lane assignment is named and narrow: browser verification, optional fast-feedback Feature probes. +- [x] Any new Browser test stays representative and avoids broad full-app route sweep cost. +- [x] Existing browser helpers, factories, and smoke-login paths are reused before adding new fixture setup. +- [x] Blocked browser checks are reported as blocked, not passed. +- [x] Runtime fixes require an active artifact update or follow-up spec before code changes. + +## Phase 1: Preflight And Guardrails + +**Purpose**: Confirm safe branch/repo state and prevent completed-spec rewrites. + +- [x] T001 Re-read `specs/340-post-scope-contract-browser-verification-gate/spec.md`, `specs/340-post-scope-contract-browser-verification-gate/plan.md`, and this `tasks.md`. +- [x] T002 Confirm branch and working tree intent with `git status --short --branch` and record the baseline commit in `specs/340-post-scope-contract-browser-verification-gate/audit-report.md`. +- [x] T003 Re-read `.specify/memory/constitution.md`, `docs/ai-coding-rules.md`, and relevant `docs/*-guidelines.md`; record no-runtime-change posture in `specs/340-post-scope-contract-browser-verification-gate/audit-report.md`. +- [x] T004 Confirm related completed specs are context only and do not modify `specs/313-workspace-environment-context-browser-verification/`, `specs/322-browser-no-drift-regression-guard/`, `specs/338-workspace-environment-resource-scope-contract/`, or `specs/339-provider-connection-scope-hardening/`. +- [x] T005 Create `specs/340-post-scope-contract-browser-verification-gate/artifacts/screenshots/` if screenshot evidence will be captured. + +## Phase 2: Repo Discovery And Matrix Setup + +**Purpose**: Build a repo-based checklist before opening the browser. + +- [x] T006 Create `specs/340-post-scope-contract-browser-verification-gate/surface-inventory.md` with columns for surface, route, expected taxonomy, origin, filter support, code owner, and verification status. +- [x] T007 Create `specs/340-post-scope-contract-browser-verification-gate/scope-verification-matrix.md` with columns for page, origin, URL/query, shell, sidebar, breadcrumb/header, visible filter evidence, reload/back-forward result, screenshot, status, and finding ID. +- [x] T008 Create `specs/340-post-scope-contract-browser-verification-gate/findings.md` with P1/P2/P3/backlog definitions and empty finding sections. +- [x] T009 Initialize `specs/340-post-scope-contract-browser-verification-gate/audit-report.md` with command log, branch, baseline commit, verification scope, and go/no-go placeholder. +- [x] T010 Inspect `apps/platform/routes/web.php` and record the current admin workspace/environment route families in `surface-inventory.md`. +- [x] T011 Inspect `apps/platform/app/Providers/Filament/AdminPanelProvider.php` for registered pages/resources, render hooks, and navigation-relevant provider configuration. +- [x] T012 Inspect `apps/platform/app/Support/Navigation/AdminSurfaceScope.php`, `WorkspaceHubRegistry.php`, `WorkspaceHubEnvironmentFilter.php`, and `WorkspaceSidebarNavigation.php`; classify expected shell/sidebar ownership in `surface-inventory.md`. +- [x] T013 Inspect `apps/platform/app/Support/ManagedEnvironmentLinks.php`, `OperationRunLinks.php`, and `WorkspaceContext.php`; record link/filter/topbar/remembered-environment seams in `surface-inventory.md`. +- [x] T014 Inspect `apps/platform/app/Filament/Resources/ProviderConnectionResource.php` and `apps/platform/app/Policies/ProviderConnectionPolicy.php`; record Provider Connection authority expectations in `surface-inventory.md`. +- [x] T015 Inspect existing browser tests under `apps/platform/tests/Browser/Spec314*`, `Spec316*`, `Spec322*`, `Spec338*`, and `Spec281*`; record reusable setup patterns in `audit-report.md`. + +## Phase 3: Browser Setup And Data Availability + +**Purpose**: Make browser results reproducible and avoid false passes from missing data. + +- [x] T016 Resolve the app URL through Laravel Boost `get_absolute_url` or documented Sail/local config and record it in `audit-report.md`. +- [x] T017 Identify the smoke-login actor and available workspace/environment fixture path from existing browser test conventions; record the source in `audit-report.md`. +- [x] T018 Verify at least one Workspace is selectable in the browser and record available Workspace evidence in `scope-verification-matrix.md`. +- [x] T019 Verify at least one Managed Environment is reachable from that Workspace and record whether a second environment exists for comparison in `scope-verification-matrix.md`. +- [x] T020 Record unavailable seed data, blocked routes, or authorization-limited surfaces in `findings.md` as `blocked`, not pass. + +## Phase 4: Workspace-Origin Verification + +**Purpose**: Prove clean Workspace mode does not imply hidden environment scope. + +- [x] T021 From a clean Workspace origin, open Workspace Overview and record shell/sidebar/header evidence in `scope-verification-matrix.md`. +- [x] T022 From clean Workspace origin, open Operations and record URL/query, scope signals, local filter state, reload behavior, and screenshot path if captured. +- [x] T023 From clean Workspace origin, open Alerts and Audit Log and record whether they behave as Workspace Hubs with local environment filters where supported. +- [x] T024 From clean Workspace origin, open Evidence Overview and record whether it remains a Workspace Hub, not an environment-owned evidence route. +- [x] T025 From clean Workspace origin, open Provider Connections and record list context, visible filter state, create affordance, and absence of remembered-environment authority. +- [x] T026 From clean Workspace origin, open Review Register, Customer Review Workspace, Governance Inbox, Decision Register, and Finding Exceptions Queue where reachable; record pass/blocked/finding status per surface. +- [x] T027 From clean Workspace origin, open Baseline Profiles and Baseline Snapshots and record that they remain workspace-owned source-of-truth surfaces. + +## Phase 5: Environment-Origin And Filtered Hub Verification + +**Purpose**: Prove Environment mode and filtered Workspace Hub mode stay distinct. + +- [x] T028 From Environment Dashboard, record route, shell, sidebar, breadcrumb/header, and environment identity evidence. +- [x] T029 From Environment Dashboard, open environment-owned detail surfaces that are present and record whether they remain environment-route-owned. +- [x] T030 From Environment Dashboard, open Operations through sidebar/global navigation and record whether it becomes clean Workspace Hub entry or explicit filtered hub entry. +- [x] T031 From Environment Dashboard, open Alerts, Audit Log, Evidence Overview, Provider Connections, Review Register, Customer Review Workspace, Governance Inbox, Decision Register, and Finding Exceptions Queue where reachable; record explicit `environment_id` behavior where intended. +- [x] T032 For at least three representative filtered Workspace Hubs, reload the page and record whether filter state remains truthful and visible. +- [x] T033 For at least three representative filtered Workspace Hubs, use browser back/forward and record whether shell/filter state remains truthful. +- [x] T034 Clear the environment filter where supported and record whether the resulting clean hub entry matches the expected Workspace Hub contract. + +## Phase 6: Topbar Semantics Verification + +**Purpose**: Prove topbar context does not silently become a page-local filter. + +- [x] T035 Use the Workspace selector from a Workspace Hub and record whether it switches workspace context rather than local page filter state. +- [x] T036 Use the Environment selector from a Workspace Hub and record whether it navigates/opens environment context instead of silently filtering the current hub. +- [x] T037 With a remembered environment present, open a clean Workspace Hub URL and record whether the hub remains unfiltered unless explicit `environment_id` is present. +- [x] T038 Record any page copy that instructs users to use the topbar as a local filter in `findings.md`. + +## Phase 7: Provider Connection Authority Verification + +**Purpose**: Prove credential-adjacent browser behavior matches Spec 339. + +- [x] T039 Open `/admin/provider-connections` clean and record list scope, filter state, and create affordance in `scope-verification-matrix.md`. +- [x] T040 Open `/admin/provider-connections?environment_id=` and record visible filter evidence plus create affordance tied to that environment. +- [x] T041 Open `/admin/provider-connections/create` without `environment_id` and record whether create is blocked or safely guided without remembered-environment authority. +- [x] T042 Open `/admin/provider-connections/create?environment_id=` where safely reproducible and record 404/blocked behavior without leaking foreign workspace details. +- [x] T043 Open an existing Provider Connection view/edit route and record whether visible context derives from record ownership, not topbar/remembered environment. +- [x] T044 Inspect credential-adjacent visible actions without executing destructive or external-provider operations; record confirmation/authorization/audit affordance expectations in `findings.md`. +- [x] T045 If a suspected Provider Connection issue appears, run or reference targeted Feature coverage in `apps/platform/tests/Feature/ProviderConnections/` before classifying severity. + +## Phase 8: Findings, Go/No-Go, And Follow-Up Control + +**Purpose**: Convert browser evidence into a concrete decision. + +- [x] T046 Classify every matrix row in `scope-verification-matrix.md` as `pass`, `P1`, `P2`, `P3`, `backlog`, `blocked`, or `not-applicable`. +- [x] T047 For each P1/P2 finding in `findings.md`, include surface, origin, URL, expected behavior, actual behavior, evidence, likely owner files, and smallest safe next action. +- [x] T048 For each blocked check in `findings.md`, include the missing route/data/tooling condition and whether it blocks go/no-go confidence. +- [x] T049 Write the final go/no-go recommendation in `audit-report.md`. +- [x] T050 If no P1/P2 drift exists, state that new feature work may resume and list deferred candidates without opening them automatically. +- [x] T051 If P1/P2 drift exists, recommend either a bounded in-scope fix path after artifact update or a follow-up spec; do not start unrelated feature work. + +## Phase 9: Optional Automated Regression Coverage + +**Purpose**: Add bounded automation only when it is stable enough to maintain. + +- [x] T052 Decide in `audit-report.md` whether to add `apps/platform/tests/Browser/Spec340PostScopeContractVerificationSmokeTest.php` or keep Spec 340 as manual/in-app browser verification only. +- [x] T053 If automation is added, create `apps/platform/tests/Browser/Spec340PostScopeContractVerificationSmokeTest.php` using existing Pest 4 browser conventions and explicit workspace/environment fixtures. +- [x] T054 If automation is added, assert no JavaScript errors and cover representative clean Workspace origin, Environment origin, filtered hub entry, topbar remembered-environment behavior, and Provider Connections create authority. +- [x] T055 Keep exhaustive route/query permutations in Feature tests or artifact matrix, not the Browser test. +- [x] T056 Do not add or modify seeders unless `spec.md` and `plan.md` are updated with the fixture-cost decision first. + +## Phase 10: Validation And Close-Out + +**Purpose**: Prove the gate ran and preparation boundaries remained intact. + +- [x] T057 Run focused Browser validation if automated coverage exists: `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Browser --filter=Spec340`. +- [x] T058 Run targeted Provider Connections Feature validation if Provider Connection authority findings were suspected: `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/ProviderConnections --filter=ScopeHardening`. +- [x] T059 Run `git diff --check` from the repository root. +- [x] T060 Update `audit-report.md` with exact commands, results, screenshots, blocked checks, full-suite status, unrelated residual failures, and final go/no-go. +- [x] T061 Confirm no completed specs were modified and no application runtime code was changed unless explicitly authorized by updated Spec 340 artifacts. + +## Explicit Non-Goals + +- [x] NT001 Do not redesign sidebar, topbar, Provider Connections, Evidence, Baselines, or Review surfaces. +- [x] NT002 Do not create migrations, models, services, jobs, policies, routes, or runtime behavior changes during preparation. +- [x] NT003 Do not rewrite completed Spec 313/322/338/339 close-out, validation, or completed-task history. +- [x] NT004 Do not create follow-up specs automatically without P1/P2 browser evidence. +- [x] NT005 Do not execute destructive or external-provider actions during browser verification.