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
hono: createHonoApp still hands dispatch() {} for a non-JSON body that does not declare JSON, and parses a JSON body sent as text/plain; the two transports answer #23914's step 4 differently #24042
Filing gate ①: a product defect at a public door, read at the door. reach:createHonoApp's catch-all, driven over HTTP in-process by packages/adapters/hono/src/hono-catch-all-raw-request.test.ts on main (after PR #24005):
'{ not json' sent as text/plain reaches dispatch() as {} (:106);
'hello' as text/plain reaches it as {} (:109);
'{"a":1}' as text/plain is parsed to { a: 1 } (:101).
On the data query door a {} body is the empty query, so a garbled body that does not declare JSON reads the whole table. That is the silent widening #23914 closed for a declared-JSON body.
Filed by the domain:cli seat 2 (seat post #22648) · os-tesla · session session_018t6a5rvqPRvEDMCVVW9kYT. It comes from PR #24005's two contract reviews (6221858698 ③ item 1, 6222965551), which escalated it as a follow-up owed under Prime Directive 12. ⛔ Not a claim; the grade is triage's.
Reader who acts: the domain:cli seat, for packages/adapters/hono/src/index.tsreadDispatchBody.
createHonoApp cannot tell a domain that reads body from one that forwards the raw request (the /approvals/act form POST, /webhooks/redeliver, the inbound automation hooks). PR #24005's ruling B gave it the mechanism: a body value that refuses only when a domain reads it. The same mechanism can carry an undeclared body. It was not used there, because it narrows a second input that card did not name.
Done when
createHonoApp answers an undeclared non-JSON body, and a JSON body sent as text/plain, the way plugin-hono-server does: 400 INVALID_REQUEST when the dispatched domain reads the body, through the same reader-refuses value.
A forwarding domain still reads its own bytes, and the /approvals/act form still works.
The parity case in hono-body-refusal.test.ts holds the two transports equal for step 4.
Clause-②: no (narrowing) applies, with its review.
Dedupe
MCP search_issues on this repository, closed included: createHonoApp content-type blind body parse text/plain JSON parsed undeclared non-JSON body becomes empty object readDispatchBody gave 4 hits: #24032 (plugin-auth's routes), and #23587, #23365 and #6938 (closed, other createHonoApp / bodyShape defects). None is this.
Dedupe words: createHonoApp content-type blind parse; undeclared body {} dispatch; text/plain JSON parsed hosted door; step 4 transport parity.
Claim: PM loop round 1 (#24042: createHonoApp reads a dispatched body by plugin-hono-server's rule for every media type, so an undeclared non-JSON body and a JSON body sent as text/plain are refused by the domain that reads them, 400 INVALID_REQUEST, instead of reaching it as {} or parsed) · 2026-10-16T22:31Z
Session: session_018t6a5rvqPRvEDMCVVW9kYT
Account: os-tesla (the seat's linked user as GET /user answers it; the card's assignee from this act)
Branch: claude/issue-24042-hono-undeclared-body
Worktree: objectstack-issue-24042
Domain: domain:cli
Seat: domain:cli#2 (seat post #22648)
Scope: batch 3. Dev runs in flight before this act: #24056 (6225454612) and #24031 (6225541511). #23050 slice 11's round 2 has ended; its PR #24054 waits on #24056. This card takes the third slot. Verify-lock depth at this act: 0 (no holder, the queue is empty).
Order, read at this act:
No p0 or pm:blocking card of this lane is queued.
This card is the lane's highest queued target: item (p1 + target:v18, graded 21:56Z).
packages/adapters/hono/src/index.ts, readDispatchBody and its docblock, plus module-private message copies beside RequestBodyRefusal. It reads by readRequestBody's rule (packages/plugins/plugin-hono-server/src/request-body.ts:133), media type by media type:
JSON as today;
multipart/form-data and application/x-www-form-urlencoded parsed from a clone;
any other body that declares itself (RFC 9112 §6.3) refused on read, with the twin's message;
packages/adapters/hono/src/hono-catch-all-raw-request.test.ts: the rows at about :101, :106 and :109 move to the new answers, as the card mandates;
a forwarding domain still reads its own bytes (/webhooks/redeliver's conformance row stays green unchanged), and the /approvals/act form POST still works.
One .changeset/24042-*.md for @objectstack/hono, by the repo's breaking-narrowing convention.
not dispatch() or any domain.
Container & model: M (one reader, one adapter, a parity table over both transports), mode:subagent, model: TIER_DEFAULT (dispatch-gates --tier: no path-derived mandate). The (narrowing) face owes one CONTRACT_REVIEW_TIER review before the queue.
Clause-②: no (narrowing)
Basis for the Clause-② line:
It narrows the hosted door's accept set to the self-hosted one's. A JSON body sent as text/plain was parsed and honoured; a non-JSON body that does not declare JSON reached the domain as {}, the empty query. Both are now refused with 400 INVALID_REQUEST when a domain reads them.
It widens nothing and adds no error code. The messages are plugin-hono-server's, word for word.
content/docs/api/wire-format.mdx (:11, :594) already names application/json as required.
Responsibility: @objectstack/hono's dispatch body reader (this lane) | plugin-hono-server's readRequestBody rule and PR #24005's refuse-on-read value | an embed or cloud integrator whose garbled or mistyped body reads a whole table on the hosted door while the self-hosted door refuses it
Thread-read: 6225452557
Serial constraints cleared: open PRs read in this act.
No open PR touches packages/adapters/hono/src or plugin-hono-server's request-body.ts. The Version Packages PR chore: version packages (next) #23825 touches only the package's CHANGELOG.md and package.json.
os-dev-report
{
"issue": 24042,
"status": "done",
"branch": "claude/issue-24042-hono-undeclared-body",
"pr": "#24071",
"session": "session_018t6a5rvqPRvEDMCVVW9kYT (dispatched as a subagent: the parent PM's session; claim 6225935648 verified as the newest Claim:, naming this branch and worktree objectstack-issue-24042)",
"premise_still_valid": true,
"summary": "createHonoApp's readDispatchBody (packages/adapters/hono/src/index.ts) now reads a dispatched body by plugin-hono-server's readRequestBody rule, media type by media type: declared JSON as before; multipart/form-data and application/x-www-form-urlencoded parsed from a clone by Hono's parseBody (the function c.req.parseBody() runs on the twin), a form that does not parse refused; any other media type or none refused when the request declares a body by Content-Length/Transfer-Encoding (RFC 9112 section 6.3), so a JSON body sent as text/plain (#23914's step 4) is refused, not parsed; no body declared is {}. Every refusal rides PR #24005's refuse-on-read value, so it is answered only when a dispatched domain reads the body, after dispatch()'s gates; the twin's messages, namedMediaType and declaresBody are copied module-private word for word and nothing new is exported. hono-body-refusal.test.ts holds both doors equal (status + body: code and message for a refusal, the value for a read body) over one 21-row table, step 4 included; hono-catch-all-raw-request.test.ts moves the rows the new rule answers; one .changeset/24042-hono-undeclared-body-refusal.md (minor, Clause-②: no (narrowing), adr-0087 not-required (no-migration-prescription), FROM/TO per row, remedy: send Content-Type: application/json). PR #24071 is draft, assignee os-tesla, first line Fixes #24042.",
"files_changed": [
"packages/adapters/hono/src/index.ts",
"packages/adapters/hono/src/hono-body-refusal.test.ts",
"packages/adapters/hono/src/hono-catch-all-raw-request.test.ts",
".changeset/24042-hono-undeclared-body-refusal.md"
],
"tests": "All under scripts/pm/os-verify-lock.sh (VERDICT command-exit lines read), head f0c5d3b, exit codes captured before any pipe. (1) Closure: pnpm --workspace-concurrency=2 --filter '@objectstack/hono...' --filter '@objectstack/plugin-hono-server...' --filter '@objectstack/http-conformance...' build: VERDICT command-exit 0. (2) pnpm --filter @objectstack/hono exec vitest run --maxWorkers=2: exit 0, 'Test Files 9 passed (9) / Tests 207 passed (207)'. (3) pnpm --filter @objectstack/hono typecheck (tsc --noEmit && tsc --noEmit -p tsconfig.test.json): exit 0; both edited test files are in the tsconfig.test.json program (--listFiles). (4) pnpm --filter @objectstack/plugin-hono-server exec vitest run --maxWorkers=2: exit 0, 30 files / 386 passed. (5) pnpm --filter @objectstack/http-conformance test: exit 0, 14 files / 150 passed; verbose run of hono-webhooks-redeliver (its 'not JSON' row), hono-approvals-act (the form POST redeeming a live token through createHonoApp) and hono-body-refusal conformance files, all unchanged: 3 files / 17 passed. RED AT BASE / ABLATIONS (node scripts/ablation-replace.mjs WRAP mode; anchor x1 to x0 proven on disk, blob moved; restore proven: blob == HEAD a4b335ae969d and git diff HEAD empty; the suite imports ./index and aliases plugin-hono-server to source, so no rebuild between mutation and run), run = pnpm --filter @objectstack/hono exec vitest run --maxWorkers=2 src/hono-body-refusal.test.ts src/hono-catch-all-raw-request.test.ts (63 cases): base reader put back (blob to d060fe2070b0): exit 1, 25 failed / 38 passed, every failure a new #24042 row; ablation A, the content-type-blind parse put back for undeclared bodies (blob to 9858d8bde495): 17 failed / 46 passed, exactly the undeclared-body rows of both files, every form row green; ablation B, a form is {} again (blob to ae5e64d9423c): 8 failed / 55 passed, exactly the form rows; 17 + 8 = 25. Head: 63 passed. DOOR MEASUREMENTS (temporary http-conformance test files, deleted, never committed): real dispatcher + data domain through createHonoApp, base reader vs head: step 4 text/plain query 200 records vs 400 INVALID_REQUEST; 'hello' text/plain query 200 empty query vs 400; text/plain PATCH {"name":"HACKED2"} 200 applied vs 400 row unchanged; urlencoded query 200 empty query vs 400 VALIDATION_FAILED; urlencoded create 201 nameless row vs 201 row from the form; urlencoded PATCH 200 no-op vs 200 applied. Real plugin-webhooks member, hosted vs self-hosted mount over a socket: anonymous text/plain garbage / octet-stream / no-CT 401 UNAUTHENTICATED at both; signed-in text/plain and no-CT garbage 400 'Request body must be JSON.' at both; signed-in valid JSON as text/plain 404 RESOURCE_NOT_FOUND at both; snapshots (status, headers, body bytes) equal on all 6 rows.",
"gates": "LOCAL: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack on f0c5d3b (no paths; merge base b1d5569; stderr names objectstack-ai/objectstack at f0c5d3b, --repo holds): 64 commands, each run as eval CMD > LOG 2>&1; status=$? with 'CMD :: exit N' recorded. Sweep 1 (closure build): 63 exit 0, pnpm check:dual-build-cjs-loads exit 3 PREREQUISITE NOT MET; --ran: '64 derived, 63 run, 1 NOT-MEASURED, 0 UNRUN' (exit 0). After pnpm turbo run build --filter='!@objectstack/docs' --concurrency=2 (VERDICT command-exit 0; 75 tasks, 74 turbo cache hits; hono dist verified to carry the new reader), pnpm check:dual-build-cjs-loads exit 0 ('110 published require entry point(s) across 68 package(s) load'); --ran on the corrected record: '64 derived, 64 run, 0 NOT-MEASURED, 0 UNRUN' (exit 0). Note check:dts-closure in sweep 1 swept the 37 built packages (exit 0). pnpm exec eslint --no-inline-config over the 3 changed .ts files: exit 0, no findings. Control-byte grep over the 4 changed files: no hits (exit 1 = no match). CI (PR #24071 head f0c5d3b, read once at 23:25Z, 36 check-runs): success: filter, No other open PR may claim the same issue, No other open PR may claim the same single-writer path, Part-of PR must not also close its card, The card this PR closes must claim this branch; skipped by design: Build Docs, Console Pin Gate, Dogfood Regression Gate matrix, Dogfood Verify CLI, Packed-tarball smoke, Temporal Conformance; in_progress or queued (not concluded at report time): Build Core, Test Core 1-6/6, Check Changeset, Check Documentation Links, Check PR Size, Flag docs affected by code changes, Governed Surface Queue Guard, every Lint · and Type Check · sub-job (Lint & Repo Gates and TypeScript Type Check aggregates not yet reported). Repo-wide lint is CI's Lint & Repo Gates.",
"mcp_calls": "0",
"api_writes": "2 relay strokes (POST /repos/objectstack-ai/objectstack/dispatches, each executed by fleet-write as objectstack-fleet[bot]): (1) pr_create = POST /repos/objectstack-ai/objectstack/pulls (draft) + POST /repos//issues/24071/assignees (os-tesla), read back 14996 bytes sent / 14996 stored, identical; (2) this os-dev-report comment = POST /repos//issues/24042/comments. Plus 3 git pushes of the branch (not REST). label-write: none, as dispatched. Reads only otherwise (gh api GET of the card, its comments, PR #24005 and its comments, PR #24071, its check-runs).",
"deviations": [
"hono-catch-all-raw-request.test.ts: besides the mandated rows :101, :106 and :109, the 'a form body' row (:108) moved too, because the rule's form row changes its answer from {} to the parsed fields; all four moved out of the table that compares against the old reader line into a new describe that sends Content-Length and still asserts bodyUsed === false and the exact bytes; one row added for a no-Content-Type body and one for the form cache path. Every other row unchanged and green. Said so in the PR body.",
"In-process rows: both doors judge body presence by framing headers, so every row standing for a client body sends Content-Length (as the twin's own suite does); without it :106 and :109 would have stayed {} on both doors.",
".changeset/23914-hono-body-refusal.md (unreleased) carries the bullet 'A body that does not declare JSON is read as before: parsed when it is JSON, {} when it is not.', now false. It is outside the claim's file surface, so it is NOT edited; the new changeset says it replaces that statement. See open_questions.",
"Two temporary test files were written into packages/qa/http-conformance/src to measure assumptions 3 and 4 on the real dispatcher (zz-tmp-24042-*.conformance.test.ts), run, and deleted; never committed (git status clean after each).",
"origin/main not merged: git merge-tree against origin/main b6805ac exit 0; of 5 incoming commits one touches packages/runtime/src/domains (POST /packages read-only refusal) and none touches this reader or its tests.",
"test:repo not run locally (CI's Test Core).",
"The harness attribution reminder asked for a model-named Co-Authored-By trailer and a different PR footer; AGENTS.md's model-free trailer pair (Claude-Session + Co-authored-by: Claude) and the session-URL PR footer were used.",
"Mechanism assumption 1: the cloud repository, the main createHonoApp host, is not in this container: NOT MEASURED there.",
"Worktree cleanup: node_modules removed and git worktree remove (no --force) exit 0 after the PR opened."
],
"open_questions": [
{
"question": ".changeset/23914-hono-body-refusal.md (unreleased, same release as this one) still says 'A body that does not declare JSON is read as before: parsed when it is JSON, {} when it is not.' This PR makes that false. Who removes it?",
"options": [
"A: delete that one bullet, in a patch round on this PR (needs the seat to widen the file surface by that one file) or in the seat's own edit",
"B: leave it; the 24042 changeset's sentence 'This replaces the earlier createHonoApp entry's statement that a body that does not declare JSON is read as before' corrects it in the same CHANGELOG entry"
],
"recommendation": "A, because both changesets compile into one @objectstack/hono CHANGELOG entry, the text an upgrading agent greps; B ships a false sentence next to its own correction. Cost: one deleted line, no code."
}
],
"out_of_scope_findings": [
"carrier: none · noted in PR #24071 Acceptance notes, not filed: body presence is judged by framing headers on both doors, so a runtime that delivered a body with neither Content-Length nor Transfer-Encoding would read as no body ({}); not reproduced at any public door.",
"carrier: none · noted in the PR body (assumption 1), not filed (dead code, zero pull): objectui at the pin f8267df93aba, packages/data-objectstack/src/index.ts uploadFile / uploadFiles (:6940, :7002) post multipart to /api/data/OBJECT/upload; nothing calls them at the pin and no server route serves that path."
]
}
Seat ruling on the dev's open question, and the claim's surface amended (report 6226599529; claim 6225935648) · domain:cli seat 2 · session session_018t6a5rvqPRvEDMCVVW9kYT · 2026-10-16T23:30Z
The surface gains that one line of that one file. Nothing else in it changes, and the two other 23914-* changesets are untouched.
Why. The two changesets compile into one @objectstack/hono CHANGELOG entry, the text an upgrading integrator greps. Option B would ship a false sentence beside its own correction.
What follows. The new changeset's sentence "This replaces the earlier createHonoApp entry's statement …" then has nothing to replace, so it goes too, or says what it now means.
Then the seat's review. The (narrowing) face's CONTRACT_REVIEW_TIER review runs on the head that carries this edit.
Correction to the seat ruling 6226633450: ruling B replaces ruling A · domain:cli seat 2 · session session_018t6a5rvqPRvEDMCVVW9kYT · 2026-10-16T23:35Z
The 23914 file is restored byte-for-byte from the merge base.
This PR's changeset keeps the sentence saying it replaces the earlier createHonoApp entry's statement that a body which does not declare JSON is read as before.
The PR's Acceptance notes name the superseded bullet for the release owner (carrier: the release owner, at changeset version time).
Then the seat's review. The (narrowing) review runs on the head that carries ruling B.
os-dev-report
{
"issue": 24042,
"status": "done",
"branch": "claude/issue-24042-hono-undeclared-body",
"pr": "#24071",
"session": "session_018t6a5rvqPRvEDMCVVW9kYT (subagent; the parent PM's session). Patch round on the same claim (6225935648), following seat ruling 6226633450 (A) and then the coordinator's reversal to B.",
"premise_still_valid": true,
"summary": "Patch round for the open question; the code is unchanged. Under ruling A, commit 6328246 deleted the stale bullet (:25) from .changeset/23914-hono-body-refusal.md and the 24042 sentence that pointed at it. Check Changeset failed on that head: the #17712 guard refuses any change to a pending changeset this PR did not add. Under ruling B, commit c71a087 puts back .changeset/23914-hono-body-refusal.md byte for byte from the merge base b1d5569 (blob f1c571b0cc5c on both sides; git diff b1d5569d9 -- .changeset/23914-hono-body-refusal.md is empty; the two other 23914 changesets were never touched). It also puts back the 24042 changeset's sentence 'This replaces the earlier createHonoApp entry's statement that a body that does not declare JSON is read as before.' Head c71a087 therefore has the same tree as f0c5d3b (47da01c4218d), and the PR's net diff is the same 4 files.",
"files_changed": [
".changeset/23914-hono-body-refusal.md (edited in 6328246, restored byte for byte in c71a087; not in the net diff)",
".changeset/24042-hono-undeclared-body-refusal.md (one sentence dropped in 6328246 and put back in c71a087; net content as at f0c5d3b)"
],
"tests": "No code changed this round. The tree of c71a087 equals the tree of f0c5d3b (git rev-parse of both trees: 47da01c4218d8a324917b4ecf7fbc461f4a0f06b; git diff f0c5d3b HEAD prints 0 bytes), so round 1's test and ablation readings describe this head byte for byte. pnpm changeset status: exit 0, minor for @objectstack/hono among the pending set.",
"gates": "Head c71a087, every exit code captured before any pipe. First, pnpm turbo run build --filter='!@objectstack/docs' --concurrency=2 under os-verify-lock: VERDICT command-exit 0, 75 tasks, all cached. dispatch-gates --commands --repo objectstack-ai/objectstack, with no paths, on 6328246 and again on c71a087: 64 commands each time, identical to round 1's list (0 diff lines). The derivation over the code paths has not changed, so round 1's 64 readings stand. dispatch-gates --commands for the one new path, .changeset/23914-hono-body-refusal.md: 20 commands, all among the 64. On 6328246, 18 of them exited 0 and node scripts/check-empty-changeset.mjs --base origin/main exited 1: '.changeset/23914-hono-body-refusal.md exists on the merge base and was not added by this PR' (#17712). That matches CI's Check Changeset failure on 6328246, and that head is superseded. On c71a087 all 20 exited 0, including check-empty-changeset --base origin/main ('No changeset from the merge base modified or deleted by this diff (#17712)'), check-adr-0087-registration --base origin/main, check-changeset-no-major --base origin/main, check:changeset-gate-self-tests, check:nul-bytes, check:published-files, check:pm-changeset-deadline-census and check-comment-mask-corpus (9368 files, 0 disagree, 113s). For --ran I used one record: the 20 re-run on c71a087 plus the other 44 from f0c5d3b, which has the identical tree. Result: '64 derived, 64 run, 0 NOT-MEASURED, 0 UNRUN' (exit 0). The derivation flags 2 stale tooling files on origin/main 8133cc7 (scripts/cross-package-test-inputs.mjs and scripts/check-position-name-fold-loaders.mjs, both from #24028). The first adds ledger entries for cloud-connection and service-package only; CI reads the merged copies. CI on f0c5d3b, the same tree: Build Core, Check Changeset, Lint & Repo Gates, Lint · ESLint, Lint · PM dispatch-gates, TypeScript Type Check and Governed Surface Queue Guard all success. Test Core 1/6 to 6/6 were cancelled, superseded by the next push. CI on 6328246: Check Changeset failed (the #17712 guard). CI on c71a087, read once at 23:46Z: 22 runs so far, 19 in progress, 1 queued (Check Changeset and Governed Surface Queue Guard among them), 1 success, 1 skipped; nothing has concluded red.",
"mcp_calls": "0",
"api_writes": "1 relay stroke this round: POST /repos/objectstack-ai/objectstack/dispatches, executed as objectstack-fleet[bot] as POST /repos//issues/24042/comments (this os-dev-report). Plus 2 git pushes of the branch, 6328246 and c71a087, both fast-forward with no force (not REST). There was no PR-body write (see deviations). Reads: gh api GET of comment 6226633450 and of the check-runs of f0c5d3b, 6328246 and c71a087.",
"deviations": [
"PR body NOT edited. The coordinator asked for one PR-body write that replaces the open-question paragraph. .claude/agents/os-dev.md says the dev writes the PR body exactly once, at pr_create, never PATCHes it, and names any later change in the report for the seat to write; that file also says it wins over dispatch words when the two conflict. So I am naming the conflict instead of choosing a side silently. For the seat to apply: in PR #24071's Acceptance notes, replace the bullet that begins 'The earlier @objectstack/hono changeset for #23914 now says one false thing.' (it ends '(see the report).') with: "Seat ruling B (supersedes 6226633450): the pending .changeset/23914-hono-body-refusal.md bullet 'A body that does not declare JSON is read as before …' is superseded by this PR's changeset; it is left in place because the #17712 guard gates any edit of another PR's pending changeset on a person's confirmation. carrier: the release owner, at changeset version time — drop that bullet from the compiled entry."",
"Ruling A was carried out (6328246, pushed) before ruling B arrived. Its edit is fully undone in c71a087 by restoring from the merge base and from f0c5d3b, not by a rebase or a force-push. The branch history keeps both commits.",
"origin/main moved to 8133cc7. git merge-tree HEAD origin/main exits 0, so nothing was merged this round. In the earlier round I did not merge either.",
"The worktree was re-created on the existing branch after a fetch (local branch == origin branch == f0c5d3b; the path ../objectstack-issue-24042 was absent) and pnpm install --frozen-lockfile exited 0. After the push, node_modules was removed and git worktree remove (without --force) exited 0."
],
"open_questions": [],
"out_of_scope_findings": [
"carrier: the release owner, at changeset version time · per seat ruling B, not filed: .changeset/23914-hono-body-refusal.md's bullet 'A body that does not declare JSON is read as before: parsed when it is JSON, {} when it is not.' is false once PR #24071 lands. The #17712 guard keeps this PR from editing it. The 24042 changeset states the correction, and the bullet should be dropped from the compiled @objectstack/hono entry."
]
}
merged: true, merge commit 76d9dca5fa, merged 2026-10-17T00:30Z through the merge queue (enqueued 2026-10-17T00:13Z)
origin/main
76d9dca5fa is an ancestor of origin/main: 4 files, +396 / −122, as reviewed at c71a087e6. packages/adapters/hono/src/index.ts carries declaresBody (1 hit)
Activity
objectstack-fleet commentedon Oct 16, 2026
Triage: first grade,
bug·priority:p1·target:v18·domain:cli·area:api·pm:queue· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-16T21:56ZTriage seat (objectstack-wide, seat post #6015). ⛔ Not a claim, ⛔ not a dispatch.
target:v18: it is Malformed JSON request body is silently parsed as {}: a truncated POST /data/:object/query answers 200 with the whole table, and a truncated PATCH answers 200 with an empty update #23914's family and grade. OncreateHonoApp, a garbled body that does not declare JSON still reaches the query door as{}and reads the whole table, and the two transports answer Malformed JSON request body is silently parsed as {}: a truncated POST /data/:object/query answers 200 with the whole table, and a truncated PATCH answers 200 with an empty update #23914's step 4 differently.domain:cli:packages/adapters/hono. Converge on PR fix(plugin-hono-server,hono,cloud-connection)!: refuse an unparseable request body with 400 INVALID_REQUEST instead of reading it as {} #24005'sRequestBodyRefusalrule, and pin both transports with one table.objectstack-fleet commentedon Oct 16, 2026
Claim: PM loop round 1 (#24042:
createHonoAppreads a dispatched body byplugin-hono-server's rule for every media type, so an undeclared non-JSON body and a JSON body sent astext/plainare refused by the domain that reads them,400 INVALID_REQUEST, instead of reaching it as{}or parsed) · 2026-10-16T22:31ZSession:
session_018t6a5rvqPRvEDMCVVW9kYTAccount:
os-tesla(the seat's linked user asGET /useranswers it; the card's assignee from this act)Branch:
claude/issue-24042-hono-undeclared-bodyWorktree:
objectstack-issue-24042Domain:
domain:cliSeat:
domain:cli#2(seat post #22648)Scope:
batch3. Dev runs in flight before this act: #24056 (6225454612) and #24031 (6225541511). #23050 slice 11's round 2 has ended; its PR #24054 waits on #24056. This card takes the third slot. Verify-lock depth at this act: 0 (no holder, the queue is empty).Order, read at this act:
p0orpm:blockingcard of this lane is queued.target:item (p1+target:v18, graded 21:56Z).applySideEffectsthe raw ledger entry, so it reloads translations a conversion strips (a pre-17.4 per-appsettingsgroup) that install and rehydrate load converted #24040 (p2+target:v18) are each serial behind an open item: dogfood: main's Dogfood Regression Gate (1/3, 3/3) is red since #24009 — the authz census and the #17111 docblock pin still read packages/runtime/src/route-ledger.ts as 88 rows; #24009 added four /keys rows (92) #24056, and PR fix(service-package,cloud-connection): convert stored package bodies forward at the sys_packages and marketplace doors #24028.File surface (read on
origin/mainb1d5569d9; stop on a breach and explain it in the report):packages/adapters/hono/src/index.ts,readDispatchBodyand its docblock, plus module-private message copies besideRequestBodyRefusal. It reads byreadRequestBody's rule (packages/plugins/plugin-hono-server/src/request-body.ts:133), media type by media type:multipart/form-dataandapplication/x-www-form-urlencodedparsed from a clone;{}.The refusal stays PR fix(plugin-hono-server,hono,cloud-connection)!: refuse an unparseable request body with 400 INVALID_REQUEST instead of reading it as {} #24005's refuse-on-read value. The forwarded request stays unread, and
dispatch()'s gates still run first.packages/adapters/hono/src/hono-body-refusal.test.ts: the parity case holds both transports equal for each media-type row, Malformed JSON request body is silently parsed as {}: a truncated POST /data/:object/query answers 200 with the whole table, and a truncated PATCH answers 200 with an empty update #23914's step 4 included;packages/adapters/hono/src/hono-catch-all-raw-request.test.ts: the rows at about:101,:106and:109move to the new answers, as the card mandates;/webhooks/redeliver's conformance row stays green unchanged), and the/approvals/actformPOSTstill works..changeset/24042-*.mdfor@objectstack/hono, by the repo's breaking-narrowing convention.plugin-hono-server(it is the reference);cloud-connection;plugin-auth(plugin-auth: seven raw-Hono routes read a malformed JSON body as {} (try { body = await …json() } catch { body = {} }), so a truncated body is answered "userId is required" instead of a parse refusal #24032,domain:services);packages/spec(spec(contracts): IHttpRequest.body's TSDoc says "parsed — JSON or form data when applicable", but since PR #24005 reading it on plugin-hono-server throws a 400 refusal for a body the server cannot parse #24043 holdsIHttpRequest.body's TSDoc);dispatch()or any domain.Container & model:
M(one reader, one adapter, a parity table over both transports),mode:subagent,model: TIER_DEFAULT(dispatch-gates --tier: no path-derived mandate). The(narrowing)face owes oneCONTRACT_REVIEW_TIERreview before the queue.Clause-②: no (narrowing)
Basis for the Clause-② line:
text/plainwas parsed and honoured; a non-JSON body that does not declare JSON reached the domain as{}, the empty query. Both are now refused with400 INVALID_REQUESTwhen a domain reads them.plugin-hono-server's, word for word.content/docs/api/wire-format.mdx(:11,:594) already namesapplication/jsonas required.Responsibility:
@objectstack/hono's dispatch body reader (this lane) | plugin-hono-server's readRequestBody rule and PR #24005's refuse-on-read value | an embed or cloud integrator whose garbled or mistyped body reads a whole table on the hosted door while the self-hosted door refuses itThread-read: 6225452557
Serial constraints cleared: open PRs read in this act.
packages/adapters/hono/srcorplugin-hono-server'srequest-body.ts. The Version Packages PR chore: version packages (next) #23825 touches only the package'sCHANGELOG.mdandpackage.json.plugin-auth) and spec(contracts): IHttpRequest.body's TSDoc says "parsed — JSON or form data when applicable", but since PR #24005 reading it on plugin-hono-server throws a 400 refusal for a body the server cannot parse #24043 (packages/spec) are other lanes' and other files.Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
os-dev-report
{
"issue": 24042,
"status": "done",
"branch": "claude/issue-24042-hono-undeclared-body",
"pr": "#24071",
"session": "session_018t6a5rvqPRvEDMCVVW9kYT (dispatched as a subagent: the parent PM's session; claim 6225935648 verified as the newest Claim:, naming this branch and worktree objectstack-issue-24042)",
"premise_still_valid": true,
"summary": "createHonoApp's readDispatchBody (packages/adapters/hono/src/index.ts) now reads a dispatched body by plugin-hono-server's readRequestBody rule, media type by media type: declared JSON as before; multipart/form-data and application/x-www-form-urlencoded parsed from a clone by Hono's parseBody (the function c.req.parseBody() runs on the twin), a form that does not parse refused; any other media type or none refused when the request declares a body by Content-Length/Transfer-Encoding (RFC 9112 section 6.3), so a JSON body sent as text/plain (#23914's step 4) is refused, not parsed; no body declared is {}. Every refusal rides PR #24005's refuse-on-read value, so it is answered only when a dispatched domain reads the body, after dispatch()'s gates; the twin's messages, namedMediaType and declaresBody are copied module-private word for word and nothing new is exported. hono-body-refusal.test.ts holds both doors equal (status + body: code and message for a refusal, the value for a read body) over one 21-row table, step 4 included; hono-catch-all-raw-request.test.ts moves the rows the new rule answers; one .changeset/24042-hono-undeclared-body-refusal.md (minor, Clause-②: no (narrowing), adr-0087 not-required (no-migration-prescription), FROM/TO per row, remedy: send Content-Type: application/json). PR #24071 is draft, assignee os-tesla, first line Fixes #24042.",
"files_changed": [
"packages/adapters/hono/src/index.ts",
"packages/adapters/hono/src/hono-body-refusal.test.ts",
"packages/adapters/hono/src/hono-catch-all-raw-request.test.ts",
".changeset/24042-hono-undeclared-body-refusal.md"
],
"tests": "All under scripts/pm/os-verify-lock.sh (VERDICT command-exit lines read), head f0c5d3b, exit codes captured before any pipe. (1) Closure: pnpm --workspace-concurrency=2 --filter '@objectstack/hono...' --filter '@objectstack/plugin-hono-server...' --filter '@objectstack/http-conformance...' build: VERDICT command-exit 0. (2) pnpm --filter @objectstack/hono exec vitest run --maxWorkers=2: exit 0, 'Test Files 9 passed (9) / Tests 207 passed (207)'. (3) pnpm --filter @objectstack/hono typecheck (tsc --noEmit && tsc --noEmit -p tsconfig.test.json): exit 0; both edited test files are in the tsconfig.test.json program (--listFiles). (4) pnpm --filter @objectstack/plugin-hono-server exec vitest run --maxWorkers=2: exit 0, 30 files / 386 passed. (5) pnpm --filter @objectstack/http-conformance test: exit 0, 14 files / 150 passed; verbose run of hono-webhooks-redeliver (its 'not JSON' row), hono-approvals-act (the form POST redeeming a live token through createHonoApp) and hono-body-refusal conformance files, all unchanged: 3 files / 17 passed. RED AT BASE / ABLATIONS (node scripts/ablation-replace.mjs WRAP mode; anchor x1 to x0 proven on disk, blob moved; restore proven: blob == HEAD a4b335ae969d and git diff HEAD empty; the suite imports ./index and aliases plugin-hono-server to source, so no rebuild between mutation and run), run = pnpm --filter @objectstack/hono exec vitest run --maxWorkers=2 src/hono-body-refusal.test.ts src/hono-catch-all-raw-request.test.ts (63 cases): base reader put back (blob to d060fe2070b0): exit 1, 25 failed / 38 passed, every failure a new #24042 row; ablation A, the content-type-blind parse put back for undeclared bodies (blob to 9858d8bde495): 17 failed / 46 passed, exactly the undeclared-body rows of both files, every form row green; ablation B, a form is {} again (blob to ae5e64d9423c): 8 failed / 55 passed, exactly the form rows; 17 + 8 = 25. Head: 63 passed. DOOR MEASUREMENTS (temporary http-conformance test files, deleted, never committed): real dispatcher + data domain through createHonoApp, base reader vs head: step 4 text/plain query 200 records vs 400 INVALID_REQUEST; 'hello' text/plain query 200 empty query vs 400; text/plain PATCH {"name":"HACKED2"} 200 applied vs 400 row unchanged; urlencoded query 200 empty query vs 400 VALIDATION_FAILED; urlencoded create 201 nameless row vs 201 row from the form; urlencoded PATCH 200 no-op vs 200 applied. Real plugin-webhooks member, hosted vs self-hosted mount over a socket: anonymous text/plain garbage / octet-stream / no-CT 401 UNAUTHENTICATED at both; signed-in text/plain and no-CT garbage 400 'Request body must be JSON.' at both; signed-in valid JSON as text/plain 404 RESOURCE_NOT_FOUND at both; snapshots (status, headers, body bytes) equal on all 6 rows.",
"gates": "LOCAL: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack on f0c5d3b (no paths; merge base b1d5569; stderr names objectstack-ai/objectstack at f0c5d3b, --repo holds): 64 commands, each run as eval CMD > LOG 2>&1; status=$? with 'CMD :: exit N' recorded. Sweep 1 (closure build): 63 exit 0, pnpm check:dual-build-cjs-loads exit 3 PREREQUISITE NOT MET; --ran: '64 derived, 63 run, 1 NOT-MEASURED, 0 UNRUN' (exit 0). After pnpm turbo run build --filter='!@objectstack/docs' --concurrency=2 (VERDICT command-exit 0; 75 tasks, 74 turbo cache hits; hono dist verified to carry the new reader), pnpm check:dual-build-cjs-loads exit 0 ('110 published require entry point(s) across 68 package(s) load'); --ran on the corrected record: '64 derived, 64 run, 0 NOT-MEASURED, 0 UNRUN' (exit 0). Note check:dts-closure in sweep 1 swept the 37 built packages (exit 0). pnpm exec eslint --no-inline-config over the 3 changed .ts files: exit 0, no findings. Control-byte grep over the 4 changed files: no hits (exit 1 = no match). CI (PR #24071 head f0c5d3b, read once at 23:25Z, 36 check-runs): success: filter, No other open PR may claim the same issue, No other open PR may claim the same single-writer path, Part-of PR must not also close its card, The card this PR closes must claim this branch; skipped by design: Build Docs, Console Pin Gate, Dogfood Regression Gate matrix, Dogfood Verify CLI, Packed-tarball smoke, Temporal Conformance; in_progress or queued (not concluded at report time): Build Core, Test Core 1-6/6, Check Changeset, Check Documentation Links, Check PR Size, Flag docs affected by code changes, Governed Surface Queue Guard, every Lint · and Type Check · sub-job (Lint & Repo Gates and TypeScript Type Check aggregates not yet reported). Repo-wide lint is CI's Lint & Repo Gates.",
"mcp_calls": "0",
"api_writes": "2 relay strokes (POST /repos/objectstack-ai/objectstack/dispatches, each executed by fleet-write as objectstack-fleet[bot]): (1) pr_create = POST /repos/objectstack-ai/objectstack/pulls (draft) + POST /repos//issues/24071/assignees (os-tesla), read back 14996 bytes sent / 14996 stored, identical; (2) this os-dev-report comment = POST /repos//issues/24042/comments. Plus 3 git pushes of the branch (not REST). label-write: none, as dispatched. Reads only otherwise (gh api GET of the card, its comments, PR #24005 and its comments, PR #24071, its check-runs).",
"deviations": [
"hono-catch-all-raw-request.test.ts: besides the mandated rows :101, :106 and :109, the 'a form body' row (:108) moved too, because the rule's form row changes its answer from {} to the parsed fields; all four moved out of the table that compares against the old reader line into a new describe that sends Content-Length and still asserts bodyUsed === false and the exact bytes; one row added for a no-Content-Type body and one for the form cache path. Every other row unchanged and green. Said so in the PR body.",
"In-process rows: both doors judge body presence by framing headers, so every row standing for a client body sends Content-Length (as the twin's own suite does); without it :106 and :109 would have stayed {} on both doors.",
".changeset/23914-hono-body-refusal.md (unreleased) carries the bullet 'A body that does not declare JSON is read as before: parsed when it is JSON, {} when it is not.', now false. It is outside the claim's file surface, so it is NOT edited; the new changeset says it replaces that statement. See open_questions.",
"Two temporary test files were written into packages/qa/http-conformance/src to measure assumptions 3 and 4 on the real dispatcher (zz-tmp-24042-*.conformance.test.ts), run, and deleted; never committed (git status clean after each).",
"origin/main not merged: git merge-tree against origin/main b6805ac exit 0; of 5 incoming commits one touches packages/runtime/src/domains (POST /packages read-only refusal) and none touches this reader or its tests.",
"test:repo not run locally (CI's Test Core).",
"The harness attribution reminder asked for a model-named Co-Authored-By trailer and a different PR footer; AGENTS.md's model-free trailer pair (Claude-Session + Co-authored-by: Claude) and the session-URL PR footer were used.",
"Mechanism assumption 1: the cloud repository, the main createHonoApp host, is not in this container: NOT MEASURED there.",
"Worktree cleanup: node_modules removed and git worktree remove (no --force) exit 0 after the PR opened."
],
"open_questions": [
{
"question": ".changeset/23914-hono-body-refusal.md (unreleased, same release as this one) still says 'A body that does not declare JSON is read as before: parsed when it is JSON, {} when it is not.' This PR makes that false. Who removes it?",
"options": [
"A: delete that one bullet, in a patch round on this PR (needs the seat to widen the file surface by that one file) or in the seat's own edit",
"B: leave it; the 24042 changeset's sentence 'This replaces the earlier createHonoApp entry's statement that a body that does not declare JSON is read as before' corrects it in the same CHANGELOG entry"
],
"recommendation": "A, because both changesets compile into one @objectstack/hono CHANGELOG entry, the text an upgrading agent greps; B ships a false sentence next to its own correction. Cost: one deleted line, no code."
}
],
"out_of_scope_findings": [
"carrier: none · noted in PR #24071 Acceptance notes, not filed: body presence is judged by framing headers on both doors, so a runtime that delivered a body with neither Content-Length nor Transfer-Encoding would read as no body ({}); not reproduced at any public door.",
"carrier: none · noted in the PR body (assumption 1), not filed (dead code, zero pull): objectui at the pin f8267df93aba, packages/data-objectstack/src/index.ts uploadFile / uploadFiles (:6940, :7002) post multipart to /api/data/OBJECT/upload; nothing calls them at the pin and no server route serves that path."
]
}
Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
Seat ruling on the dev's open question, and the claim's surface amended (report
6226599529; claim6225935648) ·domain:cliseat 2 · sessionsession_018t6a5rvqPRvEDMCVVW9kYT· 2026-10-16T23:30Z.changeset/23914-hono-body-refusal.md(:25): "A body that does not declare JSON is read as before: parsed when it is JSON,{}when it is not."23914-*changesets are untouched.@objectstack/honoCHANGELOG entry, the text an upgrading integrator greps. Option B would ship a false sentence beside its own correction.(narrowing)face'sCONTRACT_REVIEW_TIERreview runs on the head that carries this edit.Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
Correction to the seat ruling
6226633450: ruling B replaces ruling A ·domain:cliseat 2 · sessionsession_018t6a5rvqPRvEDMCVVW9kYT· 2026-10-16T23:35Z.changeset/23914-hono-body-refusal.md. ItsCheck Changeseton63282466e(job 117244722801) refuses any change to a pending changeset a PR did not add (the finding: random changeset filenames collide silently across parallel agents — a round overwrote a sibling PR'sminorchangeset and every gate stayed green #17712 guard). For a deliberate correction it stays red until a person confirms. The seat cannot confirm it, and ruling A did not read that guard first.23914file is restored byte-for-byte from the merge base.createHonoAppentry's statement that a body which does not declare JSON is read as before.carrier:the release owner, atchangeset versiontime).(narrowing)review runs on the head that carries ruling B.Generated by Claude Code
objectstack-fleet commentedon Oct 16, 2026
os-dev-report
{
"issue": 24042,
"status": "done",
"branch": "claude/issue-24042-hono-undeclared-body",
"pr": "#24071",
"session": "session_018t6a5rvqPRvEDMCVVW9kYT (subagent; the parent PM's session). Patch round on the same claim (6225935648), following seat ruling 6226633450 (A) and then the coordinator's reversal to B.",
"premise_still_valid": true,
"summary": "Patch round for the open question; the code is unchanged. Under ruling A, commit 6328246 deleted the stale bullet (:25) from
.changeset/23914-hono-body-refusal.mdand the 24042 sentence that pointed at it. Check Changeset failed on that head: the #17712 guard refuses any change to a pending changeset this PR did not add. Under ruling B, commit c71a087 puts back.changeset/23914-hono-body-refusal.mdbyte for byte from the merge base b1d5569 (blob f1c571b0cc5c on both sides;git diff b1d5569d9 -- .changeset/23914-hono-body-refusal.mdis empty; the two other 23914 changesets were never touched). It also puts back the 24042 changeset's sentence 'This replaces the earlier createHonoApp entry's statement that a body that does not declare JSON is read as before.' Head c71a087 therefore has the same tree as f0c5d3b (47da01c4218d), and the PR's net diff is the same 4 files.","files_changed": [
".changeset/23914-hono-body-refusal.md (edited in 6328246, restored byte for byte in c71a087; not in the net diff)",
".changeset/24042-hono-undeclared-body-refusal.md (one sentence dropped in 6328246 and put back in c71a087; net content as at f0c5d3b)"
],
"tests": "No code changed this round. The tree of c71a087 equals the tree of f0c5d3b (git rev-parse of both trees: 47da01c4218d8a324917b4ecf7fbc461f4a0f06b; git diff f0c5d3b HEAD prints 0 bytes), so round 1's test and ablation readings describe this head byte for byte. pnpm changeset status: exit 0, minor for @objectstack/hono among the pending set.",
"gates": "Head c71a087, every exit code captured before any pipe. First, pnpm turbo run build --filter='!@objectstack/docs' --concurrency=2 under os-verify-lock: VERDICT command-exit 0, 75 tasks, all cached. dispatch-gates --commands --repo objectstack-ai/objectstack, with no paths, on 6328246 and again on c71a087: 64 commands each time, identical to round 1's list (0 diff lines). The derivation over the code paths has not changed, so round 1's 64 readings stand. dispatch-gates --commands for the one new path, .changeset/23914-hono-body-refusal.md: 20 commands, all among the 64. On 6328246, 18 of them exited 0 and node scripts/check-empty-changeset.mjs --base origin/main exited 1: '.changeset/23914-hono-body-refusal.md exists on the merge base and was not added by this PR' (#17712). That matches CI's Check Changeset failure on 6328246, and that head is superseded. On c71a087 all 20 exited 0, including check-empty-changeset --base origin/main ('No changeset from the merge base modified or deleted by this diff (#17712)'), check-adr-0087-registration --base origin/main, check-changeset-no-major --base origin/main, check:changeset-gate-self-tests, check:nul-bytes, check:published-files, check:pm-changeset-deadline-census and check-comment-mask-corpus (9368 files, 0 disagree, 113s). For --ran I used one record: the 20 re-run on c71a087 plus the other 44 from f0c5d3b, which has the identical tree. Result: '64 derived, 64 run, 0 NOT-MEASURED, 0 UNRUN' (exit 0). The derivation flags 2 stale tooling files on origin/main 8133cc7 (scripts/cross-package-test-inputs.mjs and scripts/check-position-name-fold-loaders.mjs, both from #24028). The first adds ledger entries for cloud-connection and service-package only; CI reads the merged copies. CI on f0c5d3b, the same tree: Build Core, Check Changeset, Lint & Repo Gates, Lint · ESLint, Lint · PM dispatch-gates, TypeScript Type Check and Governed Surface Queue Guard all success. Test Core 1/6 to 6/6 were cancelled, superseded by the next push. CI on 6328246: Check Changeset failed (the #17712 guard). CI on c71a087, read once at 23:46Z: 22 runs so far, 19 in progress, 1 queued (Check Changeset and Governed Surface Queue Guard among them), 1 success, 1 skipped; nothing has concluded red.",
"mcp_calls": "0",
"api_writes": "1 relay stroke this round: POST /repos/objectstack-ai/objectstack/dispatches, executed as objectstack-fleet[bot] as POST /repos//issues/24042/comments (this os-dev-report). Plus 2 git pushes of the branch, 6328246 and c71a087, both fast-forward with no force (not REST). There was no PR-body write (see deviations). Reads: gh api GET of comment 6226633450 and of the check-runs of f0c5d3b, 6328246 and c71a087.",
"deviations": [
"PR body NOT edited. The coordinator asked for one PR-body write that replaces the open-question paragraph. .claude/agents/os-dev.md says the dev writes the PR body exactly once, at pr_create, never PATCHes it, and names any later change in the report for the seat to write; that file also says it wins over dispatch words when the two conflict. So I am naming the conflict instead of choosing a side silently. For the seat to apply: in PR #24071's Acceptance notes, replace the bullet that begins 'The earlier
@objectstack/honochangeset for #23914 now says one false thing.' (it ends '(see the report).') with: "Seat ruling B (supersedes 6226633450): the pending.changeset/23914-hono-body-refusal.mdbullet 'A body that does not declare JSON is read as before …' is superseded by this PR's changeset; it is left in place because the #17712 guard gates any edit of another PR's pending changeset on a person's confirmation. carrier: the release owner, atchangeset versiontime — drop that bullet from the compiled entry."","Ruling A was carried out (6328246, pushed) before ruling B arrived. Its edit is fully undone in c71a087 by restoring from the merge base and from f0c5d3b, not by a rebase or a force-push. The branch history keeps both commits.",
"origin/main moved to 8133cc7. git merge-tree HEAD origin/main exits 0, so nothing was merged this round. In the earlier round I did not merge either.",
"The worktree was re-created on the existing branch after a fetch (local branch == origin branch == f0c5d3b; the path ../objectstack-issue-24042 was absent) and pnpm install --frozen-lockfile exited 0. After the push, node_modules was removed and git worktree remove (without --force) exited 0."
],
"open_questions": [],
"out_of_scope_findings": [
"carrier: the release owner, at
changeset versiontime · per seat ruling B, not filed:.changeset/23914-hono-body-refusal.md's bullet 'A body that does not declare JSON is read as before: parsed when it is JSON, {} when it is not.' is false once PR #24071 lands. The #17712 guard keeps this PR from editing it. The 24042 changeset states the correction, and the bullet should be dropped from the compiled @objectstack/hono entry."]
}
Generated by Claude Code
objectstack-fleet commentedon Oct 17, 2026
ACCEPTed: PR #24071 at
c71a087e64·domain:cliseat 2 ·os-tesla· sessionsession_018t6a5rvqPRvEDMCVVW9kYT· 2026-10-17T00:13Z · holder of claim6225935648.6227173354on PR fix(hono)!: createHonoApp reads a dispatched body by plugin-hono-server's rule, so a text/plain or undeclared body is refused when a domain reads it #24071. Every check on the head is green or a roster skip, and landing is armed.CONTRACT_REVIEW_TIER,6227110262, PASS on this head.6226633450(A), replaced by6226688716(B). The pending23914bullet is left for the release owner.objectstack-ai/cloud's callers of the hosted door. That repository is not readable by this account.Generated by Claude Code
objectstack-fleet commentedon Oct 17, 2026
Landed: PR #24071 →
76d9dca5fa(#24042,Fixes) ·domain:cliseat 2 ·os-tesla· sessionsession_018t6a5rvqPRvEDMCVVW9kYT· 2026-10-17T00:31Zmerged: true, merge commit76d9dca5fa, merged 2026-10-17T00:30Z through the merge queue (enqueued 2026-10-17T00:13Z)origin/main76d9dca5fais an ancestor oforigin/main: 4 files, +396 / −122, as reviewed atc71a087e6.packages/adapters/hono/src/index.tscarriesdeclaresBody(1 hit)gh-readonly-queue/main/*pr-24071*head remains6226633450(A) and6226688716(B, replaces A);CONTRACT_REVIEW_TIERPASS6227110262; ACCEPT6227173354; card pointer6227183957.createHonoAppreads a dispatched body byplugin-hono-server's rule, media type by media type. A JSON body sent astext/plain, or any other undeclared body, is refused400 INVALID_REQUESTwhen the domain reads it, instead of being parsed or reaching it as{}. Forms are parsed from a clone. The two transports answer Malformed JSON request body is silently parsed as {}: a truncated POST /data/:object/query answers 200 with the whole table, and a truncated PATCH answers 200 with an empty update #23914's step 4 alike.objectstack-ai/cloud's callers of the hosted door are NOT MEASURED; the carrier is cloud's.objectstack-shabump.23914changeset bullet is for the release owner atchangeset version.pm:dispatchedis removed in the stroke after this comment.Generated by Claude Code