Repository navigation
studio(data): hidden system fields (__search "Search Index", owning_business_unit_id) appear in the form designer default layout and the Data → Records grid #11780
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 — a new object's default layout and grid show what authors maintain | 缺项 | P2
Triage: first grade,
bug·priority:p2·domain:ui·area:studio·pm:queue. Direction:hiddensystem fields stay out of the default layout seed and the Records gridTriage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-07T16:09Z. ⛔ Not a claim, ⛔ not a dispatch.Triage: lands in the Studio form-designer default layout seed and the Data → Records grid column set ⇒
domain:ui; rationale: a Studio or console surface in objectui. Filed from the Studio browser QA pass of 2026-10-07 (objectstack879bd38c, objectui179f6fe9).- Why p2: every object created in Studio shows
__searchandowning_business_unit_idto its author (measured). - Direction:
- filter
hiddenfields (andsystem+hidden) from the default layout seed and the Records grid
- filter
Clause-②: no. Patch changeset in objectui.
- Why p2: every object created in Studio shows
objectstack-fleet commented
on Oct 7, 2026 ContributorAuthorMore actionsClaim: PM loop round 4
Session:session_01DrKzdPdyLLBW3qpZ4vtk7z
Account:huangyiirene
Branch:claude/issue-11780-studio-hidden-system-fields
Worktree:objectui-issue-11780
Domain:domain:ui
Seat:domain:ui#1
File surface:packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx, only these regions (line numbers one06365c):STUDIO_SYSTEM_FIELD_NAMES(about:3237), thegridColumnsmemo (:3622), theformFieldsmemo (:3672), and theObjectFormDesignermount'ssystemFieldNamesprop (about:4251).packages/app-shell/src/views/studio-design/ObjectFormDesigner.tsx, where it filters bysystemFieldNames.packages/app-shell/src/views/metadata-admin/previews/ObjectFormCanvas.tsx, only if measurement shows it draws the same leak.- One new module-private helper under
packages/app-shell/src/views/studio-design/, if the predicate is shared. - The tests beside these, and
.changeset/11780-*.md.
⛔ Not on it: any
MetadataClient.savecall site or version-token read on objectui#11773's surface, including the object-draft load effect at:3550–:3600;packages/app-shell/src/views/metadata-admin/i18n.ts;packages/i18n/**;packages/plugin-list/**,packages/plugin-grid/**,packages/plugin-view/**(the runtime list already hides these fields);packages/types/**. 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/objectui: no path-derived mandate; default tier)
Clause-②: no
Responsibility:objectui app-shell Studio: the Data pillar's records grid (gridColumns), its form preview (formFields) and the form designer drop framework fields by one hard-coded name list (STUDIO_SYSTEM_FIELD_NAMES), which does not name the platform-injected __search and owning_business_unit_id, so both show to every author | the platform path is right: the spec's injected-column definitions mark owning_business_unit_id hidden + system (OWNING_BUSINESS_UNIT_FIELD_DEF), the search companion __search is hidden + system + readonly, and the runtime list already hides both | every author who opens an object in Studio's Data pillar; measured by the filer on new Studio objects and on showcase_account
Thread-read: 6041867867
Serial constraints cleared:noneblocking.area:studioin flight, both seat 3's:- objectui#11773, claim
6042151480, owns every Studio draft-save call site and the version plumbing. Its fold-or-serial line names this card, and lets a card whose surface is disjoint from that list run alongside it.- Measured: this surface holds none of its call sites (
StudioDesignSurface.tsx:1247…:5277). - Its PR objectui#11826, still a draft, changes
StudioDesignSurface.tsxin hunks starting at old:3532,:3555,:3587and:3726. None falls inside:3237,:3622–:3680or:4248–:4262.
- Measured: this surface holds none of its call sites (
- objectui#11784, claim
6044180897, ownsPackagesPage.tsx. That file is not on this surface.
- objectui#11773, claim
- Open objectui PRs:
- objectui#11826 (the draft above).
- objectui#11825 (the flow canvas files), objectui#11821 (
plugin-view), objectui#11600 (release), objectui#11069 (CLI): none touches these files. - Read 2026-10-07T18:31Z.
- This seat: dispatch is serial (maintainer instruction, seat post
6020143345). Its previous card, objectui#11777, landed ate06365c, so nothing else of this seat is in flight.
Ruling on the predicate (the seat's reading of the triage direction,
6041867867): the field set kept out of the Studio grid, the form preview and the designer issystem: trueandhidden: truetogether, the platform's own marks for the injected columns. That is the triage line's parenthetical. A bare author-declaredhiddenfield withoutsystemstays visible in Studio; the grid column and the designer are how an author reaches its inspector to un-hide it.- No "show system fields" toggle is built, and no locale key is added.
STUDIO_SYSTEM_FIELD_NAMESkeeps its role for the audit and tenant columns, unless measurement shows the marks cover them too. The dev reports which.
Why
Clause-②: no: this is a read-side filter inside app-shell's Studio views. No accepted input widens, no@object-ui/app-shellpackage-entry export changes, and no type member or locale key is added. If the fix needs any of those, the dev stops and reports, and the seat re-claims.objectstack-fleet commented
on Oct 7, 2026 ContributorAuthorMore actionsos-dev-report
{ "issue": 11780, "status": "done", "branch": "claude/issue-11780-studio-hidden-system-fields", "pr": "https://github.com/objectstack-ai/objectui/pull/11828", "session": "session_01DrKzdPdyLLBW3qpZ4vtk7z — the dispatching seat domain:ui#1 (subagent run, parent session id)", "premise_still_valid": true, "summary": "Studio's Data pillar now keeps every field the served metadata marks system: true AND hidden: true out of the records grid (gridColumns), the Form preview (formFields) and the form designer, via one module-private predicate isStudioHiddenSystemField in studio-design/studioHiddenSystemField.ts, applied beside the unchanged STUDIO_SYSTEM_FIELD_NAMES check; memo keys unchanged. ObjectFormDesigner uses one module-level test (name list OR predicate) for its density count, its containers and its commit write-back, so hidden system fields are hidden from view and written back with definitions unchanged; no prop change, nothing on the package entry, no locale key. STUDIO_SYSTEM_FIELD_NAMES is KEPT: measured, the marks cover __search, owning_business_unit_id and organization_id, but the audit columns are system without hidden (AUDIT_FIELD_DEFS; live-served created_at reads system true, no hidden). H1 measured live on objectstack a543e244 showcase (no draft and a served draft of a Studio-created object), and a live browser before/after on this branch confirms both labels gone from the grid headers and both designers.", "tests": { "head": "7343b3a (local git rev-parse --short HEAD; the gate union below ran on it unless marked)", "gates": [ "pnpm --workspace-concurrency=2 --filter '@object-ui/app-shell^...' build → exit 0 → os-verify-lock VERDICT command-exit 0", "pnpm exec vitest run StudioDesignSurface.gridColumns + StudioDesignSurface.formFields + ObjectFormDesigner + all 9 existing DataPillar.* + new DataPillar.hiddenSystemFields-11780 (13 files, repo root) → exit 0 → Test Files 13 passed (13), Tests 56 passed (56); HEAD_AT_RUN=7343b3a", "pnpm exec vitest run --maxWorkers=2 packages/app-shell/src/views/studio-design/ → exit 0 → Test Files 93 passed (93), Tests 548 passed (548); ran at 9feaf8b (7343b3a changes only the new test file mock typing; that file re-ran green at 7343b3a in the line above)", "pnpm --filter @object-ui/app-shell type-check (echoed: tsc --noEmit && tsc -p tsconfig.test.json) → exit 0 → VERDICT command-exit 0; HEAD_AT_RUN=7343b3a; the test config includes the new file (its first run reported TS2352/TS2493 in it, fixed in 7343b3a)", "pnpm check:control-bytes → exit 0 → check-control-bytes: OK", "pnpm check:new-line-citations → exit 0 → VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only", "pnpm check:changeset-claims → exit 0 → No pending changeset names a file this change touches", "pnpm check:pending-changeset-literals → exit 0 → No test source names a pending changeset", "ADDED (new vi.mock doubles): pnpm check:vi-mock-specifiers / check:vi-mock-inherit / check:vi-mock-override-shape → exit 0 each → OK", "ADDED: pnpm check:test-path-roots → exit 0 → OK; pnpm check:unreferenced-sources (new source file) → exit 0 → Every shipped source file in every covered package is reachable; pnpm check:metadata-write-doors → exit 0 → OK, 3 reach assertObjectMetadataWritable", "ADDED: node scripts/check-changeset-presence.mjs → exit 0; node scripts/check-changeset-no-major.mjs → exit 0; node scripts/check-governed-queue-guard.mjs --test (5 changed paths) → exit 0 → NOT GOVERNED", "targeted eslint as the package lint runs it, 4 touched files → exit 0, 0 errors; warnings on the 2 modified files are the same rule multiset as at base 282f252 (1 and 17), new files 0; population = the 4 files of git diff 282f252..HEAD minus the changeset; type-aware linting not enabled in eslint.config.js (no parserOptions.project / projectService), so untouched files cannot move. Repo-wide pnpm lint declared to CI." ], "reverse_checks": [ "committed first (9feaf8b); every leg has trap restore via git checkout HEAD --, proven by blob hash == HEAD and empty git diff HEAD", "leg 1, both source files at base (markers 4/4 → 0/0, on-disk blobs == base): 6 failed | 5 passed — grid, Form preview, designer x2 cases; first: expected [ name, industry, … ] to not include __search; write-back, identity, predicate stayed green — the predicted direction", "leg 2, designer commit write-back test reverted to the name list alone (anchor 1/0 → 0/1): 2 failed (write-back x2), expected undefined to deeply equal { type: text, … } — proves the pin catches a hide-and-drop", "leg 3, gridColumns key loosened to objDraft (anchor 1/0 → 0/1): 2 failed (identity x2). First attempt of leg 3 was a NO-OP (script syntax error before the mutation; counts unchanged), rerun with a fixed script", "live leg in the browser: same session, source at base → grid headers include Owning Business Unit and Search Index, both designers show both; at HEAD → absent; restored by blob hash" ], "h1_measurement": { "instrument": "objectstack a543e244, examples/app-showcase, objectstack dev --seed-admin --fresh on an isolated port; GET /api/v1/meta/object/NAME/layers and GET /api/v1/meta/object/NAME?state=draft (the MetadataClient.layered / getDraft endpoints)", "no_draft_showcase_account_effective": { "__search": "hidden true, system true, readonly true, label Search Index (absent from code.fields; provisioned into effective)", "owning_business_unit_id": "hidden true, system true, readonly true", "organization_id": "hidden true, system true, readonly true", "owner_id": "system true, readonly false, no hidden", "created_at": "system true, readonly true, no hidden", "author_name": "hidden false, readonly false, no system" }, "served_draft_studio_created_object": { "how": "skeleton like doCreateObject (one name text field) saved mode=draft into a Studio-created package; GET state=draft", "fields_served": "organization_id, created_at, created_by, updated_at, updated_by, owner_id, owning_business_unit_id, name, __search", "__search": "hidden true, system true, readonly true", "owning_business_unit_id": "hidden true, system true, readonly true", "author_name": "label only", "note": "a code-provided package object takes no draft (save answers 403 read-only), so the served-draft case is a Studio-authored object" }, "verdict": "H1 holds: the marks are on the entries readFields(objDraft.fields) returns in both cases; no second source" }, "hypotheses": { "H2": "confirmed; no separate seed carries them: buildObjectSkeleton seeds one name field, the server adds injected columns to the served draft, and the designer ungrouped bucket rendered them (the filer default layout seed)", "H3": "confirmed and kept; pinned through the real pillar: designer drop → auto-save body keeps all hidden system fields deep-equal, key set unchanged, edit order applied", "H4": "ObjectFormCanvas renders every entry via groupEntries(view, …) with no system filter at all (audit columns included); it is the metadata-admin object preview (ObjectPreview), not mounted by the Data pillar; NOT touched", "H5": "keys unchanged; new identity pin across an object-label edit through the real onPatch" }, "deviations": [ "One line outside the claim listed regions of StudioDesignSurface.tsx: the import of the new helper in the module import block (same file, on the surface). Draft PR #11826 also adds an import in that block, earlier, near useMetadataClient; hunks do not overlap, nor do its DataPillar hunks with this branch", "H1 and the live browser check used a detached objectstack probe worktree (a543e244), install + 60-task build under os-verify-lock (VERDICT command-exit 0), a showcase backend and a console Vite dev server started by me; both stopped by their own process groups (ports answer 000), worktree removed after rm -rf node_modules; no shared checkout edited", "Commit trailers use the AGENTS.md model-free pair (Claude-Session + Co-authored-by: Claude), not the harness reminder model-named line; PR footer uses the os-dev session-URL form, not the harness form", "tests field is an object (gates / reverse_checks / h1_measurement / deviations / files_changed) as the dispatch order asked, not the template string" ], "files_changed": [ "packages/app-shell/src/views/studio-design/studioHiddenSystemField.ts (new, module-private)", "packages/app-shell/src/views/studio-design/StudioDesignSurface.tsx (import, STUDIO_SYSTEM_FIELD_NAMES doc, gridColumns, formFields)", "packages/app-shell/src/views/studio-design/ObjectFormDesigner.tsx (isKeptOffLayout; density count, containers, commit write-back; prop doc)", "packages/app-shell/src/views/studio-design/DataPillar.hiddenSystemFields-11780.test.tsx (new pins)", ".changeset/11780-studio-hidden-system-fields.md (@object-ui/app-shell patch)" ] }, "mcp_calls": "0", "api_writes": "2 relay writes + git push. (1) fleet-write dispatch POST /repos/objectstack-ai/objectstack/dispatches → run 37672851542 → POST /repos/objectstack-ai/objectui/pulls (draft #11828; read-back 10252 bytes sent, 10252 stored, identical). (2) this os-dev-report comment, POST /repos/objectstack-ai/objectui/issues/11780/comments via post-stamped. git push of claude/issue-11780-studio-hidden-system-fields (3 pushes of the one branch, counted as one). Zero label, assign or MCP writes; PR labels tests + package: app-shell come from labeler.yml", "open_questions": [], "out_of_scope_findings": [ "carrier: none · ObjectFormCanvas (metadata-admin object preview) lists every field incl. audit and injected hidden columns — a different contract (full field inventory), not on the Data pillar path; noted in PR Acceptance notes, not filed", "carrier: none · the Data pillar header N fields count counts every served field incl. system ones (unchanged by this PR, true field count); noted in PR Acceptance notes, not filed" ] }objectstack-fleet commented
on Oct 7, 2026 ContributorAuthorMore actionsReview: ACCEPT — PR objectui#11828 (head
7343b3a)domain:uiseat 1 ·session_01DrKzdPdyLLBW3qpZ4vtk7z· reviewed against the PR diff, its file list and check runs, read 2026-10-07T19:19Z. Report:os-dev-report6045042649on this card.-
Shape: draft →
main. The first line isFixes #11780, andClause-②: nostarts a later line. -
Scope: 5 files, +422/−6, all inside claim
6044291818's surface:studioHiddenSystemField.ts(new, +39);StudioDesignSurface.tsx(+18/−2): the name-list doc,gridColumns,formFields, and one import line;ObjectFormDesigner.tsx(+23/−4);- one pin file;
- one changeset (
@object-ui/app-shellpatch).
The import line sits in the same file's import block, outside the listed regions. That deviation is declared and accepted. No
MetadataClient.savecall site, no version-token read and noi18n.tsis touched. -
Clause-② re-read on the diff:
- The only added
exportisisStudioHiddenSystemFieldin the new module.packages/app-shell/src/index.tsre-exports by name and does not name it. - No prop of
ObjectFormDesignerchanges; only its doc changes. - No type member or locale key is added.
noholds.
- The only added
-
Rulings held:
- Predicate:
def?.system === true && def?.hidden === true: both marks, and booleans only. - Name list:
STUDIO_SYSTEM_FIELD_NAMESis kept, with the reason measured. The audit columns aresystemwithouthidden(AUDIT_FIELD_DEFS, and the servedcreated_at), so the marks alone would put them back. - No toggle and no locale key.
- Predicate:
-
Mechanism checked on the diff:
gridColumnsandformFieldsfilter on the entry's def before mapping to names. The memo keys are unchanged (objDraft.fields, pluspublishedFieldNamesfor the grid).ObjectFormDesignerreads one test,isKeptOffLayout(name list OR predicate), in all three places: the density count, the containers, and the commit's write-back.- So a field hidden from the canvas rides back in
fieldsunchanged. Like the named system fields before it, it is placed ahead of the editable entries.
-
H1 to H5, as measured by the dev:
- H1 holds on live objectstack
a543e244showcase, both with no draft and with a served draft.__search,owning_business_unit_idandorganization_idcarryhidden+system.owner_idandcreated_ataresystemonly. - H2: there is no separate seed. The designer's ungrouped bucket was the filer's "default layout".
- H3 is kept and pinned.
- H4:
ObjectFormCanvasis untouched. It is the metadata-admin preview, and the Data pillar does not mount it. - H5: the memo keys are unchanged, and a new identity pin covers them.
- H1 holds on live objectstack
-
Tests:
-
New pins: 5 rows × 2 cases (no draft; served draft), plus the predicate row. The fixture carries the three controls the order asked for:
- an author-hidden field (
internal_note), which stays; - a system-not-hidden field (
owner_id), which stays; - an audit column (
created_at), which stays out.
The write-back row checks every hidden system def deep-equal and the key set unchanged after a designer drop.
- an author-hidden field (
-
Reverse checks, each restored by blob hash:
- both sources at base: 6 rows red, grid / preview / designer × 2 cases, in the predicted direction;
- the write-back reverted to the name list alone: 2 rows red;
- the
gridColumnskey loosened toobjDraft: 2 rows red. The first attempt at this leg was a no-op, which the dev declared and then reran.
-
Local runs:
studio-design/93 files, 548 tests green; the 13-file target set green at7343b3a;app-shelltype-check green. -
Live browser: before the fix, both labels showed in the grid headers and in both designers; after it, both are gone.
-
-
Overlap re-read:
- Since the PR's base
282f252,maingained only objectui#11825 (flow-canvas files). Nothing understudio-design/changed. - The one in-flight PR on this file, objectui#11826 (seat 3, still a draft), adds its import earlier in the block and has no hunk in
DataPillar's memos. Whichever lands second mergesmain.
- Since the PR's base
-
CI at
7343b3a: 42 runs, still converging at this read: 29 green, 3 expected skips, 10 in progress, none red. The PR waits to be queued until every check completes. -
Out-of-scope notes, not filed:
ObjectFormCanvaslists every field, because it is a full-inventory contract on a different path.- The Data pillar header's "N fields" counts every served field, which is the true count.
-
PR assignee: set by this seat to
huangyiirene, the card's assignee.
Generated by Claude Code
-
objectstack-fleet commented
on Oct 7, 2026 ContributorAuthorMore actionsLanded: PR objectui#11828 →
maind53fd02domain:uiseat 1 ·session_01DrKzdPdyLLBW3qpZ4vtk7z· verified 2026-10-07T19:48Z.- Merged through the merge queue at 2026-10-07T19:47:12Z, after it was queued at 2026-10-07T19:31:44Z.
- CI on head
7343b3abefore queueing: 40 of 43 check runs passed, and the 3 skipped are the expected ones. check-governed-merges.mjsread 0 of 5 paths governed and 428 changed lines, under the human-merge threshold.
- CI on head
- Content check:
d53fd02is one squash commit on parent2dec305. It changes 5 files, +422/−6, the same as the PR.- Between the PR's base
282f252and that parent,maintook seat 3's objectui#11826 (2dec305), which also editsStudioDesignSurface.tsx. A plaingit diff 7343b3a d53fd02over the PR's paths therefore carries fix(app-shell): Studio draft saves send the version they were built on, and a stale save opens a reload / overwrite dialog (objectui#11773) #11826's hunks (16389 bytes) and is not the measure here. The checks that hold:- 4 of the 5 files are blob-identical between the reviewed head and
d53fd02: the helper,ObjectFormDesigner.tsx, the pin file and the changeset. - The squash commit's own diff (
d53fd02~1..d53fd02) has the samegit patch-id --stableas the PR's diff (282f252..7343b3a):b15930b9…for the whole change,22c5ed0e…forStudioDesignSurface.tsxalone. - The landed bytes are the reviewed change, applied on top of fix(app-shell): Studio draft saves send the version they were built on, and a stale save opens a reload / overwrite dialog (objectui#11773) #11826. The merge queue ran CI on that combined tree.
- 4 of the 5 files are blob-identical between the reviewed head and
- On
main:isStudioHiddenSystemFieldhitsStudioDesignSurface.tsx4 times.
- Card: closed
completedby the PR'sFixes.pm:dispatchedwas removed and read back. - Landing window: objectui#11826 (seat 3, objectui#11773) also closed after 19:30Z, by its own PR. This PR closes only this card.
Generated by Claude Code
- Merged through the merge queue at 2026-10-07T19:47:12Z, after it was queued at 2026-10-07T19:31:44Z.
- added a commit that references this issue
on Oct 9, 2026
Filing gate ① — product defect with a named location and a reproduction. reach: every object created in Studio: the default form layout and the Data → Records grid show
__search("Search Index") andowning_business_unit_id("Owning Business Unit"), bothhidden: truein the served metadata.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
The form designer's default layout and the Records grid in the Data pillar include the two hidden system fields (also on showcase
showcase_account). The Interfaces runtime list and the end-user list hide them, so the two grids an author sees disagree.Expected
Designer and Records grid honour
hiddenlike the runtime list; an explicit "show system fields" toggle if authors need them.Suggested direction (triage to rule)
Filter
hidden(andsystem+hidden) fields from the default layout seed and the Records grid column set.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: hidden system fields form designer · search index field visible · owning business unit records grid
Filed by Claude Code (session
session_01D76mrPJrSSdaKRxR2rvrMG) from that QA pass.Generated by Claude Code