---
title: "Release notes"
description: "Every change to Indicators in the om CLI's changelog, newest first, one section per release: the runtime and its four contracts, the sheet, the scaffold and…"
order: 95
section: "releases"
---

<!-- source: docs/indicators/releases/changelog.md; generated by packages/cli/scripts/gen-indicator-docs.ts, do not edit -->

# Release notes

Every change to Indicators in the `om` CLI's changelog, newest first, one
section per release: the runtime and its four contracts, the sheet, the scaffold
and templates, the chart lanes that draw Indicators, and the commands that
install, preview, and publish them. Entries that touch other parts of the
product stay in the full `CHANGELOG.md`. Where an entry names the old
language, kScript (legacy), it is the parity program that proved Indicator
ports of registry kScript indicators bit-exact; those ports are the rows
that carry a **New engine** badge on the chart. The kit's scaffold, runtime,
and marketplace commands predate the changelog's coverage, which begins at
v0.4.0.

| Version | Date | Highlights |
| --- | --- | --- |
| v0.398.1 | 2026-09-22 | `align` on label handles; the `hud-terminal` template; scaffold 14 |
| v0.392.5 | 2026-09-21 | live tape as a celled source class (`tape.cells`); scaffold 13 |
| v0.392.0 | 2026-09-21 | anchors on drawing handles (nine pane spots and four edges); scaffold 12 |
| v0.391.0 | 2026-09-21 | the fourth contract: frame snapshots, level profiles, panels, ladder / feed / meter widgets, series inputs |
| v0.390.0 | 2026-09-20 | `draw.card` |
| v0.366.0 | 2026-09-18 | a package that failed validation stops shouting on every command |
| v0.348.0 | 2026-09-17 | a live condition source reads a package operand on the bar it declared |
| v0.343.0 | 2026-09-16 | edge comparisons on package outputs carry their bar identity in condition sources |
| v0.337.0 | 2026-09-15 | one source tree for these docs, one full-text bundle |
| v0.290.0 | 2026-09-13 | the registry contract is one installed package; `om open` reads a kScript (legacy) package's real fields |
| v0.244.0 | 2026-09-08 | a strategy holds on a side that has gone quiet, by the package's own grid |
| v0.242.0 | 2026-09-08 | composable packages: a watch pack pins the Indicators its conditions read |
| v0.238.0 | 2026-09-07 | the default registry is staging until launch; priced listings |
| v0.234.0 | 2026-09-06 | the third contract: the whole TA library, mutable drawing handles, strategies, the last-bar flag |
| v0.224.0 | 2026-09-05 | one watch primitive: the `signal` noun and its verbs are gone |
| v0.221.0 | 2026-09-04 | one ledger of installed packages (`om packages`, `om uninstall`); `om install` updates in place |
| v0.200.0 | 2026-09-02 | `--version` on `om wrun remove` and `om wrun upgrade` takes a value |
| v0.193.1 | 2026-08-31 | a preview is not a placement |
| v0.191.1 | 2026-08-31 | a range's bare sign palette validates |
| v0.180.0 | 2026-08-30 | the visual vocabulary: renderer color and size, `bgcolor`, `ranges`, width ladders |
| v0.173.0 | 2026-08-29 | parity program closed: 167 of 177 registry indicators bit-exact |
| v0.171.0 | 2026-08-29 | sided liquidations, primary densification, `displacement_bars`, 32 renderers |
| v0.169.0 | 2026-08-28 | the parity factory; `missing: "nan"`; explicit `windowBars` |
| v0.167.0 | 2026-08-28 | celled sources, string slots, renderers, drawings; the authoring skill |
| v0.165.0 | 2026-08-27 | the second ABI; code-first authoring; the perf rig; probe-verified docs |
| v0.160.0 | 2026-08-27 | agent-authored sheets validate up front |
| v0.158.0 | 2026-08-26 | lower-pane previews; previews report their value range |
| v0.155.1 | 2026-08-24 | refusals name the alternative; value age on the package's own grid |
| v0.154.0 | 2026-08-20 | bindable Indicators preview with `--bind`; bindable limits enforced in code |
| v0.153.0 | 2026-08-20 | previews persist server-side |
| v0.150.0 | 2026-08-19 | bindable odds inputs: one package, any market |
| v0.149.0 | 2026-08-18 | a commissioned draft installs itself |
| v0.147.0 | 2026-08-18 | a failed compile no longer wedges the authoring loop |
| v0.138.0 | 2026-08-16 | previews print the chart URL |
| v0.135.0 | 2026-08-16 | `om chart indicator preview` |
| v0.134.0 | 2026-08-16 | yanks disclose, never disable; cross-symbol pins taught |
| v0.127.0 | 2026-08-15 | kScript (legacy) packages open on charts by reference |
| v0.123.0 | 2026-08-15 | Indicators plot as themselves from chat |
| v0.117.0 | 2026-08-14 | missed alerts fire late; the gap digest names Indicator legs |
| v0.111.0 | 2026-08-13 | the `time` source |
| v0.27.0 | 2026-07-30 | closed bars follow the venue's clock |
| v0.12.0 | 2026-07-23 | metric fetches bounded by a deadline |
| v0.4.0 | 2026-07-10 | backtests replay installed Indicators; package visibility; `om indicators` became `om metric` |

