Repository navigation
Bytecode carries the fetch body (fixes #143) - #145
Conversation
howlcipher
left a comment
There was a problem hiding this comment.
Verdict: merge-ready (COMMENT-only; APPROVE is unavailable for this account). Reviewed head 2c96eaa9522421b56549c6261e58685fb1ebcb5c against base be5fc0e2 in one fresh local checkout.
1. Flip lock scoped to fetch_body. In prod_flip_criteria_test.go the only change is inside t.Run("fetch body") (18 +/- lines). The old checks were "has FETCH" and "body string absent". The new ones are "has HTTP_REQUEST", "no body-less FETCH" and "body string present", all on both the HFIR-lowered and AST programs. The opcode allow-list, the OpFetch registry pin, the transport subtests, try/match control edges, html/attr_escape, regex, time_now and sleep are all untouched. No CLI or default files changed, so there's no prod -compile-bc/HFIR default flip and #90 stays Partial. All 25 TestProdFlipCriteriaLock subtests pass.
2. No new opcode, capability or grant. FetchWithBody emits the existing CONVERT, HTTP_REQUEST 1, LOAD_CONST and MAP_GET. The HTTP_REQUEST registry entry stays Capability: network, and the hfir unit test now asserts that. The VM gates it at runtime the same way as FETCH (the effect-gate conformance already covers OpHttpRequest), and the receipt already handles HTTP_REQUEST IntOperand==1. The profile scan is AST/HFIR-level on the fetch node and is unchanged. TestOpcodeCapabilityDrift passes.
3. TestIssue143FetchBodyEveryPath runs the real binary on three paths: -run (interpreter), build + -run-bc (AST bytecode), and -compile-hfir-bc + -run-bc (HFIR). It runs them against an httptest server that records method and body. It asserts the exact requests POST hello | PUT 42 | GET and the echoed stdout on each path, and with no network grant it asserts that both bytecode paths send zero requests. Passes.
4. Updated tests are justified. The hfir operand test now pins the exact 7-instruction sequence and its operands, so it is stricter than before. In nested_multi_effect, the body fetch sits in a while false branch, so it is now compiled but never runs. The rename to phase2d-dead-branch-body is just the old marker made accurate, and the conformance test still asserts bodies == 0 and no leak of the marker. TestHFIRBytecodeFetchOperandOrder now expects the PUT body to arrive and checks that AST and HFIR emit the same shapes. These tests were changed to reflect the new behaviour, not loosened.
5. Caveats, neither blocking.
- A failed fetch with a body reports
http_request failed. Reproduced: with a body you getIO_ERROR … opcode HTTP_REQUEST, "http_request failed: …"; without one you getopcode FETCH "fetch failed". The interpreter saysfetch failedin both cases. The error code is the same, so this is cosmetic. Could be a follow-up. - List/dict body formatting. I probed this against a local server on all three paths with
(list 1 2 3),(list "a" "b"),(dict ("k" 1) ("z" 2)),trueand1.5. The bodies received were byte-identical on every path:[1 2 3],[a b],map[k:1 z:2],true,1.5. For these types the difference doesn't happen. Bytes and nested values weren't probed. Optionally, add a list/dict case to the new test to lock this in.
6. #142 arity/drift tests: TestIssue141EveryArityEntry, TestIssue141MotokoArityRepros (29 cases), TestIssue141ArityFuzzNoPanic, TestIssue139FetchArityFailsClosed, TestArityTableCoversRegistry, TestArityMessages, TestArityAcceptsWellFormed, TestOpcodeCapabilityDrift, TestCompareToCanonicalDetectsDrift, the call-arity tests and TestLoweredHFIRABIConformance all pass (exit 0).
7. Build: CI build passes on this head. gofmt -l is empty. Full go test ./... exits 0, and that includes apps/task_api (2.7s) and apps/status_api (2.5s). They didn't flake this run, so no isolated rerun was needed.
8. Hard nos intact: nothing under the 4d74dbcf tip-lock evidence is touched, there's no live LLM and no H1 PASS/KILL claim, and no UI/DOM changes.
Nits (non-blocking):
- The denied-network check in the new test covers only the two bytecode paths. An interpreter denial assert would make it symmetric.
- Consider making the HTTP_REQUEST-with-body error say
fetch failedfor parity.
Fixes #143
This changes the flip criteria, with the Owner's approval. William Elias signed off:
TestProdFlipCriteriaLock/fetch_bodyand thenested_multi_effect_*conformance cases now lock in "the bytecode fetch body is sent" in place of "the body is skipped".What changed
-compile-hfir-bc+-run-bc) now carry the fetch body. The interpreter already did.(fetch url method body)through the shared helperbytecode.FetchWithBodyto: url, method, body,CONVERT to_string,HTTP_REQUEST 1,LOAD_CONST "body",MAP_GET.network), no artifact-format change.TestProdFlipCriteriaLock/fetch_bodynow requires HTTP_REQUEST, no body-less FETCH, and the body kept.TestLowerToBytecodeFetchSendsBodyOperand, which pins the exact instruction sequence.TestHFIRBytecodeFetchOperandOrdernow expects the PUT body to be received.nested_multi_effect_*: the only body fetch is in a deadwhile falsebranch.phase2d-dead-branch-body.TestIssue143FetchBodyEveryPathuses a local httptest server only (no external network).Journal:
docs/journals/2026-10-12_issue143_fetch_body.mdCaveats
http_request failed(opcode HTTP_REQUEST) instead offetch failed. The error codes are the same.fmt.Sprint. Lists, dicts and bytes may format differently.-compile-bc/HFIR flip. Write flagged http_server bytecode and stop #90 stays Partial.experiments/token-efficiency-heldout-v2is untouched.Verification
gofmt -lis empty.go build ./...andgo vet ./...pass.go test ./...: one unrelated failure,apps/task_api. A connection reset on localhost:8091 was followed by a 10-minute timeout. No other test uses that port and the app has no fetch. The package passes when rerun on its own.go test ./experiments/...passes.run.shpass: v0 60/60 ×4, heldout-v0 howl 30/30 and others 32/32, heldout-v1 34/34 ×4.