버전 관리
Versioning and compatibility policy
이 페이지는 영어입니다. 하나의 언어로 유지된 사양은 하나의 내용만 말합니다.
1. What is versioned, independently#
| artifact | version lives in | current |
|---|---|---|
| language specification (standard library included) | t0_compiler::LANGUAGE_VERSION (0.1.2 programs are still compiled as such) |
0.2.0 |
| compiler implementation | t0-compiler crate version (= COMPILER_VERSION) |
0.1.1 |
| IR format and semantics | t0_ir::IR_VERSION (accepted: >=0.1.0, <0.2.0) |
0.1.7 |
| runtime implementation | t0-runtime crate version |
0.1.1 |
| host API (per host) | manifest host.api_version (ttt) |
0.1.5 |
| each contract | ContractDesc.version |
workspace 0.1.3; market 0.1.1; backtest 0.1.3; features 0.1.0; research 0.1.2; capabilities 0.1.0 |
| manifest format | HostManifest.manifest_format |
1 |
| CLI machine-readable output | format field of every --json result |
t0-cli/1 (docs/tooling/cli.md) |
| diagnostic codes | docs/language/diagnostics.md |
stable: a code is never reused for another meaning |
0.1.0 → 0.1.1 (2026-10-09), all compatible under the 0.x rule below: the
standard library modules text, list, decimal, time, fin, ind
(new IR builtins, so the IR moved too; a 0.1.0 runtime refuses an artifact
using them instead of misreading it); new ttt operations and the
research contract (docs/api/host-api.md §5). One correction:
nesting deeper than 128 levels is now refused with E-SYN-TOO-DEEP;
before, such a program was not accepted either — it overflowed the stack
and aborted the process.
Host API 0.1.1 → 0.1.2 (2026-10-10), compatible: backtest 0.1.2 and
research 0.1.1 return explicit errors at limits that did not exist
(E-BT-CAPACITY, E-BT-TOO-MANY, at most 64 research features). A program
that never hit them behaves the same; one that did would have exhausted
the terminal instead. The runtime's memory budget (E-RT-LIMIT-MEMORY) is
an execution limit like fuel, not a language change.
IR 0.1.6 → 0.1.7 (2026-10-29), compatible: a strategy may declare the history it must run over before its first order, warm_up 220 days; (or warm_up entry_days days;, an Int parameter): its handlers build their memory from the bars they are shown, which no signal reveals. The signal graph carries it (SignalGraph.warm_up, written only when declared); language 0.2.0 is unchanged (a program that says lang ">=0.1.0, <0.2.0" cannot use it: E-VER-FEATURE). A reader of 0.1.6 ignores the field, so it would run such a strategy without the warm-up: hosts that need it must require IR 0.1.7. E-STRAT-WARM-UP.
IR 0.1.5 → 0.1.6 (2026-10-24), compatible: @param gains switch: true (an Int that is 1 or 0) and off: N (the value that means a filter is off) (ADR-0016); the signal graph carries off (ParamTune.off, written only when present). A reader of 0.1.5 ignores the field.
Language 0.2.0 and IR 0.1.4 → 0.1.5 (2026-10-23), compatible: a strategy parameter may be decorated, @param(min: …, max: …, …) (ADR-0015), and the signal graph carries the range (StrategyParam.tune, written only when present).
A program that says lang ">=0.1.0, <0.2.0" cannot use one (E-VER-FEATURE); an artifact with none is written exactly as before.
Language 0.1.2 → 0.2.0 and IR 0.1.2 → 0.1.3 (2026-10-18), compatible for every program that says lang ">=0.1.0, <0.2.0" (it is compiled as 0.1.2, with none
of what 0.2 added -- the 52 shipped examples of 0.1 give the same results): strict mode, if let/while let, Map<K, V>, user modules, var/set, books,
handlers, order types and options. The IR gains the Map type and its builtins, and nothing an artifact without them is written differently for. The decision
on the version number (it was left open): the IR moves by a patch, as it did for the standard library in 0.1.1 -- an older runtime refuses an artifact that uses the
new type or builtins (it cannot read them) instead of misreading it, and an artifact that uses none of them reads exactly as before. Modules do not touch the IR
(a program and its modules are one text, and the artifact hashes it all); handlers travel as a program inside the strategy definition, not in the IR of the language.
Language 0.1.1 → 0.1.2 and IR 0.1.1 → 0.1.2 (2026-10-14), compatible: an entry may carry its own take-profit and stop-loss, order(…, Protect.Bracket(take_profit, stop_loss)) (docs/language/specification.md). New syntax: every program accepted before is accepted and means
the same. In the IR a rule's action gains one optional field, protect, written only when there is one; an artifact that has it says IR 0.1.2,
and Protect reserves no name. The host's part -- leaving the two as resting orders on the account -- needs no contract change.
In the same 0.1.2, and as compatible: a part of a position may be closed (Intent.Reduce with Sizing.PercentOfPosition), the stop and the
target resting on an open position may be set or moved (protect(…), a new action beside order(…)), and a value may be held from the entry
(at_entry(x), a new prelude function and IR node). An artifact that uses none of them is written as it was.
Host API 0.1.8 → 0.1.9 (2026-10-14), compatible, with one correction decided as such: features 0.1.4 adds the bar still forming
(forming_open/high/low/volume/delta). The correction: features.volume, cvd, bar_delta and the min_volume of
inferred_absorption_sell_side are now in units of the instrument; they were in the engine's internal integer scale (10^-8), which was documented
nowhere and contradicted both an order's size and the shipped example that used min_volume. By the table in §3 a change of meaning is breaking;
this one was taken as a correction of an undocumented defect instead, knowingly, so that programs keep loading -- at the price that a program which
compared one of these against a number in the old scale now reads another thing without being refused (docs/api/host-api.md §5).
Host API 0.1.4 → 0.1.5 (2026-10-10), compatible: a new contract, event 0.1.0 (event.current), and nothing
else; no existing contract or operation changed.
Host API 0.1.3 → 0.1.4 (2026-10-10), compatible: workspace.close_chart and
workspace.close_panel (new operations; no existing one changed).
Host API 0.1.2 → 0.1.3 (2026-10-10), compatible: new operations
(workspace.chart/open_chart/focus_chart/panel_kinds/panels/open_panel/ focus_panel, backtest.trades_page), a new contract (capabilities),
research.market_state now cancellable, and market.candles refusing
before reading a range too large to answer (it was refused after reading
before). No signature or meaning of an existing operation changed.
A TTT release number never stands in for any of these.
2. Version and range syntax#
- Versions are
MAJOR.MINOR.PATCH, non-negative integers, no pre-release or build suffixes in v0. - A range is a comma-separated list of comparators that must all hold:
=V,>=V,>V,<=V,<V. Example:">=0.1.0, <0.2.0". - No
^,~,*or bare versions: they mean different things in different ecosystems (E-VER-SYNTAX).
3. What counts as breaking#
Semantic versioning with explicit 0.x rules: while MAJOR is 0, a MINOR
bump is breaking and a PATCH bump is compatible. From 1.0, MAJOR is
breaking and MINOR is additive.
| artifact | breaking | compatible | corrective (patch) |
|---|---|---|---|
| language | rejecting a program previously accepted; changing the meaning or result of an accepted program (including numeric rounding) | accepting new programs (new syntax, new prelude function) | fixing the compiler to match this spec |
| IR | any change an older reader could misread or that a newer reader must reject; changing an operation's semantics | new optional fields readers can ignore safely | — |
| contract | removing or renaming an operation or type; changing a parameter or return type; changing semantics; adding a required field; adding an enum variant (exhaustive matches in older programs would break) | adding an operation | documentation, message text |
| host API | removing a contract or moving a contract to an incompatible version | adding a contract | — |
A semantic change in financial computation (rounding, fees, fill rules) is always breaking, even if no signature changes.
4. Checks before execution#
- The program's
langrange contains the compiler'sLANGUAGE_VERSION. - The artifact's
ir_versionis within the runtime's accepted range. - The
hostname equals the manifest's host, and its range contains the manifest'sapi_version. - For each
requires: the manifest has the contract at a version inside the declared range, compatible with the version the artifact was checked against — same major, same minor while the major is 0, and not older (Version::is_compatible_with). A host that movedworkspacefrom 0.1.0 to 0.1.1 still runs artifacts built against 0.1.0; one that moved it to 0.2.0 refuses them (E-CAP-VERSION: recompile and review). - Needed permissions ⊆ session grants.
- Every used operation is available now.
A host version inside a declared range does not imply every operation is available (check 6 is separate).
5. Deprecation and migration#
- An operation marked
deprecated { replacement, removal }still works; the compiler warnsW-DEPRECATEDnaming the replacement and the removal version. Removal is a breaking contract change. - Artifacts are not migrated: an artifact whose versions no longer match is
recompiled from source. Old programs are never reinterpreted under new
financial semantics; a program's
langrange pins it. - Automated source migration (planned with the language server) may only
apply meaning-preserving rewrites and never adds
requireslines, permissions, or removes checks.