Skip to content

fix(api): *_tao field names across ~25 schemas hold cross-subnet alpha, not TAO #8945

Description

@JSONbored

Context

total_stake_tao is used across roughly 25 schema files for a quantity that is, in most of them,
not TAO.

A non-root neuron's stake_tao is that subnet's alpha token, not TAO (src/metagraph-neurons.ts,
#2550). Anything that sums stake_tao across subnets and calls the result *_tao is therefore
publishing a cross-subnet alpha count under a TAO name. The repo's own economics code already relies
on this: scripts/lib/economics-artifacts.ts's computeAlphaMarketCapTao(alphaPriceTao, totalStakeTao) => alphaPriceTao * totalStakeTao is only dimensionally valid because
total_stake_tao is alpha.

#8803 fixed the one place where this actually produced impossible numbers — /accounts/top-holders
added the alpha sum to genuine System::Account TAO, so the top account reported 71% of a supply
hard-capped at 21M — and renamed the two fields that issue named
(/accounts/{ss58}/positions and /chain/yield) to total_stake_alpha / total_emission_alpha.

The rest were left alone on purpose. Renaming two of ~25 identically-named fields is defensible
when those two are the ones an issue names; renaming a moving subset of the remainder ad hoc is how
you end up with the same concept spelled two ways depending on which route you ask. The rest need one
deliberate pass, or a deliberate decision to leave them.

Why this is maintainer-only

Every option here is a breaking change to public route shapes, MCP tool outputs, and the GraphQL
schema at once, or an explicit decision to keep a known-misleading name. It also needs a judgement
this repo has not yet made in one place: which of these fields should be renamed (they are alpha
counts and always will be) versus converted (they are meant to be a value, and should be priced
like #8803's delegated_tao).

Requirements

  1. Inventory first. Every field spelled *_tao whose value is or may be alpha, with its route,
    its schema file, and what the number is used for. Start from
    grep -rn "total_stake_tao\|total_emission_tao\|stake_tao" schemas-src/ src/ workers/.
  2. Classify each one as rename, convert, or leave, with the reason:
    • rename when the field is a count and nothing downstream treats it as a value (e.g. a yield
      denominator — /chain/yield is the precedent, where converting the denominator alone would
      have broken three published ratios);
    • convert when the field is read as "what is this worth", using the same latest-per-netuid
      subnet_snapshots.alpha_price_tao join fix(api): top-holders delegated_tao/total_tao add per-subnet alpha to real TAO (top account = 71% of max supply) #8803 established — not a new price source;
    • leave for per-row columns that carry the on-chain column name verbatim, if that is the call —
      but say so, because positions[].stake_tao sitting next to total_stake_alpha is exactly the
      kind of split this issue exists to resolve.
  3. Land it as one contract change, not a drip. Whatever the classification, the renames ship
    together with one regenerated openapi.json/types/GraphQL SDL, so consumers see one break rather
    than five.
  4. Every renamed field carries a description saying what it is — alpha vs TAO, and why —
    following the wording fix(api): top-holders delegated_tao/total_tao add per-subnet alpha to real TAO (top account = 71% of max supply) #8803 established, so the next reader does not have to re-derive it.
  5. apps/ui consumers move in the same change. fix(api): top-holders delegated_tao/total_tao add per-subnet alpha to real TAO (top account = 71% of max supply) #8803's rename included
    apps/ui/src/lib/metagraphed/{types,queries}.ts; a rename that leaves the UI reading a field that
    no longer exists silently renders 0.

Deliverables

  • The inventory + classification from Requirements 1-2, committed (a doc or a test), not just
    posted in a PR comment.
  • The renames/conversions implemented together, with regenerated openapi.json, generated types,
    and GraphQL SDL committed in the same PR (validate:contract-drift fails otherwise).
  • Every consumer updated in the same PR: src/graphql.ts resolvers, src/graphql-sdl.ts,
    apps/ui/src/lib/metagraphed/**, and tests.
  • Patch coverage: every changed line and branch in src/** / workers/** is covered —
    codecov/patch enforces target: 99%, threshold: 0%.

Expected Outcome

Across every public surface, a field named *_tao holds TAO and a field named *_alpha holds alpha,
or the exceptions are named and justified in one place. No route publishes a cross-subnet alpha sum
under a TAO name without saying so.

Links & Resources

Metadata

Metadata

Assignees

No one assigned

    Labels

    backendmaintainer-onlyOwner-only work — yields no Gittensor points.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions