Some checks failed
Main Confidence / confidence (push) Failing after 59s
Automatisch erstellt: Merge `platform-dev` into `dev` (via MCP) Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #299
101 lines
4.5 KiB
YAML
101 lines
4.5 KiB
YAML
version: 1
|
|
kind: finding-creation-invariants
|
|
|
|
scope:
|
|
goal: enforce lifecycle-ready finding creation and recurrence or reopen semantics across the active finding writers only
|
|
non_goals:
|
|
- repair tooling or backfill runtime surfaces
|
|
- new workflow states or new findings lifecycle families
|
|
- customer-facing workflow expansion
|
|
- compare refresh work
|
|
- external support handoff
|
|
- broader findings redesign
|
|
- silent database-constraint rollout
|
|
stop_conditions:
|
|
- another shipped finding writer is discovered outside the three confirmed paths
|
|
- application-level write enforcement proves insufficient without a migration or DB constraint
|
|
- the only available implementation shape is a new generic invariant framework
|
|
|
|
active_writer_families:
|
|
baseline_compare:
|
|
owner_files:
|
|
- apps/platform/app/Jobs/CompareBaselineToTenantJob.php
|
|
identity:
|
|
canonical_key: recurrence_key
|
|
fingerprint_contract: fingerprint equals recurrence_key
|
|
observation_boundary:
|
|
duplicate_guard: current_operation_run_id prevents double counting the same compare run
|
|
entra_admin_roles:
|
|
owner_files:
|
|
- apps/platform/app/Services/EntraAdminRoles/EntraAdminRolesFindingGenerator.php
|
|
identity:
|
|
canonical_key: existing role-assignment or aggregate fingerprint
|
|
observation_boundary:
|
|
duplicate_guard: later observedAt advances seen history
|
|
permission_posture:
|
|
owner_files:
|
|
- apps/platform/app/Services/PermissionPosture/PermissionPostureFindingGenerator.php
|
|
identity:
|
|
canonical_key: existing permission or error fingerprint
|
|
observation_boundary:
|
|
duplicate_guard: later observedAt advances seen history
|
|
|
|
shared_lifecycle_contract:
|
|
model:
|
|
owner_file: apps/platform/app/Models/Finding.php
|
|
invariants:
|
|
- workspace_id and tenant_id remain required ownership anchors
|
|
- no new status or reason-code family is introduced
|
|
reopen_service:
|
|
owner_file: apps/platform/app/Services/Findings/FindingWorkflowService.php
|
|
requirement:
|
|
- terminal findings reopen only through reopenBySystem
|
|
- reopened_at is set
|
|
- resolved and closed markers clear according to current service behavior
|
|
- sla_days and due_at are recalculated from reopenedAt
|
|
- existing audit and alert side effects are preserved
|
|
|
|
lifecycle_invariants:
|
|
create:
|
|
required_fields:
|
|
- status is new
|
|
- first_seen_at equals observedAt
|
|
- last_seen_at equals observedAt
|
|
- times_seen equals 1
|
|
- sla_days is initialized when the current severity policy returns a value
|
|
- due_at is initialized when the current severity policy requires due-state truth
|
|
contextual_fields:
|
|
- current_operation_run_id remains populated where the current writer already sets it
|
|
refresh_existing:
|
|
required_behavior:
|
|
- the same canonical finding identity is reused
|
|
- missing first_seen_at, last_seen_at, and times_seen are repaired inline
|
|
- missing sla_days or due_at covered by this slice are repaired inline without a second-pass repair tool
|
|
- already-valid lifecycle fields are not reset unnecessarily
|
|
reopen:
|
|
required_behavior:
|
|
- the same canonical finding identity is reopened, not duplicated
|
|
- resolved_at and resolved_reason clear on reopen
|
|
- first_seen_at is retained
|
|
- last_seen_at and times_seen advance according to the family observation rule
|
|
|
|
downstream_regression_consumers:
|
|
findings_surfaces:
|
|
owner_files:
|
|
- apps/platform/app/Filament/Resources/FindingResource.php
|
|
- apps/platform/app/Filament/Resources/FindingResource/Pages/ListFindings.php
|
|
- apps/platform/app/Filament/Pages/Findings/MyFindingsInbox.php
|
|
- apps/platform/app/Filament/Pages/Findings/FindingsIntakeQueue.php
|
|
expectation:
|
|
- no design change is required; these surfaces should continue to read truthful due_at and reopened_at data from the same Finding records
|
|
|
|
validation_expectations:
|
|
required_feature_proof:
|
|
- baseline compare proves create readiness, same-run retry protection, reopened reuse, and inline repair of incomplete lifecycle fields
|
|
- Entra admin roles proves create readiness, repeated observation, reopened reuse, and inline repair of incomplete lifecycle fields
|
|
- permission posture proves create readiness, repeated observation, reopened reuse, and inline repair of incomplete lifecycle fields
|
|
excluded_lanes:
|
|
- browser
|
|
- heavy-governance
|
|
migration_posture:
|
|
- no new migration or schema artifact is allowed in this slice |