Re-record the session-snapshot README bilingual pairing sidecar, and admit
the source-reference regression fixture with the v4 producer-owned `user`
message source kind.
Session V4 reserves developer-role messages for incremental model-visible
session changes. The role, tool addition/removal blocks, and deferred-loading
marker need a durable representation before independent provider and UI
integrations can emit or consume them. Known developer events must match an
open turn and step; unsupported providers and UI consumers fail explicitly.
Request headers already capture full tool definitions. Persisting another
ToolSchema in each addition would duplicate Session information and create
two definitions that could drift. Additions therefore store toolName, and
the containing developer event uses headerSeq to select one earlier known
request/header for all its additions. A same-name replacement keeps its
historical definition identity through restart, fork and surface changes.
Removals require no definition copy, and ordinary developer messages omit
headerSeq. Generic sourceEventSeqs remains independent derivation metadata.
The rejected inline tool field is optional never with @persistenceReserved.
The schema extractor retains that uninhabited slot, so permitting a future
value requires a format bump instead of being mistaken for compatible
optional metadata. Unrelated optional fields remain additive and readable.
Native and Session admission reject missing, forward, non-header, unknown,
ambiguous and incomplete referenced definitions, and reject the retired
inline tool field. Validate complete schema fields only for referenced
definitions, preserving unrelated header behavior and extra JSON metadata.
Unknown ignorable records remain opaque. Empty developer nodes retain their
surface position without producing a message or shadowing the system head.
No automatic emitter, provider activation, UI implementation, or speculative
public resolver is added.
Keep the core-owned developer source binding beside the introduced role,
including the request-only type rejection and attribution round trips. Update
consumer guards, SDK/snapshot handling, bilingual owner documentation, and
the same unreleased V4 acknowledgement. Keep earlier tool/source migration
work and its documentation in the parent. Preserve the existing recorded
Cordis inspection generation from the original developer change.
Integration keeps the final source layer as the sole parent and preserves
master's Messages input filtering, empty-user omission, empty tool results,
and system-update placement. Developer/deferred guards still run before
conversion. Native V4 admission, header references, reservation declarations,
and generic tooling match the validated marker candidate. Parent-owned
fixture and generator fixes remain in the parent.
Earlier feature validation passed full build, full lint, 41 doc-sync gates,
and 16 hygiene gates. The unchanged native implementation retains that evidence.
The focused Session/V4/request-input run passes 884 tests across 38 files with
100% statement, branch, function and line coverage for the V3-to-V4 package
and Session surface. Consumer tests pass 482 with one existing skip; tool,
message and optional-field tests pass 146. Cordis inspection and compaction
replays pass in both source and built modes (two cases per mode). Ten invalid
referenced-definition/unknown-header controls failed before their scoped
guards and pass after them.
Reservation validation: the actual generated developer root records tool as
optional primitive never. Widening it requires a bump, while traceId remains
additive and preserved; all 85 focused reader/classifier tests pass.
Final-parent validation: 205 tests across eight provider, type, catalog,
Session and native-format files pass. The preserved parent fixture verifies
Messages input-history replay; runtime/declaration and parent-owned-file
comparisons show no loss during the final rebase.
Co-authored-by: Tianyi Cui <[email protected]>
Consolidate the existing in-history capability, loop, UI and artifacts into one baseline. Preserve the reviewed tree so each independently verified correction has a subsequent rationale-rich commit.
Delete the leftover diff3 parent marker and both copies of the obsolete request-header prompt JSDoc. Keep only the current system/message tokenization contract. This is a local comment-only finding; neither oracle behavior nor fixture content changes.
Evidence: git diff --check is clean; focused normalize.spec.ts scrubSystemPrompts test passes (1 selected, 64 skipped). The earlier header-preservation commit intentionally retained this marker so the findings stay independent.
sessionFixtures already selects the highest generation independently for each parent or child role. Filtering its output to files[0] silently exempted every child from prompt and schema fixed points and prompt-before-request ordering. Merge those assertions into the per-role loop and expose the actual checker for focused negative controls without mocking Vitest registration.
The three selected-child controls reject missing system/message, raw prompt text, and raw tool schemas; each resolved incorrectly with the parent-only filter. A positive mixed-generation case proves retained predecessors remain unselected. Correct the two versionless record-suite child fixtures that the restored enforcement exposes, including the retired-child copy used by recording tests. No released historical generation or broad recording is rewritten.
Evidence: pnpm exec vitest run packages/test-support/session-snapshot/tests/storage-policy.spec.ts packages/test-support/session-snapshot/tests/suite.spec.ts --coverage --coverage.include=packages/test-support/session-snapshot/src/suite.ts: 143 pass, one intentional record-mode skip, suite.ts 100% statements/branches/functions/lines. Update and re-record the session-snapshot README EN/ZH pair.
Remove both unconditional header.system erasures from log normalization and replay comparison encoding, including the unrelated Session-header deletion. The catalog owns released-format migration; comparison must not turn an unexpected field into equality or supply a compatibility shim.
Add direct log/snapshot and catalog-restoration controls that retain unexpected request/header.system and differ from the field-absent fixture. Preserve malformed provenance data as well, closing the owned normalizer coverage gap. Update the two package README pairs with this oracle obligation.
Evidence: pnpm exec vitest run packages/test-support/session-snapshot/tests/normalize.spec.ts packages/test-support/llm-replay/tests/llm-replay.spec.ts --coverage --coverage.include=packages/test-support/session-snapshot/src/normalize.ts --coverage.include=packages/test-support/llm-replay/src/index.ts: 205 tests pass, both files 100% statements/branches/functions/lines. Direct normalizer negative control fails before the fix. Baseline diff3 comment remains untouched for the separate cleanup finding.
Consolidate the representation-change PR and its rebase reconciliations into one baseline. Preserve the exact tree and keep the in-history feature in the dependent PR. Follow-up fixes remain separate.
`session[.vN].jsonl` was assembled independently by the JSONL provider
(twice), the session-log export archive, and the recorded-session fixture
helpers. `dsh-session-format` now owns `sessionFormatLogFilename` and
`parseSessionFormatLogFilename`; the three consumers append only their
compression suffix, and the migration note names the owner.
`snapshotSessionFormatJson` re-implemented the lossless JSON walk that
`dsh-util-values` already publishes as `snapshotJsonValue` + `deepFreeze`,
and the frozen v0 relationship validator carried a third structural JSON
comparison next to `deepEqualJson`. Both now delegate; the format package
reports one `is not lossless JSON` diagnostic per labelled subject instead
of ten member-specific ones, and enumerable accessors whose values survive
a JSON round trip are accepted like `JSON.stringify` accepts them.
The package exported six functions, four of them shaped by one SDK's
transport each: a dispatcher factory, a `node:http` agent factory, a
proxy-URL lookup, and a policy accessor. Review asked whether the call
sites could converge instead of the package growing an export per SDK.
They could, and each removal took a whole shape with it:
- The OTLP exporter moves to the SDK's `fetch` delegate, retiring
`createNodeHttpAgent`. Its Node-version floor goes too: `proxyEnv` on
an `http.Agent` needs 22.21 or 24.5, inside the engines range, so
telemetry was direct on 22.19, 22.20, and 24.0-24.4. The cost is
`compression`, a Node-transport option; the plugin now refuses it,
`keepAlive`, and `httpAgentOptions` at load instead of ignoring them.
- `web-fetch-http` builds its own address-pinning agent under an
annotated `proxy-exempt:` exemption, retiring `createDispatcher`.
Pinning is per-request state a process-wide dispatcher cannot hold.
- E2B reads `route.proxy`, retiring `proxyUrlFor`.
What remains is `installProxyFromEnvironment`, `proxyRouteFor`,
`proxyEnvironmentForChild`, and `clearedProxyEnv` — one per way a caller
can need the policy. Installation absorbs resolution and diagnostic
reporting, which no caller needed apart.
`proxyRouteFor` also closes a defect the old accessor made expressible:
`web-fetch-http` read the policy to decide whether to pin, then read it
again to build a transport, so an unmount between the two returned a
direct, unpinned agent for a URL the first read had cleared as proxied.
A route carries the answer and the transport that answer assumed.
Every egress spec now installs through `installProxyFromEnvironment`, so
no test asserts a policy object a real launch could not produce.