feat(evals): typed runner core + automation/demo mode split - #2971
Merged
Conversation
- pnpm evals = automation mode: no voiceover/narration policy anywhere - pnpm fraimz = demo mode: unchanged behavior (drift check, narrated frames) - runner converted to TypeScript on Node 24 native type-stripping (no build step, no new runtime deps); run.mjs stays as a thin bootstrap - typed flow contract: defineFlow + FlowContext (evals/runner/flow.ts); new flows are *.flow.ts, legacy *.flow.mjs still load via compat shims - scaffold emits typed .flow.ts stubs; plain stub without a script in automation mode, approved script still required in demo mode - OPENWORK_EVAL_VOICEOVERS_DIR override for fixture isolation - tsc gate (pnpm evals:typecheck) + runner unit tests (pnpm evals:test) - nightly workflow pinned to pnpm fraimz --all to keep drift coverage
Narrated internal demo (approved script: evals/voiceovers/typed-automation-dx.md) proving the DX end to end: mode split wiring, drift decoupling, scriptless typed scaffold, tsc contract gate, legacy compatibility, and demo-path default.
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Member
Author
…ation # Conflicts: # evals/runner/den-stack.ts
The chart test cross-references the eval den-stack to keep the den-api entrypoint consistent; den-stack.mjs became den-stack.ts in this branch.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.





What
Decouples the eval runner from the voice-over/demo machinery and gives it a typed core, per the primitives plan (create the contract, delete the fusion, combine the entrypoints):
pnpm evalsis now automation mode: no narration requirements anywhere (no drift check, no unnarrated-frame warnings, scriptless scaffold).pnpm fraimzis demo mode: byte-for-byte today's behavior (voice-over drift check enforced, narrated frames, script-first scaffold). Default mode for directnode evals/runner/run.mjsinvocations staysdemo, so existing automations/CI behave identically.evals/runner/*.ts) with no build step and no new runtime dependencies.run.mjsremains as a thin bootstrap so every existing entrypoint keeps working.defineFlow()+FlowContext(evals/runner/flow.ts): new flows are*.flow.tswith compile-time checking (pnpm evals:typecheck); a flow that misuses the ctx API failstscbefore it ever drives an app. All 200+ legacy*.flow.mjsflows load unchanged via compat shims (voiceover.mjs,cdp.mjs,pr.mjs,context.mjs,daytona-computer-use.mjs).report.json/fraimz.htmlnow carry the runmode; nightly workflow pinned topnpm fraimz --allso nightly keeps narration-drift coverage.Why
The voiceover policy was fused into
runFlow— a passing automation could be failed by narration drift, scaffolding required an approved script, and 150 flows imported narration plumbing just to exist. The engine and the demo policy are now separate primitives; voiceover is a layer on top. Typedctxmakes generated flow code verifiable before runtime — the contract agents compose against.Tests run
pnpm evals:typecheck— clean (runner + typed flows).pnpm evals:test— 4/4 runner unit tests pass.pnpm fraimz --flow voiceover-first-dx— the demo-path canary passes end to end (scaffold, drift-failure fixture, red-run exit codes, PR renderer).pnpm fraimz --flow typed-automation-dx— the new internal demo (frame proof posted below), including the voice-over coverage step..devcontainer/test-on-daytona.shon this branch):pnpm fraimz --flow app-smoke --flow core-flow --cdp-url <sandbox>— both pass:app-smokeruns from the migrated.flow.ts, and the canonicalcore-flowjourney (boot → new task → message → real model response via opencode zen → close/reopen → session intact) is unchanged.pnpm evals --flow app-smoke(automation mode) also passes against the live app.Frame proof (fraimz) posted as a PR comment below (typed-automation-dx + app-smoke + core-flow driven against the sandbox).
Notes / follow-ups
core-flow's "agent responds" assertion is satisfiable by the user's own message text rendering (waitForText("core-flow ok")matches the typed message; the step-3 screenshot can fire before the reply streams). Pre-existing behavior, faithfully preserved by this refactor — worth tightening in a follow-up (assert on an assistant-role row).Targetprimitive:--target local | daytona-linux | daytona-windows+ macOS CI lane) is designed but intentionally not in this PR.