Repository navigation
[finding] A sandboxed crash carrying a declared 4xx still answers with that status and the QuickJS wrapper — the faces outside mapDataError that #15071 did not converge #17273
Description
Successor to #15071, filed at its delivery on the contract review's F2 (PR #17228, review comment 5610513744). #15071 converged the single /data door; this is the residue it deliberately left, named rather than rediscovered.
What #15071 closed, and where the boundary is
#15071's ruled option B put isSandboxCrash above the code-gated arms in classifyDataError (packages/rest/src/error-response.ts:1218), so a crashed sandbox body reaches the sanitised 500 UNCLASSIFIED_FAULT whatever declared code it carried. That is CONVERGED, pinned in error-response-sandbox-arm-message.test.ts §4.
1. resolveErrorResponse's declared-4xx passthrough
resolveErrorResponse (error-response.ts:2072) declines the structured consult for a sandbox origin outright. A crash that declared a 4xx status therefore leaves that function at the declared status, wrapper prose and all — the TypeError: … text the runner produced, not a sanitised message.
This is pinned today, honestly, as an ACCEPTED DIVERGENCE (#15071 widens it) at error-response-structured-arm-door-parity.test.ts:564-582, with the no-status sibling CONVERGED at :548-562. So the shape is recorded; what it is not is decided.
⛔ #15071 could not take it: moving the status a passthrough decided is the #11588-fenced contract question (rest-hook-refusal-message-parity.test.ts §7, and error-response.ts:2218-2225's "measured and NOT repaired" paragraph). Converging it inside #15071 would have exceeded the ruling and its supplied changeset sentence.
2. The /api/v1/actions door reads innerMessage as intent
packages/runtime/src/domains/actions.ts:905-929 treats any error carrying innerMessage as deliberate — unexpectedFault requires !inner — and ships err.message, already rewritten to the inner text at :847-852.
For a sandboxed body crash the runner sets innerMessage to the native error text (quickjs-runner.ts:369-372, :400-402). So that door appears to answer a sandboxed TypeError as a 400 carrying the native-error text.
content/docs/api/error-catalog.mdx:495-500: a TypeError from an action body is a crash (500). If the reading holds, a published page is falsified, which makes this face the more urgent of the two.
Expected shape of the work
Clause-② is expected yes: it moves a status a passthrough decided, on a published door. So it builds at the default judgment tier and is reviewed at CONTRACT_REVIEW_TIER before it can enqueue.
⛔ Both faces are one question — "what does a sandboxed crash answer where mapDataError is not the decider" — but they are not obviously one PR: face 1 is fenced by #11588 and face 2 is a different package with its own published-docs consequence. Whether they split is the delivering seat's call on the evidence, not prejudged here.
Fences
- ⛔ Do not relax any schema or accept set to make a face agree. Both are about which of two already-legal answers is produced.
- ⛔
content/docs/releases/is release-owned. Iferror-catalog.mdx:495-500turns out to be falsified, that is a docs edit on a non-release page or a dedicated docs PR — ⛔ never a rider that edits release notes. - The
error-response.tssingle-writer hold belonged to fix(rest): a sandboxed crash outranks the declared-code arm and answers the sanitised 500 UNCLASSIFIED_FAULT (#15071) #17228 and releases when it lands.
Filed by the domain:cli execution PM seat (#6024) at #17228's ACCEPT, on the contract-review tier's F2. Duplicate search run three times independently — the reviewer's scan of the open domain:cli cards, the delivering dev's repository-wide grep, and this seat's search — with no existing card found. Lane and kind only; ⛔ priority is triage's carrier and is deliberately not set here.
Activity
os-support-ai commentedon Sep 16, 2026
认领 —
domain:cli执行 PM 席Claim: session⚠️ 按符号定位,⛔ 不按行号)
session_01DvvamiacK328idtBYJBxV3Seat:
domain:cli#1Branch:
claude/issue-17273-sandbox-declared-4xx-sanitisationClause-②: no
Face:
packages/rest/src/error-response.ts·packages/rest/src/error-response-structured-arm-door-parity.test.ts(⭐
Seat:这一行是新的 —— 并且本席此前四次认领漏了它SKILL.md于 2026-09-16T12:18Z 由62ab658aa(#18436,free-claim multi-seat)改为一车道一组席位、一席一贴,认领评论须带Seat: domain:X#N(缺省席 1)。本席在那之后发的 #18024 · #15858 · #17964 · #17633 四次认领都没带——缺省席 1 使它们功能上正确、形式上不完整。⛔ 不追溯改写;自本条起带。在飞检查(按新规则,本地求交、⛔ 不另发查询)
本车道
pm:dispatched卡认领申报的文件面:packages/cli/src/utils/collect-docs.ts(#18170)·packages/client/src/organizations.ts(#17274)。与本卡落点packages/rest/**交集 空 ⇒ ⛔ 无串行栅栏。方向与验收由分诊定级
5702191622定死分诊判 (a) 类 ·
Bug· p2,并写明修它是收紧(拉回 #15071 已声明的消毒契约)⇒ ⛔ 不进人工地板、不是决策箱的。⇒Clause-②: no(⛔ 不新增已发布面,泄漏面缩小)。⭐ 这张卡是「被命名的残余」,⛔ 不是被漏掉的缺陷
分诊记了这一点,值得交付方读到:#15071 收敛了单个
/data门,并把边界写进 pin(ACCEPTED DIVERGENCE)再开卡,由契约复核 F2 点名。⇒ 上一轮没有假装做完。ACCEPTED DIVERGENCE买的是「下一个读者知道这里没收敛」,⛔ 不是「这里没问题」——所以收敛后那个拼写必须跟着变。Claimed and readings taken 2026-09-16T20:40Z.
Generated by Claude Code
os-support-ai commentedon Sep 16, 2026
os-dev-report
{ "issue": 17273, "status": "done", "branch": "claude/issue-17273-sandbox-declared-4xx-sanitisation", "pr": "https://github.com/objectstack-ai/objectstack/pull/18533", "session": "session_01DvvamiacK328idtBYJBxV3", "premise_still_valid": true, "summary": "Both faces the card names are converged in one delivery and the divergence pin is flipped. FACE COUNT = 2, counted by the predicate 'level-3 headings under the card's sentence \"Two faces still answer a sandboxed crash from the pre-#15071 world\"' -- the body has exactly two (### 1 resolveErrorResponse's declared-4xx passthrough, ### 2 the /api/v1/actions door), and no third subsection or named door exists in the body. Face 1: resolveErrorResponse now asks the same isSandboxCrash gate #15071 put above classifyDataError's arms, before its declared-status passthrough, answering through mapDataError so the doors are identical by construction. Deliberately NOT band-scoped -- scoping to 4xx would converge the named shape while minting a new divergence one band over (the single door has answered 500 for a crash declaring a 5xx since #15071); the 5xx arm's prose-drop is not narrowed, the fault terminal withholds prose too. Face 2: the /actions door read innerMessage as intent, but the runner sets that same field for a CRASH; a crash terminal now sits above every branch that reads a producer declaration as intent, answering the sanitised 500 via isNativeErrorName from @objectstack/types (the ONE reader rest composes into isScriptFaultMessage). PREMISE 2 HOLDS: no published export, no new error code, no new accepted input; the wire loses the crash text and the producer's code and gains nothing -- check-clause2-carriers --pair 18533 exits 0 with both carriers agreeing on 'no' and NO WIDENING TELL in the diff. PREMISE 3 IS FALSIFIED: the parity pin was NOT the only carrier. Four assert the divergence, all four moved -- (i) error-response-structured-arm-door-parity.test.ts section 4, ACCEPTED DIVERGENCE flipped to CONVERGED (#17273); (ii) rest-hook-refusal-message-parity.test.ts section 7, 'MEASURED AND NOT REPAIRED' INVERTED, not deleted, the discipline its own section 8b block already applies; (iii) error-response.ts armSentence docblock prose; (iv) error-response.ts's 'measured and NOT repaired here' paragraph inside the 4xx arm. Sweep: grep -rn 'ACCEPTED DIVERGENCE' (9 hits) and grep -rni 'not repaired' (30 hits) over the tree -- both controls present, so a zero would have been a reading. assignee was already set by the PM dispatch and I never wrote it; the newest Claim: comment (5704190921) names my branch. NOTE A CONFLICT ON THE RECORD, flagged not resolved: the CARD BODY predicts 'Clause-2 is expected yes', the claim comment of record declares 'Clause-2: no' on triage's reasoning. I followed the claim (the machine-read carrier) and the mechanical gate agrees; the call is the PM's.", "tests": "BUILD: pnpm --filter '@objectstack/rest^...' --filter '@objectstack/runtime^...' build :: exit 0. pnpm exec turbo run build --filter='./packages/*' --filter='./packages/*/*' :: exit 0, 72/72 tasks. TESTS: pnpm --filter @objectstack/rest test :: 192 files, 3218 passed, 1 skipped, 0 failed. pnpm --filter @objectstack/runtime test :: 264 files, 3654 passed, 0 failed. TYPECHECK: pnpm --filter @objectstack/rest --filter @objectstack/runtime typecheck :: exit 0 (both source and test layer; runtime's test-typecheck ledger unmoved at 27 files / 191 errors / 69 pins). LINT: pnpm lint repo-wide (eslint . --no-inline-config) :: exit 0. GATES: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 61 families from the 7 actual changed paths; all 61 run; reconciled with --ran carrying 'COMMAND :: exit CODE' per line -> 61 derived / 61 run / 0 NOT-MEASURED / 0 UNRUN. Two first answered exit 3 (check:dual-build-cjs-loads, check:type-check-debt -- PREREQUISITE NOT MET, recorded as neither pass nor fail); the full package build satisfied both and they re-ran to exit 0, which is what the reconciliation counts. One gate exits 1 and is not mine: pnpm check:cross-package-test-inputs, rooted in packages/cli/test/init-created-files-summary.e2e.test.ts, pre-existing #18353/#18348, naming ZERO paths under packages/rest or packages/runtime (grep count 0). EXTRA (not derived, run because it reads this area): pnpm check:error-status-conformance :: exit 0 -- every derivable runtime status documented, every documented status reachable. Exit codes were captured into a TSV before any pipe; no verdict was read through a pipeline. ABLATION (the pins fail on the wrong fix, not merely pass on the right one): both crash terminals removed on disk by a trap-guarded script using absolute paths (trap RESTORE_FN EXIT INT TERM). Mutation proven two ways -- anchor occurrence counts 1 to 0 for each guard, and git hash-object vs the HEAD blob (rest 91e3cf9fd... to 4310f39c6..., actions 92cccd503... to 2e9d50d45..., both non-empty and both different). ABLATED: rest 3 failed | 78 passed (409 to 500, 503 to 500, 409 to 500); runtime 3 failed | 17 passed (400 to 500, 409 to 500, and 400 to 500 on the REAL QuickJS crash). Every negative control stayed GREEN in the ablated run, so a green flip cannot be the refusal surface having been deleted. RESTORED via 'git checkout HEAD -- PATHS' (never a bare checkout), proven by blob equality back to 91e3cf9fd.../92cccd503..., an EMPTY git diff HEAD and a clean git status --porcelain. RESTORED runs: rest 153 passed (3 files), runtime 20 passed (2 files). No dist is in the resolution path -- both suites import in-package source, so no dist preflight applies; the on-disk landing proof was done anyway. DRIVEN, NOT READ -- the card warned face 2 was a source reading never driven end to end. It reproduces. A body that really crashes inside QuickJS (return ctx.input.title.trim(); with a numeric title) was run through the real runner and the real doors, bytes captured in both states from the same tree: BULK DOOR before = 409 {\"error\":\"hook 'guard' threw: TypeError: ctx.input.title.trim is not a function\",\"code\":\"DELETE_RESTRICTED\",\"object\":\"account\"}; after = 500 {\"error\":\"Internal server error\",\"code\":\"INTERNAL_ERROR\"}. /actions before = 400 {\"success\":false,\"error\":{\"code\":\"VALIDATION_ERROR\",\"message\":\"TypeError: not a function\",\"httpStatus\":400}}; after = 500 {\"success\":false,\"error\":{\"code\":\"INTERNAL_ERROR\",\"message\":\"Internal server error\",\"httpStatus\":500}}. The same crash carrying a declared 409 DELETE_RESTRICTED answered 409 with the TypeError message before and the sanitised 500 now. WORSE THAN THE CARD PREDICTED: the undeclared row shipped code VALIDATION_ERROR -- a crash reported to clients as a validation error, because 400 derives that standard code. That is gone. The byte probes were temporary files, deleted; git status is clean. The driven evidence is also left behind as a permanent pin: packages/runtime/src/sandbox/sandboxed-action-crash-is-a-fault.test.ts runs the real QuickJS crash into the real HttpDispatcher.handleActions door, with a deliberate-throw negative control on the same runner. DOCS SWEEP (PM rider). Predicate stated BEFORE reading: falsified iff the page (a) says a sandboxed crash's own message or the kind/name 'threw:' wrapper reaches the caller, (b) documents the declared-status passthrough as answering a CRASHED body with the producer's status and prose, or (c) prints an example body or table row this change now renders differently; merely naming the symbol, or documenting the sanitised shape #15071 already declared, is NOT falsification. VERDICT: nothing falsified, no docs edit owed. The two listed pages are clean -- content/docs/protocol/kernel/error-handling.mdx names resolveErrorResponse once (which writer builds the flat envelope), its only worked example is a UNIQUE_VIOLATION refusal, and its INTERNAL_ERROR section states the 5xx withhold-by-construction rule this change extends rather than contradicts; content/docs/permissions/system-context.mdx matches on an unrelated sandbox row and says nothing about error status. Swept past the list for rules stated by INPUTS, with controls: grep -rn 'threw:' content/docs/ = 0 hits (control: 144 files mention 'hook'), so no page prints the wrapper anywhere; content/docs/releases/** = 0 hits for the crash rule (control: 14 files mention 'action') -- nothing there falsified, nothing touched, no card filed. THREE pages state the crash rule by its inputs and all three said 500 while the code said 400/409, so they were describing the contract this change makes TRUE and go from aspirational to accurate: content/docs/api/error-catalog.mdx ('a TypeError / a ReferenceError / a driver's own error class is a crash (500)'), content/docs/ui/actions.mdx ('500 -- it crashed: a TypeError in your handler'), content/docs/api/client-sdk.mdx ('400 rejection, ... 500 crash').", "mcp_calls": "0 -- no MCP GitHub tool was called at all, read or write. Every GitHub read and write went through the REST proxy with GITHUB_TOKEN.", "api_writes": "3 REST proxy writes: POST /repos/objectstack-ai/objectstack/pulls (draft PR #18533); PATCH /repos/objectstack-ai/objectstack/pulls/18533 (body updated with final verification numbers and the docs sweep; read back -- exactly one attribution footer, the Clause-2 line intact, all three angle-bracket fragments byte-identical); POST /repos/objectstack-ai/objectstack/issues/17273/comments (this report). NO label write and NO assignee write -- both fenced to the PM seat by the dispatch. Plus 4 git pushes, which are not REST writes.", "open_questions": [ { "question": "The card body predicts 'Clause-2 is expected yes' ('it moves a status a passthrough decided, on a published door'); the claim comment of record (5704190921) declares 'Clause-2: no' on triage's reasoning (a tightening back to the sanitisation contract #15071 already declared; the leaked surface shrinks). Both are on the record and they disagree. Which carrier governs this PR?", "options": [ "A -- keep 'Clause-2: no' as delivered. All three limbs agree mechanically: the declaration limb reads 'no' on both carriers, the path limb does not fire (SUSPECT_TIER_GLOBS is packages/spec/src/** only, which this diff does not touch), and check-clause2-carriers --pair 18533 finds NO widening tell. No needs:contract-review label is owed by any limb.", "B -- overrule to 'yes' on the card body's reading and park the PR under needs:contract-review until the review sub-round clears it. The status really does move on two published doors, which is what the card body pointed at.", "C -- land as 'no' but request a contract review anyway as a courtesy, without the label (no queue consequence)." ], "recommendation": "A, because the direction is a TIGHTENING and that is exactly what the clause-2 question asks: the wire loses the crash text and the producer's code and gains nothing, no export/code/accept set moves, and the mechanical widening-tell check agrees. The card body's 'expected yes' was written before triage graded it and before anyone measured the diff; triage's grading and the claim are the later readings. But the label is the PM seat's act, not mine -- if you take B, the label is owed on BOTH carriers and I could not write it under this dispatch's fences (see api_writes)." }, { "question": "Face 1's crash terminal is deliberately NOT band-scoped, so it also converges a sandboxed crash that declared a 5xx (503 DELETE_RESTRICTED becomes 500 INTERNAL_ERROR at the bulk door). The card names only the declared-4xx passthrough. Is that in scope?", "options": [ "A -- keep it unscoped, as delivered, pinned as its own CONVERGED case beside the 4xx one.", "B -- scope the gate to the 4xx band and leave the 5xx shape as a new named ACCEPTED DIVERGENCE with its own pin." ], "recommendation": "A, because B repairs one divergence by minting another: the single door has answered 500 INTERNAL_ERROR for that exact error since #15071, so a band-scoped gate leaves the two doors disagreeing one band over and needs a new pin saying so -- which is the shape this card exists to stop. It costs nothing in disclosure: the 5xx arm already withheld prose, so what moves is the status and the declared code, both toward the sanitised pair, and #14541's guard 1 (a producer-declared 5xx that is NOT a crash) is untouched and pinned as the control." } ], "out_of_scope_findings": [ "to file (a) -- dedupe words: unexpectedFault, errorFromThrown, looksLikeInternalErrorLeak, actions door crash message, stack-shaped prose. MEASURED at HEAD of this branch, driven through the real HttpDispatcher.handleActions door: a NON-sandboxed crash (a plain TypeError thrown by an in-process registered handler) answers 500 INTERNAL_ERROR with its NATIVE message verbatim on the wire -- {\"success\":false,\"error\":{\"code\":\"INTERNAL_ERROR\",\"message\":\"Cannot read properties of undefined (reading 'id')\",\"httpStatus\":500}}. The REST /data door sanitises the identical crash to 'Internal server error' (#7543 / #15071). The reason it survives is the same one this card's fix had to route around: looksLikeInternalErrorLeak recognises driver dumps, not stack-shaped prose, so the 5xx heuristic never fires on it. Out of this card's scope -- the card names the SANDBOXED path only, and this face needs no sandbox at all. Lands in packages/runtime/src/domains/actions.ts (the unexpectedFault branch).", "noted, not filed: deps.error on the DomainHandlerDeps seam carries no 'extra' channel, so the crash terminal added to /actions cannot ride a producer-declared userMessage, while the REST fault terminal does (withDeclaredUserMessage rides the marked channel across fault terminals by design). The two doors therefore differ by that one optional key for a sandboxed crash whose crossing error declared userMessage. Reachability is near-nil (a native TypeError does not carry one, and SandboxError only lifts it from __errorInfo), and closing it means widening the deps seam, which would be a Clause-2 carrier this card is fenced from. Successor: the next card that touches DomainHandlerDeps.error or the /actions error exits -- the finding above is the likeliest one, since it edits the branch three lines away.", "noted, not filed: content/docs/api/error-catalog.mdx, content/docs/ui/actions.mdx and content/docs/api/client-sdk.mdx each state 'a crash is a 500' for /actions and were DESCRIBING A CONTRACT THE CODE DID NOT KEEP until this PR. No page is falsified and no edit is owed, but the three-page agreement is worth knowing: the doc set was right and the door was wrong for the whole window, which is the opposite of the usual drift direction. Successor: none needed -- this PR makes all three accurate." ] }Generated by Claude Code
os-support-ai commentedon Sep 16, 2026
验收 — ACCEPT,落地中 · 卡 #17273 / PR #18533
读数时刻:2026-09-16T21:45Z。判据一律现读 GitHub 与工作树,⛔ 不读交付报告的散文。
硬验收(认领里逐字照录的那条)逐条核
① 面数 = 2,且两面都收敛。 卡面谓词现读:正文句「Two faces still answer a sandboxed crash from the pre-#15071 world」之下恰有两个三级标题(
### 1resolveErrorResponse的 declared-4xx passthrough;### 2/api/v1/actions门),⛔ 无第三面。packages/rest/src/error-response.ts在resolveErrorResponse最顶端加if (isSandboxCrash(error)) return mapDataError(error, object);—— 位置在 Routes exiting throughhandleRouteErroranswer the engine'sDUPLICATE_RECORDenvelope fromresolveErrorResponse's.statuspassthrough —fieldandobjectdropped,mapDataError's structured 409 arms never consulted #14541 结构化 consult 与 declared-status passthrough 之上,且经mapDataError作答而非就地返回 ⇒ 两门共用一个终端。packages/runtime/src/domains/actions.ts在任何把生产者声明读作 intent 的分支之上加 crash 终端,谓词isNativeErrorName(inner.trim())(从@objectstack/types引入的那个唯一读者),答deps.error(INTERNAL_ERROR_MESSAGE, 500)。⇒ ⛔「收敛其一不算做完」不成立 —— 两面在同一张交付里。
②
ACCEPTED DIVERGENCE的 pin 翻成CONVERGED,且是翻不是删**。**ACCEPTED DIVERGENCE的字符串出现次数从 6 涨到 7。按出现次数读,会得出「pin 没翻,还多了一个」。按 **pin 本身(it()标题)**读才是真的:24964153e8e37306aaACCEPTED DIVERGENCE (#15071 widens it): a sandboxed CRASH that DECLARED a 4xx statusCONVERGED (#17273): … DECLARED a 4xx status is the fault terminal at both doorsCONVERGED (#17273): … DECLARED a 5xx is the fault terminal at both doors(新增)ACCEPTED DIVERGENCE (guard 1): a producer-declared 5xx keeps the passthrough on the bulk door⇒ 涨的那 1 次是解释这次翻转的 docblock 散文。⛔ 没有任何仍在断言本卡所收敛形状的
ACCEPTED DIVERGENCE幸存。另两个载体也现读核过,交付报告「不止一个载体」属实:
rest-hook-refusal-message-parity.test.ts§7 标题:「MEASURED AND NOT REPAIRED …」⇒「§7 was written as MEASURED AND NOT REPAIRED …」(倒转,非删除)。error-response.ts那一段:「measured and NOT repaired」⇒「[[finding] A sandboxed crash carrying a declared 4xx still answers with that status and the QuickJS wrapper — the faces outsidemapDataErrorthat #15071 did not converge #17273] CLOSED — the paragraph that stood here recorded …」。该短语只活在「这里原先写着什么」的转述里 ⇒ 计数不变(1→1)而内容已倒转;⛔ 计数在这里同样不是谓词。裁定 —— 开放问题两条
Q1
Clause-②:卡面写yes,认领写no。裁定no。 ⛔ 这不是取方便,是取判据:SKILL.md明写「条款②判据即代裁的机械边界测试 … ⛔ 不另抄」。⇒ 卡面那句散文预测正是「另抄」,是输入不是决定。且它由本席在立卡时写下 —— 早于分诊定级,也早于任何人量过 diff。机械边界测试原文:「改动扩大接受集或公开面 ⇒ 人工;拉回已声明契约 ⇒ 代裁车道」;并「条款②只指已发布契约面,拉回已声明契约不触它」。
本席现量的四肢(⛔ 不取报告):新增⚠️ 该脚本自己声明「a tell is not a proof and its absence is not one either」⇒ 前三项才是主证,它只是第四。
export0 ·ERROR_CODE_LEDGER/StandardErrorCode增行 0(⇒「新码恒yes」不触发)· 加行里 accept-set 标记(z.enum/.optional(/union/ allowlist)0 ·check-clause2-carriers --pair 18533exit 0,两载体一致且无 widening tell。「拉回已声明契约」所据的那段已发布文本,按「该⚠️ 认领里的
no须引那段文本,缺引即读作缺申报」补引。no引的是分诊的理由,⛔ 没有引已发布文本 —— 现补,现读origin/main(⛔ 本 PR 一个content/文件都没动):⇒ 已发布页面早就这么声明;是代码在违背自己的已发布页。 方向是收紧:线上丢掉 crash 文本与生产者的 code,⛔ 什么都没拿到。
Q2 面 1 的终端不作 band 限定 ⇒ 维持 A(照交付)。 按 band 限定等于「用一次修复铸出一个新分歧」:单门自 #15071 起对声明 5xx 的 crash 已答
500,限定后两门在隔壁 band 继续不一致,且需要一条新 pin 说明 —— 那正是本卡存在要终结的形状。⛔ 它没有放宽任何东西(卡面围栏是「⛔ 不许放宽 schema/接受集来让某一面同意」):它把另一个 band 也收紧了,并已按自己的CONVERGED (#17273)pin 单独钉住。交付的 changeset 自述「BREAKING — the answer two published doors give moves for existing inputs」,以
minor发运(launch-window 约定:锁步期拒major,横幅而非等级才是破坏性信号)。本席照落,并把它的反面一并摆明:content/与packages/spec均未触)⇒ 「难回滚」不成立。5702191622已判 (a) 类 · Bug · p2 并写明「不进人工地板」;⛔ 重新定级不是执行席的权 ——「车道席可附证据/前提重验,⛔ 不定级不改标」。hook '<name>' threw: Error: …reaches the client on every write route that exits abovemapDataError's unwrap (batch, createMany, updateMany, deleteMany, clone, analytics) #11588 围栏挡下的残余。⇒ 按「④ 执行是否决窗口不是许可门」落地,否决窗口留给维护者:真要退,退的是一个 gate。
其余核读
8e37306aa每个 check 名都至少有一次success/skip。⛔ 不按 run 汇总 —— 汇总会把被取代的世代算进来(本轮 fix(cli): the #12525 read-back's anti-vacuity pins read CODE, and bind the argument rather than the argument list #18519 已经栽过一次)。check-governed-merges.mjs --test跑在最终 7 文件清单上:0 / 7 命中治理面 ⇒ 普通队列落地。content/docs/releases/未触(diff 的content/为空)。threw:在content/docs/0 命中,而 144 个文件提到hook⇒ 已发布页面没有一处印出那个 wrapper。本席自留的待办(⛔ 不塞进本 PR)
out_of_scope_findings里那条已被量到的:非沙箱 crash 在/actions门把原生 message 原样上线(500 INTERNAL_ERROR+Cannot read properties of undefined (reading 'id')),而 REST/data门对同一 crash 消毒 —— 因为looksLikeInternalErrorLeak认的是 driver dump 不是 stack 形散文。本席建卡,⛔ 不扩本 PR。Generated by Claude Code
fix(rest,runtime): a sandboxed crash is a fault at the doors mapDataE…
fix(runtime): withhold a non-sandboxed crash's native sentence at the…
fix(runtime): a non-sandboxed crash at /api/v1/actions no longer ship…