Repository navigation
Size the plan import request limit from the parser bound (#146) - #158
Merged
Merged
Conversation
POST /api/plan/import refused every body over 16 KiB, though the parser accepts a 1 MiB source and the v1 schema permits plans far larger than 16 KiB. The import body limit is now 6 x 1 MiB + 16 KiB: any JSON encoding writes each UTF-8 source byte as at most 6 bytes, so every source the parser accepts fits. Other POSTs keep 16 KiB. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
🔵 Needs a closer look
Exact-head full-suite and CI validation remain incomplete.
0 open findings
What changed in this PR
Aligns plan-import transport limits with the parser’s 1 MiB source bound.
Changes:
- Derives a 6 MiB + 16 KiB import limit from parser constraints.
- Adds boundary and route-isolation tests.
- Documents the endpoint limit.
| File | Description |
|---|---|
web/server.ts |
Applies the expanded limit only to plan imports. |
core/parse-v1.ts |
Exports the parser source-size bound. |
test/runner-planning-feedback.test.ts |
Tests valid, boundary, oversized, and unaffected routes. |
docs/plan-format.md |
Documents sizing and refusal behavior. |
docs/implementation/runner-lifecycle.md |
Updates the endpoint contract. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
mchwang
added a commit
that referenced
this pull request
Oct 10, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 10, 2026
mchwang
added a commit
that referenced
this pull request
Oct 10, 2026
* Close out Lane G status records (#145) Lane G (G1-G4) merged in PRs #148, #150, #151 and #152. The README and the design overview still described the Planning screen as unbuilt, and build step 6 said "no screen yet". Record the screen as built, mark build step 6 done, and record Lane G's release of the shared web files plus the remaining lane F follow-up (#146) in the planning-screen document. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Point lane status readers to the live table; name released files (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Clarify Lane G handoff and screen name (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Tighten Lane G handoff wording (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Mark lane G done in the Wave 2 table; state #146 ownership source (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Name the web files lane G released in the Wave 2 table (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Put the finished lane G row in the past tense (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Drop unneeded history from the lane G row (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Match the H row layout; cite where #146 is assigned to lane F (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * README: planning agent needs a github review, not the demo (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Clarify met G4 condition and demo limits (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Put wave 2 ownership rules in the past tense (#145) Copilot round 1 found that the Wave 2 note and integration rule 2 still gave G active ownership of web files the handoff says were released. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Record where H4a's web files went after G1 (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Name G3's one web/server.ts change in the handoff records (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Put the H4a ownership bullet in the past tense (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Name F's wave 2 server files in integration rule 2 (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Remove unneeded ownership history; quote the AGENTS.md rule (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep only supported ownership history (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Describe wave 1 config ownership as the plan's (#145) Copilot round 2 found that rule 2 still stated C's and D's finished wave 1 assignments as active rules. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Mark the lane plans as the original schedule (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Link the Lane G close-out follow-ups (#155, #156) (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * List all open Lane G follow-ups in the handoff (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Note what the Plans screen does for amendments today (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Match the handoff to #155's scope (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Update next steps and menu-link status for the Plans screen (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Describe the built Dismiss control in plan-format (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Match plan-format's Plans screen controls to the built screen (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Mark unbuilt Plans screen design features (#155) (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Match the handoff to #155's widened scope (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Name the suggestion Apply control; date the Plans DT update (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Correct the amendment and Settings notes (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Qualify build step 6 status with #155's unbuilt parts (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Place the refresh line below the cards in plan-format (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Qualify the Plans screen in What to do next (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Say the Plans screen has no approval step yet (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * List the approval step among #155's unbuilt parts (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Put lane H's ownership section in the past tense (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Put the H4b bullet in the past tense (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep H4b's storage note as the original plan (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep plan-format's v1 contract text; list shipped differences separately (#145) Copilot round 3: the guide's suggestion-card wording had been changed to match the shipped screen, which conflicts with the immutable v1 contract (schema/versions/1/semantics.md). Restore the contract-mirroring text, describe what the shipped screen does in its own section, and track the non-conformance in #159. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Cite #159 in status lines; note the #146 import limit (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * List the amendment-proposal gap in plan-format's shipped section (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Record that #146 was fixed by PR #158 (#145) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #146.
What changed
POST /api/plan/importrefused every body over 16 KiB before parsing, though the parser accepts a 1 MiB source and the v1 schema permits plans far larger than 16 KiB.web/server.ts: the import body limit is nowMAX_IMPORT_REQUEST_BYTES = 6 * MAX_SOURCE_BYTES + MAX_REQUEST_BYTES(6 MiB + 16 KiB = 6,307,840 bytes). Every other POST keepsMAX_REQUEST_BYTES(16 KiB).core/parse-v1.ts: exports the parser's 1 MiB bound asMAX_SOURCE_BYTES.yamlparser accepts a raw control character in a quoted scalar, and JSON writes it as\^A. So every source within the parser limit fits, inside any envelope that fits 16 KiB with an empty source. A body within the limit whose source is above 1 MiB gets the parser's refusal (409, recorded and replayed), not a transport one.docs/plan-format.md(the documented maximum) and the endpoint table indocs/implementation/runner-lifecycle.md.The schema was not tightened: the parser's 1 MiB bound already binds before the schema's larger theoretical maximum, so the contracts agree once transport admits every parser-valid source.
Tests
New
import request size (#146)block intest/runner-planning-feedback.test.ts, against the real server and Store:With the limit set back to 16 KiB, tests 1–3 fail with 413. With the import limit applied to every planning path, test 5 fails.
Validation
-t 146)runner-planning-feedback,runner-shutdown)f7d47e8tsc --noEmit)f7d47e8f7d47e8: 74 files, 1990/1990 pass (load average ~84). Earlier runs at intermediate checkpoint3cb9673(load 150–200) had differentpre-merge.test.tstiming failures each time; that file passed 40/40 alone. Recorded as infrastructure, not product.test)f7d47e8agent-isolation.ymlpath filters do not match this diffReview record
ae9fc3d/3cb9673ae9fc3d/3cb9673/api/action, so the import limit leaking to every planning path would pass. (b) Low: at-limit test asserted onlynot 413. (c) Nit: code comment implied the parser refusal was unconditional.f7d47e8.ae9fc3d/f7d47e8server.close()from settling, and can reset the client. Info: the 6× worst case relies on theyamllibrary's leniency for C0 controls.ae9fc3d/f7d47e8Review-lesson audit
AGENTS.md/CLAUDE.mdupdate needed.🤖 Generated with Claude Code