Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions devlog/_plan/260912_audio_apis_stack/000_plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Standalone audio APIs

Expose file transcription, streaming dictation and GPT-Live to external clients with OpenCodex credentials. Connections gains separate Dictation and Live Voice sections. Existing OpenAI account selection and transport lifecycle remain the integration points.

## Loop contract

Owner steering during wp1 C: no local Bun suites, product tests, typecheck, build or dependency installation. Push with --no-verify and use exact-head remote CI for remaining executable verification. This supersedes every local command example in the layer plans. Already completed checks are historical evidence only; interrupted/crashed checks are not passing evidence. All active task-owned local suites were stopped. Functional layer closure uses the completed source review and pre-restriction focused evidence; PR readiness and final completion retain the remote CI gate under wp3 publication.

- Archetype: satisfy-spec, C4 API/auth and C3 dashboard integration.
- Trigger: owner requested both audio capabilities, inherited subagent verification and a published dependent PR stack.
- Goal: three independently reviewable ordinary PRs with protocol tests, documentation and usable client controls.
- Non-goals: merge, release, deployment, account configuration, microphone capture during agent QA, paid upstream probes, Responses protocol conversion, native GitHub stack registration.
- Verification: focused Bun transport tests observe mock upstream requests and real loopback sockets; typecheck observes tsconfig source includes; GUI build/lint/i18n and browser smoke observe rendered controls. Final review readiness also requires repository test runner and exact-head remote CI.
- Stop: all three PRs published with final-head evidence and no unresolved actionable independent findings.
- Artifacts: this unit for functional design; ignored .tmp/audio-security for trust-boundary working notes; session-bound goalplan and test receipts for orchestration.
- Outcomes: DONE means all criteria met; external dependency failures remain unmet with evidence. No invented budget exhaustion or scope reduction.
- Escalation: main resolves technical review findings; no additional authority for destructive operations or external messages. Main reclaims a failed delegated packet after two distinct agents; implementation delegation requires an explicit plan amendment.
- Resources: existing shell/Git/GitHub and inherited model tools; task worktree only; no new paid services, billable voice calls or personal recordings. User set no token, cost or wall-clock cap and allowed unrestricted parallel subagents.

## Current ownership

Source root: task-owned linked worktree on origin/dev ec065aa0c6fb46b376a2f01873bd677327b99150. Native session state stays in the original checkout. Existing uncommitted user work stays there.

| Cycle | Plan | Branch / PR base | Output |
| --- | --- | --- | --- |
| wp0 | all documents in this unit | documentation checkpoint on first branch | audited complete roadmap |
| wp1 | 010_transcription.md | codex/audio-transcription -> dev | bounded file transcription and audio upstream contract |
| wp2 | 020_streaming_voice.md | codex/audio-streaming -> codex/audio-transcription | dictation stream and externally owned live sessions |
| wp3 | 030_connections.md | codex/audio-connections -> codex/audio-streaming | endpoint metadata, audio controls, examples and publication |

All layers include their own regression coverage and source-of-truth sync. The branch base is the dependency edge; no branch is merged in this task.

## Evidence and decisions

Local Codex reference: 095da4b7e8b70b01afb5c6131ef926dcb8c0d85d, realtime default gpt-live-1-codex. Installed desktop package 26.908.40834 has separate file and dictation-stream transports. File API interoperability reference: Soju06/codex-lb 82567556f9f75ea13986667fc5282f035b7ca8d2, app/modules/proxy/api.py and app/core/clients/proxy.py. Its gpt-4o-transcribe subscription model is a compatibility identifier, not proof of the backend model.

No native architect field is exposed by the host spawn schema. Main owns the plan; an inherited generic read-only design verifier supplies the consultation evidence. This is recorded as a transport deviation, not native architect completion. Independent A/code reviewers inherit the requested model/context; model-family independence is not claimed.

Configuration alone cannot create the missing audio endpoints. Reuse the existing sidecar selection, admission, response envelope, stream limits and API workspace instead of a separate service or provider registry.

## Progress

wp0: roadmap locked after independent PASS and resolved design reflection. Documentation checkpoint 5e4ade8432; staged whitespace check passed. Production code unchanged. Next cycle executes 010_transcription.md; protocol and auth decisions remain the dependency foundation.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Roadmap review disposition

Inherited design verification accepted the narrow sidecar reuse, bounded transport and call-lifetime decisions. Reflection found an ambiguous Location contract; 020 now requires a proxy-relative join path for external callers and independently trusted upstream destinations. Follow-up reflection: ALIGNED.

