Repository navigation
session-format-v3-to-v4 refuses valid sessions: system/message must not be required to be the first surface node #8888
Paimonshen
started this conversation in
General
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Describe the bug and which rule is wrong.
Package:
@deepseek-ai/dsh-session-format-v3-to-v4(packages/session/session-format-v3-to-v4/src/relationships.ts,foldSurface)foldSurfacerefuses anysystem/messagethat does not become the very first surface node of the whole log:protectedHeadis assigned only when asystem/messageis appended onto a then-empty surface. So the guard fires for everysystem/messagepreceded by any other surface node — a session whose model-visible history starts with auser/messageand whose firstsystem/messagearrives later cannot migrate, permanently, with no user-side recovery.The native rule in
@deepseek-ai/dsh-session(packages/core/session/src/surface.ts,assertSystemHeadRewrite) protects the system prompt positionally at node 0, and only while that node holds asystem/message. It guards replacements only, and requires nothing about what node 0 is:The package README already states the intended behaviour ("The protected first system head can be replaced only by one system message covering exactly that head"), so this looks like an implementation that drifted from its own documented rule.
Minimal reproduction
In a valid open turn and step:
Real case: an imported 26,124-event V3 history whose first
system/messageis at seq 2337, with 995 surface nodes ahead of it. The artifact itself is fine — native V4foldSurfaceaccepts the migrated result (1,091 final surface nodes).Suggested change
system/messageis an ordinary appended surface nodefirst === 0) rather than node identitysystem/messagethat reaches node 0 through a replacementA replacement still may not shadow a real node 0 system head, and a promoted head gains that protection — which the current identity check silently loses, so this also fixes the opposite direction.
Note this changes documented, tested behaviour:
tests/relationships.spec.tscurrently asserts that[turn/start, step/start, user/message, system/message]must throw, which is the mis-encoded rule.Two related copies worth knowing about
dsh-session-persistence-jsonlbundles its own copy.lib/worker.cjsis a full independent copy of the format code, loaded withnew Worker(new URL('./worker.cjs', import.meta.url))(lib/index.js:1446-1493). It carries its own instance of this same guard, so patching the migration package alone has no effect on the worker path — a test that imports the package exercises a different code path than production.session-format-v2-to-v3/src/validation.ts:43has the same over-strict idea, plus two extra invariants that re-keyheadthroughreplace.startSeq/endSeq. Removing the guard there without re-derivingheadpositionally was measured over 141 stored sessions and broke 125 of them, so the v3→v4 edit cannot simply be transplanted. It needs a separate fix.Relationships.spanalso still guards compaction against the system head, while native V4 does not treatcompaction/*as surface-eligible at all.I have a validated fix for the v3→v4 edge (3,168 session tests pass, typecheck and lint clean) but could not open a PR — CONTRIBUTING.md states external pull requests are not accepted at the moment. Happy to provide the patch if that is useful.
All reactions