A release that is missing from this list changed nothing an Indicator
author can observe. To see what a release means for an installed machine,
[Releases overview](overview.md) has the upgrade checklist:

```bash
om upgrade
om wrun build ./my-indicator
```

## v0.398.1 (2026-09-22)

### Added

- **A label handle has an `align` word.** `left`, `center` or `right`
  (absent is center): the text edge that sits on the handle's x, with
  (x, y) staying the point. A sheet declares the default with
  `handles.label({ align })`; a code-first workspace gets the `ALIGN_*`
  constants and `.align(...)` on a live label (scaffold version 14), and
  the chart's `drawings` widget label item takes the same word.
- **The `hud-terminal` template.** A code-first template that draws a
  terminal-style HUD from inside the package: a title bar and a body box
  anchored top-left, four left-aligned label rows (last close, bar change,
  a 20-bar signed flow figure from side-split trade volume, a status line)
  rewritten only on the live bar, and a data-only flow output
  ([HUD terminal](../cookbook/hud-terminal.md)).

## v0.392.5 (2026-09-21)

### Added

- **Live tape as a celled source class.** A `tape` input reads the
  daemon's live trade stream as `[offsetMs, price, size, side]` cells per
  primary bar, at or above a required `min_size` in the trade's native
  amount; `history` other than `"0"` refuses by name
  (`wrun_tape_history_unavailable`), because the data plane has no raw
  trade lane. One rolling buffer per market (two hours or 200k prints,
  trade ids deduplicated) opens on first use and closes once the market
  goes idle; the alert tick, the indicator preview and in-daemon rule
  reads pass it to the compute, and a lane without one (a backtest
  replay, a one-shot CLI read) refuses `wrun_tape_unavailable`. Scaffold
  version 13 declares `tape.cells` and the `min_size` / `history` input
  facets ([Data sources](../core-concepts/data-sources.md)).

## v0.392.0 (2026-09-21)

### Added

- **Anchors on drawing handles.** A line, box, label or polyline handle
  may name an anchor: nine pane spots (`top_left` through `bottom_right`)
  or the four edges, in CSS pixels from the pane's content rectangle, so a
  HUD keeps its place while the chart pans. The kind declaration may carry
  a default (`handles.label({ anchor: "top_left" })`), `.anchor(ANCHOR_*)`
  sets it per handle and `ANCHOR_CHART` restores chart coordinates
  (scaffold version 12). The chart's `drawings` widget kind takes up to
  256 anchored items ([Drawing objects](../functions/drawing-objects.md)).

## v0.391.0 (2026-09-21)

### Added

- **The fourth contract: frames.** `abi_version: "wrun-4"` adds one
  import to the third contract, a frame channel: `frame(name)` declares up
  to 8 snapshot slots of at most 96 KiB each, `writeFrame(...)` in
  `finalize()` replaces the run's snapshot, and the sheet binds a frame to
  a docked level profile (`plot.levels`, up to 512 monotonic prices), a
  panel below or beside the chart (`panel.bars`, `line`, `scatter`,
  `histogram`, `pie`, `heatmap`, `table`, `tiles`) or a widget
  (`draw.ladder`, `draw.feed`, `draw.meter`). A `series` input (sheet
  only) reads a watch value or an installed series snapshot on your
  machine. The first three contracts stay frozen
  ([Drawing primitives](../functions/drawing-primitives.md)).

