You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is a low-priority offshoot of the call_args shape-parity audit tracked in #4669 (itself following from #4668's live-verification of the D1→Postgres serving cutover, ADR 0013 Sequencing step 3). While walking all 105 call types D1 and Postgres both currently ingest, 13 came back "unresolved" because neither store had a recent occurrence to compare. 12 of those 13 are genuinely dormant on both sides (0 occurrences in the 365-day window in D1 and in Postgres) — e.g. Sudo.sudo, SubtensorModule.faucet, SubtensorModule.commit_crv3_weights. AdminUtils.sudo_set_weights_version_key is the one exception:
AdminUtils.sudo_set_weights_version_key (Postgres HAS a recent in-window occurrence at block 8584440, yet D1's own filtered feed returns zero rows for this call type — this one looks like a genuine D1 coverage gap, not a retention/rarity issue)
Re-querying D1's dedicated AdminUtils feed directly against production just now reproduces the same result:
That route is handleGovernanceConfigChanges (workers/request-handlers/entities.mjs:3849, routed via GOVERNANCE_CONFIG_CHANGES_PATH_PATTERN in workers/config.mjs:266) — it's loadExtrinsics hardcoded to callModule: "AdminUtils" against the same D1 extrinsics tier the cutover flag gates. Its own comment explains why this matters more than it would for most call types:
workers/request-handlers/entities.mjs:3846-3848: "most AdminUtils calls (77 of ~83) don't emit their own dedicated event, so the extrinsic + its decoded call_args is the reliable source, not chain_events."
In other words, for this call family the extrinsics tier isn't just a source, it's the only first-party place this occurrence could be corroborated from chain data — a D1-side gap here is exactly the case that comment is warning about, not a cosmetic difference.
This is unrelated to the call_args shape divergence (D1 SS58/hex strings vs. indexer-rs's raw newtype arrays) that's the actual blocker for flipping METAGRAPH_EXTRINSICS_SOURCE (still "d1" per wrangler.jsonc:88, METAGRAPH_BLOCKS_SOURCE already flipped to "postgres" at wrangler.jsonc:87). If anything it's a point in Postgres's favor: Postgres has data D1 is missing, not the reverse.
A plausible mechanism exists in D1's own ingestion path, worth checking first. scripts/fetch-events.py's extrinsics_for_block() silently drops any extrinsic that raises during decode:
# scripts/fetch-events.py:712-734forextrinsic_index, extinenumerate(extrinsics):
try:
value=ext.valueifextisnotNoneelseNoneifnotisinstance(value, dict):
continue# an undecodable extrinsic — skip this row only
...
exceptException:
continue# shape drift on one extrinsic → skip it, keep the rest
and _extrinsic_call() (scripts/fetch-events.py:567-585) independently swallows its own exceptions, returning (None, None, None) rather than raising — so a row for this call could either (a) never have been written at all (a per-extrinsic decode exception at line 733-734), or (b) exist with call_module/call_function left NULL (an internal _extrinsic_call failure), which would also make it invisible to a call_function=sudo_set_weights_version_key filter without being a true "zero rows" situation. Both are testable hypotheses, not conclusions — this issue is to actually determine which (if either) applies, or whether it's simpler (e.g. block 8584440 sits outside D1's current retention/backfill window).
Requirements
Determine which of the following actually explains the gap, with direct evidence (not another audit-style extrapolation):
True ingestion gap — D1's poller (scripts/fetch-events.py) never saw/wrote a row for this extrinsic at all (block outside its scan window, a continue at fetch-events.py:716 or :734 was hit for this specific extrinsic, or the cursor/backfill never covered block 8584440).
Silent null-attribution — a row exists in D1 for the right (block_number, extrinsic_index) but with call_module/call_functionNULL because _extrinsic_call() (fetch-events.py:567-585) hit its own internal exception path, so it exists but is invisible to the call_function filter.
Retention/pruning — the row was written but has since aged out of D1's retained window (check D1's current min/max block_number for the extrinsics tier and whether 8584440 falls inside it).
Confirm the corresponding Postgres row (block 8584440, AdminUtils.sudo_set_weights_version_key) independently via the indexer box to pin the exact extrinsic_index, then look up the identical (block_number, extrinsic_index) coordinate directly against D1 (not just the call_function-filtered route) to distinguish case 2 from cases 1/3.
Do not bundle a fix into this ticket. This is a diagnosis-only ticket per its stated priority; if the root cause turns out to be a one-line, low-risk fix (e.g. an obvious metadata-version branch gap in _extrinsic_call), open it as its own separate, focused PR rather than folding a code change in here (house rule: one focused change per PR).
Explicitly state whether this affects the METAGRAPH_EXTRINSICS_SOURCE cutover decision (expectation: no — Postgres already has the data, so this is D1 under-coverage, not a Postgres shape or completeness problem).
If mechanism (1) or (2): a minimal captured repro of the specific extrinsic's decoded ext.value shape (or lack thereof) that demonstrates exactly where D1's pipeline drops or mis-attributes it — no test file required for a diagnosis-only ticket, but a saved query artifact/comment is sufficient.
A one-paragraph, evidence-backed root-cause statement exists for why GET /api/v1/governance/config-changes?call_function=sudo_set_weights_version_key returns extrinsic_count: 0 in production while Postgres has a confirmed row at block 8584440.
Re-running that same query (or the equivalent direct D1 SQL) after investigation either still returns zero rows with a documented, understood reason attached, or returns the row because an actual fix (tracked separately, per Requirements) landed.
ADR 0013 (docs/adr/0013-hybrid-deployment-topology.md) — Sequencing step 3, "serving cutover," the umbrella this work sits under
scripts/fetch-events.py:689-735 (extrinsics_for_block) and :567-585 (_extrinsic_call) — D1's ingestion path and its silent-skip/null-attribution behavior
workers/request-handlers/entities.mjs:3843-3891 (handleGovernanceConfigChanges) — the D1 "filtered extrinsics feed" the audit and this issue both query
wrangler.jsonc:87-88 — the two existing cutover flags (METAGRAPH_BLOCKS_SOURCE: "postgres", METAGRAPH_EXTRINSICS_SOURCE: "d1")
deploy/postgres/schema.sql — Postgres extrinsics.call_args jsonb column definition, indexer box: sudo docker exec -i metagraphed-indexer-postgres-1 psql -U metagraphed -d metagraphed for direct verification of block 8584440
Evidence citation: Postgres AdminUtils.sudo_set_weights_version_key occurrence at block 8584440 (from the Roadmap: complete the D1 -> Postgres serving cutover for chain data (ADR 0013) #4669 audit); live reproduction via curl https://api.metagraph.sh/api/v1/governance/config-changes?call_function=sudo_set_weights_version_key → extrinsic_count: 0 (run during this issue's drafting, 2026-07-09/10)
Priority
low — informational data-quality/coverage finding on the D1 side that does not block the call_args shape-parity work or the METAGRAPH_EXTRINSICS_SOURCE cutover decision; fold into the parity harness as an annotation rather than tracking standalone.
Context
This is a low-priority offshoot of the
call_argsshape-parity audit tracked in #4669 (itself following from #4668's live-verification of the D1→Postgres serving cutover, ADR 0013 Sequencing step 3). While walking all 105 call types D1 and Postgres both currently ingest, 13 came back "unresolved" because neither store had a recent occurrence to compare. 12 of those 13 are genuinely dormant on both sides (0 occurrences in the 365-day window in D1 and in Postgres) — e.g.Sudo.sudo,SubtensorModule.faucet,SubtensorModule.commit_crv3_weights.AdminUtils.sudo_set_weights_version_keyis the one exception:Re-querying D1's dedicated AdminUtils feed directly against production just now reproduces the same result:
That route is
handleGovernanceConfigChanges(workers/request-handlers/entities.mjs:3849, routed viaGOVERNANCE_CONFIG_CHANGES_PATH_PATTERNinworkers/config.mjs:266) — it'sloadExtrinsicshardcoded tocallModule: "AdminUtils"against the same D1extrinsicstier the cutover flag gates. Its own comment explains why this matters more than it would for most call types:In other words, for this call family the extrinsics tier isn't just a source, it's the only first-party place this occurrence could be corroborated from chain data — a D1-side gap here is exactly the case that comment is warning about, not a cosmetic difference.
This is unrelated to the
call_argsshape divergence (D1 SS58/hex strings vs. indexer-rs's raw newtype arrays) that's the actual blocker for flippingMETAGRAPH_EXTRINSICS_SOURCE(still"d1"perwrangler.jsonc:88,METAGRAPH_BLOCKS_SOURCEalready flipped to"postgres"atwrangler.jsonc:87). If anything it's a point in Postgres's favor: Postgres has data D1 is missing, not the reverse.A plausible mechanism exists in D1's own ingestion path, worth checking first.
scripts/fetch-events.py'sextrinsics_for_block()silently drops any extrinsic that raises during decode:and
_extrinsic_call()(scripts/fetch-events.py:567-585) independently swallows its own exceptions, returning(None, None, None)rather than raising — so a row for this call could either (a) never have been written at all (a per-extrinsic decode exception at line 733-734), or (b) exist withcall_module/call_functionleftNULL(an internal_extrinsic_callfailure), which would also make it invisible to acall_function=sudo_set_weights_version_keyfilter without being a true "zero rows" situation. Both are testable hypotheses, not conclusions — this issue is to actually determine which (if either) applies, or whether it's simpler (e.g. block 8584440 sits outside D1's current retention/backfill window).Requirements
scripts/fetch-events.py) never saw/wrote a row for this extrinsic at all (block outside its scan window, acontinueatfetch-events.py:716or:734was hit for this specific extrinsic, or the cursor/backfill never covered block 8584440).(block_number, extrinsic_index)but withcall_module/call_functionNULLbecause_extrinsic_call()(fetch-events.py:567-585) hit its own internal exception path, so it exists but is invisible to thecall_functionfilter.block_numberfor theextrinsicstier and whether 8584440 falls inside it).AdminUtils.sudo_set_weights_version_key) independently via the indexer box to pin the exactextrinsic_index, then look up the identical(block_number, extrinsic_index)coordinate directly against D1 (not just thecall_function-filtered route) to distinguish case 2 from cases 1/3._extrinsic_call), open it as its own separate, focused PR rather than folding a code change in here (house rule: one focused change per PR).METAGRAPH_EXTRINSICS_SOURCEcutover decision (expectation: no — Postgres already has the data, so this is D1 under-coverage, not a Postgres shape or completeness problem).Deliverables
wrangler d1 execute/ psql / curl commands run and their raw output — mirroring the evidentiary style already used in Roadmap: complete the D1 -> Postgres serving cutover for chain data (ADR 0013) #4669's status update.ext.valueshape (or lack thereof) that demonstrates exactly where D1's pipeline drops or mis-attributes it — no test file required for a diagnosis-only ticket, but a saved query artifact/comment is sufficient.AdminUtils.sudo_set_weights_version_keyout of the generic "genuinely rare/dormant on both sides" bucket into an annotated line describing the actual cause found here.Expected outcomes
GET /api/v1/governance/config-changes?call_function=sudo_set_weights_version_keyreturnsextrinsic_count: 0in production while Postgres has a confirmed row at block 8584440.METAGRAPH_EXTRINSICS_SOURCEcutover readiness assessment — this issue is confirmed non-blocking for that decision either way.Links/resources
METAGRAPH_BLOCKS_SOURCE/METAGRAPH_EXTRINSICS_SOURCEand thetryPostgresTierfallback mechanismmultisigCallHash/proxyRealAccountmade shape-agnostic (prior work in the same parity effort)docs/adr/0013-hybrid-deployment-topology.md) — Sequencing step 3, "serving cutover," the umbrella this work sits underscripts/fetch-events.py:689-735(extrinsics_for_block) and:567-585(_extrinsic_call) — D1's ingestion path and its silent-skip/null-attribution behaviorworkers/request-handlers/entities.mjs:3843-3891(handleGovernanceConfigChanges) — the D1 "filtered extrinsics feed" the audit and this issue both queryworkers/config.mjs:262-267(GOVERNANCE_CONFIG_CHANGES_PATH_PATTERN) — route definition (/api/v1/governance/config-changes)wrangler.jsonc:87-88— the two existing cutover flags (METAGRAPH_BLOCKS_SOURCE: "postgres",METAGRAPH_EXTRINSICS_SOURCE: "d1")deploy/postgres/schema.sql— Postgresextrinsics.call_args jsonbcolumn definition, indexer box:sudo docker exec -i metagraphed-indexer-postgres-1 psql -U metagraphed -d metagraphedfor direct verification of block 8584440AdminUtils.sudo_set_weights_version_keyoccurrence at block 8584440 (from the Roadmap: complete the D1 -> Postgres serving cutover for chain data (ADR 0013) #4669 audit); live reproduction viacurl https://api.metagraph.sh/api/v1/governance/config-changes?call_function=sudo_set_weights_version_key→extrinsic_count: 0(run during this issue's drafting, 2026-07-09/10)Priority
low — informational data-quality/coverage finding on the D1 side that does not block the
call_argsshape-parity work or theMETAGRAPH_EXTRINSICS_SOURCEcutover decision; fold into the parity harness as an annotation rather than tracking standalone.