chore: establish local platform baseline

This commit is contained in:
Codex Local
2026-08-26 06:41:54 +08:00
commit 29bdf4900f
575 changed files with 95644 additions and 0 deletions
+155
View File
@@ -0,0 +1,155 @@
param(
[ValidateRange(1, 50)][int]$BatchCount = 10,
[ValidateRange(1, 1000)][int]$SegmentsPerBatch = 1000
)
$ErrorActionPreference = 'Stop'
$PSNativeCommandUseErrorActionPreference = $true
$projectRoot = Split-Path -Parent $PSScriptRoot
Set-Location -LiteralPath $projectRoot
$api = 'http://localhost:58080'
$tenantId = '10000000-0000-0000-0000-000000000001'
$householdId = '10000000-0000-0000-0000-000000000201'
$subjectId = '10000000-0000-0000-0000-000000000401'
$deviceInternalId = '10000000-0000-0000-0000-000000000501'
$deviceId = '10000000-0000-0000-0000-000000000511'
$ownerId = '10000000-0000-0000-0000-000000000101'
$deviceSecret = [Text.Encoding]::UTF8.GetBytes('local-simulated-device-secret-32-bytes-minimum')
$conversationId = [Guid]::NewGuid().ToString()
$conversationInternalId = [Guid]::NewGuid().ToString()
$consentId = [Guid]::NewGuid().ToString()
$snapshotId = [Guid]::NewGuid().ToString()
$contextId = [Guid]::NewGuid().ToString()
function Get-Sha256Hex([byte[]]$Bytes) {
$sha = [Security.Cryptography.SHA256]::Create()
try { return ([BitConverter]::ToString($sha.ComputeHash($Bytes))).Replace('-', '').ToLowerInvariant() }
finally { $sha.Dispose() }
}
function Invoke-DeviceRequest([string]$Method, [string]$Path, [string]$Body, [hashtable]$ExtraHeaders) {
$bodyBytes = [Text.Encoding]::UTF8.GetBytes($Body)
$digest = Get-Sha256Hex $bodyBytes
$timestamp = [DateTime]::UtcNow.ToString('yyyy-MM-ddTHH:mm:ssZ')
$nonce = [Guid]::NewGuid().ToString('N')
$canonical = "$Method`n$Path`n$timestamp`n$nonce`n$digest"
$hmac = [Security.Cryptography.HMACSHA256]::new($deviceSecret)
try {
$signature = [Convert]::ToBase64String($hmac.ComputeHash([Text.Encoding]::UTF8.GetBytes($canonical))).TrimEnd('=').Replace('+', '-').Replace('/', '_')
}
finally { $hmac.Dispose() }
$headers = @{
'X-Device-Id' = $deviceId
'X-Device-Timestamp' = $timestamp
'X-Device-Nonce' = $nonce
'X-Device-Content-SHA256' = $digest
'X-Device-Signature' = $signature
}
foreach ($entry in $ExtraHeaders.GetEnumerator()) { $headers[$entry.Key] = $entry.Value }
return Invoke-WebRequest -UseBasicParsing -Method $Method -Uri ($api + $Path) -Headers $headers -ContentType 'application/json' -Body $Body
}
function Get-ApiMemoryBytes {
$containerId = (docker compose ps -q api | Out-String).Trim()
if (-not $containerId) { throw 'API container is not running' }
$usage = ((docker stats --no-stream --format '{{.MemUsage}}' $containerId | Out-String).Trim() -split '/')[0].Trim()
if ($usage -notmatch '^([0-9.]+)([KMG]iB)$') { throw "Cannot parse API container memory usage: $usage" }
$factor = switch ($Matches[2]) { 'KiB' { 1KB } 'MiB' { 1MB } 'GiB' { 1GB } }
return [long]([double]$Matches[1] * $factor)
}
function Invoke-Database([string]$Sql) {
$Sql | docker compose exec -T postgres psql -U voice -d voice_platform -v ON_ERROR_STOP=1 -q | Out-Null
}
$created = $false
try {
$fixtureSql = @"
BEGIN;
INSERT INTO consent_record(id,public_id,tenant_id,subject_id,consent_type,scope,policy_version,notice_digest,actor_user_id,evidence_ref,granted_at)
VALUES('$consentId'::uuid,gen_random_uuid(),'$tenantId'::uuid,'$subjectId'::uuid,'raw_audio_storage','{"scope":"synthetic_media_capacity"}'::jsonb,'local-v1',repeat('e',64),'$ownerId'::uuid,'local-synthetic://media-capacity',now());
INSERT INTO consent_snapshot(id,public_id,tenant_id,subject_id,snapshot_version,effective_consents,source_consent_ids)
VALUES('$snapshotId'::uuid,gen_random_uuid(),'$tenantId'::uuid,'$subjectId'::uuid,1000,'{"voice_chat":true,"transcript_storage":true,"raw_audio_storage":true}'::jsonb,jsonb_build_array('$consentId'));
INSERT INTO context_snapshot(id,public_id,tenant_id,subject_id,profile_version,consent_snapshot_id,memory_versions,prompt_bundle_version,engine_mode,content_digest,sanitized_summary)
VALUES('$contextId'::uuid,gen_random_uuid(),'$tenantId'::uuid,'$subjectId'::uuid,1,'$snapshotId'::uuid,'[]'::jsonb,'media-capacity-v1','s2s_hybrid',repeat('f',64),'synthetic media capacity');
INSERT INTO conversation(id,public_id,tenant_id,household_id,subject_id,device_id,consent_snapshot_id,context_snapshot_id,provider_task_ref,engine_mode,retention_mode,status,allocation_expires_at,started_at,ended_at)
VALUES('$conversationInternalId'::uuid,'$conversationId'::uuid,'$tenantId'::uuid,'$householdId'::uuid,'$subjectId'::uuid,'$deviceInternalId'::uuid,'$snapshotId'::uuid,'$contextId'::uuid,'media-capacity-$conversationId','s2s_hybrid','transcript_and_audio','COMPLETED',now()+interval '1 hour',now()-interval '2 minutes',now()-interval '1 minute');
INSERT INTO rtc_task(conversation_id,provider,provider_task_ref,room_id,device_rtc_user_id,agent_rtc_user_id,status,lease_expires_at,last_checked_at)
VALUES('$conversationInternalId'::uuid,'mock','media-capacity-task-$conversationId','media-capacity-room-$conversationId','device-media-capacity','agent-media-capacity','COMPLETED',now()-interval '1 minute',now());
COMMIT;
"@
Invoke-Database $fixtureSql
$created = $true
$memoryBefore = Get-ApiMemoryBytes
$memoryPeak = $memoryBefore
$batchDurations = [Collections.Generic.List[double]]::new()
$preparedTotal = 0
for ($batchIndex = 0; $batchIndex -lt $BatchCount; $batchIndex++) {
$segments = [Collections.Generic.List[object]]::new($SegmentsPerBatch)
for ($index = 0; $index -lt $SegmentsPerBatch; $index++) {
$global = ($batchIndex * $SegmentsPerBatch) + $index
$segments.Add([ordered]@{
track = if (($global % 2) -eq 0) { 'near' } else { 'far' }
sequence_no = [int][Math]::Floor($global / 2)
codec = 'wav_pcm_s16le'
content_type = 'audio/wav'
duration_ms = 20
expected_size = 1
expected_digest = $global.ToString('x64')
})
}
$body = @{ segments = $segments } | ConvertTo-Json -Compress -Depth 5
$headers = @{ 'Idempotency-Key' = "media-capacity-$conversationId-$batchIndex" }
$stopwatch = [Diagnostics.Stopwatch]::StartNew()
$response = Invoke-DeviceRequest 'POST' "/device/v2/conversations/$conversationId/upload-batches" $body $headers
$stopwatch.Stop()
$prepared = ($response.Content | ConvertFrom-Json).data
if ($prepared.status -ne 'UPLOADING' -or $prepared.segment_count -ne $SegmentsPerBatch -or $prepared.segments.Count -ne $SegmentsPerBatch) {
throw "Batch $batchIndex did not return all authorized segments"
}
$missingUrls = @($prepared.segments | Where-Object { -not $_.upload_url }).Count
if ($missingUrls -ne 0) { throw "Batch $batchIndex has $missingUrls missing upload URLs" }
$preparedTotal += $prepared.segments.Count
$batchDurations.Add($stopwatch.Elapsed.TotalSeconds)
$currentMemory = Get-ApiMemoryBytes
if ($currentMemory -gt $memoryPeak) { $memoryPeak = $currentMemory }
Write-Host ("Prepared batch {0}/{1}: segments={2}, elapsed_seconds={3:N2}, api_memory_mb={4:N1}" -f ($batchIndex + 1), $BatchCount, $prepared.segments.Count, $stopwatch.Elapsed.TotalSeconds, ($currentMemory / 1MB))
}
$databaseEvidence = (docker compose exec -T postgres psql -U voice -d voice_platform -t -A -F '|' -c "SELECT count(DISTINCT ub.id),count(DISTINCT ms.id),count(ubs.*) FROM upload_batch ub JOIN upload_batch_segment ubs ON ubs.upload_batch_id=ub.id JOIN media_segment ms ON ms.id=ubs.media_segment_id WHERE ub.conversation_id='$conversationInternalId'::uuid" | Out-String).Trim()
$expectedTotal = $BatchCount * $SegmentsPerBatch
if ($preparedTotal -ne $expectedTotal -or $databaseEvidence -ne "$BatchCount|$expectedTotal|$expectedTotal") {
throw "Media capacity evidence mismatch: response=$preparedTotal database=$databaseEvidence expected=$expectedTotal"
}
$memoryAfter = Get-ApiMemoryBytes
$average = ($batchDurations | Measure-Object -Average).Average
$maximum = ($batchDurations | Measure-Object -Maximum).Maximum
$orderedDurations = @($batchDurations | Sort-Object)
$p95 = $orderedDurations[[Math]::Max(0, [Math]::Ceiling($orderedDurations.Count * 0.95) - 1)]
if ($p95 -ge 1.0) { throw ("Media manifest p95 target failed: {0:N3}s >= 1.000s" -f $p95) }
Write-Host ("Media manifest capacity passed: batches={0}, segments={1}, database={2}, avg_batch_seconds={3:N2}, p95_batch_seconds={4:N2}, max_batch_seconds={5:N2}, api_memory_before_mb={6:N1}, peak_mb={7:N1}, after_mb={8:N1}" -f $BatchCount, $expectedTotal, $databaseEvidence, $average, $p95, $maximum, ($memoryBefore / 1MB), ($memoryPeak / 1MB), ($memoryAfter / 1MB))
}
finally {
if ($created) {
$cleanupSql = @"
BEGIN;
DELETE FROM web_event WHERE resource_public_id IN (SELECT public_id FROM upload_batch WHERE conversation_id='$conversationInternalId'::uuid) OR resource_public_id='$conversationId'::uuid;
DELETE FROM audit_event WHERE resource_id IN (SELECT public_id FROM upload_batch WHERE conversation_id='$conversationInternalId'::uuid UNION SELECT public_id FROM media_segment WHERE conversation_id='$conversationInternalId'::uuid);
DELETE FROM outbox_event WHERE aggregate_id IN (SELECT public_id FROM upload_batch WHERE conversation_id='$conversationInternalId'::uuid);
DELETE FROM upload_batch_segment WHERE upload_batch_id IN (SELECT id FROM upload_batch WHERE conversation_id='$conversationInternalId'::uuid);
DELETE FROM media_segment WHERE conversation_id='$conversationInternalId'::uuid;
DELETE FROM upload_batch WHERE conversation_id='$conversationInternalId'::uuid;
DELETE FROM rtc_task WHERE conversation_id='$conversationInternalId'::uuid;
DELETE FROM conversation WHERE id='$conversationInternalId'::uuid;
DELETE FROM context_snapshot WHERE id='$contextId'::uuid;
DELETE FROM consent_snapshot WHERE id='$snapshotId'::uuid;
DELETE FROM consent_record WHERE id='$consentId'::uuid;
COMMIT;
"@
Invoke-Database $cleanupSql
}
}