Repository navigation
Conversation
04d66d1 to
b8d922a
Compare
ee0bdba to
eb217d3
Compare
bc4afe5 to
7b3fd89
Compare
b5d4634 to
61e1bcc
Compare
5187d45 to
1d7604f
Compare
d4953ec to
1e2ab55
Compare
AI review: 4 P0-P2 finding(s)Syncs the OpenAPI contract and generated Go client. The change leaves an autofix manifest incompatibility, incorrect environment-name validation, and outdated public docs; authorization and pricing changes need human judgment. 🟡 P2
🟣 Pre-existing
Not checked: The AI review read the diff, the code, and the PR's text; it ran no tests or builds and read nothing outside this repository.
Push a fix, or have a collaborator with write access (including the PR author) add the Human review: needed
Decide the points above: approve to accept them, or request changes. Suggested reviewer: |
tkkhq
left a comment
There was a problem hiding this comment.
Live compatibility with the target Hosting deployment is unverified. Verify server support before exposing the new generated operations in CLI commands.
There was a problem hiding this comment.
Copilot wasn't able to review any files in this pull request. Check if the Files changed in this pull request are included in default exclusions.
| Auth *ProjectConfigAuth `json:"auth,omitempty"` | ||
|
|
||
| // Autofix AI diagnosis and fix settings. Omitted fields keep their current value. Your API key is never part of the manifest, and an apply never sets or deletes it: set it with `PUT /projects/{id}/autofix` before turning on a provider that runs on your own key. | ||
| Autofix *ProjectConfigAutofix `json:"autofix,omitempty"` |
There was a problem hiding this comment.
🟡 P2: Add autofix support to the CLI manifest parser
The generated configuration now supports autofix, but internal/projectconfig/manifest.go uses a separate Manifest without that field and decodes with KnownFields(true). Consequently, volcano cloud config deploy rejects valid manifests such as autofix: {enabled: false} before contacting the server, including pulled exports containing this section. Extend the local manifest type and update its documentation.
Found by gpt-6.1-sol
| @@ -15528,7 +16427,7 @@ components: | |||
| type: integer | |||
| minimum: 0 | |||
| maximum: 2147483647 | |||
| description: Inherits the template TTL when omitted (cloud default 3600 seconds; local default 0, unlimited). Cloud accepts 30–28800 seconds; local accepts 0 for unlimited or a positive lifetime. | |||
| description: Inherits the template TTL when omitted (cloud default 3600 seconds; local default 0, unlimited). Cloud HOBBY accepts 30–3600 seconds; SUPERAGENT accepts 30–28800 seconds. Inherited template defaults are clamped to the plan limit; explicit values above it are rejected. Local accepts 0 for unlimited or a positive lifetime. | |||
There was a problem hiding this comment.
🟡 P2: Update published Sandbox limits and CLI help
The revised contract limits HOBBY sessions to 1024 MiB and 3600 seconds, but docs/sandboxes.md and the flag help in internal/cmd/sandboxes/exec.go still advertise 2048 MiB and 28800 seconds without plan qualifications. HOBBY users following that guidance receive plan-limit errors. Update the matching docs and help, including inherited lifetime clamping, as required by AGENTS.md.
Found by gpt-6.1-sol
| publish. Its value is the same on every request. The record must be | ||
| served at that name itself; a record reached through a CNAME does not | ||
| count. | ||
| publish. Its value stays the same until Volcano rotates the key it is |
There was a problem hiding this comment.
🟡 P2: Correct the published domain-verification permanence guarantee
The contract now says verification TXT values change when Volcano rotates its derivation key and old values stop counting, while docs/domains.md:56 still promises that the value “never changes.” After rotation, users relying on that promise can retain a record that no longer satisfies verification. Update the guide to explain obtaining and publishing the replacement value.
Found by gpt-6.1-sol
Summary
API change report
Public API
New Endpoints: 22
GET /durable-functions/{functionId}/executions/{executionId}/messages
POST /durable-functions/{functionId}/executions/{executionId}/messages
POST /durable-messages/publish
POST /durable-messages/sessions
POST /durable-messages/waits
GET /projects/{id}/autofix
PUT /projects/{id}/autofix
GET /projects/{id}/autofix-runs
GET /projects/{id}/autofix-runs/{runId}
DELETE /projects/{id}/autofix/api-key
GET /projects/{id}/durable-functions/{functionId}/executions/{executionId}/message-waits
GET /projects/{id}/durable-functions/{functionId}/executions/{executionId}/messages
POST /projects/{id}/durable-functions/{functionId}/executions/{executionId}/messages
GET /projects/{id}/issues
GET /projects/{id}/issues/{issueId}
PATCH /projects/{id}/issues/{issueId}
POST /projects/{id}/issues/{issueId}/autofix-runs
GET /projects/{id}/variable-environments
POST /projects/{id}/variable-environments
DELETE /projects/{id}/variable-environments/{environmentId}
GET /projects/{id}/variable-environments/{environmentId}
PATCH /projects/{id}/variable-environments/{environmentId}
Deleted Endpoints: None
Modified Endpoints: 61
POST /auth/forgot-password
POST /auth/logout
POST /auth/oauth/exchange
GET /auth/password-policy
POST /auth/refresh
POST /auth/reset-password
POST /auth/signin
or account banned/deleted
' to 'Unauthorized - Invalid credentials, invalid/tampered/revoked anon key,
or account banned/deleted; or invalid auth proxy metadata
'
POST /auth/signup
' to 'Unauthorized - Invalid, tampered, revoked, or wrong-project anon key.
Also returned for invalid, repeated, or under-scoped auth proxy metadata
(
invalid auth proxy metadata).'
POST /auth/signup-anonymous
GET /capabilities
to decide what to offer, instead of calling a route to see whether it fails.
sandboxessandboxes.sessionssandboxes.custom_templatessandboxes.sessionsis unavailableA capability missing from the list is unavailable, and a capability under
another, such as
sandboxes.sessions, is unavailable whenever its parent is.While a capability is unavailable, requests that start new work answer
404or
400with codefeature_unavailable; refresh this list when you receivethat code. Reading, deleting, and terminating what already exists keep
working unless the whole feature is absent from the environment. Every caller
in an environment gets the same answer.
' to 'Lists which product capabilities accept new work in this environment. Check it
to decide what to offer, instead of calling a route to see whether it fails.
sandboxessandboxes.sessionssandboxes.custom_templatessandboxes.sessionsis unavailableissuesautofixautofix.managed_modelsA capability missing from the list is unavailable, and a capability under
another, such as
sandboxes.sessions, is unavailable whenever its parent is.While a capability is unavailable, requests that start new work answer
404or
400with codefeature_unavailable; refresh this list when you receivethat code. Reading, deleting, and terminating what already exists keep
working unless the whole feature is absent from the environment. Every caller
in an environment gets the same answer.
'
sandboxes,sandboxes.sessions, orsandboxes.custom_templates. New IDs may appear at any time.' to 'Stable capability ID, such assandboxes,sandboxes.sessions,sandboxes.custom_templates,issues, orautofix. New IDs may appear at any time.'POST /durable-approvals
Request body changed
limited to 64 KiB.
' to 'Any JSON value to show the person deciding. A number's exponent must
be between -324 and 324, and a number too large or too precise to
store is refused with
400. Numbers are read back written out infull, so the exponents' absolute values may total at most 65,536.
The whole request is limited to 64 KiB.
'
Responses changed
codesays why:approval_not_ready: the workflow has not finished opening theapproval yet. Retry with a short backoff; the SDK does.
approval_closed: the workflow is no longer waiting on it.execution_ended: the execution has finished.too_many_pending_approvals: the execution already has themaximum number of pending approvals.
' to 'The approval cannot be registered now.
codesays why:approval_not_ready: the workflow has not finished opening theapproval yet. Retry with a short backoff; the SDK does.
approval_closed: the workflow is no longer waiting on it.callback_taken: the callback is already registered as amessage wait or a messages session.
execution_ended: the execution has finished.too_many_pending_approvals: the execution already has themaximum number of pending approvals.
'
POST /durable-functions/{functionId}/executions
returned when two starts under the same execution name raced and
both released it, which is retryable as it stands.
' to 'Function is not deployed yet, or has no deployed region. Also
returned when two starts under the same execution name raced and
both released it, which is retryable as it stands, and with
codeexecution_name_heldwhen an unfinished start this caller may notresume holds the execution name, which needs a name of its own.
'
POST /functions/{functionId}/invoke
visibilitydecides which credentialsmay call it, and the function does not run for any other. A
privatefunction answers every credential but a service key exactly as a
missing one, with 404, so its name and id cannot be discovered; an anon
key on an
authenticatedfunction gets 403. An SDK calling by nameresolves it first through
GET /functions/resolve, which answers thatanon key with 404 instead.
With Service Key (admin/background operations, every visibility):
With Auth User Token (user-facing,
authenticatedorpublicfunctions):__volcano_authcontext:With Anon Key (
publicfunctions only):functions.invokevisibility: public__volcano_auth)Transport and CORS:
POST
{payload: ...}contract, including for functions whose DNS ingress isconfigured in HTTP mode.
invoke_url. It is on adifferent domain from this API, so it cannot be derived from the API host.
/. HTTP-mode DNS ingress accepts GET,HEAD, POST, PUT, PATCH, and DELETE at
/and nested paths.POST, OPTIONS. HTTP-mode DNSpreflight advertises
GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS.http_auth_mode: noneapplies only to public HTTP-mode DNS ingress; thisdirect operation always requires a Volcano credential.
Durable functions are not invocable here. A durable function's id
answers 404, whatever its visibility, because a synchronous call would
run it with no execution record, no idempotency and no concurrency
accounting. Start one with
POST /durable-functions/{functionId}/executions.' to 'Invoke a function. The function's
visibilitydecides which credentialsmay call it, and the function does not run for any other. A
privatefunction answers every credential but a service key exactly as a
missing one, with 404, so its name and id cannot be discovered; an anon
key on an
authenticatedfunction gets 403. An SDK calling by nameresolves it first through
GET /functions/resolve, which answers thatanon key with 404 instead.
With Service Key (admin/background operations, every visibility):
With Auth User Token (user-facing,
authenticatedorpublicfunctions):__volcano_authcontext:With Anon Key (
publicfunctions only):functions.invokevisibility: public__volcano_auth)Reserved payload keys: the top-level
__volcano_authand__volcano_httpkeys are reserved. Volcano removes caller-suppliedvalues for both before the function runs; only an auth user token adds
a server-built
__volcano_auth, and only HTTP-mode ingress sets__volcano_http: true.Transport and CORS:
POST
{payload: ...}contract, including for functions whose DNS ingress isconfigured in HTTP mode.
invoke_url. It is on adifferent domain from this API, so it cannot be derived from the API host.
/. HTTP-mode DNS ingress accepts GET,HEAD, POST, PUT, PATCH, and DELETE at
/and nested paths.POST, OPTIONS. HTTP-mode DNSpreflight advertises
GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS.http_auth_mode: noneapplies only to public HTTP-mode DNS ingress; thisdirect operation always requires a Volcano credential.
Durable functions are not invocable here. A durable function's id
answers 404, whatever its visibility, because a synchronous call would
run it with no execution record, no idempotency and no concurrency
accounting. Start one with
POST /durable-functions/{functionId}/executions.'
If invoked with auth user token, Volcano automatically injects
__volcano_authcontext:' to 'Payload to send to the function.
If invoked with auth user token, Volcano automatically injects
__volcano_authcontext:The top-level
__volcano_authand__volcano_httpkeys are reserved;Volcano removes caller-supplied values for both.
'
GET /projects
POST /projects
GET /projects/{id}
PATCH /projects/{id}
GET /projects/{id}/auth/config
PUT /projects/{id}/auth/config
GET /projects/{id}/auth/insights
active users, and zero-filled signup, deletion, net-growth, and successful
sign-in counts for an inclusive UTC date range. Weeks start on Monday.
Signups remain counted after deletion; net growth is signups minus
deletions. Deleted users contribute to active counts until their last
activity leaves the rolling window. Token refreshes affect active users
but not the sign-in series. Collection starts at deployment, with signup
history backfilled from accounts still present then. Earlier hard-deleted
accounts cannot be recovered.
' to 'Returns current and deleted auth-user totals, rolling 24-hour and 30-day
active users, and zero-filled daily activity and account-retention counts
for an inclusive UTC date range. Weeks start on Monday.
The existing deletions series counts accounts by deletion date; net_growth
remains signups minus deletions and is not affected by bans.
The banned_users, deleted_users, and available_users fields describe the
current state of users registered in each bucket. Banned users exclude
deleted users and expired bans. Available users are signups minus
banned_users minus deleted_users. Unban and expiry restore availability in
the original signup bucket. These current-state cohorts can change after
the requested dates have passed, without rewriting activity counts.
Sign-in counts remain grouped by session creation date. Deleted users
contribute to active counts until their last activity leaves the rolling
window. Token refreshes affect active users but not the sign-in series.
Signup history is backfilled from accounts present when collection was
deployed. Accounts hard-deleted before deletion-history collection cannot
be recovered. Current bans require no separate event-history collection.
'
GET /projects/{id}/config
tlsis requiredwhen the domain is first created and optional afterwards. For an existing
domain, omitting
tlsor sending onlytls.modekeeps the storedcertificate; new BYOC material for the same domain rotates the
certificate in place (zero downtime). Changing
tls.modefor the samehostname, or the hostname of a managed domain, requires deleting the
domain first. BYOC TLS material is write-only; exports render only
tls.mode.' to 'Custom domain with managed or BYOC TLS.
tlsis requiredwhen the domain is first created and optional afterwards. For an existing
domain, omitting
tlsor sending onlytls.modekeeps the storedcertificate; new BYOC material for the same domain rotates the
certificate in place (zero downtime). Changing
tls.modefor the samehostname switches an active domain in place (zero downtime); a domain
that is not yet active, or a managed domain changing hostname, must be
deleted first. BYOC TLS material is write-only; exports render only
tls.mode.'
PUT /projects/{id}/config
tlsis requiredwhen the domain is first created and optional afterwards. For an existing
domain, omitting
tlsor sending onlytls.modekeeps the storedcertificate; new BYOC material for the same domain rotates the
certificate in place (zero downtime). Changing
tls.modefor the samehostname, or the hostname of a managed domain, requires deleting the
domain first. BYOC TLS material is write-only; exports render only
tls.mode.' to 'Custom domain with managed or BYOC TLS.
tlsis requiredwhen the domain is first created and optional afterwards. For an existing
domain, omitting
tlsor sending onlytls.modekeeps the storedcertificate; new BYOC material for the same domain rotates the
certificate in place (zero downtime). Changing
tls.modefor the samehostname switches an active domain in place (zero downtime); a domain
that is not yet active, or a managed domain changing hostname, must be
deleted first. BYOC TLS material is write-only; exports render only
tls.mode.'
GET /projects/{id}/domains
GET /projects/{id}/durable-functions/{functionId}/executions
POST /projects/{id}/durable-functions/{functionId}/executions
GET /projects/{id}/durable-functions/{functionId}/executions/{executionId}
POST /projects/{id}/durable-functions/{functionId}/executions/{executionId}/stop
GET /projects/{id}/frontends
POST /projects/{id}/frontends
If a frontend with the same name already exists in the project, this operation updates that
frontend using the uploaded archive and starts a new deployment. A deployment that starts
immediately returns
status: provisioning, then transitions toactive,degraded, orfailed. If another deployment is running, the response preserves the frontend's current statusand exposes the queued deployment through
pending_deployment_id.Existing frontend traffic continues to use an available runtime while the new deployment builds
and provisions. Each deployment publishes its own static assets before the runtimes switch to its
build, and the live build's assets keep serving until the new deployment is live, so a page loaded
mid-deployment resolves its assets whichever build served it. A failed redeploy puts the runtimes
back on the build they were running, leaves the frontend
activeon the previous deployment, andrecords the attempted deployment as failed.
degradedmeans the runtime remains available butedge synchronization requires recovery; Volcano retries the edge step without rebuilding. Only one deployment may run for a
given frontend, while independent frontends and projects can deploy concurrently.
For monorepos, provide
app_rootas a relative path from the uploaded archive rootto the Next.js app that should be built. Omit it for single-app archives.
Supported frontend environments are Next.js 15.x and 16.x with Node.js
22.x or 24.x. The Node.js runtime is inferred from
package.jsonengines.node; if omitted, Volcano uses Node.js 22.x.The selected Node.js family must also satisfy the installed Next.js package's
engines.nodeconstraint. Volcano tests Next 15.5.27 (^18.18.0 || ^19.8.0 || >=20.0.0) and Next 16.4.0 (>=20.9.0).Source archive size is enforced by the API with
SOURCE_ARCHIVE_SIZE_LIMIT_MB; the CLIdoes not apply its own source archive size limit. After the final container images are
built, the publish build enforces
LAMBDA_TARGET_CONTAINER_SIZE_LIMIT_MBbefore pushing.This operation is limited by plan-based frontend deployment quotas (
FREE_FRONTEND_DEPLOYMENTS,PRO_FRONTEND_DEPLOYMENTS).Each project can contain up to 10,000 frontends regardless of plan.
' to 'Creates and deploys a frontend for the project.
If a frontend with the same name already exists in the project, this operation updates that
frontend using the uploaded archive and starts a new deployment. A deployment that starts
immediately returns
status: provisioning, then transitions toactive,degraded, orfailed. If another deployment is running, the response preserves the frontend's current statusand exposes the queued deployment through
pending_deployment_id.Existing frontend traffic continues to use an available runtime while the new deployment builds
and provisions. Each deployment publishes its own static assets before the runtimes switch to its
build, and the live build's assets keep serving until the new deployment is live, so a page loaded
mid-deployment resolves its assets whichever build served it. A failed redeploy puts the runtimes
back on the build they were running, leaves the frontend
activeon the previous deployment, andrecords the attempted deployment as failed.
degradedmeans the runtime remains available butedge synchronization requires recovery; Volcano retries the edge step without rebuilding. Only one deployment may run for a
given frontend, while independent frontends and projects can deploy concurrently.
For monorepos, provide
app_rootas a relative path from the uploaded archive rootto the Next.js app that should be built. Omit it for single-app archives.
Supported frontend environments are Next.js 15.x and 16.x with Node.js
22.x or 24.x. The Node.js runtime is inferred from
package.jsonengines.node; if omitted, Volcano uses Node.js 22.x.The selected Node.js family must also satisfy the installed Next.js package's
engines.nodeconstraint. Volcano tests Next 15.5.28 (^18.18.0 || ^19.8.0 || >=20.0.0) and Next 16.4.2 (>=20.9.0).Source archive size is enforced by the API with
SOURCE_ARCHIVE_SIZE_LIMIT_MB; the CLIdoes not apply its own source archive size limit. After the final container images are
built, the publish build enforces
LAMBDA_TARGET_CONTAINER_SIZE_LIMIT_MBbefore pushing.This operation is limited by plan-based frontend deployment quotas (
FREE_FRONTEND_DEPLOYMENTS,PRO_FRONTEND_DEPLOYMENTS).Each project can contain up to 10,000 frontends regardless of plan.
'
GET /projects/{id}/frontends/{frontendId}
DELETE /projects/{id}/frontends/{frontendId}/domain
GET /projects/{id}/frontends/{frontendId}/domain
POST /projects/{id}/frontends/{frontendId}/domain
The default Volcano-generated frontend URL remains active.
Wildcard Volcano frontend TLS remains valid and isolated from custom-domain certificate changes.
The account must own the hostname: it must have verified the hostname or a domain above it (see
POST /user/domains). A certificate does not prove ownership.When the account owns no domain covering the hostname, Volcano asks for a TXT record at
_volcano.<registrable domain>, such as_volcano.example.com. Publishing it verifies the whole domain, so later subdomains need no record. A managed TLS request reserves the hostname and returns that record inverification_records; the reservation expires after 72 hours unless the record is published. A BYOC request gets409withcode: ownership_verification_requiredand the record inrequired_record; publish it and send the same request again.Managed TLS then returns the CNAME that authorizes certificate issuance and renewal.
An unverified reservation does not block an account that proves ownership. When another acc
Report truncated; see the source commit for the complete contract diff.
Validation