Skip to content

clear claude_session_id on recurring task completion#6

Merged
bborbe merged 3 commits into
masterfrom
feature/clear-session-on-recurring
May 31, 2026
Merged

clear claude_session_id on recurring task completion#6
bborbe merged 3 commits into
masterfrom
feature/clear-session-on-recurring

Conversation

@bborbe
Copy link
Copy Markdown
Owner

@bborbe bborbe commented May 31, 2026

Summary

  • Recurring task completion now clears claude_session_id before writing the file
  • New ClearClaudeSessionID() method on TaskFrontmatter (delegates to FrontmatterMap.Delete)
  • Non-recurring task completion is unchanged (claude_session_id is part of the historical record there)
  • Spec: specs/in-progress/015-recurring-task-clears-claude-session-id.md

Why

Daily recurring tasks were inheriting the previous run's session ID. A real vault task had carried the same claude_session_id for ~5 weeks of daily completions — corrupts any tooling that trusts the field to identify the current session.

Test plan

  • make precommit (passes locally)
  • New Describe("ClearClaudeSessionID") in pkg/domain/task_frontmatter_test.go (set+clear path; absent-key no-op)
  • New It("clears claude_session_id after completion") in pkg/ops/complete_test.go recurring-daily context
  • Test asserts Get("claude_session_id") == nil — kills the SetClaudeSessionID("") shortcut
  • Existing non-recurring tests untouched and passing

bborbe added 3 commits May 31, 2026 14:10
Spec 015 / Prompt 136: handleRecurringTask now calls task.ClearClaudeSessionID()
before WriteTask so the next occurrence of a recurring task starts with no stale
session ID. New ClearClaudeSessionID() method on TaskFrontmatter delegates to
FrontmatterMap.Delete. Non-recurring path unchanged.

Test asserts key absence via Get("claude_session_id") == nil so an
empty-string shortcut (SetClaudeSessionID("")) would fail.
…ests

- GoDoc on ClearClaudeSessionID explains why it exists alongside SetClaudeSessionID
  (spec 015 invariant: empty-string setter semantics unchanged)
- New Describe("ClearClaudeSessionID") in task_frontmatter_test.go covers
  the set+clear path and the absent-key no-op path
- Assertion uses Get("claude_session_id") == nil (kills the empty-string shortcut)
Copy link
Copy Markdown

@ben-s-pull-request-reviewer ben-s-pull-request-reviewer Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Review Report: clear claude_session_id on recurring task completion

Files Changed

  • CHANGELOG.md — release note for the bugfix
  • pkg/domain/task_frontmatter.go — adds ClearClaudeSessionID() method
  • pkg/domain/task_frontmatter_test.go — direct unit tests for the new method
  • pkg/ops/complete.go — calls ClearClaudeSessionID() in handleRecurringTask
  • pkg/ops/complete_test.go — integration test verifying the key is absent post-completion

Must Fix (Critical)

None.

Should Fix (Important)

  1. pkg/domain/task_frontmatter.go:177, 234, 430 — Three errors.Wrapf calls use no format placeholder:

    • Line 177: errors.Wrapf(ctx, validation.Error, "unknown task phase '%s'", value)%s appears twice in the string literal but is not a printf placeholder; the value argument is passed but ignored.
    • Line 234: errors.Wrapf(ctx, err, "invalid priority") — same issue, no format args.
    • Line 430: errors.Wrapf(ctx, validation.Error, "unknown task status '%s'", value) — same.

    Fix: use errors.Wrap(ctx, ...) or fix the format string. (Pre-existing issue in unchanged code, not introduced by this PR but flagging per guidelines.)

Nice to Have (Optional)

None.


Plan Concerns — Resolved

Concern Resolution
ClearClaudeSessionID() delegates to Delete() — verifies Get() returns nil (absent) not "" (present-but-empty) ✅ Confirmed: Delete removes the key; Get returns nil for absent keys. Test uses Get() not ClaudeSessionID() — correct.
ClearClaudeSessionID() only in handleRecurringTask, not in non-recurring paths ✅ Only handleRecurringTask (line 169) exists in this file. No handleNonRecurringTask or handleSingleTask to worry about.
Test sets session ID before calling Complete BeforeEach at line 276 calls task.SetClaudeSessionID("test-session-uuid") before JustBeforeEach — not vacuous.
SetClaudeSessionID("") redundancy after this change SetClaudeSessionID("") stores "" as a value (key present); ClearClaudeSessionID() deletes the key. Distinct semantics, no conflict.

Verdict

{
  "verdict": "approve",
  "summary": "The feature is well-implemented: ClearClaudeSessionID() uses Delete() (not Set+empty) so Get() returns nil, the call is correctly scoped to handleRecurringTask only, tests verify both presence and absence paths, and the GoDoc clearly distinguishes key-removal semantics from store-empty-string. Three pre-existing errors.Wrapf calls without format placeholders exist in the file but are not introduced by this changeset.",
  "comments": [
    {
      "file": "pkg/domain/task_frontmatter.go",
      "line": 177,
      "severity": "major",
      "message": "errors.Wrapf: format placeholder '%s' appears in the string literal but is not a printf directive; 'value' argument is passed but ignored. Use errors.Wrap(ctx, validation.Error, \"unknown task phase '\"+value+\"'\") or fmt.Errorf. (Pre-existing, not introduced by this PR.)"
    },
    {
      "file": "pkg/domain/task_frontmatter.go",
      "line": 234,
      "severity": "major",
      "message": "errors.Wrapf: no format arguments provided to a Wrapf call. Use errors.Wrap(ctx, err, \"invalid priority\"). (Pre-existing, not introduced by this PR.)"
    },
    {
      "file": "pkg/domain/task_frontmatter.go",
      "line": 430,
      "severity": "major",
      "message": "errors.Wrapf: same issue as line 177 — '%s' in the string literal is not a printf placeholder; 'value' argument is passed but unused. Use errors.Wrap or fix the format string. (Pre-existing.)"
    }
  ],
  "concerns_addressed": [
    "correctness: ClearClaudeSessionID() uses Delete() — Get() returns nil (absent), not \"\" (present-but-empty); test assertion uses Get() which is correct",
    "correctness: ClearClaudeSessionID() is only called from handleRecurringTask; no handleNonRecurringTask or handleSingleTask exists to pollute",
    "tests: BeforeEach sets session ID via SetClaudeSessionID() before JustBeforeEach calls Complete — not a vacuous pass",
    "correctness: SetClaudeSessionID(\"\") keeps store-empty semantics; ClearClaudeSessionID() uses Delete(); distinct methods, no redundancy"
  ]
}

@bborbe bborbe merged commit 093c2a7 into master May 31, 2026
2 checks passed
@bborbe bborbe deleted the feature/clear-session-on-recurring branch May 31, 2026 12:52
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.

1 participant