### Analytics (burndown and scope)
- `tix analytics burndown --scope cycle|milestone --id <REF> [--from <D> --to <D>]
[--mode count|estimate --unit <UNIT>]` prints the daily series: the scope, its
period, the mode and unit, the documented formula version, the coverage tally and
one tab-separated row per day (`scope_total`, `remaining`, `completed`,
`scope_added`, `completions`, `coverage`). An unanswerable value prints `-`, never
`0`, and a day with no recorded history is `coverage_limited`, never a zero by
assumption
- `tix analytics projection --scope cycle|milestone --id <REF> --as-of <D>` draws the
read-only end-date forecast against the scope's own planning end: its `status`
(`projected`/`unknown`/`insufficient_data`), `remaining`, `observed_rate`,
`projected_completion` and `meets_end_date`, each rendered `-` when the record
cannot derive it. It never invents a date and never moves a planning date
- `tix analytics export --scope cycle|milestone --id <REF> --mode count|estimate
[--unit <UNIT>] [--as-of <D>] [--output <path>]` writes the deterministic,
versioned local chart document (`tix-chart`, schema 1): the scope, period and
snapshot binding, the mode/unit and precision, the ordered points with their
coverage markers and `null`s, the optional projection, the aggregate coverage, the
formula version and the findings. The same repository state produces byte-identical
output
- Scope and mode are **closed vocabularies**: an unknown word is refused by name.
Estimate mode converts only through the board's declared
`[kanban.<board>.wip.units]` ratio — a missing or unknown unit is a
`missing_conversion` finding, never a silent count
- Analytics is a **pure projection** over append-only History, issue frontmatter and
the cycle/milestone planning data, and the shared status/unit services: there is no
analytics store, no issue mutation and no second cycle/status model. A day with no
recorded history is explicitly `unknown`/`coverage_limited`; scope that was never
recorded is **not** guessed; history a closed snapshot bounds is not rewritten by a
later edit. The estimate-change class sees only what the `tix edit` seam records —
an estimate written by another path appends no event and cannot appear — and the
coverage markers are what a reader gets. A hosted analytics service, a guessed
historical scope, a new conversion rule or an external data source is an escalation
trigger
- The TUI's `F7` Stats page has a **Burndown** tab beside `[Health]` and `[Time]`
rendering exactly the CLI's values (no TUI-only numbers); MCP exposes
`analytics_metadata`, `analytics_burndown`, `analytics_projection` and
`analytics_export`, whose text is the CLI's own; and the remote export targets
(`gitlab`/`linear`) cannot carry a chart document, which the document itself
reports as `unsupported_remote_field` rather than dropping values silently