## v0.390.0 (2026-09-20)

### Added

- **Packages can declare a card.** `draw.card(...)` in the sheet's
  drawings binds rows to outputs (with a format), string slots or
  literals, a state from an output, a colour ladder and a countdown; the
  chart draws it from the newest complete row
  ([Drawing primitives](../functions/drawing-primitives.md)).

## v0.366.0 (2026-09-18)

### Fixed

- **A broken local package stops shouting on every command.** A package
  that failed validation logged its whole ABI reason to the terminal on
  every `om packages`, `om packages show`, chat turn or MCP call. The
  reason now goes to `runner.log`, the package row reads
  `failed validation · om wrun list says why · om wrun remove <id>`, and
  `om indicator list` names the remove verb beside each skipped package.

## v0.348.0 (2026-09-17)

### Fixed

- **A live condition source reads a package operand on the bar it
  declared.** A source declared `eval: closed` decides on closed bars
  only, and its built-in operands did; a `wrun/` operand was computed with
  no closed-bar cut, so the live tick folded a value that included the bar
  still forming, and a crossing on it could fire a bar before the backtest
  replay did. The live projection now takes the same cut, and a source
  whose primary operand is a package folds once per closed bar.

## v0.343.0 (2026-09-16)

### Fixed

- **Edge comparisons on package outputs carry their bar identity in
  condition sources.** An Indicator inside a `crosses_above` /
  `crosses_below` comparison arrived with no bar identity in the source
  lane, so the same-bar guard withheld the cross on every bar and the run
  reported a flat book as warm-up. The identities are threaded on the
  source replay path too, and the fold reads each operand by that
  operand's own bar.

## v0.337.0 (2026-09-15)

### Changed

- **One source tree for these docs.** The website shape is built from
  `docs/indicators` into ignored output with one full-text bundle
  (`llms-full.txt`); the published pages are unchanged.

## v0.290.0 (2026-09-13)

### Changed

- **The registry contract is one installed package.** The schema modules
  the registry used to copy from the SDK (the package spec, the metric id
  grammar, the watch condition and the wire shapes) live in
  `@openmarket/contracts`, and `om publish` reads the registry's contract
  version once per attempt, refusing on a major mismatch with one sentence
  naming which side to upgrade.

### Fixed

- **`om open @scope/name` on a kScript (legacy) package reads the
  resolve's real fields.** A package whose every version is discontinued
  says so and points at `package_show` for the author's note, and the
  chart title is the package's display name.

## v0.244.0 (2026-09-08)

### Changed

- **A strategy holds on a side that has gone quiet.** A strategy's rule
  reads an operand as not ready when its newest bar is older than one bar
  of that operand's own grid (a package's primary interval, otherwise the
  selector's), the way it reads an operand still warming up: a rule the
  fold can settle without that operand still acts, with the quiet side
  named in the strategy's health note.

## v0.242.0 (2026-09-08)

### Added

- **Composable packages.** A set of watches publishes as ONE package and
  installs as ONE watch (`om watch share --group <label>`, or `--ref
  <slug>` repeated with `--name`, the same flags on `om publish`); the
  pack carries each source, each step and the exact dependency pins, so an
  Indicator a condition reads installs first as an ordinary install of its
  own name. The example `examples/packages/btc-sma-desk` is a three-source
  composite with an Indicator-backed condition.

## v0.238.0 (2026-09-07)

### Changed

- **The default registry is staging until launch.** The CLI's default
  registry origin is `https://registry-staging.openmarket.xyz`;
  `OM_REGISTRY_URL` keeps overriding, and follows or shares minted against
  either OpenMarket registry keep resolving. Priced listings landed in the
  same cut: a manifest `pricing` tag is validated at publish and install,
  and `om install` on a priced listing you have not bought refuses with
  the price and `om buy @scope/name`.

## v0.234.0 (2026-09-06)

### Added

