resolve(spec427RedactionResourceType($canonicalType)); $rules = $decision->sourceMetadata['redaction_rules']; $metadataJson = json_encode($decision->sourceMetadata, JSON_THROW_ON_ERROR); expect($decision->sourceContractState)->toBe(CoverageSourceContractDecision::CONTRACT_BLOCKED_REPO_ADAPTER_MISSING) ->and($rules['raw_payload_default_visible'])->toBeFalse() ->and($rules['permission_context_default_visible'])->toBeFalse() ->and($rules['redacted_permission_context'])->toBeTrue() ->and($rules['forbidden_default_output'])->toContain('raw_provider_payload') ->and($rules['forbidden_default_output'])->toContain('tokens') ->and($rules['forbidden_default_output'])->toContain('credentials') ->and($rules['forbidden_default_output'])->toContain('mail_content') ->and($metadataJson)->not->toContain('client-secret-value') ->and($metadataJson)->not->toContain('authorization-token-value'); })->with([ 'transportRule', 'acceptedDomain', 'appPermissionPolicy', 'meetingPolicy', ]); it('Spec427 preserves Exchange and Teams helper redaction for future verified payloads', function (): void { $normalized = app(ExchangeTeamsComparablePayloadNormalizer::class)->normalize('transportRule', [ 'Guid' => 'rule-guid', 'DisplayName' => 'Sensitive transport rule', 'ProviderResponse' => 'raw-provider-response-secret', 'SubjectContainsWords' => ['private subject phrase'], 'clientSecret' => 'client-secret-value', ]); $json = json_encode($normalized, JSON_THROW_ON_ERROR); expect($json) ->not->toContain('raw-provider-response-secret') ->not->toContain('private subject phrase') ->not->toContain('client-secret-value') ->and(data_get($normalized, 'conditions.subject_contains_words'))->toBe('[redacted]'); }); function spec427RedactionResourceType(string $canonicalType): TenantConfigurationResourceType { $definition = collect(ResourceTypeRegistry::defaultDefinitions()) ->firstWhere('canonical_type', $canonicalType); expect($definition)->not->toBeNull("Missing default resource type definition for {$canonicalType}."); return new TenantConfigurationResourceType($definition); }