Skip to content

fix(ask): avoid numeric enum in round-zero schema for Cloud Code Assist - #4606

Merged
Yeachan-Heo merged 1 commit into
Yeachan-Heo:devfrom
Veritas-7:fix/ask-round-zero-enum-400
Aug 17, 2026
Merged

fix(ask): avoid numeric enum in round-zero schema for Cloud Code Assist#4606
Yeachan-Heo merged 1 commit into
Yeachan-Heo:devfrom
Veritas-7:fix/ask-round-zero-enum-400

Conversation

@Veritas-7

Copy link
Copy Markdown
Contributor

Problem

The ask tool's deep-interview round-zero schema uses z.literal(0):

round: z.literal(0).describe("Round 0 topology confirmation"),

When serialized to JSON Schema this emits {"type": "number", "enum": [0]}. The Cloud Code Assist API (google-antigravity provider) rejects numeric enum values with:

Cloud Code Assist API error (400): Invalid value at
'request.tools[0].function_declarations[...].parameters...
enum[0]' (TYPE_STRING), 0

Any session on the google-antigravity provider that activates the deep-interview skill prompt fails with HTTP 400 before the first assistant turn.

Fix

Replace z.literal(0) with an integer range pinned to zero:

round: z.number().int().min(0).max(0).describe("Round 0 topology confirmation"),

This keeps the runtime contract identical (only 0 is accepted — verified by schema tests) while avoiding the numeric enum that Cloud Code Assist rejects. String literals elsewhere (component, dimension) are unaffected because their enums are already strings.

Verification

  • bun test packages/coding-agent/test/deep-interview-* and sdk-ask-*: 76 pass / 0 fail
  • Schema probe: round accepts 0, rejects 1 and -1 (same contract as z.literal(0))
  • Repro: deep-interview session on google-antigravity previously 400'd; with this change the schema no longer contains a numeric enum

z.literal(0) serializes to {"type":"number","enum":[0]}, which Cloud
Code Assist API rejects with HTTP 400 (expects TYPE_STRING for enum
values). Replace with an int range [0,0] that keeps round pinned to zero
without emitting a numeric enum.

@Yeachan-Heo Yeachan-Heo left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

MERGE_READY

Independent adversarial review of head db09c22 against origin/dev 7ca1d66a (lane branch review/pr-4606-current-head-1786958478). The defect, mechanism, and fix were all independently reproduced before this verdict.

Defect — independently confirmed

z.literal(0) in DeepInterviewTopologyMeta (packages/coding-agent/src/tools/ask-contract.ts:102) serializes via z.toJSONSchema to {"type":"number","const":0}. The Cloud Code Assist path (normalizeAntigravityToolsnormalizeSchemaForCCA) forbids const (CCA_FORBIDDEN_KEYS) and rewrites it to enum: [0] (normalizeSchemaForCCA const→enum conversion). The serialized antigravity tool declaration therefore carries a numeric enum, which the CCA API rejects with the exact 400 Invalid value at ... enum[0]' (TYPE_STRING), 0 from the PR description. Any google-antigravity session whose active deep-interview stage is topology fails before the first assistant turn.

Scope check on the old form across every ask surface: only selectAskParameters("topology") emits the numeric enum; the deferred askSchema union, post-topology, and ordinary forms do not (their round constraints are positive ranges, and the union collapses to a single variant). This matches the reported blast radius exactly.

Fix — verified

z.number().int().min(0).max(0) emits {"type":"integer","minimum":0,"maximum":0}. On the CCA wire this becomes {"type":"integer","description":"Round 0 topology confirmation\n\n{minimum: 0, maximum: 0}"} — minimum/maximum are stripped into the liftable-to-description spill, the identical treatment the adjacent ambiguity field already receives. No numeric enum remains anywhere in the serialized schema (verified by regex over the full serialized declaration).

