Skip to content

fix(eval): accept run event envelope fields on managed eval stream frames - #5335

Merged
kwakayama merged 2 commits into
mainfrom
fix/3578-managed-eval-stream-frames
Oct 19, 2026
Merged

kwakayama merged 2 commits into
mainfrom
fix/3578-managed-eval-stream-frames

Conversation

@kwakayama

Copy link
Copy Markdown
Contributor

Managed evals on staging fail on the first frame of the agent child's GET /runs/{run_id}/stream. The eval report records Invalid canonical managed eval stream frame.

Since veryfront-api#6054, every RunStreamFrame carries the run event envelope fields run_id, event_class, span_id, parent_span_id, turn_id, origin_event_type, origin_custom_name and unrecoverable_fields beside the five base fields. The published contract lists them as optional properties. adaptManagedEvalRunStream validated frames with .strict(), so the extra fields rejected every frame.

Changes:

  • The frame schema now follows the published RunStreamFrame contract. The five base fields the adapter reads stay required and keep their checks, together with the payload.type, SSE event and id agreement checks. The envelope fields are optional, and when present they are checked against getRunEventEnvelopeSchema from run-events/envelope.ts, so a malformed event_class, span_id or unrecoverable_fields is still rejected. Fields the contract adds later are stripped, because the API extends the frame additively.
  • Regression tests use frames captured from staging on 2026-10-19 (identifiers replaced). They failed before this change and pass after it. Other tests cover an unknown future field and malformed envelope fields. The old "rejects an extra envelope field" case is removed, because that expectation contradicts the published superset contract.

Audit of other parsers of the same frames or rows (same bug class): none found. runs/target/client.ts isCanonicalFrame (SDK stream), runs/runs-client.ts events(), the live-evals runner and run-events/envelope.ts all accept or strip extra top-level fields. The nearby .strict() schemas parse POST /runs/{id}/events append receipts, control-plane payloads or the separate canonical-v1 representation, so they are a different class.

Verification:

  • deno task test:file src/server/handlers/request/managed-eval-run-stream.test.ts: red (2 failures) before the fix, 15/15 after
  • deno task test:file src/server/handlers/request/project-run-execute.handler.test.ts: 458 steps pass
  • deno task test:unit: pass (Deno 2.9.7)
  • deno task lint:testing-front-door, lint:test-semantic-dispositions, lint:dependency-boundaries, lint:module-boundaries, lint:anti-slop: pass

Closes veryfront/veryfront-issue-inbox#3578

…ames

Since the Runs API added the run event envelope fields (run_id, event_class,
span_id, parent_span_id, turn_id, origin_event_type, origin_custom_name,
unrecoverable_fields) to every RunStreamFrame, the managed eval adapter's
strict frame schema rejected the first frame and failed every managed eval.

Validate frames against the published RunStreamFrame contract instead: the
five base fields stay required, the envelope fields are checked against the
run event envelope schema when present, and fields added later are dropped.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-19T14:46:00.564934Z 2aa6ed9 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@github-actions

Copy link
Copy Markdown

📦 Client bundle boundary

Entrypoint Modules Source size Server leaks
src/index.client.ts 65 362 KiB ✅ 0
src/react/components/Head.tsx 5 74 KiB ✅ 0
src/react/router/index.tsx 5 74 KiB ✅ 0
src/react/context/index.tsx 5 74 KiB ✅ 0
src/react/fonts/index.ts 6 81 KiB ✅ 0
src/react/components/ui/index.ts 111 717 KiB ✅ 0
src/react/components/ui/adapter/contract.ts 1 18 KiB ✅ 0
src/react/components/ui/icons/index.ts 3 17 KiB ✅ 0
src/chat/index.ts 301 2017 KiB ✅ 0
src/chat/ag-ui.ts 61 457 KiB ✅ 0
src/chat/protocol.ts 1 11 KiB ✅ 0
src/chat/types.ts 45 242 KiB ✅ 0
src/chat/message-prep.ts 67 513 KiB ✅ 0
src/markdown/index.ts 6 30 KiB ✅ 0
src/mdx/index.ts 2 2 KiB ✅ 0
src/agent/identity-contracts.ts 1 2 KiB ✅ 0
src/schemas/index.ts 42 216 KiB ✅ 0
src/platform/env.ts 5 53 KiB ✅ 0
src/workflow/claude-code/react/index.ts 9 91 KiB ✅ 0
src/events/index.ts 31 568 KiB ✅ 0
src/events/ag-ui/public.ts 30 561 KiB ✅ 0
src/run-events/index.ts 53 317 KiB ✅ 0

A server module in a client graph aborts hydration in the browser. New leaks fail CI; known leaks are tracked in scripts/lint/client-bundle-baseline.json to burn down.

@github-actions

Copy link
Copy Markdown

@codex review

Copy link
Copy Markdown
Contributor Author

Score: 88/100. Small, well-scoped fix that makes the managed eval stream adapter accept the published RunStreamFrame envelope fields.

  • Strength: The fix reuses getRunEventEnvelopeSchema().partial().extend(...) instead of duplicating the field definitions. The five base fields stay required, and the envelope fields are validated when present, so a malformed event_class, span_id or unrecoverable_fields is still rejected.
  • Strength: The tests use frames captured from staging with identifiers replaced, and they cover the failure cases: unknown future field, bad class, empty span id, non-string run id, non-array unrecoverable fields. The PR reports the new tests failing before the fix. Dropping the old "extra envelope field" case is justified, because it contradicted the superset contract.
  • Strength: The PR description explains the root cause and records an audit of sibling parsers. The diff is minimal (121 additions, 3 deletions, 2 files).
  • Minor concern: .partial() on the envelope schema drops the strict event_class versus event_type agreement check that getTypedRunEventRowSchema applies to catalogued types. That is probably intended, since the adapter only needs the base fields, but a one-line comment would make the choice explicit.
  • Minor concern: The schema is built with defineSchema but composed from a defineRunEventSchema schema. The tests pass, but check that the two wrappers stay compatible, for example if defineRunEventSchema later adds refinements.

I reviewed the diff statically and did not run the tests. Nothing here blocks merge.


Generated by Claude Code

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep it up!

Reviewed commit: 6f8b25ea72

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@codecov

codecov Bot commented Oct 19, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@kwakayama
kwakayama added this pull request to the merge queue Oct 19, 2026
@kwakayama
kwakayama removed this pull request from the merge queue due to a manual request Oct 19, 2026
@kwakayama

Copy link
Copy Markdown
Contributor Author

Addressed both minor concerns in 2aa6ed9: the schema comment now states that the adapter checks envelope field shapes only and skips the event_class/event_type agreement check (it forwards only the payload), and why composing getRunEventEnvelopeSchema (a plain object schema from the same defineSchema registry) is safe.

@kwakayama
kwakayama enabled auto-merge October 19, 2026 14:44
@github-actions

Copy link
Copy Markdown

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 👍

Reviewed commit: 2aa6ed9792

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@kwakayama
kwakayama added this pull request to the merge queue Oct 19, 2026
@sonarqubecloud

Copy link
Copy Markdown

Merged via the queue into main with commit 68f6e79 Oct 19, 2026
438 checks passed
@kwakayama
kwakayama deleted the fix/3578-managed-eval-stream-frames branch October 19, 2026 15:20
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.

1 participant