TenantAtlas/specs/192-record-header-discipline/contracts/record-header-discipline.logical.openapi.yaml
ahmido 9f6985291e feat: implement spec 192 record page header discipline (#226)
## Summary
- implement Spec 192 across the targeted Filament record, detail, and edit pages with explicit action-surface inventory and guard coverage
- add the focused Spec 192 browser smoke, feature tests, and spec artifacts under `specs/192-record-header-discipline`
- improve unhandled promise rejection diagnostics by correlating 419s to the underlying Livewire request URL
- disable panel-wide database notification polling on the admin, tenant, and system panels and cover the mitigation with focused tests

## Validation
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/DatabaseNotificationsPollingTest.php`
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/DatabaseNotificationsPollingTest.php tests/Feature/Filament/UnhandledRejectionLoggerAssetTest.php tests/Feature/Filament/FilamentNotificationsAssetsTest.php tests/Feature/Workspaces/ManagedTenantsLivewireUpdateTest.php tests/Feature/Filament/AdminSmokeTest.php`
- `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`
- manual integrated-browser verification of the Spec 192 surfaces and the notification-polling mitigation

## Notes
- Livewire v4 / Filament v5 compliance remains unchanged.
- Provider registration stays in `bootstrap/providers.php`.
- No Global Search behavior was expanded.
- No destructive action confirmation semantics were relaxed.
- The full test suite was not run in this PR.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #226
2026-04-11 21:20:41 +00:00

252 lines
7.6 KiB
YAML

openapi: 3.1.0
info:
title: Record Page Header Discipline Internal Surface Contract
version: 0.1.0
summary: Internal logical contract for Spec 192 record-page header discipline
description: |
This contract is an internal planning artifact for Spec 192. The affected
surfaces continue to render HTML through Filament and Livewire. The schemas
below define the bounded render contract and regression expectations for
standard record/detail/edit headers, grouped secondary actions, contextual
navigation outside the header, and the explicit workflow-heavy exception.
servers:
- url: /internal
x-record-header-discipline-consumers:
- surface: standard-record-pages
sourceFiles:
- apps/platform/app/Filament/Resources/BaselineProfileResource/Pages/ViewBaselineProfile.php
- apps/platform/app/Filament/Resources/EvidenceSnapshotResource/Pages/ViewEvidenceSnapshot.php
- apps/platform/app/Filament/Resources/FindingExceptionResource/Pages/ViewFindingException.php
- apps/platform/app/Filament/Resources/TenantReviewResource/Pages/ViewTenantReview.php
- apps/platform/app/Filament/Resources/TenantResource/Pages/EditTenant.php
mustRender:
- at_most_one_primary_header_action
- grouped_secondary_actions
- contextual_navigation_or_related_context_outside_header
- separated_danger_actions_when_present
mustNotRender:
- flat_navigation_mutation_strip
- multiple_competing_primary_actions
- empty_action_group_placeholders
- surface: workflow-heavy-special-type
sourceFiles:
- apps/platform/app/Filament/Resources/TenantResource/Pages/ViewTenant.php
mustRender:
- explicit_exception_reason
- grouped_and_ordered_actions
- optional_single_primary_only_when_dominant
mustNotRender:
- silent_exception
- flat_multi_button_primary_strip
- surface: regression-guards
sourceFiles:
- apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceValidator.php
- apps/platform/app/Support/Ui/ActionSurface/ActionSurfaceExemptions.php
- apps/platform/tests/Feature/Guards/ActionSurfaceContractTest.php
- apps/platform/tests/Feature/Guards/ActionSurfaceValidatorTest.php
paths:
/internal/action-surfaces/record-pages/{surface}:
get:
summary: Return the logical header-discipline contract for an in-scope record page
operationId: getRecordPageHeaderDisciplineContract
parameters:
- name: surface
in: path
required: true
schema:
$ref: '#/components/schemas/SurfaceKey'
responses:
'200':
description: Logical render contract and regression expectations for the requested surface
content:
application/vnd.tenantpilot.record-header-discipline+json:
schema:
$ref: '#/components/schemas/RecordHeaderSurfaceContract'
'404':
description: Requested surface is not in the Spec 192 inventory
components:
schemas:
SurfaceKey:
type: string
enum:
- baseline_profile_view
- evidence_snapshot_view
- finding_exception_view
- tenant_review_view
- tenant_edit
- tenant_view
- provider_connection_view
- finding_view
- review_pack_view
- alert_destination_view
- policy_version_view
- workspace_view
- baseline_snapshot_view
- backup_set_view
SurfaceClassification:
type: string
enum:
- remediation_required
- minor_alignment_only
- compliant_reference
- workflow_heavy_special_type
ActionKind:
type: string
enum:
- navigation
- mutation
- external_link
- lifecycle
- danger
Placement:
type: string
enum:
- primary_visible
- secondary_grouped
- contextual
- danger_grouped
OperationScope:
type: string
enum:
- TenantPilot only
- Microsoft tenant
- simulation only
- read-only
HeaderActionDescriptor:
type: object
additionalProperties: false
required:
- actionKey
- label
- actionKind
- placement
- requiresConfirmation
- usesUiEnforcement
- operationScope
properties:
actionKey:
type: string
label:
type: string
actionKind:
$ref: '#/components/schemas/ActionKind'
placement:
$ref: '#/components/schemas/Placement'
requiresConfirmation:
type: boolean
usesUiEnforcement:
type: boolean
capabilityKey:
type:
- string
- 'null'
writesAuditLog:
type: boolean
operationScope:
$ref: '#/components/schemas/OperationScope'
ContextualNavigationEntry:
type: object
additionalProperties: false
required:
- label
- sourceSection
- isAvailable
properties:
label:
type: string
targetUrl:
type:
- string
- 'null'
sourceSection:
type: string
enum:
- summary
- related_context
- field_context
- status_context
isAvailable:
type: boolean
SecondaryActionGroup:
type: object
additionalProperties: false
required:
- label
- orderedBuckets
- actions
properties:
label:
type: string
orderedBuckets:
type: array
items:
type: string
actions:
type: array
items:
$ref: '#/components/schemas/HeaderActionDescriptor'
HeaderRegressionExpectation:
type: object
additionalProperties: false
required:
- maxVisiblePrimaryActions
- requiresGroupedSecondaryActions
- allowsPrimaryNavigation
- requiresExplicitExceptionReason
properties:
maxVisiblePrimaryActions:
type: integer
minimum: 0
maximum: 1
requiresGroupedSecondaryActions:
type: boolean
allowsPrimaryNavigation:
type: boolean
requiresDangerSeparation:
type: boolean
requiresExplicitExceptionReason:
type: boolean
browserSmokeRequired:
type: boolean
RecordHeaderSurfaceContract:
type: object
additionalProperties: false
required:
- surfaceKey
- classification
- canonicalNoun
- primaryQuestion
- actions
- contextualNavigation
- regressionExpectation
properties:
surfaceKey:
$ref: '#/components/schemas/SurfaceKey'
classification:
$ref: '#/components/schemas/SurfaceClassification'
canonicalNoun:
type: string
primaryQuestion:
type: string
primaryAction:
anyOf:
- $ref: '#/components/schemas/HeaderActionDescriptor'
- type: 'null'
secondaryActionGroup:
anyOf:
- $ref: '#/components/schemas/SecondaryActionGroup'
- type: 'null'
dangerActions:
type: array
items:
$ref: '#/components/schemas/HeaderActionDescriptor'
contextualNavigation:
type: array
items:
$ref: '#/components/schemas/ContextualNavigationEntry'
explicitExceptionReason:
type:
- string
- 'null'
regressionExpectation:
$ref: '#/components/schemas/HeaderRegressionExpectation'