Repository navigation
studio: console noise from expected misses — ?state=draft probes 404, /layers 404, /ai/usage 501 polled without AI #11799
Description
Activity
- addedbugSomething isn't workingSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatobjectui ui stream: fix lands on the published library or apps — objectui execution seatarea:studioChanging a running app without code — authoring, publish, docs and the portalChanging a running app without code — authoring, publish, docs and the portal
on Oct 7, 2026 objectstack-fleet commented
on Oct 7, 2026 ContributorAuthorMore actionsPath: write metadata — Studio's console reads clean | 缺项 | P3
Triage: first grade,
bug·priority:p3·domain:ui·area:studio·pm:queue. Direction: the client stops asking questions it can answer itselfTriage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-07T17:22Z. ⛔ Not a claim, ⛔ not a dispatch.Triage: lands in the draft probe (
data-objectstack/src/metadata-client.ts), the/layersread (views/metadata-admin/LayeredDiff.tsx) andlayout/AiUsageIndicator.tsx⇒domain:ui; rationale: a Studio or console surface in objectui. Filed from the browser QA pass of 2026-10-07 (objectstack879bd38c, objectui179f6fe9); paths re-read on objectuimain9990f9e122.- Why p3: expected misses show as 404 and 501 errors in the console. Noise, not a fault.
- Direction:
- decide whether a draft exists from the
/meta/_draftslist Studio already reads - skip
/layersfor an unsaved item - do not poll
/ai/usagewhen discovery says AI is off - ⛔ The body's server-side alternative (200 with null) changes a REST answer and is not in this card
- decide whether a draft exists from the
Clause-②: no. Patch changeset in objectui.
objectstack-fleet commented
on Oct 8, 2026 ContributorAuthorMore actionsDeferred, not parked:
domain:uiseat 2 (session_01MgfduSkFrfM3eorB3UGfAU) · 2026-10-08T01:12Z. ⛔ Not a claim. The card stayspm:queue.Why it is not dispatched this round. Two of this card's three fixes sit where this seat's in-flight objectui#11797 (claim
6050079539) is working:- deciding draft existence from the
/meta/_draftslist; - the
?state=draftprobe inpackages/data-objectstack/src/metadata-client.ts.
objectui#11797 makes identical reads share one in-flight promise, inside
metadata-client.tsandpreview/usePendingDrafts.ts. The fold-or-serial answer is serial. The two do not share a defect shape: objectui#11797 merges duplicate reads, and this card stops reads that should not be made.Known pits for whoever picks it up:
- After objectui#11797 lands, the
_draftslist is a shared read. Answering "does a draft exist" from it must use the same shared read, not a second fetch. - Writes clear that read. A draft created a moment ago must not be reported as absent.
- The other two fixes do not touch objectui#11797's files and could ride the same PR:
- skip
/layersfor an unsaved item (views/metadata-admin/LayeredDiff.tsx); - no
/ai/usagepoll when discovery says AI is off (layout/AiUsageIndicator.tsx).
- skip
- Triage
6043104063rules out the server-side alternative (200 with null). - Release condition: objectui#11797 merged.
Generated by Claude Code
- deciding draft existence from the
objectstack-fleet commented
on Oct 8, 2026 ContributorAuthorMore actionsClaim: PM loop round 8
Session:session_01DrKzdPdyLLBW3qpZ4vtk7z
Account:huangyiirene
Branch:claude/issue-11799-studio-expected-misses
Worktree:objectui-issue-11799
Domain:domain:ui
Seat:domain:ui#1
File surface (line numbers on8962734). The dev measures each call site and names the file before editing it.- Draft existence: where Studio probes
GET /meta/:type/:name?state=draftto learn whether a draft exists. That is the caller, orpackages/data-objectstack/src/metadata-client.ts's draft read (stateabout:330). It answers from the/meta/_draftslist Studio already reads, through the shared read objectui#11797 made (packages/app-shell/src/preview/usePendingDrafts.ts/ the client's in-flight sharing), never a second fetch. A write still clears that read. /layers:packages/app-shell/src/views/metadata-admin/LayeredDiff.tsx. Noclient.layered(...)for an item that has never been saved./ai/usage:packages/app-shell/src/layout/AiUsageIndicator.tsxand itsuseAiUsagehook. No request and no poll while discovery says AI is off.- The tests beside these, and
.changeset/11799-*.md.
⛔ Not on it:
- The server-side alternative (a 200 with null). Triage
6043104063rules it out. - Seat 3's objectui#11786
StudioDesignSurface.tsxregions:useDraftAutoSave, the Data and Automations draft saves, anddoPublish. - Seat 2's objectui#11781 / studio(automations): Notify recipients are only editable as Advanced JSON, create_record field values are free text, and New automation does not ask for a trigger #11788 / studio(interfaces): the nav rail draws a separator item as an unlabeled disabled row and ignores badge #11791 regions.
- If the draft probe's caller sits in one of those regions, the dev stops and reports.
packages/components/src/ui/**,packages/i18n/**, and any REST answer.
Any file outside this list: the dev reports it before opening the PR (stop on breach; explain in the report).
Container & model:M,mode:subagent,model: opus(dispatch-gates --tier --repo objectstack-ai/objectuiover these paths: no path-derived mandate; default tier)
Clause-②: no
Responsibility:objectui app-shell and data-objectstack: Studio probes expected misses as errors (a ?state=draft 404 per item, /layers 404 for unsaved items, /ai/usage 501 polled with AI off), filling the console with red lines that hide real failures | the platform path is right: the client already holds the answers (the _drafts list, the item's saved state, discovery) | every developer debugging Studio, measured by the filer in the 2026-10-07 QA pass
Thread-read: 6050119975
Serial constraints cleared:noneblocking.- The deferral's release condition (seat 2,
6050119975: "objectui#11797 merged") holds. objectui#11797 closedcompletedat 03:38Z, landing as6d8bf0c(identical reads share one in-flight request). - Its known pits are carried into the order: answer from the shared
_draftsread, never a second fetch, and make sure a fresh draft is not reported absent. area:studioin flight: seat 2's objectui#11781, studio(interfaces): the nav rail draws a separator item as an unlabeled disabled row and ignores badge #11791 and studio(api panel): the example request body types every field as "string" and lists 8 of 23 fields #11803; seat 3's objectui#11786; this seat's objectui#11847 and studio(interfaces): create flows for list views, dashboards, reports and pages in a writable package (ADR-0084), after #11790's nav item types #11823 (PR objectui#11868, in the merge queue).- Their claims were read 2026-10-08T03:47Z. None holds
LayeredDiff.tsx,AiUsageIndicator.tsxor the draft probe. - objectui#11797's
metadata-client.tsandusePendingDrafts.tswork has landed.
- Their claims were read 2026-10-08T03:47Z. None holds
- Open objectui PRs: objectui#11868, fix(app-shell): the form designer's drag live region names labels and places, not ids (objectui#11802) #11869, fix(app-shell,console): zh names a Studio pillar by its tab label; settings label probes stop logging missing-translation warnings (objectui#11801) #11870, fix(app-shell): notify recipients render online and are picked; record field values pick their field; New automation asks for the trigger (objectui#11788) #11875, fix(app-shell): Studio holds an incomplete field or step as an unsaved edit with a hint, and Publish refuses while one is held (objectui#11786) #11876, fix(app-shell): Studio's API tab shows an example create body the server would accept (objectui#11803) #11877 and fix(app-shell,fields): valid package-sheet header markup; select field controlled from its first render (objectui#11804) #11879 touch none of these files. Read 2026-10-08T03:47Z.
- This seat: dispatch is parallel,
batch3 working devs, on the maintainer's word in this session's chat (「改为并行派发,batch 3」, 「继续派发」).- objectui#11804's dev has finished (PR objectui#11879), which freed this slot.
- Working with this card: objectui#11813's dev and objectui#11847's.
Why
Clause-②: no: the client stops asking questions it can answer itself. No export, prop,@object-ui/typesmember, accepted input or REST answer changes.- Draft existence: where Studio probes
objectstack-fleet commented
on Oct 8, 2026 ContributorAuthorMore actionsos-dev-report
{
"issue": 11799,
"status": "done",
"branch": "claude/issue-11799-studio-expected-misses",
"pr": "#11892",
"session": "session_01DrKzdPdyLLBW3qpZ4vtk7z",
"premise_still_valid": true,
"summary": "Legs 1 and 3 landed whole. Leg 2 landed for the Interfaces and Automations pillars. The Data pillar keeps its /layers read of a never-published object, so the PR first line is "Refs #11799 (...)" and the card stays open (open_questions[0]). Leg 1: MetadataClient.getDraft() (data-objectstack) reads the drafts ledger first, through listDrafts(), the shared in-flight read objectui#11797 made, and sends ?state=draft only when the ledger lists the name. An unreadable ledger (403/501/network) is unknown, so the item read is sent. sendWrite drops the pending ledger read when a write lands, so a draft saved a moment ago is found (pinned). The ledger is read UNFILTERED: the strict draft read accepts either type spelling, and with a package the package-less row too, so a type- or package-filtered ledger could report absent for a draft the probe serves. This is a measured deviation from the suggested "for the package". Leg 2: in StudioDesignSurface.tsx, the Interfaces leaf load and the Automations flow load read the draft first and /layers only for an item with no pending draft, the one case they use the baseline. The Interfaces app load reads no /layers for an app the same-run published list does not hold. Leg 3: AiUsageIndicator reads /ai/usage only while useAgents at its own apiBase lists an agent. That catalog is the useAiSurfaceEnabled signal, not discovery services.ai, per that module's ruling. H1 confirmed (four Studio loads Promise.all layered+getDraft; a 404 reads as null). H2 falsified: LayeredDiff.tsx fetches nothing; the /layers reads are the same four loads. H3 partly falsified: no interval; the 501 repeats per dock mount, because StudioChatDock renders while the catalog loads.",
"tests": "GATES on local HEAD b34f4f5 (after merging origin/main bfca7ec, merge commit b34f4f5; read via git rev-parse --short HEAD inside each locked run): [1] turbo run build --filter=@object-ui/app-shell^... --concurrency=2 -> exit 0 -> "Tasks: 28 successful, 28 total" + "os-verify-lock: VERDICT command-exit 0". [2] pnpm --filter @object-ui/data-objectstack type-check && pnpm --filter @object-ui/app-shell type-check (tsc --noEmit && tsc -p tsconfig.test.json) -> exit 0 -> "VERDICT command-exit 0" (data-objectstack tsc --listFiles counts both touched test files: 2). [3] vitest run --maxWorkers=2 packages/data-objectstack/ + 282 app-shell files (all of studio-design/, layout/, hooks/; every app-shell test naming getDraft, new MetadataClient(, useAiUsage or AiUsageIndicator; viewCacheInvalidation.guard.test.tsx, the only .guard.test. in either package) -> exit 0 -> "Test Files 364 passed (364) / Tests 3084 passed (3084)" + "VERDICT command-exit 0". [4] pnpm check:control-bytes -> 0 -> "check-control-bytes: OK"; check:new-line-citations -> 0 -> "VERDICT new-cross-file-line-citations: 0 new citation(s)"; check:changeset-claims -> 0 -> "No pending changeset names a file this change touches."; check:pending-changeset-literals -> 0 -> "No test source names a pending changeset."; check:metadata-write-doors -> 0 -> "OK 17 metadata write door(s) derived"; check:vi-mock-specifiers / check:vi-mock-inherit / check:vi-mock-override-shape -> 0 -> "OK"; check:test-path-roots -> 0 -> "OK"; check:phantom-deps -> 0; check:unreferenced-sources -> 0 -> "OK"; node scripts/check-changeset-presence.mjs -> 0 -> "8 source file(s) of 2 released package(s) changed, and this change declares 1 changeset(s)"; node scripts/check-changeset-no-major.mjs -> 0. Derived additions beyond the order list: the three vi-mock gates (new vi.mock sites), test-path-roots, phantom-deps (new @object-ui/plugin-chatbot import in app-shell, already a dependency), unreferenced-sources, changeset presence and no-major. NOT MEASURED locally, declared to CI: the other ~839 app-shell test files and pnpm lint. CI at report time on b34f4f5: 23 check-runs completed with 0 failures, 19 in_progress. PINS (new): data-objectstack metadata-client.draftLedger-11799.test.ts (10 tests); app-shell StudioDesignSurface.expectedMisses-11799.test.tsx (6); layout/tests/AiUsageIndicator.aiOff-11799.test.tsx (3). Updated: metadata-client.get-envelope.test.ts A10 (its fake server now answers the ledger) and AiUsageIndicator.test.tsx (useAgents stubbed to one agent: those cases are AI-on viewers). REVERSE CHECKS (one-time, not committed; scratchpad script; each leg's file reverted with git checkout BASE -- path, blob hash checked equal to the base blob, pins run, restored with git checkout HEAD -- path, hash checked equal to HEAD, git diff HEAD empty; trap restore on EXIT/INT/TERM): leg1 metadata-client.ts on a473d14 -> 16 failed / 11 passed of 27, predicted direction (e.g. received ["/api/v1/meta/page/home?state=draft"] where the ledger was expected; Studio pins received a ?state=draft 404 for the saved leaf and the saved object); leg2 StudioDesignSurface.tsx on a473d14 -> 4 failed / 2 passed of 6 (/layers read for the unsaved leaf, ledger-only app and unsaved flow; "expected 2 to be 1" for /layers of the reopened leaf with a draft; Data row and published-app control stayed green as predicted); leg3 AiUsageIndicator.tsx re-run on bee4e1b -> 2 failed / 1 passed of 3 (empty catalog: "expected 2 to be +0" usage reads; the loading case fails at its precondition because base never reads the catalog; control green). NETWORK READING (dev-only vitest+happy-dom harness, never committed: real pillars over a real MetadataClient on an in-memory server answering like the framework, 404 ?state=draft without draft, 404 /layers without a layer, 501 /ai/* except /ai/agents empty-list). Requests / 404-501: Interfaces 9/3 -> 9/0; Data 6/2 -> 7/1 (the kept /layers of the draft-only object); Automations 7/2 -> 7/0; Studio AI dock, open edition 2/1 -> 1/0. Total 24/8 -> 24/1. DEVIATIONS: (a) no real-browser reading: no runnable backend here (/home/user/objectstack has no node_modules, and the order forbids touching it), so the order's network-recorded alternative was used; (b) leg 1 lives in the client getDraft (a claim-listed location), not in each caller; (c) the ledger is unfiltered, not package-scoped (reason in summary); (d) the /layers change is in StudioDesignSurface.tsx loads (the claim-named draft caller, same Promise.all lines), not LayeredDiff.tsx (it fetches nothing); (e) leg 2 is partial (Data pillar), hence the Refs line; (f) commits carry the model-free trailer pair per AGENTS.md rather than the harness reminder's model-named Co-Authored-By; the merge commit was amended locally before its first push to carry the pair; (g) reverse checks used whole-file reverts proved by blob hashes, not ablation-replace.mjs (objectstack-only); (h) the first app-shell union attempt was cut by my own 580 s timeout before any output, then re-run in the background under the lock and awaited with tail --pid. FILES_CHANGED: .changeset/11799-studio-expected-misses.md (new, patch for @object-ui/data-objectstack and @object-ui/app-shell); packages/data-objectstack/src/metadata-client.ts; packages/data-objectstack/src/metadata-client.get-envelope.test.ts; packages/data-objectstack/src/metadata-client.draftLedger-11799.test.ts (new); packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx (Interfaces app load, Interfaces leaf load and Automations flow load effects only; none of the fenced regions); packages/app-shell/src/views/studio-design/StudioDesignSurface.expectedMisses-11799.test.tsx (new); packages/app-shell/src/layout/AiUsageIndicator.tsx; packages/app-shell/src/layout/tests/AiUsageIndicator.test.tsx; packages/app-shell/src/layout/tests/AiUsageIndicator.aiOff-11799.test.tsx (new).",
"mcp_calls": "0 - no MCP GitHub tool was called",
"api_writes": "2 - (1) pr_create through scripts/pm/fleet-write/dispatch.mjs: POST /repos/objectstack-ai/objectstack/dispatches (relay run 37730134750), executed as POST /repos/objectstack-ai/objectui/pulls, giving draft PR #11892, read-back 11622 bytes identical; (2) this os-dev-report comment through scripts/pm/post-stamped.mjs: POST /repos//issues/11799/comments. Plus git push of the branch (not REST). Zero label or assignee writes; the labeler workflow applied data-adapter, tests and "package: app-shell" itself.",
"open_questions": [
{
"question": "The Data pillar still reads GET /meta/object/NAME/layers for a never-published object (one 404 per open). Its answer sets hasBaseline (no records table yet) and the published field projection, both used even with a draft. Which route closes it?",
"options": [
"A - accept that read as the pillar's published-definition question. The seat edits the PR first line to "Fixes #11799" and adds an Acceptance note, so the card closes on landing.",
"B - take "never saved" from the rail's package-scoped published list. Cost: the rail re-reads on the refresh pulse while the load re-runs on publishNonce, so a just-published object can read as unpublished (records grid hidden) until the next load.",
"C - re-read a fresh published list (or a single-item read) in the object load. Cost: one more 200 request on every object open to save one 404 on draft-only opens."
],
"recommendation": "A. The read is the question itself, not a by-product. B trades console noise for a wrong "not published" state, and C adds a request to every open. Decided by the seat; if A, the PR body edit is: replace the first line with "Fixes #11799" and append the Data-pillar note to Acceptance notes."
}
],
"out_of_scope_findings": [
"carrier: objectui#11799 (stays open via Refs) - noted, not filed: other /layers reads of a draft-only item outside the claimed surface still 404: PackageOwdOverviewPanel.tsx (load and save reads per object), ObjectListViewInspector.tsx (landed with objectui#11823; reads /layers for a list view that newListViewItem says may not exist yet), and ResourceEditPage.tsx, EmbeddedItemEditor.tsx and PermissionMatrixEditor.tsx in Setup. Their ?state=draft 404s are gone through leg 1. No public-door measurement was taken, so no class-a reach. Dedupe words: layers 404 draft-only, list view layers 404, OWD overview layers.",
"carrier: 承接者:无 - noted, not filed (read-only inference, no reach measured): usePendingDrafts.ts readDraftsPayload clears its pending _drafts reads only on the publish pulse, not on a draft save, so a topbar refresh asked right after a save can join a ledger read sent before it and show a stale pending count. The client's sendWrite clears only the client's own map, keyed by a different transport. Dedupe words: pending drafts count stale after save, readDraftsPayload clear on save."
]
}
Generated by Claude Code
objectstack-fleet commented
on Oct 8, 2026 ContributorAuthorMore actionsReview: ACCEPT as a partial landing — PR objectui#11892 (head
b34f4f5) · the open question ruled Adomain:uiseat 1 ·session_01DrKzdPdyLLBW3qpZ4vtk7z· reviewed against the PR's file list and diff hunks,git merge-tree, its check runs and the dev's report6052669636, read 2026-10-08T05:04Z.- Shape: draft →
main. The first line isRefs #11799 (…), a partial landing, andClause-②: nostarts a later line. - Scope: 9 files, +765/−19, inside claim
6051768139's surface.data-objectstack/src/metadata-client.ts(+39):getDraft()reads the drafts ledger first.StudioDesignSurface.tsx(+44/−19): only three load effects, the Interfaces app load (about:2871), the Interfaces leaf load (about:3048) and the Automations flow load (about:5637).- Seat 3's objectui#11786 regions are untouched:
useDraftAutoSave(:329),doPublish(:1270) and bothdoSaves (:4491,:5688).
- Seat 3's objectui#11786 regions are untouched:
layout/AiUsageIndicator.tsx(+15).- Pins, and one changeset (
@object-ui/data-objectstackand@object-ui/app-shellpatch).
- Clause-② re-read: no export or signature changes.
MetadataClient.getDraft()keeps its signature and its answer,nullfor "no draft"; it stops sending the probe it can answer from the ledger.noholds. - Leg 1 (draft existence), landed:
getDraft()reads the ledger throughlistDrafts(), objectui#11797's shared in-flight read, and sends?state=draftonly when the ledger lists the name.- An unreadable ledger (403, 501 or network) counts as unknown, so the item read is sent.
sendWritedrops the pending ledger read on a write, so a just-saved draft is found (pinned). That honours seat 2's two known pits from6050119975.- Deviation (c), accepted: the ledger is read unfiltered, because the strict draft read accepts either type spelling and the package-less row. A filtered ledger could report a served draft as absent.
- Leg 2 (
/layersfor an unsaved item), landed for Interfaces and Automations:- H2 falsified:
LayeredDiff.tsxfetches nothing. The reads are those loads. - The Data pillar keeps its read; see the ruling below.
- H2 falsified:
- Leg 3 (
/ai/usagewith AI off), landed: the indicator reads usage only whileuseAgentslists an agent. That is theuseAiSurfaceEnabledsignal, per that module's ruling.- H3 partly falsified: there is no interval. The 501 repeated per dock mount.
- Open question (the Data pillar's
/layersread of a never-published object) ruled A: keep the read.- Its answer is the pillar's published-definition question: it sets
hasBaseline(no records table yet) and the published field projection. - B would read a just-published object as unpublished until the next load.
- C adds a request to every object open to save one 404 on draft-only opens.
- Its answer is the pillar's published-definition question: it sets
- The PR stays
Refs, notFixes.- The dev measured other
/layersreads of draft-only items outside this claim's surface:PackageOwdOverviewPanel.tsx,ObjectListViewInspector.tsx(objectui#11823's step 1), and Setup'sResourceEditPage.tsx,EmbeddedItemEditor.tsxandPermissionMatrixEditor.tsx. They are the same direction ("skip/layersfor an unsaved item"). - On merge, the card returns to
pm:queuewith aRelease:line naming them, with the Data pillar's read named as kept by ruling.
- The dev measured other
- Tests:
-
Local union on
b34f4f5(withmainbfca7ecmerged in): 364 files and 3084 tests green acrossdata-objectstackand app-shell'sstudio-design/,layout/andhooks/, plus every test naming the touched symbols and the view-cache guard. Both type-checks and the derivedcheck:*set are green. -
Reverse check, per leg:
- leg 1: 16 failed and 11 passed;
- leg 2: 4 failed and 2 passed, with the Data pillar and published-app controls green as predicted;
- leg 3: 2 failed and 1 passed.
Each restore was proven by blob hash.
-
Network reading (an in-memory server answering like the framework): Interfaces went from 3 misses to 0, Automations from 2 to 0, the AI dock from 1 to 0, and Data from 2 to 1 (the kept read). In total, 8 misses became 1 over the same 24 requests.
-
Deviation (a), accepted: there was no real-browser reading, because no runnable backend was available in-container.
-
- Overlap: an in-memory
git merge-treeis clean againstmainand against objectui#11890. - CI at
b34f4f5: converging, none red at this read. The PR is queued when every check completes. - Out-of-scope, noted, not filed (no reach measured):
usePendingDrafts.ts'sreadDraftsPayloadclears its pending_draftsreads only on the publish pulse, not on a save. So a topbar refresh right after a save can join a stale ledger read. - PR assignee: set by this seat to
huangyiirene.
Generated by Claude Code
- Shape: draft →
objectstack-fleet commented
on Oct 8, 2026 ContributorAuthorMore actionsLanded (partial): PR objectui#11892 →
main5dff027· card released topm:queueRelease:
session_01DrKzdPdyLLBW3qpZ4vtk7z(domain:uiseat 1, accounthuangyiirene) releases claim6051768139. Reason: a partial landing,Refs #11799, as accepted in6052694298's review, with the open question ruled A there. Next: back topm:queuewith the assignee cleared, for the remainder named below. Verified 2026-10-08T05:34Z.- Merged through the merge queue at 2026-10-08T05:33:20Z, after it was queued at 2026-10-08T05:17:33Z.
- CI on head
b34f4f5before queueing: 42 of 45 check runs passed, and the 3 skipped are the expected ones. check-governed-merges.mjs: not governed, +765/−19.
- CI on head
- Content check:
5dff027is one squash commit on parent5e446ab. It changes 9 files, +765/−19, the same as the PR.- 8 files are blob-identical to the reviewed head
b34f4f5. - The 9th,
StudioDesignSurface.tsx, differs only becausemainmoved under it: objectui#11891 (objectui#11843) and objectui#11884 landed in the same file. Its-U0patch-id matches (38d9b7df…). - The whole diff's
-U0patch-id matches too (522a3409…), against the PR's basebfca7ec.
- What landed:
- Draft existence:
getDraft()reads the drafts ledger first (throughlistDrafts()'s shared read) and sends?state=draftonly for a name the ledger lists. An unreadable ledger counts as unknown, so the item read is still sent. /layersfor an unsaved item: the Interfaces app and leaf loads and the Automations flow load skip it./ai/usagewith AI off: the indicator reads usage only whileuseAgentslists an agent.- Measured in-memory over the same 24 requests: 8 expected misses became 1, the Data pillar's read kept by ruling.
- Draft existence:
- The remainder, for the next claim. These are the same direction ("skip
/layersfor an item that was never saved"), measured by the dev outside this claim's surface:PackageOwdOverviewPanel.tsx;ObjectListViewInspector.tsx(objectui#11823's step 1 file);- Setup's
ResourceEditPage.tsx,EmbeddedItemEditor.tsxandPermissionMatrixEditor.tsx. - Kept by ruling, not part of the remainder: the Data pillar's
/layersread of a never-published object. Its answer is the pillar's published-definition question (hasBaselineand the published field projection). - A premise to re-check before the claim: the remainder's files sit in two areas (Studio and Setup). Check the area rule against the in-flight
area:studiocards when you claim it.
- Noted, not filed (no reach measured):
usePendingDrafts.ts'sreadDraftsPayloadclears its pending_draftsreads only on the publish pulse, not on a save. So a topbar refresh right after a save can join a stale ledger read. - Landing window: after 05:10Z, the objectui cards closed are objectui#11819 and objectui#11843 (seat 3's), objectui#11842 (this seat's, by objectui#11890) and objectui#11814 (seat 2's). This PR closes no card, by design.
Generated by Claude Code
- Merged through the merge queue at 2026-10-08T05:33:20Z, after it was queued at 2026-10-08T05:17:33Z.
15 remaining items
objectstack-fleet commented
on Oct 9, 2026 ContributorAuthorMore actionsUnlock: objectstack-ai/objectstack#22397 is answered (a), by design, and closed.
pm:blocked→pm:queue; p3 anddomain:uistandTriage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-09T02:58Z. ⛔ Not a claim, ⛔ not a dispatch.- The framework answer: objectstack keeps
/layersanswering404for a name with no stored layer, the author included (ADR-0045 §3, #20507). There is no contract change. The reasoning is on meta: the layered view answers the author of a draft-only item the same 404 as an absent name, so Studio can only learn "never published" from an error status objectstack#22397. - So the four remaining reads settle here, client-side, with no server change to wait for:
- the metadata edit page's first load;
- the embedded item editor's save read;
- the permission matrix's package-door re-read;
- the list-view inspector's read of a view that exists nowhere yet.
- For each read:
- Skip the layered read when the editor already knows the item is draft-only, since it read it as a draft.
- Otherwise, treat its
404as "never published" without an error state. The lock banner, overlay diff and reset verdict show their "no published version" form. - ⛔ Don't suppress errors in general.
- Pins: for each read, a draft-only item opens with no error state, and a published item still gets its layers.
- The
?state=draftprobes and the/ai/usagepolling on this card are unchanged by this answer.
- The framework answer: objectstack keeps
objectstack-fleet commented
on Oct 9, 2026 ContributorAuthorMore actionsClaim: PM loop round 3
Session:session_01CGZy1BGCjdN5cXqL9cnvB8
Account:os-support-ai
Branch:claude/issue-11799-layers-draft-only
Worktree:objectui-issue-11799
Domain:domain:ui
Seat:domain:ui#3
File surface (line numbers onmain6694abe7). This is the card's remainder after objectui#11892 and objectui#11928. It follows triage's unlock6073343714, which relays the framework answer (a) from objectstack-ai/objectstack#22397: skip the read where the editor already holds the item as a draft; otherwise read its404as "never published", with no error state. ⛔ Errors are not suppressed in general. This claim closes the card.packages/app-shell/src/views/metadata-admin/ResourceEditPage.tsx: the metadata edit page's first load (client.layeredat about:1051), and what the lock banner, overlay diff and reset verdict show for a draft-only item.packages/app-shell/src/views/metadata-admin/EmbeddedItemEditor.tsx: the save read (about:114).packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.tsx: the package door's re-read (readLayeredat about:543), which decides which other packages' rows survive (objectui#9420). objectui#11787's autosave has just landed in this file.packages/app-shell/src/views/studio-design/ObjectListViewInspector.tsx: the read of a view that exists nowhere yet (about:299).- The tests beside these, and
.changeset/11799-*.md.
⛔ Not on it:
- any server change, and
data-objectstack'sMetadataClient; - the Data pillar's
/layersread of a never-published object (kept by ruling in6052694298); - the reads objectui#11892 and objectui#11928 settled;
- the environment door's save and its post-save re-read;
- the embedded editor's publish-mode PUT of the parent's
effective; packages/components/src/ui/**andpackages/i18n/**.
Any file outside this list: the dev reports it before opening the PR (stop on breach; explain in the report).
Container & model:M,mode:subagent(an in-session subagent),model: opus(dispatch-gates --tier --repo objectstack-ai/objectuiover these paths: no path-derived mandate; default tier)
Clause-②: no
Responsibility:objectui app-shell: four layered reads still ask /layers for an item the author holds only as a draft, and read the 404 as an error | the platform path: GET /meta/:type/:name/layers answers absent (404) for a name with no stored layer, the author included, by design (ADR-0045 §3, objectstack-ai/objectstack#20507 and #22397) | every author who opens a never-published item in Setup or Studio
Thread-read: 6073343714
Serial constraints cleared:noneblocking.- objectui#11787 (
PermissionMatrixEditor.tsx): this seat's, landed as6694abe. - Seat 2's objectui#11865 slice o (
StudioDesignSurface.tsx): landed as5382a865. No file here is on it. - Open objectui PRs, read 2026-10-09T04:40Z: none touches these four files.
- In-flight claims, read 2026-10-09T04:40Z: seat 2's objectui#11865 (slice p:
ListView.tsx,ChatbotEnhanced.tsx) names none of them. - First-load budget: within the margin ruled in
6070754914.
Why
Clause-②: no: app-shell editor behaviour only. No prop, export, type or published pack key changes. Any of those is a stop: the dev reports it before opening the PR, and the seat amends this line.
Generated by Claude Code
objectstack-fleet commented
on Oct 9, 2026 ContributorAuthorMore actionsos-dev-report
{
"issue": 11799,
"status": "done",
"branch": "claude/issue-11799-layers-draft-only",
"pr": "#12026",
"session": "session_01CGZy1BGCjdN5cXqL9cnvB8",
"premise_still_valid": true,
"summary": "The four remaining reads of GET /meta/:type/:name/layers were measured on main 6694abe over the real editors and a real MetadataClient. The reads are: the metadata edit page's first load, the embedded item editor's save read, the permission matrix's package-door save re-read, and the list-view panel's read of a view that exists nowhere. None can be skipped with what its editor holds, and none reads the 404 as an error. MetadataClient.layered() already resolves a /layers 404 as an envelope with every layer null and never rejects on it, so a draft-only item already opens with no error state, while a 5xx still throws and shows its error. So the PR (draft #12026, Fixes #11799, Clause-② no) changes no executable code. It adds 12 pins (22 tests across the four files) that hold that reading: a draft-only item opens clean, a published item still gets its layers, and a 5xx still errors at every read. This takes the outcome triage's (a) answer on objectstack-ai/objectstack#22397 allows: accept the 404 as the never-published signal. The card's premise stands: these four reads still send /layers and the browser still logs its 404 line, which triage says neither repo controls. The claim's mechanism half, 'read the 404 as an error', is falsified by measurement. Per site: (1) the edit page's load sends its draft read in parallel, and a pending draft does not say the item was never published; the 404 form shows no error strip, no lock banner and no reset/delete control, and the Layers sheet shows overlay 'none' with the no-baseline diff. (2) The embedded editor holds only the item snapshot and the parent name, and the parent page's answer could reach it only through MetadataDetailDrawer and RelatedPanel, which are off-surface; opening sends no read. (3) The permission matrix's save re-read is objectui#9420's fresh read: the open-time published list can be stale and the first save after a load is unpinned, so skipping it would risk dropping other packages' rows; its 404 already saves over the draft's own slice. (4) The list view has no draft and no stored-view list in hand; its 404 leaves the buffer null with no failure, and the canvas seeds the view.",
"tests": "All local runs were on head d761384, with the sha printed inside the locked run. PINS: pnpm exec vitest run --maxWorkers=2 over ResourceEditPage.layersUnsaved-11799.test.tsx, EmbeddedItemEditor.layersRead-11799.test.tsx (new), PermissionMatrixEditor.layersUnsaved-11799.test.tsx and ObjectListViewInspector.layersUnsaved-11799.test.tsx gave 'Test Files 4 passed (4)', 'Tests 22 passed (22)', 'os-verify-lock: VERDICT command-exit 0'. Of those, 12 tests are new: 4 for the edit page's load, 3 for the embedded editor, 3 for the PME save re-read through the real client, and 2 for the list view; the other 10 are the existing objectui#11928 pins. BUILD+TYPECHECK: turbo run build --filter=@object-ui/app-shell^... --concurrency=2 ('Tasks: 28 successful, 28 total'), then pnpm --filter @object-ui/app-shell type-check (tsc --noEmit and tsc -p tsconfig.test.json) exited 0 with 'VERDICT command-exit 0'. tsc -p tsconfig.test.json --listFilesOnly lists all four touched test files out of 5268 entries. ESLINT: pnpm exec eslint --format json on the four files exited 0: 4 files, 0 errors, 0 warnings. This narrowed lint is a measurement: the population is the four changed files (the JSON count is 4, and none was ignored, since an ignored file would carry a warning); eslint.config.js has no parserOptions.project and no projectService, so linting is not type-aware; and nothing imports a test file, so no untouched file's verdict can move. pnpm lint is declared to CI. REVERSE CHECKS (one-time, not committed): objectstack's scripts/ablation-replace.mjs ran in WRAP mode under the lock on packages/data-objectstack/src/metadata-client.ts, which app-shell tests resolve to src through the vitest alias, so no dist leg is needed. Each mutation landed on disk: anchor x1 to x0 and the blob changed (R1 93ee19e0 to 1a1d138d; R2 93ee19e0 to a4fca296). Each restore was proven: the blob equals the HEAD blob 93ee19e0 and git diff HEAD is empty. R1 (the layered 404 arm throws: a 404 read as an error) gave 5 failed / 17 passed of 22, in the predicted direction. Red: the edit page's draft-only load plus the objectui#11928 SAVE and DISCARD pins, whose load fails first; the PME '+ New' save ('expected [] to have a length of 1': refused, no PUT); and the list view's exists-nowhere load ('error: Error: absent'). Green: every published and 5xx control, and the embedded editor's open, which sends no read. R2 (a 5xx resolves like the 404: errors suppressed) gave 4 failed / 18 passed of 22, exactly the four 5xx controls. The first R2 attempt was refused by the tool before anything ran (its replacement contained the anchor: 'anchor count moved 1 to 2'); that was a no-op, restored and proven, and it was re-run with a two-line anchor. The one-time measurement harnesses I used before writing the pins were deleted and never committed. No real-browser or live-server reading was taken: /home/user/objectstack has no node_modules, so there is no runnable backend. NOT MEASURED locally, declared to CI: the other app-shell suites, because no executable source changed and the four files are the whole affected population. CI at report time on d761384: 42 check runs, 24 completed (21 success, 3 skipped), 18 in_progress, 0 failed.",
"mcp_calls": "0 - no MCP GitHub tool was called",
"api_writes": "3 - (1) pr_create through scripts/pm/fleet-write/dispatch.mjs: POST /repos/objectstack-ai/objectstack/dispatches (relay run 37886859741), executed as POST /repos/objectstack-ai/objectui/pulls, giving draft PR #12026; the read-back was 8268 bytes sent, 8268 stored, identical. (2) The PR assignee through scripts/pm/label-write.mjs --repo objectstack-ai/objectui --issue 12026 --assign os-support-ai: POST /repos/objectstack-ai/objectstack/dispatches (relay run 37886920498), executed as the assignee add on objectui#12026; the read-back matched (assignee os-support-ai; labels 'tests' and 'package: app-shell' were set by labeler.yml, not by me). (3) This os-dev-report comment through scripts/pm/post-stamped.mjs: POST /repos//issues/11799/comments. Plus two git pushes of the branch, which are not REST: the empty probe and d761384. No ready, no auto-merge, no review request and no label write.",
"open_questions": [],
"out_of_scope_findings": [
"class: a · reach: UI save door (metadata edit page, Related drawer, 'Save into object'), with the console's own request measured as the wrong answer over the real MetadataClient on an in-memory server; the live server's answer is NOT MEASURED · evidence: for a draft-only parent object, EmbeddedItemEditor's save reads /layers (404, resolved as all-null), splices the item into an empty body, and sends PUT /api/v1/meta/object/sales_order with no query string (publish mode, no mode=draft) and the body {fields:{amount:{type:number,label:'Order amount'}}}, dropping name, label and every other field of the draft. The editor then shows 'Saved.'. The claim excludes this PUT ('the embedded editor's publish-mode PUT of the parent's effective'); seat 1 recorded it as a read-only inference in 6054754910, and this is the first measured probe. It is not pinned, so nothing in PR #12026 holds that body in place · dedupe words: embedded item editor publish mode stub parent, save into object draft-only parent, embedded field save empty body, EmbeddedItemEditor PUT effective",
"carrier: 承接者:无 · noted, not filed (observation, no contract cited, no reach beyond the measurement): the metadata edit page opens an empty editable form, with no error state, for a name that has neither a draft nor a layer (/layers 404, no ?state=draft since the ledger lists nothing). Only a 5xx shows 'Failed to load'. Recorded in PR #12026's Acceptance notes · dedupe words: edit page absent item empty form no error, metadata edit not found state"
],
"gates": [
{
"command": "pnpm exec vitest run --maxWorkers=2 (four pin files), under os-verify-lock",
"exit": 0,
"verdict": "Test Files 4 passed (4) / Tests 22 passed (22) / os-verify-lock: VERDICT command-exit 0"
},
{
"command": "pnpm exec turbo run build --filter=@object-ui/app-shell^... --concurrency=2 and pnpm --filter @object-ui/app-shell type-check, under os-verify-lock",
"exit": 0,
"verdict": "Tasks: 28 successful, 28 total / os-verify-lock: VERDICT command-exit 0"
},
{
"command": "pnpm exec eslint --format json (four touched files)",
"exit": 0,
"verdict": "4 files, 0 errors, 0 warnings"
},
{
"command": "pnpm check:control-bytes",
"exit": 0,
"verdict": "check-control-bytes: OK (scanned 8176 tracked text file(s); skipped 85 binary)."
},
{
"command": "pnpm check:test-path-roots",
"exit": 0,
"verdict": "check-test-path-roots: OK"
},
{
"command": "pnpm check:changeset-claims",
"exit": 0,
"verdict": "No pending changeset names a file this change touches."
},
{
"command": "pnpm check:pending-changeset-literals",
"exit": 0,
"verdict": "No test source names a pending changeset."
},
{
"command": "pnpm check:new-line-citations",
"exit": 0,
"verdict": "VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only"
},
{
"command": "pnpm check:vi-mock-specifiers",
"exit": 0,
"verdict": "check-vi-mock-specifiers: OK"
},
{
"command": "pnpm check:vi-mock-inherit",
"exit": 0,
"verdict": "check-vi-mock-inherit: OK"
},
{
"command": "pnpm check:vi-mock-override-shape",
"exit": 0,
"verdict": "check-vi-mock-override-shape: OK"
},
{
"command": "pnpm check:phantom-deps",
"exit": 0,
"verdict": "Every in-scope import is declared by the package that publishes it."
},
{
"command": "pnpm check:unreferenced-sources",
"exit": 0,
"verdict": "OK Every shipped source file in every covered package is reachable."
},
{
"command": "pnpm check:metadata-write-doors",
"exit": 0,
"verdict": "OK 17 metadata write door(s) derived"
},
{
"command": "pnpm check:handler-key-reads",
"exit": 0,
"verdict": "OK 152 arm(s), 184 registration(s)"
},
{
"command": "node scripts/check-changeset-presence.mjs",
"exit": 0,
"verdict": "4 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s): .changeset/11799-layers-draft-only.md. Every one of them has an EMPTY frontmatter"
},
{
"command": "node scripts/check-changeset-no-major.mjs",
"exit": 0,
"verdict": "No changeset declares amajorbump."
},
{
"command": "i18n gates and check:readme-exports",
"exit": null,
"verdict": "not applicable: no locale pack or export changed"
}
],
"deviations": [
"(a) No executable code change, so the changeset is empty-frontmatter (no release, tests only) instead of the dispatch's patch. A patch would release the fixed group for a test-only change; check-changeset-presence accepts the empty frontmatter as the declaration.",
"(b) Dispatch rule 'a 404 for an item the editor does not hold keeps its error state': at none of the four reads is there such an error state to keep, because the client resolves every /layers 404 as the empty envelope. So the 5xx is the error control pinned at every read (Zone 2 item 5's 'or a 5xx'), and no new error state was added: that would be new behaviour and a new message key.",
"(c) The claim's PermissionMatrixEditor pointer names readLayered in the load effect. The remainder read (objectui#9420, other packages' rows) is doSave's package-door re-read, and that is what is pinned. The load read was objectui#11928's and is unchanged.",
"(d) Zone 3 helper not written: the '404 means never published' judgment lives in MetadataClient.layered (data-objectstack, off-surface), so there is nothing in app-shell to factor.",
"(e) The reverse checks mutated packages/data-objectstack/src/metadata-client.ts, which is off-surface, temporarily and only through ablation-replace WRAP mode. Restore was proven and nothing was committed. The first R2 attempt was a refused no-op and was re-run.",
"(f) Commits carry the model-free trailer pair from objectui AGENTS.md (Claude-Session plus Co-authored-by: Claude), not the harness reminder's model-named Co-Authored-By. The PR body ends with the os-dev session-URL footer and the session URL in prose, not the harness's other footer form.",
"(g) No real-browser or live-server reading: there is no runnable backend in the container. Behaviour was measured over the real components and real MetadataClient on an in-memory server shaped like the framework (404 for /layers with no layer and for ?state=draft with no draft).",
"(h) Three existing 11799 pin files were extended rather than new ones added beside them. Their headers' 'Not covered' paragraphs for these reads were rewritten, and their in-memory servers gained a 5xx switch (and PUT handling for PME). The existing assertions are unchanged.",
"(i) The worktree was removed after the PR opened (node_modules first; the tree was clean and pushed)."
],
"files_changed": [
".changeset/11799-layers-draft-only.md (new, empty frontmatter)",
"packages/app-shell/src/views/metadata-admin/EmbeddedItemEditor.layersRead-11799.test.tsx (new)",
"packages/app-shell/src/views/metadata-admin/ResourceEditPage.layersUnsaved-11799.test.tsx",
"packages/app-shell/src/views/metadata-admin/PermissionMatrixEditor.layersUnsaved-11799.test.tsx",
"packages/app-shell/src/views/studio-design/ObjectListViewInspector.layersUnsaved-11799.test.tsx"
],
"line_budget": "not applicable (no skills/** surface)"
}
Generated by Claude Code
objectstack-fleet commented
on Oct 9, 2026 ContributorAuthorMore actionsACCEPT —
domain:uiseat 3,session_01CGZy1BGCjdN5cXqL9cnvB8, 2026-10-09T05:23Z. PR objectui#12026, headd7613848. It closes the card's remainder after objectui#11892 and objectui#11928.- PR shape:
- Draft against
main, based on6694abe7.git merge-treeagainstmain8f8f760fis clean. - First line
Fixes #11799, the body's only closing keyword.Clause-②: noat line start. - One commit, with the model-free trailer pair only. Assignee
os-support-ai, set with no refusal.
- Draft against
- Scope: 5 files, +431/−19, on the claim (
6074397332). No governed path and no executable source:- one new pin file,
EmbeddedItemEditor.layersRead-11799.test.tsx; - three extended pin files beside
ResourceEditPage,PermissionMatrixEditorandObjectListViewInspector(objectui#11928's), whose existing assertions are unchanged; - an empty-frontmatter changeset: tests only, no release. objectui already lands test-only fixes this way, for example
.changeset/11978-hooks-target-label-wait.md.
- one new pin file,
- The claim's mechanism half is falsified by measurement, and the seat accepts that.
- The claim expected these reads to treat
/layers's 404 as an error. Onmain,MetadataClient.layered()already resolves a 404 as an envelope with every layernull(packages/data-objectstack/src/metadata-client.ts:1464, read by the seat), and throws for any other failure. - So a draft-only item already opens with no error state at all four reads, and a 5xx still errors.
- None of the four can skip its read with what its editor holds:
- The edit page's first load sends its draft read in parallel, and a pending draft does not say the item was never published. The 404 form shows no error strip, no lock banner and no reset/delete control.
- The embedded editor holds only the item snapshot and the parent name.
- The matrix's package-door save re-read is objectui#9420's fresh read: the open-time published list can be stale, so skipping it risks dropping other packages' rows. The claim's pointer named the load read; the dev pinned the save re-read, which is the remainder.
- The list view holds no draft and no stored-view list for a view that exists nowhere.
- The claim expected these reads to treat
- Triage's direction honoured (
6073343714, relaying answer (a) on meta: the layered view answers the author of a draft-only item the same 404 as an absent name, so Studio can only learn "never published" from an error status objectstack#22397): the 404 is the "never published" signal, read without an error state, and errors are not suppressed in general. Each read still sends/layers, and the browser still logs its 404 line. That is the framework's answer by design, not something either repo controls. - Pins and reverse verification (dev report on this card):
- 12 new tests over the four reads (22 with objectui#11928's): a draft-only item opens clean, a published item still gets its layers, and a 5xx still shows its error at every read.
- Two ablations, run in
ablation-replacewrap mode onmetadata-client.tsand not committed:- the 404 arm throwing: 5 red, the draft-only cases;
- a 5xx resolving like a 404: exactly the four 5xx controls red.
- Every restore was proven (blob equals HEAD).
- Tests and gates: the four pin files passed 22 of 22; the dependency build passed 28 of 28; the app-shell type-check exits 0; eslint reports 0 errors and 0 warnings on the four files. CI on
d7613848: 43 runs: 40 success, 3 skipped (the expected three), 0 failure.Bundle Analysisis success, and no shipped source changed. Mergeable stateclean. - Contract review: not required (
Clause-②: no).
Findings:
- Filed objectui#12027 (class a). For a draft-only parent, the embedded item editor's save sends a publish-mode
PUTof a one-field stub. The draft's name, label and every other field are dropped, and the editor says Saved. The console's request was measured; the live server's answer was not. This is seat 1's earlier unfiled inference (6055471680), now measured. The claim kept it off this PR. - Acceptance notes, not filed: the edit page opens an empty, editable form, with no error state, for a name that has neither a draft nor a layer. Only a 5xx shows Failed to load. This is an observation, with no contract cited and no reach beyond the probe.
Landing: ready + auto-merge through the queue, now. Its merge closes objectui#11799.
Generated by Claude Code
- PR shape:
objectstack-fleet commented
on Oct 9, 2026 ContributorAuthorMore actionsLanded —
domain:uiseat 3,session_01CGZy1BGCjdN5cXqL9cnvB8, 2026-10-09T05:45Z. PR objectui#12026 merged through the queue as3639a31at 2026-10-09T05:44Z.- The merge:
- One parent,
8f8f760f, an ancestor oforigin/main. - The landed tree equals
git merge-treeof that parent and the accepted headd7613848(treeffe78550on both). - 5 files, +431/−19, and all five blobs equal the accepted head's. No shipped source changed: four test files and one empty-frontmatter changeset.
- One parent,
- Content check,
8f8f760f→3639a31:objectui#11799citations across app-shell's test files went from 18 to 24, the new pins for the four reads. - Closures: the PR's only closing keyword was
Fixes #11799, and this merge closed objectui#11799 ascompletedat 2026-10-09T05:44Z.pm:dispatchedis removed in this pass. - The card's three items, settled:
- the
?state=draftprobes and/ai/usagepolling by objectui#11892; - four
/layersreads skipped by objectui#11928; - the last four pinned here, reading the framework's by-design 404 as "never published" (meta: the layered view answers the author of a draft-only item the same 404 as an absent name, so Studio can only learn "never published" from an error status objectstack#22397, answer (a)). Those four still log one 404 line each in the browser, by design.
- the
- Carried out as its own card: objectui#12027, the embedded item editor's publish-mode stub
PUTfor a draft-only parent.
Generated by Claude Code
- The merge:
- added 3 commits that reference this issue
on Oct 9, 2026
Filing gate ① — product defect with a named location and a reproduction. reach: every Studio surface open:
GET /api/v1/meta/<type>/<name>?state=draft→ 404 when there is no draft;GET /api/v1/meta/<type>/<name>/layers→ 404 on new items;GET /api/v1/ai/usage→ 501 (repeated) on a server without AI.Who acts on it: objectui triage → the Studio / app-shell owner. ⛔ Not a claim. Found in a manual browser QA pass of Studio on 2026-10-07; filed one card per finding on the maintainer's word: 「你发现的问题全部提交 issue」, and on the one-card-per-finding question 「覆盖规则,逐条立卡」.
What happens
Expected misses are probed as errors, so the console fills with red "Failed to load resource" lines that hide real failures during debugging.
Suggested direction (triage to rule)
Decide draft existence from the
/meta/_draftslist Studio already reads (or have the server answer 200 + null); skip/layersfor unsaved items; do not call/ai/*when discovery says AI is off.Environment
objectstack
879bd38c·examples/app-showcasebooted withobjectstack dev --ui --seed-adminon an isolated port and SQLite file · objectui179f6fe9(HEAD; the framework pin.objectui-shaisa58626c8) served by the console's Vite dev server, perf numbers from avite buildof the same commit · Chromium 141 at 1440×900 · signed in as the seeded platform adminadmin@objectos.aiunless stated.Duplicate check
Dedupe words: state=draft 404 probe · layers 404 · ai usage 501 polled · console noise studio
Filed by Claude Code (session
session_01D76mrPJrSSdaKRxR2rvrMG) from that QA pass.Generated by Claude Code