refactor(code-runtime-python): export PROTOCOL_FD and tidy the mirror binding

Address the remaining review findings on the wire-mirror layer:

- Export PROTOCOL_FD from protocol.ts as the TS-side source of truth the host
  wires, and assert the Python constant against it in the mirror e2e instead of
  a bare literal 3, so an fd drift on either side is caught.
- Correct the FrameFieldRoles JSDoc to point at the actual assertion site
  (WIRE_FRAME_FIELD_ROLES's satisfies clause, not WIRE_FRAME_FIELDS).
- Drop the redundant explicit type annotation on WIRE_FRAME_FIELDS (the trailing
  `as` cast already types it; Object.fromEntries returns an index signature).
- Refresh the mirror-test comment to describe the roles-map binding (a TS-side
  add/remove/rename/optionality-flip fails typecheck; a Python-side change fails
  the comparison).
This commit is contained in:
Chinesezjc
2026-08-07 13:27:54 +08:00
parent adba2e305a
commit 4de8c914c9
2 changed files with 26 additions and 19 deletions
@@ -6,10 +6,16 @@
* @module @deepseek-ai/dsh-code-runtime-python/src/protocol
*/
// The protocol channel is fd 3 from the child's perspective — the host pins it
// positionally via `stdio: ['pipe','pipe','pipe','pipe']` when it spawns the
// child, and the Python bootstrap reads the same constant from its own
// protocol.py.
/**
* The framed-JSON channel's file descriptor from the child's perspective. The
* host pins it positionally when it spawns the child (`stdio` index 3, i.e.
* `['pipe','pipe','pipe','pipe']`), and the Python bootstrap reads the same
* number from its own `protocol.py`. Exported as the single TS-side source of
* truth: the host wiring uses it, and the cross-language mirror test asserts the
* Python constant equals it, so a drift on either side breaks the boot channel
* loudly rather than silently.
*/
export const PROTOCOL_FD = 3
/**
* One binding namespace declaration inside a {@link BootMessage}. `global` is
@@ -157,10 +163,10 @@ type OptionalKeys<T> = { [K in keyof T]-?: object extends Pick<T, K> ? K : never
* Because it is `Record<keyof T, …>`, an entry MUST list every key — a field
* added to the interface without a corresponding entry fails typecheck — and
* `keyof T`-typed keys reject a name no frame declares. The `'required'` /
* `'optional'` tag must match the field's actual optionality (checked by
* {@link WIRE_FRAME_FIELDS}'s per-entry assertions), so an optionality flip is
* caught too. This is the exhaustive counterpart the array form could not
* express (a subset array satisfied it silently).
* `'optional'` tag must match the field's actual optionality (checked by the
* `satisfies FrameFieldRoles<…>` clause on {@link WIRE_FRAME_FIELD_ROLES}), so
* an optionality flip is caught too. This is the exhaustive counterpart the
* array form could not express (a subset array satisfied it silently).
*/
type FrameFieldRoles<T> = Record<RequiredKeys<T>, 'required'> & Record<OptionalKeys<T>, 'optional'>
@@ -209,7 +215,7 @@ const WIRE_FRAME_FIELD_ROLES = {
* field add, remove, rename, or optionality flip fails typecheck at the roles
* map, and a Python-side divergence fails the mirror test at runtime.
*/
export const WIRE_FRAME_FIELDS: Record<keyof typeof WIRE_FRAME_FIELD_ROLES, { required: string[]; optional: string[] }> =
export const WIRE_FRAME_FIELDS =
Object.fromEntries(
Object.entries(WIRE_FRAME_FIELD_ROLES).map(([frame, roles]) => {
const required = Object.keys(roles).filter(key => (roles as Record<string, string>)[key] === 'required').sort()
@@ -3,7 +3,7 @@ import { existsSync } from 'node:fs'
import { fileURLToPath } from 'node:url'
import { promisify } from 'node:util'
import { describe, expect, it } from 'vitest'
import { logTruncationMarker, WIRE_FRAME_FIELDS } from '../src/protocol.ts'
import { logTruncationMarker, PROTOCOL_FD, WIRE_FRAME_FIELDS } from '../src/protocol.ts'
/**
* Cross-language mirror check between `src/protocol.ts` and `py/protocol.py`,
@@ -47,9 +47,9 @@ describe.skipIf(!python3Available)('protocol.py mirrors protocol.ts at runtime',
].join('\n')
const { stdout } = await execFileAsync('python3', ['-I', '-c', probe])
const seen = JSON.parse(stdout) as { fd: number; markers: string[] }
// fd 3 is the wire contract, not a tunable: the host pins it positionally
// when it spawns the child.
expect(seen.fd).toBe(3)
// Assert against the TS-side PROTOCOL_FD export (the value the host wires),
// not a bare literal, so a drift on either side of the wire is caught here.
expect(seen.fd).toBe(PROTOCOL_FD)
expect(seen.markers).toEqual(budgets.map(budget => logTruncationMarker(budget)))
})
@@ -57,12 +57,13 @@ describe.skipIf(!python3Available)('protocol.py mirrors protocol.ts at runtime',
// Turn the TypedDict mirror from a review-only obligation into an executable
// check: enumerate EVERY TypedDict in py/protocol.py (public names carrying
// __required_keys__) and assert both the frame roster and each frame's
// required/optional key sets against WIRE_FRAME_FIELDS — the TS-side source
// of truth bound to the frame interfaces by `satisfies` in protocol.ts.
// Together this catches drift on EITHER side of the wire: a TS rename or
// optionality flip breaks typecheck; a Python frame added, removed, or with
// a changed field set breaks this comparison. `global` is the reserved-
// keyword wire key the Python side carries via a functional TypedDict.
// required/optional key sets against WIRE_FRAME_FIELDS — projected from the
// WIRE_FRAME_FIELD_ROLES map that `satisfies` binds exhaustively to the
// frame interfaces in protocol.ts. Together this catches drift on EITHER
// side of the wire: a TS-side field add, remove, rename, or optionality flip
// fails typecheck at the roles map; a Python frame added, removed, or with a
// changed field set fails this comparison. `global` is the reserved-keyword
// wire key the Python side carries via a functional TypedDict.
const probe = [
'import json, sys',
`sys.path.insert(0, ${JSON.stringify(pyDir)})`,