- **The third contract: feature parity with kScript (legacy).**
  `abi_version: "wrun-3"` adds a handle-keyed draw channel through which
  `finalize()` creates, mutates and deletes lines, boxes, labels and
  polylines across bars (500 live per kind, 1,500 in all, 256 points per
  polyline, 4,096 draw calls per row) and a last-bar flag (`bar.isLast()`)
  with a close-confirm rule that keeps a live session bit-identical to a
  full run; the sheet gains a `handles` map, a `label` renderer `position`
  and a `text` renderer `style`. The strategy channel rides the same
  contract: `strategy(...)` in the file, `strategy.long(...)` / `short` /
  `exit` / `close` builders in `finalize()`, the engine's own broker run
  by the host, the reserved `strategy.position` and `strategy.equity`
  outputs, and `om backtest` replaying the trade list from the same bars,
  params and sheet. The TA library grew from seven classes to the whole
  kScript catalog, 52 stateful classes in `src/sdk/ta.ts` (scaffold
  version 9). The first two contracts stay frozen
  ([Drawing objects](../functions/drawing-objects.md),
  [Strategies overview](../strategies/overview.md),
  [TA library](../functions/ta-library.md)).

## v0.224.0 (2026-09-05)

### Removed

- **The `signal` noun and its verbs.** One watch primitive replaced the
  `alert`, `signal`, `strategy`, `schedule` and `stream` nouns, their CLI
  verbs and their tools; an Indicator's consumers are watch conditions,
  screens, series and backtests. The hosted kScript (legacy) alerts bridge
  went with them: an alert on an Indicator is a watch on your machine
  ([Alerts](../functions/alerts.md)).

## v0.221.0 (2026-09-04)

### Added

- **One ledger of what is installed.** `om packages` lists every install
  as one row: the copy on disk, what it made here (the alerts an
  Indicator's metrics feed, watches, schedules, signals, strategies), the
  publisher, version, source, and tarball hash. `om packages list --outdated` is the `npm outdated` view, `om packages show` one
  package's field sheet, `om packages update` the latest version after
  one confirmation, and `om uninstall @scope/name` removes what a package
  made here and its copy after a card naming each object. `/packages` in
  `om chat` is the same ledger with update and uninstall keys; an alert a
  package made carries a `from @scope/name@version` row in `/alerts`.

### Changed

- **`om install` on an installed package updates it.** The same name at a
  newer version goes through the first install's path: an Indicator's
  copy is swapped and its alerts keep their pins, and the older copy
  retires once nothing living pins it. The same version with the same
  content answers "installed and up to date" and writes nothing.
  `--replace` stays for scripts. The update and uninstall cards bind the
  yes to the exact versions and objects they showed.

## v0.200.0 (2026-09-02)

### Fixed

- **`--version` on `om wrun remove` and `om wrun upgrade` takes a
  value.** Both used to print the CLI version and exit instead of reading
  the flag; the root now stops scanning for its own `-v, --version` at
  the first subcommand. `om --version` and `om -v` are unchanged.

## v0.193.1 (2026-08-31)

### Fixed

- **A preview is not a placement.** `om chart indicator preview` and the
  agent's `chart_indicator_preview` say so in the description and in the
  result note: the line is ephemeral, and mounting a package on a
  workspace is `om chart indicator add`.

## v0.191.1 (2026-08-31)

### Fixed

- **A range with `colors` and no `color_by` validates.** Two entries
  paint the band by the pair's per-bar orientation (the first where
  `upper` plots above `lower`, the second where it plots below); one
  entry paints everywhere. This matches what the chart host always
  rendered for the form; the conformance corpus pins the acceptance, and
  every other range refusal (`color_by` pairing, ladder caps, unknown
  outputs) is unchanged.

## v0.180.0 (2026-08-30)

### Added

- **Indicators can declare everything kScript (legacy) can draw.** Four
  additive fields close the visual gap an engine-confirmed audit found:
  `text` and `label` renderers take `color` and `size`; a `bgcolor`
  renderer tints per-bar backgrounds behind a firing gate, with an
  optional per-bar color ladder; sheet-level `ranges` declare true bands
  (an upper and lower pair with edge width, edge line style, `smooth`,
  and ladder tinting), the presentation sibling of `fills`; and outputs
  take `width_by` plus `widths` for per-bar line-width ladders. All four
  are code-first declarable (`render.bgcolor`, `range(...)`, output and
  renderer options), every refusal is named, every ladder follows the
  engine's floor-and-entry-0 rule with non-finite values producing
  nothing, and the cross-host conformance corpora carry accept and reject
  cases for the whole surface. Existing packages parse and behave
  byte-identically.

