clear claude_session_id on recurring task completion#6
Merged
Conversation
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)
There was a problem hiding this comment.
PR Review Report: clear claude_session_id on recurring task completion
Files Changed
CHANGELOG.md— release note for the bugfixpkg/domain/task_frontmatter.go— addsClearClaudeSessionID()methodpkg/domain/task_frontmatter_test.go— direct unit tests for the new methodpkg/ops/complete.go— callsClearClaudeSessionID()inhandleRecurringTaskpkg/ops/complete_test.go— integration test verifying the key is absent post-completion
Must Fix (Critical)
None.
Should Fix (Important)
-
pkg/domain/task_frontmatter.go:177, 234, 430— Threeerrors.Wrapfcalls use no format placeholder:- Line 177:
errors.Wrapf(ctx, validation.Error, "unknown task phase '%s'", value)—%sappears twice in the string literal but is not a printf placeholder; thevalueargument 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.) - Line 177:
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"
]
}
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.
Summary
claude_session_idbefore writing the fileClearClaudeSessionID()method onTaskFrontmatter(delegates toFrontmatterMap.Delete)specs/in-progress/015-recurring-task-clears-claude-session-id.mdWhy
Daily recurring tasks were inheriting the previous run's session ID. A real vault task had carried the same
claude_session_idfor ~5 weeks of daily completions — corrupts any tooling that trusts the field to identify the current session.Test plan
make precommit(passes locally)Describe("ClearClaudeSessionID")inpkg/domain/task_frontmatter_test.go(set+clear path; absent-key no-op)It("clears claude_session_id after completion")inpkg/ops/complete_test.gorecurring-daily contextGet("claude_session_id") == nil— kills theSetClaudeSessionID("")shortcut