본문으로 건너뛰기

버전 관리

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#

  1. The program's lang range contains the compiler's LANGUAGE_VERSION.
  2. The artifact's ir_version is within the runtime's accepted range.
  3. The host name equals the manifest's host, and its range contains the manifest's api_version.
  4. 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 moved workspace from 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).
  5. Needed permissions ⊆ session grants.
  6. 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 warns W-DEPRECATED naming 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 lang range pins it.
  • Automated source migration (planned with the language server) may only apply meaning-preserving rewrites and never adds requires lines, permissions, or removes checks.