## v0.173.0 (2026-08-29)

### Added

- **The parity program closed: 167 of 177 eligible registry indicators
  proven bit-exact as Indicators.** The last nine fetchable families were
  ported and matched with a deviation of exactly 0 at every gated
  comparison record, after which the registry census was exhausted; the
  remaining 90 families are custody-held and verified against an
  independently rebuilt census snapshot. Across the program (219 frozen
  families, every port frozen and rebuild-proven before its holdout
  windows were captured), the 10 indicators outside the tally carry
  machine-typed causes, none a math divergence. Tranche 6 (33 of 35
  bit-exact over 40 families) rode the v0.172.0 cut without an entry of
  its own.

## v0.171.0 (2026-08-29)

### Added

- **Sided liquidations, a dense grid for sparse feeds, and a declared plot
  offset.** An input on `liquidations` accepts `side: "BUY" | "SELL"`
  (absent means the per-bar total of both sides), so long and short
  liquidation Indicators are expressible. `missing` accepts `"zero"`
  beside `"carry"` and `"nan"`, and on the PRIMARY input `"nan"` and
  `"zero"` densify a sparse feed (a liquidations-only package included)
  onto a dense interval grid whose phase is derived from the fetched
  rows, with named refusals for empty or mixed-phase fetches, metric
  composition sources, and session grids that shift with daylight saving.
  Outputs accept `displacement_bars` (the value at bar i is displayed at
  bar i + N), carried through the sheet and the render selection, honored
  by the parity comparator, and refused by name in chart previews until
  the chart wire carries it. Code-first `input()` and `output()` declare
  all three. The per-package renderer cap rose from 16 to 32; the 2 MiB
  expanded-result refusal stays the resource guard.
- **Parity tranche 5 and the re-port wave.** Forty more registry families
  ran through the factory (30 of 33 eligible bit-exact across the dev
  window and both post-freeze holdouts), and the ten previously failing
  rows were re-ported on the new primitives: all ten convert with zero
  divergent cells, the Ichimoku lagging span proven under a preregistered
  displacement alignment. Cumulative: 126 of 133 eligible registry
  indicators bit-exact across 170 frozen families. The porter cheat sheet
  and the reproducible harnesses ship in-repo under `tools/parity/`.

## v0.169.0 (2026-08-28)

### Added

- **The parity factory.** The machine that measures a kScript (legacy)
  indicator against its Indicator port shipped with its first frozen
  experiment: ten registry indicators frozen by name, version, and hash
  before porting, each rewritten as a code-first package on the second
  ABI and compared against the real engine over a dev window, two holdout
  windows captured only after the ports were frozen, and metamorphic
  variants. Nine of ten matched with a maximum deviation of exactly 0 on
  every comparable cell (Wilder RSI, 900-bar EMAs, CVD, and order-book
  pressure included); the tenth matched numerically and diverged only on
  liquidation long/short text, a data-plane gap closed in v0.171.0. Two
  runtime features rode along: an input source may declare `missing: "nan"` so a sparse secondary delivers NaN instead of carrying forward
  (absent keeps the old behavior, byte-identical), and compute callers
  may pass an explicit `windowBars`.

### Changed

- **`om metric get` no longer requires a venue for registry metrics**: an
  omitted `--exchange` resolves the coin's default listing. An Indicator
  metric with no venue named is refused rather than defaulted, because
  its source book (funding, open interest, candles) is the package's to
  state; name the venue for Indicator metrics.

## v0.167.0 (2026-08-28)

### Added

