Repository navigation
remove compat dual-writes from change state store #29
Description
Proposal
Skein currently maintains a duplicate runtime state location: the primary .skein/changes/<slug>/ AND a compat mirror openspec/changes/<slug>/.skein/ via NewWithCompat. This creates confusion, stale state, and makes the codebase harder to understand.
The goal is to have ONE source of truth: .skein/changes/<slug>/ for Skein runtime state, and openspec/changes/<slug>/ for OpenSpec planning content (proposal.md, tasks.md, specs/). No duplication.
Current state:
NewWithCompat(runtimeBase, specBase)indefaults.gowrites to both locationsHasFlag,FlagMtimeread from both (primary first, compat fallback)SetFlag,ClearFlag,SetBlocked,WriteTextFile,AppendTextFile,SetPrioritywrite to bothisInitializedChangeinopenspec/load.gochecks for.skein/in the openspec dir as a markerresolveStatusinopenspec/load.gohas store-first path + legacy file fallbackresolveStatusWithStoreinauditor/auditor.gohas store-first path + legacy file fallback- Migrate command exists to copy state from compat→primary
What to do:
-
Remove compat writes — Change
NewWithCompattoNewindefaults.goand all callers. Remove thespecBasefield and all compat write logic fromfile_store.go. -
Update
isInitializedChange— Instead of checking for.skein/in the openspec dir, check if.skein/changes/<slug>/exists (viachangestate.Current().RuntimeDir(slug)). Keep theproposal.md/tasks.mdchecks for hand-authored changes. -
Remove compat reads — Remove the compat directory fallback from
HasFlag,FlagMtimeinfile_store.go. -
Remove legacy fallback — In
resolveStatusinopenspec/load.go, remove the legacy file check fallback and only use the store path. Same forresolveStatusWithStoreinauditor/auditor.go. -
Run the Migrate command on existing repos to copy compat state → primary, then clean up the compat directories.
-
Update tests — Tests that use
NewWithCompatshould useNew. Tests that check for compat writes should be updated. -
Clean up comments — Remove references to "Slice 8" and "compat" and "legacy" throughout.
Key files:
internal/port/adapter/defaults.go— changeNewWithCompattoNewinternal/infra/changestate/file_store.go— remove compat logicinternal/openspec/load.go— updateisInitializedChange, remove legacy fallbackinternal/auditor/auditor.go— remove legacy fallbackinternal/cli/intake_test.go— update testinternal/cli/migrate_state.go— can be simplified/removed after migration
Caution: This is a breaking change for repos that have only compat state. The Migrate command should be run first on existing repos.
Disposition (2026-09-18)
Archived — superseded/obsolete. Misfiled — targets the skein Go repo (internal/port/adapter, changestate).
Tasks
- Remove compat writes: change NewWithCompat to New in defaults.go and all callers
- Remove specBase field and all compat write logic from file_store.go
- Update isInitializedChange to check .skein/changes// instead of openspec/changes//.skein/
- Remove compat reads from HasFlag and FlagMtime
- Remove legacy file fallback from resolveStatus in openspec/load.go
- Remove legacy file fallback from resolveStatusWithStore in auditor/auditor.go
- Update tests to use New instead of NewWithCompat
- Run Migrate on brick-now repo to copy compat state to primary
- Clean up compat references in comments and documentation
Unchecked items above: see Disposition in proposal.md (2026-09-18).
Activity
androidand commentedon Sep 17, 2026
Archived 2026-09-18 — see the change's Disposition section.