Skip to content

fix(memory-ingest): --include-unattributed is inert — apply the fallback to page.git_remote (#2353) - #2371

Open
noron12234 wants to merge 1 commit into
garrytan:mainfrom
noron12234:fix/2353-unattributed-guard
Open

fix(memory-ingest): --include-unattributed is inert — apply the fallback to page.git_remote (#2353)#2371
noron12234 wants to merge 1 commit into
garrytan:mainfrom
noron12234:fix/2353-unattributed-guard

Conversation

@noron12234

Copy link
Copy Markdown

Fixes #2353.

Root cause

buildTranscriptPage applies the _unattributed fallback in two of the three
places it computes it, and the one it skips is the one the guard reads:

const remote = resolveGitRemote(session.cwd);   // "" when the remote can't be resolved
const slug_repo = repoSlug(remote);             // → "_unattributed"

`git_remote: ${remote || "_unattributed"}`,     // :729 frontmatter — defaulted

git_remote: remote,                             // :750 page record — RAW
if (!args.includeUnattributed && page.git_remote === "_unattributed") {   // :1173

page.git_remote is "", so the comparison is never true, the branch is dead, and
--include-unattributed has no effect in either direction. The earlier !session.cwd
guard doesn't cover it — these sessions have a cwd, it just no longer resolves to a
remote (deleted directories, ephemeral worktrees).

buildArtifactPage already stores the defaulted value (git_remote: slug_repo, :787),
so this is the transcript builder catching up.

Fix

One line, plus a comment noting the guard depends on it:

git_remote: remote || "_unattributed",

Taking the fix at the source rather than loosening the guard to !page.git_remote || … === "_unattributed" keeps the field consistent with the frontmatter and the slug,
which is what buildArtifactPage already does.

Verification

Reproduced with a real session JSONL whose cwd is a directory that isn't a git repo,
run through --bulk --no-write:

written skipped (unattrib)
before 1 0
after 0 1
after, --include-unattributed 1 0
after, cwd is a repo with a remote 1 0

Three regression tests added to test/gstack-memory-ingest.test.ts, in the existing
runScript / writeClaudeCodeSession style. Confirmed they actually bite — reverting
just the one-line change makes the first one fail:

(fail) unattributed skip > skips a session whose cwd is not a git repo
Expected to contain: "written:               0"
Received: "… written:               1 … skipped (unattrib):    0 …"

Suites run clean with the fix in place:

bun test test/gstack-memory-ingest.test.ts                  26 pass  0 fail
bun test test/memory-ingest-no-put_page.test.ts \
         test/memory-ingest-timeout.test.ts \
         test/gstack-memory-helpers.test.ts                 34 pass  0 fail

Note on scope

The issue also suggests recovering attribution from the Claude Code project-directory
encoding rather than discarding it. That's a behaviour change with its own design
questions, so it's left out — this PR only makes the existing flag do what it says.

…te (garrytan#2353)

buildTranscriptPage wrote the raw resolveGitRemote() result into
page.git_remote while the frontmatter and repoSlug both applied the
"_unattributed" fallback. The skip guard reads page.git_remote, so
`"" === "_unattributed"` was never true and --include-unattributed
was inert: every session whose repo could not be resolved got imported
regardless of the flag, and skipped_unattributed always reported 0.

buildArtifactPage already stores the defaulted value (slug_repo); this
brings the transcript builder in line.

Adds three regression tests: non-git cwd is skipped by default, imported
with --include-unattributed, and a cwd that does resolve is unaffected.
@trunk-io

trunk-io Bot commented Jul 28, 2026

Copy link
Copy Markdown

Merging to main in this repository is managed by Trunk.

  • To merge this pull request, check the box to the left or comment /trunk merge below.

After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

--include-unattributed is inert: the skip guard compares "" against "_unattributed", so unattributable sessions always import

1 participant