Skip to content

fix: align Clip + Voice contracts with the live gateway - #48

Merged
yakimoto merged 5 commits into
mainfrom
fix/live-gateway-contract
Sep 6, 2026
Merged

fix: align Clip + Voice contracts with the live gateway#48
yakimoto merged 5 commits into
mainfrom
fix/live-gateway-contract

Conversation

@yakimoto

@yakimoto yakimoto commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

User description

The api-spec was out of sync with the live gateway (verified today by probing api.wave.online):

  • ClipCreate previously required the rejected numeric videoId/startTime/endTime shape. The gateway accepts { source: "<recording-id>", in: "5s", out: "10s" }.
  • The voice path is POST /voice (not /voice/generate), requiring only text (voiceId optional, also sent as voice_id). The primary 200 returns raw audio/mpeg bytes.

CHANGELOG updated.


View with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is enabled.


Open in Devin Review

Review in cubic

Note

Align Clip and Voice API contracts with live gateway

  • Renames the Voice synthesis path from POST /voice/generate to POST /voice; the 200 response now returns raw audio/mpeg bytes by default, with JSON only when opting into timestamps or async engines.
  • ClipCreate now requires source, in, and out (relative time strings e.g. 5s, 2m30s) instead of videoId, startTime, and endTime (numeric).
  • VoiceGenerateRequest now only requires text; voiceId and voice_id are optional snake/camel aliases but mutually exclusive — providing both is invalid.
  • Risk: all three changes are breaking; clients using /voice/generate, numeric clip times, or passing voiceId as required must update.

Macroscope summarized 16af177.


Note

Medium Risk
OpenAPI schema changes (required fields and new mutual-exclusion rule) can affect generated clients and strict validators; response docs reorder wire semantics but clarify default audio/mpeg.

Overview
This PR narrows an earlier Clip/path-rename proposal: POST /voice/generate stays, and ClipCreate is unchanged (CHANGELOG explains why). The work aligns POST /voice/generate with live gateway behavior.

The 200 response is documented so raw audio/mpeg is the default; application/json (VoiceSynthesisInline / VoiceGeneration) applies only when the request opts into timestamps or async paths. The OpenAPI content map lists audio/mpeg first and the description is rewritten accordingly; generated/api-types.d.ts mirrors that.

VoiceGenerateRequest now requires only text. voiceId is optional (default voice when omitted), and voice_id is documented as the SDK wire alias, with a schema not rule rejecting both camel and snake on one body.

Published drift adds a shared-drift allowlist entry for the richer repo 200 description vs the published spec, and contract-drift.json is regenerated (allowlisted count 9 → 10).

Reviewed by Cursor Bugbot for commit aaeb252. Bugbot is set up for automated code reviews on this repo. Configure here.

Summary by Sourcery

Align the voice synthesis API specification with the live gateway while retaining the existing endpoint and clip contract.

Bug Fixes:

  • Align the voice synthesis response and request schemas with the live gateway by documenting default raw MP3 responses and making voice selection optional.

Enhancements:

  • Clarify voice request aliases and reject simultaneous camelCase and snake_case voice identifiers.

Documentation:

  • Document the updated voice contract and its live-gateway behavior in the changelog.

Chores:

  • Update generated API types and contract-drift metadata for the revised voice schema.

CodeAnt-AI Description

Align voice generation contracts with the live gateway

What Changed

  • Voice generation now documents raw MP3 bytes as the default successful response, with JSON results reserved for timestamped or asynchronous requests
  • Text is the only required voice-generation input; the gateway can choose a default voice when no voice is provided
  • Voice selection accepts either voiceId or voice_id, while rejecting requests that provide both
  • Updated generated API types, changelog, and drift tracking to reflect the live behavior

Impact

✅ Direct MP3 responses by default
✅ Voice generation without specifying a voice
✅ Clearer validation for conflicting voice IDs

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

Verified by probing api.wave.online: ClipCreate previously required the
rejected numeric videoId/startTime/endTime shape; the gateway accepts
{ source: "<recording-id>", in: "5s", out: "10s" }. The voice path is
POST /voice (not /voice/generate), requiring only text, and the primary
200 returns raw audio/mpeg bytes.

- ClipCreate: source (recording id string) + in/out relative time strings.
- /voice/generate -> /voice; VoiceGenerateRequest.text required, voiceId
  optional (also sent as voice_id).
@cursor

cursor Bot commented Aug 11, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_4433be5b-ea99-4ac6-9085-eb4bb1bdfe31)

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 39 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available. Your 91 included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Team

