stacklok / stacklok/mecatl

import: batch Claude Code / Codex session discovery (--days, dedup, skip-existing)

Open
#412 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

devex enhancement
Dominant language
Go
Stars
152
Forks
16
Avg merge
14h 48m
Merged PRs (30d)
536

Description

import: batch Claude Code / Codex session discovery (--days, dedup, skip-existing) — with the compact-summary and retention questions settled first

Sub-issue of the portability epic (#410) — see the parent for the shared artefact map and inherited
boundaries (no secrets, offline, ADR 0099's write guards, trust posture).

Follow-up to ADR 0099 / cmd/mecated/import.go.
Technically independent, but should land after sub-issue A so discovery has one home.

Problem

mecated import takes exactly one transcript path the operator must locate by hand under
~/.claude/projects/<mangled-workspace-path>/<uuid>.jsonl. Nobody browses that tree. The
practical effect is that history migration is a documented capability almost no one performs.

What batch mode needs — and the four questions that must be answered in the issue

1. Dedup key. mintImportID falls back to sha256(transcriptPath) when the transcript
carries no external id (import.go:181-198). A moved or copied file
therefore mints a different session id — duplicates, not dedup. Batch mode must key on the
transcript's own sessionId (already extracted into Transcript.ExternalID,
transcript.go:158) and skip, not
path-hash, when it is absent.

2. Re-run semantics. performImport currently hard-errors when the id already exists
(import.go:209-210). Over a 30-day sweep that means the second run
fails on the first already-imported session. Batch mode needs explicit skip-existing
(counted and reported), preserving the single-import command's error as-is — a re-import must
never overwrite a session the user has since continued in mecatl.

3. Compact summaries — the payload problem. parseClaudeCode skips isSidechain,
isMeta and isCompactSummary records (transcript.go:155).
For a long, compacted session the surviving text is the post-compaction tail; the history the
user actually wants lives in the summary record that gets dropped. So the sessions most worth
migrating import the emptiest. Decide and document one of:

  • admit isCompactSummary as assistant/system-neutral text (it is model-authored prose, not
    a provider-private record — arguably outside ADR 0099's exclusion rationale), or
  • keep dropping it and skip the session with a reported reason rather than importing a
    misleadingly thin shell.
    Either is defensible; silently importing the shell is not.

4. Context budget on resume. There is no token seeding or compaction at import — a large
transcript enters verbatim as text. Bound it (size/turn cap with a reported truncation, or
seed the store's token metadata so the first resume compacts) instead of discovering the
limit on the user's first prompt.

Privacy and retention (must be stated, not assumed)

Importing 30 days duplicates plaintext conversations — which routinely contain pasted
credentials and customer data — into a second plaintext store. Compounding it: mecated's
main-session retention is off by default (docs/usage/configuration.md), so imported
sessions never age out. Requirements:

  • Default the sweep window narrow (--days default 7, not 30) and require the flag to widen.
  • Print the destination and its 0700 posture in the summary; state plainly that raw
    conversation text is being copied.
  • Recommend/verify a retention interaction: imported main sessions should be sweepable, so
    --main-retention is not silently bypassed for a class of sessions the user did not author
    in mecatl.

Acceptance

  • mecated import --from claude-code --all --days 7 --store-dir <dir> discovers transcripts
    under ~/.claude/projects/**, imports one session each, and reports
    imported / skipped-existing / skipped-with-reason counts.
  • Re-running the same command is a no-op: same report, no new sessions, no error, and any
    session continued in mecatl since the first run is untouched (asserted by test).
  • Two copies of the same transcript at different paths produce one session.
  • A transcript whose only history is a compact summary follows the decided rule (imported with
    the summary, or skipped with a reason) — locked by a test either way.
  • An oversized transcript is bounded, and the bound is reported rather than silent.
  • Sidechain-only files (subagent transcripts) are not imported as top-level sessions.
  • ADR 0099 amended with the batch semantics, the compact-summary decision, and the retention
    interaction; docs/usage/mecated.md updated.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start at cmd/mecated/import.go and internal/adapter/agentimport/transcript.go, then read ADR 0099 and the referenced retention documentation. Resolve the stated deduplication, re-run, compact-summary, context-budget, and retention questions before implementing the batch entry point. Done means the acceptance cases pass and ADR 0099 plus docs/usage/mecated.md describe the resulting behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
cli, documentation
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.