{"assessments":[],"deployments":[],"fuzz":[],"identity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"interpretation":"Records acceptance and evidence. Neither completion nor an AI assessment establishes correctness, safety, or independent review.","jobId":"0c371f80-1a55-4b76-b8ba-5abaaaa05c84","kind":"skill:build-website","nodes":[{"acceptedSubmissionHash":"060f90db26c7b6d80414c2c1d64918be88a0c574f15f99e43eba6c9812828d5b","dependsOn":[],"execution":{"mustProduce":["dist/index.html"],"network":true,"optionalTools":["browser"],"profile":"none","requires":["network"],"skillHash":"d09d5c017130fd8c9114daa8383d99944c68d9819cc4bab4554508c9ce6d73c9","skillId":"build-website","tools":[]},"key":"build_website","kind":"code","role":"implement","skillHash":"d09d5c017130fd8c9114daa8383d99944c68d9819cc4bab4554508c9ce6d73c9","skillId":"build-website","state":"accepted"},{"acceptedSubmissionHash":"9b3ce7b989113be00cc10e8b7c6a4bd69a1764f6c2d26af64d50b097d974538d","dependsOn":["build_website"],"execution":{"network":true,"optionalTools":["browser"],"profile":"none","requires":["network"],"skillHash":"4a5e9fb083a47bea78572ce4262f6ed18e7af57736a86ec2bbb7d17a8c72c62e","skillId":"design-critic","tools":[]},"key":"design_critic","kind":"code","role":"review","skillHash":"4a5e9fb083a47bea78572ce4262f6ed18e7af57736a86ec2bbb7d17a8c72c62e","skillId":"design-critic","state":"accepted"}],"objective":"Continue PLEA test run 2: build its site for the live Sepolia launch #1311. and change no contracts. Start from the PLEA v10 site (Vite + TypeScript + viem) at https://github.com/identity-md-launches/launch-1242-launch-plea-sepolia-foundry/tree/e1a93f13dc30072e5ba524b34bdb9d5f1e8e56b2/web and keep what already meets this spec. Read addresses from .imd/reads/deployment.json (PLEA, CabalGate, Seasons, Laureates, PleaDistributor, PleaLaunch); PleaHook 0x2d5A03d5bAb98a4a435edad11813373963bcA8cC (also PleaLaunch.hook()); launch block 11893845, trading opened 2026-10-11 19:49 UTC. Also: PoolSwapTest 0x9b6b46e2c869aa39918db7f52f5557fe577b6eee, Intake v2 0xa43e6f75ee006411f79ac1c84120606c2330de82, oracle-fee token 0x44a1cd38474fb1748400e7deb5f8d786cce3f89a (open mint(address,uint256)), TestIMD 0x2b69099e59b05901faa1dd164fabf098bf831e82 (faucet()), TestSIMD 0xf9e2eec3b610ec6781f7438ac5fb4bc049d81cc1 (24 decimals), Stacker 0x0457276d7b036818b3eddc1a4a3fceda61e9314d. README and ABIs are the source of truth; read every number (fees, caps, timings, SEASON, DEADMAN, START, BONUS_PER_SEASON) from chain. Public Sepolia RPCs with fallback; build pleas, verdicts and seasons from the Gate's and Seasons' events from the launch block.\n\nWHAT IS NEW SINCE v10 (show all of it):\n- Season PLEA bonus: each of the first 4 seasons also pays 5,000,000 PLEA to its qualifying top 10 with the same shares and the same 60-point minimum; unpaid shares are burned at close; after the Cabal dies the rest is burned. Show \"+ 5,000,000 PLEA bonus\" on seasons 1-4, the PLEA each rank gets next to its IMD, BonusPaid / BonusBurned events in the Hall of Fame and Seasons.bonusBurned(). Supply split: 88% pool, 2% season bonus, 10% distributor.\n- Intake v2: a plea that gets no verdict is cleared at once by the Intake (PleaFailed(id, status, reason, agreed, answered)). Show \"No verdict\" with the reason and the split (agreed/answered). \"Clear plea\" (expire) only as the fallback once 20 minutes passed and the plea is still pending.\n- Cashback: this Stacker has no stackedBy. Show \"Cashback earned\" as the sum of imd in the Stacker's Stacked(project, trader, imd, shares) events with project = the hook, and the wallet's sIMD balance (24 decimals).\n- The hook now checkpoints the price before each swap; the fact score text should say \"hourly price snapshots, never the live price\".\n\nHEADER on every page: the PLEA wordmark; Cabal state (\"Cabal alive · dies in 31h 12m without a verdict\" or \"The Cabal is dead. PLEA trades freely forever.\"); season pill (\"Season 3 · 2h 41m left · pot 12.4 IMD + 5M PLEA\"; season N = key + 1; pot = Seasons.seasonFees(key) + rollover()); theme toggle; one Connect button.\n\nPAGES (top nav, all items visible at 360px):\n- Overview: three short paragraphs (buy freely; sell only with a plea the Cabal approves; approved pleas earn season points, IMD prizes and the PLEA bonus; after 33h without a verdict the Cabal dies and PLEA trades freely forever); live strip (price, PLEA burned, pleas judged, prize pot); latest six verdicts; buttons \"Buy PLEA\" and \"Plead to sell\". Footer credits TokenWorks' CabalCoin as the inspiration.\n- Buy: tIMD faucet; PoolSwapTest exact-input swap, direction from hook.pleaIsZero(), hookData abi.encode(buyer) on every swap, preview by eth_call; launch fee and 5M cap while the 90-min window runs; fees \"1.75%: 0.5% back to you as sIMD, 0.25% to this season's prizes\"; cost basis (hook.basisOf); cashback earned. After death: a plain \"Sell PLEA\" form here.\n- Plead (hidden after death): amount (≤ min(2.5M, 35% of balance)), text with a live byte counter (1-280, mirror the Gate's _validateText exactly), live factScore and need (70 - fact); need > 45 disables Submit (\"This plea cannot pass: lower the amount or wait for better facts\"). \"Get oracle IMD\" mints 0.5 fee token. States: Pending (20-min countdown), No verdict, Approved (7-min countdown, executeSell(minOut) with slippage), Denied (one appeal within 4h, amount ≤ original, 0.5 oracle IMD + 0.35 tIMD), Lapsed (starts the 4h cooldown), Executed, Expired. Tip: \"Write your own case; never tell the judges how to score: that counts as manipulation and scores 0.\" After approval: \"+38 points\", \"Record my points\" (Seasons.record) until recorded, \"you're #4 this season\".\n- Wall: every plea as a card in a grid (1/2/3 columns), stamp, amount, fact/need, judges' score, points, plea text (as text, never HTML), author (Laureates name or short address), time; filters (All, Approved, Denied, Pending, No verdict, Appeals, Laureates); permalink page per plea; appeal pairs linked.\n- Seasons: current top 10 (topOf) with points, share 25/18/14/11/9/7/6/4/3/3 % and the IMD and PLEA it pays now; \"below 60 points the share rolls over (IMD) or is burned (PLEA)\"; top 5 pleas; the wallet's rank and best three scores. \"Close season N\" after the 1-hour grace (closeSeason with that season's unrecorded approved plea ids). After death and the last close: \"Send leftovers to the buy wall\" (flushToWall). Hall of Fame: closed seasons, payouts, bonus, Laureates from tokenURI (on-chain SVG).\n- Profile: display name (Laureates.setName: 3-20 chars a-z 0-9 _, unique, reserved names refused; validate live; \"This is your current name\" for the name it already owns), the wallet's pleas, points, Laureates, cashback.\n- Status: Cabal state, last verdict, price, market cap, PLEA in market, wall IMD, \"Rebalance\" when pendingRebalance(), burned, bonus burned, every address with explorer links.\n\nWALLET: one Connect button, top right, every page. Read-only data without a wallet; actions say \"Connect in the top bar to ...\". Switch to Sepolia when needed.\n\nTRANSACTIONS: explicit gas limits. Swaps (buy, sell, executeSell): estimateGas × 1.3, never below creditGas + 1,300,000. Others: estimate × 1.5. Per-button states (pending, success with explorer link, error in plain words from the contracts' custom errors).\n\nFIXES FROM THE v10 SITE:\n1. Verdict stamps were all red. One colour per state with light and dark tokens: Approved/Executed green, Denied/Upheld red, Pending amber, No verdict/Expired/Lapsed neutral grey, Laureate gold. The stamp text also names the state.\n2. Text too large: plea text on cards ~1.125rem (detail page larger), headings one step smaller, tighter card padding.\n3. sIMD has 24 decimals (v10 showed it ×1e6).\n4. Nav at 360px in one row with smaller items.\n\nDESIGN: keep v10's identity: the PLEA wordmark in Instrument Serif, Geist body, mono only for addresses and numbers, tabular numerals; ink, parchment and wax-seal red; tinted neutrals; real light and dark themes; 12-column grid, max ~1200px; Phosphor icons only where they carry meaning, no emoji; the verdict stamp as a wax seal with one exponential ease-out motion. Every control has hover, focus, disabled, loading, error and empty states; touch targets ≥44px; contrast ≥4.5:1. No nested cards, gradients, glass, glows, bounce or modals.\n\nNOT IN THIS SITE: claim cashback, killCabal, moods, ransom, relics.\n\nQA: every page in a real browser at 360, 768 and 1280 px, light and dark, against the live contracts: no console errors, no horizontal scroll, every flow works. Fix, then one more round. Deliver the source and the built dist to the repository.","parentJobId":"4aca2460-33f9-477b-9480-cd229f874c9a","planHash":"f9afcde76e3f8f789fa57279a79bf9bddc3cad30efd24be01e7302bde5c80d64","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"4aca2460-33f9-477b-9480-cd229f874c9a","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-1311-launch-plea-test-run"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"52019","feedbackHash":"0decbd79d3ab289f30fd60b29005acd7e586692e9a815fe1a8d600494982b0fe","nodeKey":"build_website","submissionHash":"060f90db26c7b6d80414c2c1d64918be88a0c574f15f99e43eba6c9812828d5b","tag1":"verification:structural","tag2":"acceptance-v2","value":1},{"agentId":"51216","feedbackHash":"9f801905f695dd740b3318c5bda34d8b186db69ece742117059f8ab79958ac91","nodeKey":"design_critic","submissionHash":"9b3ce7b989113be00cc10e8b7c6a4bd69a1764f6c2d26af64d50b097d974538d","tag1":"review:submission","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"e7733d3f1beec51236d904b2970dcdebed8b67a29d66b3111c4e6c35c38279b0","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":"67d7393e6bcded001e187bc587320b27e4f63115e9802175374b985e15350feb","device":"be3be4cc237417f9","findings":[],"hash":"060f90db26c7b6d80414c2c1d64918be88a0c574f15f99e43eba6c9812828d5b","nodeId":"146d4857-a690-40f8-9924-0237cac31dc6","outcome":"completed","summary":"The site for PLEA test run 2 is built, checked and committed as commit 9901391 on top of fb8c0ae. No contract was changed and nothing was deployed or published.\n\n**What was delivered**\n\n- `web/` holds the v11 source (Vite, React, TypeScript, viem), continuing the v10 site and keeping what already met the spec. `dist/` holds the committed static export with relative asset URLs and hash routes. `DESIGN.md`, a website section in the README and `artifacts/validation.md` document tokens, commands, results and limits.\n- Addresses come from the pinned deployment manifest plus the task's auxiliary contracts. The hook is checked against both `PLEA.hook()` and `PleaLaunch.hook()` before any write. ABIs match all six pinned hashes, and the live runtime bytecode of all seven contracts matches the source build.\n- Everything new since v10 is shown: the season PLEA bonus in the header pill, Seasons page, leaderboard PLEA column, Hall of Fame events and burned total; Intake v2 \"No verdict\" with reason and agreed/answered split, with \"Clear plea\" only as the 20-minute fallback; cashback summed from the Stacker's events plus the 24-decimal sIMD balance; the hourly-snapshot wording.\n- The four v10 fixes are in: one colour per verdict state with measured contrast in both themes, headings and card text one step smaller, correct sIMD decimals, and a one-row navigation at 360 px.\n\n**Checks that ran**\n\n| Check | Result |\n|---|---|\n| tsc --noEmit | 0 errors |\n| Unit tests | 11 passed |\n| Production build | OK, dist 948 KB |\n| Browser QA, 48 page combinations | round 3 clean: no console errors, no overflow, 0 axe violations, all targets at least 44 px |\n\nBrowser QA used real headless Chrome against the live Sepolia contracts at 360, 768 and 1280 px in light and dark, plus the 390 first screen and a 320 reflow. Round 1 found narrow navigation items and a sideways-scrolling leaderboard at 360; both were fixed and rechecked.\n\n**Limitations to know about**\n\n- No wallet or Sepolia ETH exists on this worker, so buy, plead, appeal, execute, record, close, flush, name and faucet transactions were not sent. They are implemented against verified ABIs and typed, but unproven in a wallet here.\n- The launch has no pleas, verdicts, closed seasons or Laureates yet, so those surfaces were exercised in their empty states. Seals, state tags, failure text and bonus arithmetic were verified by unit tests and injected DOM samples instead of live records.\n- Screen-reader and physical-device checks were not performed.\n\nThe uncommitted `web/node_modules` folder was removed; the commit's delta is about 0.5 MB, well under the bundle limit.","treeHash":"37dd124928a9fb7742579a6ba9ec3944e7ee0ef9","usage":{"cachedInputTokens":7651065,"inputTokens":1162,"model":"claude-fable-5-1","outputTokens":103119,"runtime":"claude","turns":99,"wallClockMs":1907784}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"fa2b7fcb5f53535a","findings":[{"citation":"resolved","description":"Now: `approved(p)` is true for status 2 and status 5, so once the 7-minute window has passed (pleaState returns \"Lapsed\") the seal still reads \"Approved\" with data-tone=\"approved\" (green) while the small state tag below it reads \"Lapsed\" in neutral grey; the same card shows two colours and two states, and the seal text does not name the state.\nChange to: resolve the seal from the state first: `const verdict = state === \"Lapsed\" ? \"Lapsed\" : p.status === 4 ? \"Executed\" : approved(p) ? \"Approved\" : p.status === 3 ? (p.isAppeal ? \"Upheld\" : \"Denied\") : state;` so `toneOf(\"Lapsed\")` gives the neutral tone already defined in style.css (`--tone-neutral`); nothing else changes.\nWhy: the brief's fix 1: \"One colour per state with light and dark tokens: Approved/Executed green, Denied/Upheld red, Pending amber, No verdict/Expired/Lapsed neutral grey, Laureate gold. The stamp text also names the state.\"","line":238,"path":"web/src/components.tsx","reproduction":"Any width. Open #/wall (or the plea's permalink) for a plea whose status is 2 (Approved) and whose verdictAt + EXECUTE_WINDOW (420 s, read from chain) is in the past, or whose status is 5 (Lapsed). Expected: a grey seal reading \"Lapsed\". Actual: pleaState() returns \"Lapsed\" (domain.ts line 189) and the StateTag shows \"Lapsed\" in grey, but `verdict` evaluates to \"Approved\" because approved(p) is [2,4,5].includes(p.status), so <Stamp label=\"Approved\"> renders data-tone=\"approved\" (green, #38553b on #dfe9dc light, #b4ccab on #2b3a2a dark). The chain holds no plea yet (CabalGate.nextId returns 0 pleas; the Wall reads \"0 pleas · all\" at block 11894160), so the path was confirmed from the code, not a screenshot.","severity":"medium","snippet":"  const verdict =\n    p.status === 4\n      ? \"Executed\"\n      : approved(p)\n        ? \"Approved\"","title":"fidelity: a lapsed plea keeps a green \"Approved\" wax seal instead of a grey \"Lapsed\" one"},{"citation":"resolved","description":"Now: the three intro paragraphs run 35, 38 and 20 words (93 words) plus the 7-word lead line, and at 390 x 844 all three sit on the first screen (paragraph bottoms measured at 550, 665 and 728 px), so the product's first screen is mostly explainer.\nChange to: keep the three paragraphs and the live numbers but cut each to one sentence or two: (1) \"Anyone can buy PLEA. To sell while the Cabal lives, you plead your case and {PANEL_SIZE} oracle judges decide.\" (2) \"Approved pleas earn season points, IMD prizes and the PLEA bonus: {BONUS_PER_SEASON} PLEA for each of the first {BONUS_SEASONS} seasons' top ten.\" (3) \"{DEADMAN/3600} hours without a verdict and the Cabal dies. PLEA then trades freely, forever.\" That is 56 words with the numbers still read from chain; the live strip moves up by about 110 px at 390.\nWhy: the probe's copy-budget bar is 60 words of prose on the first screen at 390 and 90 at 1440; the brief asks for \"three short paragraphs\", and these are not short. The Laureates sentence is already said on the Seasons page.","line":58,"path":"web/src/pages.tsx","reproduction":"390 wide, light or dark, open #/ and wait for the live block to load. Probe line from `node .imd/reads/skills/design-critic/scripts/taste.mjs --out test/scratch/taste`: \"copy-budget: prose on the first screen: 103 words at 390 (bar 60), 110 at 1440 (bar 90); all words on the first screen: 126 at 390, 149 at 1440\". Measured in Chromium at 390 x 844: the Buy PLEA button sits at y=352 (product is on the first screen) and the three paragraph boxes end at y=550, 665 and 728.","severity":"medium","snippet":"            Anyone can buy PLEA. To sell while the Cabal lives, you write a\n            plea, and a panel of {c ? String(c.PANEL_SIZE) : \"30\"} oracle judges\n            decides whether your case is good enough.","title":"copy: 103 words of prose sit on the first phone screen of the Overview, against a bar of 60"},{"citation":"resolved","description":"Now: while no season has closed, the Hall of Fame section renders <Empty title=\"The Hall is waiting\"> and then NFTGallery's own <Empty title=\"The next Laureates are being written\"> directly beneath it: two `.empty` blocks, each with its top and bottom rule and 48 px of padding, both saying the Laureates will come after a close, about 330 px of repeated empty state at 360.\nChange to: render the gallery only when there is something to show: `{data.nfts.length > 0 && <NFTGallery nfts={data.nfts} />}` (the Profile page keeps its own gallery empty state, which is the right place for \"Your Laureates\"). The section then ends after \"The Hall is waiting\" and the footer moves up by the height of the removed block.\nWhy: the reference's rule on empty states: each state says only what the app knows and does not repeat; one count or message once, in one shape.","line":502,"path":"web/src/pages.tsx","reproduction":"360 or 1280 wide, open #/seasons and scroll to \"Hall of Fame\". Screenshot test/scratch/review/light-1280-_seasons.png shows \"The Hall is waiting / Close an ended season after its grace period to settle prizes and mint the first Laureates.\" followed at once by \"The next Laureates are being written / The top five approved pleas of each closed season become on-chain artworks.\", two rule-bounded blocks back to back; the same at 360 in light and dark (light-360-_seasons.png, dark-360-_seasons.png).","severity":"low","snippet":"        <NFTGallery nfts={data.nfts} />","title":"taste: the Hall of Fame stacks two bordered empty states that say the same thing"},{"citation":"resolved","description":"Now: the empty title is built by lower-casing the filter name and inserting it before \"pleas\", which works for Approved, Denied and Pending but produces \"No appeals pleas yet\", \"No no verdict pleas yet\" and \"No laureates pleas yet\" for the other three filters.\nChange to: a small map next to `filters`: { All: \"No pleas yet\", Approved: \"No approved pleas yet\", Denied: \"No denied pleas yet\", Pending: \"No pending pleas yet\", \"No verdict\": \"No pleas without a verdict yet\", Appeals: \"No appeals yet\", Laureates: \"No Laureate pleas yet\" } and use `emptyTitles[filter]`; the result-count line (line 177) can keep its \"0 pleas · appeals\" form since it is a label, not a sentence.\nWhy: the brief's copy rule: plain words; an empty state says what the app knows in a sentence a reader would write.","line":186,"path":"web/src/pages.tsx","reproduction":"390 wide, open #/wall, tap the \"Appeals\" filter (or \"No verdict\" / \"Laureates\") while the filtered list is empty, which it is now (0 pleas on chain at block 11894160). Measured in Chromium: `.filters button[aria-pressed=true]` = \"Appeals\", `.result-count` = \"0 pleas · appeals\", `.empty h3` = \"No appeals pleas yet\". Expected: \"No appeals yet\".","severity":"low","snippet":"              ? `No ${filter === \"All\" ? \"\" : filter.toLowerCase() + \" \"}pleas yet`","title":"bug: the Wall's empty title reads \"No appeals pleas yet\" and \"No no verdict pleas yet\""},{"citation":"resolved","description":"Now: on #/plead without a wallet the \"Get oracle IMD\" button is greyed out (TxButton disables itself when there is no account) with only \"Oracle IMD balance: —.\" beneath it, while every other write on the site (Submit plea, Get tIMD, Buy PLEA, Set display name, Close season, Rebalance, Record points) is preceded by the site's WalletHint line saying what connecting unlocks.\nChange to: add `<WalletHint verb=\"mint the oracle fee\" />` directly above this TxButton, reusing the existing component; nothing else moves.\nWhy: the brief's WALLET section: \"Read-only data without a wallet; actions say 'Connect in the top bar to ...'\".","line":331,"path":"web/src/Plead.tsx","reproduction":"390 wide, open #/plead with no wallet extension and wait for the live block. The left column shows \"Connect in the top bar to submit a plea.\" above \"Submit plea\"; the right column shows \"Get oracle IMD\" disabled (cursor not-allowed, muted fill) with no hint. Screenshot test/scratch/review/light-360-_plead.png, right under \"The price of a hearing\".","severity":"low","snippet":"            label=\"Get oracle IMD\"","title":"accessibility: \"Get oracle IMD\" is disabled without a wallet and is the one action with no \"Connect in the top bar\" line"},{"citation":"resolved","description":"Now: the Overview hero and the Plead page open with the identical h1 \"Make your case.\", so the site's one signature line appears twice and the Plead page, a form, does not say what the reader does there, while its nav item says \"Plead\" and its tab title says \"Plead to sell\".\nChange to: `<h1>{appealId ? \"Ask the court again.\" : \"Plead to sell.\"}</h1>`; the one-sentence line beneath (\"Tell the Cabal why you should be allowed to sell.\") stays.\nWhy: the reference: tool pages are read to get a task done, so \"headings name the task in plain words\"; the hero headline should \"could only belong to this product\" and keep its force by appearing once.","line":187,"path":"web/src/Plead.tsx","reproduction":"Any width; compare #/ and #/plead. Measured h1 text in Chromium: \"/\" → \"Make your case.\", \"/plead\" → \"Make your case.\" (test/scratch/review/report.json, both themes and all three widths). Screenshots light-360-_.png and light-360-_plead.png.","severity":"low","snippet":"        <h1>{appealId ? \"Ask the court again.\" : \"Make your case.\"}</h1>","title":"taste: the Plead page reuses the Overview headline \"Make your case.\" instead of naming its task"},{"citation":"resolved","description":"Now: the share image is declared as \"./og-image.png\". The Open Graph protocol defines og:image as a URL, and the Facebook/Meta, X and Slack scrapers do not resolve relative paths against the page, so the link unfurls with the title and description but no card image even though web/public/og-image.png (1200 x 630, the wordmark and \"Make your case.\") exists in the build.\nChange to: the absolute URL of the published site, e.g. `content=\"https://<published host>/og-image.png\"` (the host the site is deployed to is not in the repository, so the builder sets it at publish time); keep the relative `href` for the favicon, which browsers resolve.\nWhy: the reference's share bar: \"A title, favicon, og:title and og:image, so the link unfurls when someone posts it.\"","line":17,"path":"web/index.html","reproduction":"Open dist/index.html (line 17) or web/index.html (line 17): og:image is \"./og-image.png\". The probe's share check passes because it tests presence only (\"title \\\"PLEA — Make your case\\\", favicon, og:title, og:image, description\"). Paste the published URL into the Meta Sharing Debugger or a Slack message: the preview has no image because the scraper discards the relative og:image.","severity":"low","snippet":"    <meta property=\"og:image\" content=\"./og-image.png\" />","title":"bug: og:image is a relative path, so the share card will not unfurl on most platforms"}],"hash":"9b3ce7b989113be00cc10e8b7c6a4bd69a1764f6c2d26af64d50b097d974538d","nodeId":"9298b67b-164f-49d5-b1b4-68ce77f8ecdd","outcome":"completed","summary":"| Area | Count |\n|---|---|\n| Brief requirements | 64 met · 1 missing (Lapsed seal colour) · 0 faked |\n| Broken features | 0 |\n| Product on the first screen at 390 | yes (Buy PLEA at y=352, Plead to sell beside it) |\n| taste@1 checks passed | 15 / 16 (copy-budget failed) |\n| Copy findings | 3 |\n| Share card | present, but og:image is a relative path |\n\nThe review is written to `.imd-findings.json` with 7 findings (2 medium, 5 low), each cited to source lines that I checked against the tree. No file in the tree was changed; scratch output was removed.\n\n**How it was checked.** The probe ran on `dist/` after installing Playwright and Chromium's system libraries outside the repository. I then served `dist/` and walked all eight routes at 360, 768 and 1280 in light and dark against live Sepolia (block 11894159 to 11894165): zero console errors, zero horizontal overflow, every control at least 44 px, all tone pairs 5.4:1 or better. Without a wallet I exercised the byte counter against the Gate's `_validateText` (marker, zero-width, newline, overlength all caught), Connect without a provider, theme persistence, Wall filters, Status constants and keyboard focus. The chain holds no plea yet, so cards, seals and the Hall were judged from code and from the empty states.\n\n**Requirements, one line each**\n- Header wordmark, Cabal state line, season pill \"Season N · time · pot X IMD + 5M PLEA\", theme toggle, one Connect: met, `App.tsx` header.\n- Nav with all items visible at 360 in one row: met, screenshot at 360 shows seven items.\n- Overview three paragraphs, live strip, latest six verdicts, Buy PLEA and Plead to sell, TokenWorks credit: met, `pages.tsx` Overview and footer. Paragraphs are not short (finding 2).\n- Buy: faucet, PoolSwapTest exact-input with direction from pleaIsZero, hookData = buyer, eth_call preview, launch fee and 5M cap notice, \"1.75%: 0.5% back to you as sIMD, 0.25% to this season's prizes\", cost basis, cashback, Sell form after death: met, `Trade.tsx`, `swaps.ts`.\n- Plead hidden after death, limit min(2.5M, 35%), live byte counter mirroring the Gate, live factScore and need, need > 45 disables with the exact sentence, Get oracle IMD mints ORACLE_FEE, all seven states, manipulation tip, \"+N points\", Record my points, \"you're #N this season\": met, `Plead.tsx`.\n- Wall cards in 1/2/3 columns, seal, amount, fact/need, score, points, text as text, author name or short address, time, seven filters, permalink, appeal pairs: met, `components.tsx` PleaCard.\n- Seasons top ten with shares 25/18/14/11/9/7/6/4/3/3, IMD and PLEA per rank, the roll-over/burn sentence, top five pleas, rank and best three, Close season N after the grace, flushToWall after the last close, Hall of Fame with BonusPaid/BonusBurned, bonusBurned(), Laureates from tokenURI: met, `pages.tsx` Seasons.\n- Season bonus text \"+ 5,000,000 PLEA bonus\" and supply split 88/2/10: met, Seasons heading and notice.\n- Intake v2 \"No verdict\" with reason and agreed/answered split, Clear plea only after 20 minutes: met, `domain.ts` pleaState, `Plead.tsx` PleaActions.\n- Cashback from Stacked(project = hook) events plus 24-decimal sIMD: met, `data.ts` loadCashback, `fmtSimd`.\n- \"hourly price snapshots, never the live price\": met, Plead aside.\n- Profile name rules, reserved names, live availability, \"This is your current name\": met, matches `Laureates._checkName`.\n- Status: state, last verdict, price, market cap, PLEA in market, wall IMD, Rebalance when pendingRebalance(), burned, bonus burned, every address with explorer links: met.\n- Addresses from deployment.json plus the task's auxiliary addresses, chain 11155111, three public RPCs with fallback, events from block 11893845, every number read from chain: met, `contracts.ts`, `data.ts`.\n- Gas: swaps estimate × 1.3 with floor creditGas + 1,300,000, others × 1.5; per-button states with custom-error decoding: met, `domain.ts` gasLimit, `context.tsx`, `errors.ts`.\n- Fix 1 one colour per state: met for Approved, Executed, Denied, Uphe","treeHash":null,"usage":{"cachedInputTokens":2947360,"inputTokens":584,"model":"claude-fable-5-1","outputTokens":38630,"runtime":"claude","turns":61,"wallClockMs":677995}}],"verification":[{"checks":[],"detail":"paths and tree verified; no suite was run for this kind of work","evaluation":"structural","profile":"none","status":"accepted","submissionHash":"060f90db26c7b6d80414c2c1d64918be88a0c574f15f99e43eba6c9812828d5b","verifiedTreeHash":"37dd124928a9fb7742579a6ba9ec3944e7ee0ef9","verifierVersion":"0.1.0+fb8278c5"}]}