telegram-task-card-projection-notice · git:20261012.ec184ba · 2026-10-12 · sha256 9811fbb08ae2fe97

telegram-task-card-projection-notice git:20261012.ec184baA

Immutable. This exact content never changes and is served at /api/v1/blob/9811fbb08ae2fe97.

---
name: telegram-task-card-projection-notice
description: |
  Shipped retained-legacy/projection notice for Telegram Task Card files. The
  public `task_card` tool is intrinsic and documented at
  src/lingtai/tools/task_card/manual/SKILL.md; Telegram only projects the
  intrinsic taskcard/status + taskcard/taskcard.md artifact read-only. It also
  explains the Telegram-only per-call API token list-price estimate line and
  its since-molt SESSION Cost total.
last_changed_at: 2026-09-30T00:00:00Z
related_files:
- src/lingtai/mcp_servers/telegram/SKILL.md
- src/lingtai/mcp_servers/telegram/task_card/ANATOMY.md
- src/lingtai/mcp_servers/telegram/task_card/CONTRACT.md
- src/lingtai/mcp_servers/telegram/task_card/api_cost.py
- src/lingtai/mcp_servers/task_card/event_projection.py
- src/lingtai/tools/task_card/manual/SKILL.md
maintenance: |
  Keep this shipped subpackage manual aligned with the intrinsic Task Card
  owner. Do not reintroduce the retired Telegram controller schema, endpoint,
  ceiling, or lifecycle as active behavior.
---

# Telegram Task Card Projection Notice

This shipped file is retained beside the governed projection docs; it is **not**
the active public Task Card manual. The public, channel-neutral owner is the intrinsic Task Card, with packaged
procedures at [`task_card/manual/SKILL.md`](../../../tools/task_card/manual/SKILL.md).
Source-checkout architecture lives at `src/lingtai/tools/task_card/ANATOMY.md`
(not a packaged manual link).
Use that owner for `start | inspect | retry | stop | remove | settings | manual`,
renderer authoring, limits, recovery, and cleanup.

Telegram only projects the producer's `taskcard/status` and
`taskcard/taskcard.md` read-only. Author `taskcard.md` as Markdown: Telegram
renders ATX headings/subheadings, `**bold**`, inline backtick code, and unordered,
ordered, or task-list items inside the complete resident card. Raw HTML and
special characters are escaped; malformed or unmatched Markdown delimiters stay
safe literal text rather than becoming provider markup. Exact `active` plus a
nonempty body projects the programmable slot; exact `inactive` idempotently
excludes only that slot. Missing/unreadable status, active with a missing/blank
body, other status text, and unchanged bytes are no-ops. The resident message,
automatic event-journal slot, authored programmable bytes, and producer files
are not deleted or rewritten.

Do not use this retained package as the old Telegram-owned schema, endpoint,
JSON-card renderer, reverse-MCP route, or refresh-ceiling source.

## API token list-price line (Telegram only)

The automatic Telegram card shows time and token information on separate
lines, then adds the plain price line, for example:

```text
↻12.4s · ⚡1.2s · 35 tok/s
↓200 (20) ↑900 ◌ 1.0k | 10.0%
```

`Δ +1.3k`, when present before `↑` (e.g. `↓625 (0) Δ +1.3k ↑3.9k ◌ 157.5k | 97.5%`),
is how much the context input grew (`+`) or shrank (`-`) versus the previous
API call of this agent; `↑` is a different, overlapping measure (uncached
input). It is omitted when there is no reliable previous call (first call,
restart, molt, missing data).

`☕X.Ys`, when present on the first line, is the sum of real IDLE
intervals between the progress rows defining `↻`. It comes from the existing
`agent_state` events: the kernel measures each IDLE exit monotonically. It is
not gap minus API time. Tools, prompt build, queue/network wait, ASLEEP and
STUCK do not count. Older events, partial intervals, missing anchors and
restart-crossing gaps omit coffee; only a witnessed zero-length interval can
show `☕0.0s`. New complete intervals after a restart can be displayed.

