Repository navigation
feat: add first-class milestone dimension - #7
Merged
Merged
Conversation
Add an optional @milestone=<id-or-alias> tag plus an optional # Milestones registry so work can be tagged and rolled up by milestone — without breaking existing TASKS.md files or forcing milestones on projects that don't want them. - Opt-in and backward-compatible: with no milestone data the tool behaves exactly as before; untagged items resolve to an implicit sentinel bucket (default, configurable via TASKS_MILESTONE_SENTINEL, never an M<n> id). The sentinel is never written to task lines, so old files round-trip byte-for-byte. - Optional # Milestones registry maps id -> alias -> status -> title, powering alias resolution (@milestone=alpha == @milestone=m1) and rollups; absent => freeform (grouped by raw value). - CLI: new/set --milestone (set "" clears to the sentinel), list --milestone, next --milestone, a `milestone` rollup + `milestone <id>` detail + `milestone --table` (milestone x features x status), and migrate-tags-to-milestone for the interim @tags=<id> convention. `show` now displays a resolved Milestone line; features and tasks can both carry a milestone (assign existing features with `set F-N --milestone`). - validate warns (exit 0) on an @milestone= value not in the registry when a registry exists; never hard-fails on milestone data. - 10 new e2e scenarios covering the spec's 7 acceptance criteria plus migration, feature assignment, and the table view. Docstring/schema/README/CHANGELOG updated; version 1.0.1 -> 1.1.0.
Address findings from the PR review of the milestone dimension: - migrate-tags-to-milestone no longer silently drops a milestone. A task with a CONFLICTING existing @milestone= is left untouched and reported (not stripped and mis-counted as migrated — that was silent data loss). A redundant tag for the same milestone is dropped. The helper now validates its argument, refuses the sentinel, and prints a distinct message when nothing matched. - milestone rollup/detail now group case-insensitively, matching the list/next filters, so freeform @milestone=Alpha and `milestone alpha` agree. - validate now audits registry health (duplicate ids, colliding aliases, unparseable entries) as warnings. - new/set --milestone print a non-fatal warning when assigning a value absent from an existing registry, so a typo (e.g. m11) is caught at assignment time rather than only by a later validate warning. - milestone errors on ambiguous `milestone <id> --table` / extra positionals; cmd_list pre-initializes its locals; new and set agree on the clear tokens ("", clear, or the sentinel name). - Docs: fix the misleading "alias resolves to its id" example (values are stored verbatim, resolved on read), align "clears to sentinel" wording, change "may not" -> "must not" for the sentinel guard, and document the clear tokens and registry-health warnings. - Tests: 7 new scenarios (41-47) — clear-via-default/clear, freeform no-warn, migrate tag-removal + conflict preservation, zero-task registry milestone, alias case-insensitivity, --table row-association, and registry-health warnings.
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
Adds a first-class milestone dimension so work rolls up to "how close is milestone M<n>?" — while staying 100% backward-compatible with existing
TASKS.mdfiles and with projects that don't use milestones. Implements the acceptance spec (taxjot/docs/process/tasks-milestone-spec.md).What's new
@milestone=<id-or-alias>tag on any feature/task line (mirrors@branch=/@deps=). Absent ⇒ implicit sentinel bucket (default, configurable viaTASKS_MILESTONE_SENTINEL; rejected if it looks like anM<n>id, to avoidset --milestone m1ambiguity). The sentinel is never written to task lines.# Milestonesregistry (its own H1 section) mappingid → alias → status → title. Present ⇒ alias resolution (@milestone=alpha≡@milestone=m1) + rich rollups; absent ⇒ freeform (grouped by raw value).new … --milestone,set T-N --milestone(""clears to sentinel),list --milestone,next --milestone, amilestonerollup,milestone <id>detail,milestone --table(milestone × features × status), andmigrate-tags-to-milestone <tag>for the interim@tags=<id>convention.showdisplays a resolvedMilestone:line.validatewarns (exit 0) on an unknown@milestone=when a registry exists; never hard-fails on milestone data.@system=/@tags=—@systemis not overloaded.Backward compatibility (hard requirement)
TASKS.md(no milestone data):validatepasses, file unchanged,next/list/treeunchanged.@tags=m1on 6 tasks;migrate-tags-to-milestone m1converts them cleanly, preserving their other tags.Testing
make checkgreen:py_compile+ 204 e2e assertions, 0 failures. Python 3.8-safe, zero new dependencies, single file.Re-vendoring note
Version bumped
1.0.1 → 1.1.0. Sister projects pick this up viatasks selfupdate, then runmigrate-tags-to-milestone <id>to move any interim@tags=<id>onto@milestone=<id>.