Skip to content

Wesley TS emitter also emits a Zod runtime-validation layer #586

Description

@flyingrobots

Migrated from a local Wesley Method backlog card after adopting METHOD v2.1.0 tracker doctrine.

  • Source path: docs/method/backlog/cool-ideas/wesley-ts-emitter-emits-zod-layer.md
  • Original filesystem lane: cool-ideas
  • Canonical Method lane label: lane:cool-ideas
  • Legend: TRANSMUTE
  • Migration issue: Migrate Wesley Method backlog to GitHub Issues #548
  • Migrated on: 2026-06-04

Original Local Backlog Card

Wesley TS emitter also emits a Zod runtime-validation layer

Status: cool idea.

The idea

Add a Wesley emit target — emit zod-typescript (or fold into
existing emit typescript) — that produces Zod schemas alongside the
TS interfaces:

// Generated by Wesley TS emitter:
export interface CreateBufferWorldlineInput {
    bufferKey: string;
    initialText?: string | null;
    ...
}

// Same emit, Zod layer:
export const CreateBufferWorldlineInputSchema = z.object({
    bufferKey: z.string(),
    initialText: z.string().nullable().optional(),
    ...
});

Both derive from the same Wesley IR. Drift is structurally impossible.

What it replaces

jedit currently maintains hand-authored Zod schemas in
src/adapters/jedit-echo-optic-codec.ts (~250 lines of Zod that
mirrors the Wesley TS types). Plus a generated
src/generated/jedit/rope.zod.generated.ts produced by some other
generator. Drift between Wesley TS types and Zod schemas is currently
a hand-coordinated activity.

Why it matters

Wesley's whole pitch is "one schema, all representations emit
atomically; drift is structurally impossible." Today that's true for
types + codecs + op ids; runtime validation lives outside the
guarantee.

After the EINT cutover (0024 design Phase 7), the JSON-side Zod parse
in jedit-echo-optic-codec.ts becomes mostly dead code. The remaining
runtime validation (e.g., reading user input from a UI before
codec-encoding) still needs Zod or equivalent. Generating it from
Wesley closes the last drift gap.

Open questions

  • One target or merge into emit typescript? Merging means a
    consumer that wants only types pays the Zod import cost; separating
    is cleaner but adds a fourth emit target.
  • Zod 3 or Zod 4? Wesley's existing zod adapter (scripts/run-wesley-tool.mjs host-node zod) targets one specific version — would the Rust-native
    emit target pick a different one?
  • Does the schema's default_value translate to .default(x) or
    .optional()? Both? The Wesley TS emit currently uses ?: T | null
    which suggests both nullable AND optional.

Surface when

Touching src/adapters/jedit-echo-optic-codec.ts Zod definitions
during the Phase 5/6/7 jedit cutover work and feeling the urge to
hand-edit a Zod schema to match a type change.

Activity

  1. added
    triage:cool-ideasExploratory idea intake that still needs scheduling, closure, or a repo move
    legend:TRANSMUTETransformation/emitter/generator work
    on Jun 4, 2026
  2. coderabbitai commented on Jun 4, 2026

    @coderabbitai
    🔗 Related PRs

    #44 - feat(qir): ops emission (VIEW + SQL function returning jsonb rows) [merged]
    #368 - feat(ttd): TTD Protocol Compiler - Phase 1 [merged]
    #402 - feat: add WASM ABI codec generation to generator-echo [merged]
    #499 - test(stack): add Stack Witness 0001 fixture artifact shape [merged]
    #504 - Compile runtime optic artifacts [merged]


    📝 Issue Planner

    Check the box below or use the @coderabbitai plan command to generate an implementation plan and prompts that you can use with your favorite coding assistant.

    • Create Plan

    🧪 Issue enrichment is currently in open beta.

    You can configure auto-planning by selecting labels in the issue_enrichment configuration.

    To disable automatic issue enrichment, add the following to your .coderabbit.yaml:

    issue_enrichment:
      auto_enrich:
        enabled: false

    💬 Have feedback or questions? Drop into our discord!

  3. flyingrobots commented on Jun 25, 2026

    @flyingrobots
    OwnerAuthor

    Triage decision: keep this in Wesley and move it out of the inbox into lane:v0.5.0 / Goalpost: Make It a Real Platform.

    Rationale: A Zod layer can only survive as generic TypeScript emitter output from IR shape, not RPC/Postgres validation.

    This is scheduled core Wesley work now, not an inbox item. The triage label is being removed as part of this state change.

  4. added
    v0.5.0Scheduled work for the v0.5.0 release.
    and removed
    triage:cool-ideasExploratory idea intake that still needs scheduling, closure, or a repo move
    on Jun 25, 2026
  5. flyingrobots commented on Jul 6, 2026

    @flyingrobots
    OwnerAuthor

    Closing as not planned after the Rust-native roadmap audit. Zod runtime validation should live in an external target/module when needed, not be folded into the generic Wesley TypeScript emitter. This preserves the domain-empty compiler boundary and avoids making a runtime validation library part of the core product contract.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    docsDocumentation changeslegend:TRANSMUTETransformation/emitter/generator workv0.5.0Scheduled work for the v0.5.0 release.

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions