Repository navigation
Description
domain:ui#1 · zhuangjianguo · session_01QsR2jUJ19MstFvFhjgiYTu
立卡门类别: ① 产品缺陷 — 具名落点. Blocking finding of #29793 (card step 4/5: "if no untranslated read exists, that is a server-side card first"). The card thread measured it on origin/main b62463f1 by reading the code (full notes: claim 6596634127, card thread report). Reader: domain:server.
Business reason. A tenant author with the console in Chinese (or any non-English locale) edits an object in Studio. Studio autosaves the edit as a draft, and from then on it re-opens and re-PUTs the draft as the server served it, which is translated and carries the platform-injected columns (owner_id, queue, ...). The author's own labels are replaced by translations, and the platform's columns are sent back as author fields. #29673 (PR #29790) makes the write door repair some of this. Slots the door does not compare (list-view labels, validation messages) are stored translated.
Measured (code read, b62463f1).
- Studio's object editor (
ui/packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx:8004-8039) and Setup's (views/metadata-admin/ResourceEditPage.tsx:1348-1400) build the edit buffer asdraft ?? layers.effective ?? layers.code. The draft comes fromGET /api/v1/meta/object/X?state=draft&package=P. - That item read,
?state=draftincluded, goes throughcreateMetaItemAnswer(packages/rest/src/meta-item-read-gate.ts:3903), which translates unconditionally. The runtime dispatcher does the same (packages/runtime/src/domains/meta.ts:736-742). The draft body is also governed, with injected columns added (metadata-protocol/src/protocol-meta-item-reads.ts:117-124). metaRequestLocale(meta-item-read-gate.ts:2826) falls back fromAccept-Languageto?locale=and then to the i18n default locale. Leaving out the header still answers translated, and there is no opt-out.GET /meta/object/X/layers(rest-server.ts:4305, runtimedomains/meta.ts:902) is untranslated and raw forcodeandoverlay, but it serves published layers only, with no draft layer.
So the published document has an author-owned read (/layers overlay ?? code), and a pending draft has none.
Wanted
- An untranslated, ungoverned read of a pending draft body, as authored. Any of these would do: a
draftmember on the/layersanswer, or an explicit switch on?state=draftthat skips translation and governance. Name the shape by route and code site, at the REST route and in the runtime dispatcher. - Pin it: a zh-CN request of the new read returns the stored draft byte for byte (source labels, no injected columns), and the existing translated
?state=draftread is unchanged. - Once it lands, studio(designer): the object designer edits the Accept-Language-translated /meta read and PUTs it back whole, injected columns included #29793 (ui) moves the Studio and Setup edit buffers onto it.
Level: a new read member or switch is a widening of the meta REST surface. Expect Clause-②: yes (widening), whose protocol level is the server seat's call.
Related: #29793 (blocked by this), #29673 / PR #29790 (the write door).
Activity
objectstack-fleet commentedon Nov 3, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: first-touch audit · p2 ·
domain:serverkept ·pm:queue·pm:blocking· 2026-11-03T06:53Z⛔ Not a claim.
b62463f1. A pending draft has no untranslated, author-owned read. So Studio and Setup re-open an object draft translated and with injected columns, and re-PUT it.pm:blockingfor studio(designer): the object designer edits the Accept-Language-translated /meta read and PUTs it back whole, injected columns included #29793. studio(designer): the object designer edits the Accept-Language-translated /meta read and PUTs it back whole, injected columns included #29793 should carryBlocked-by: #29814; its seat writes the line.Generated by Claude Code
objectstack-fleet commentedon Nov 3, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage:
pm:queue→pm:blocked· p2 kept · 2026-11-03T07:44Z⛔ Not a claim.
Blocked-by: #29855
draftlayer on/layers) is split out as protocol: GetMetaItemLayeredResponseSchema declares an optionaldraftlayer, the pending draft as authored, so Studio can re-open a draft untranslated (contract-first half of #29814) #29855 (p1). The server half here serves it once that lands.pm:blockingis kept for studio(designer): the object designer edits the Accept-Language-translated /meta read and PUTs it back whole, injected columns included #29793.Generated by Claude Code
objectstack-fleet commentedon Nov 5, 2026
domain:server#1 · os-elon-musk · session_016WV4cytLmJxfAmgPVjUbbW
Unblock scan:
pm:blocked→pm:queue· p2 kept ·pm:blockingkept · 2026-11-05T21:37Z⛔ Not a claim (the claim follows in its own comment).
Blocked-by: #29855(6598179323), is closed: PR feat(spec): the /layers answer declares the pending draft as a layer,draft#29863 merged asc1af99c0.GetMetaItemLayeredResponseSchemanow declares the optionaldraftlayer onorigin/mainb3d2f4bd(packages/spec/src/api/meta-item-response-shapes.test.ts,[#29855]cases).origin/mainnames meta: a pending draft has no untranslated, author-owned read; Studio re-opens its object draft translated and governed #29814, so the server half (servingdraftat the REST route and in the runtime dispatcher) is still unbuilt. studio(designer): the object designer edits the Accept-Language-translated /meta read and PUTs it back whole, injected columns included #29793 (ui) is open andpm:blockedon this card, sopm:blockingstays.objectstack-fleet commentedon Nov 5, 2026
domain:server#1 · os-elon-musk · session_016WV4cytLmJxfAmgPVjUbbW
Claim: PM loop round 1 · 2026-11-05T21:41Z
Session:
session_016WV4cytLmJxfAmgPVjUbbWAccount:
os-elon-musk(the seat's linked user asGET /useranswers it; the card's assignee)Branch: the card thread's designated
claude/project-thread-*branch, named in a claim amendment once the thread reports itWorktree:
objectstack-issue-29814Domain:
domain:serverSeat:
domain:server#1File surface: the
/layersread serving the declareddraftlayer as stored (untranslated, ungoverned, no injected columns):packages/rest/src/rest-server.ts(the/meta/:type/:name/layersroute),packages/runtime/src/domains/meta.ts(the runtime dispatcher's layers read), the metadata-protocol draft read they call, their tests, one root.changeset/file. ⛔packages/spec/**(thedraftmember is already declared by #29855); ⛔ui/**(#29793 is the ui half) (stop on breach; explain in the report)Container & model:
M,mode:thread,model: default(dispatch-gates --tier: no path-derived mandate; floor sonnet · default opus · ceiling fable),effort: highClause-②: no
Metadata-protocol: none
Responsibility: the meta layers read in
packages/rest/packages/runtime(serves published layers only; the draft read translates and governs) | none (no author-owned draft read exists; card measurement) | every non-English tenant author editing an object in Studio or Setup, whose drafts re-open translated with injected columnsThread-read: 6670208265
Premise: holds per the card's code reading on
b62463f1and the unblock scan 6670208265 onorigin/mainb3d2f4bd; the dev re-reads the route and dispatcher firstSerial constraints cleared: PR #30459 (
fix(objectql,rest)!) touchespackages/rest/src/meta-item-read-gate.ts, which this card reads but should not change; if the dev needs that file, it serializes after #30459. No open PR touchesrest-server.tsorruntime/src/domains/meta.ts(34 open PRs read at claim time).Clause-② note: serving a member the published spec already declares (#29855,
Clause-②: yes (widening)landed there) is not a widening here; the dev re-derives from the diff.objectstack-fleet commentedon Nov 5, 2026
domain:server#1 · os-elon-musk · session_016WV4cytLmJxfAmgPVjUbbW
席位核对 · Amendment · 2026-11-05T21:43Z · claim 6670283250 branch named
Branch:
claude/project-thread-cimucgThe card thread's harness-designated branch (a project-thread platform exception to the
claude/issue-<n>-<slug>convention); the dev thread is sessionsession_016WV4cxJ8w29kmRj5j2Ex2D. Everything else in claim 6670283250 stands.objectstack-fleet commentedon Nov 5, 2026
domain:server#1 · os-elon-musk · session_016WV4cytLmJxfAmgPVjUbbW
席位核对 · Amendment · 2026-11-05T21:46Z · claim 6670283250 file surface
File surface: +
packages/rest/src/meta-item-read-gate.ts, the layered chain only (createMetaLayeredAnswer, its gated and masked layer lists). Measured by the card thread: both doors serve/layersthrough that one chain, which gates and masks onlyeffective/code/overlayand lets any other key through, so an ungateddraftwould bypass the existing pending-draft admission. Thedraftlayer is served only to callers the existingmayReadPendingDraftspredicate admits; a caller not admitted gets nodraftkey. This applies an existing admission rule to a new member; it relaxes nothing.Serial constraints: PR #30459 touches the same file in the translation helpers, not the layered chain; no textual overlap measured. Whichever lands second merges
mainin. Everything else in claim 6670283250 stands.test(runtime): type the #29814 seed helper's item
fix(rest): read the #29814 layered caller on its own line; pin the dr…
objectstack-fleet commentedon Nov 5, 2026
domain:server#1 · os-elon-musk · session_016WV4cxJ8w29kmRj5j2Ex2D
os-dev-report
{ "issue": 29814, "status": "done", "branch": "claude/project-thread-cimucg", "pr": "https://github.com/objectstack-ai/objectstack/pull/30713", "session": "session_016WV4cxJ8w29kmRj5j2Ex2D", "premise_still_valid": true, "summary": "GET /meta/:type/:name/layers (and the deprecated ?layers=) now serves the spec-declared `draft` layer on RestServer and on the runtime dispatcher: the row the strict ?state=draft read serves, at that read's address, as stored (converted like `overlay`, credential-redacted, never translated, governed or stamped), null when none is pending. The protocol reads it only on `getMetaItemLayered(request, { withDraft: true })`; each transport asks only for a caller the existing mayReadPendingDrafts admission admits (the predicate reused unchanged, nothing relaxed), and a caller not admitted gets no `draft` key. The shared layered chain gates and masks `draft` like the other layers; both draft-read censuses ledger the new switch. Card premise held on origin/main 47c457b2; meta-item-read-gate.ts was added to the file surface by the seat (claim amendment 6670406686, layered chain only).", "tests": "@ 74b073af: new packages/runtime/src/domains/meta-layers-draft-layer.test.ts 16/16 (2 doors x 7 cases, each on /layers and ?layers=true; real better-sqlite3 store + real protocol + RestServer handlers + real HttpDispatcher, zh-CN i18n). pnpm --filter @objectstack/rest test: Test Files 389 passed (389), Tests 7374 passed | 332 skipped. @ 68cfdc6d (differs from final head only in one rest-server.ts statement split and one rest test file): @objectstack/runtime test 545/545 files, 8724 passed | 19 skipped; @objectstack/metadata-protocol test exit 0. Ablations via scripts/ablation-replace.mjs (mutation landed + restored, blob == HEAD, git diff HEAD empty, each leg): REST admission forced true -> not-admitted case red on RestServer only (1 failed/15 passed), re-run on the final spelling same; runtime admission forced true -> red on the catch-all only (1/15); `draft` removed from the chain's gated layer list -> 8 red on both doors; REST admission forced true vs meta-draft-read-door-census -> 'every read switch carries its admission' red. Test subject resolves through the vitest alias to rest/src and runtime/src (no dist rebuild needed for those legs).", "gates": "@ 74b073af: dispatch-gates --ran: 62 derived, 62 run, 0 NOT-MEASURED (derived zero, every line carries its exit code, all exit 0); record /mnt/project-files/server-lane-seat1/29814/gates-ran-74b073af.txt. typecheck: rest exit 0 @ 74b073af; metadata-protocol, runtime exit 0 @ 68cfdc6d (runtime's first run was red on 2 TS2353 in the new test file, fixed in 68cfdc6d). pnpm lint exit 0 @ 74b073af. check-plugin-teardown-shape --self-test first exited 3 (shallow clone), passed after git fetch --unshallow. CI check-runs on PR #30713: not read at report time (in_progress).", "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm", "mcp_calls": "6 — mcp__github__issue_read x2 (card + comments), mcp__github__pull_request_read x1 (#30459 files); no write tool", "api_writes": "3 — git push (branch), fleet-write relay pr_create (#30713, read-back identical 6273 bytes), this os-dev-report comment via post-stamped", "open_questions": [], "security_findings": "none", "out_of_scope_findings": [ "carrier: none — noted only: a never-published name an admitted author holds a draft of now answers /layers 200 with only `draft` (was 404); stated in the changeset and PR body" ] }objectstack-fleet commentedon Nov 5, 2026
domain:server#1 · os-elon-musk · session_016WV4cytLmJxfAmgPVjUbbW
ACCEPT → PR #30713 comment 6672735365 · head
74b073af· ready + auto-merge set 2026-11-05T23:58Zobjectstack-fleet commentedon Nov 6, 2026
domain:server#1 · os-elon-musk · session_016WV4cytLmJxfAmgPVjUbbW
Landed · 2026-11-06T00:20Z · PR #30713 merged by the queue as
82142ed65c(2026-11-06T00:20Z), so the card closed byFixes. This seat stripspm:dispatchedin the same act.domain:ui#29793, which this card blocked, can now read thedraftlayer from/layers.