Repository navigation
schema: make serde_json arbitrary_precision opt-in (exact-numbers) - #48
Merged
Merged
Conversation
octoscript-schema enabled serde_json's arbitrary_precision on its plain dependency. Cargo unifies features, so every consumer of octoscript-schema, octoscript-capabilities or octoscript-workflow got arbitrary_precision across its whole graph, which changes serde_json's Number representation and breaks untagged/flattened numbers elsewhere (octos cannot depend on these crates). - octoscript-schema: new `exact-numbers` feature, off by default, that turns on serde_json/arbitrary_precision. ExactNumber already parses serde_json's shortest round-trip output, so without the feature bounds stay exact for every i64/u64 integer and every f64-representable decimal; only literals past that precision are rounded by serde_json at parse time. - octoscript-capabilities / octoscript-workflow: depend on schema (and capabilities) with default-features = false and expose an `exact-numbers` passthrough. - octoscript-cli and octoscript-media-host (leaf binaries) and the fuzz crate enable exact-numbers, so Octoscript's own behaviour is unchanged. - Tests: the two beyond-f64 tests are gated on exact-numbers; new tests cover int and decimal bounds, i64/u64 extremes, exponents and inclusive min/max boundaries without the feature, plus one documenting the loss. - Docs: numeric precision section in docs/schema-contracts.md, crate docs, README. CI tests the three library crates without the feature and fails if arbitrary_precision reappears in their normal graph. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Problem
octoscript-schemaenabledserde_json/arbitrary_precisionon its plain dependency. Cargo unifies features, so every crate that depends onoctoscript-schema, directly or throughoctoscript-capabilities/octoscript-workflow, turned onarbitrary_precisionfor its whole dependency graph. That changes serde_json'sNumberrepresentation for every other crate in the build, which breaks untagged or flattened numbers and any code that inspectsNumber. octos can't take these crates for that reason, and todayoctos-researchuses onlyoctoscript-core.Fix
octoscript-schema: adds a newexact-numbers = ["serde_json/arbitrary_precision"]feature, off by default. The plainserde_jsondependency no longer enables the feature.octoscript-capabilities,octoscript-workflow: depend on schema (and workflow on capabilities) withdefault-features = false. Each exposes anexact-numberspassthrough feature.Leaf binaries keep today's behaviour:
octoscript-cli(theoctoscriptbinary),octoscript-media-hostand the fuzz crate enableexact-numbers.octoscript-lspuses schema, capabilities and workflow only as dev-dependencies, so it can't leak the feature to consumers.Why off by default rather than on:
arbitrary_precisionis global and changes behaviour elsewhere. Only the crate that owns the final graph should turn it on. If the feature were on by default, every consumer would have to rememberdefault-features = falseon every path to schema, and one default edge anywhere would turn it back on.Tests: the two tests that need precision beyond f64 are gated on
#[cfg(feature = "exact-numbers")]: the existing 40-digit decimal test and a new 30-digit integer bound. New tests pass without the feature:i64::MIN/u64::MAXextremes0.1 + 0.2 > 0.31e21,1E+21,-1e-7and1e2for integerOne more test, which runs only without the feature, documents what is lost.
Docs: a new "Numeric precision" section in
docs/schema-contracts.md, crate-level docs, and a README line.CI: tests the three library crates without the feature, and fails if
arbitrary_precisionshows up again in their normalcargo tree.What is lost without
exact-numbersExactNumberalready parses serde_json's shortest round-trip output, so without the feature, bounds stay exact for every integer in thei64/u64range and every decimal that round-trips throughf64(0.1,2.5e-3,1e21). Only literals that need more precision are affected: a 30-digit integer bound, or0.30000000000000000001vs0.30000000000000000002. serde_json rounds these to the nearestf64at parse time, in both the schema and the value, so they can compare equal. Nothing else about validation changes.Downstream note: OctoSense's
octosense-toolboxdepends onoctoscript-schemadirectly. When it bumps its pin it gets the f64 behaviour unless it enablesexact-numbers. Its template bounds are small integers (for example1..720), which are exact either way.Verification (macOS, local)
cargo fmt --check;cargo +nightly fmt --manifest-path fuzz/Cargo.toml --checkcargo clippy --workspace --all-targets --all-features -- -D warningscargo clippy -p octoscript-schema -p octoscript-capabilities -p octoscript-workflow --all-targets --no-default-features -- -D warningscargo test --workspace --all-featuresandcargo test --workspace: all greencargo test -p octoscript-schema -p octoscript-capabilities -p octoscript-workflow --no-default-features: schema 12, capabilities 127, workflow 97 tests passcargo test -p octoscript-schema --features exact-numbers: 13 passcargo test -p octoscript-lsp,-p octoscript-core,-p makepad-script,-p makepad-regex: all passRUSTFLAGS='--cfg fuzzing' cargo +nightly check --locked --manifest-path fuzz/Cargo.toml: okcargo tree -e features -i serde_json -p <crate>for every workspace crate:arbitrary_precisionappears only foroctoscript-cliandoctoscript-media-host. It is also absent for workflow and capabilities with all their other features on.octos proof (throwaway worktree, not a PR)
This used a scratch worktree of octos
origin/main(90617dc1). In it,octos-researchpointedoctoscript-coreat this branch by path, addedoctoscript-capabilities,octoscript-schemaandoctoscript-workflowwithdefault-features = false, and aligned itsmakepad-scriptpin to Octoscript'sbf318136.cargo tree -e features -i serde_json -p octos-cli --no-default-features --features apihas 0arbitrary_precisionlines, while schema, capabilities and workflow all show in the tree. Control: addingfeatures = ["exact-numbers"]to the schema dependency makesserde_json feature "arbitrary_precision"→octoscript-schema feature "exact-numbers"→octos-researchappear.cargo build -p octos-cli --no-default-features --features api: ok.cargo test -p octos-research: ok, 201 tests. This includes a probe test that deserializes an untagged/flattened number, validates a schema and runs a one-stepWorkflowEngineplan.The worktree was deleted afterwards.
🤖 Generated with Claude Code