Independent A round 1 returned FAIL on three concrete contract omissions. All accepted: 010 now specifies explicit-key resolution before loopback shortcut and stored-main Direct materialization under a lease; 020 specifies tagged key/native ownership on both listeners; HTTP-only AUTH_MATRIX gets protocol-correct multipart fixtures in api-key-attribution.test.ts, while WebSocket auth is separately advertised and tested with upgrades.

Baseline command: bun test tests/server/server-live.test.ts tests/server/api-access-endpoints.test.ts. Result: 46 pass, 0 fail, 351 assertions at ec065aa0c6fb46b376a2f01873bd677327b99150 before production changes. This is baseline evidence, not feature verification.
52 changes: 52 additions & 0 deletions devlog/_plan/260912_audio_apis_stack/010_transcription.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# File transcription

Depends on wp0. This layer owns the unary audio transport and the shared upstream boundary used by wp2.

## File changes

| Operation | Path | Contract change |
| --- | --- | --- |
| NEW | src/server/audio-upstream.ts | audio model constants, proxy-owned upstream resolution reusing existing OpenAI sidecar auth; no provider registry mutation |
| NEW | src/server/audio-transcriptions.ts | parse bounded multipart, select transcription model, relay to subscription or keyed upstream, map response/errors and cancel |
| MODIFY | src/server/live.ts | retain public live exports; share only reusable upstream resolution as needed, preserving native call-create behavior |
| MODIFY | src/server/index.ts | register exact POST /v1/audio/transcriptions before unknown-v1 guard; perform admission/origin/drain checks before body consumption; record request outcome |
| MODIFY | src/server/auth-cors.ts | append matching transcription row to AUTH_MATRIX; preserve existing header precedence |
| MODIFY | tests/server/api-key-attribution.test.ts | send valid multipart for transcription matrix rows, retaining per-header denial and attribution assertions |
| NEW | tests/server/audio-transcriptions.test.ts | isolated home and synthetic file fixtures, mock canonical upstream fetch, actual ingress requests |
| MODIFY | scripts/test-layout/layout.json | register the new server-domain test |
| MODIFY | tests/fixtures/test-layout-expected.json | add matching expected test path |
| MODIFY | structure/data-planes/inbound-compat.md | describe the audio data-plane contract and owned source/test paths |
| MODIFY | docs-site/src/content/docs/reference/proxy-formats.md | document multipart audio usage and supported response fields |

## Before / after contracts

Before: unknown POST /v1/audio/transcriptions falls through to JSON 404. After: authentication and origin rejection run first; an admitted request reaches handleAudioTranscriptions(req, config, logCtx, lease).

New handler accepts exactly one nonempty file, required model, optional prompt/language/response_format. gpt-4o-transcribe is the subscription compatibility model. Only explicitly supported JSON/text output is accepted; unsupported streaming/timestamp/temperature extensions fail clearly rather than being silently claimed. File limit 25,000,000 bytes; whole multipart limit 32 MiB; text field limits and duplicate checks bound parsing. No file is written to disk. The entire body is capped while reading before Web-platform multipart parsing; multipart overhead therefore remains bounded.

Subscription destination is canonical https://chatgpt.com/backend-api/transcribe (remove only the known /codex suffix). Rebuild FormData so the boundary matches; send file and supported context fields, omit compatibility model and response_format. Keyed OpenAI destination is /v1/audio/transcriptions and receives the validated model/options. Use registered OpenAI account helpers; never forward the client OpenCodex secret. Existing native explicit credential flow remains available only under its existing admission contract. No generic caller-controlled destination.

The resolver takes the already-resolved DataPlaneAdmission and uses resolveFirstUsableOpenAiSidecar directly, rather than invoking the complete Live handler. Retain account context/provider identity/outcome callback for wp2. For a proxy-owned Authorization value, remove only that admission credential before constructing upstream headers and use admitted stored-account resolution. Direct-mode behavior is explicitly tested; no automatic paid-provider fallback after a selected ChatGPT account error. Missing stored Direct credentials report unavailable rather than silently reclassifying an API key as a native token.

New audio ingress resolves explicitly supplied credentials with resolveDataPlaneAdmissionSecret even on loopback; precedence is dedicated header, Bearer, x-api-key. Invalid explicit credentials cannot fall through to loopback admission. File transcription and dictation streaming require a valid proxy key on either listener. This rule is audio-owned and does not modify global resolveApiAuth behavior.

For Direct with a valid proxy key, call resolveCodexAuthContext with mode=direct, substituteMainCredentialForDirect=true and beginCodexAccountSelection=codexAccountSelectionForTurn(lease); then materializeCodexUpstreamAuth with substituteMainCredential=true. This path claims stored-main ownership before reading it. A missing lease, draining main, missing/expired stored credential fails before I/O. Test successful stored-main substitution with isolated fake home, missing credentials and draining state. Native explicit caller auth keeps the existing sidecar path.