- **Indicators read footprints and books, write text, and draw.**
  (Recorded under v0.168.0 in the full changelog; shipped in this cut.)
  Celled source classes fetch live and exact-join the primary grid:
  `volume_profile` serves each bar's per-price `[low, high, buy, sell]`
  cells and `book` serves `block_size`-faceted `[price, size, side]`
  cells (`om block-sizes` lists a venue's widths). `finalize()` writes
  byte-capped per-bar text through generated `str_<slot>` senders; sheets
  declare renderers (`text`, `label`, `table`, `shape`, `stats_row`) and
  drawings (`line`, `box`, `polyline`, `label`) selected under one
  cross-host lifecycle with an accounted 2 MiB cap, and the chart backend
  vendors the same conformance corpus and parity fixtures so both hosts
  agree verdict for verdict. Code-first declarations cover the whole
  vocabulary (`input("profile", volume_profile.cells, ...)`, `string()`,
  `render.*`, `draw.*`), and the `vp-buy-share-codefirst` template
  scaffolds a working footprint Indicator in 20 non-blank lines. The
  first ABI stays frozen and byte-identical; backtests and screens refuse
  celled packages by name (`wrun_celled_metric_unsupported`) and name the
  consumers that do support them.

### Changed

- **Authoring has its own skill.** The authoring loop, the sheet dialect,
  input pins, bindable odds inputs, and chart styling moved out of the
  marketplace skill into a bundled authoring skill served index-first;
  the marketplace skill keeps install, mount, bind, repoint, remove, and
  publishing.

## v0.165.0 (2026-08-27)

### Added

- **The second ABI.** `abi_version` in the sheet selects the runtime
  contract (absent means the frozen first ABI, `wrun-1`). Modules on
  `wrun-2` read per-bar cell blocks through `wrun_arg_len` and
  `wrun_arg_bytes` with exact, statically validated signatures,
  `max_cells` enforced as a named refusal, and a packed transferable
  worker transport in both directions (no structured clone). In this cut
  celled packages installed with a named warning and their metrics
  refused with `wrun_cells_unavailable`; the celled data lane followed in
  v0.167.0.
- **Code-first authoring.** Declare params, inputs, and outputs in the
  typed source (`param`, `input`, `output` from `./sdk/declare`); the
  build derives the sheet (`generated_from` plus `source_digest`) and the
  accessors from one staged pipeline, scaffold version 3 migrates
  existing workspaces non-destructively, and the `sma-codefirst` template
  authors a moving average in 14 non-blank lines. Sheet-first authoring
  is unchanged.
- **A performance and parity rig.** A required direct-versus-worker
  bit-identity test over a committed module fixture, a benchmark with
  recorded dispersion and environment, a performance baseline with an
  advisory regression comparator (`docs/PERF_BUDGETS.md`), and an
  advisory CI lane. The packed transport measures 0.29 microseconds per
  bar in the worker, a 3.3x ratio over direct calls, down from about 10x.
- **Probe-verified docs.** `docs/indicators/` (getting started, the SDK
  and sheet references, sources, styling, publishing, the kScript port
  guide), generated into `docs/llms-full-indicators.txt` and the skill's
  teaching regions by one writer; every fenced sample compiles through
  the real build in CI.

## v0.160.0 (2026-08-27)

### Fixed

- **Agent-authored sheets validate up front.** The agent's `wrun_author`
  tool validates its metadata argument against the package schema before
  writing, part of the turn-context lifecycle work that also sanitizes
  provider failures and refuses oversized tool arguments early.

## v0.158.0 (2026-08-26)

### Added

- **Lower-pane previews.** `om chart indicator preview` accepts `panel: "lower"` outputs: the wire's series gains an optional `panel` field
  (absence keeps the price-pane overlay byte-identical), and preview-aware
  chart frontends render the line in its own sub-pane with its own
  y-range, where momentum-class values are readable.

### Fixed

- **Previews report their drawn value range.** An overlay preview shares
  the pane's price axis, so a 0..1 output on a price pane draws
  off-screen; the receipt now carries `valueRange` (min, max, last finite
  value, trailing-null count) and the note says to compare it with the
  pane's scale instead of claiming a visible line.

## v0.155.1 (2026-08-24)

### Changed

- **Refusals name the alternative.** An import rejection lists the
  runtime's legal import set and how to declare a host call
  (`@external("wrun", "<name>")`). `om chart indicator add` refuses an
  unpublished package up front with `wrun_add_unpublished` (the hosted
  chart mounts packages by registry reference, so a local install used
  to fail only at render time), pointing at `om chart indicator preview`
  for local drafts or publish-then-add; a registry install made before
  install receipts existed reads as unproven, and the message names the
  `--replace` reinstall that stamps its receipt.
- **An Indicator value's age counts on the package's own bar grid**, and
  `om metric screen` renders `data_age_seconds` in text the way `om metric get` does.

## v0.154.0 (2026-08-20)

### Added

- **Bindable Indicators preview and author on the first try.** `om chart indicator preview` gains a repeatable `--bind` sharing `om metric get`'s parser (the agent's tool accepts `sourceBindings`), validated
  before any workspace call or data fetch, so an unpublished bindable
  draft draws through local compute; the receipt echoes the resolved
  binding, because the drawn odds line is not self-identifying. The
  agent's `wrun_author` ships the exact bindable-odds sheet shape as a
  validated example, and the skill teaches the follow-up: ask the market,
  prove a value with a bound `om metric get`, then the alert.

