feat(book): enumerate a vocabulary on any grid - #46
Merged
Conversation
`required_assets` is computed from the grid compiled into each device,
so a renderer that knows only its own can serve only devices that agree
— which makes narrowing wait on the whole fleet updating, an event that
does not occur.
Adds an explicit grid to both twins (`bookVocabularyRefs(node, {
granularityMins })`, `vocabulary_refs_on`) so a renderer can cover the
union of every grid still installed and stop being pinned to its oldest
device's opinion. Defaults are untouched: every existing caller,
including the arming check itself, gets exactly what it got before.
See the platform's docs/36.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018stjkZJ4kxDViq1ENnVDmH
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.
The mechanism half of the platform's docs/36. Additive, npm + crates.io
only — no daemon needs this, and no daemon behaviour changes.
Why
required_assetsis computed from theBOOK_GRANULARITY_MINScompiledinto each device, not from anything a flow version carries. So a
renderer that only knows its own grid can satisfy only the devices that
happen to agree with it, and narrowing the grid becomes a change that is
safe once the whole fleet has updated — which is not an event that
happens. Installed clients are not ours to move.
The way out is for the renderer to cover the union of every grid
still installed. That needs a way to enumerate a grid this build does
not compile in:
What is deliberately not here
No list of which grids are live. That is a fact about our customers'
machines, not about the format — it changes with no format change, and
baking it in would make every consumer inherit our fleet's history. The
package owns the mechanism; the platform owns the policy
(
LIVE_BOOK_GRIDS).Compatibility
The parameter is optional and defaults to
BOOK_GRANULARITY_MINS, soevery existing caller is byte-identical — including the daemon's arming
check, which should keep asking about its own grid, because that is the
question it is actually being asked.
The conformance corpus is untouched and still passes: it pins the
default derivation in both languages, which is exactly the guard that
must not move while this lands.
Tests
Both languages: an explicit grid is walked instead of the build's own;
non-time refs (days, keypad, taken) are unaffected; a finer grid is a
superset of a coarser one — the property the union rests on. TypeScript
throws on a non-positive or fractional grid; Rust returns empty for a
zero step, where the failure would otherwise be a hung device rather
than a wrong answer.
Draft until the platform side is reviewed — merging this releases
@wavekat/flow-schemaand the crate, and there is no reason to publisha mechanism before the caller that needs it exists.
🤖 Generated with Claude Code
https://claude.ai/code/session_018stjkZJ4kxDViq1ENnVDmH