Response is bounded before JSON parsing. JSON requires a string text field. text format returns text/plain. Forward sanitized machine-readable upstream status/errors, not arbitrary exception bodies. Client abort, upstream timeout and redirect rejection follow existing relay conventions; outcome callback and admission/sidecar cleanup must settle once.

New transport types are internal: creation in audio-transcriptions, in-memory consumers only, no persistence or reviver. Public multipart is parsed once at ingress. AUTH_MATRIX is serialized by existing management response and validated by GUI isApiAuthMatrix; its consumer remains ApiKeysEndpointsPanel.

## Acceptance and checks

1. POST synthetic WAV with a configured proxy Bearer key: upstream receives the selected stored account/API credential and correct multipart bytes; client gets text.
2. Missing/wrong key and hostile Origin: 401/403 before upload read or upstream call. Main and optional companion listener policies are tested separately.
3. Missing/duplicate file/model, unsupported model or format, malformed multipart: explicit 400; no upstream call.
4. Declared and streamed body oversize, file oversize, text oversize: 413 at configured boundary; body cancellation observed.
5. JSON and text response modes, upstream malformed JSON and excessive response, redirect, timeout and abort: exact response and cleanup assertions.
6. Existing live and auth matrix tests retain their behavior.

Commands: bun test tests/server/audio-transcriptions.test.ts tests/server/server-live.test.ts tests/server/api-keys-routes.test.ts; bun run typecheck; bun run structure:check; bun run privacy:scan. Before new test exists, its execution is NOT RUN; existing commands are declared in package.json and focused file arguments directly observe this layer. Full repository suite runs before review-ready publication, not as a documentation check.

Security control activation cases and residual assumptions are recorded in ignored scratch, reviewed independently, and never copied into the public planning record.

Implementation review amendment: readBodyCapped gains an optional AbortSignal to cancel its locked reader; the transcription operation registers a controller with its turn lease and has an overall deadline plus upload deadline. src/providers/openai-sidecar.ts releases probe ownership if header materialization or post-resolution validation fails before returning a context. Explicit validated native Direct caller auth uses the existing sidecar path; stored-main substitution applies only to proxy-key-only Direct. These narrow changes are prerequisites for safe reuse and preserve existing callers by default.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Transcription implementation checks

File transcription is implemented with explicit client-key admission, canonical OpenAI upstreams, bounded multipart and response handling, leased Direct substitution, explicit native Direct passthrough, and cancellation linked from upload through shutdown. Responses/chat routing is unchanged.

Fresh targeted evidence: 24 audio regression tests pass; 17 test-layout tests pass; typecheck and structure checks pass. Import-connected check: bun run test:changed selected 326 of 1202 files and completed 8138 pass, 2 skip, 0 fail. The final two probe-release regressions were added afterwards and passed in the focused audio run. No paid upstream call or personal recording was used.

Independent review found upload lifetime, shutdown cancellation, explicit Direct handling, probe cleanup and final-outcome defects; these were fixed and rechecked. The final bounded Noether review returned VERDICT: PASS. Additional probe-release tests cover both pre-return helper failure paths.

The original ec065aa0c6 layout JSON incorrectly seeded cline-client.test.ts and cline-writer.test.ts as providers despite explicit clients ownership. This was reproduced using the original JSON and unchanged resolver. The two seed families now agree; no assertion or coverage was removed.

Synthetic curl QA completed against the built handler with a mocked canonical upstream: success 200, invalid key 401, unsupported model 400; teardown confirmed no listener. Documentation build completed 425 pages. A later expanded curl case correctly returned 413 after HTTP 100 Continue; the QA script misclassified that interim status, so the expanded run is not a passing receipt.

The default full suite crashed inside Bun 1.4.2 with SIGSEGV on a separate immutable verification checkout. Its failed-file count includes aborted work and is not an assertion-failure count; baseline causation remains unproven. The serial diagnostic was interrupted by the owner's explicit no-local-suite instruction and is NOT PASS. All future product checks move to exact-head remote CI; first PR 4391 stays draft pending that gate. Local product tests/typecheck/build/install are NOT RUN after this steering, and pushes use --no-verify.

wp1 functional implementation is complete based on the pre-restriction focused/affected checks and independent source review; remote review-readiness remains tracked by the publication criterion. Next cycle consumes 020_streaming_voice.md and the completed audio upstream boundary. Real OpenAI/ChatGPT account entitlement and server behavior remain outside synthetic verification and are not claimed.
Loading
Loading