Skip to content

fix: parse machine tags only from the trailing tag region (#9) - #10

Merged
budhash merged 1 commit into
mainfrom
fix/anchor-tag-parsing
Jul 1, 2026
Merged

budhash merged 1 commit into
mainfrom
fix/anchor-tag-parsing

Conversation

@budhash

@budhash budhash commented Jul 1, 2026

Copy link
Copy Markdown
Owner

Fixes #9.

Problem

Machine tags (@milestone=, @deps=, @tags=, …) were extracted by scanning the whole item line, so a @key=value that merely appears in a task's descriptive title was parsed as a real tag. Reported for @milestone=:

  • milestone rollup showed a phantom bucket for a milestone mentioned only in prose.
  • migrate-tags-to-milestone treated such a task as an already-assigned conflict and skipped it — which is exactly what happens to the task that tracks the migration itself.

The write path had the same class of bug: set/link would re.sub a look-alike @key=value out of the title prose.

Fix

Anchor tag parsing/editing to the trailing contiguous run of recognized @… tokens after the title:

  • split_item_tags(rest) -> (title, tag_tokens) — only the trailing run of known @name=value / @shadow tokens counts as tags.
  • Reads (_get_tag_value, get_all_items) and edits (_set_single_tag, _set_or_remove_tag) now operate on that region only.
  • Whitespace normalization matches how the tool already writes tags, so tool-managed lines are byte-identical — no migration, no churn.

Verification

  • New e2e scenario 48 reproduces milestone rollup / migrate parse @milestone= from task prose, not the tag position #9 end to end (rollup, list --milestone filter, show, migrate not-skipped, and title preserved on write).
  • make check green: 243 assertions, 0 failures; smoke OK; Python 3.8-safe; single file, zero deps.
  • Re-verified against taxjot's real file: the prose @milestone=<id> no longer creates a phantom bucket; the rollup shows only real milestones + default.

Notes

  • @shadow detection is intentionally left whole-line: it's a system-only flag never typed in prose, and it's central to the heavily-tested shadow machinery.
  • Patch release: __version__ 1.1.0 → 1.1.1; CHANGELOG + schema updated.

Tag extraction and editing scanned the whole item line, so a `@key=value`
mentioned in a task's descriptive title (e.g. a task titled after the
`@tags=… → @milestone=…` migration) was parsed as a real tag. This miscounted
such a task into a phantom `milestone` bucket, and made
`migrate-tags-to-milestone` treat it as an already-assigned conflict and skip it.

Anchor tag parsing to the trailing contiguous run of recognized `@…` tokens
after the title:

- split_item_tags() splits an item's rest into (title, trailing tag tokens);
  reads (_get_tag_value, get_all_items) and edits (_set_single_tag,
  _set_or_remove_tag) now operate on that region only. Whitespace normalization
  matches how the tool already writes tags, so tool-managed lines are unchanged.
- Fixes the write path too: set/link no longer strip a look-alike @key=value out
  of the title prose.
- Docstring + schema note the trailing-region rule. version 1.1.0 -> 1.1.1.
- New e2e scenario 48 reproduces the issue (rollup, list filter, show, migrate,
  and title-preservation on write).
@budhash
budhash merged commit 63760d5 into main Jul 1, 2026
5 checks passed
@budhash
budhash deleted the fix/anchor-tag-parsing branch July 1, 2026 23:11
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.

milestone rollup / migrate parse @milestone= from task prose, not the tag position

1 participant