You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
id(world): records.read cap pages can exceed the result_event size cap — admitted 768 KiB pages are replaced by result_too_large above 64 KiB #4888
Finding (from PR #4856 CodeRabbit review, dispositioned by task 4880)
records.read pages are admitted up to MAX_RECORDS_PAGE_BYTES (768 KiB), but cap results are delivered through result_event (pkgs/id/crates/id-core/src/world_caps.rs), which replaces any serialized result event larger than MAX_EVENT_BYTES (64 KiB) with a result_too_large error. A records page between 64 KiB and 768 KiB therefore passes the page check in execute_records_read (pkgs/id/src/world/actor.rs) yet can never reach the program as records.
Evidence
pkgs/id/crates/id-core/src/world_caps.rs: MAX_EVENT_BYTES = 64 * 1024; result_event returns the result_too_large error above that size; RECORDS_READ_BOUNDS (added by PR refactor(id): add static provider registry (slice 1 of #1061) #4856) reports ProviderBound::ResponseBytes(MAX_RECORDS_PAGE_BYTES).
pkgs/id/src/world/actor.rs: execute_records_read admits records until used + size > MAX_RECORDS_PAGE_BYTES (768 KiB).
Note MAX_RECORDS_PAGE_BYTES also bounds the session-protocol page path (pkgs/id/src/world_session/mod.rs), which is a different consumer from cap result events — the fix must distinguish the two budgets, not blindly shrink the shared constant.
PR #4856 (issue #1061 slice 1) is a no-behavior-change registry refactor; bounding the records page changes runtime behavior and belongs in its own change with its own tests.
Acceptance
A records.read cap result can never be admitted at a size result_event will refuse: derive the cap-result page bound from the event limit minus the result envelope, or route the result so the admitted page is deliverable.
RECORDS_READ_BOUNDS reports the bound that actually applies to cap results.
Regression test: a records page near the bound is delivered as records (not replaced by result_too_large), and the session-protocol page budget is unchanged.
agent-note:v1
state: reviewed (coverage loop-back)
Coverage pass 2026-11-03, loop-back review: this issue was re-reviewed (drift / overlap / already-handled / stale / blockers / ordering) so every open issue in the four repos is reviewed and in the system. Verdict: still live; in the system as task 7935 (triage, queued, priority 30) in repo-health-code-pilot. Labels audited and synced. If it is already handled at current main, its triage closes it with evidence; if oversized, the triage files the split; blockers belong on this issue.
Found via: coverage loop-back 2026-11-03
agent-note:v1 — task 7935 picked up by lane code-k (repo-worker-code). Execution lane assigned: opencode — handed off to the opencode claimant, which will launch a bound session to triage issue #4888 at current main.
Links: follow-up task 8079 (small_fix) in repo-health-code-pilot
Verdict: CONFIRMED at main 67f97516c (checked 2026-11-03T14:37Z)
The defect is unchanged since PR #4856 merged (a39baa65, 2026-11-03T12:40Z). No open PR or branch owns this fix; no held/Drew-owned artifact is involved.
Evidence
pkgs/id/src/world/actor.rs:822 — execute_records_read admits records until used + size > MAX_RECORDS_PAGE_BYTES.
pkgs/id/src/world/actor.rs:604 — every cap result is delivered through world_caps::result_event.
pkgs/id/crates/id-core/src/world_caps.rs:71,746-762 — MAX_EVENT_BYTES = 64 * 1024; result_event replaces any serialized event larger than that with result_too_large.
pkgs/id/crates/id-core/src/world_caps.rs:288-291 — RECORDS_READ_BOUNDS advertises ProviderBound::ResponseBytes(MAX_RECORDS_PAGE_BYTES), i.e. 768 KiB, the bound the cap path cannot deliver.
So a records.read page whose records total anywhere from 64 KiB to 768 KiB passes the page check and is then replaced wholesale by result_too_large: the program can never read a page in that band, and the manifest advertises a bound that is not honored.
One extra wrinkle for the fix
execute_records_read estimates each record as key.len() + serde_json::to_vec(value).len() + 8 (actor.rs:821), but the serialized item is {"key":"…","value":…} — about 20 bytes plus a separator, and key escaping can grow it further. With many small records the estimate can undercount by tens of KiB, so shrinking the constant to MAX_EVENT_BYTES minus the envelope is not by itself sufficient. The fix should count the exact serialized item bytes (or reserve explicit headroom) and keep the existing fail-closed bad_args behavior for a single record that cannot fit.
Fix path (scoped, no blockers)
Add a cap-result page budget derived from MAX_EVENT_BYTES minus the result_event envelope (id ≤ MAX_NAME_BYTES), e.g. a named constant in world_caps.rs next to MAX_RECORDS_PAGE_BYTES.
Enforce it in actor.rs:execute_records_read and report it from RECORDS_READ_BOUNDS so the manifest and the code agree.
Do not shrink MAX_RECORDS_PAGE_BYTES: the session protocol (pkgs/id/src/world_session/mod.rs:1762, used at :1792, :1873) and the web records feed (pkgs/id/src/web/world_ws.rs:168) are different consumers and must keep the 768 KiB page budget; the existing session-protocol test at world_session/tests.rs:1435 should keep passing.
Regression tests: a page just under the new bound is delivered as records through after_change() (not result_too_large); a page over the bound paginates via next_after without truncation; RECORDS_READ_BOUNDS reports the enforced bound; the shared 768 KiB budget is asserted unchanged.
Ordering / blockers
None. The change is independent, touches one subsystem, and needs no decision or access beyond this repo. Follow-up task 8079 is queued at priority 40 with the scope, tests, and acceptance above.
Agent: queue worker (repo-worker-code), lane code-c shift
Session / ID: task 8079
Found via: queue claim · resume from reproduced checkpoint (branch queue/8079-4888-records-read-cap, laptop worktree ~/git/fleet/8079-4888-records-read-cap)
Task: Implement the cap-result page bound for records.read: derive the page budget from MAX_EVENT_BYTES minus the result envelope in id-core world_caps, enforce it in actor execute_records_read with accurate serialized-size accounting, and make RECORDS_READ_BOUNDS report the enforced bound. The 768 KiB session-protocol/web page budget stays unchanged.
Expectation: effort s/m — one PR; done = regression tests pass (page just under bound delivered in full, over-bound page paginates via next_after, single over-bound record fails closed as bad_args), 768 KiB budget asserted unchanged.
Agent: queue worker (repo-worker-code), lane code-c shift
Session / ID: task 8079
Found via: queue claim · resumed at the reproduced checkpoint (implementation commit 0d22749 already on branch queue/8079-4888-records-read-cap)
Task: records.read cap pages are now bounded by MAX_RECORDS_RESULT_PAGE_BYTES (MAX_EVENT_BYTES minus a 1024-byte result-event envelope allowance), entries are counted at true serialized size, and RECORDS_READ_BOUNDS reports the enforced bound; the 768 KiB session-protocol/web page budget is unchanged and test-asserted.
Activity
dezren39 commentedon Nov 3, 2026
agent-note:v1
state: reviewed (coverage loop-back)
Coverage pass 2026-11-03, loop-back review: this issue was re-reviewed (drift / overlap / already-handled / stale / blockers / ordering) so every open issue in the four repos is reviewed and in the system. Verdict: still live; in the system as task 7935 (triage, queued, priority 30) in repo-health-code-pilot. Labels audited and synced. If it is already handled at current main, its triage closes it with evidence; if oversized, the triage files the split; blockers belong on this issue.
Found via: coverage loop-back 2026-11-03
dezren39 commentedon Nov 3, 2026
agent-note:v1 — task 7935 picked up by lane code-k (repo-worker-code). Execution lane assigned: opencode — handed off to the opencode claimant, which will launch a bound session to triage issue #4888 at current main.
dezren39 commentedon Nov 3, 2026
🤖 Agent note · handed off
ses_e5e5e29789dffepOUt0k3wEhkorepo-worker-code(bound worker uses this id for all queue helper verbs)opencode-route/workhorse, agentbuilddezren39 commentedon Nov 3, 2026
🤖 Agent note · done (triaged: confirmed live on main)
ses_e5e5e29789dffepOUt0k3wEhkorepo-health-code-pilotVerdict: CONFIRMED at main
67f97516c(checked 2026-11-03T14:37Z)The defect is unchanged since PR #4856 merged (
a39baa65, 2026-11-03T12:40Z). No open PR or branch owns this fix; no held/Drew-owned artifact is involved.Evidence
pkgs/id/src/world/actor.rs:822—execute_records_readadmits records untilused + size > MAX_RECORDS_PAGE_BYTES.pkgs/id/crates/id-core/src/world_caps.rs:536—MAX_RECORDS_PAGE_BYTES = 768 * 1024.pkgs/id/src/world/actor.rs:604— every cap result is delivered throughworld_caps::result_event.pkgs/id/crates/id-core/src/world_caps.rs:71,746-762—MAX_EVENT_BYTES = 64 * 1024;result_eventreplaces any serialized event larger than that withresult_too_large.pkgs/id/crates/id-core/src/world_caps.rs:288-291—RECORDS_READ_BOUNDSadvertisesProviderBound::ResponseBytes(MAX_RECORDS_PAGE_BYTES), i.e. 768 KiB, the bound the cap path cannot deliver.So a
records.readpage whose records total anywhere from 64 KiB to 768 KiB passes the page check and is then replaced wholesale byresult_too_large: the program can never read a page in that band, and the manifest advertises a bound that is not honored.One extra wrinkle for the fix
execute_records_readestimates each record askey.len() + serde_json::to_vec(value).len() + 8(actor.rs:821), but the serialized item is{"key":"…","value":…}— about 20 bytes plus a separator, and key escaping can grow it further. With many small records the estimate can undercount by tens of KiB, so shrinking the constant toMAX_EVENT_BYTESminus the envelope is not by itself sufficient. The fix should count the exact serialized item bytes (or reserve explicit headroom) and keep the existing fail-closedbad_argsbehavior for a single record that cannot fit.Fix path (scoped, no blockers)
MAX_EVENT_BYTESminus theresult_eventenvelope (id ≤MAX_NAME_BYTES), e.g. a named constant inworld_caps.rsnext toMAX_RECORDS_PAGE_BYTES.actor.rs:execute_records_readand report it fromRECORDS_READ_BOUNDSso the manifest and the code agree.MAX_RECORDS_PAGE_BYTES: the session protocol (pkgs/id/src/world_session/mod.rs:1762, used at:1792,:1873) and the web records feed (pkgs/id/src/web/world_ws.rs:168) are different consumers and must keep the 768 KiB page budget; the existing session-protocol test atworld_session/tests.rs:1435should keep passing.after_change()(notresult_too_large); a page over the bound paginates vianext_afterwithout truncation;RECORDS_READ_BOUNDSreports the enforced bound; the shared 768 KiB budget is asserted unchanged.Ordering / blockers
None. The change is independent, touches one subsystem, and needs no decision or access beyond this repo. Follow-up task 8079 is queued at priority 40 with the scope, tests, and acceptance above.
2 remaining items
dezren39 commentedon Nov 3, 2026
🤖 Agent note · picked up
repo-worker-coderepo-health-code-pilottask 8079, issue id(world): records.read cap pages can exceed the result_event size cap — admitted 768 KiB pages are replaced by result_too_large above 64 KiB #4888c29174f1-48e0-4b13-b4ff-9b73ab67e9abopenchamber-scheduled-lane.dezren39 commentedon Nov 3, 2026
🤖 Agent note · picked up
reproducedcheckpoint (branch queue/8079-4888-records-read-cap, laptop worktree ~/git/fleet/8079-4888-records-read-cap)fix(id): bound records.read cap pages by the result-event limit (#4888)…
dezren39 commentedon Nov 3, 2026
🤖 Agent note · done
reproducedcheckpoint (implementation commit 0d22749 already on branch queue/8079-4888-records-read-cap)cargo test -p id-core world_caps7 passed,cargo test -p id records154 passed (main suite).