### Changed

- **Bindable-package limits are enforced in code, not prose.** `om chart indicator add` refuses bindable packages with a typed error (the hosted
  overlay carries no market binding, so a mounted one would never
  compute), and `om wrun source set` refuses to repoint a bindable input
  before touching the sheet; it previously wrote first and validated
  after.

## v0.153.0 (2026-08-20)

### Changed

- **Previews persist server-side.** Indicator previews, Strategy Tester
  panels, and event pins live in the platform's payload store, so the
  chart tools stop warning about viewers whose daemon is off; the
  daemon's re-push remains a cache that heals a missed store write.

## v0.150.0 (2026-08-19)

### Added

- **One package, any market.** An odds input can declare `binding: "required"` instead of hard-wiring a Polymarket market at authoring
  time: the market (a conditionId, with an optional YES or NO outcome)
  arrives per use, as `sourceBindings` beside `params` on alert and
  signal operands and metric queries, or as `om metric get --bind input=0x...`. Publish refuses odds inputs still pinned to the template's
  placeholder conditionId, which computed zero rows forever.

### Fixed

- **Previews survive restarts and joins.** Indicator previews persist
  before broadcast and replay to viewers who join later.

## v0.149.0 (2026-08-18)

### Added

- **A commissioned draft installs itself.** The agent's `wrun_build`
  installs the draft it authored (idempotent across rebuild loops) and
  returns a receipt with the one-command undo, instead of asking you to
  install your own artifact. Registry installs stay approval-gated;
  publish is unchanged.

## v0.147.0 (2026-08-18)

### Fixed

- **A failed compile no longer wedges the agent's authoring loop.** A bad
  build used to leave its broken artifact behind, and every later
  `wrun_author` call re-validated the stale file and threw a misleading
  missing-export error at once. Authoring validation treats a bad
  artifact as a warning (the source is the authoring truth), the build
  runner deletes artifacts on a compile or export-validation failure, and
  the missing-export error lists the artifact's actual exports and
  restates the four-export contract.

## v0.138.0 (2026-08-16)

### Fixed

- **`om chart indicator preview` prints the chart URL** and states the
  ordering that mattered at the time: open the chart before pushing,
  because previews broadcast live and did not replay to late joiners
  (v0.150.0 added the replay).

## v0.135.0 (2026-08-16)

### Added

- **`om chart indicator preview`: draw an unpublished Indicator on a
  chart.** The daemon computes ONE output of any locally installed
  package (drafts from `om wrun install` included) and pushes the
  finished series to a chart pane as an ephemeral preview line: no
  publish, no run authorization, no server compute. The preview is pinned
  to the pane's symbol and interval at compute time, so viewers on any
  other interval see a stale badge, never a recomputed line. One preview
  per pane: re-running replaces it, `--clear` removes it, a reload clears
  it. Typed refusals name the remedy: a bare package reference (a preview
  draws exactly one output), non-line outputs, chart-only or unserved
  intervals, packages whose primary input pins another interval,
  unattached workspaces, all-warm-up windows.

## v0.134.0 (2026-08-16)

### Added

- **Yanked packages disclose, never disable.** A publisher yanking a
  package your alerts pin cannot switch those alerts off (a remote
  disable would be a griefing lever); the daemon sweeps the registry
  daily over the fleet's pins, pushes one durable notice per yanked
  version, and `om alert list` and `om doctor` carry the disclosure from
  the cache. Installed copies keep evaluating.
