Release v0.5.12 — state schema versioning (clears the world-class punch-list)#20
Merged
Conversation
…ch-list) Everything under $CLIKAE_HOME/ was un-versioned: the moment any on-disk format needs a new field there'd be no way to tell old from new and no migration path (dim ⑤, the portfolio-wide weak dimension). This is the minimum fix. - lib/core/state_version.sh: a $CLIKAE_HOME/version integer (CLIKAE_STATE_VERSION — the STATE schema version, bumped only on a format change, not per release) + a forward-migration runner. state_version_check on startup migrates n→n+1 via _state_migrate_<n> hooks when the on-disk version is older, warns (not downgrades) when newer, no-ops when current. A missing file = the original un-versioned layout = v1 (migrates cleanly to a future v2). - Read-only-preserving: stamped when state is CREATED (ensure_profile --create → state_version_ensure), so steady-state read commands never write it. The "bare clikae changes nothing on disk" guarantee still holds (test-verified). - dry_store's line format documented as governed by the schema version (evolve via a migration, not by parsing two shapes). - Deliberately 克制: one version file + one runner, no framework. tests/bats/state-version.bats: 8 cases (stamp on init, no-file=v1, migrate older, migrate-from-unversioned, warn-on-newer, no-op-when-current, no-op-no-dir). bats -r tests = 345/345; shellcheck -S warning = 0. With this, clikae's quality punch-list (docs/HANDOFF-world-class-gaps.md) is empty. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
mixflavor
added a commit
that referenced
this pull request
Jun 13, 2026
Release v0.5.12 — state schema versioning (clears the world-class punch-list)
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.
What
Everything under
$CLIKAE_HOME/was un-versioned — the moment an on-disk format needs a new field, there'd be no way to tell old from new and no migration path (dim ⑤, the portfolio-wide weak dimension flagged indocs/HANDOFF-world-class-gaps.md). This is the minimum, restrained fix.How
lib/core/state_version.sh— a$CLIKAE_HOME/versioninteger (CLIKAE_STATE_VERSION, the state schema version — bumped only on a format change, not per release) + a forward-migration runner:state_version_checkmigratesn→n+1via_state_migrate_<n>hooks if the on-disk version is older, warns (never downgrades) if newer, and no-ops when current.ensure_profile --create), so steady-state read commands never write it. The "bareclikaechanges nothing on disk" guarantee still holds (test-verified).dry_store's line format is documented as governed by the schema version.Tests
tests/bats/state-version.bats— 8 cases (stamp-on-init · no-file=v1 · migrate-older · migrate-from-unversioned · warn-on-newer · no-op-when-current · no-op-no-dir).bats -r tests= 345/345;shellcheck -S warning= 0.🤖 Generated with Claude Code