Skip to content

feat: derive and set a document's schema_version - #41

Merged
wavekat-eason merged 1 commit into
mainfrom
feat/schema-version-primitives
Aug 9, 2026
Merged

feat: derive and set a document's schema_version#41
wavekat-eason merged 1 commit into
mainfrom
feat/schema-version-primitives

Conversation

@wavekat-eason

Copy link
Copy Markdown
Contributor

Why

The format grew a second version when book arrived, and the number leaked into the authoring surface: an editor that adds a book step to a v1 draft gets node "book" is a book step, which needs schema_version 2 (this document declares 1). The author placed a step; the answer named a number they have no way to know about.

Nothing here decides policy — these are the two primitives an authoring tool needs so it can keep the declared version in step with the components actually placed.

What

  • requiredSchemaVersion(flow) (model.ts, next to KIND_MIN_SCHEMA_VERSION) — the lowest version that can carry a document's components. Floor of 1, because Math.max() of nothing is -Infinity and a new draft has no steps yet.
  • setSchemaVersion(source, version) (mutate.ts, next to stampIdentity) — restates the declared version through withDoc, so comments, key order, and the ui block survive. Lowers as readily as it raises.
  • required_schema_version(flow) — the Rust twin, in validate.rs beside kind_min_schema_version. setSchemaVersion gets none: mutate.rs doesn't exist because the daemon never edits documents, which that file already states.

Paired, they let an editor hold a draft at the lowest version that can run it — which is also the widest, since an engine only runs versions it knows. A document that needs nothing newer stays at 1 and stays runnable everywhere.

Not a migration

KIND_MIN_SCHEMA_VERSION's comment said "Documents are never rewritten", which reads as a contradiction sitting next to a function whose job is to rewrite the version. It isn't one — that promise is about stored documents, and it still holds. The comment now says so explicitly rather than leaving the next reader to work it out.

Tests

  • New test/model.test.ts: v1-only → 1, book → 2, falls back when the component is removed, empty nodes → 1.
  • test/mutate.test.ts: sets the version leaving comments and ui alone, lowers as well as raises, parse_failed on unparseable text.
  • validate.rs: the three twin cases.

Both languages green — pnpm --filter @wavekat/flow-schema test (137) and cargo test -p wavekat-flow (53 + 3 conformance). cargo fmt --check and clippy --all-targets clean. Corpus untouched: this adds no schema change and no case.

🤖 Generated with Claude Code

https://claude.ai/code/session_01AFE4mZNdkfPUBbTTwW4e7A

An authoring tool should not make the author think about the format's
version number. `requiredSchemaVersion` reports the lowest version that
can carry a document's components; `setSchemaVersion` restates the
declared one through the CST, so comments and key order survive.

Together they let an editor keep a draft at the lowest version that can
run it — which is also the widest, since an engine only runs versions it
knows. Adding a `book` step raises the document on its own; removing it
lowers it again.

This does not migrate stored documents. The format's promise that a v1
flow keeps working is unchanged, and the comment on
KIND_MIN_SCHEMA_VERSION now says which of the two it is talking about.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AFE4mZNdkfPUBbTTwW4e7A
@wavekat-eason
wavekat-eason merged commit 756c209 into main Aug 9, 2026
3 checks passed
@wavekat-eason
wavekat-eason deleted the feat/schema-version-primitives branch August 9, 2026 02:00
@github-actions github-actions Bot mentioned this pull request Aug 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant