Set-StrictMode -Version 2.0 $ErrorActionPreference = "Stop" $repoRoot = Resolve-Path (Join-Path $PSScriptRoot "..") $verifier = Join-Path $PSScriptRoot "verify-send-audit-idempotency.ps1" $workDir = Join-Path ([System.IO.Path]::GetTempPath()) ("isphere-send-audit-idempotency-test-" + [System.Guid]::NewGuid().ToString("N")) New-Item -ItemType Directory -Path $workDir | Out-Null try { $auditPath = Join-Path $workDir "send-audit.jsonl" $idempotencyPath = Join-Path $workDir "send-idempotency.jsonl" @( @{ tool = "isphere_send_message"; target_ref = "contact:alice"; content_sha256 = "hash-a"; idempotency_key_sha256 = "key-a"; result = "planned" }, @{ tool = "isphere_send_message"; target_ref = "contact:alice"; content_sha256 = "hash-a"; idempotency_key_sha256 = "key-a"; result = "planned" }, @{ tool = "isphere_send_message"; target_ref = "contact:alice"; content_sha256 = "hash-b"; idempotency_key_sha256 = "key-a"; result = "blocked" } ) | ForEach-Object { $_ | ConvertTo-Json -Compress } | Set-Content -Path $auditPath -Encoding UTF8 @( @{ tool = "isphere_send_message"; target_ref = "contact:alice"; content_sha256 = "hash-a"; idempotency_key_sha256 = "key-a"; audit_ref = "send-message:first" } ) | ForEach-Object { $_ | ConvertTo-Json -Compress } | Set-Content -Path $idempotencyPath -Encoding UTF8 $summary = & $verifier -AuditPath $auditPath -IdempotencyPath $idempotencyPath | ConvertFrom-Json if (-not $summary.ok) { throw "expected ok summary, got: $($summary | ConvertTo-Json -Compress)" } if ($summary.audit_records -ne 3) { throw "audit_records=$($summary.audit_records), want 3" } if ($summary.idempotency_records -ne 1) { throw "idempotency_records=$($summary.idempotency_records), want 1" } if (-not $summary.duplicate_detected) { throw "duplicate_detected should be true" } if (-not $summary.conflict_detected) { throw "conflict_detected should be true" } if ($summary.raw_body_present) { throw "raw_body_present should be false" } if ($summary.raw_idempotency_key_present) { throw "raw_idempotency_key_present should be false" } $leakyAuditPath = Join-Path $workDir "leaky-audit.jsonl" @{ tool = "isphere_send_message"; content_text = "raw body"; idempotency_key_sha256 = "key-b" } | ConvertTo-Json -Compress | Set-Content -Path $leakyAuditPath -Encoding UTF8 $leakyOutput = & $verifier -AuditPath $leakyAuditPath -IdempotencyPath $idempotencyPath 2>&1 if ($LASTEXITCODE -eq 0) { throw "leaky audit unexpectedly passed: $leakyOutput" } Write-Output (@{ ok = $true verification = "send_audit_idempotency_fixture" repo_root = $repoRoot.Path } | ConvertTo-Json -Compress) } finally { if (Test-Path $workDir) { Remove-Item -LiteralPath $workDir -Recurse -Force } }