Skip to content

fix: stop --append-agent-note duplicating @agent-note past body text - #75

Merged
fohara merged 1 commit into
mainfrom
fix/append-agent-note-duplicate-74
Aug 30, 2026
Merged

fix: stop --append-agent-note duplicating @agent-note past body text#75
fohara merged 1 commit into
mainfrom
fix/append-agent-note-duplicate-74

Conversation

@fohara

@fohara fohara commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Fixes #74.

Root cause

TaskLines::find_annotation_line in update/mutations.rs searched only the contiguous annotation block directly under the checkbox, stopping at the first non-@ line. The parser is more forgiving: an @key: line found after free-text body lines becomes an orphaned annotation and is merged into the most recent task (parse_task_section_internal). So a note below body text belonged to the task in the parsed model, but the editor couldn't see it — --append-agent-note concluded the task had no note and fell through to the create path, writing a second @agent-note: under the checkbox. Lint then rejected the file as a duplicate annotation, lash index skipped it, and later mutations died on E_INDEX_STALE.

Fix

  • find_annotation_line now scans the task's whole body region — up to the next checkbox line or ## heading, the same boundary that ends the parser's orphan merging.
  • continuation_range handles the orphaned position with a stricter rule (only lines indented deeper than the annotation), so trailing same-indent body text is never swallowed.
  • append_agent_note indents the continuation relative to the found annotation line (unchanged result for the normal in-block case).

This also fixes the same latent duplicate-insert path in --agent-note (replace), --owner/--estimate, and @labels: edits.

Tests

  • Unit tests: append/replace past body text stays a single annotation, lookup doesn't reach into the next task, same-indent trailing body text isn't swallowed.
  • Integration test reproducing the issue verbatim: append lands as a continuation, file stays lint-clean and indexable, and a second append keeps working (no E_INDEX_STALE).

Out of scope

The parser attaches an orphaned annotation as a single line and silently drops its indented continuation lines, so lash show renders only the first line of a note in this position. That predates this fix (the repro's original "Second line" was already invisible) and is a lash-core parsing gap worth its own issue.

…74)

Annotation lookup now scans the task's whole body, mirroring the
parser's orphaned-annotation merge, instead of only the contiguous block.
/// which the parser still attributes to this task).
fn find_annotation_line(&self, key: &str) -> Option<usize> {
let (start, end) = self.annotation_block_range();
let start = self.task_idx + 1;
@fohara
fohara merged commit ae13f63 into main Aug 30, 2026
24 checks passed
@fohara
fohara deleted the fix/append-agent-note-duplicate-74 branch August 30, 2026 19:18
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.

--append-agent-note writes a duplicate @agent-note when body text precedes the note, reporting success

2 participants