Releases: carson-sweet/sweetclaude
v4.2.14-beta
Added — interactive orphan resolution
The update skill's orphan scan now offers interactive resolution when orphaned
work items are found. Users can re-onboard all items as new ISSUE entries,
review by group or one at a time, archive all, or leave them in place.
Re-onboarded items preserve provenance via reonboarded_from metadata linking
back to the original path and ID.
Fixed — orphan scan path handling
The scan now emits paths relative to the project directory, ensuring all action
commands work correctly regardless of where the project lives on disk.
v4.2.12-beta
Added — interactive orphan resolution
The orphan scan now offers five actions when orphaned work items are found:
re-onboard all as new ISSUE items, review by group, review one by one, archive
all, or leave in place. Previously, the scan was report-only. Each action
preserves provenance — re-onboarded items link back to their original path and
ID via reonboarded_from metadata.
Fixed — orphan scan returned absolute paths
scan-orphans now emits paths relative to the project directory, so all action
CLIs (reonboard-orphans, resolve-orphan, archive-orphans,
acknowledge-orphans) work correctly in any project location.
Fixed — orphan scan false positives eliminated
The scan no longer flags migrated ISSUE-format items in the primary backlog as
orphans. Previously, 525 false positives were reported on a real project with
2 actual orphans.
Changed — orphan terminology
Internal function and CLI names renamed from martian to orphan for clarity.
No user-facing behavior change.
v4.2.11-beta
Fixed — a missing derived state snapshot bricked nearly every skill on load
session-state.yaml is a per-session derived snapshot, not a tracked file.
Since ec771ea (ISSUE-193), 85 skills loaded it with a bare
!cat .sweetclaude/state/session-state.yaml`` bang preamble, assuming the
SessionStart preflight always regenerated it first. Whenever the snapshot was
absent — preflight hadn't run this session, an update/doctor run regenerated
state mid-session, a worktree with a different working directory, a fresh
checkout — the bare cat exited non-zero and the skill aborted on load with
`cat: .sweetclaude/state/session-state.yaml: No such file or directory`.
`/sweetclaude:go` and the rest of the skill surface became unusable.
All 86 bang-preamble state loaders (85 × session-state, plus orchestrator's
sweetclaude.yaml) now route through hooks/read-state.sh, invoked via
${CLAUDE_SKILL_DIR}/../../hooks/ so it resolves on fresh installs regardless
of working directory. The wrapper emits file contents when present and a
STATE_NOT_FOUND sentinel (which skills already handle) when absent, always
exiting 0 — a missing snapshot can no longer abort skill load.
Fixed — orphan scan missed legacy formats and had no catch-all for unknowns
The scan-orphans step in the v3→v4 migrator had two gaps:
-
Missing formats.
EP-*.md,EPIC-*.md,US-*.md, andspike-BL-*.md
were never in_WORK_ITEM_PATTERNS, so they were invisible to the scan.
BL-*.mdfiles in backlog/ were shielded by anexpected_filesentry that
was meant to protect migratedISSUE-*.mdfiles. All five patterns are now
detected, and the S2 migrator can migrate every one of them. -
No catch-all. Files with frontmatter but an unrecognized prefix (e.g.
FEAT-001,REQ-042) passed through silently. A new Step 5 catch-all
flags these as "martian" unknowns. V4-format files (ISSUE-,EP-,MS-,
SP-,TH-,RM-,REL-,PITCH-,CYC-,I-) are excluded.
Martians can be acknowledged (stored in a registry so they stop being
flagged) or archived (archive-martianssubcommand).
v4.2.10-beta
Fixed — typed-legacy backlog projects could never leave compatibility mode
A project whose product tree used typed backlog folders (backlog/stories/,
backlog/debt/, …) with legacy work-item prefixes (STORY-, DEBT-, BL-, …)
was classified typed_legacy_backlog and parked in compatibility mode
permanently. The migrator for that layout was supported: false, graduation
required zero legacy prefixes (impossible for the shape), and recovery only
re-stabilized — so update, doctor, migrate, and recover could never get
the project out. Running them again did nothing, because the framework was built
to park it. This release builds and wires the missing migrator end to end.
- A real typed-legacy → unified
ISSUE-NNNmigrator.migrate_taxonomy
recognizes typed backlog dirs (including nesteddone/subdirs), top-level
legacy-prefix files, spike reports, and the bespokestories/EPIC-NNN/and
stories/BL-NNN/user-story trees. It produces a reviewable dry-run plan
(global ISSUE renumbering,EP-NNNepics,migrated_from, aMIGRATION-MAP,
and reference rewrites), then executes behind a snapshot with byte-for-byte
rollback and auto-rollback on failure. - The guard now offers the migrator.
migrate.typed_legacy_backlogis
supported; the recovery guard, doctor maintenance route, and bootstrap route a
typed-legacy project tosupported-migration-availableinstead of a no-action
compatibility mode. Projects with real (non-backup) duplicate IDs are routed
to a resolvable step, not a wall. - No project shape is a dead end — a test now asserts every guard status
routes to an offered action.
Bugs found and fixed while validating against a real corpus:
- The migrator crashed when run as a CLI (
No module named 'recovery') — i.e.
exactly howsweetclaude:migrateinvokes it; the test suite had masked it. - Migration left items behind: nested
backlog/stories/done/and
stories/BL-NNN/story dirs weren't scanned, so the project stayed
typed-legacy after "migrating." - Versioned draft documents (
BL-005-product-brief-draft-v1.0-….md) were
miscounted as work items, leaving the project reading asflat_bl_backlogand
faking duplicate-ID blockers. - Tool backups (
*.bold-backup-*) were counted as duplicate IDs and used to
justify refusing migration. - Recovery forbade the now-safe migration: the stabilize postcondition required
doctor to recommend no migration; it now fails only on unsupported migration. - Interrupted (
incomplete) migrations got stuck in recovery; stabilize now
normalizesincomplete → deferredso recover-then-migrate completes.
Fixed — dashboard detail-panel dates now show their timezone
Detail-panel date fields rendered as 2026-05-21 00:00:00.000Z because an
over-escaped regex in fmtDate was emitted literally into the page JS and never
matched. They now read 2026-05-21 00:00:00 UTC.
v4.2.9-beta
Fixed — missing skills.yaml was still a dead end (and said something scary)
The 4.2.8 totality audit misclassified one finding as cosmetic, and a user
hit it within hours: after updating, doctor reported "Skills configuration
hasn't been set up yet" — wording that reads as if plugin skills are
broken, with guidance pointing at a bootstrap path that never creates the
file. Plugin skills were always fine: .sweetclaude/state/skills.yaml is
the optional-feature onboarding ledger (parking lot, milestones, usage
tracking activation state), not the skill registry, and every feature skill
tolerates its absence.
- New generator:
scripts/maintenance/generate-skills-state.pycreates
the v2 stub that init normally writes. Idempotent — an existing file is
never touched; uninitialized projects (no state directory) are refused
with a pointer to/sweetclaude:init. - The finding now auto-fixes.
onboarding-state:missing:skills.yaml
runs the generator through doctor's executor — archived, backed up,
reversible viadoctor restore— instead of being report-only with
guidance that led nowhere. - Honest wording. Summary is now "Optional-feature state file is missing
(skills all work; this ledger only tracks feature onboarding)." - End-to-end test locks the contract: scan → auto-fix → file created
withschema_version: 2→ rescan clears the finding.
Process note, recorded in the totality matrix: a finding every user sees
with no working resolution path is never "cosmetic" — this one is now in the
test corpus so the class stays closed.
v4.2.8-beta
Fixed — maintenance dead ends closed end-to-end
This release closes the class of bug where Doctor, Update, Recover, and
Bootstrap detected maintenance issues but never connected the user to a
resolution — the "Doctor says run Recover, Recover says nothing to do" loop.
Every fix was driven by failing end-to-end tests derived from three real
projects, and acceptance was verified by those projects' session starts
coming up clean, not by the unit suite alone.
- Guard names graduation blockers. New
graduation-blockedguard status:
when a compatibility-mode project fails graduation validation on fixable
blockers only (duplicate IDs, legacy type aliases, missing fields,
frontmatter parse errors), the guard lists each blocker with its resolution
instead of collapsing everything into the generic compatibility-mode
message. Structural blockers (old taxonomy prefixes, non-standard layout)
keep the project honestly in compatibility mode — those genuinely require a
layout-specific migration plan. resolve-graduation-blockerCLI (recover_project.py): resolves
duplicate-ID blockers through Doctor's executor — archived, backed up,
reversible viadoctor restore. It distinguishes misnamed files (the
filename id and frontmatter id disagree → rename the file to match its
frontmatter) from true duplicates (two files share a frontmatter id →
renumber the non-canonical copy). Renumbering a misnamed file would have
clobbered a valid id other artifacts reference.- The no-op compatibility exit is gone. Doctor's
exit_compatibility_modeprompt wrote a flag the guard never read for
status, so "exiting" changed nothing and the prompt re-offered itself every
scan, forever. Graduation is now the single exit from compatibility mode. - Cross-location duplicate findings carry their fix.
storage-lint:cross-location-duplicate-idsupersedes the file-diagnostics
duplicate finding in scan dedup but was report-only with an empty recipe —
the dedup kept the dead end and dropped the resolution. It now carries the
full renumber recipe. - Bootstrap routes every guard status. Step 5b is now a two-mode
maintenance guard. The v3 hard-stop is unchanged; a new advisory mode
runs the guard at session start for v4 projects in compatibility/recovery
states — previously the guard never ran for them, so graduation
opportunities were invisible. Advisory mode also triggers when legacy
taxonomy files (STORY-/BUG-/DEBT-/CHORE-) exist despite state
claiming migration complete. Every status maps to an action or an honest
explanation; migrate is never recommended except for
migration-may-be-needed. - Recover acknowledges schema drift.
diagnosenow reports a
state-schema-driftfailure class (informational — it never flips the
recovery route) instead of answering "no recovery needed" while state files
sit behind the registry schema. The next-step text names the drifted files
and points at the migration runner path that actually fixes them. - Update's referral circle closed. The PARTIAL-update halt told users to
run Doctor "or Recover" for drift; Recover correctly reports drift as
informational-only, so that referral looped. The halt now routes to Doctor
alone, which auto-fixes drift through the migration runner.
Added — dead-end totality test corpus
tests/test_dead_end_totality.py: 14 end-to-end tests locking the
detection-to-resolution contracts, built from the observed states of three
real projects (graduation-blocked with a hidden blocker, recovery-required
with legacy artifacts, healthy control). Includes a totality lint: every
guard status the capability manifest can emit must be handled in the
bootstrap skill.- Totality matrix audit: all 59 Doctor finding constructors classified
(auto/prompted findings all carry executable archived recipes; every
report-only finding verified as policy block, broken-chain fallback,
human-content, or owned by a reachable route).
v4.2.7-beta
Fixed — doctor dead-end resolution paths
- Schema drift auto-fix. Doctor now auto-fixes v1→v2 schema drift via the
migration runner instead of marking it report-only and sending the user in
circles between/sweetclaude:doctor,/sweetclaude:update, and
/sweetclaude:recover(none of which could actually fix it). - skills.yaml v1 schema auto-fix. Skills file schema upgrades now route
through the migration runner instead of referencing a non-existent bootstrap
script that silently failed. - skills.yaml missing finding corrected. Missing skills.yaml is now
report-only with actionable guidance instead of offering a prompted fix that
called the wrong script and silently did nothing. - Broken migration chains stay report-only. Schema drift with broken
migration chains (out-of-support-window) correctly falls back to report-only
instead of offering an auto-fix that would fail. runner.pyadded to executor allowlist. The migration runner can now
execute through Doctor's backup pipeline (before-image + diff, reversible
via restore).
v4.2.6-beta
Added — compatibility mode graduation
- Compatibility mode graduation capability. Projects stuck in compatibility
mode (stabilized-without-migration) can now graduate when they are already
v4-compliant. Doctor detects graduation candidates at the maintenance route
prompt and offers a one-click exit — a state-only write tosweetclaude.yaml
with one-file blast radius, fully reversible via Doctor's restore flow. - v4 compliance detection in
characterize_project.py: newv4_compliance
output block reports old-prefix count, v4-prefix count, required-field coverage,
canonical-type compliance, duplicate-ID status, and standard structure. graduation-checkandgraduateCLI subcommands onrecover_project.py
for read-only validation and state-only graduation execution.graduation_candidateproject shape andrecover.graduate_from_compatibility
capability in the manifest, with full safety contract (diagnose → validate →
snapshot → approve → execute → verify → rollback).- Doctor routes
graduation-availablebefore falling through to
compatibility-mode, so compliant projects see the exit rather than the dead end. - 17 new tests covering graduation-check happy path, blocker detection
(old prefixes, duplicates, legacy types, parse errors), guard routing,
doctor maintenance route, graduate execution, idempotency, and read-only
guarantees.
v4.2.5-beta
Fixed — doctor conformance, safety hardening
- Doctor conformance remediation (P0–P5). The
sweetclaude:doctorsubsystem
now fully satisfies its PRD (verified 127/0/0 by an independent caucus): every
Tier-2 prompted fix is wired end-to-end through the executor backup pipeline;
the Tier-4 purge/re-onboard fallback is surfaced; detection gaps (missing hooks,
legacy type aliases, schema drift) are closed; taxonomy drift routes to migrate;
and a realrestore/rollback path exists. - Scan is strictly read-only (P2/P4). The suppression-ledger prune was moved
out of the read-only scan into the execute phase and routed through the backup
pipeline (before-image + diff,restore-reversible). - Path-containment guards.
restore,file_move,renumber_duplicate, and
run_scriptnow reject paths that escape the project tree or~/.claude,
closing arbitrary-write/exec vectors via crafted recipes or archives.
Added — release & test infrastructure
- Tag-push release automation (
.github/workflows/release.yml): pushing a
v*tag now publishes a GitHub release with CHANGELOG-sourced notes. - Test collection fix: hyphenated
test-*.pysuites (~440 tests) are now
collected and run; 7 pre-existing, unrelated failures are tracked viaxfail.
v4.2.4-beta (4.x beta)
- fix(release): bump plugin.json to 4.2.4-beta (authoritative plugin version)
- feat(workflow): add small-story controller, hooks, skill, and routing
Backfilled release. Source: commits v4.2.3-beta..v4.2.4-beta. Full history: CHANGELOG.md.