Schema Version Recommendation
schema.version_contract
Overview
You send the old and new text of a contract plus the version you are on, and we return the bump SemVer 2.0.0 calls for and the version it produces. The comparison is not ours: it is the same engine schema.diff_json_schema uses, so a diff and a recommendation can never disagree. A breaking change is major, an additive one is minor, and a change the engine itself calls ambiguous escalates to major rather than being quietly resolved — an over-recommendation spends a version number, an under-recommendation ships a consumer outage. Every change behind the verdict is cited with its path, its type and the bump it implies. We recommend; code.bump_version computes.
Something has to decide which bump a change deserves. A diff classifies changes and a bump calculator applies a decision, but between them sits a judgement that today is made by hand in a pull request, inconsistently, at the moment everyone wants to ship.
Reliability
The same two contracts and the same version always produce the same recommendation, independent of your machine's locale, time zone and default character set. Hand recommendedBump straight to code.bump_version, but leave that skill's own zeroMajorPolicy at its default: setting it to breaking_minor would re-interpret a decision already made here. Twelve refusals stop the call. VERSION_CONTRACT_SCHEMA_INVALID means one of the contracts is not valid JSON and carries the json_repair recovery intent, so schema.repair_json can make a retry meaningful; VERSION_CONTRACT_SCHEMA_TOO_LARGE means a side is over 524288 bytes; VERSION_CONTRACT_VERSION_INVALID means currentVersion is not a SemVer 2.0.0 release core; VERSION_CONTRACT_PRERELEASE_INVALID and VERSION_CONTRACT_BUILD_METADATA_INVALID mean the segment after the hyphen or the plus is malformed, and neither is silently normalised; VERSION_CONTRACT_POLICY_UNSUPPORTED means zeroMajorPolicy is neither published member; VERSION_CONTRACT_NODE_LIMIT_EXCEEDED means a side has over 20000 nodes, nests deeper than 50 levels — the platform parser's ceiling, which binds first because contracts arrive here as text — breaks a per-object cap, or would pass 100000 nodes once its local references were expanded; VERSION_CONTRACT_REF_REMOTE_REFUSED, VERSION_CONTRACT_REF_CYCLE_DETECTED and VERSION_CONTRACT_REF_DEPTH_EXCEEDED are the reference refusals; VERSION_CONTRACT_WORK_REFUSED means the run was projected past the 2000000-unit budget before it started and reports both numbers; and VERSION_CONTRACT_OUTPUT_TOO_LARGE means the cited evidence would not fit the 2 MiB response ceiling, so lower maxChanges.
Context footprint
Cited changes carry a path, a type and an implied bump — never the schema text either side of the change — and both lists are capped at maxChanges. A successful call costs 2 execution credits.
When to use it
Before releasing a changed contract, especially in CI where the version number should not depend on who is reviewing.
When you have already decided the bump and only need the next number, or when you want the list of differences rather than a verdict.
Scope
Non-goals
- We never write a version anywhere, touch a file, or contact a registry
- We never compare schemas ourselves: the diff engine does that
- We never downgrade minor to patch — an added optional property is a feature
- We never resolve an ambiguous change quietly; it escalates and is cited
Properties
Capabilities
Cost & billing
Flat rate per invocation
File handling
How we handle your data
What this means
This skill may receive sensitive content, but it does not target sensitive data and returns only a structured non-sensitive result.
Squillify guarantees
- Runs inside Squillify
- This skill runs inside Squillify.
- Payloads are not sent to an external service by this skill.
- Squillify does not permanently store submitted payloads.
- Telemetry records metadata only, not submitted content.
- Submitted payloads are not used for training.
- Submitted payloads are not reviewed by humans.
- This skill does not target sensitive data.
- The response does not contain submitted content.
Your responsibility
Squillify does not determine whether submitted content is sensitive. Your application is responsible for deciding what data it is allowed to submit. Your application is responsible for securing the response.
Input schema
| Field | Type | Required | Description |
|---|---|---|---|
| oldContract | string | Yes | Published contract as JSON Schema text, 2 through 524288 bytes. |
| newContract | string | Yes | Proposed contract as JSON Schema text, 2 through 524288 bytes. |
| currentVersion | string | Yes | Strict SemVer 2.0.0 version you are on now, 1 through 256 characters. |
| zeroMajorPolicy | string | No | How 0.y.z breaking changes are recommended; omit it for SEMVER_INITIAL_DEVELOPMENT. |
| maxChanges | integer | No | How many cited changes to list, 1 through 500; omit it for 500. |
Output schema
| Field | Type | Required | Description |
|---|---|---|---|
| recommendedBump | string | Yes | Recommended bump spelled as code.bump_version accepts it, or none. |
| recommendedVersion | string | Yes | Version the bump produces, with build metadata dropped. |
| currentVersionNormalized | string | Yes | Release core of the version sent, without pre-release or build metadata. |
| compatible | boolean | Yes | True when the diff engine found no breaking change. |
| breaking | array | Yes | Breaking changes that drove a major bump, 0 through 500 closed objects with path, changeType and impliedBump. |
| rationale | object | Yes | Closed decision record with the rule profile, what decided the bump, cited changes and how pre-release, build metadata and 0.y.z were handled. |
| summary | object | Yes | Closed unfiltered counts with totalChanges, breakingCount, nonBreakingCount, ambiguousCount and truncated. |
API contract
POST /v1/executecurl -sS -X POST "$BASE/v1/execute" -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' -d '{"skillKey":"schema.version_contract","input":{"oldContract":"{\"type\":\"object\"}","newContract":"{\"type\":\"string\"}","currentVersion":"1.2.3"}}'import { Squillify } from "@squillify/sdk";
const sq = new Squillify({ apiKey: process.env.SQUILLIFY_API_KEY });
const { output } = await sq.execute("schema.version_contract", {"oldContract":"{\"type\":\"object\",\"properties\":{\"id\":{\"type\":\"integer\"}}}","newContract":"{\"type\":\"object\",\"properties\":{\"id\":{\"type\":\"string\"}}}","currentVersion":"2.4.1"});Errors
| Code | HTTP | Retryable | Description |
|---|---|---|---|
| VALIDATION_ERROR | 400 | No | The request payload failed schema validation. |
| UNAUTHORIZED | 401 | No | Missing or invalid API key. |
| SKILL_NOT_ACCESSIBLE | 403 | No | The API key is not granted access to this skill. |
| SKILL_NOT_AVAILABLE_FOR_PLAN | 403 | No | This skill is not included in your current plan. |
| PLAN_ELIGIBILITY_UNAVAILABLE | 503 | Yes | Plan eligibility could not be decided. Retry after backoff. |
| SKILL_NOT_FOUND | 404 | No | The requested skill or version does not exist. |
| TENANT_RATE_LIMITED | 429 | Yes | Request rate limit exceeded. Retry after backoff. |
| QUOTA_EXCEEDED | 429 | Yes | Plan quota exhausted. Retryable once the quota period resets. |
| EXECUTION_TIMEOUT | 504 | Yes | Execution exceeded the allowed time budget. |
| VERSION_CONTRACT_SCHEMA_INVALID | 400 | No | The request payload failed this skill's input validation. |
| VERSION_CONTRACT_SCHEMA_TOO_LARGE | 429 | No | A size, quota, rate, or time limit was exceeded. |
| VERSION_CONTRACT_VERSION_INVALID | 400 | No | The request payload failed this skill's input validation. |
| VERSION_CONTRACT_PRERELEASE_INVALID | 400 | No | The request payload failed this skill's input validation. |
| VERSION_CONTRACT_BUILD_METADATA_INVALID | 400 | No | The request payload failed this skill's input validation. |
| VERSION_CONTRACT_POLICY_UNSUPPORTED | 400 | No | The skill does not support the requested variant. |
| VERSION_CONTRACT_NODE_LIMIT_EXCEEDED | 429 | No | A size, quota, rate, or time limit was exceeded. |
| VERSION_CONTRACT_REF_REMOTE_REFUSED | 400 | No | The request payload failed this skill's input validation. |
| VERSION_CONTRACT_REF_CYCLE_DETECTED | 400 | No | The request payload failed this skill's input validation. |
| VERSION_CONTRACT_REF_DEPTH_EXCEEDED | 429 | No | A size, quota, rate, or time limit was exceeded. |
| VERSION_CONTRACT_WORK_REFUSED | 429 | No | A size, quota, rate, or time limit was exceeded. |
| VERSION_CONTRACT_OUTPUT_TOO_LARGE | 429 | No | A size, quota, rate, or time limit was exceeded. |
Other limits
| Limit | Value |
|---|---|
| Recommended inline bytes | 32 KiB |
Limitations
- We never write a version anywhere, touch a file, or contact a registry
- We never compare schemas ourselves: the diff engine does that
- We never downgrade minor to patch — an added optional property is a feature
- We never resolve an ambiguous change quietly; it escalates and is cited
- Computing a next version from a bump you have already chosen, which code.bump_version does
- Listing the differences themselves, which schema.diff_json_schema does
How to call
POST /v1/execute (requires authentication)
{
"skillKey": "schema.version_contract",
"input": {
"oldContract": "{\"type\":\"object\",\"properties\":{\"id\":{\"type\":\"integer\"}}}",
"newContract": "{\"type\":\"object\",\"properties\":{\"id\":{\"type\":\"string\"}}}",
"currentVersion": "2.4.1"
}
}Examples
A property whose type changed, forcing a major
{
"oldContract": "{\"type\":\"object\",\"properties\":{\"id\":{\"type\":\"integer\"}}}",
"newContract": "{\"type\":\"object\",\"properties\":{\"id\":{\"type\":\"string\"}}}",
"currentVersion": "2.4.1"
}{
"compatible": false,
"recommendedVersion": "3.0.0",
"breaking": [
{
"path": "/properties/id/",
"changeType": "type_changed",
"impliedBump": "major"
}
],
"recommendedBump": "major",
"summary": {
"totalChanges": 1,
"breakingCount": 1,
"nonBreakingCount": 0,
"ambiguousCount": 0,
"truncated": false
},
"currentVersionNormalized": "2.4.1",
"rationale": {
"rule": "semver-recommend-1",
"decidedBy": "breaking_change_present",
"citedChanges": [
{
"path": "/properties/id/",
"changeType": "type_changed",
"bucket": "breaking",
"impliedBump": "major"
}
],
"zeroMajorPolicy": "SEMVER_INITIAL_DEVELOPMENT",
"ambiguityHandling": "none",
"preReleaseHandling": "not_present",
"buildMetadataDropped": false
}
}Two identical contracts, which is no release at all
{
"oldContract": "{\"type\":\"object\"}",
"newContract": "{\"type\":\"object\"}",
"currentVersion": "1.0.0"
}{
"compatible": true,
"recommendedVersion": "1.0.0",
"breaking": [],
"recommendedBump": "none",
"summary": {
"totalChanges": 0,
"breakingCount": 0,
"nonBreakingCount": 0,
"ambiguousCount": 0,
"truncated": false
},
"currentVersionNormalized": "1.0.0",
"rationale": {
"rule": "semver-recommend-1",
"decidedBy": "no_change",
"citedChanges": [],
"zeroMajorPolicy": "SEMVER_INITIAL_DEVELOPMENT",
"ambiguityHandling": "none",
"preReleaseHandling": "not_present",
"buildMetadataDropped": false
}
}Recommended use cases
- Decide the release number for a schema change in CI
- Show a reviewer which change forced a major bump
- Check whether a proposed contract can ship as a minor release
Avoid for
- Computing a next version from a bump you have already chosen, which code.bump_version does
- Listing the differences themselves, which schema.diff_json_schema does
Related skills
Composable with
Safety & privacy
- Runs without calling any external service.
- Your payloads are never stored permanently.
- Telemetry captures metadata only — never your payload contents.
- We never train models on your payloads.
- No human reviews your payloads.