Runtime contract is unchanged: round: 0 accepted; 1, -1, 0.5 rejected (full valid Round-0 payload with intent_contract). The TS-level widening of the inferred type from 0 to number is safe — every consumer of this field does runtime value checks (=== 0, <= 0), and check:ts passes.

Red-team checklist

  • Regression: none found. This is the same constraint-relaxation pattern the file already uses for ambiguity (min(0).max(1)) and the sibling round fields (positive()).
  • Lifecycle/authority/privacy/security: no behavioral, permission, or data-surface change; schema-shape only, tool-input validation preserved exactly.
  • Generated/aggregate fixture closure: tool-catalog.generated.ts (38 entries), schemas/*.schema.json, plugins, and docs-index all regenerate byte-identical — the catalog snapshot uses the ordinary ask form, which does not contain this field.
  • Stale base: fork point c83ffe3d vs dev tip 7ca1d66a; GitHub three-dot diff is exactly this one file; dev drift (0.14.0 version bumps, README/MAINTAINERS/terminal-app-integrations docs) has zero interaction. Merges clean.
  • Targeted tests: deep-interview suites (skill-contract, workflow-gates, gate-redteam, hangul-normalization, plaintext-gate-guard, acp-wire, session-continuation) + sdk-ask suites + tools/descriptors + tools-registry + default-gjc-definitions: 162 pass / 0 fail.
  • Full gates: bun run check:ts full closure (all workspaces, schemas, plugins, sdk-closure manifests) exit 0.
  • Build + smoke: bun run build exit 0; compiled binary --versiongjc/0.14.0, --smoke-test → ok.
  • Local-only noise: a handful of packages/ai tests (baseurl-trust, register-builtins watchdogs, auth-broker-wire, auth-storage-mcp-origin, auth-gateway-*, openai-responses-cache-affinity) fail in this sandbox identically on pristine origin/dev — machine config (ANTHROPIC_BASE_URL=api.layofflabs.com in the ambient env, fetch-spy/global-fetch interception), not this PR.

Notes (non-blocking)

  • No changelog entry under packages/coding-agent/CHANGELOG.md [Unreleased]; dev history shows fix entries are conventionally recorded. Merge will add one so the release notes carry the CCA 400 fix.
  • The PR description's claim that zod emits enum:[0] is imprecise (zod 4.4.3 emits const:0; the CCA normalizer converts it to enum), but the end-to-end diagnosis and fix are correct.

Proceeding to merge into dev under delegated authority, followed by canonical dev fast-forward, bun run build, and dogfood on the merged tree.

[repo owner's gaebal-gajae (clawdbot) 🦞]

@Yeachan-Heo
Yeachan-Heo merged commit eee2a91 into Yeachan-Heo:dev Aug 17, 2026
Yeachan-Heo pushed a commit that referenced this pull request Aug 17, 2026
The merged fix removes the numeric enum from the deep-interview Round-0
topology ask schema on the Cloud Code Assist wire, unblocking
google-antigravity deep-interview sessions that previously died with
HTTP 400 before the first assistant turn. Records it under
[Unreleased] per repo convention.

Lore-id: 8f2c1e94
Constraint: changelog entries go under [Unreleased]; released sections are never edited
Confidence: high
Scope-risk: narrow
Reversibility: trivial
Tested: merged dev targeted suites in the review lane (162 pass)
Supersedes: eee2a91

c243017c0e
pull Bot pushed a commit to folding-mirror/gajae-code that referenced this pull request Aug 18, 2026
…#4606

The merged fix removes the numeric enum from the deep-interview Round-0
topology ask schema on the Cloud Code Assist wire, unblocking
google-antigravity deep-interview sessions that previously died with
HTTP 400 before the first assistant turn. Records it under
[Unreleased] per repo convention.

Lore-id: 8f2c1e94
Constraint: changelog entries go under [Unreleased]; released sections are never edited
Confidence: high
Scope-risk: narrow
Reversibility: trivial
Tested: merged dev targeted suites in the review lane (162 pass)
Supersedes: eee2a91

c243017c0e

(cherry picked from commit b91aece)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants