Skip to content

feat(tempo): wire chain 42431 (v019) into the dapp + finish v019 exit/URI reads#3317

Merged
drewstone merged 1 commit into
developfrom
feat/wire-tempo-develop
Jul 8, 2026
Merged

feat(tempo): wire chain 42431 (v019) into the dapp + finish v019 exit/URI reads#3317
drewstone merged 1 commit into
developfrom
feat/wire-tempo-develop

Conversation

@drewstone

Copy link
Copy Markdown
Contributor

Makes the live tnt-core 0.19 Tempo deployment usable in the dapp and finishes the two v019 TODOs the staggered-rollout PR (#3316) left behind. Builds on #3316 (already merged to develop).

Wire Tempo (chain 42431 = v019)

Tempo Moderato is deployed + verified live on 0.19. Added it as a selectable chain:

  • viem chain def (id 42431, native currency USD/18-dec, testnet), EVMChainId.TempoModerato + canonical NetworkId.TEMPO_MODERATO, wagmi chains/transports, network switcher.
  • TEMPO_CONTRACTS + case 42431 in getContractsByChainId; getTntCoreRevisionByChainId returns 'v019' for 42431 (every other chain stays 'legacy' — correct, they run pre-0.18).
  • Addresses: tangle 0xff13…b4cda, multiAssetDelegation 0x9484…f89e, operatorStatusRegistry 0xaeda…2b48, rewardVaults 0x9a16…f7c4, inflationPool 0x3602…836f (others address(0) w/ traceability comments).

Finish v019 TODOs (no more degraded reads)

  • Exit eligibility: getExitStatus(uint64,address) exists in 0.19 → replaced the v019 fail-closed stub with a real read + ExitStatus enum mapping (None=eligible; Scheduled/Executable/Completed=not). 6 unit tests.
  • binaryUri / reportUri: event-only on 0.19 → resolved from BinaryVersionPublished / BinaryVersionAttested logs (address-scoped, indexed blueprintId/versionId) instead of null; graceful fallback if no event.

Verified

nx typecheck tangle-dapp + tangle-cloud pass; nx lint dapp-config + tangle-shared-ui pass; canScheduleExit.spec 6/6 + revision.spec 11/11; 0 remaining TODO(v019).

…/URI reads

- Add Tempo Moderato (chainId 42431, v019) as a selectable chain: viem chain def, EVMChainId
  + NetworkId enums, wagmi chains/transports, TEMPO_CONTRACTS + getContractsByChainId case,
  getTntCoreRevisionByChainId -> v019. Points the dapp at the live 0.19 deploy
  (tangle 0xff13..b4cda, staking 0x9484..f89e, statusRegistry 0xaeda..2b48, rewardVaults
  0x9a16..f7c4, inflationPool 0x3602..836f).
- Finish the exit-eligibility TODO: on v019 read getExitStatus(uint64,address) and map the
  ExitStatus enum (None=eligible, Scheduled/Executable/Completed=not) instead of fail-closing.
- Finish the binaryUri/reportUri TODO: on v019 resolve from BinaryVersionPublished /
  BinaryVersionAttested logs (address-scoped, indexed blueprintId/versionId) instead of null.

Verified: nx typecheck tangle-dapp + tangle-cloud pass; lint dapp-config + tangle-shared-ui
pass; canScheduleExit.spec 6/6 + revision.spec 11/11; 0 remaining TODO(v019).
@drewstone drewstone requested a review from AtelyPham as a code owner July 8, 2026 16:27

@tangletools tangletools left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Auto-approved drewstone PR — 19f53d4b

This PR was opened by the trusted drewstone account.
The full PR reviewer audit still runs separately and will publish findings if it detects issues.

tangletools · auto-approval · reason: drewstone_author · 2026-07-08T16:27:46Z

@tangletools tangletools left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Value Audit — sound-with-nits

Verdict sound-with-nits
Concerns 2 (2 weak-concern)
Heuristic 0.0s
Duplication 0.0s
Interrogation 200.2s (2 bridge agents)
Total 200.2s

💰 Value — sound-with-nits

Wires the live Tempo Moderato (v019) chain into the dapp and replaces two v019 fail-closed stubs (exit eligibility, URI reads) with real on-chain reads; good and in-grain, with one small factoring nit.

  • What it does: Three things: (1) adds Tempo Moderato (EVM chain id 42431) as a selectable chain everywhere it needs to be — viem chain def, EVMChainId/NetworkId/PresetTypedChainId enums, wagmi chains/transports in both dapp and cloud, network switcher entries, TEMPO_CONTRACTS, and routes it to the v019 revision in getTntCoreRevisionByChainId; (2) replaces the v019 fail-closed stub in useCanScheduleExit with a re
  • Goals it achieves: Make the live tnt-core 0.19 deployment actually usable in the dapp (selectable chain, correct contracts, correct read paths) and eliminate the two degraded reads the staggered-rollout PR #3316 left behind, so operators on v019 can schedule exits and binary/attestation URIs render instead of being blank.
  • Assessment: Sound and clearly in the codebase's grain. The chain wiring is a near-exact mirror of how Base Sepolia is wired (same files, same shape, same NetworkId/Network object pattern). The log-sourcing pattern mirrors the existing useServiceRequestDetails.ts:225 getLogs usage (address-scoped, fromBlock:0, toBlock:'latest', graceful fallback). The pure-module split of ExitStatus + the eligibility mapper fo
  • Better / existing approach: Looked for (a) an existing GraphQL/indexer source for binaryVersion/attestation URIs — none; the blueprints data dir is all on-chain reads, so log-sourcing is consistent. (b) An existing getLogs precedent — found useServiceRequestDetails.ts:225, which this PR mirrors. (c) Whether getExitStatus and the two events already exist in synced ABIs — they do (tangle.ts:1826, tangleBinaryUpgrade.ts:277/390
  • Model: opencode/zai-coding-plan/glm-5.2
  • Bridge attempts: 2
  • Bridge warning: opencode/kimi-for-coding/k2p7: bridge stream ended without value-audit content

🎯 Usefulness — error

usefulness agent produced no parseable value-audit JSON.

  • Model: opencode/deepseek/deepseek-v4-pro
  • Bridge attempts: 3
  • Bridge error: opencode/zai-coding-plan/glm-5.2: bridge stream ended without value-audit content; opencode/kimi-for-coding/k2p7: bridge stream ended without value-audit content; opencode/deepseek/deepseek-v4-pro: bridge stream ended without value-audit content

💰 Value Audit

🟡 On v019, useCanScheduleExit re-reads getExitStatus that useExitStatus already reads [duplication] ``

OperatorExitPanel mounts BOTH hooks (OperatorExitPanel.tsx:123 useExitStatus, :130 useCanScheduleExit). On v019 they each fire the same getExitStatus(serviceId, operator) RPC under different react-query keys (['exitStatus',...] vs ['canScheduleExit',...]), so the cache won't dedupe — one duplicate cheap RPC per panel mount on v019 chains. The PR already did the hard part: it split ExitStatus and mapExitStatusToEligibility into pure, composable modules (exitStatus.ts, canScheduleExit.ts). The nat

🟡 binaryUri event-resolution tail duplicated across two hooks [duplication] ``

useEffectiveBinaryVersion (useBinaryVersions.ts:376-388) and useServiceUpgradeState (useBinaryVersions.ts:452-464) now carry near-identical 'read effectiveBinaryVersion, normalize, if v019 && binaryUri===null resolve from event' blocks. The shared helper resolveBinaryUriFromEvent is correctly factoreded; what's duplicated is the surrounding condition + call. Could be collapsed into a normalizeEffectiveBinaryVersionWithUri(raw, { publicClient, tangle, blueprintId, chainId }) helper. Predates the


What this audit checks

It judges the change on its merits — not whether it was tasked out in an issue. Unticketed, fast-moving work is fine; the question is whether the change is good and whether a better or existing approach should be used instead.

Pass What it asks
Heuristic Vague title? Whitespace-only or cruft-bearing diff? (content signals only)
Duplication Do added function/class names already exist elsewhere in the repo?
Value Audit What does it do? What goal does it achieve? Is it good? Better architecture or already-exists?
Usefulness Audit Does it integrate and fit? Will it hold up in real use and actually get used?

Findings are concerns, not blocks — the human reviewer decides what to do with them.

value-audit · 20260708T163301Z

@tangletools

Copy link
Copy Markdown
Contributor

⚠️ Review Interrupted — 19f53d4b

The review runner stopped before publishing a final verdict: max_run_seconds.

State Detail
Interrupted max run seconds

No review verdict was produced for this run. Trigger a fresh review on the current PR head if the PR is still open.

tangletools · #3317 · model: kimi-for-coding · updated 2026-07-08T18:29:31Z

@tangletools tangletools left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Auto-approved drewstone PR — 19f53d4b

This PR was opened by the trusted drewstone account.
The full PR reviewer audit still runs separately and will publish findings if it detects issues.

tangletools · auto-approval · reason: drewstone_author · 2026-07-08T18:47:13Z

@tangletools tangletools left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚪ Value Audit — audit-incomplete

Verdict audit-incomplete
Concerns 0 (none)
Heuristic 0.0s
Duplication 0.0s
Interrogation 17.5s (2 bridge agents)
Total 17.5s

💰 Value — error

value agent produced no parseable value-audit JSON.

  • Model: opencode/deepseek/deepseek-v4-pro
  • Bridge attempts: 3
  • Bridge error: opencode/kimi-for-coding/k2p7: bridge stream ended without value-audit content; opencode/zai-coding-plan/glm-5.2: bridge stream ended without value-audit content; opencode/deepseek/deepseek-v4-pro: bridge stream ended without value-audit content

🎯 Usefulness — error

usefulness agent produced no parseable value-audit JSON.

  • Model: opencode/deepseek/deepseek-v4-pro
  • Bridge attempts: 3
  • Bridge error: opencode/zai-coding-plan/glm-5.2: bridge stream ended without value-audit content; opencode/kimi-for-coding/k2p7: bridge stream ended without value-audit content; opencode/deepseek/deepseek-v4-pro: bridge stream ended without value-audit content

No PR concerns were produced because the value/usefulness agent pass did not complete. Treat this audit as incomplete, not as approval.


What this audit checks

It judges the change on its merits — not whether it was tasked out in an issue. Unticketed, fast-moving work is fine; the question is whether the change is good and whether a better or existing approach should be used instead.

Pass What it asks
Heuristic Vague title? Whitespace-only or cruft-bearing diff? (content signals only)
Duplication Do added function/class names already exist elsewhere in the repo?
Value Audit What does it do? What goal does it achieve? Is it good? Better architecture or already-exists?
Usefulness Audit Does it integrate and fit? Will it hold up in real use and actually get used?

Findings are concerns, not blocks — the human reviewer decides what to do with them.

value-audit · 20260708T185305Z

@tangletools

Copy link
Copy Markdown
Contributor

✅ No Blockers — 19f53d4b

Review health 100/100 · Reviewer score 63/100 · Confidence 90/100 · 6 findings (2 medium, 4 low)

kimi-code: Correctness 63 · Security 63 · Testing 63 · Architecture 63

Reviewer score is advisory once the run is complete and the verdict has no blockers.

Full multi-shot audit completed 6/6 planned shots over 18 changed files. Global verifier still owns final merge decision.

🟠 MEDIUM N+1 full-chain log scans per blueprint version — libs/tangle-shared-ui/src/data/blueprints/useBinaryVersions.ts

For each versionId the fetcher issues a separate getLogs scan of the entire chain history (lines 211-217). A blueprint with many versions multiplies RPC load and rate-limit risk. Fix: fetch all BinaryVersionPublished events for the blueprint once, map by versionId, and join.

🟠 MEDIUM Unbounded getLogs with swallowed errors silently drops v019 URIs — libs/tangle-shared-ui/src/data/blueprints/useBinaryVersions.ts

Lines 120-132 and 151-168 call publicClient.getLogs with fromBlock: BigInt(0) and toBlock: 'latest', then catch all exceptions and return null/empty. Many RPC providers reject or truncate wide log ranges, so v019 binaryUri/reportUri backfill can silently fail and the UI will show null URIs without any retry or error signal. Fix: chunk the log range and only swallow the no-logs case, or re-throw transient RPC errors so react-query can retry.

🟡 LOW Tempo chain ID -> revision/contracts mapping lacks unit test — libs/dapp-config/src/contracts.ts

The new case 42431 returning 'v019' and the TEMPO_CONTRACTS branch in getContractsByChainId are config wiring with no direct test coverage. Existing revision tests in libs/tangle-shared-ui mock getTntCoreRevisionByChainId, so they do not guard against a typo in the hardcoded chain ID or a mismatch between the enum and these switches. A drift would silently make Tempo decode v019 tuples with the legacy ABI, breaking reads. Add a small dapp-config unit test asserting getTntCoreRevisionByChainId(EVMChainId.TempoModerato) === 'v019' and getContractsByChainId(EVMChainId.TempoModerato).tangle equals the documented TEMPO_CONTRACTS.tangle address.

🟡 LOW No tests for event-sourced URI resolution — libs/tangle-shared-ui/src/data/blueprints/useBinaryVersions.ts

The main new v019 behavior—resolving binaryUri and reportUri from chain logs—is not covered by unit tests. Only the ABI selection, normalizers, and the canScheduleExit mapping are tested. Fix: add tests for resolveBinaryUriFromEvent and resolveReportUrisFromEvents with a mocked PublicClient to cover event-found, missing-event, and re-attestation cases.

🟡 LOW Public hook signature change for useEffectiveBinaryVersion — libs/tangle-shared-ui/src/data/blueprints/useBinaryVersions.ts

The signature changed from (serviceId, options?) to (serviceId, blueprintId?, options?). No internal callers exist, but it is a library export; external consumers passing an options object as the second argument would misinterpret it as blueprintId. Fix: consider an overload or place blueprintId inside options to preserve backward compatibility.

🟡 LOW Fragile cross-package enum value coupling — libs/ui-components/src/constants/networks.ts

NetworkId.TEMPO_MODERATO is appended last so its numeric value (9) mirrors the hardcoded value in apps/tangle-cloud/src/constants/networks.ts. The comment documents the constraint, but there is no compile-time enforcement. If a future change inserts another NetworkId before TEMPO_MODERATO in ui-components, the numeric values will diverge silently. Consider explicitly assigning numeric values in libs/ui-components/src/constants/networks.ts (matching the app-local enum) or adding a static assertion to keep the two enums in sync.


tangletools · 2026-07-08T20:09:16Z · trace

@tangletools tangletools left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Approved — 6 non-blocking findings — 19f53d4b

Full multi-shot audit completed 6/6 planned shots over 18 changed files. Global verifier still owns final merge decision.

Full immutable report for this review: trace

Summary comment for this run: full summary


tangletools · 2026-07-08T20:09:16Z · immutable trace

@drewstone drewstone merged commit a21a977 into develop Jul 8, 2026
13 checks passed
@drewstone drewstone deleted the feat/wire-tempo-develop branch July 8, 2026 22:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants