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
Four diagnostic pieces for the governance hash mismatch on dev.node2:
scripts/dev-node-battery.ts — single-command smoke test (pay → stake → validators list → governance propose → vote → unstake → final state), with per-stage tx polling via getTransactionStatus nodeCall and a self-contained markdown report writer.
test-reports/dev-node-battery-FINAL.md — clean run captured against dev.node2.demos.sh:53552 (node v0.9.8 / a0957941, dirty=true, osDenomination active).
test-reports/governance-hash-mismatch-analysis.md — root-cause analysis + why the existing test suite missed it (every governance test bypasses the SDK builder).
src/libs/blockchain/transaction.ts — isCoherent mismatch dump (sibling of PR debug(validation): emit raw gcr_edits dump on mismatch + version canary (DEBUG-ONLY) #870's GCREdit dump). When the full content hash diverges, emits tx type, both hashes, and the serialized bytes at log.warn level so the next dev.node2 repro pinpoints the diverging byte from logs.
Why diagnostic, not fix
Without log access to dev.node2 + the binary being dirty=true, a speculative serializer fix would chase the wrong asymmetry. The two known divergences (node doesn't walk gcr_edits[], node rebuilds transaction_fee without spread) both produce identical bytes for both PAY and PROPOSE in pure local round-trips, so the dev.node2-specific divergence is not yet pinned. The battery + log dump close that gap on next repro cycle.
CI status
All green:
Greptile Review: success
SonarCloud Code Analysis: success
claude-review: success
AI feedback addressed (6 rounds)
#
Source
Severity
Issue
Commit
1
Greptile
P1
log.error × 4 would page on-call on every mismatch
2b9aa96c — collapsed to single log.warn
2
Greptile
P2
unused existsSync import
2b9aa96c
3
Greptile
P2
skipped stages counted as failures in summary
2b9aa96c — added skipped?: boolean
4
TS6
error
demos.confirm(tx, demos) passed wrong arg count
f961fcdc — dropped spurious 2nd arg, 8 call sites
5
SonarCloud
hotspot
http:// URL in default RPC
c9373c9f — // NOSONAR with rationale
6
Greptile
P1
proposalId = randomUUID() set before await, Stage 5 ran on failed propose
49dd4e79 — mint local id, promote only after included
PR: #876
Branch:
diag/governance-hash-mismatch-v2→feat-stabilisation-testHead:
49dd4e79What it does
Four diagnostic pieces for the governance hash mismatch on dev.node2:
scripts/dev-node-battery.ts— single-command smoke test (pay → stake → validators list → governance propose → vote → unstake → final state), with per-stage tx polling viagetTransactionStatusnodeCall and a self-contained markdown report writer.test-reports/dev-node-battery-FINAL.md— clean run captured againstdev.node2.demos.sh:53552(node v0.9.8 /a0957941, dirty=true, osDenomination active).test-reports/governance-hash-mismatch-analysis.md— root-cause analysis + why the existing test suite missed it (every governance test bypasses the SDK builder).src/libs/blockchain/transaction.ts—isCoherentmismatch dump (sibling of PR debug(validation): emit raw gcr_edits dump on mismatch + version canary (DEBUG-ONLY) #870's GCREdit dump). When the full content hash diverges, emits tx type, both hashes, and the serialized bytes atlog.warnlevel so the next dev.node2 repro pinpoints the diverging byte from logs.Why diagnostic, not fix
Without log access to dev.node2 + the binary being
dirty=true, a speculative serializer fix would chase the wrong asymmetry. The two known divergences (node doesn't walkgcr_edits[], node rebuildstransaction_feewithout spread) both produce identical bytes for both PAY and PROPOSE in pure local round-trips, so the dev.node2-specific divergence is not yet pinned. The battery + log dump close that gap on next repro cycle.CI status
All green:
AI feedback addressed (6 rounds)
log.error× 4 would page on-call on every mismatch2b9aa96c— collapsed to singlelog.warnexistsSyncimport2b9aa96c2b9aa96c— addedskipped?: booleandemos.confirm(tx, demos)passed wrong arg countf961fcdc— dropped spurious 2nd arg, 8 call siteshttp://URL in default RPCc9373c9f—// NOSONARwith rationaleproposalId = randomUUID()set before await, Stage 5 ran on failed propose49dd4e79— mint localid, promote only afterincludedVerified locally
bunx tsx scripts/dev-node-battery.tsend-to-end against dev.node2: 6/7 stages + 2 skipped (clean — Stage 5 properly ⏭️ after Stage 4 failure)npx tsc --noEmit --skipLibCheckclean fortransaction.tsand battery scriptAlso fixed in this PR
stress-test-mnemonicto.gitignore— was almost leaked viagit checkout stash@{N}side-effect during the session. Caught locally before push.Next step
Reviewer approval. mergeable=MERGEABLE. After merge: redeploy dev.node2 → re-run battery → grep node logs for
[TX] isCoherent mismatch→ pinpoint diverging byte → targeted serializer fix.