Skip to content

autoplan: publication hook never reaches 'ready' when the journal's root record is a SessionStart attachment, not a user message #3009

Closed

Description

@CharlesBerg85

Summary

/autoplan's publication hook never reaches "ready" in sessions whose transcript journal starts with an attachment record (SessionStart hook output) rather than a user message. That's every session in a project with a SessionStart hook. The hook loops on Native parent evidence has not reached the journal yet. and /autoplan can't publish. This is independent of the Windows path issue in #2986, which it would hit even after that fix.

Where (v1.89.0.0)

  • lib/claude-public-transcript.ts, ownedCausalLines (~l.182): requires the journal's null-parent root record to be a user message.
  • The same assumption in readPlanCountTranscript's origin seeding (~l.297, record.parentUuid === null).

Evidence

Current Claude Code journals open with an attachment record (SessionStart hook output) as the null-parent root, with the first user turn beneath it. With a synthetic journal:

  • user-root → status: ready, events: 1
  • attachment-root → status: missing, events: 0

Two real journals, from separate sessions, each had exactly one null-parent root, and it was an attachment.

Possibly related (unverified)

In git-worktree sessions, CLAUDE_PROJECT_DIR may point at the main checkout rather than the worktree, so root.cwd !== projectCwd. Worth checking alongside this.

Suggested fix

Anchor ownership on the first user record beneath a message-free prefix of attachment records (no user or assistant content before it), in both ownedCausalLines and the origin seeding. Add tests for an attachment-rooted journal (with and without multiple leading attachments) next to the existing user-rooted case.

Environment

Windows 11, Git Bash, Claude Code desktop, gstack v1.89.0.0 (still present upstream at the time of filing). Related: #2986 (Windows path normalisation; a one-line path.win32.normalize on the CLAUDE_PROJECT_DIR value fixes that part and was tested locally).

Activity

  1. CharlesBerg85 commented on Oct 1, 2026

    @CharlesBerg85
    ContributorAuthor

    Confirmed on a live Claude Code session journal. The only null-parent record is a type:"attachment" SessionStart hook_success with no message, and the first user prompt sits beneath it. The fix accepts a message-less attachment root only when the first user prompt descends from it, and seeds ancestry through that prompt's chain only. It also widens the competing-roots check: any other root (user or attachment) that carries a user/assistant conversation now counts, while a childless stray attachment root does not. With that fix, plus the #2986 spelling fix, the owned reader returns ready on the real journal.

    On the "possibly related" worktree note: confirmed, and it's a separate blocker. Desktop worktree sessions get the repository root as CLAUDE_PROJECT_DIR while the journal is rooted in the linked worktree. #3010 handles it by verifying git's two-way worktree link.

    Fixed with tests in #3010.

  2. capy-ai commented on Oct 2, 2026

    @capy-ai
    Contributor

    Fixed in v1.91.13.0 (#3013, merged as f30b7b7): a journal whose root record is a SessionStart attachment now reaches 'ready'; ownership anchors on the first user turn under the attachment chain. Run /gstack-upgrade, then start a new Claude Code session. Thanks for the report. Reopen if you still see it after upgrading.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions