Skip to content

test(core): pin the shared validation corpus to every envelope value domain - #2315

Merged
Astro-Han merged 3 commits into
mainfrom
test/core-envelope-value-domains
Aug 6, 2026
Merged

test(core): pin the shared validation corpus to every envelope value domain#2315
Astro-Han merged 3 commits into
mainfrom
test/core-envelope-value-domains

Conversation

@Astro-Han

Copy link
Copy Markdown
Contributor

Summary

#2314 fixed a drift that made every one of an 89-cell benchmark run's Maka trajectories export as a one-line summary: the Harbor exporter re-implements the RuntimeEvent envelope check in Python and had never learned origin or modelVisibility. It closed that class of drift at the key level — the shared validation corpus is now held to runtimeEventEnvelopeKeys(), so a key added to the interface cannot ship without a corpus case, and a corpus case the Python side rejects turns the exporter's silence into a red test.

The same drift is still open one level down. Python spells the closed value domains out again ({"provider", "code_mode"}, {"visible", "hidden"}, the status set), so a member added on the TypeScript side that no corpus case carries leaves the two disagreeing about what is valid with nothing red — and every event carrying that member degrades to a summary exactly as an unknown key did.

Two changes, and the first is what makes the second possible:

  • status already derived its type from RUNTIME_EVENT_STATUSES. origin and modelVisibility were inline unions that the decoder compared against by hand, which left their domains unenumerable: a chain of !== is invisible to anything asking what a field may hold. They now have the same shape as status, and the decoder reads the constants through a shared isOptionalMember in record-schema.ts rather than repeating their members.
  • runtimeEventEnvelopeValueDomains() exports those three domains, and a new test requires an accepted corpus case for every member. branch is free text and has nothing to enumerate, so it does not appear.

The corpus gains the four status members it never carried (streaming, failed, aborted, cancelled) — only completed was ever exercised.

Refs #2314.

Verification

Both halves of the chain proved by reverting, not by reading:

  • Red, TypeScript side: added 'harness' to RUNTIME_EVENT_ORIGINS without touching the corpus → no corpus case carries origin: harness.
  • Red, Python side: narrowed the exporter's modelVisibility set to {"hidden"} → the headless corpus round-trip fails on valid-visible-model-visibility with runtime_event_schema_invalid — the exact degradation fix(headless): teach the trajectory exporter the two envelope fields it never learned #2314 was about, now caught by a test instead of by a benchmark run.
  • Green: @maka/core 799 pass / 0 fail, @maka/headless 1431 pass / 0 fail (includes the Python corpus round-trip), @maka/runtime 3293 pass / 0 fail. npm run lint and npm run format clean.

Not run: desktop E2E and Storybook — this touches no renderer surface.

Review focus

The value-domain test is only as strong as the corpus round-trip it feeds: it guarantees a case exists, and the Python side is what turns that case into a cross-language assertion. It does not reach nested shapes (content, actions, refs), whose domains are still pinned only by the cases someone thought to write.

…domain

Pinning the corpus to the envelope key list closed one half of the drift
that made an 89-cell benchmark run export a one-line summary per cell: a
key nobody wrote a case for. The other half was still open — a value
nobody wrote a case for. The Harbor exporter spells `origin`,
`modelVisibility` and `status` out again in Python, so a member added on
this side that no corpus case carries leaves the two disagreeing about
what is valid with nothing red.

`status` already derived its type from a runtime constant; `origin` and
`modelVisibility` were inline unions the decoder compared against by
hand, which made their domains unenumerable — a chain of `!==` is
invisible to anything asking what a field may hold. Give them the same
shape as `status`, have the decoder read the constant through a shared
`isOptionalMember`, and hold the corpus to what those constants contain.

The corpus gains the four `status` members it never carried.
`role` and `author` are closed envelope domains that the Python exporter
spells out too, so leaving them out of the map made the invariant false
where it was stated: three of five domains were pinned.

The holes were real, not hypothetical. The corpus never carried `role`
or `author` as `tool` or `system`, and events with `role: tool` are among
the most common a run emits — narrowing the exporter's role set to drop
it degrades a real event stream to a summary, and nothing was red.
@Astro-Han
Astro-Han marked this pull request as ready for review August 6, 2026 07:11
@Astro-Han
Astro-Han merged commit 3391a00 into main Aug 6, 2026
12 checks passed
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