A real CLI fixture reproduced an infinite allocation loop from an existing unsafe numeric ID. Reject unsafe IDs and overflow without writing markers; 26 workflow fixtures, changed-code coverage and validators pass.
Preserve full contributor history and current catalog. Actual process workflows cover concurrency, recovery, sprint planning and read-only status. Bound registry symlinks, counts and lock waits; preserve manually curated trigger provenance.
A non-numeric, negative, or exponent Points value was persisted and
silently skewed the derived sprint total (bogus -> 0, -3, 1e3 -> 1000)
with no drift reported. parseStory now enforces the documented values,
so apply rejects the batch and status reports the invalid story.
Resolve the Greptile findings on 74262955:
- Refuse symlinked .stories/, epics/, sprints/, .txn/, .ids/ and
symlinked ledger files, so no read or write leaves .stories/.
- Recovery accepts only regular backup-<n> files in .txn/, validates the
whole journal before restoring, and never writes through a planted
restore.tmp.
- Remove a stale lock only under .lock.break after a re-read, so a live
lock is never deleted; a leftover .lock.break times out (exit 3)
instead of spinning.
- apply enforces one-step-forward status transitions, new stories start
as todo, and Sprint must be unassigned or an existing sprint file.
- Refuse a batch that names the same file twice (e.g. a\b vs a/b).
Symlink tests skip on Windows when symlink creation returns EPERM.
Route every .stories/ write through skills/story-lifecycle/scripts/ledger.js:
- exclusive per-ledger lock; a second writer waits, then exits 3 without writing
- story IDs reserved with exclusive-create markers in the git common dir, so
concurrent agents and worktrees of one clone never share an ID
- journaled batches: stage, journal, rename; derived epic/sprint tables are
regenerated inside the batch; an interrupted batch is rolled back by the
next write command or `recover`; `status` reports it only when no live
writer holds the lock
Bound the ledger to an opt-in planning projection that is never canonical
ECC Task/Evidence/Completion/Integration state, and state that .stories/
follows the checkout.
tests/docs/story-lifecycle-ledger.test.js exercises create, concurrent
create, concurrent cross-worktree allocation, lock contention, overwrite
refusal, interrupted-batch recovery, sprint planning, status drift and
reconcile, and path confinement. Also refresh the skill-triggers manifest
digest for 294 skills.
Address maintainer review on #2311:
- story file is the single authoritative status record; epic/sprint
tables are derived and reconciled; todo → in-progress → review → done
with done gated on confirmed merge to main
- implement lane: tdd-workflow first, language reviewer +
verification-loop before a story reaches review
- naming/path contract (slug, story-id, sprint validation), resolved-path
confinement under .stories/, untrusted-content handling, no silent
overwrites, harness-native file operations (no POSIX-only shell)
- documented boundary and handoff to issue-backed epic-* coordination
- replaced references that do not resolve on main; added
tests/docs/story-lifecycle-skill.test.js contract test
Carries forward a Greptile-suggested fix already applied on origin
(commit 1104f4be) that predates this session's rebase: marking a story
done should only touch .stories/sprints/sprint-<n>.md's table when the
story actually has a Sprint assigned, not unconditionally.
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Adds skills/story-lifecycle/SKILL.md, a community skill inspired by
the BMAD Method's epic/story/sprint workflow: a self-contained,
file-based delivery loop (Epic → Stories → Sprint → Implement → Done)
with all state under .stories/, no external PM tool required.
Rebuilt on current upstream/main as a skill-only diff, per affaan-m's
review (same blockers as #2309): the shared format-code.ts Windows fix
and github-coordination branch-coverage tests that were bundled here
now live in #2459. Skill count recomputed as 277->278 against current
main (the old bump was stale, which was the actual conflict source).
Also repoints the Related Skills entry from the closed project-context
skill (#2310) to dev-team, which now owns reading/generating
PROJECT-CONTEXT.md.