Stability Policy
Terminology: This specification uses RFC 2119 keywords (MUST, SHOULD, MAY, etc.) to indicate requirement levels.
This document defines Structyl's stability guarantees and versioning policy.
Version Numbering
Structyl follows Semantic Versioning 2.0.0:
- MAJOR (X.0.0): Breaking changes
- MINOR (0.X.0): New features, backward-compatible
- PATCH (0.0.X): Bug fixes, backward-compatible
Compatibility Types
Source Compatibility
Source compatibility means existing code using Structyl APIs continues to compile and work without modification.
Guarantees:
- Public Go API (
pkg/*) signatures MUST NOT change within a major version - Configuration schema MUST NOT remove or rename required fields within a major version
- CLI command syntax MUST NOT change within a major version
Allowed changes in minor versions:
- Adding new optional configuration fields
- Adding new CLI flags with sensible defaults
- Adding new functions to public Go packages
- Adding new CLI commands
Behavioral Compatibility
Behavioral compatibility means existing behavior is preserved even if not explicitly documented.
Guarantees:
- Exit codes MUST NOT change meaning within a major version
- Default behavior MUST NOT change within a major version
- Error message formats defined in the Error Message Grammar MUST NOT change within a major version
Allowed changes in minor/patch versions:
- Improved error messages (wording, not structure)
- Performance improvements
- Bug fixes that align behavior with documentation
Configuration Compatibility
Forward Compatibility: Older Structyl versions SHOULD be able to read configurations from newer versions. Unknown fields are ignored with a warning (see Extensibility Rule 3).
Backward Compatibility: Newer Structyl versions MUST be able to read configurations from older versions without error.
Deprecation Policy
Timeline
- Deprecation notice: Feature marked deprecated with replacement documented
- Minimum notice period: One minor version (at least 3 months)
- Removal: Earliest in next major version
Deprecation Markers
Go code:
// Deprecated: Use [NewFunction] instead. Will be removed in v2.0.0.
func OldFunction() {}Configuration:
{
"old_field": "...", // Deprecated: use new_field instead
"new_field": "..."
}Structyl logs warnings when deprecated features are used.
Current Deprecations
| Feature | Deprecated In | Removal Target | Replacement | Reason |
|---|---|---|---|---|
CompareOutput function | v1.0.0 | v2.0.0 | Equal | Clearer function name |
FormatDiff function | v1.0.0 | v2.0.0 | FormatComparisonResult | Better semantics (empty string on match, diff on mismatch) |
NewCompareOptions function | v1.0.0 | v2.0.0 | NewCompareOptionsOrdered | Parameter order differs from struct field order |
SpecialFloatPosInfinity constant | v1.0.0 | v2.0.0 | SpecialFloatInfinity | Canonical form preferred ("Infinity" vs "+Infinity") |
new command (alias) | v1.0.0 | v2.0.0 | init | Standardize on init for initialization |
Maintenance Note
This table is synchronized with // Deprecated: comments in Go source code. If discrepancies arise between this table and the code comments, the code comments are authoritative. Run grep -r '// Deprecated:' pkg/ internal/ to list all deprecated symbols for verification.
Public API Surface
Stable (Covered by Guarantees)
pkg/structyl: Exit code constants (ExitSuccess,ExitFailure,ExitConfigError,ExitEnvError)pkg/testhelper: Test loading and comparison library (detailed below)- CLI commands and flags documented in commands.md
- Configuration schema documented in configuration.md
- Exit codes documented in error-handling.md
- Skip error reason identifiers:
disabled,command_not_found,script_not_found(see error-handling.md) structyl targets --jsonoutput format (see TargetJSON Structure below)- Diff path format: JSON Path notation (
$,$.foo,$.foo[0].bar) inCompare/FormatComparisonResultoutput (see test-system.md)
pkg/testhelper Stable Symbols
Types:
TestCase— Test case representation with builder methodsCompareOptions— Comparison configurationProjectNotFoundError,SuiteNotFoundError,TestCaseNotFoundError— Structured error typesInvalidSuiteNameError,InvalidTestCaseNameError— Validation error types
Sentinel Errors:
ErrProjectNotFound,ErrSuiteNotFound,ErrTestCaseNotFound— Forerrors.Is()matchingErrInvalidSuiteName,ErrInvalidTestCaseName— Forerrors.Is()matchingErrEmptySuiteName,ErrEmptyTestCaseName— Empty name errorsErrFileReferenceNotSupported—$filesyntax rejection
Test Loading Functions:
LoadTestSuite,LoadTestCase,LoadTestCaseByName,LoadTestCaseWithSuite— Load test casesLoadAllSuites— Load all suites as mapListSuites,ListTestCases— Discovery functionsFindProjectRoot,FindProjectRootFrom— Project root detectionNewTestCase,NewTestCaseFromJSON,NewTestCaseFromJSONWithSuite,NewTestCaseWithSuite— ConstructorsSuiteExists,SuiteExistsErr,TestCaseExists,TestCaseExistsErr— Existence checksValidateSuiteName,ValidateTestCaseName— Name validation
Comparison Functions:
Equal,EqualE— Boolean equality check (panic/error variants)Compare,CompareE— Equality check with diff path (panic/error variants)FormatComparisonResult,FormatComparisonResultE— Formatted diff output (panic/error variants)ULPDiff— ULP distance calculation for floats
Options Functions:
DefaultOptions— Default comparison optionsNewCompareOptionsOrdered— Constructor with validated parametersValidateOptions— Options validation
Constants:
ToleranceModeRelative,ToleranceModeAbsolute,ToleranceModeULP— Float tolerance modesArrayOrderStrict,ArrayOrderUnordered— Array comparison modesSpecialFloatNaN,SpecialFloatInfinity,SpecialFloatNegInfinity— Special float string representationsReasonPathTraversal,ReasonPathSeparator,ReasonNullByte— Validation rejection reasons
TestCase Methods:
Clone,DeepClone— Copy methodsWithName,WithSuite,WithDescription,WithInput,WithOutput,WithTags,WithSkip— Builder methodsID,HasSuite,TagsContain— Query methodsValidate,ValidateStrict,ValidateDeep— Validation hierarchy
CompareOptions Methods:
IsValid,IsZero— Validation and zero-value check
Unstable (May Change)
internal/*: All internal packages- Undocumented CLI behavior
- Debug output format
TestCase.String()output format (explicitly unstable, see code comment)CompareOptions.String()output format (explicitly unstable, see code comment)structyl targetsoutput format (intended for human consumption, not machine parsing)- Log and warning message wording (structure is stable, wording is not; includes
STRUCTYL_PARALLELvalidation warnings) - Panic message format in
pkg/testhelpercomparison functions (currently"testhelper.<FuncName>: <error>"but may change)
Breaking Change Process
Before a major version release:
- All breaking changes documented in CHANGELOG
- Migration guide provided
- Deprecated features removed only after notice period
- Beta period for community feedback (minimum 4 weeks)
Go Module Compatibility
Structyl follows Go module versioning conventions:
- v0.x.x and v1.x.x:
github.com/AndreyAkinshin/structyl - v2.x.x and beyond:
github.com/AndreyAkinshin/structyl/v2
Import paths change only at major version boundaries.
Exceptions
The following may change without major version bump:
- Security fixes: Critical security issues may require breaking changes
- Spec compliance: Aligning with external specifications (e.g., SemVer clarifications)
- Legal requirements: License or legal compliance changes
Such changes are documented in release notes with clear migration guidance.
TargetJSON Structure
The structyl targets --json command outputs an array of target objects with the following stable structure:
[
{
"name": "rs",
"type": "language",
"title": "Rust",
"commands": ["clean", "restore", "build", "test", "check"],
"depends_on": ["core"]
}
]| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Target identifier (e.g., "rs", "py", "img") |
type | string | Yes | Target type: "language" or "auxiliary" |
title | string | Yes | Human-readable name (required in config schema) |
commands | string[] | Yes | Available commands for this target (always present, may be empty) |
depends_on | string[] | Yes | Dependency target names (always present, may be empty array) |
Intentionally omitted fields:
toolchain: The target's toolchain is intentionally NOT included in the JSON output. Toolchain selection is an internal implementation detail that MAY change without affecting the target's public behavior. Usestructyl targets(human-readable format) to see toolchain information for debugging purposes.
This structure is stable and covered by the Source Compatibility guarantees. New optional fields MAY be added in minor versions.