Compatibility Policy
Draft
This policy is at draft status. It reaches stable status at v1.0 GA. Before v1.0 GA, individual sections may be amended via RFC or Senior Project Architect decision; changes are noted in CHANGELOG.md.
1. Purpose and Scope
This document defines the compatibility warranty for openLogForge and its supported file formats. It governs three areas:
- Community
.olfformat - the open use case exchange format - Premium
.olf-premiumformat - the encrypted content pack format - Application - API, database, and Docker configuration stability
This policy is binding from v1.0 GA onward. Pre-GA (v0.x) releases guarantee compatibility only within the same minor version (e.g., v0.5.0 → v0.5.3 is safe; v0.5.x → v0.6.x may break).
2. Compatibility Warranty
The following warranty applies from v1.0 GA:
Backward compatibility guarantee - within any major version
Any .olf or .olf-premium file that was valid and importable on app vN.0 will import cleanly on any vN.x release (where x ≥ 0).
Minor and patch releases of the app never introduce breaking format changes.
Major version boundary
At a major version increment (vN.x → v(N+1).0), breaking changes to .olf and .olf-premium formats are permitted. A migration guide is published with the major release. Entitlement to new major versions requires active annual maintenance. Customers on a perpetual-only license (no active maintenance) retain full compatibility with the major version they purchased; they are not entitled to the new major version until maintenance is purchased or renewed.
This means customers and contributors can reason about compatibility using only the application major version number - no separate format version tracking required.
3. Versioning Scheme
3.1 Application (semantic versioning)
openLogForge releases follow Semantic Versioning 2.0.0:
| Increment | Meaning | Format change allowed? | Upgrade procedure |
|---|---|---|---|
| MAJOR | Breaking changes permitted | Yes - .olf and .olf-premium schemas may change |
Read migration guide |
| MINOR | New features, additive changes only | No - format is frozen within major version | docker compose pull && docker compose up -d |
| PATCH | Bug fixes and security patches | No | docker compose pull && docker compose up -d |
3.2 Community format (olf_version)
The olf_version field major number tracks the application major version. They are not independently versioned:
| App version series | olf_version major |
Meaning |
|---|---|---|
| v1.x | 1 |
All v1.x releases share format major 1 |
| v2.x | 2 |
A v2.0 release may introduce a new format major |
The minor part of olf_version (e.g., 1.2) is informational - it records which minor app version last changed the schema. It is not a compatibility gate: any olf_version: "1.x" file is guaranteed to import on any app v1.x.
Current value: "1.0".
3.3 Premium format (schema_version)
Premium bundles carry one version field in manifest.json:
| Field | Meaning | Behaviour |
|---|---|---|
schema_version |
Schema/structure version of the bundle manifest | Strict exact-match: the application accepts only the currently known value. Any other value is OLF_PREMIUM_VERSION_UNSUPPORTED. |
Current value: "1". Unlike community olf_version, there is no minor-version tolerance for schema_version - this is intentional because the manifest governs cryptographic key derivation and decryption. See olf-format.md §schema_version Versioning for the rationale. There are no olf_premium_format_version or min_app_version fields; those were superseded by the current design.
4. Community .olf Compatibility
4.1 Parser behaviour
| Condition | Behaviour |
|---|---|
olf_version major matches app major |
Import normally |
olf_version minor higher than app knows (same major) |
Warn in UI that unknown fields were ignored; import proceeds - backward compat guarantee applies |
olf_version major higher than app major |
Hard stop: "This use case requires a newer version of openLogForge." |
olf_version major lower than app major |
Import with migration notice; app converts to current schema on import |
| Unknown fields | Ignored with warning - never a hard failure |
| Missing optional fields | Handled with defaults |
| Missing required fields | Hard stop with validation error listing missing fields |
4.2 What is a breaking change
Only changes that violate the backward compatibility guarantee require a major version increment. This can only happen at an app major release:
Breaking (major version boundary only):
- Removing or renaming a required field
- Changing the type or semantic meaning of an existing field incompatibly
- Restructuring the top-level document layout
- Removing a previously allowed enumerated value
Additive (permitted in any minor or patch release):
- Adding new optional fields (top-level or nested)
- Adding new allowed enumerated values (if old apps ignore unknown enum values safely)
- Adding new optional classification or metadata fields
- Documentation and example updates
4.3 Schema evolution process
All format changes - additive or breaking - must be proposed via RFC before implementation. The RFC must specify:
- Whether the change is additive or breaking
- The new
olf_versionminor value (for additive) or major value (for breaking) - Updated schema and examples
docs/content/spec/olf-format.md is updated as part of RFC approval. The compatibility matrix in §7 is updated with each release.
5. Premium .olf-premium Compatibility
5.1 Format versioning warranty
The same major-version warranty applies to .olf-premium:
- Within app v1.x: any v1.0-valid bundle imports on v1.5 without modification
- At v2.0: the bundle format may change; existing bundles can be re-downloaded from
premium.openlogforge.comin the updated format using the original license key UUID
5.2 Import compatibility checks
The premium activation engine checks compatibility in the mandatory order defined in olf-format.md §Activation Flow. All failures return OLF_ACTIVATION_FAILED with a generic message; step-specific messages are not disclosed. The high-level checks are:
| Phase | Check | Error code |
|---|---|---|
| Step 0 | manifest.json present and parseable; schema_version exactly "1"; required fields present with correct types |
OLF_PACKAGE_INVALID / OLF_ACTIVATION_FAILED / OLF_PREMIUM_VERSION_UNSUPPORTED |
| Step 2 | License key fingerprint matches manifest (constant-time) | OLF_ACTIVATION_FAILED |
| Step 3a | Ed25519 signature on license.lic valid (Keygen.sh public key embedded at build time) |
OLF_ACTIVATION_FAILED |
| Step 3b | Bundle-license binding cross-check (constant-time) | OLF_ACTIVATION_FAILED |
| Step 3c | Duplicate activation check (bundle_id not already active) |
OLF_ACTIVATION_FAILED |
| Steps 4-5 | HKDF key derivation, AES-256-GCM decryption, schema validation | OLF_ACTIVATION_FAILED |
See olf-format.md §Activation Flow for the normative step definitions and ordering constraints.
5.3 Purchase entitlement - perpetual and version-spanning
A one-time purchase of a content pack entitles the customer to all future versions (minor and major) of that pack. The license key UUID is the permanent entitlement and never expires.
When a new version of a pack is released:
| Version type | What changes | Customer action |
|---|---|---|
| Minor - bug fixes, typo corrections | Bundle re-signed with same format | Optional re-download from portal using license key UUID |
| Major - new format, new app required | olf_premium_format_version or min_app_version updated |
Update app; re-download bundle from portal |
5.4 App upgrade - no reimport required
Updating the app (Docker pull and restart) never requires reimporting existing premium bundles. Imported use case data lives in SQLite and is unaffected by app updates. Reimport is only needed when deploying to a new instance or after deliberate deletion.
6. Application Compatibility
6.1 REST API (/api/v1/)
| Change type | Within minor/patch | At major version |
|---|---|---|
| Remove or rename a response field | Not permitted | Permitted with deprecation notice |
| Add optional response field | Permitted at any time | Permitted |
| Add optional request field | Permitted at any time | Permitted |
| Change endpoint URL or method | Not permitted | Permitted (new version prefix, e.g., /api/v2/) |
API stability: v1 reaches stable status at v1.0 GA. Before GA, breaking API changes may occur on minor version releases with explicit announcement in release notes.
6.2 Database (SQLite + Alembic)
| Operation | Support |
|---|---|
| Upgrade to newer minor or patch | Alembic migrations run automatically on startup |
| Upgrade to new major version | Migration guide published; Alembic handles schema changes |
| Downgrade to prior version | Not supported - restore from backup |
Run scripts/backup.sh before any major version upgrade.
6.3 Docker Compose configuration
Breaking changes (renamed services, changed volume paths, removed required environment variables) occur only at major version releases, documented in the migration guide. Minor and patch releases may add new optional environment variables with documented defaults.
6.4 Supported versions for security fixes
Only the latest stable release receives security fixes.
7. Signing Key
Premium bundles are verified against a single Ed25519 public key embedded in the application binary at build time. There is no key_id field and no growing key set - exactly one verification key is in scope per application build.
| Rule | Detail |
|---|---|
| Rotation | If Keygen.sh rotates their signing key, a patch release is required to update the embedded constant. The Senior Security Officer coordinates rotation with Keygen.sh and triggers the patch release. |
| No retirement set | Because exactly one key is embedded at a time, rotation replaces the constant rather than appending to a set. Bundles signed under a rotated-out key require re-issuance and re-download from the portal. |
| Compromise | Key compromise is treated as a security incident: an emergency patch release is issued with the replacement key, and all license holders are notified directly. |
The embedded key must be stored in a named constant (not inline at the verification call site) so that a key rotation patch changes exactly one location in the codebase. There is no compatibility concern for the key set across versions: the key embedded in a given binary version is the only valid key for that version.
8. Compatibility Matrix
Updated with each release. Cells marked TBD are confirmed when the corresponding version ships.
| App version | Community .olf format major (olf_version) |
Premium manifest schema_version |
Backward compat guaranteed from |
|---|---|---|---|
| v0.1 - v0.5 | 1 | 1 | Within same minor only (pre-GA) |
| v0.6 | 1 | 1 | Within same minor only (pre-GA) |
| v0.7 - v0.8 RC | 1 | 1 | Within same minor only (pre-GA) |
| v1.0 GA | 1 | 1 | v1.0 onward - full major-version guarantee |
| v1.x | 1 | 1 | Any v1.0-valid file imports on any v1.x |
9. Deprecation Policy
| Step | Requirement |
|---|---|
| Mark deprecated | Field or endpoint marked deprecated in spec or API docs |
| Notice period | Minimum two minor releases before removal (before GA: one minor release, stated explicitly) |
| Removal | Treated as a breaking change - only at a major version boundary |
| Communication | Deprecation notice in release notes for the release in which it is first marked |
10. Change Communication
| Channel | Used for |
|---|---|
CHANGELOG.md |
All changes; breaking changes marked [BREAKING] |
| GitHub Release Notes | Summary of breaking changes and migration steps |
| GitHub Discussions | Advance notice of planned breaking changes |
| Email (premium customers) | Direct notification of format changes or entitlement impacts |
This policy is maintained by the Senior Project Architect. Format schema changes require RFC. The compatibility matrix (§8) is updated as part of each release. This document reaches stable status at v1.0 GA.