Run ID: c5da2215-f7f2-4154-b36e-cb70bde10b92

📥 Commits

Reviewing files that changed from the base of the PR and between 756588b and aaeb252.

⛔ Files ignored due to path filters (1)
  • generated/api-types.d.ts is excluded by !**/generated/**
📒 Files selected for processing (4)
  • .github/scripts/published-drift-allowlist.json
  • CHANGELOG.md
  • contract-drift.json
  • openapi.yaml

Comment @coderabbitai help to get the list of available commands.

@macroscopeapp

macroscopeapp Bot commented Aug 11, 2026

Copy link
Copy Markdown

Approvability

Verdict: Would Approve

Macroscope's review found this PR approvable — This is a focused, author-owned OpenAPI contract correction for the existing Voice endpoint, with synchronized generated types and drift metadata and no production runtime or infrastructure changes. The remaining comments concern unchanged or stale areas and do not establish a concrete blocker for this diff.

Not approved because:

  • Credit balance exhausted. Approvability relies on correctness review in order to determine eligibility

Review your spending limits in Billing settings. You can add or adjust custom eligibility rules. Learn more.

macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Aug 11, 2026
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Fix OpenAPI ClipCreate + Voice endpoints to match live gateway

🐞 Bug fix 📝 Documentation 🕐 10-20 Minutes

Grey Divider

AI Description

• Update ClipCreate request schema to source + in/out time strings accepted by the live
 gateway.
• Correct Voice generation endpoint to POST /voice and document primary audio/mpeg byte
 response.
• Record the contract alignment in the Unreleased changelog for downstream SDK/spec consumers.
Diagram

graph TD
  A["SDK / API Client"] --> B["OpenAPI spec"] --> C["Live Gateway"]
  B --> D["ClipCreate schema"] --> G["source + in/out"]
  B --> E["POST /voice"] --> F["200 audio/mpeg"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Add gateway contract checks in CI
  • ➕ Detects spec drift automatically before release
  • ➕ Prevents future mismatches like endpoint paths and required fields
  • ➖ Requires stable test credentials / environment access
  • ➖ Can introduce flaky CI if the live gateway is unstable
2. Generate OpenAPI from the gateway source of truth
  • ➕ Eliminates manual spec maintenance for these endpoints
  • ➕ Reduces risk of breaking SDKs due to spec drift
  • ➖ May be non-trivial if gateway isn’t instrumented for spec generation
  • ➖ Can constrain gateway implementation choices to tooling limitations
3. Versioned endpoint aliases (/voice and /voice/generate)
  • ➕ Backwards compatibility for existing clients pinned to old paths
  • ➕ Allows gradual migration with deprecation notices
  • ➖ Adds maintenance burden and ambiguity about the canonical path
  • ➖ Doesn’t address request/response schema drift by itself

Recommendation: The PR’s approach (manually correcting the OpenAPI contract to match verified live behavior) is the right immediate fix because it unblocks SDK/spec consumers quickly. Follow up with CI-level contract probing (or spec generation if feasible) to prevent recurring drift, since these changes indicate the spec is not currently the source of truth.

Files changed (2) +28 / -14

Bug fix (1) +19 / -14
openapi.yamlFix ClipCreate schema and Voice endpoint/response to match gateway +19/-14

Fix ClipCreate schema and Voice endpoint/response to match gateway

• Updates Voice generation path from '/voice/generate' to '/voice' and clarifies that the primary 200 response returns raw 'audio/mpeg' bytes. Adjusts 'ClipCreate' to require 'source', 'in', and 'out' (string offsets) and makes 'VoiceGenerateRequest.text' the only required field with optional 'voiceId'.

openapi.yaml

Documentation (1) +9 / -0
CHANGELOG.mdDocument live-gateway contract alignment for Clip and Voice +9/-0

Document live-gateway contract alignment for Clip and Voice

• Adds an Unreleased 'Changed' entry describing the ClipCreate schema update and Voice endpoint correction. Notes the live verification and the primary 'audio/mpeg' response behavior for Voice.

CHANGELOG.md

@cubic-dev-ai

cubic-dev-ai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Running ultrareview automatically — This PR makes significant changes to the Clip and Voice API contracts—replacing required fields, altering endpoint paths, and updating response types—which risk breaking client integrations if any detail is misaligned with the live gateway.. I'll post findings when complete.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 3 potential issues.

Open in Devin Review

Comment thread openapi.yaml Outdated
Comment thread openapi.yaml Outdated
Comment thread openapi.yaml Outdated
@cubic-dev-ai

cubic-dev-ai Bot commented Aug 11, 2026

Copy link
Copy Markdown

I can't run this ultrareview because your workspace has reached its monthly review limit. cubic has reviewed 100,145 of the 100,000 allowed lines of code this month. Reviews resume on 4 September 2026 (in 25 days). Enable flex capacity to cover overages automatically and resume reviews now. Learn how flex capacity works.

To help optimise your usage, you can tune cubic to get the most out of your usage limits:

Learn more →

Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
@qodo-code-review

qodo-code-review Bot commented Aug 11, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (1) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. voice_id not in schema ✓ Resolved 🐞 Bug ⚙ Maintainability
Description
VoiceGenerateRequest’s prose claims the SDK also sends voiceId as voice_id, but the schema only
defines voiceId and does not define a voice_id property. This is an internal contract
inconsistency that can mislead consumers and break schema-driven validation for callers that follow
the documented alias.
Code

openapi.yaml[R2408-2411]

+          description: Text to convert to speech.
+        voiceId:
+          type: string
+          description: Voice id to use. Optional — the gateway picks a default when omitted. The SDK also sends this as `voice_id`.
Evidence
The schema defines voiceId but its description states it is also sent as voice_id, creating a
mismatch between declared properties and documented request shape.

openapi.yaml[2402-2411]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`VoiceGenerateRequest.voiceId` is documented as “also sent as `voice_id` by the SDK”, but `voice_id` is not represented in the schema. This makes the OpenAPI contract internally inconsistent and may mislead integrators who implement requests based on the spec text.

### Issue Context
If `voice_id` is a wire-level alias accepted by the gateway, it should be explicitly modeled (or otherwise formally documented). If it’s purely an internal SDK serialization detail, the OpenAPI schema should not claim it as a request-field alias.

### Fix Focus Areas
- Decide which is true and update the spec accordingly:
 - **Wire accepts both**: add a `voice_id` property (potentially marked `deprecated: true`), and explain precedence between `voiceId` and `voice_id` if both are provided.
 - **SDK-only serialization**: remove the `voice_id` claim from the schema description and document serialization behavior elsewhere (e.g., SDK docs), keeping the OpenAPI contract strictly about wire fields.

### Fix Focus Areas (code references)
- openapi.yaml[2402-2411]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Voice 200 negotiation unclear ✓ Resolved 🐞 Bug ≡ Correctness
Description
The /voice 200 response description now claims the primary path returns raw audio/mpeg bytes, but
the spec still advertises application/json alongside it without clearly specifying when each media
type is returned or how clients should request JSON vs MP3. This creates an ambiguous contract for
SDKs and callers about response handling/content negotiation.
Code

openapi.yaml[R407-410]

+            Speech generated. Verified against the live gateway: the primary path returns the raw
+            audio bytes (`audio/mpeg`) in the response body — POST `/v1/voice` with `{ text }`
+            returns the MP3 directly. Engines that request timestamps may instead return an inline
+            JSON payload with base64 audio + character `alignment`, or an async job to poll.
Evidence
The updated /voice 200 description says the primary response is raw MP3 bytes, but the response
still declares both application/json and audio/mpeg without specifying the selection condition.
Elsewhere in the same spec, /render documents the exact Accept-driven behavior for its
binary-vs-JSON 200 response, highlighting the lack of equivalent specificity for /voice.

openapi.yaml[393-420]
openapi.yaml[111-142]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`POST /voice` now documents that the primary 200 returns raw `audio/mpeg`, but the OpenAPI response still lists both `application/json` and `audio/mpeg` without defining the selection rule (e.g., `timestamps: true` vs `Accept: application/json`). This leaves clients uncertain about what they’ll receive and how to request the JSON shapes.

### Issue Context
There is already a precedent in this spec for “binary by default, JSON when Accept is application/json” (`/render`), which makes the current `/voice` wording/content less precise by comparison.

### Fix Focus Areas
- Define an explicit rule in the `/voice` 200 response docs, e.g.:
 - `timestamps: true` → `application/json` (inline alignment/job)
 - otherwise → `audio/mpeg` (binary MP3)
 - or explicitly tie JSON to `Accept: application/json` (and mention default behavior)
- Consider aligning the presentation with `/render` (documenting the Accept header behavior) and, if helpful for consumers/tools, order the default/binary media type first.

### Fix Focus Areas (code references)
- openapi.yaml[393-420]
- openapi.yaml[111-142]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. openapi.yaml exceeds 500 lines 📘 Rule violation ⚙ Maintainability
Description
openapi.yaml is a touched file and is well over the 500-line limit (it contains content past line
2400). This makes the spec harder to maintain and violates the maximum file-length requirement.
Code

openapi.yaml[R2404-2407]

+      required: [text]
      properties:
-        voiceId:
-          type: string
        text:
          type: string
Evidence
Compliance ID 2497975 requires each touched source file to be <=500 lines of code. The modified
openapi.yaml includes schema definitions at/after line 2402 in the PR branch, proving the file
length is far beyond 500 lines.

Rule 2497975: Limit source file length to 500 lines of code
openapi.yaml[2402-2411]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The PR modifies `openapi.yaml`, which is far larger than the 500-line maximum required by the compliance checklist.

## Issue Context
The file contains content beyond line 2400, indicating it significantly exceeds the 500-line cap.

## Fix Focus Areas
- openapi.yaml[393-410]
- openapi.yaml[2241-2251]
- openapi.yaml[2404-2411]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context
✅ Compliance rules (platform): 1 rule
✅ REVIEW.md
Review mode: ⚖️ Balanced: This changes public OpenAPI contracts and endpoint/response semantics across Clip and Voice paths; it carries real compatibility risk but is not dense enough in independent logic to warrant extended review.

Grey Divider

Tip of the day
💡 Did you know, you can group findings by type and pick your Finding display, from Minimal to Full

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread openapi.yaml
Comment thread openapi.yaml Outdated
Comment thread openapi.yaml Outdated
@qodo-code-review

Copy link
Copy Markdown

Qodo Fixer

No findings are within the configured fix scope. To change which findings are fixed, adjust the setting on your Qodo configuration page.

Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
devin-ai-integration[bot]

This comment was marked as resolved.

Co-authored-by: Codesmith <codesmith-bot@users.noreply.github.com>
@wave-bugbot

wave-bugbot Bot commented Aug 12, 2026

Copy link
Copy Markdown

🟢 WAVE BugBot — clear

No confident findings on the changed lines.

Local review · $0 inference · wave-dispatch

@yakimoto

yakimoto commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

Premise verification against the live gateway — the path rename looks backwards

Reviewing this for GA criterion CONTRACT-001 / COMPAT-001. CI is fully green (15/15) and the branch is
MERGEABLE, so this is not a build problem — it is a correctness problem with the premise. Posting the
receipts rather than editing the branch, since reversing an author's intent isn't a reviewer's call.

1. POST /voice is not a mapped route; POST /voice/generate is

Unauthenticated probes against api.wave.online separate mapped POST routes (401, auth wall reached)
from unmapped ones (405, no handler). Control pairs establish the discriminator:

Probe Result Meaning
POST /voice/generate 401 mapped
POST /clips 401 mapped
POST /voice/clone 401 mapped
POST /clips/detect 500 UPSTREAM_ERROR mapped, reached upstream
POST /voice/voices 405 mapped GET-only — correctly rejects POST
POST /voice 405 not mapped
POST /voice/zzz1 (control) 405 not mapped
POST /clips/zzz2 (control) 405 not mapped
POST /voice/generate2 (control) 405 not mapped
POST /clips/detectx (control) 405 not mapped

11/11 probes reproduce the live spec's method map exactly, including correctly 405-ing the GET-only
/voice/voices. POST /voice groups with the fabricated controls, not with the real routes.

Note the documented server base https://api.wave.online/v1 cannot be probed this way — every /v1/* path,
including fabricated ones, returns a uniform x402 402 payment required that echoes back whatever path you
send. So the 402s carry no route-existence signal; the discriminating surface is the un-prefixed mount, which
returns genuine WAVE error envelopes (UPSTREAM_ERROR, with suggestions) and is therefore a real gateway
surface, not the marketing app.

2. The published live spec contradicts all three changes

curl https://api.wave.online/openapi.json → HTTP 200, 1.0.0, 54 paths / 75 operations:

  • path is /voice/generate, not /voice
  • ClipCreate.required = [videoId, startTime, endTime] (numeric), not [source, in, out]
  • VoiceGenerateRequest.required = [voiceId, text], not [text]

Independently corroborated: sdk-python pins tests/fixtures/openapi_snapshot.json captured 2026-09-01
from that same URL — info_version 1.0.0, total_ops 75, and {"operationId":"generateSpeech","method":"POST","path":"/voice/generate"}.

3. origin/main already agrees with live on these three items

origin/main (now 1.1.0, 209 paths / 230 operations) still carries /voice/generate,
ClipCreate.required=[videoId,startTime,endTime], and VoiceGenerateRequest.required=[voiceId,text]
byte-identical in meaning to what the gateway serves. There is no drift here to remove. As written this PR
would introduce drift on exactly the three items it aims to fix, which is the failure CONTRACT-001 is meant to
catch: an unverified claim laundered into the contract.

4. The branch is also badly stale

Branch spec measures 1.0.0, 43 paths / 62 operations against main's 1.1.0 / 209 / 230. Merge base is
6649096. Git reports no textual conflict, so the rename would apply cleanly onto a file that has since moved
a long way — worth a rebase before any merge regardless of the outcome above.

What would change my read

The PR body says the shapes were "verified today by probing api.wave.online" but carries no attached output.
An authenticated transcript — request line, status, and response body for POST /v1/voice with {text},
plus a POST /v1/clips with {source, in, out} — would settle it, since body validation never runs on my
unauthenticated probes. If the gateway really does accept those shapes behind auth, then the published
openapi.json is the stale artifact
and the right fix is to regenerate/repoint it, with this PR rebased on
current main. Happy to re-verify the moment that transcript exists.

Separate finding, not this PR's file

Both SDKs POST to /v1/voice/synthesize (sdk/src/voice.ts:155, sdk-python/wave_sdk/voice.py:29), and
POST /voice/synthesize probes 405 — unmapped, same as the controls. That is a third path, matching
neither the spec nor this PR, and looks like a real COMPAT-001 defect in the SDK repos. Flagging for whoever
owns those; out of scope here.

🤖 Generated with Claude Code

…ice rename + ClipCreate

ClipCreate: main independently re-verified this schema against the live
gateway since this PR branched, with a more thorough contract (source +
in, out/duration alternatives, sourceType, visibility). Keeping mains
version; this PRs source/in/out variant is superseded.

Voice path rename (/voice/generate -> /voice): dropped. Verified live
that the gateways x402 paywall gates on the top-level product path
segment for ANY sub-path under /voice/ (including nonexistent ones,
e.g. /v1/voice/nonexistent-xyz -> 402), so an unauthenticated probe
cannot distinguish /voice from /voice/generate. main already documents
/voice/generate; the rename claim is unverifiable, so the path stays.

Kept: VoiceGenerateRequest now requires only text (voiceId optional,
also accepted as the voice_id wire alias; supplying both is rejected
at the schema level), and the /voice/generate 200 response description
clarified that audio/mpeg is the default (JSON shapes are opt-in) --
verified live via POST /voice/generate. Added a published-drift
shared-drift allowlist entry for this response-description change,
keyed on the published documents current (unchanged) description.

Regenerated contract-drift.json and generated/api-types.d.ts.
@codeant-ai

codeant-ai Bot commented Sep 6, 2026

Copy link
Copy Markdown

🤖 CodeAnt AI — Review Status

Status Commit Started (UTC) Finished (UTC)
✅ Reviewed your PR aaeb252 Sep 06, 2026 · 03:42 03:44

@codeant-ai

codeant-ai Bot commented Sep 6, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@cursor

cursor Bot commented Sep 6, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_167ef0b9-ae0a-4a7c-9deb-9773b8947fb1)

@codeant-ai codeant-ai Bot added the size:M This PR changes 30-99 lines, ignoring generated files label Sep 6, 2026
Comment thread .github/scripts/published-drift-allowlist.json
@qodo-code-review

Copy link
Copy Markdown

ⓘ Qodo reviews are paused because your workspace is out of credits. Ask your workspace admin to add credits to resume reviews. Manage billing

@yakimoto
yakimoto merged commit 4ea990d into main Sep 6, 2026
28 of 29 checks passed
@yakimoto
yakimoto deleted the fix/live-gateway-contract branch September 6, 2026 05:05
yakimoto added a commit that referenced this pull request Sep 6, 2026
…ce contract alignment

Resolves conflicts from #40 (README), #43 (CI/body-guard), and #48 (Clip/Voice
contract alignment) landing ahead of this PR.

- CHANGELOG.md: kept both this PR entry (Enhance AI video super-resolution
  surface) and mains body content-policy gate entry.
- contract-drift.json: took mains version then regenerated via
  published-drift.mjs against the merged openapi.yaml (exit OK, no drift).
- generated/api-types.d.ts: regenerated via npm run gen:types against the
  merged openapi.yaml.
- openapi.yaml and README.md merged cleanly with no manual edits needed.

Live-verified POST /v1/enhance still returns 402 (x402 challenge, priced
wave_enhance_minutes meter) against https://api.wave.online/v1/enhance,
confirming the route is live and staying published (not draft).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M This PR changes 30-99 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant