Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,25 @@ All notable changes to `tasks`. Format loosely follows
[Keep a Changelog](https://keepachangelog.com/); this project uses
[semantic versioning](https://semver.org/).

## [1.4.1] — 2026-07-16

Docs-only release; no behavior changes. Marks the repo "migration-ready": three
blind cold-clone audits confirmed a fresh session can resume from the repo alone.

### Added
- `MEMORY.md` — successor briefing (resume point, off-repo context, bootstrap),
ranked below `CLAUDE.md`; referenced from the fresh-session read order.
- Docstring/`schema.md`/README: explicit note that tasks do **not** inherit
their parent feature's `@milestone=` (rollup counts task tags only).

### Fixed
- Stale "155 scenarios" claims (actual: 54 scenarios / 298 assertions as of
v1.4.0) + an editor's note on the mislabeled v1.0.0 entry.
- Layout tables now list `LEARNINGS.md`, `MEMORY.md`, `docs/superpowers/specs/`.
- `examples/TASKS.md` now showcases milestones (registry + `@milestone=` tags).
- `CONTRIBUTING.md`/`CLAUDE.md` release + branching process aligned with actual
practice (squash-merge only; `gh release create` every release).

## [1.4.0] — 2026-07-15

### Added
Expand Down
3 changes: 2 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ Vendored copies on older versions pick up the new release via
commit to `main` directly.
- Number references: in `CHANGELOG.md`, `LEARNINGS.md`, and spec prose, `#N`
cites a **GitHub issue**; the `(#N)` suffix on a squash-merge commit subject
is the **PR** number. They are different sequences on the same tracker.
is the **PR** number. Issues and PRs share one number sequence on GitHub, so
a given `#N` is exactly one of the two — the tracker resolves it either way.
- New behavior is developed test-first: add the e2e scenario, watch it fail for
the right reason, then implement. Larger features get a design doc in
`docs/superpowers/specs/` committed with the same PR.
Expand Down
5 changes: 4 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,16 @@ make smoke # quick functional smoke test

## Pull requests

- All changes land via feature branch → PR → CI green → squash-merge; nothing
is committed to `main` directly.
- One concern per PR; clear, imperative commit messages.
- `make check` green, and the change documented in `CHANGELOG.md`.

## Releasing (maintainers)

Bump `__version__` + `CHANGELOG.md`, then `git tag -a vX.Y.Z -m "tasks vX.Y.Z"
&& git push origin vX.Y.Z`.
&& git push origin vX.Y.Z`, then `gh release create vX.Y.Z` with notes (every
release since v1.1.0 has one). Full process notes: `CLAUDE.md` → Releasing.

## Known cleanup

Expand Down
22 changes: 22 additions & 0 deletions LEARNINGS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,28 @@
Insights, gotchas, and decisions worth remembering — newest first. For *what*
changed see `CHANGELOG.md`; this file records *why* and what it taught us.

## 2026-07-16 — v1.4.1 (migration readiness: blind-dogfood audits)

- **Blind readers find what self-review can't.** Preparing a machine move, we ran
three rounds of "fresh agent, cold clone, zero context, answer a resume
questionnaire from the repo alone". Round 1: stale claims ("155 scenarios"),
lagging layout tables/roadmap, and no in-repo resume point. Round 2: an
overclaiming doc sentence, a flagship example file that predated the flagship
feature, and a real bug (#25: `validate` swallows unknown argv). Round 3: only
minor phrasing — converged. Each reader must be blind to the previous reports,
or later rounds just re-confirm earlier ones.
- **The highest-value probe is "continue where we left off".** It cleanly
separates "nothing is unmerged" (derivable from git) from "what would you do
next" (not derivable unless written down). `MEMORY.md` now pins the resume
point and is maintained in the same PR as any release or roadmap change.
- **Hardcoded counts in prose always rot.** Pin them to a version ("as of
v1.4.0") and point at the runner for the live number. And when a frozen
history entry (CHANGELOG) is misleading, append a dated editor's note — never
rewrite the entry.
- **Example files are docs and rot like docs.** `examples/TASKS.md` was billed
as "fully populated" but had no milestone content two releases after
milestones shipped. When a feature ships, grep the examples too.

## 2026-07-15 — v1.4.0 (collision-resistant allocation)

- **Fail closed when the flag *is* the safety.** `new --base <ref>` exists to
Expand Down
10 changes: 7 additions & 3 deletions MEMORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@

## Now / next (the resume point)

- **Nothing is in flight.** `main` is the complete, released state (v1.4.0,
2026-07-15). No open PRs; the only branch is `main`.
- **Nothing is in flight.** `main` is the complete state; no open PRs; the only
branch is `main`. v1.4.1 (docs-only, migration-readiness) is committed on
`main` — if no `v1.4.1` tag exists yet, tagging it is pending the owner's
confirmation (a tag push triggers the release; see CLAUDE.md → Releasing).
- **Next up, if told "continue where we left off": issue #14 — `validate --refs`**,
a reference-integrity check. Agreed shape (triage comment on the issue): v1 detects
*dangling* refs only (`@deps=`/`@rel=`/`## <ID>` notes header pointing at an ID
Expand Down Expand Up @@ -40,7 +42,9 @@ field edits (#17) → v1.2.0 `set --title` (#18) → v1.3.0 `renumber` (#12) →
v1.4.0 `new --id`/`--base` (#13). The through-line: a three-way ID collision
(`T-2006`, three parallel branches) in a consumer repo produced the
fix/prevent/detect triad — #12 shipped (fix), #13 shipped (prevent), #14 open
(detect).
(detect). Afterwards (2026-07-15/16), three blind cold-clone audits drove the
migration-readiness docs work (v1.4.1): MEMORY.md, corrected doc claims, and
issue #25 (found by the audit).

## Off-repo context a fresh machine won't have

Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,14 @@ EOF
./tools/tasks.py next --milestone m1 # next actionable task within M1
```

Assignment is per-item: a task does **not** inherit its parent feature's
milestone. The `milestone` rollup counts task tags only (untagged tasks stay in
the sentinel bucket) — tag tasks individually, or use `new … --milestone`, if
you want them counted under the target.

`milestone --table` gives the delivery-oriented view — each milestone, the
features assigned to it, and the milestone's status:
features assigned to it (directly or via their tagged tasks), and the
milestone's status:

```
MILESTONE FEATURES STATUS
Expand Down
5 changes: 4 additions & 1 deletion schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,10 @@ A task may carry one `@milestone=<id-or-alias>` tag. It is fully optional and
orthogonal to `@system=`/`@tags=`: files with no milestone data behave exactly
as before, and a task without the tag falls into an implicit sentinel bucket
named `default` (override via `TASKS_MILESTONE_SENTINEL`; it must not look like
an `M<n>` id). The sentinel is never written into task lines.
an `M<n>` id). The sentinel is never written into task lines. Assignment is
per-item: a task does **not** inherit its parent feature's milestone — the
`milestone` rollup counts task tags only, while `--table` attributes a feature
directly or via its tagged tasks.

An optional `# Milestones` registry (its own H1 section) maps ids → alias →
status → title, and powers alias resolution + rollups:
Expand Down
7 changes: 5 additions & 2 deletions tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,10 @@
data behaves exactly as before, and a task without the tag resolves to an
implicit sentinel bucket named "default" (configurable via the
TASKS_MILESTONE_SENTINEL env var; it must not look like an M<n> id). The
sentinel is never written into task lines.
sentinel is never written into task lines. Assignment is per-item: a task does
NOT inherit its parent feature's milestone — the `milestone` rollup counts task
tags only (untagged tasks stay in the sentinel bucket), while `milestone
--table` attributes a feature directly or via its tagged tasks.

An optional "# Milestones" registry (its own H1 section) maps ids to aliases,
statuses, and titles. When present it powers alias resolution (@milestone=alpha
Expand Down Expand Up @@ -198,7 +201,7 @@
from pathlib import Path
from typing import List, Tuple, Optional, Dict, Set, Iterator

__version__ = "1.4.0"
__version__ = "1.4.1"

# Canonical source for `selfupdate` — the published raw URL. `selfupdate`
# overwrites this very script with the fetched content, so a NON-default source
Expand Down
Loading