`⏱` is the unrounded `↻` gap minus the same API wait and generation time,
and minus measured same-gap `☕` when present. Thus `⏱104.3s · ☕102.8s`
becomes `⏱1.5s · ☕102.8s`, with `↻` unchanged. Missing coffee keeps the
previous inclusive residual (not a claim of zero idle); negative residuals
are omitted, not clamped.

`⚡` measures actual stream dispatch to first nonempty **text or tool
name/argument payload**. Reasoning, ids, lifecycle, heartbeat, usage and empty
events do not count. `tok/s` uses final provider output (including tools) minus
explicitly reported reasoning tokens, divided by the measured dispatch-to-final-usage
interval (`first_token_s + generation_s`; 180 / 5.2 ≈ 35 here), not the total API gap
or a buffered delivery burst. It is observed API-average output throughput including
first-output wait and wire/trailer delay, not server-only generation speed. Generic OpenAI Chat Completions and Responses streaming currently
supply this evidence for text, tool-only and mixed rounds. Missing/estimated
usage, missing explicit reasoning counts, untimed adapters, and
nonstream/forced-SSE fallback omit speed; unknown timing is omitted, not inferred
as zero. Total existing delay, its `↻` and token symbols/counts are retained. The following cost line remains independent:

```text
$0.0084 · ↓$0.0010 ↑$0.0070 | $0.0004
```

Reading it:

- **What it is.** The line is a public per-token list-price ESTIMATE in USD
  (LiteLLM prices), not a bill or invoice. It is not the actual subscription/Codex-pool bill, and it
  does not claim the routed tier, batch pricing or discounts. Search,
  grounding and image fixed fees are not included in `total`.
- **Requested tier.** Prices are STANDARD unless that round REQUESTED the
  `priority` tier (authored `service_tier: "fast"`), in which case LiteLLM's
  `*_priority` rates are used, for the per-call line and the SESSION row alike.
  Such a line ends `priority est.`, and a SESSION row containing one ends
  `requested-tier est.`; unlabelled output is standard. This is the
  tier the request asked for, not proof the provider applied it. Rounds that
  recorded no tier (older history, or none requested) or `default` stay
  STANDARD and are not recalculated from current settings; `auto`/`flex` and a
  missing priority rate show `?` (no guessed multiplier).
- **Source and basis.** Prices come from LiteLLM's public
  `model_prices_and_context_window.json`, looked up by the EXACT model that
  made that round (no alias or fuzzy match), fetched by this process in the
  background; `stale prices` is appended once the snapshot is older than six
  hours and a refresh has not landed. Above 200k/272k total input the
  catalog's above-threshold rates are used when the model lists them.
- **Claude Code model aliases.** When a CLI result reports one unambiguous
  exact model, the price line names it as `model <id>` if it differs from the
  configured selection (e.g. `opus`). That id prices this call; the SESSION
  header keeps the configured alias. Missing, conflicting or multi-model
  evidence leaves the configured name unchanged, not a guessed version.
  An exact id absent from the catalog still shows `model not listed`; this
  remains a list-price estimate, not subscription spend.
- **Mirrors the metrics row.** `↓` is the provider-billable output; `↑` is the
  cache-miss input (total input minus cache read — uncached input plus any
  cache writes, the writes at the catalog's cache-write rate when it lists one,
  otherwise at the input rate); `|` is the cache-hit (cache-read) input,
  the `| hit%` share of `◌`. `↓` is the provider-billable output (thinking included exactly
  once). `<$0.0001` is a nonzero amount that rounds below the display precision.
- **Unknowns are never zero.** When the catalog prices cache writes
  separately but a round has no recorded write count (for example rounds
  logged before the adapter read `input_tokens_details.cache_write_tokens`),
  `↑` shows a lower bound with a trailing `+`: every cache-miss token priced at
  the cheapest applicable rate. A part shows `?` when no safe value exists: a
  count it needs is missing, the catalog lacks or has an invalid rate, or the
  counts are incoherent (for example a 1-hour cache-write part larger than the
  whole write). If any part is a lower bound or unknown, the headline total is
  the known subtotal with a trailing `+` (`$0.0682+`), or `cost ?` when nothing
  is known.
