Versioning
`metadata.schema` says which shape an object has. `metadata.version` says how that object's content has changed. They are not interchangeable.
A workspace may contain more than one shape of the same object at once (rule::1.0 next to rule::1.1, and the same for any later revision of any family). Validation, deployment, and every other feature MUST follow the shape the file declares. Supporting a revision means the whole product can read it, not only the schema check.
Requirements
- Every Tide object MUST declare
metadata.schemaas a registered schema identifier ({family}::{major}.{minor}). - Every Tide object MUST declare
metadata.versionas a business version (semver string or integer). - Consumers MUST NOT use
metadata.versionto choose a schema. - More than one revision of the same family MAY coexist in one workspace.
- A breaking structural change MUST introduce a new schema identifier and a new spec file. The previous revision stays valid for files that still declare it.
- Git is the history of instance content. No
revisions.jsonindexer is required. - An implementation MUST register a model for every schema identifier it claims to support. A class or pin table that is not registered is not a supported revision.
- Validation, deployment, documentation, export, query validation, promotion, sharing, and editor validation MUST use the model selected by
metadata.schema. They MUST NOT assume a single shape per object family. - A missing or unknown
metadata.schemaMUST be an error. The implementation MUST NOT substitute the newest revision of the family. - Loading an object MUST check it as declared. Changing
metadata.schemaMUST be an explicit migration. Validate, deploy, and the other features MUST NOT rewrite it as a side effect. - A migration, when the implementation provides one, MUST move forward only. It MUST set
metadata.schemato the target revision and MUST NOT changemetadata.version. - Each registered revision MUST have its own JSON Schema and its own template. A filename that includes a revision (
rule.1.0.schema.json) MUST contain that revision only. - When a family has more than one registered revision, editor validation MUST choose the schema from
metadata.schema. Mapping a whole object folder to one schema file is not enough. - Authors adopt a new revision one object at a time. Shipping a revision MUST NOT require every file in the repository to change in one step.
Definition
Schema identifier
| Component | Format | Example |
|---|---|---|
| Family | lowercase object type | rule, threat, objective |
| Revision | {major}.{minor} | 1.0 |
| Full identifier | {family}::{major}.{minor} | rule::1.0 |
Artifact naming
| Artifact | Path pattern | Example |
|---|---|---|
| JSON Schema | .opentide/schemas/{family}.{major}.{minor}.schema.json | rule.1.0.schema.json |
| YAML template | .opentide/templates/{family}.{major}.{minor}.template.yaml | rule.1.0.template.yaml |
| IDE router | .opentide/schemas/opentide.schema.json | routes objects by metadata.schema |
Each per-revision JSON Schema MUST pin metadata.schema as a const.
How a feature reads an object
- Resolve — read
metadata.schemaand take the registered model for that identifier. - Check — validate the object against that model.
- Use — read fields where that revision puts them. A
rule::1.0deploy readsconfigurations.<platform>. A later rule revision reads the platform block where its spec puts it. Description, status, and links follow the same rule.
Migration is not part of that read. It is a separate action that rewrites one object onto a newer revision and then stops. The next read follows the identifier the migration wrote.
Coexistence
When a new revision ships, the previous one stays registered beside it. Generation emits an artifact for each. Objects opt in by setting metadata.schema. A file that still declares the old identifier keeps working, for deployment as well as validation, until someone migrates that file.
Relationships
- metadata.md —
metadata.schemaandmetadata.version - validation.md — the schema check is one consumer of this contract
- deployment.md — deployment is another; it uses the declared revision's fields
- sharing.md — sharing is another; it carries the document as declared
- workspace.md — where schemas and templates are written
- Object specs under
objects/— one spec per revision
Defaults & overrides
Path defaults live in bundled paths.toml. Clients MAY override paths via configuration.md. They MUST NOT point two revisions at one schema file. Files under .opentide/schemas/ MUST NOT be hand-edited.
Examples
- A rule on
rule::1.0: fixtures/valid/rule-1.0.yaml - A rule on
rule::1.1: fixtures/valid/rule-1.1.yaml - An unknown identifier: fixtures/invalid/rule-unknown-schema.yaml
A workspace that holds both valid rules validates each against its own identifier: the rule::1.1 file may carry metadata.reviewed, the rule::1.0 file may not. It deploys each from the platform block its revision defines (configurations.<platform> for both).
History
| Version | Date | Notes |
|---|---|---|
| 1.1 | 2026-10-19 | Every feature follows metadata.schema, not only validation. Missing schema is an error. Migration is explicit and does not change metadata.version (specifications#27). |
| 1.0 | 2026-06-25 | Initial spec bootstrapped from opentide SCHEMA_REVISION.md |