{"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":"d5530989-b886-4f9d-80dd-44d26d85ffd2","kind":"shape:chain","nodes":[{"acceptedSubmissionHash":"957a234076faa98c7304ea6c0c356cef8712e2a041d280eb032bb7df5089b44b","dependsOn":["build_contract_project","implement_component","write_foundry_tests","integrate_project"],"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":"427de9220e879fa0a3d23135283d4ce9484b36805d79398ffdf3575f96e26606","dependsOn":[],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"d59561da3b378461b7c749f6bd5084477d44993aa94972ddea90f542535751df","skillId":"build-contract-project","tools":[]},"key":"build_contract_project","kind":"code","role":"implement","skillHash":"d59561da3b378461b7c749f6bd5084477d44993aa94972ddea90f542535751df","skillId":"build-contract-project","state":"accepted"},{"acceptedSubmissionHash":"3276632c86cf8b2374b65c3a0fb74b26e5486c02f6e577e8dd3502c8f780fa7b","dependsOn":["build_contract_project"],"execution":{"network":true,"profile":"none","requires":["network"],"skillHash":"15deecb0f930dd3c37b4e551121fe447b9d43818640ca22223cf3c7951e0db98","skillId":"implement-component","tools":[]},"key":"implement_component","kind":"code","role":"implement","skillHash":"15deecb0f930dd3c37b4e551121fe447b9d43818640ca22223cf3c7951e0db98","skillId":"implement-component","state":"accepted"},{"acceptedSubmissionHash":"acac92ddca40904b994a4511a3414ad5727882d487b273d44d10e628c82c4e50","dependsOn":["write_foundry_tests"],"execution":{"network":true,"profile":"none","requires":["network"],"skillHash":"9efd723ed31bbb0747bce27bea59184a0681c23fb933fb2cc1d560029c52df8c","skillId":"integrate-project","tools":[]},"key":"integrate_project","kind":"code","role":"integrate","skillHash":"9efd723ed31bbb0747bce27bea59184a0681c23fb933fb2cc1d560029c52df8c","skillId":"integrate-project","state":"accepted"},{"acceptedSubmissionHash":"142c151faefc354301209d6b9dc5fb0dc1177994cdfca24aed7327ceee869d93","dependsOn":["implement_component"],"execution":{"network":false,"profile":"foundry","requires":[],"skillHash":"4c76766b00591dfe982fe85d3de589fdb2f810e5137c301155d1c5e36a1d3b23","skillId":"write-foundry-tests","tools":[]},"key":"write_foundry_tests","kind":"code","role":"tests","skillHash":"4c76766b00591dfe982fe85d3de589fdb2f810e5137c301155d1c5e36a1d3b23","skillId":"write-foundry-tests","state":"accepted"},{"acceptedSubmissionHash":"b73e40ce6daa7427bddd6788609d489229cf709c4a183a6d5d2729a87aef5716","dependsOn":["adversarial_review"],"execution":{"network":false,"profile":"none","requires":[],"skillHash":"7e3e9a90f2342f72573636f539f0a3a3016b9f8bf53c7b77a17dc4608a09d0b2","skillId":"write-readme-and-docs","tools":[]},"key":"write_readme_and_docs","kind":"code","role":"implement","skillHash":"7e3e9a90f2342f72573636f539f0a3a3016b9f8bf53c7b77a17dc4608a09d0b2","skillId":"write-readme-and-docs","state":"accepted"}],"objective":"Build CTO Relay Station A1: complete Agent-facing public-project continuation, root Foundry contracts plus Node SDK/CLI, local tests, independent review and repairs. Local test deployments required; no public-chain deployment, frontend, live paid tests, paid child jobs, real credentials, autonomous spending, token launch, governance, ranking or treasury. Actual files, multi-assets and historical forks belong in A1.\n\nSIX FUNCTIONS: anyone creates project/root Branch with fixed public goal; proposes work; explicitly sponsors a nonzero proposal; reads files/state/history; continues; forks accepted history. Creation/proposal/fork never implicitly buys AI. No two-round limit. Proposal binds current anchor, profile, target assetKey, selected input keys, output mapping, text and publish choice. Sponsors cannot replace them. Reject stale/conflicting/invalid purchases before collecting IMD. Adding a proposal cannot change execution anchor or invalidate other current proposals; any current proposal is selectable, without FIFO.\n\nAUTHORITY: Factory registers fixed nonupgradeable Branch code, atomically initialized with immutable encoder/verifier/profiles. No operator setters, admin edits or arbitrary request/skill/payment entrypoint. Branch is IMD payer; root/child first runs use job.open@job-1, later runs job.continue@job-1 with own latest bound job. Child starts without own project/head. Never pass repoUrl/baseCommit or parent's projectId to continue.\n\nINTAKE: official intake-client protocol, not its mutable-owner tutorial. Ethereum Intake v2 0xa43e6f75ee006411f79ac1c84120606c2330de82; IMD 0xd34a99bc0f67ae1bbd63c660e6d0b0dd03e263b7. Runtime priceOf(action,asset), sponsor maxFee, exact transfer/approval, requestWithFailure, clear leftover allowance. Authenticate fixed Intake, own outstanding request and target/selector. Small callbacks record digest/phase only; no parsing/download/binding/new work. Reentrancy/state guards required.\n\nFAILURES: if no callback arrives, remain pending indefinitely. Refused status 1 allows only explicit funded retry of identical body/snapshot/proposal with new attempt receipt; no parent/text/file substitution. Status 2 or unknown failure freezes purchases. Failed attempts are not revisions. No timeout unlock, automatic refund/retry, admin repair or HTTP settlement. Bad binding preserves recorded result/old checkpoint; anyone can resubmit correct binding without buying AI.\n\nBINDING: exact raw manifest plus bounded old-asset witness; verify callback keccak256, complete JSON/completion/job/project identity and unique declared accepted files[] output. Never reserialize JSON or substitute source[]/later Git metadata. Strict UTF-8/escapes; reject decoded duplicate keys, trailing data, bad Unicode/paths and excessive depth/count/length. Preserve name,path,hash,mediaType,bytes,submissionHash and producing Branch/job/result/revision. File SHA-256 differs from manifest keccak256. Writer honesty/availability remain trust assumptions; hashes do not prove quality/input consumption.\n\nASSETS: bounded sorted canonical assetKey table; one accepted main file per slot, one predeclared target changes per round; all other descriptors/provenance remain identical without model re-emission. Latest job orders execution; assets may originate in older rounds. Permanent per-revision checkpoints bind chain/Factory/Branch/policy/revision/source; calldata/events allow public witness reconstruction. Factory.fork authenticates registered parent's chosen checkpoint/full witness, inherits exactly that historical asset set/provenance, fixes child direction. No copying proposals/project IDs/publication names/authority; no recursive ancestry or latest-only fake history.\n\nLIMITS: candidates 16 assets/8 inputs/1 output, 64 KiB document/2 MiB HTML; measure/fix safe constants and disclose restrictions. Reserve one slot per enabled type; at capacity existing updatable slots still update. Bound all fields/parser resources; runtime request bodies <=16,384 UTF-8 bytes. Reject known overlimits before payment; no implicit deletion/unbounded loops.\n\nPROFILES: implement/test Markdown create/update, self-contained HTML create/update, single image generation; no all-stub/all-disabled A1. Explicit runtime steps[].inputs carry full authenticated descriptors/unique aliases at .imd/reads/artifacts/<alias>; selected current assets only, update target mandatory. Fix skill/output/MIME/size/create/update/input-type/publish rules in encoder. Unsupported image reference/editing modes disabled; stored unselected files not falsely claimed read.\n\nHTML: accepted named HTML equals dist/index.html bytes; inline CSS/JS/small PNG/JPEG/WebP. Restore selected HTML, not stale workspace; dist only index.html, no symlinks. Candidate images <=256 KiB each/512 KiB aggregate; count Base64/data-URI overhead within HTML cap and reject known invalid input before payment. HTML -> image -> HTML: third parent is second job, inputs first HTML plus second image; retain old markers and exact inline image bytes. Profiles use github:true, nonwebsite ipfs:false. Publishing defaults off and unverified modes disabled in fixed release config. File/Git/publication states stay separate; live compatibility remains NOT_RUN.\n\nSDK/CLI: six functions, previews, canonical witnesses, prepared proposal/sponsor/retry/bind transactions, history recovery and actual file SHA-256/length/MIME checks. Default unsigned; no real keys/wallets, mandatory server/signer/indexer. Separate transaction/admission/execution/callback/binding/file/Git/publication. Reconcile unknown transactions, never rebuy automatically. Inputs untrusted; no local/private-network downloads or file execution. No browser preview.\n\nTEST/DELIVERY: execute each step's local tests and independent review. Unresolved Critical/High or core failures block readiness. Deliver public source, ABI/config, CLI, raw evidence, measured limits and live-validation tools. Local mocks are not real IMD consumption or deployment proof.","parentJobId":null,"planHash":"8eaa53b2262a152ab0045ba273e313c12443f9e0a3a7c61505f0141760691f6e","previousHash":"0000000000000000000000000000000000000000000000000000000000000000","projectId":"d5530989-b886-4f9d-80dd-44d26d85ffd2","publication":{"commit":null,"deliveredAt":null,"repoUrl":"https://github.com/identity-md-launches/launch-2294-build-cto-relay-station"},"receiptIdentity":{"adapter":"0xde152afb7db5373f34876e1499fbd893a82dd336","chainId":1,"collection":"0x0000ec93127baa929e58e97dd0095a2bfb38ec1d","registry":"0x8004a169fb4a3325136eb29fa0ceb6d2e539a432"},"registry":"0xb6d0a187b050fa5bb0b87033a203f37becf4a775","research":[],"schema":"identitymd-work-v1","signals":[{"agentId":"51511","feedbackHash":"5d401bc18bbf250bea31699a6bb70a749e6f01301d8d54d0027761b4ad853d60","nodeKey":"adversarial_review","submissionHash":"957a234076faa98c7304ea6c0c356cef8712e2a041d280eb032bb7df5089b44b","tag1":"review:submission","tag2":"acceptance-v2","value":1},{"agentId":"51085","feedbackHash":"ba22fc1007ee193d313af8084fc7db612b16f9ef8c0a68eb71f79a340ca63d34","nodeKey":"build_contract_project","submissionHash":"427de9220e879fa0a3d23135283d4ce9484b36805d79398ffdf3575f96e26606","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"51548","feedbackHash":"80cdf10f21555e6b6c5e11241a248db36c7646a71e426f6c99f2cb863801a3a4","nodeKey":"implement_component","submissionHash":"3276632c86cf8b2374b65c3a0fb74b26e5486c02f6e577e8dd3502c8f780fa7b","tag1":"verification:structural","tag2":"acceptance-v2","value":1},{"agentId":"51725","feedbackHash":"07e97c83d973952bcb5f933a16ed59ca938defda1537c58335768fc05569b96b","nodeKey":"integrate_project","submissionHash":"acac92ddca40904b994a4511a3414ad5727882d487b273d44d10e628c82c4e50","tag1":"verification:structural","tag2":"acceptance-v2","value":1},{"agentId":"51567","feedbackHash":"32260ac58d73213a85cef8863c1c17da0aaf834b2c38ed3e56f9ab42ff08c555","nodeKey":"write_foundry_tests","submissionHash":"142c151faefc354301209d6b9dc5fb0dc1177994cdfca24aed7327ceee869d93","tag1":"verification:checks","tag2":"acceptance-v2","value":1},{"agentId":"52713","feedbackHash":"099bd4fcaab7aa1a30a2aeba18cf2eb8166942716150c10ebd24aea19c08fc08","nodeKey":"write_readme_and_docs","submissionHash":"b73e40ce6daa7427bddd6788609d489229cf709c4a183a6d5d2729a87aef5716","tag1":"verification:structural","tag2":"acceptance-v2","value":1}],"site":null,"snapshotHash":"2527c20a5a742296b340a93a52be1fd9d637c5e26677b5411a20e0a8d728c3b7","state":"completed","submissions":[{"artifacts":[],"attempt":1,"bundleHash":"c32a8b00e318c7e0103b40937cf72ecd2e6bf69f943478c1fa2fa629d02c814e","device":"165e283901cb9619","findings":[],"hash":"142c151faefc354301209d6b9dc5fb0dc1177994cdfca24aed7327ceee869d93","nodeId":"59b85866-e267-4f07-957e-e2497e351023","outcome":"completed","summary":"Added 37 adversarial tests, all under `test/`.\n\n- `forge build` passed.\n- Seeded `forge test`: **91 passed, 0 failed, 0 skipped**.\n- New invariant: **24,576 random calls**, zero handler reverts.\n\nNo confirmed contract defects found. Live validation remains **NOT_RUN**.\n\n[Coverage and raw evidence](/root/.identitymd/work/d5530989-b886-4f9d-80dd-44d26d85ffd2/59b85866-e267-4f07-957e-e2497e351023/test/adversarial/README.md)","treeHash":"db3683f6096285b248d378e5b3baca0d6ad13478","usage":{"cachedInputTokens":6983296,"inputTokens":162126,"model":"gpt-6-astra","outputTokens":52373,"runtime":"codex","turns":13,"wallClockMs":1774872}},{"artifacts":[],"attempt":1,"bundleHash":"01bcb8ae4e0be60ab4c028e6679ee970b7b90b7fd303f4a2c1860c0ce5e93439","device":"0116c8455d2c62d4","findings":[],"hash":"3276632c86cf8b2374b65c3a0fb74b26e5486c02f6e577e8dd3502c8f780fa7b","nodeId":"0428418f-f36e-4eb8-bc03-e5ece3b6f289","outcome":"completed","summary":"Implemented the unsigned Node SDK/CLI deliverable.\n\n- Added fixed-profile pre-admission validation, optional read-only EIP-1193 queries, lifecycle status separation, and CLI history recovery.\n- Added bounded public-HTTPS artifact fetching with DNS/private-network protections and structured errors.\n- Added actual fixture verification, mock EIP-1193 coverage, CLI error/status tests, and recorded evidence.\n- No wallet, keys, signing, broadcasting, automatic retry, or paid/live-chain action added.\n\nChecks passed: `node --test test-sdk/*.test.mjs` — 17/17.\n\nDocumentation: [SDK-CLI-A1.md](/home/imd-worker/.identitymd/work/d5530989-b886-4f9d-80dd-44d26d85ffd2/0428418f-f36e-4eb8-bc03-e5ece3b6f289/docs/agent/SDK-CLI-A1.md), [sdk-cli-checks.md](/home/imd-worker/.identitymd/work/d5530989-b886-4f9d-80dd-44d26d85ffd2/0428418f-f36e-4eb8-bc03-e5ece3b6f289/docs/agent/sdk-cli-checks.md).","treeHash":"3e8556eb68045051ac06fe5a008660f7a7241e40","usage":{"cachedInputTokens":2681856,"inputTokens":109747,"model":null,"outputTokens":26444,"runtime":"codex","turns":4,"wallClockMs":776767}},{"artifacts":[],"attempt":1,"bundleHash":"9b776a2415cb9bbd1f4d2c106dfe5e7fc48edb7e839db8ef29c46393172c58ff","device":"e8f1969b1b8ff9d4","findings":[],"hash":"427de9220e879fa0a3d23135283d4ce9484b36805d79398ffdf3575f96e26606","nodeId":"5d710dbf-907b-4b7d-acf3-ec1f16473496","outcome":"completed","summary":"Implemented the Solidity core, vendored dependencies, ABIs/config, and unsigned SDK/CLI foundation.\n\nPassed: `forge build`, 54 Solidity tests, 12 Node tests, and `forge fmt --check`.\n\n[README.md](/home/imd/.identitymd/work/d5530989-b886-4f9d-80dd-44d26d85ffd2/5d710dbf-907b-4b7d-acf3-ec1f16473496/README.md) documents the measured 8 KiB manifest limit and evidence. Live validation and independent contributor review remain `NOT_RUN`.","treeHash":"8d09f1e96856b6669f7f77072247086c9801793e","usage":{"cachedInputTokens":9376384,"inputTokens":186031,"model":"gpt-6-astra","outputTokens":117206,"runtime":"codex","turns":9,"wallClockMs":3862505}},{"artifacts":[],"attempt":1,"bundleHash":null,"device":"fbcdfc017217af1f","findings":[{"citation":"resolved","description":"Actor: any proposer plus any sponsor. _validate's create branch rejects only a colliding asset key; outputName/outputPath are never compared against the other current slots (Assets.validate and descriptor check each entry in isolation). After a Markdown slot key=1 named 'main' at docs/main.md is accepted, MarkdownCreate with key=2, outputName 'main', outputPath 'docs/main.md' passes propose, sponsor and bind. The table then holds two slots whose public file mapping is identical but whose hash/jobId/revision differ, and the Git tree can only hold one of them, so the 'one accepted main file per slot' and 'create without replacing another slot' guarantees are broken: the second run overwrites the first slot's file while the first descriptor still claims it. An HTML proposal selecting both as inputs also emits two steps[].inputs entries with the same name and path (only the alias differs), an ambiguous instruction to the runtime. The SDK validateProposal mirrors the gap. Fix preserving design: in the create branch reject any current asset whose name or path equals p.outputName/p.outputPath (HTML's fixed dist/index.html then implies at most one HTML slot, which should be disclosed).","line":98,"path":"src/RelayEncoder.sol","proof":"// SPDX-License-Identifier: MIT\npragma solidity 0.8.26;\n\n// Self-contained: forge-std is not vendored in this tree, so a minimal Vm interface is declared here.\nimport {RelayFactory} from \"src/RelayFactory.sol\";\nimport {RelayBranch} from \"src/RelayBranch.sol\";\nimport {RelayTypes as T} from \"src/RelayTypes.sol\";\nimport {Policy} from \"src/libraries/Policy.sol\";\nimport {Text} from \"src/libraries/Text.sol\";\nimport {IIntake} from \"src/interfaces/IIntake.sol\";\n\ninterface Vm {\n    struct Log {\n        bytes32[] topics;\n        bytes data;\n        address emitter;\n    }\n\n    function prank(address) external;\n    function etch(address, bytes calldata) external;\n    function expectRevert() external;\n    function recordLogs() external;\n    function getRecordedLogs() external returns (Log[] memory);\n}\n\ncontract Tok {\n    mapping(address => uint256) public balanceOf;\n    mapping(address => mapping(address => uint256)) public allowance;\n    function mint(address to, uint256 v) external { balanceOf[to] += v; }\n    function approve(address s, uint256 v) external returns (bool) { allowance[msg.sender][s] = v; return true; }\n    function transferFrom(address f, address t, uint256 v) external returns (bool) {\n        allowance[f][msg.sender] -= v;\n        balanceOf[f] -= v;\n        balanceOf[t] += v;\n        return true;\n    }\n}\n\ncontract Intake is IIntake {\n    address public writer;\n    uint256 public count;\n    mapping(bytes32 => IIntake.Callback) public cbs;\n    function init(address w) external { writer = w; }\n    function priceOf(bytes32, address) external pure returns (uint256) { return 0.5 ether; }\n    function requestWithFailure(bytes32, bytes calldata body, Callback calldata cb, bytes4, address asset, uint256 amount)\n        external payable returns (bytes32 id)\n    {\n        require(body.length != 0 && body.length <= 16_384 && amount >= 0.5 ether);\n        Tok(asset).transferFrom(msg.sender, address(0xC0FE), amount);\n        id = keccak256(abi.encode(++count));\n        cbs[id] = cb;\n    }\n    function complete(bytes32 id, bytes calldata raw) external {\n        require(msg.sender == writer);\n        (bool ok,) = cbs[id].target.call{gas: 200_000}(\n            abi.encodeWithSelector(cbs[id].selector, id, keccak256(raw), \"ipfs://x/result.json\"));\n        require(ok, \"cb\");\n    }\n}\n\ncontract DuplicateMappingTest {\n    Vm constant vm = Vm(address(uint160(uint256(keccak256(\"hevm cheat code\")))));\n    RelayFactory factory;\n    RelayBranch branch;\n    Tok token;\n    Intake intake;\n    address constant SPONSOR = address(0xB0B);\n    address constant WRITER = address(0xA11CE);\n\n    function setUp() public {\n        vm.etch(Policy.IMD, address(new Tok()).code);\n        vm.etch(Policy.INTAKE, address(new Intake()).code);\n        token = Tok(Policy.IMD);\n        intake = Intake(Policy.INTAKE);\n        intake.init(WRITER);\n        factory = new RelayFactory();\n        branch = factory.createProject(\"Maintain a public relay project.\");\n        token.mint(SPONSOR, 100 ether);\n        vm.prank(SPONSOR);\n        token.approve(address(branch), 100 ether);\n    }\n\n    function _manifest(string memory job) internal pure returns (bytes memory) {\n        return bytes.concat(\n            '{\"jobId\":\"', bytes(job), '\",\"projectId\":\"proj-1\",\"state\":\"completed\",\"files\":[{\"name\":\"main\",\"path\":\"docs/main.md\",\"hash\":\"',\n            bytes(Text.hex32(sha256(\"c\"))), '\",\"mediaType\":\"text/markdown\",\"bytes\":10,\"submissionHash\":\"',\n            bytes(Text.hex32(sha256(\"s\"))), '\"}]}'\n        );\n    }\n\n    function _proposal(uint256 key) internal view returns (T.Proposal memory p) {\n        p.anchor = branch.anchor();\n        p.profile = T.Profile.MarkdownCreate;\n        p.target = bytes32(key);\n        p.inputs = new bytes32[](0);\n        p.outputName = \"main\";\n        p.outputPath = \"docs/main.md\";\n        p.text = \"Write it.\";\n    }\n\n    function _accept(T.Proposal memory p, T.Asset[] memory old, string memory job) internal returns (T.Asset[] memory next) {\n        uint256 id = branch.propose(p, old);\n        vm.prank(SPONSOR);\n        bytes32 req = branch.sponsor(id, 1 ether, old);\n        bytes memory raw = _manifest(job);\n        vm.prank(WRITER);\n        intake.complete(req, raw);\n        vm.recordLogs();\n        branch.bind(raw, old);\n        Vm.Log[] memory logs = vm.getRecordedLogs();\n        for (uint256 i; i < logs.length; ++i) {\n            if (logs[i].emitter == address(branch) && logs[i].topics[0] == keccak256(\"CheckpointWritten(uint64,bytes32,bytes)\")) {\n                next = abi.decode(abi.decode(logs[i].data, (bytes)), (T.Asset[]));\n            }\n        }\n    }\n\n    /// Two distinct slots must not share one public file mapping (name and path).\n    function test_secondSlotWithSameNameAndPathIsRejected() public {\n        T.Asset[] memory one = _accept(_proposal(1), new T.Asset[](0), \"job-1\");\n        require(one.length == 1, \"first slot accepted\");\n        T.Proposal memory dup = _proposal(2); // new key, identical name \"main\" and path \"docs/main.md\"\n        vm.expectRevert();\n        branch.propose(dup, one);\n    }\n}","reproduction":"Root branch; accept MarkdownCreate(target=0x..01, outputName='main', outputPath='docs/main.md') through propose/sponsor/complete/bind. Then propose MarkdownCreate(target=0x..02, outputName='main', outputPath='docs/main.md', inputs=[]) with the one-asset witness. Expected: revert Policy.Invalid (duplicate public mapping). Actual: proposal id 2 is created and can be sponsored and bound (scratch test fails with 'next call did not revert as expected').","severity":"medium","snippet":"            if (targetIndex != type(uint256).max) revert Policy.Invalid();","title":"Create profiles only check key uniqueness, so two accepted slots can claim the same public name and path"},{"citation":"resolved","description":"Actor: the honest writer delivering a status-0 callback. bind requires the exact raw bytes whose keccak256 was recorded, and parses the whole document under MAX_MANIFEST=8192 bytes, 32 members per object/array, 256 tokens, 1024-byte strings, depth 8. The live result document also carries 'source' and 'delivery' whose size the Branch does not control; the fixtures assume source:[]. If the real document has a source[] of 33 entries, or exceeds 8192 bytes, or any string longer than 1024 bytes, bind reverts Policy.Limit on every call. Phase stays ResultRecorded forever: sponsor/retry are blocked (phase != Ready/Refused), no other callback can arrive, and there is no admin path by design, so every proposal and all future work on that branch is lost even though the result is valid and the IMD was spent. Only a fork at an older checkpoint survives. The limits document discloses the bounds but not this liveness consequence, and no evidence shows a live result.json measured against them (evidence/check-results.json is a check of request bodies, not of result documents). Fix within design: either size the envelope from a measured live result document (and record that measurement), or let the verifier skip unknown top-level members by scanning raw bytes with a bounded structural skipper that does not materialize tokens/strings, so unknown metadata cannot exhaust the token/member caps.","line":138,"path":"src/libraries/StrictJSON.sol","reproduction":"Branch with a pending attempt. Writer completes with raw = {\"jobId\":\"j1\",\"projectId\":\"p1\",\"state\":\"completed\",\"source\":[\"a\",\"b\",...33 strings...],\"files\":[{valid single output}]} (about 300 bytes). onIntakeResult records keccak256(raw), phase=ResultRecorded. Expected: bind(raw, witness) accepts the valid output (unknown metadata should not matter) or some funded path to continue exists. Actual: bind reverts Policy.Limit at the 33rd array member; sponsor and retry revert Busy; the branch is stuck in ResultRecorded indefinitely. Same outcome for a 8193-byte document or a 1025-byte 'uri'/'commit' string.","severity":"medium","snippet":"            if (++members > MAX_MEMBERS) revert Policy.Limit();","title":"A completed result whose raw document exceeds the fixed parser envelope can never be bound and permanently freezes the branch"},{"citation":"resolved","description":"Actor: any proposer. outputPath only checks the suffix for Markdown/Image, so ImageCreate with outputPath 'dist/logo.png' or MarkdownCreate with 'dist/notes.md' is accepted before payment, while the encoder's HTML instruction and the SDK's verifyHTMLDist require dist to contain only index.html. A later HTML run then cannot satisfy both the accepted asset table and the dist-shape rule; the SDK's dist check fails on an otherwise correct delivery. Fix: reject any non-HTML output path whose first segment is 'dist' (and disclose it), mirrored in sdk/index.mjs outputPath.","line":44,"path":"src/libraries/Assets.sol","reproduction":"Root branch, empty witness: propose(ImageCreate, target=0x..01, inputs=[], outputName='logo', outputPath='dist/logo.png', text='A logo'). Expected: revert Policy.Invalid. Actual: proposal accepted and sponsorable; after binding, verifyHTMLDist on a repo containing dist/logo.png and dist/index.html throws 'dist must contain only a regular index.html'.","severity":"low","snippet":"        if (kind == T.Kind.Image && !Text.suffix(path, \".png\")) revert Policy.Invalid();","title":"Markdown and image outputs may be declared under dist/, contradicting the 'dist contains only index.html' rule"},{"citation":"resolved","description":"Non-blocking observation, consistent with the brief's 'status 1 allows only explicit funded retry of identical body'. Any actor can propose text the plane's content screen refuses, sponsor it once, receive status 1, and from then on sponsor() reverts Busy for every other proposal while retry() can only re-spend on the same refused body. The only exit for the public is a Factory.fork of an earlier accepted revision (impossible for a root at revision 0). The README does not spell out that a single refusal is terminal for new work on that branch; disclosing it, or a scope decision to allow a different current proposal after a status-1 refusal, is the requester's call.","line":178,"path":"src/RelayBranch.sol","reproduction":"Root branch: propose P1 (text that the plane refuses), sponsor P1, writer fails with status 1. propose P2 (anchor unchanged) succeeds; sponsor(P2) reverts Busy; retry() re-spends 0.5 IMD on P1's identical body. Expected per brief: exactly this; reported so the requester confirms it is intended.","severity":"info","snippet":"        if (phase != T.Phase.Refused) revert Busy();","title":"One refused purchase (0.5 IMD) pins a branch to retrying that single proposal forever; design consequence worth stating"}],"hash":"957a234076faa98c7304ea6c0c356cef8712e2a041d280eb032bb7df5089b44b","nodeId":"b5804a73-da1b-400f-a346-8559a0e5bbdb","outcome":"completed","summary":"The findings file is written and all four snippets match the tree at the quoted lines. Final recap:\n\n**Outcome.** The build and all 91 Foundry tests pass, and the core payment, callback, binding, fork and parser paths hold up under the inputs I traced. I found no Critical or High defect, so nothing blocks readiness on core invariants. Two Medium findings, one Low and one Info observation are in `.imd-findings.json`, each with a concrete reproducer, plus a coverage row for every listed entry point.\n\n**Findings, ranked.**\n1. **Medium, duplicate public file mapping across slots.** Create profiles reject only a colliding asset key, never a colliding output name or path. After a Markdown slot named `main` at `docs/main.md` is accepted, a second MarkdownCreate with a new key but the same name and path passes propose, sponsor and bind. Two slots then claim one Git file, breaking \"one accepted main file per slot\". Confirmed with a self-contained scratch test under `test/scratch/` that fails on the current code and is attached as proof.\n2. **Medium, unbindable honest result freezes the branch.** The verifier parses the whole raw document under fixed caps, including unknown members like `source[]`. A valid completed result with 33 source entries, more than 8192 bytes, or any string over 1024 bytes can never be bound. The branch stays in ResultRecorded forever with no retry or new purchase. No evidence measures a real live result document against these caps.\n3. **Low, non-HTML outputs allowed under dist/.** An image at `dist/logo.png` is accepted before payment, which contradicts the \"dist only index.html\" rule the encoder instruction and the SDK dist check enforce.\n4. **Info, refusal pins the branch.** One refused purchase for 0.5 IMD makes every other proposal unsponsorable until an identical retry succeeds. This matches the brief and is reported only for the requester to confirm the intent.\n\n**What I checked and found sound.** Fixed Intake and IMD addresses, runtime price against the sponsor's maxFee, exact pull and cleared allowance, request id uniqueness, callback authentication and reentrancy guards, status 1 versus other failures, factory-only atomic initialization with a pre-initialized implementation, fork authentication against a stored nonzero checkpoint, strict JSON handling of decoded duplicate keys, surrogates, overlong UTF-8 and trailing data, and the SDK's HTTPS-only, public-address-pinned, size-bounded artifact fetch with SHA-256 and MIME verification. Slither's reentrancy leads are covered by the guard and the pending-request check and did not reproduce.\n\n**Not verified.** Live compatibility of the request body shape and the result document with the real plane remains NOT_RUN; local mocks prove no real IMD consumption.","treeHash":null,"usage":{"cachedInputTokens":983863,"inputTokens":322,"model":"claude-fable-5-1","outputTokens":31890,"runtime":"claude","turns":29,"wallClockMs":533661}},{"artifacts":[],"attempt":1,"bundleHash":"969b073ace9b9833978959af8682e69a73e4be1af89f0964ae044cffcfe23b91","device":"004eae350f695d24","findings":[],"hash":"acac92ddca40904b994a4511a3414ad5727882d487b273d44d10e628c82c4e50","nodeId":"f5a3468f-9878-4094-a115-eec2787fbf15","outcome":"completed","summary":"Integrated and validated A1. Repaired the SDK’s private-network download bypass and added regression tests.\n\n- Foundry: 91 passed.\n- Node: 20 passed.\n- Actual Anvil flow passed across all profiles, historical fork, child continuation, retry and binding recovery.\n- Independent review found no unresolved Critical/High issues.\n- ABI/config and resource measurements verified.\n\nEvidence: [docs/validation/README.md](docs/validation/README.md).\n\nLive IMD compatibility remains `NOT_RUN`; no public deployment or paid execution occurred.","treeHash":"c76ec6c4e0b9afae00482075bc964afff3491894","usage":{"cachedInputTokens":2418816,"inputTokens":97262,"model":null,"outputTokens":14735,"runtime":"codex","turns":6,"wallClockMs":465497}},{"artifacts":[],"attempt":1,"bundleHash":"e6d953dcc4f09d5eb78d81c25636b1e3068c06e5359032db61e2254af863da86","device":"027fa8eee8653e6f","findings":[],"hash":"b73e40ce6daa7427bddd6788609d489229cf709c4a183a6d5d2729a87aef5716","nodeId":"c094af11-dc7f-4c35-be2c-4ca7a4cac349","outcome":"completed","summary":"Updated README.md and docs/ with runnable build/test/CLI instructions, public API permissions and failures, limits, review status, future IMD validation steps, and the A1-to-W1 handoff.\n\nValidated 91 Foundry tests, 20 Node tests, seven local integration rounds, and every documented CLI shell block.\n\nCode remains unchanged. Live compatibility and public deployment remain **NOT_RUN**; production readiness remains false.","treeHash":"5b60530aee3e82f65563934ff2e03b783670fa2a","usage":{"cachedInputTokens":3257472,"inputTokens":143789,"model":"gpt-6.1-sol","outputTokens":41327,"runtime":"codex","turns":7,"wallClockMs":1070692}}],"verification":[{"checks":[{"durationMs":139308,"exitCode":0,"name":"build","output":"Compiling 37 files with Solc 0.8.26\nSolc 0.8.26 finished in 139.20s\nCompiler run successful with warnings:\nWarning (2519): This declaration shadows an existing declaration.\n   --> test/RelayProfiles.t.sol:324:13:\n    |\n324 |             bytes memory raw = _manifest(Text.hex32(keccak256(abi.encode(i))), Policy.kind(profile), 32);\n    |             ^^^^^^^^^^^^^^^^\nNote: The shadowed declaration is here:\n   --> test/RelayProfiles.t.sol:332:9:\n    |\n332 |         bytes memory raw = _manifest(Text.hex32(keccak256(\"new job\")), T.Kind.Markdown, 42);\n    |         ^^^^^^^^^^^^^^^^\n\n","passed":true},{"durationMs":26503,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 2 tests for test/CrossLanguage.t.sol:CrossLanguageTest\n[PASS] test_sdkCalldataActuallyCreatesBranchWithoutPayment() (gas: 327533)\n[PASS] test_sdkCanonicalWitnessMatchesSolidity() (gas: 663085)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 20.96ms (2.97ms CPU time)\n\nRan 5 tests for test/adversarial/ContinuationSpec.t.sol:ContinuationSpecTest\n[PASS] test_checkpointPreimageBindsChainFactoryBranchPolicyRevisionAndSource() (gas: 4329671)\n[PASS] test_currentProposalsSelectableInEitherOrderAndLosingSponsorPaysNothing() (gas: 9067844)\n[PASS] test_everyWitnessFieldAuthenticatedForSponsorBindAndHistoricalFork() (gas: 9856365)\n[PASS] test_fiveRootRoundsTwoSponsorsHistoricalForkAndTwoChildRounds() (gas: 41722332)\n[PASS] test_foreignFactoryAndUnregisteredLookalikeCannotForgeHistoricalFork() (gas: 3766336)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 1.02s (295.19ms CPU time)\n\nRan 9 tests for test/RelayHistory.t.sol:RelayHistoryTest\n[PASS] test_badBindingPreservesResultThenCorrectWitnessWorksWithoutPurchase() (gas: 6972999)\n[PASS] test_childCannotBindParentsProjectAsOwn() (gas: 7051933)\n[PASS] test_forkCannotAuthenticateFakeParentLatestWitnessOrForgedProvenance() (gas: 7001657)\n[PASS] test_forkChosenHistoricalCheckpointStartsOwnProjectAndPayer() (gas: 15984077)\n[PASS] test_forkIsAllowedWhileParentPendingOrFrozen() (gas: 6727514)\n[PASS] test_htmlImageHtmlLatestJobAndOlderSelectedInputs() (gas: 27253583)\n[PASS] test_projectMismatchCannotOverwriteCheckpoint() (gas: 7446871)\n[PASS] test_reinitializeAndImplementationInitializationCannotChangeAuthority() (gas: 219434)\n[PASS] test_reusedJobCannotCreateNewRevision() (gas: 6531511)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 1.45s (365.66ms CPU time)\n\nRan 11 tests for test/adversarial/ManifestSpec.t.sol:ManifestSpecTest\n[PASS] testFuzz_nonWhitespaceTrailingByteAlwaysRejected(uint8) (runs: 1000, μ: 72226, ~: 72227)\n[PASS] testFuzz_unicodeScalarEscapesDecodeAndDuplicateKeysReject(uint32) (runs: 1000, μ: 243405, ~: 242436)\n[PASS] test_callbackDigestBindsWhitespaceAndKeyOrderOfOriginalBytes() (gas: 3622098)\n[PASS] test_exactDepthMemberKeyAndTokenBoundaries() (gas: 4652769)\n[PASS] test_exactManifestAndStringByteLimitsAcceptBoundaryRejectOneMore() (gas: 10120444)\n[PASS] test_fileSizeIntegerGrammarAndAllProfileDeclaredCaps() (gas: 25094661)\n[PASS] test_hashEncodingTypeWidthNonhexAndZeroAreCheckedForBothDigests() (gas: 98828485)\n[PASS] test_identityLengthDecodedFieldsAndEmptyAcceptedFiles() (gas: 8745774)\n[PASS] test_manifestRejectionsKeepRecordedDigestAndOldHistory() (gas: 64600160)\n[PASS] test_projectSwitchAndHistoricalJobReplayPreservePreviousCheckpoint() (gas: 17042293)\n[PASS] test_sourceAndLaterGitMetadataNeverReplaceAcceptedFilesDescriptor() (gas: 3834148)\nSuite result: ok. 11 passed; 0 failed; 0 skipped; finished in 1.45s (3.71s CPU time)\n\nRan 5 tests for test/adversarial/ProfileBoundarySpec.t.sol:ProfileBoundarySpecTest\n[PASS] testFuzz_htmlBase64RoundingAndOneByteOverTheKnownInputBudget(uint32) (runs: 1000, μ: 931995, ~: 932047)\n[PASS] test_realEightAssetWitnessExact16384ByteRequestAndOneByteOverRejectedBeforePayment() (gas: 133916201)\n[PASS] test_slotReservationInputCountAndFullCapacityUpdateBoundaries() (gas: 7888749)\n[PASS] test_unsafePathComponentsInvalidUtf8AndDisabledModesRejectWithoutSpending() (gas: 2356657)\n[PASS] test_utf8TextLimitsCountBytesAndOutputMappingLengthsAreBounded() (gas: 29913491)\nSuite result: ok. 5 passed; 0 failed; 0 skipped; finished in 1.45s (1.91s CPU time)\n\nRan 14 tests for test/adversarial/PaymentSpec.t.sol:PaymentSpecTest\n[PASS] testFuzz_priceChangeCapAndDonationsConserveEveryWei(uint96,uint64) (runs: 1000, μ: 2963997, ~: 2964457)\n[PASS] testFuzz_unknownFailureFrozenDespiteNewProposalsAndTime(uint8) (runs: 1000, μ: 3271679, ~: 3271681)\n[PASS] test_continuationRetryRetainsParentAndFullSelectedSnapshot() (gas: 8213914)\n[PASS] test_exactWholeBalanceAndMaxFeeDoesNotOvercharge() (gas: 2219952)\n[PASS] test_insufficientApprovalAndBalanceRollbackBeforeAnyReceipt() (gas: 3422008)\n[PASS] test_intakeRevertPartialPullZeroIdAndClearFailureRollbackAllEffects() (gas: 7546650)\n[PASS] test_malformedResultIsRecordedWithoutParsingThenBadBindingPreservesIt() (gas: 2627685)\n[PASS] test_maximumCallbackURIWithinStipendAndOversizeFailureStaysPending() (gas: 6464950)\n[PASS] test_missingCallbackHasNoTimeoutButAuthenticLateCallbackStillWorks() (gas: 3243746)\n[PASS] test_reentrancyAtTransferApprovalAndIntakeCannotProposeOrBuyAgain() (gas: 8173450)\n[PASS] test_refusalCannotSubstituteProposalAndRetryRacesCostOnlyWinner() (gas: 6148654)\n[PASS] test_reusedIntakeRequestIdOnRetryCannotOverwriteAttemptOrDoubleCharge() (gas: 4520920)\n[PASS] test_spoofForeignCrossBranchAndReplayCallbacksCannotSettleOwnRequest() (gas: 6157705)\n[PASS] test_synchronousIntakeResultAndFailureCannotSettlePurchasingState() (gas: 3974215)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 1.50s (2.92s CPU time)\n\nRan 13 tests for test/RelayPayments.t.sol:RelayPaymentsTest\n[PASS] testFuzz_exactDynamicFeeConservesBalances(uint96) (runs: 1000, μ: 1982247, ~: 1982219)\n[PASS] testFuzz_nonRefusalFailureAlwaysFreezes(uint8) (runs: 1000, μ: 2139701, ~: 2139702)\n[PASS] test_callbacksAuthenticateSenderOwnRequestAndSingleDelivery() (gas: 2246344)\n[PASS] test_creationAndProposalsDoNotPurchaseOrMoveAnchor() (gas: 3734583)\n[PASS] test_dynamicFeeBranchPayerExactBodyAndSelectors() (gas: 2448757)\n[PASS] test_feeOnTransferSenderTaxFalseAndPartialPullRevertAtomically() (gas: 3574569)\n[PASS] test_foreignIntakeRequestCannotSettleBranch() (gas: 2265742)\n[PASS] test_missingCallbackStaysPendingIndefinitely() (gas: 2053533)\n[PASS] test_noReturnTokenAndStickyAllowanceCleared() (gas: 1985124)\n[PASS] test_refusedOnlyExplicitIdenticalRetryWithNewReceipt() (gas: 5392803)\n[PASS] test_stipendCallbackOnlyRecordsAndBindingIsPermissionless() (gas: 3184322)\n[PASS] test_tokenReentrancyAndSynchronousCallbackAreRejected() (gas: 3334808)\n[PASS] test_zeroUnknownProposalFeeCapAndUnpricedRejectBeforeTransfer() (gas: 1591479)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 1.50s (2.42s CPU time)\n\nRan 14 tests for test/RelayProfiles.t.sol:RelayProfilesTest\n[PASS] test_capacityEndToEndSixteenAssetsThenUpdate() (gas: 69858353)\n[PASS] test_htmlImagesPerFileAggregateAndBase64OverheadBounds() (gas: 1247154)\n[PASS] test_imageReferencesAndMarkdownImageInputsDisabled() (gas: 3492942)\n[PASS] test_invalidTextAndCanonicalWitnessRejectBeforePayment() (gas: 300358)\n[PASS] test_jsonEscapingCannotInjectRuntimeFields() (gas: 1018961)\n[PASS] test_maximumCompleteBindingASCIIFitsGasBudget() (gas: 207086875)\n[PASS] test_maximumCompleteBindingEscapedUnicodeFitsGasBudget() (gas: 211097959)\n[PASS] test_maximumCompleteBindingWideObjectsFitsGasBudget() (gas: 213750368)\n[PASS] test_measureMaximumWitnessAndLargeManifestTogether() (gas: 17656959)\n[PASS] test_publishDisabledAndOutputMappingFixedBeforePayment() (gas: 321649)\n[PASS] test_requestBodyUTF8ByteLimitCheckedBeforePayment() (gas: 6219758)\n[PASS] test_reserveEachEnabledTypeAndExistingSlotsUpdatableAtCapacity() (gas: 3439074)\n[PASS] test_selectedInputsMustBeCurrentSortedUniqueAndWithinEight() (gas: 10490345)\n[PASS] test_updateTargetMandatoryCreateCannotOverwriteAndRenameDisabled() (gas: 3891990)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 1.55s (4.15s CPU time)\n\nRan 15 tests for test/StrictManifest.t.sol:StrictManifestTest\n[PASS] testFuzz_asciiJSONQuoteDecodeRoundTrip(bytes32,uint8) (runs: 1000, μ: 241701, ~: 120486)\n[PASS] testFuzz_decodedDuplicateKeyAlwaysRejected(uint8) (runs: 1000, μ: 77968, ~: 77955)\n[PASS] test_actualFileHashesAndManifestKeccakAreDistinct() (gas: 605327)\n[PASS] test_boundedLargeManifestMeasurement() (gas: 9013128)\n[PASS] test_onlyDeclaredFilesNotSourceOrGitMetadataSupplyAcceptedFile() (gas: 4713703)\n[PASS] test_parserBoundsManifestStringDepthMembersAndTokens() (gas: 2625047)\n[PASS] test_rejectDuplicateKeysIncludingDecodedEscapesAtEveryDepth() (gas: 6117912)\n[PASS] test_rejectEmptyAndMultipleFilesEvenIfOneMatches() (gas: 4412636)\n[PASS] test_rejectIncompleteWrongIdentityTypesAndWrongFileTypes() (gas: 14661257)\n[PASS] test_rejectInvalidUTF8UnicodeSurrogatesAndNoncharacters() (gas: 871737)\n[PASS] test_rejectPathsTraversalHiddenURLAbsoluteAndDecodedControl() (gas: 17798512)\n[PASS] test_rejectTrailingAndMalformedJSON() (gas: 1231652)\n[PASS] test_rejectZeroOversizedNonIntegerAndStringFileBytes() (gas: 16582336)\n[PASS] test_validUTF8EscapesAndSurrogatePairsDecodeExactly() (gas: 1752634)\n[PASS] test_whitespaceIsLegalButDigestIsOverExactRawBytes() (gas: 622173)\nSuite result: ok. 15 passed; 0 failed; 0 skipped; finished in 1.55s (3.40s CPU time)\n\nRan 1 test for test/RelayInvariant.t.sol:RelayInvariantTest\n[PASS] invariant_conservationAndPermanentHistory() (runs: 128, calls: 8192, reverts: 0)\n\n╭--------------+--------------+-------+---------+----------╮\n| Contract     | Selector     | Calls | Reverts | Discards |\n+==========================================================+\n| RelayHandler | bind         | 1359  | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| RelayHandler | fail         | 1381  | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| RelayHandler | propose      | 1358  | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| RelayHandler | recordResult | 1326  | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| RelayHandler | retry        | 1401  | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| RelayHandler | sponsor      | 1367  | 0       | 0        |\n╰--------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 5.02s (5.01s CPU time)\n\nRan 2 tests for test/adversarial/StateMachineSpec.t.sol:StateMachineSpecTest\n[PASS] invariant_modelFeesReceiptsAssetsAndPermanentCheckpoints() (runs: 256, calls: 24576, reverts: 0)\n\n╭------------------+-----------------+-------+---------+----------╮\n| Contract         | Selector        | Calls | Reverts | Discards |\n+=================================================================+\n| SpecStateHandler | advanceTime     | 2531  | 0       | 0        |\n|------------------+-----------------+-------+---------+----------|\n| SpecStateHandler | bind            | 2505  | 0       | 0        |\n|------------------+-----------------+-------+---------+----------|\n| SpecStateHandler | donate          | 2491  | 0       | 0        |\n|------------------+-----------------+-------+---------+----------|\n| SpecStateHandler | fail            | 2476  | 0       | 0        |\n|------------------+-----------------+-------+---------+----------|\n| SpecStateHandler | forkHistory     | 2431  | 0       | 0        |\n|------------------+-----------------+-------+---------+----------|\n| SpecStateHandler | hostileCallback | 2468  | 0       | 0        |\n|------------------+-----------------+-------+---------+----------|\n| SpecStateHandler | propose         | 2394  | 0       | 0        |\n|------------------+-----------------+-------+---------+----------|\n| SpecStateHandler | purchase        | 2472  | 0       | 0        |\n|------------------+-----------------+-------+---------+----------|\n| SpecStateHandler | recordResult    | 2395  | 0       | 0        |\n|------------------+-----------------+-------+---------+----------|\n| SpecStateHandler | retry           | 2413  | 0       | 0        |\n╰------------------+-----------------+-------+---------+----------╯\n\n[PASS] test_modelExercisesRefusalRetryChildContinuationAndHistoricalFork() (gas: 23379937)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 26.30s (26.30s CPU time)\n\nRan 11 test suites in 26.30s (42.80s CPU time): 91 tests passed, 0 failed, 0 skipped (91 total tests)\n","passed":true},{"durationMs":245,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"RelayBranch.bind(bytes,(bytes32,uint8,string,string,bytes32,string,uint32,bytes32,address,string,bytes32,uint64)[])\",\"RelayBranch.initialize(string,string,(address,uint64,bytes32),bytes32,(bytes32,uint8,string,string,bytes32,string,uint32,bytes32,address,string,bytes32,uint64)[])\",\"RelayBranch.onIntakeFailure(bytes32,uint8,bytes32,uint16,uint16,bytes)\",\"RelayBranch.onIntakeResult(bytes32,bytes32,string)\",\"RelayBranch.propose((bytes32,uint8,bytes32,bytes32[],string,string,string,bool),(bytes32,uint8,string,string,bytes32,string,uint32,bytes32,address,string,bytes32,uint64)[])\",\"RelayBranch.retry(uint256,(bytes32,uint8,string,string,bytes32,string,uint32,bytes32,address,string,bytes32,uint64)[])\",\"RelayBranch.sponsor(uint256,uint256,(bytes32,uint8,string,string,bytes32,string,uint32,bytes32,address,string,bytes32,uint64)[])\",\"RelayFactory.createProject(string)\",\"RelayFactory.fork(address,uint64,(bytes32,uint8,string,string,bytes32,string,uint32,bytes32,address,string,bytes32,uint64)[],string)\"],\"files\":{\".gitignore\":4,\"LICENSE\":21,\"README.md\":106,\"abi/IIntake.json\":82,\"abi/RelayBranch.json\":1463,\"abi/RelayEncoder.json\":353,\"abi/RelayFactory.json\":298,\"abi/RelayVerifier.json\":232,\"cli/relay.mjs\":79,\"config/release.json\":94,\"docs/LIMITS.md\":50,\"docs/OPERATIONS.md\":32,\"docs/REVIEW.md\":50,\"docs/agent/SDK-CLI-A1.md\":70,\"docs/agent/sdk-cli-checks.md\":79,\"evidence/README.md\":16,\"evidence/check-results.json\":32,\"evidence/combined-limits-initial-trace.txt\":90,\"evidence/forge-build.txt\":844,\"evidence/forge-fmt.txt\":0,\"evidence/forge-test.txt\":94,\"evidence/limits-initial-trace.txt\":1453,\"evidence/metrics.json\":64,\"evidence/node-test.txt\":86,\"evidence/wide-binding-trace.txt\":1400,\"foundry.toml\":16,\"package-lock.json\":127,\"package.json\":20,\"remappings.txt\":1,\"sdk/files.mjs\":162,\"sdk/index.mjs\":319,\"sdk/strict-json.mjs\":100,\"src/RelayBranch.sol\":314,\"src/RelayEncoder.sol\":183,\"src/RelayFactory.sol\":75,\"src/RelayTypes.sol\":78,\"src/RelayVerifier.sol\":64,\"src/interfaces/IIntake.sol\":20,\"src/libraries/Assets.sol\":91,\"src/libraries/Policy.sol\":50,\"src/libraries/StrictJSON.sol\":260,\"src/libraries/Text.sol\":175,\"test-sdk/files.test.mjs\":58,\"test-sdk/mock-rpc.mjs\":14,\"test-sdk/relay.test.mjs\":238,\"test/CrossLanguage.t.sol\":37,\"test/RelayHistory.t.sol\":229,\"test/RelayInvariant.t.sol\":151,\"test/RelayPayments.t.sol\":240,\"test/RelayProfiles.t.sol\":389,\"test/RelaySetup.sol\":137,\"test/StrictManifest.t.sol\":254,\"test/TestBase.sol\":100,\"test/adversarial/ContinuationSpec.t.sol\":336,\"test/adversarial/ManifestSpec.t.sol\":400,\"test/adversarial/PaymentSpec.t.sol\":376,\"test/adversarial/ProfileBoundarySpec.t.sol\":222,\"test/adversarial/README.md\":40,\"test/adversarial/SpecSupport.sol\":459,\"test/adversarial/StateMachineSpec.t.sol\":482,\"test/adversarial/check-inline-fixtures.py\":43,\"test/adversarial/evidence/fixture-check.txt\":14,\"test/adversarial/evidence/forge-build.txt\":836,\"test/adversarial/evidence/forge-test.txt\":169,\"test/fixtures/FixtureData.sol\":54,\"test/fixtures/SdkGolden.sol\":13,\"test/fixtures/document-updated.md\":5,\"test/fixtures/document-updated.md.result.json\":1,\"test/fixtures/document.md\":3,\"test/fixtures/document.md.result.json\":1,\"test/fixtures/html-1.html\":1,\"test/fixtures/html-1.html.result.json\":1,\"test/fixtures/html-3.html\":1,\"test/fixtures/html-3.html.result.json\":1,\"test/fixtures/image-2.png\":3,\"test/fixtures/image-2.png.result.json\":1,\"test/fixtures/sdk-golden.json\":20,\"test/mocks/MockIntake.sol\":101,\"test/mocks/MockToken.sol\":63,\"tools/export-abi.mjs\":7,\"tools/generate-fixtures.py\":27,\"tools/generate-sdk-fixtures.mjs\":26,\"tools/validate-live.mjs\":23,\"vendor/ethers/LICENSE.md\":21,\"vendor/ethers/PROVENANCE.md\":1,\"vendor/ethers/ethers.mjs\":26619,\"vendor/npm/PROVENANCE.json\":56,\"vendor/npm/adraffy-ens-normalize-1.11.1.tgz\":813,\"vendor/npm/aes-js-4.0.0-beta.5.tgz\":1433,\"vendor/npm/ethers-6.17.0.tgz\":10241,\"vendor/npm/noble-curves-1.2.0.tgz\":1096,\"vendor/npm/noble-hashes-1.3.2.tgz\":443,\"vendor/npm/tslib-2.7.0.tgz\":58,\"vendor/npm/types-node-22.7.5.tgz\":1658,\"vendor/npm/undici-types-6.19.8.tgz\":78,\"vendor/npm/ws-8.21.0.tgz\":142},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":true}","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"142c151faefc354301209d6b9dc5fb0dc1177994cdfca24aed7327ceee869d93","verifiedTreeHash":"db3683f6096285b248d378e5b3baca0d6ad13478","verifierVersion":"0.1.0+6a374fcd"},{"checks":[],"detail":"paths and tree verified; no suite was run for this kind of work","evaluation":"structural","profile":"none","status":"accepted","submissionHash":"3276632c86cf8b2374b65c3a0fb74b26e5486c02f6e577e8dd3502c8f780fa7b","verifiedTreeHash":"3e8556eb68045051ac06fe5a008660f7a7241e40","verifierVersion":"0.1.0+6a374fcd"},{"checks":[{"durationMs":58226,"exitCode":0,"name":"build","output":"Compiling 31 files with Solc 0.8.26\nSolc 0.8.26 finished in 58.11s\nCompiler run successful with warnings:\nWarning (2519): This declaration shadows an existing declaration.\n   --> test/RelayProfiles.t.sol:324:13:\n    |\n324 |             bytes memory raw = _manifest(Text.hex32(keccak256(abi.encode(i))), Policy.kind(profile), 32);\n    |             ^^^^^^^^^^^^^^^^\nNote: The shadowed declaration is here:\n   --> test/RelayProfiles.t.sol:332:9:\n    |\n332 |         bytes memory raw = _manifest(Text.hex32(keccak256(\"new job\")), T.Kind.Markdown, 42);\n    |         ^^^^^^^^^^^^^^^^\n\n","passed":true},{"durationMs":5689,"exitCode":0,"name":"test","output":"No files changed, compilation skipped\n\nRan 2 tests for test/CrossLanguage.t.sol:CrossLanguageTest\n[PASS] test_sdkCalldataActuallyCreatesBranchWithoutPayment() (gas: 327533)\n[PASS] test_sdkCanonicalWitnessMatchesSolidity() (gas: 663085)\nSuite result: ok. 2 passed; 0 failed; 0 skipped; finished in 42.64ms (23.43ms CPU time)\n\nRan 15 tests for test/StrictManifest.t.sol:StrictManifestTest\n[PASS] testFuzz_asciiJSONQuoteDecodeRoundTrip(bytes32,uint8) (runs: 1000, μ: 248921, ~: 123382)\n[PASS] testFuzz_decodedDuplicateKeyAlwaysRejected(uint8) (runs: 1000, μ: 77967, ~: 77955)\n[PASS] test_actualFileHashesAndManifestKeccakAreDistinct() (gas: 605327)\n[PASS] test_boundedLargeManifestMeasurement() (gas: 9013128)\n[PASS] test_onlyDeclaredFilesNotSourceOrGitMetadataSupplyAcceptedFile() (gas: 4713703)\n[PASS] test_parserBoundsManifestStringDepthMembersAndTokens() (gas: 2625047)\n[PASS] test_rejectDuplicateKeysIncludingDecodedEscapesAtEveryDepth() (gas: 6117912)\n[PASS] test_rejectEmptyAndMultipleFilesEvenIfOneMatches() (gas: 4412636)\n[PASS] test_rejectIncompleteWrongIdentityTypesAndWrongFileTypes() (gas: 14661257)\n[PASS] test_rejectInvalidUTF8UnicodeSurrogatesAndNoncharacters() (gas: 871737)\n[PASS] test_rejectPathsTraversalHiddenURLAbsoluteAndDecodedControl() (gas: 17798512)\n[PASS] test_rejectTrailingAndMalformedJSON() (gas: 1231652)\n[PASS] test_rejectZeroOversizedNonIntegerAndStringFileBytes() (gas: 16582336)\n[PASS] test_validUTF8EscapesAndSurrogatePairsDecodeExactly() (gas: 1752634)\n[PASS] test_whitespaceIsLegalButDigestIsOverExactRawBytes() (gas: 622173)\nSuite result: ok. 15 passed; 0 failed; 0 skipped; finished in 559.41ms (1.49s CPU time)\n\nRan 14 tests for test/RelayProfiles.t.sol:RelayProfilesTest\n[PASS] test_capacityEndToEndSixteenAssetsThenUpdate() (gas: 69858353)\n[PASS] test_htmlImagesPerFileAggregateAndBase64OverheadBounds() (gas: 1247154)\n[PASS] test_imageReferencesAndMarkdownImageInputsDisabled() (gas: 3492942)\n[PASS] test_invalidTextAndCanonicalWitnessRejectBeforePayment() (gas: 300358)\n[PASS] test_jsonEscapingCannotInjectRuntimeFields() (gas: 1018961)\n[PASS] test_maximumCompleteBindingASCIIFitsGasBudget() (gas: 207086875)\n[PASS] test_maximumCompleteBindingEscapedUnicodeFitsGasBudget() (gas: 211097959)\n[PASS] test_maximumCompleteBindingWideObjectsFitsGasBudget() (gas: 213750368)\n[PASS] test_measureMaximumWitnessAndLargeManifestTogether() (gas: 17656959)\n[PASS] test_publishDisabledAndOutputMappingFixedBeforePayment() (gas: 321649)\n[PASS] test_requestBodyUTF8ByteLimitCheckedBeforePayment() (gas: 6219758)\n[PASS] test_reserveEachEnabledTypeAndExistingSlotsUpdatableAtCapacity() (gas: 3439074)\n[PASS] test_selectedInputsMustBeCurrentSortedUniqueAndWithinEight() (gas: 10490345)\n[PASS] test_updateTargetMandatoryCreateCannotOverwriteAndRenameDisabled() (gas: 3891990)\nSuite result: ok. 14 passed; 0 failed; 0 skipped; finished in 842.83ms (2.53s CPU time)\n\nRan 9 tests for test/RelayHistory.t.sol:RelayHistoryTest\n[PASS] test_badBindingPreservesResultThenCorrectWitnessWorksWithoutPurchase() (gas: 6972999)\n[PASS] test_childCannotBindParentsProjectAsOwn() (gas: 7051933)\n[PASS] test_forkCannotAuthenticateFakeParentLatestWitnessOrForgedProvenance() (gas: 7001657)\n[PASS] test_forkChosenHistoricalCheckpointStartsOwnProjectAndPayer() (gas: 15984077)\n[PASS] test_forkIsAllowedWhileParentPendingOrFrozen() (gas: 6727514)\n[PASS] test_htmlImageHtmlLatestJobAndOlderSelectedInputs() (gas: 27253583)\n[PASS] test_projectMismatchCannotOverwriteCheckpoint() (gas: 7446871)\n[PASS] test_reinitializeAndImplementationInitializationCannotChangeAuthority() (gas: 219434)\n[PASS] test_reusedJobCannotCreateNewRevision() (gas: 6531511)\nSuite result: ok. 9 passed; 0 failed; 0 skipped; finished in 842.82ms (519.79ms CPU time)\n\nRan 13 tests for test/RelayPayments.t.sol:RelayPaymentsTest\n[PASS] testFuzz_exactDynamicFeeConservesBalances(uint96) (runs: 1000, μ: 1982247, ~: 1982219)\n[PASS] testFuzz_nonRefusalFailureAlwaysFreezes(uint8) (runs: 1000, μ: 2139701, ~: 2139702)\n[PASS] test_callbacksAuthenticateSenderOwnRequestAndSingleDelivery() (gas: 2246344)\n[PASS] test_creationAndProposalsDoNotPurchaseOrMoveAnchor() (gas: 3734583)\n[PASS] test_dynamicFeeBranchPayerExactBodyAndSelectors() (gas: 2448757)\n[PASS] test_feeOnTransferSenderTaxFalseAndPartialPullRevertAtomically() (gas: 3574569)\n[PASS] test_foreignIntakeRequestCannotSettleBranch() (gas: 2265742)\n[PASS] test_missingCallbackStaysPendingIndefinitely() (gas: 2053533)\n[PASS] test_noReturnTokenAndStickyAllowanceCleared() (gas: 1985124)\n[PASS] test_refusedOnlyExplicitIdenticalRetryWithNewReceipt() (gas: 5392803)\n[PASS] test_stipendCallbackOnlyRecordsAndBindingIsPermissionless() (gas: 3184322)\n[PASS] test_tokenReentrancyAndSynchronousCallbackAreRejected() (gas: 3334808)\n[PASS] test_zeroUnknownProposalFeeCapAndUnpricedRejectBeforeTransfer() (gas: 1591479)\nSuite result: ok. 13 passed; 0 failed; 0 skipped; finished in 843.22ms (1.61s CPU time)\n\nRan 1 test for test/RelayInvariant.t.sol:RelayInvariantTest\n[PASS] invariant_conservationAndPermanentHistory() (runs: 128, calls: 8192, reverts: 0)\n\n╭--------------+--------------+-------+---------+----------╮\n| Contract     | Selector     | Calls | Reverts | Discards |\n+==========================================================+\n| RelayHandler | bind         | 1359  | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| RelayHandler | fail         | 1381  | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| RelayHandler | propose      | 1358  | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| RelayHandler | recordResult | 1326  | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| RelayHandler | retry        | 1401  | 0       | 0        |\n|--------------+--------------+-------+---------+----------|\n| RelayHandler | sponsor      | 1367  | 0       | 0        |\n╰--------------+--------------+-------+---------+----------╯\n\nSuite result: ok. 1 passed; 0 failed; 0 skipped; finished in 5.55s (5.54s CPU time)\n\nRan 6 test suites in 5.55s (8.68s CPU time): 54 tests passed, 0 failed, 0 skipped (54 total tests)\n","passed":true},{"durationMs":269,"exitCode":0,"name":"source-index","output":"{\"v\":1,\"entryPoints\":[\"RelayBranch.bind(bytes,(bytes32,uint8,string,string,bytes32,string,uint32,bytes32,address,string,bytes32,uint64)[])\",\"RelayBranch.initialize(string,string,(address,uint64,bytes32),bytes32,(bytes32,uint8,string,string,bytes32,string,uint32,bytes32,address,string,bytes32,uint64)[])\",\"RelayBranch.onIntakeFailure(bytes32,uint8,bytes32,uint16,uint16,bytes)\",\"RelayBranch.onIntakeResult(bytes32,bytes32,string)\",\"RelayBranch.propose((bytes32,uint8,bytes32,bytes32[],string,string,string,bool),(bytes32,uint8,string,string,bytes32,string,uint32,bytes32,address,string,bytes32,uint64)[])\",\"RelayBranch.retry(uint256,(bytes32,uint8,string,string,bytes32,string,uint32,bytes32,address,string,bytes32,uint64)[])\",\"RelayBranch.sponsor(uint256,uint256,(bytes32,uint8,string,string,bytes32,string,uint32,bytes32,address,string,bytes32,uint64)[])\",\"RelayFactory.createProject(string)\",\"RelayFactory.fork(address,uint64,(bytes32,uint8,string,string,bytes32,string,uint32,bytes32,address,string,bytes32,uint64)[],string)\"],\"files\":{\".gitignore\":4,\"LICENSE\":21,\"README.md\":106,\"abi/IIntake.json\":82,\"abi/RelayBranch.json\":1463,\"abi/RelayEncoder.json\":353,\"abi/RelayFactory.json\":298,\"abi/RelayVerifier.json\":232,\"cli/relay.mjs\":55,\"config/release.json\":94,\"docs/LIMITS.md\":50,\"docs/OPERATIONS.md\":32,\"docs/REVIEW.md\":50,\"evidence/README.md\":16,\"evidence/check-results.json\":32,\"evidence/combined-limits-initial-trace.txt\":90,\"evidence/forge-build.txt\":844,\"evidence/forge-fmt.txt\":0,\"evidence/forge-test.txt\":94,\"evidence/limits-initial-trace.txt\":1453,\"evidence/metrics.json\":64,\"evidence/node-test.txt\":86,\"evidence/wide-binding-trace.txt\":1400,\"foundry.toml\":16,\"package-lock.json\":127,\"package.json\":20,\"remappings.txt\":1,\"sdk/files.mjs\":48,\"sdk/index.mjs\":220,\"sdk/strict-json.mjs\":100,\"src/RelayBranch.sol\":314,\"src/RelayEncoder.sol\":183,\"src/RelayFactory.sol\":75,\"src/RelayTypes.sol\":78,\"src/RelayVerifier.sol\":64,\"src/interfaces/IIntake.sol\":20,\"src/libraries/Assets.sol\":91,\"src/libraries/Policy.sol\":50,\"src/libraries/StrictJSON.sol\":260,\"src/libraries/Text.sol\":175,\"test-sdk/files.test.mjs\":41,\"test-sdk/relay.test.mjs\":175,\"test/CrossLanguage.t.sol\":37,\"test/RelayHistory.t.sol\":229,\"test/RelayInvariant.t.sol\":151,\"test/RelayPayments.t.sol\":240,\"test/RelayProfiles.t.sol\":389,\"test/RelaySetup.sol\":137,\"test/StrictManifest.t.sol\":254,\"test/TestBase.sol\":100,\"test/fixtures/FixtureData.sol\":54,\"test/fixtures/SdkGolden.sol\":13,\"test/fixtures/document-updated.md\":5,\"test/fixtures/document-updated.md.result.json\":1,\"test/fixtures/document.md\":3,\"test/fixtures/document.md.result.json\":1,\"test/fixtures/html-1.html\":1,\"test/fixtures/html-1.html.result.json\":1,\"test/fixtures/html-3.html\":1,\"test/fixtures/html-3.html.result.json\":1,\"test/fixtures/image-2.png\":3,\"test/fixtures/image-2.png.result.json\":1,\"test/fixtures/sdk-golden.json\":20,\"test/mocks/MockIntake.sol\":101,\"test/mocks/MockToken.sol\":63,\"tools/export-abi.mjs\":7,\"tools/generate-fixtures.py\":27,\"tools/generate-sdk-fixtures.mjs\":26,\"tools/validate-live.mjs\":23,\"vendor/ethers/LICENSE.md\":21,\"vendor/ethers/PROVENANCE.md\":1,\"vendor/ethers/ethers.mjs\":26619,\"vendor/npm/PROVENANCE.json\":56,\"vendor/npm/adraffy-ens-normalize-1.11.1.tgz\":813,\"vendor/npm/aes-js-4.0.0-beta.5.tgz\":1433,\"vendor/npm/ethers-6.17.0.tgz\":10241,\"vendor/npm/noble-curves-1.2.0.tgz\":1096,\"vendor/npm/noble-hashes-1.3.2.tgz\":443,\"vendor/npm/tslib-2.7.0.tgz\":58,\"vendor/npm/types-node-22.7.5.tgz\":1658,\"vendor/npm/undici-types-6.19.8.tgz\":78,\"vendor/npm/ws-8.21.0.tgz\":142},\"excluded\":[\"lib/\",\"node_modules/\"],\"truncated\":true}","passed":true},{"durationMs":19191,"exitCode":0,"name":"slither","output":"[high/medium] reentrancy-balance at src/RelayBranch.sol:184: Reentrancy in RelayBranch._purchase(uint256,bytes32,bytes,uint256) (src/RelayBranch.sol#184-223):\n[medium/medium] divide-before-multiply at src/RelayEncoder.sol:79: RelayEncoder._validate(RelayTypes.Proposal,RelayTypes.Asset[]) (src/RelayEncoder.sol#79-136) performs a multiplication on the result of a division:\n[medium/medium] uninitialized-local at src/libraries/Assets.sol:79: Assets.replace(RelayTypes.Asset[],RelayTypes.Asset).j (src/libraries/Assets.sol#79) is a local variable never initialized\n[medium/medium] uninitialized-local at src/libraries/StrictJSON.sol:109: StrictJSON._object(StrictJSON.Parser,uint256).keys (src/libraries/StrictJSON.sol#109) is a local variable never initialized\n[medium/medium] uninitialized-local at src/libraries/Assets.sol:11: Assets.validate(RelayTypes.Asset[]).last (src/libraries/Assets.sol#11) is a local variable never initialized\n[medium/medium] uninitialized-local at src/RelayEncoder.sol:112: RelayEncoder._validate(RelayTypes.Proposal,RelayTypes.Asset[]).last (src/RelayEncoder.sol#112) is a local variable never initialized\n[medium/medium] uninitialized-local at src/libraries/Assets.sol:80: Assets.replace(RelayTypes.Asset[],RelayTypes.Asset).inserted (src/libraries/Assets.sol#80) is a local variable never initialized\n[medium/medium] uninitialized-local at src/RelayEncoder.sol:114: RelayEncoder._validate(RelayTypes.Proposal,RelayTypes.Asset[]).htmlBytes (src/RelayEncoder.sol#114) is a local variable never initialized\n[medium/medium] uninitialized-local at src/libraries/Text.sol:145: Text.unhex32(string).v (src/libraries/Text.sol#145) is a local variable never initialized\n[medium/medium] uninitialized-local at src/RelayEncoder.sol:111: RelayEncoder._validate(RelayTypes.Proposal,RelayTypes.Asset[]).selectedTarget (src/RelayEncoder.sol#111) is a local variable never initialized\n[medium/medium] uninitialized-local at src/RelayVerifier.sol:35: RelayVerifier.verify(bytes,bytes32,RelayTypes.Proposal,RelayTypes.Asset[],address,uint64).a (src/RelayVerifier.sol#35) is a local variable never initialized\n[medium/medium] uninitialized-local at src/RelayEncoder.sol:115: RelayEncoder._validate(RelayTypes.Proposal,RelayTypes.Asset[]).embeddedBytes (src/RelayEncoder.sol#115) is a local variable never initialized\n[medium/medium] uninitialized-local at src/libraries/Assets.sol:22: Assets.validate(RelayTypes.Asset[]).missing (src/libraries/Assets.sol#22) is a local variable never initialized\n[medium/medium] uninitialized-local at src/libraries/Text.sol:19: Text.utf8(bytes).n (src/libraries/Text.sol#19) is a local variable never initialized\n[medium/medium] uninitialized-local at src/RelayEncoder.sol:113: RelayEncoder._validate(RelayTypes.Proposal,RelayTypes.Asset[]).imageBytes (src/RelayEncoder.sol#113) is a local variable never initialized\n[medium/medium] uninitialized-local at src/libraries/Text.sol:20: Text.utf8(bytes).minimum (src/libraries/Text.sol#20) is a local variable never initialized\n[medium/medium] uninitialized-local at src/libraries/Assets.sol:12: Assets.validate(RelayTypes.Asset[]).kinds (src/libraries/Assets.sol#12) is a local variable never initialized\n[medium/medium] uninitialized-local at src/RelayEncoder.sol:104: RelayEncoder._validate(RelayTypes.Proposal,RelayTypes.Asset[]).missing (src/RelayEncoder.sol#104) is a local variable never initialized\n[medium/medium] uninitialized-local at src/libraries/Text.sol:142: Text.unhex32(string).offset (src/libraries/Text.sol#142) is a local variable never initialized\n[medium/medium] unused-return at src/RelayBranch.sol:137: RelayBranch.propose(RelayTypes.Proposal,RelayTypes.Asset[]) (src/RelayBranch.sol#137-149) ignores return value by (None,body) = encoder.encode(goal,direction,latestJobId,p,current) (src/RelayBranch.sol#144)\n[low/medium] reentrancy-benign at src/RelayBranch.sol:184: Reentrancy in RelayBranch._purchase(uint256,bytes32,bytes,uint256) (src/RelayBranch.sol#184-223):\n[low/medium] reentrancy-benign at src/RelayFactory.sol:62: Reentrancy in RelayFactory._create(string,string,RelayTypes.Source,bytes32,RelayTypes.Asset[]) (src/RelayFactory.sol#62-74):\n[low/medium] reentrancy-events at src/RelayFactory.sol:62: Reentrancy in RelayFactory._create(string,string,RelayTypes.Source,bytes32,RelayTypes.Asset[]) (src/RelayFactory.sol#62-74):\n[low/medium] reentrancy-events at src/RelayBranch.sol:184: Reentrancy in RelayBranch._purchase(uint256,bytes32,bytes,uint256) (src/RelayBranch.sol#184-223):","passed":true},{"durationMs":917,"exitCode":0,"name":"aderyn","output":"[high] reentrancy-state-change at src/RelayBranch.sol:94: Reentrancy: State change after external call (3 places)\n[low] internal-function-used-once at src/libraries/Assets.sol:30: Internal Function Used Only Once (5 places)\n[low] literal-instead-of-constant at src/RelayEncoder.sol:39: Literal Instead of Constant (76 places)\n[low] require-revert-in-loop at src/RelayEncoder.sol:116: Loop Contains `require`/`revert` (16 places)\n[low] unchecked-return at src/libraries/StrictJSON.sol:40: Unchecked Return (4 places)\n[low] uninitialized-local-variable at src/RelayEncoder.sol:62: Uninitialized Local Variable (22 places)","passed":true}],"detail":"all checks passed","evaluation":"checks","profile":"foundry","status":"accepted","submissionHash":"427de9220e879fa0a3d23135283d4ce9484b36805d79398ffdf3575f96e26606","verifiedTreeHash":"8d09f1e96856b6669f7f77072247086c9801793e","verifierVersion":"0.1.0+6a374fcd"},{"checks":[],"detail":"paths and tree verified; no suite was run for this kind of work","evaluation":"structural","profile":"none","status":"accepted","submissionHash":"acac92ddca40904b994a4511a3414ad5727882d487b273d44d10e628c82c4e50","verifiedTreeHash":"c76ec6c4e0b9afae00482075bc964afff3491894","verifierVersion":"0.1.0+6a374fcd"},{"checks":[],"detail":"paths and tree verified; no suite was run for this kind of work","evaluation":"structural","profile":"none","status":"accepted","submissionHash":"b73e40ce6daa7427bddd6788609d489229cf709c4a183a6d5d2729a87aef5716","verifiedTreeHash":"5b60530aee3e82f65563934ff2e03b783670fa2a","verifierVersion":"0.1.0+6a374fcd"}]}