Conversation
Extend XERK-101 migration to qwen, the dsh [K] (XERK-475) analogue. The load-bearing difference: qwen is Claude-shaped, so its native log IS the durable store qwen --resume reloads from (no separate store like dsh's). - export_session locates qwen's native log by glob (_qwen_native_log) and packs it under the reserved .qwen-store/ prefix, truncated to its last complete line like the main transcript. - import_session routes it to the single target native-log FILE under the TARGET cwd's slug (_qwen_store_dest, == _project_slug — verified qwen's slug rule is Claude's every-non-alnum->'-'), so qwen --resume in the new worktree finds it; drops it on a claude fallback (no qwen on target). - _reconcile_qwen_store_cwd re-points the cwd carried on every native-log row (qwen keys on cwd, issue #2373) to the localized worktree; no-op on a same-mount move. - _launch_qwen re-validates the carried model against the target's config, falling back to the host default; endpoint/key are always the target's. - Resume (process death / boot-adopt) was already wired by [Qwen B]/[Qwen C] (--resume in place + tail at native EOF); [K] pins it and adds migration. The <slug>/<sid>/qwen/ raw-archive mirror is the display/metrics feed and is NEVER carried (the target rebuilds it) — kept straight from the resumable log. Tests: qwen cases in TestMigrateSession (pack/unpack, stray-drop, cross-mount place+rekey, claude-fallback drop, slug rule, same-mount no-op).
# Conflicts: # .claude/rules/qwen.md
# Conflicts: # .claude/rules/qwen.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Extends XERK-101 session migration + resume to the qwen (Qwen Code) runtime — the dsh [K] (XERK-475) analogue. Parent: XERK-504.
The load-bearing difference from dsh: qwen is Claude-shaped, so its native log (
~/.qwen/projects/<slug>/chats/<id>.jsonl) IS whatqwen --resume <id>reloads from — there is no separate durable store like dsh'sDSH_SESSIONS_ROOT. So a qwen migration carries that native log itself, not a distinct store.Resume (process-death
--resume, boot-adopt) was already wired by [Qwen B]/[Qwen C] (_launch_qwen(resume=True)+ tail at native-log EOF); this ticket pins it. The net-new work is migration.Changes (all in
agent/hub-agent.py)_qwen_native_log(sid)— glob-locate the native log (slug-rule-independent, like_qwen_runtime_file/the tail)._qwen_store_dest(cwd, sid)— target native-log path under the target cwd's slug. Verified: qwen's cwd→slug rule is_project_slug(every non-alnum→-), not the G0 doc's imprecise/→-.export_session— for a qwen session, packs the native log under the reserved.qwen-store/chat.jsonlprefix, truncated to its last complete line (a live log is appended by its process). Un-droppable resumable data — export refuses cleanly overMIGRATION_BLOB_MAXrather than shipping un-resumable.import_session/_unpack_transcript— routes the.qwen-store/*member to the single target file (never a dir — the sharedchats/dir holds other sessions' logs), with the same path-escape hardening as the dsh store. Dropped on a claude fallback (no qwen on target, via the existingagent_type_configuredguard)._reconcile_qwen_store_cwd— re-points thecwdcarried on every native-log row (qwen keys on cwd — upstream issue #2373) from the source to the localized worktree; no-op on same-mount; never raises._launch_qwen— re-validates the carried model against the target host's config (kept only ifQWEN_IDENT_RE-valid, else host defaultQWEN_MODEL); endpoint/key are always the target's.The
<slug>/<sid>/qwen/raw-archive mirror is the display/metrics feed and is never carried by migration (the target rebuilds it) — the [K] correction the ticket names.Verification
TestMigrateSession(pack/unpack round-trip + tail truncation, stray-drop on claude import, cross-mount place+rekey end-to-end, claude-fallback drop, slug-rule pin, same-mount no-op).qaagent): PARTIAL, zero defects, zero security findings. Everything runnable was driven:~/.qwen/projects/logs (incl. thegit/.turma→git--turmacase the G0 rule would break)._unpack_transcriptpath-escape hardening confirmed with hostile tar members (traversal/absolute →ValueError; symlink/dir → skipped; member relpath discarded so no escape)._reconcile_qwen_store_cwdconfirmed across 11 edge cases: rows & fields preserved, unparseable lines kept verbatim, zero raises, correct same-mount no-op.qwen --resumeover the placed+rekeyed log is not runnable in one worktree and qwen isn't in CI — the same footing [Qwen C]/[Qwen E] shipped on. Low-risk residual: reconcile reserializes matching rows (valid JSON, same values), unproven only if qwen does byte-level per-row integrity checks; dsh's analogous header rewrite works against real dsh.Docs
[Qwen K]section added to.claude/rules/qwen.md(32,971 chars, under the 40k cap)..claude/rules/agent-archive.md.