{"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":"7deb4144-5498-49eb-b419-f3837845e2a6","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"0925e324220bef8b60737959c8f21882d70923753cec6acad74ecba35cf37e66","dependsOn":["frontend_for_contract","site_content_check"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"6b037a7b6601e883cf8a906c1520c0624817d42d8310b65c2f43679204608af3","skillId":"adversarial-review","tools":[]},"key":"adversarial_review","kind":"code","role":"review","skillHash":"6b037a7b6601e883cf8a906c1520c0624817d42d8310b65c2f43679204608af3","skillId":"adversarial-review","state":"accepted"},{"acceptedSubmissionHash":"5ab70d0c399183c36f823d62051f4a077faa96999090f5563259aa8956c4bbe4","dependsOn":["frontend_for_contract"],"execution":{"network":true,"optionalTools":["browser"],"profile":"none","requires":["network"],"skillHash":"fd33b6741366d364a55a4c0ba2bc4f5d329cec0b62f27a83289dc5b30ab03575","skillId":"design-critic","tools":[]},"key":"design_critic","kind":"code","role":"review","skillHash":"fd33b6741366d364a55a4c0ba2bc4f5d329cec0b62f27a83289dc5b30ab03575","skillId":"design-critic","state":"accepted"},{"acceptedSubmissionHash":"210ed14d7d98c44f17cc81a680744aebc0b412f20d484fd8db8c62be48a3e27c","dependsOn":[],"execution":{"mustProduce":["dist/index.html"],"network":true,"optionalTools":["browser"],"profile":"none","requires":["network"],"skillHash":"06a34ab3124a69f0ac4896a302a6fae785cbe50a9f5644516a9f24d101f27716","skillId":"frontend-for-contract","tools":[]},"key":"frontend_for_contract","kind":"code","role":"implement","skillHash":"06a34ab3124a69f0ac4896a302a6fae785cbe50a9f5644516a9f24d101f27716","skillId":"frontend-for-contract","state":"accepted"},{"acceptedSubmissionHash":"a63e43c99901d93c54bb204cbb30e28205f97167de4cbe05a05db5baacff5c4e","dependsOn":["frontend_for_contract"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"8189a3059fc9bb774ad7dcee66b87f32e25d781025f0e9f82a4c75182fe0ef19","skillId":"site-content-check","tools":[]},"key":"site_content_check","kind":"code","role":"review","skillHash":"8189a3059fc9bb774ad7dcee66b87f32e25d781025f0e9f82a4c75182fe0ef19","skillId":"site-content-check","state":"accepted"}],"objective":"SITE v3.1, a small continuation: the author's own CHILD CALL. The hook requires every thesis to receive one ordinary call from its own author within 7 days (parentId = the thesis id, same author; MarginaliaHook.sol: parent.author == author, parent.status ThesisOpen, within THESIS_GRACE) or the thesis bond is forfeited, and the site cannot produce one: call mode has no parent field, the trade box sets parentId only for counters, and #/post?counter= refuses the author's own note. Ship: (1) on an open thesis page (#/note/<id>) whose author is the connected wallet, a primary button 'Post the child call' that opens the composer (Trade and post, or Just the call) with parentId prefilled to the thesis id and a visible line 'Child call under your thesis <short id>, due <grace end>'; the child may be on any token and any side, so prefill nothing else and do not apply the counter rules (same token, opposite side, other author) to it; (2) an optional 'Parent (your own open thesis)' field in call mode and in the trade box, validated against the chain: parent must exist, be ThesisOpen, be the connected wallet's, and be inside its grace, with one-sentence errors; (3) the Write a thesis flow ends with 'Next: your child call, due <date>' linking to (1), and the thesis card in the feed shows 'needs its child call' until children > 0; (4) tests for the three gates; (5) keep everything else exactly as is: same stack, manifest, caveat, copy rules. Deliver into this project's repository as before.","parentJobId":"6d73f9eb-1d0a-44f6-8773-d6d8e5fe3fb3","planHash":"5be7ee446296ac1b393eeeeea14319577005491d83779c21319fba6986da85fc","previousHash":"f9e2ddcbb411a7750cf7211dfddaf7404030350e4e1d4b1c26bbb8ef8ce3b813","projectId":"9060a248-29ce-4683-b5d1-54fbc83cd49d","publication":{"commit":"4629fdd2da0b4be6663c668a12d3ad971ac09ed7","deliveredAt":"2026-10-13T02:33:58.715Z","repoUrl":"https://github.com/identity-md-launches/launch-1283-marginalia-x-com-marginalia-md-notes-mar"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[],"site":{"cid":"bafybeicj77hs3b2mqarnabtuq2euk4zoaaeywpa6v4362mlueonqwj7qk4","ensName":"marginalia.site.identitymd.eth","namingTransaction":"0xac69384cd76692cc5ac4609ed0d8b7f730f1a61253a060547dabda77170996cb"},"snapshotHash":"c5defd2e0487dc6d7eb8849295c2621860c81542437642d282ec6bd4d1688be9","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"2c968e88904ec22b","findings":[{"citation":"resolved","description":"Opening #/?child=<thesis-id> seeds the trade draft with parentId (line 29). The effect at line 41 then writes the whole draft, parentId included, to localStorage under marginalia.trade.v3, and readDraft (line 22) restores parentId on every later mount of #/ that has no child parameter. afterPost never clears it. So the thesis id becomes the default parent of every later Trade-and-post: (a) after the child is posted, the next plain #/ visit still shows 'Child call under your thesis …' with the disclosure open, and an unrelated call is submitted with NoteParams.parentId = the thesis, increasing parent.children on chain; (b) once the thesis's grace has passed or it has closed, the restored parent fails validation, childParent.ready is false, fieldsOk/params are null (lines 66-67) and the Approve, Wrap, Checkpoint and 'Trade and post' buttons on the home screen are all disabled until the visitor finds 'Parent thesis (optional)' and clears the field by hand. The brief asked for parentId to be prefilled for that one composer, not to become the standing default. Fix direction: do not persist parentId from a child link (or clear it after a post and when the link is absent). Reproduced by this review against the built dist with the project's own tests/child-call-browser.mjs harness; the specialist report of the same defect is confirmed and merged here.","line":41,"path":"web/src/trade.tsx","reproduction":"State: connected wallet 0x1111…1111 is the author of thesis 0x…01 (ThesisOpen, children 0, posted 1 h ago). 1. Open #/?child=0x…01; localStorage.getItem('marginalia.trade.v3') now contains \"parentId\":\"0x…01\". 2. Set location.hash to #/feed, then to #/ (no query). Expected: an ordinary composer with an empty parent. Actual: #trade-parent reads 0x…01, the context line reads 'Child call under your thesis 0x0000…0001, due …', and pressing 'Trade and post' (token MARG, why 'A tested call') produces a tradeAndNote wallet request whose NoteParams.parentId is 0x…01. 3. With the same saved draft {token: MARG, amount '1', side 0, pct '25', days '7', why '', bond '0.25', manual '', parentId 0x…01} and the thesis aged 604801 s: open plain #/, fill 'Why'. Expected: an ordinary call can be posted. Actual: the context reads 'This thesis's child-call deadline has passed…' and the 'Trade and post' button is disabled (isDisabled() === true).","severity":"medium","snippet":"  useEffect(() => { try { localStorage.setItem(DRAFT_KEY, JSON.stringify(draft)); } catch { setStorageError(true); } }, [draft]);","title":"Trade box persists the child-link parent into the saved draft, so later ordinary calls on #/ are filed under the thesis and, after grace, the home composer is blocked"},{"citation":"resolved","description":"useThesisParent re-reads noteOf/horizonEnd whenever Math.floor(now/15) changes (child-call.tsx:12). useRead sets loading=true for the duration of each refresh (chain.ts:333: pending === revision), and ready is defined as !loading (child-call.tsx:17). The Note page renders the primary CTA only while ready, so on every poll the button and its 'Due …' line unmount for one RPC round trip and the page reflows. On a slow public node (the project's own validation records 429s and empty responses from the configured RPCs) this is a visible blink every 15 s, and a tap that lands in that window hits the thesis text instead. When the fixed-block read fails (e.g. HTTP 429), read.error makes ready false and the CTA vanishes with no explanation and no 'Retry parent check' button, because ChildCallContext/ThesisParentField are not rendered on the Note page; the only visible line is the keeper text saying the author still has time. The trade box (trade.tsx:147, disabled: !childParent.ready) and the Post page (Post.tsx:187, readyToPost) toggle their primary buttons disabled during the same polls. Fix direction: keep the CTA mounted while a previous successful read is current (gate on parent && !error, not on !loading) and show the read error with a retry on the Note page.","line":71,"path":"web/src/pages/Note.tsx","reproduction":"State: author wallet connected, thesis 0x…01 ThesisOpen, children 0, posted 1 h ago; RPC eth_call for the hook's noteOf takes 600 ms. Open #/note/0x…01 and sample getByRole('link', {name: 'Post the child call'}).count() every 100 ms for 20 s. Expected: 1 throughout. Actual (this review, Chromium, project harness with a 600 ms noteOf delay): '…11110000001111…', the link is absent for about 600 ms around the 15-second poll; with a 1.5 s round trip it is absent for the whole read. Second state: same thesis, but eth_call with an explicit blockNumber (the fixed-block parent read) returns error 429 'Too Many Requests' while 'latest' reads succeed. Expected: either the button or a one-sentence error with a retry. Actual: the heading 'Note № 1' and the keeper line 'The author has … left to hang a call off this thesis' render, the link count is 0, and main#main contains neither 'Could not verify' nor 'Retry parent check'.","severity":"low","snippet":"      {thesis && childParent.ready && childParent.parent && <div className=\"actions\">","title":"Note page 'Post the child call' button unmounts during every 15-second parent poll and silently disappears on a transient RPC failure, with no message"},{"citation":"resolved","description":"When childId is present the initial draft is built from defaults with token '' and parentId, ignoring the stored marginalia.trade.v3 draft; the persistence effect at line 41 then runs on mount and replaces the stored draft. A writer who typed a 'why' and amounts in the home trade box, navigated to their thesis and pressed 'Post the child call' loses that draft permanently, and the next ordinary visit starts with token '' instead of the MARG default. The brief says the child link should prefill nothing but the parent; it does not ask for the previous draft to be discarded. The project's test 'A child link discards unrelated saved trade and seal prefills' asserts the new form is empty but never checks what remains in storage. Fix direction: keep the stored draft untouched until the user edits in the child composer, or merge the child parent over the stored draft instead of replacing it.","line":29,"path":"web/src/trade.tsx","reproduction":"State: localStorage marginalia.trade.v3 = {token: MARG, amount '3', side 1, pct '50', days '30', why 'My half-written reason', bond '2', manual '', parentId ''}; author wallet of open thesis 0x…01 connected. Open #/?child=0x…01 and wait for 'Child call under your thesis'. Read localStorage.getItem('marginalia.trade.v3'). Expected: why still 'My half-written reason', amount '3'. Actual (this review, Chromium): why '' and amount '1'; the earlier draft is gone.","severity":"low","snippet":"    return childId && !annex && !counter ? { ...defaults, token: '', parentId: childId } : readDraft(defaults);","title":"Following 'Post the child call' overwrites the visitor's saved in-progress trade draft with the empty child draft"},{"citation":"resolved","description":"The reminder is keyed only on ThesisOpen and children == 0. MarginaliaHook rejects a child once block.timestamp > postedAt + THESIS_GRACE (src/MarginaliaHook.sol:484) and lets anyone settleThesis after that (line 702), so a thesis in that state is waiting to be forfeited, not waiting for a child. The Note page for the same thesis correctly hides the CTA and shows 'Forfeit thesis', while the feed card and the author's own list (Author.tsx reuses Entry) still show a to-do the author cannot act on. The brief's wording 'until children > 0' is satisfied literally, so this is a copy/accuracy issue rather than a spec violation; a line such as 'child-call deadline passed' after n.timestamp + thesisGrace would be consistent with the Note page. Specialist finding reproduced and kept.","line":45,"path":"web/src/pages/Feed.tsx","reproduction":"Feed state: a thesis with status ThesisOpen, children 0 and NotePosted block timestamp 604801 s in the past (n.timestamp + contracts.limits.thesisGrace < now). Open #/feed. Expected: no 'needs its child call' line, or one saying the grace has passed. Actual (this review, Chromium, project fixture ownThesis with noteAge 604801): the card prints 'needs its child call' (count 1); #/note/<id> for the same thesis shows the keeper button 'Forfeit thesis' and no 'Post the child call' link.","severity":"low","snippet":"      {thesis && n.status === Status.ThesisOpen && n.children === 0 && <p className=\"small\">needs its child call</p>}","title":"Feed card keeps saying 'needs its child call' after the grace has expired, when no child can be posted and the thesis is forfeitable"},{"citation":"resolved","description":"AGENTS.md is copied verbatim to dist/agents.md and served as the agent interface. v3.1 adds #/?child=<hex-id>, #/post?child=<hex-id> and the 'Parent (your own open thesis)' field (documented in web/README.md) but the served document still lists only the counter prefill. Harmless for hosting: an agent can still post a child through router.note with parentId as the 'Theses and duels' section implies, and the brief's 'keep everything else exactly as is' may have been read as covering this file. Non-blocking.","line":48,"path":"AGENTS.md","reproduction":"grep -n 'child=' AGENTS.md dist/agents.md returns no match; grep -n 'Parent (your own open thesis)' AGENTS.md returns no match, while web/README.md 'Child calls' documents both.","severity":"info","snippet":"Hash routes: #/, #/feed, #/post, #/seal, #/pools, #/note/<hex-id>, #/duel/<counter-hex-id>, #/author/<address>, #/about. #/post?counter=<hex-id> prefills a counter-call. Pages and client-side share cards need no backend. The Pages market remains hidden until its deployment address is supplied; cited handles never establish identity. Informational, not advice. Bonds can be lost.","title":"Served agents.md does not describe the new child-call routes or the own-thesis parent field"}],"hash":"0925e324220bef8b60737959c8f21882d70923753cec6acad74ecba35cf37e66","nodeId":"18f456e7-5f13-4f0c-9c23-1654d9bf61c9","outcome":"completed","summary":"The review is complete. No repository file was changed; the only new file is `.imd-findings.json` at the root, which holds five substantiated findings.\n\n**What I checked.** I read the v3.1 diff against the hook source for the child-call rule, ran the project's unit test and its 21-scenario Chromium browser suite against the built export (all pass as claimed), then wrote my own scenarios on that harness, outside the repository, to reproduce each candidate. Parent validation itself is correct: the three gates, the inclusive grace boundary, fixed-block reads, the fresh preflight before approve and post, and the deadline cap at grace end all match the contract's checks at `src/MarginaliaHook.sol:478`. Counter rules, the Annex exclusion and seal reveals are untouched.\n\n**Findings, most severe first.**\n\n- **Medium, saved trade draft keeps the thesis parent.** Opening the child link writes parentId into the persisted draft and nothing clears it. Every later plain home visit is still a child call. After the grace passes the home composer's primary button is disabled until the hidden parent field is cleared by hand. Reproduced end to end, including a tradeAndNote request carrying the thesis id from a plain home visit.\n- **Low, the thesis page CTA blinks and can vanish silently.** The button is gated on a loading flag that flips true during every 15-second poll, so it unmounts for one RPC round trip each time. A transient 429 on the fixed-block read hides it with no message and no retry on that page.\n- **Low, the child link discards an in-progress trade draft.** The stored draft is replaced by the empty child draft on mount, so a half-written reason is lost.\n- **Low, feed card still says \"needs its child call\" after the grace.** Confirmed from the specialist report. The brief's literal wording is satisfied, so this is a copy accuracy issue.\n- **Info, served agents.md omits the child routes and parent field.** Confirmed from the specialist report.\n\nThe specialist's trade-draft and feed-label findings reproduced and are kept, the first merged with my own extended reproduction. None of the findings is in Solidity, so no Foundry proof applies. Nothing I examined warrants a high rating.","treeHash":null,"usage":{"cachedInputTokens":1927459,"inputTokens":546,"model":"claude-fable-5-1","outputTokens":30894,"runtime":"claude","turns":41,"wallClockMs":519828}},{"artifacts":[],"attempt":1,"bundleHash":"c5a7628fb8320abe06d0a8c927986f1bb129471f60ec3c1700edfce9517322f7","device":"b5ff2623f878600d","findings":[],"hash":"210ed14d7d98c44f17cc81a680744aebc0b412f20d484fd8db8c62be48a3e27c","nodeId":"2f65e03d-ddde-47ab-b3c9-93a42befbb69","outcome":"completed","summary":"Implemented the child-call flow, parent validation, thesis follow-up links and feed reminders. Rebuilt `dist/` and updated documentation.\n\nBuild, typecheck, hashes and 21 child-call scenarios passed in both Chromium and WebKit. Submission fits under 8 MiB.\n\nAdditional live checks encountered RPC 429/empty responses; no transactions were sent. No commit was created because `.git/` writes are forbidden.","treeHash":"8724b13520322f6933a2d3fb9d43ae5b5bf6f5e5","usage":{"cachedInputTokens":10758400,"inputTokens":231823,"model":"gpt-6-astra","outputTokens":53125,"runtime":"codex","turns":11,"wallClockMs":1808966}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"9a29c101a23c14cc","findings":[{"citation":"resolved","description":"Now: The new 'Next: your child call, due <date>' link is rendered above the form. After posting, the viewport stays at the submit button and the visible 'Posted as' confirmation contains no child-call handoff.\nChange to: Move the existing child-call link and due date into the posted confirmation below the submit button (the posted block at lines 323–330), and remove the separate notice above the form.\nWhy: The brief says the Write a thesis flow ends with this next action; the author needs to see the deadline and continuation where completion is confirmed.","line":194,"path":"web/src/pages/Post.tsx","reproduction":"Chromium, 390×844. Use the existing child-call-browser.mjs RPC/wallet fixture with reject:false and its default funded author; open #/post?kind=thesis, enter 'An argument that needs an ordinary child call.', click Post the thesis, and wait for Confirmed/Posted as without scrolling afterward. The visible confirmation is at viewport y=513.08..609.08, while the next-action link is at y=-1435.34..-1392.34 (scrollY=1657), so it cannot be seen. Repeat from #/ → Write a thesis: confirmation y=512.95..608.95; next-action link y=-1484.58..-1441.58 (scrollY=2429). Expected: the dated child-call link accompanies the visible success confirmation. Screenshots and measurements were captured against the unchanged dist export using the repository's isolated fixture; no real transaction was sent. Independently repeated in WebKit at 390×844: dedicated-form link y=-1434.84..-1391.84 versus confirmation y=512.58..608.58; home-flow link y=-1483.58..-1440.58 versus confirmation y=512.95..608.95.","severity":"medium","snippet":"      {posted?.graceEnd !== undefined && <Notice kind=\"ok\"><p>Thesis recorded. <a href={childCallHref(posted.id)}>Next: your child call, due {fmtDate(posted.graceEnd)}</a></p></Notice>}","title":"bug: thesis completion leaves the child-call handoff above the viewport"}],"hash":"5ab70d0c399183c36f823d62051f4a077faa96999090f5563259aa8956c4bbe4","nodeId":"5f36f15b-017e-4e13-939c-e0a494345e10","outcome":"completed","summary":"| Area | Result |\n|---|---|\n| Requirements | 15 met; 0 missing; 0 faked |\n| Broken features | 1 medium usability defect |\n| First screen at 390px | Product and action visible |\n| taste@1 | 14/16 passed; 2 required-caveat exceptions |\n| Copy | 0 actionable findings |\n| Share card | Present, with metadata |\n\nSaved one finding in [.imd-findings.json](/home/imd-worker/.identitymd/work/7deb4144-5498-49eb-b419-f3837845e2a6/5f36f15b-017e-4e13-939c-e0a494345e10/.imd-findings.json).\n\n**Medium — bug: thesis completion leaves the child-call handoff above the viewport.** After posting at 390×844, the visible confirmation omits the next action; its link sits over 1,400px above the viewport in Chromium and WebKit. Move the existing dated link from [Post.tsx:194](/home/imd-worker/.identitymd/work/7deb4144-5498-49eb-b419-f3837845e2a6/5f36f15b-017e-4e13-939c-e0a494345e2a6/web/src/pages/Post.tsx:194) into the confirmation below the submit button so authors see their required next step.\n\n| Explicit requirement | Status and evidence |\n|---|---|\n| Owner’s open thesis has primary “Post the child call” button | Met — `web/src/pages/Note.tsx:71` |\n| Opens composer with thesis `parentId` | Met — `thesis-parent.ts`, `trade.tsx`, `pages/Post.tsx` |\n| Visible “Child call under your thesis …, due …” | Met — `child-call.tsx:23` |\n| Any token/side; no thesis-derived prefills or counter restrictions | Met — both composers and browser scenarios |\n| Optional parent field in call mode | Met — `pages/Post.tsx:227` |\n| Optional parent field in trade box | Met — `trade.tsx`, `ThesisParentField` |\n| Parent existence checked on chain | Met — `thesis-parent.ts:30` |\n| Parent must be `ThesisOpen` | Met — `thesis-parent.ts:23` |\n| Parent belongs to connected wallet | Met — `thesis-parent.ts:24` |\n| Parent remains within grace | Met — `thesis-parent.ts:25` |\n| One-sentence validation errors | Met — `thesis-parent.ts`, `child-call.tsx` |\n| Thesis confirmation supplies dated “Next” link | Met, with placement defect above — `pages/Post.tsx:194` |\n| Feed says “needs its child call” until a child exists | Met — `pages/Feed.tsx:45` |\n| Tests cover three gates | Met — `web/tests/child-call-unit.ts`, `child-call-browser.mjs` |\n| Preserve stack, manifest, caveat and copy; deliver in repository | Met — source/export comparison and verified manifest |\n\nAll 21 browser scenarios passed in WebKit. Chromium passed 20 initially; the polling-sensitive remaining scenario passed on rerun. Unit tests, live parent reads, 15 asset hashes and three deployment ABI hashes passed. No real transactions were sent.\n\nThe brief’s “same … caveat” requirement overrides the probe’s repetition and copy-budget flags.\n\nMarginalia presents trades and bonded calls through a paper ledger with rust-colored primary actions. The site files remain unchanged.","treeHash":null,"usage":{"cachedInputTokens":3642368,"inputTokens":137750,"model":"gpt-6-astra","outputTokens":14410,"runtime":"codex","turns":7,"wallClockMs":573768}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"d5e40d018a0986f3","findings":[{"citation":"resolved","description":"Opening #/?child=<thesis-id> seeds the trade draft with parentId (web/src/trade.tsx:29) and the effect at line 41 writes the whole draft, parentId included, to localStorage under marginalia.trade.v3. readDraft (line 22) restores parentId on every later mount of #/ that has no child parameter, and afterPost never clears it. Consequences: (a) after the child is posted, the next visit to the home composer still shows 'Child call under your thesis …' and the next 'Trade and post' is sent with parentId = the thesis, so an unrelated call is recorded as another child; (b) once the thesis's seven-day grace passes (or the thesis closes), the restored parent fails validation, childParent.ready is false, fieldsOk/params are null and the Approve, Wrap, Checkpoint and 'Trade and post' buttons are all disabled until the visitor finds the 'Parent thesis (optional)' disclosure and clears the field. The brief asked that the child link prefill nothing except the parent for that one composer, not that the parent become the default for every later trade. Advisory: no funds are at risk and the context line is visible.","line":41,"path":"web/src/trade.tsx","reproduction":"1. Connect the author wallet of an open thesis T and open #/?child=<T>. The trade box shows 'Child call under your thesis …'. 2. Navigate to #/feed, then back to #/ (no query). Expected: an ordinary composer with an empty parent. Actual: the 'Parent thesis (optional)' disclosure is open with T prefilled and the child context line shows; a call posted now carries parentId = T (web/src/trade.tsx:67). 3. Repeat step 2 after T's grace end (or after T is closed): the context shows the deadline/open-thesis error and the primary action stays disabled (fieldsOk false at line 66) until the field is cleared by hand. Equivalent check in any browser: localStorage.getItem('marginalia.trade.v3') contains \"parentId\":\"0x…T\" after step 1. Reproduced by this review against the built dist with the project's own web/tests/child-call-browser.mjs harness (ownThesis fixture, extra scenario): after opening #/?child=0x…01 and then setting location.hash to #/feed and back to #/, the #trade-parent input read 0x…01, the context line read 'Child call under your thesis 0x0000…0001, due …' with the disclosure open, and pressing 'Trade and post' produced a tradeAndNote wallet request whose NoteParams.parentId was 0x…01; with the same saved draft and the thesis aged 604801 s the context read 'This thesis’s child-call deadline has passed…' and the 'Trade and post' button was disabled.","severity":"medium","snippet":"  useEffect(() => { try { localStorage.setItem(DRAFT_KEY, JSON.stringify(draft)); } catch { setStorageError(true); } }, [draft]);","title":"Trade box persists the child-link parent into the saved draft, so later ordinary calls are silently filed under the thesis and, after grace, the composer is blocked"},{"citation":"resolved","description":"The reminder is keyed only on ThesisOpen and children == 0. MarginaliaHook rejects a child once block.timestamp > postedAt + THESIS_GRACE (src/MarginaliaHook.sol:484) and lets anyone settleThesis after that (line 702), so a thesis in that state does not need a child call; it is waiting to be forfeited. The Note page for the same thesis correctly switches to 'Forfeit thesis', while the feed card and the author's own list still show a to-do the author cannot act on. Advisory copy issue.","line":45,"path":"web/src/pages/Feed.tsx","reproduction":"Feed state: a thesis with status ThesisOpen, children 0 and timestamp older than 7 days (n.timestamp + contracts.limits.thesisGrace < now). Expected: no 'needs its child call' line, or a line that says the grace has passed. Actual: the card prints 'needs its child call'; opening #/note/<id> shows the Keeper action 'Forfeit thesis' for the same note. Reproduced by this review against the built dist with the project's web/tests/child-call-browser.mjs fixture (ownThesis with noteAge 604801): #/feed text contained 'needs its child call' while #/note/<id> for the same thesis showed 'Forfeit thesis' and no 'Post the child call' link.","severity":"low","snippet":"      {thesis && n.status === Status.ThesisOpen && n.children === 0 && <p className=\"small\">needs its child call</p>}","title":"Feed card keeps saying 'needs its child call' after the grace has already expired, when the child can no longer be posted and the thesis is forfeitable"},{"citation":"resolved","description":"AGENTS.md is copied verbatim into dist/agents.md and served as the agent interface. v3.1 adds #/?child=<hex-id>, #/post?child=<hex-id> and the 'Parent (your own open thesis)' field, documented in web/README.md but not in the served agent document, which still lists only the counter prefill. Harmless for hosting; agents can still post a child through router.note with parentId as the 'Theses and duels' section implies.","line":48,"path":"AGENTS.md","reproduction":"Open dist/agents.md (identical to AGENTS.md per web/scripts/check.mjs) and search for 'child=' or 'Parent (your own open thesis)': no match. Compare web/README.md 'Child calls' section, which documents both.","severity":"info","snippet":"Hash routes: #/, #/feed, #/post, #/seal, #/pools, #/note/<hex-id>, #/duel/<counter-hex-id>, #/author/<address>, #/about. #/post?counter=<hex-id> prefills a counter-call. Pages and client-side share cards need no backend. The Pages market remains hidden until its deployment address is supplied; cited handles never establish identity. Informational, not advice. Bonds can be lost.","title":"Served agents.md does not describe the new child-call route or the own-thesis parent field"}],"hash":"a63e43c99901d93c54bb204cbb30e28205f97167de4cbe05a05db5baacff5c4e","nodeId":"6a823499-33ca-4c50-84b9-19f00c02403e","outcome":"completed","summary":"The review is complete. The findings file is written and no repository file was changed.\n\n**Outcome: nothing blocks hosting.** The v3.1 child-call work contains no critical or high content. I found one medium behavioural defect, one low copy defect and one informational gap, all recorded in `.imd-findings.json`.\n\n**What I verified**\n\n- Every hosted file was read: `dist/index.html`, both bundled scripts and the stylesheet, the ABIs, `agents.md`, `llms.txt`, the manifest and the full source they come from.\n- The shipped `dist/` is a byte-identical rebuild of `web/src` with the unchanged lockfile, and the regenerated manifest matches the shipped one. The project's manifest check passes.\n- Approvals are unchanged: exact amounts to the hook's router or the Annex only. No external script loads, no hidden frames, no new outbound hosts. The only external links are the pre-existing Radar, explorer and X intent links.\n- The three chain gates match MarginaliaHook: parent must exist, be ThesisOpen, belong to the posting wallet, and be inside the inclusive seven-day grace. Deadlines are capped at grace end.\n- The project's unit suites pass. Its 21-scenario child-call browser suite passes against the export in a headless Chromium I set up under /tmp.\n\n**Findings**\n\n- **Medium, `web/src/trade.tsx:41`.** The trade box writes the child-link parent into the saved draft. On any later plain visit to `#/` the thesis is prefilled and the next \"Trade and post\" is sent as another child; after the grace passes, the restored parent disables the primary action until cleared by hand. Reproduced in the real export: the sent `tradeAndNote` carried the thesis as parentId, and the expired case showed the deadline error with the button disabled.\n- **Low, `web/src/pages/Feed.tsx:45`.** The feed still prints \"needs its child call\" for a thesis whose grace has expired, while the note page for the same thesis offers \"Forfeit thesis\". Reproduced in the export.\n- **Info, `AGENTS.md:48`.** The served agent document does not mention the new child route or the own-thesis parent field, though the README does.","treeHash":null,"usage":{"cachedInputTokens":4732582,"inputTokens":1122,"model":"claude-fable-5-1","outputTokens":38986,"runtime":"claude","turns":47,"wallClockMs":661284}}],"verification":[{"checks":[],"detail":"paths and tree verified; no suite was run for this kind of work","evaluation":"structural","profile":"none","status":"accepted","submissionHash":"210ed14d7d98c44f17cc81a680744aebc0b412f20d484fd8db8c62be48a3e27c","verifiedTreeHash":"8724b13520322f6933a2d3fb9d43ae5b5bf6f5e5","verifierVersion":"0.1.0+327e1e9f"}]}