Added `BaselineReadinessGate`, resolution propagation, and disclosure semantics logic per Spec 385. Integrates baseline unreadiness into Customer Review Workspace and Review Packs to prevent report generation when identity bindings are unresolved. Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #456
96 lines
3.5 KiB
PHP
96 lines
3.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Filament\Pages\Reviews\CustomerReviewWorkspace;
|
|
use App\Models\ManagedEnvironment;
|
|
use App\Models\ReviewPack;
|
|
use App\Models\User;
|
|
use App\Support\Baselines\CompareSemantics\CompareResultReason;
|
|
use App\Support\EnvironmentReviewStatus;
|
|
use App\Support\OperationRunOutcome;
|
|
use App\Support\Workspaces\WorkspaceContext;
|
|
use Livewire\Livewire;
|
|
|
|
it('shows baseline readiness blockers on the customer review workspace without exposing raw binding internals', function (): void {
|
|
$environment = ManagedEnvironment::factory()->create(['name' => 'Spec385 Baseline Blocked']);
|
|
[$user, $environment] = createUserWithTenant(tenant: $environment, role: 'owner', workspaceRole: 'manager');
|
|
[$profile, $baselineSnapshot] = seedActiveBaselineForTenant($environment);
|
|
|
|
seedBaselineCompareRun(
|
|
tenant: $environment,
|
|
profile: $profile,
|
|
snapshot: $baselineSnapshot,
|
|
compareContext: spec385FilamentCompareContext([CompareResultReason::UnresolvedAmbiguousIdentity]),
|
|
outcome: OperationRunOutcome::PartiallySucceeded->value,
|
|
);
|
|
|
|
$snapshot = seedEnvironmentReviewEvidence($environment, findingCount: 0, driftCount: 0);
|
|
$review = composeEnvironmentReviewForTest($environment, $user, $snapshot);
|
|
$review->forceFill([
|
|
'status' => EnvironmentReviewStatus::Published->value,
|
|
'published_at' => now(),
|
|
'published_by_user_id' => (int) $user->getKey(),
|
|
])->save();
|
|
|
|
$pack = ReviewPack::factory()->ready()->create([
|
|
'managed_environment_id' => (int) $environment->getKey(),
|
|
'workspace_id' => (int) $environment->workspace_id,
|
|
'environment_review_id' => (int) $review->getKey(),
|
|
'evidence_snapshot_id' => (int) $snapshot->getKey(),
|
|
'initiated_by_user_id' => (int) $user->getKey(),
|
|
'options' => [
|
|
'include_pii' => false,
|
|
'include_operations' => true,
|
|
],
|
|
]);
|
|
$review->forceFill(['current_export_review_pack_id' => (int) $pack->getKey()])->save();
|
|
|
|
spec385WorkspaceComponent($user, $environment)
|
|
->assertSee('Output not customer-ready')
|
|
->assertSee('Baseline readiness blocked')
|
|
->assertSee('Open baseline resolution')
|
|
->assertDontSee('baseline_identity_unresolved')
|
|
->assertDontSee('provider_resource_id')
|
|
->assertDontSee('canonical_subject_key')
|
|
->assertDontSee('internal_diagnostics');
|
|
});
|
|
|
|
function spec385WorkspaceComponent(User $user, ManagedEnvironment $environment): mixed
|
|
{
|
|
session()->put(WorkspaceContext::SESSION_KEY, (int) $environment->workspace_id);
|
|
setAdminPanelContext();
|
|
|
|
return Livewire::actingAs($user)
|
|
->test(CustomerReviewWorkspace::class);
|
|
}
|
|
|
|
/**
|
|
* @param list<CompareResultReason> $reasons
|
|
* @return array<string, mixed>
|
|
*/
|
|
function spec385FilamentCompareContext(array $reasons): array
|
|
{
|
|
$byReason = [];
|
|
$byReadinessImpact = [];
|
|
|
|
foreach ($reasons as $reason) {
|
|
$byReason[$reason->value] = ($byReason[$reason->value] ?? 0) + 1;
|
|
|
|
$impact = $reason->readinessImpact()->value;
|
|
$byReadinessImpact[$impact] = ($byReadinessImpact[$impact] ?? 0) + 1;
|
|
}
|
|
|
|
return [
|
|
'result_semantics' => [
|
|
'version' => 'compare_semantics.v1',
|
|
'run_outcome' => 'partial',
|
|
'operation_outcome' => OperationRunOutcome::PartiallySucceeded->value,
|
|
'counts' => [
|
|
'by_reason' => $byReason,
|
|
'by_readiness_impact' => $byReadinessImpact,
|
|
],
|
|
],
|
|
];
|
|
}
|