Skip to content

fix: NOD-002 envelope enforcement parity (TypeScript mirror) - #46

Merged
mrnicholasbcarter-code merged 9 commits into
masterfrom
fix/nod002-canonical-parity-ts
Aug 21, 2026
Merged

fix: NOD-002 envelope enforcement parity (TypeScript mirror)#46
mrnicholasbcarter-code merged 9 commits into
masterfrom
fix/nod002-canonical-parity-ts

Conversation

@mrnicholasbcarter-code

Copy link
Copy Markdown
Owner

NOD-002 / ADR-025 — TypeScript cross-runtime ExecutionEnvelope enforcement parity

The Python contracts.py is the source of truth; the TypeScript Zod schema in @bodanglin/verdict-contracts mirrors it. This PR adds the verdict-node side of the parity gate.

What's here

  • test_fixtures/envelopes/*.json — 1 valid + 13 invalid canonical-shape fixtures, byte-identical to verdict-core's test_fixtures/envelopes/ (canonical shape: eligibility_decision / execution_constraints, not the divergent source_state / budget_usd shape from an earlier draft).
  • scripts/envelope-parity-verdicts.mjs — emits JSON accept/reject verdicts via the canonical Zod schema (parseContract('execution_envelope')).
  • scripts/envelope_parity_verdicts.py — Python counterpart using ExecutionEnvelope.from_dict.
  • tests/contract-parity.test.ts — jest assertions mirroring Python tests/test_envelope_parity.py (verdict + error substring per fixture).
  • src/middleware/forwarder.ts — re-exports the canonical ExecutionEnvelope type from @bodanglin/verdict-contracts.
  • .github/workflows/ci.yml — new contract-parity job: builds the contracts package from verdict-core main and npm links it (the published npm release may lag behind source), diffs TS vs Python verdicts, and asserts the fixture sets match verdict-core's canonical copy.

Published-npm-lag note

The published @bodanglin/verdict-contracts@0.1.0 on npm predates the execution_envelope Zod schema. The CI job therefore builds the contracts package from the verdict-core main checkout and links it, so the TS side always tests against the canonical (source-of-truth) schemas rather than a stale npm release. Locally validated with npm link against the rebuilt dist; all 37 contract-parity jest tests pass.

Pairing

TypeScript counterpart to verdict-core PR #302 (fix: NOD-002 envelope enforcement parity (Python source of truth) [closes #286]). PR #302's CI is fully green including its own typescript-contract-parity job.

Pre-existing failures (not this PR's scope)

The tests/middleware/streaming-field-preservation.test.ts suite has 8 flaky abort/timeout failures on clean master as well (supertest timing), unrelated to envelope enforcement; this PR is scoped to envelope parity only.

refs #286.

Nicholas Carter added 9 commits August 20, 2026 11:42
NOD-002 / ADR-025: cross-runtime ExecutionEnvelope enforcement parity.
The Python contracts.py is the source of truth; the TypeScript Zod schema
in @bodanglin/verdict-contracts mirrors it. This adds a verdict-node CI gate
that fails when the two runtimes disagree on the shared invalid-envelope
fixtures (1 valid + 13 invalid, byte-identical to verdict-core's
test_fixtures/envelopes/).

- test_fixtures/envelopes/*.json: canonical-shape fixtures copied verbatim
  from verdict-core (eligibility_decision / execution_constraints, not the
  divergent source_state / budget_usd shape an earlier draft used).
- scripts/envelope-parity-verdicts.mjs: emits JSON accept/reject verdicts
  via the canonical Zod schema (parseContract('execution_envelope')).
- scripts/envelope_parity_verdicts.py: Python counterpart using
  ExecutionEnvelope.from_dict.
- tests/contract-parity.test.ts: jest assertions mirroring Python
  tests/test_envelope_parity.py (verdict + error substring per fixture).
- src/middleware/forwarder.ts: re-exports the canonical ExecutionEnvelope
  type from @bodanglin/verdict-contracts.
- .github/workflows/ci.yml: new contract-parity job builds the contracts
  package from verdict-core main and links it (the published npm release
  may lag behind the source), then diffs TS vs Python verdicts and asserts
  the fixture sets match verdict-core's canonical copy.

Paired with verdict-core PR #302 (Python source-of-truth enforcement fix).
… 24 for ESM

- clean-install: now builds+links verdict-core contracts package before npm ci,
  so typecheck/lint/build/test all run against source-of-truth Zod schemas
  (which include execution_envelope). The published npm package v0.1.0 is stale.
- contract-parity: Node version bumped to 24.x so --experimental-vm-modules
  supports synchronous ESM module loading (Jest 30 + ts-jest requires this).
- Both jobs verified locally against rebuilt contracts dist; all 37
  contract-parity tests pass.
- lint.yml now clones verdict-core, builds contracts package, links it,
  then runs npm run lint/format:check against source-of-truth schemas.
- Bumps Node to 24.x for consistency with clean-install.
The canonical @bodanglin/verdict-contracts package is pure ESM (type: module).
Jest 30 on Node 24 requires --experimental-vm-modules to synchronously
load ESM dependencies via ts-jest. This updates the test script so all
jest runs (clean-install, contract-parity, local) use the ESM entrypoint.
@mrnicholasbcarter-code
mrnicholasbcarter-code merged commit acd2f4b into master Aug 21, 2026
5 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