v29: Harden ENSJobPages preview + contract-faithful Alpha Agent Identity flow#1478
v29: Harden ENSJobPages preview + contract-faithful Alpha Agent Identity flow#1478MontrealAI wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e7ab9741fd
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const [ownerOf, labelData, tokenURI] = await Promise.all([ | ||
| freeTrialRegistrarIdentity.methods.ownerOf(preview.tokenId).call().catch(()=>''), | ||
|
|
||
| if(preview?.tokenId && (preview?.identityExists || preview?.tokenOwner)){ |
There was a problem hiding this comment.
Clear token card fields when preview has no identity token
In refreshIdentityState(), token card fields are now only updated inside this if block, but there is no fallback path to reset them when the selected label has no identity token. If an operator first views a minted label and then switches to an unminted/invalid one, stale owner/mintedAt/metadata/image values from the previous label remain visible, which misrepresents the current preview state and can lead to incorrect operator decisions.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0f9d678c13
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if(preview?.tokenId && (preview?.identityExists || preview?.tokenOwner)){ | ||
| const [ownerOf, labelData, tokenURI, lockedState] = await Promise.all([ | ||
| freeTrialRegistrarIdentity.methods.ownerOf(preview.tokenId).call().catch(()=> preview?.tokenOwner || ''), |
There was a problem hiding this comment.
Skip token-card reads when preview has no minted identity
The new guard if(preview?.tokenId && (preview?.identityExists || preview?.tokenOwner)) treats any non-empty tokenOwner string as proof of an identity token, but preview.tokenOwner is typically the zero address (0x000…000) when identityExists is false. In that common claimable/available case, this branch still runs, ownerOf/locked revert and fall back values are shown, so the UI reports a zero-address owner and soulbound locked: true for a token that does not exist. This regresses preview accuracy and can mislead operators about current identity state.
Useful? React with 👍 / 👎.
Motivation
ENSJobPagescontract address and public state (preferAGIJobManager.ensJobPages()and fall back to the verified0x06188e77...only when required).FreeTrialSubdomainRegistrarIdentityintegration by replacing truncated ABI shapes and rebuilding the identity state machine aroundpreview(label)androotHealth()so the identity path is contract-faithful and robust.register(label)identity path the recommended UX and enforce soulbound semantics.Description
resolveEnsJobPagesContract()now readsagiJobManager.methods.ensJobPages()first, records the address source explicitly (AGIJobManager getter/verified fallback/unavailable), andupdateEnsJobPagePreview()populates preview rows from livejobLabelSnapshot,jobEnsLabel,jobEnsName,jobEnsURI, andjobEnsNode.rootHealth(),preview(string), andlabelData(uint256), and rewroteparseIdentityPreviewResult()to map the full tuple and status codes intoAPP_STATE.identity.preview.refreshIdentityState()now usespreview(label)as the primary state machine, decodesrootHealth()correctly, enforces label validation rules, blocks writes onROOT_NODEmismatch, shows cross-contract mismatch warnings, gatesregister/claim/syncbuttons by preview-driven rules, and decodestokenURI(base64 JSON) into the token card.updateMissionControl()CTA precedence soclaimable> repair (desynced/expired+exists) >registrable> generic prompts;verifySubdomain()now uses liveAGIJobManager.nameWrapper()andAGIJobManager.ens()reads and degrades explicitly when those getters are unavailable.FreeTrialSubdomainRegistrar.registerSimple(parentNode,label,newOwner)path as the secondary/expert flow and preserved recipient override only for the ENS-only path; the identity path (register(label)) never exposes a recipient override and always mints tomsg.sender.job-<id>assumptions, and updated visible version copy to v29.Testing
node --check /tmp/v29.jsto validate the updated JS syntax, which passed successfully.python -m http.server 8000and captured a Playwright screenshot ofhttp://127.0.0.1:8000/ui/agijobmanager_genesis_job_mainnet_2026-03-05-v29.html, producing the artifact for visual inspection (artifact available).refreshIdentityState(),updateEnsJobPagePreview()flow) in-browser; the contract-read code paths and preview rendering executed without syntax/runtime errors in the checked environment.Codex Task