- **Cross-symbol input pins are taught.** Packages could always read a
  fixed reference market on a secondary input (`symbol` + `exchange` on
  an input source); the skills, `wrun_author`, and the docs now teach the
  capability and its safe shapes. The guidance at the time fenced
  `interval` pins off; the as-of-close join that makes a coarser pin safe
  landed later and is the rule
  [Script definition](../functions/script-definition.md) documents today.
  Zero engine changes.

## v0.127.0 (2026-08-15)

### Added

- **kScript (legacy) packages open on charts by reference.** `om open @scope/name` resolves a registry kScript package to its platform script
  id and opens the chart with the indicator applied (`--print` for the
  URL only), and `om chart indicator add --type @scope/name` places it on
  a live workspace chart. Nothing installs or executes locally; the
  publishing guide states the rule for choosing between a kScript package
  and an Indicator.

## v0.123.0 (2026-08-15)

### Fixed

- **Indicators plot as themselves from chat.** Asking the agent to put a
  marketplace Indicator on the chart no longer walks the picker through
  "Simple Moving Average", and the tool contract says one add mounts the
  whole package (every renderable output), so agents stop stacking one
  overlay per output.

## v0.117.0 (2026-08-14)

### Added

- **Missed alerts fire late instead of never.** After downtime the runner
  re-evaluates the unseen closed bars (up to 7 days) with the cooldown,
  once-mode, and edge-debounce gates applied at each bar's close; the gap
  digest reports what could not be verified, Indicator legs included,
  because an Indicator's metric history is not replayed for the
  catch-up.

## v0.111.0 (2026-08-13)

### Added

- **Indicators can read the clock.** Modules receive each bar's open
  timestamp as a host-supplied input (the `time` source, field
  `bar_open_sec`), so calendar and session logic (day-of-week gating,
  session windows, anchored levels such as a prior session's close) is
  expressible inside the sandbox, deterministically: live evaluation and
  backtest replay see identical series.

## v0.27.0 (2026-07-30)

### Fixed

- **Closed bars follow the venue's clock.** An Indicator operand in a
  bar-mode strategy used to classify bars by the Unix epoch's phase, so on
  venues whose week opens on Monday a still-forming weekly bar was folded
  in as if it had closed, a live look-ahead carried inside the module's
  state. A bar is now closed once its own full interval has elapsed, the
  strategy evaluates each bar exactly once on the bar the venue
  delivered, and a package whose primary input pins a different interval
  than the signal contributes no bar identity rather than a mis-gridded
  one. Backtests are unchanged by construction.

## v0.12.0 (2026-07-23)

### Fixed

- **A hung metric fetch cannot wedge a strategy's exits.** Metric fetches,
  Indicator packages included, are bounded by `OM_DEADLINE_METRIC_FETCH`
  (30 s by default); an Indicator composition chains at most four
  packages, and on expiry the chain is aborted, the exit check still
  runs, and the tick records `metric_timeout` naming the knob.

## v0.4.0 (2026-07-10)

### Added

- **Backtests replay installed Indicators.** `om backtest spec --strategy-slug` replays a saved strategy through the live decision
  core against a simulated venue; bar-mode metric signals, installed
  Indicator packages included, resolve against their save-time
  `package_locks` and replay on a bar cadence over `--from` and
  `--until`.
- **Package visibility.** `visibility` on every manifest: `public` (the
  default), `unlisted` (installable by exact name, hidden from search and
  the catalog), `private` (entitlement-gated by registry grants). `om install` retries a 401 or 403 with the account key it already holds,
  sent only to the configured registry origin, and surfaces the
  registry's `not_entitled` message plainly.

### Changed

- **`om indicators` became `om metric`.** `metric_get`, `metric_list`,
  and `metric_screen` (and `om metric get`, `om metric list`, `om metric screen`) replaced the `indicators_*` names: price, `delta_pct`, volume,
  funding, and open interest were always supported alongside the
  indicator metrics, and an Indicator's outputs join the same namespace
  as `wrun/@scope/name/<output>`. The error code
  `unsupported_exchange_for_indicators` became
  `unsupported_exchange_for_metrics`.
