test: add post-scope contract browser verification gate (340) #411

Merged
ahmido merged 1 commits from 340-post-scope-contract-browser-verification-gate into platform-dev 2026-05-31 14:37:31 +00:00
10 changed files with 1172 additions and 0 deletions

View File

@ -0,0 +1,158 @@
<?php
declare(strict_types=1);
use App\Filament\Pages\EnvironmentDashboard;
use App\Filament\Pages\Governance\DecisionRegister;
use App\Filament\Pages\Governance\GovernanceInbox;
use App\Filament\Pages\Monitoring\FindingExceptionsQueue;
use App\Filament\Pages\Reviews\CustomerReviewWorkspace;
use App\Filament\Pages\Reviews\ReviewRegister;
use App\Filament\Resources\BaselineProfileResource;
use App\Filament\Resources\BaselineSnapshotResource;
use App\Filament\Resources\ProviderConnectionResource;
use App\Support\ManagedEnvironmentLinks;
use App\Support\OperationRunLinks;
use Tests\Browser\Support\Spec322WorkspaceEnvironmentBrowserHarness as Spec322Harness;
pest()->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();
});

View File

@ -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 <new-file>` 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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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=<environment>` | 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=<environment>` | 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=<environment>` | 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.

View File

@ -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.

View File

@ -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/`

View File

@ -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=<valid-environment>` 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=<wrong-workspace-environment>` 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.