{"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":"86c1ca2d-51d1-45bd-aefd-4f6d2ff788ac","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"07ba684926236d42e04e211d4501a0a5bcb29a5374764c28a3d264d3894d8ff6","dependsOn":[],"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":"Host the KEPT website: the committed static export in dist/ of this repository, unchanged, under the site name kept.","parentJobId":null,"planHash":"9f9749ac1859c6d0d219ddd6ee7c232d4e91e77c5052796bed5152a0d7723f52","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"86c1ca2d-51d1-45bd-aefd-4f6d2ff788ac","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-2195-host-kept-website-committed"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"51378","feedbackHash":"1969fe4d50d8c792c8d346a6f2e6fc84954bb84a7460b2ded4fb2643f9089fa9","nodeKey":"site_content_check","submissionHash":"07ba684926236d42e04e211d4501a0a5bcb29a5374764c28a3d264d3894d8ff6","tag1":"review:submission","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"e2fc3abf1b19b8ff3c63e607f01a78f292d0b3648829ebba88f606be4b3cd751","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":null,"device":"f1bc2d45837b6b78","findings":[{"citation":"resolved","description":"The homepage substitutes sampleData().feed when the vault has no pledges, and substitutes the entire sample dataset when the RPC fails. The Swarm Scope remains labelled LIVE because its mode depends only on a configured vault address. With the actual default vault empty, the homepage displayed invented recent events including \"9/9 agree · DELIVERED\" and \"kept · 30,000,000 released\", while its counters correctly showed zero pledges. RPC failure additionally produces invented counts of seven kept and two broken milestones. These events refer to nonexistent pledges and are not identified as examples. Source: web/src/main.js:403-406 and the feed fallback in heroData, plus web/src/hero.js:23,130-148. This is an advisory data-integrity defect, not evidence that the financial claims were built to deceive. Display an empty/unavailable feed or label samples explicitly.","line":36,"path":"dist/assets/index-Dy3b-GBY.js","reproduction":"Serve unchanged dist/ over HTTP and open / in a fresh browser with reduced motion enabled (making the first four feed entries immediately visible). At Robinhood block 92104638, the configured vault returned pledgeCount=0: .rows said No pledges yet, all pledge/verdict counters were zero and the status bar said Vault live, but .vu-mode said LIVE and .vu-log showed a 9/9 DELIVERED verdict and a 30,000,000-token release for pledge #1. Reproduced against the real default RPC with no response interception and no browser errors. This is deterministic for any successful read of an empty vault. Independently, block https://rpc.mainnet.chain.robinhood.com/* in a fresh browser context and reload /: after retries fail, the same LIVE feed appears with fabricated kept/broken counts 7/2 above the Could not read the vault notice. Expected: empty/unavailable activity, or a clearly labelled SAMPLE FEED, with no sample releases presented as live.","severity":"medium","snippet":"feed:a.length?a:pu().feed","title":"Empty or unavailable vault data displays fabricated activity as LIVE"},{"citation":"resolved","description":"The published application accepts vault and rpc query parameters as trusted deployment configuration. Those values control both contract reads and the spender in token approvals, without a custom-deployment warning in the donation flow. A link to the trusted site can therefore use an attacker-controlled RPC to impersonate vault constants and cause the Donate button to approve IMD spending by an arbitrary address. The footer abbreviates that address, but the confirmation sheet calls it the vault and describes a Referee Fund donation. The observed request was for exactly 1 IMD, not an unlimited allowance. This is an advisory vulnerability in the deployment-selection feature; it does not establish malicious intent in the default deployment. Restrict production overrides or require a clear, explicit custom-deployment acknowledgement before any approval.","line":36,"path":"dist/assets/index-Dy3b-GBY.js","reproduction":"Serve dist/ at http://127.0.0.1:8765. Open a fresh browser at /?vault=0x1111111111111111111111111111111111111111&rpc=http://127.0.0.1:8765/review-rpc#/referee. Intercept POST /review-rpc as a JSON-RPC fixture: for eth_call return ABI-encoded GRACE=259200, MAX_ATTEMPTS=3, refereeFund=0, imd=0x5f7bb59365ce557c26dbcaa4ee9d39a4b95b7127, panelSize=9, quorum=7, owner=zero address, pledgeCount=0, pendingProtocol=(zero address,zero bytes32,zero address,0), collected=0, pending=0, feeNow=100, allowance=0 and approve=true; eth_chainId=0x1237. Inject a mock window.ethereum returning account 0x2222222222222222222222222222222222222222 and chain ID 0x1237, capturing and rejecting eth_sendTransaction. Click Donate with the default amount 1. Actual captured transaction: to the IMD address, calldata approve(0x1111111111111111111111111111111111111111,1000000000000000000); the sheet says Donate to the Referee Fund / Allow the vault to take the IMD and never warns about a custom deployment. Expected: production donation stays bound to the committed vault, or the altered spender/RPC requires explicit acknowledgement. Reproduced against the unchanged export without broadcasting any transaction; a remote RPC supplied through the same query parameter can provide the same fixture responses.","severity":"medium","snippet":"Ac=new URLSearchParams(location.search),jc=(e,t)=>Ac.get(e)||t,z={chainId:Number(jc(`chain`,kc.chainId)),rpc:jc(`rpc`,kc.rpc),explorer:jc(`explorer`,kc.explorer),vault:jc(`vault`,kc.vault),hook:jc(`hook`,kc.hook),token:jc(`token`,kc.token),fromBlock:BigInt(jc(`from`,kc.fromBlock)),","title":"URL overrides silently change the spender used for IMD approvals"},{"citation":"resolved","description":"The new-pledge flow independently ensures an allowance for the locked tokens and an allowance for the IMD check budget. If the selected pledge token is IMD, both use the same token/spender allowance: checking each amount separately does not cover their sum. For 10 IMD locked plus a 1 IMD budget, the site approves 10 IMD, skips the budget approval because 10 >= 1, then createPledge fails when the vault pulls both amounts. The user pays for an approval but cannot complete the otherwise valid pledge through this flow. Source: web/src/main.js:982-983; src/KeptVault.sol:createPledge calls _pullExact(token,total), then _fund pulls the budget. Combine the amounts when the token addresses match. This is a frontend transaction-flow defect, not a claim that the vault spends outside the disclosed pledge and budget.","line":36,"path":"dist/assets/index-Dy3b-GBY.js","reproduction":"Run a fresh local Anvil chain with ID 4663. Compile the unchanged src/KeptVault.sol and test/mocks/MockERC20.sol with Solc 0.8.26, Cancun and via-IR. Deploy MockERC20(\"Review IMD\",\"IMD\",1000e18) from account A, then KeptVault(A, B, token, nonzero bytes32 action, B, 9, 7), where B is a second local account. Serve unchanged dist/ and open /?vault=<local vault>&token=<local IMD>&rpc=http://127.0.0.1:8546#/new using an injected wallet backed only by local account A. Enter name \"IMD pledge reproduction\", promise \"Ship v1\", amount 10, repository kept-labs/app, release tag v1.0.0, leave the default deadline 14 days ahead and check budget 1 IMD. With initial allowance zero and balance 1000 IMD, click Lock tokens and create pledge and accept the local approval. Actual: only approve(vault,10e18) is sent; the sheet marks Allow 1 IMD for checks as Not needed, then creation fails with Panic from MockERC20 allowance underflow; pledgeCount remains 0. Expected: allowance at least 11e18 and successful creation. Control reproduced: approve exactly 11e18 directly on the local token, retry the unchanged form, and creation succeeds with locked=10e18, budget=1e18, pledgeCount=1 and allowance=0. No transaction was sent to a public network.","severity":"medium","snippet":"{label:`Allow the vault to lock ${G(l,t.token.decimals)} ${t.token.symbol}`,run:async e=>await Dl(t.token.address,z.vault,l)?Ol(t.token.address,z.vault,l,e):null},{label:`Allow ${G(u,18)} IMD for checks`,run:async e=>await Dl(d,z.vault,u)?Ol(d,z.vault,u,e):null},","title":"Creating an IMD-denominated pledge approves too little for its check budget"}],"hash":"07ba684926236d42e04e211d4501a0a5bcb29a5374764c28a3d264d3894d8ff6","nodeId":"42b8affc-cc1d-49e6-b254-a6cda6c3fa01","outcome":"completed","summary":"Reviewed all 17 export files and matching web source. Saved three medium findings in [.imd-findings.json](/home/imd-worker/.identitymd/work/86c1ca2d-51d1-45bd-aefd-4f6d2ff788ac/42b8affc-cc1d-49e6-b254-a6cda6c3fa01/.imd-findings.json):\n\n- Fabricated activity labelled “LIVE.”\n- URL overrides redirect token approvals.\n- Insufficient allowance prevents IMD pledge creation.\n\nNo critical or high hosting blockers found. Findings were reproduced; source and export remain unchanged.","treeHash":null,"usage":{"cachedInputTokens":6086144,"inputTokens":346376,"model":"gpt-6-astra","outputTokens":23122,"runtime":"codex","turns":10,"wallClockMs":782603}}],"verification":[]}