- **Independent from speed.** The price line does not calculate tokens/second.
  The token line above uses only measured compatible stream evidence; the total
  API gap includes waiting/prefill/orchestration and is not its denominator.
- **Async cache, offline, old history.** The card never waits for the network:
  the first render may show `cost loading`, one bounded background refresh (fixed
  URL, 8 MiB cap, per-read timeout plus a total deadline, no credentials)
  fills a process-local snapshot, and a failed fetch is retried no faster than
  every five minutes. Offline, prices stay `cost n/a (prices unavailable)` (or the
  last snapshot marked `stale prices`). Old events written before this feature carry no
  round facts and show `cost n/a (model unknown)`; no price is invented for them.
  Feishu and other channels render exactly as before.

## SESSION Cost row (Telegram only)

Under SESSION the card adds one row with the since-molt total of the same
per-call estimates:

```text
Cost · total ~$0.1234 · in $0.0200 · write $0.0100 · read $0.0034 · out $0.0900
```

Each main-Agent API response since the last molt is counted once (however many
tool calls it made), including actual returned one-shot a-priori summary calls
recorded as `apriori_summary_usage` v1 receipts. Each is priced with its own
canonical billing model, cache-write/read and billable-output facts. The helper's
API id is distinct from the parent call that requested the tool; duplicate
receipts, tool-result carriers and summary presentation rows do not add charges.
Empty or invalid summary text does not erase usage actually returned by a provider.
SESSION cumulative counts include these observed same-generation helper receipts;
latest parent context, TPS, Δ and cache/input/output per-call lines do not change.
There is still one Cost row and no summary subtotal. A molt starts a new
total. Daemon and other-Agent calls are not included. The total is only shown as
complete (`~`) when this Telegram process has seen every response of the
current session with priced facts. After a restart or refresh it rebuilds only
from the existing bounded event tail, so an older session shows
`total ≥$x · [per-bucket amounts or ?] · partial`; the same lower-bound form covers
responses with missing usage, billing facts, model or price. With nothing
priceable it shows `total ? · in ? · write ? · read ? · out ? · partial`. It is never shown as `$0` for
unknown history, and it is still a list-price estimate, not a bill.

A returned response without valid normalized usage leaves aggregate token totals
unknown (not zero); a missing receipt associated with an existing generated,
empty or failed summary outcome also leaves aggregate response count unknown
and Cost partial. Provider exceptions have no neutral normalized usage contract:
no SDK exception payload is inspected and no fictional `$0` charge is emitted.
No call is charged for a cap refusal or absent summarizer. Bounded replay can only
recover observed receipts/outcomes; wholly absent historical helper facts remain
an explicit scope gap, not proof of a complete session or an invoice. SESSION is
this Agent's current since-molt view, not lifetime, child or other-Agent spend.

The SESSION line splits ordinary input, cache writes, cache reads and output without double charging. Unknown write counts keep input/write allocation unknown even when the combined total is known.

## Async Work Daemon stats row

The card keeps every Session, Cost, Identity and Async Work row; there is no
500-character metadata budget. Any non-empty Async Work block carries a `Scope`
row: recorded jobs counted are running/queued plus those finished in the last
10 minutes (daemon and Shell alike), within the kernel's bounded record-tail
selection; this is not a whole-ledger census. The Daemon stats row is the sum of those daemon runs'
*reported lifetime* usage, not tokens from the last 10 minutes; runs that
report no positive values show `usage n/a (no positive usage reported)`. For
readability the visible row uses the compact `Daemon stats` label and omits
the unavailable-cost suffix. That omission does not mean zero cost: daemon
cost is not reported or priced, never `$0`, and never part of the Session
Cost row. An empty or stale snapshot shows no Async rows. Only when the whole
message would exceed its overall limit (after reasoning excerpts shrink) does the
tail of a long Daemons or Backends list become `+N omitted`.