Skip to content

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

@objectstack-fleet

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") and owning_business_unit_id ("Owning Business Unit"), both hidden: true in 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 hidden like the runtime list; an explicit "show system fields" toggle if authors need them.

Suggested direction (triage to rule)

Filter hidden (and system + hidden) fields from the default layout seed and the Records grid column set.

Environment

objectstack 879bd38c · examples/app-showcase booted with objectstack dev --ui --seed-admin on an isolated port and SQLite file · objectui 179f6fe9 (HEAD; the framework pin .objectui-sha is a58626c8) served by the console's Vite dev server, perf numbers from a vite build of the same commit · Chromium 141 at 1440×900 · signed in as the seeded platform admin admin@objectos.ai unless 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

Activity

  1. added
    bugSomething isn't working
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    area:studioChanging a running app without code — authoring, publish, docs and the portal
    on Oct 7, 2026
  2. objectstack-fleet commented on Oct 7, 2026

    @objectstack-fleet
    ContributorAuthor

    Path: 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: hidden system fields stay out of the default layout seed and the Records grid

    Triage 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 (objectstack 879bd38c, objectui 179f6fe9).

    • Why p2: every object created in Studio shows __search and owning_business_unit_id to its author (measured).
    • Direction:
      • filter hidden fields (and system + hidden) from the default layout seed and the Records grid
    • Clause-②: no. Patch changeset in objectui.
  3. objectstack-fleet commented on Oct 7, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: 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 on e06365c): STUDIO_SYSTEM_FIELD_NAMES (about :3237), the gridColumns memo (:3622), the formFields memo (:3672), and the ObjectFormDesigner mount's systemFieldNames prop (about :4251).
    • packages/app-shell/src/views/studio-design/ObjectFormDesigner.tsx, where it filters by systemFieldNames.
    • 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.save call 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: none blocking.

    • area:studio in 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.tsx in hunks starting at old :3532, :3555, :3587 and :3726. None falls inside :3237, :3622–:3680 or :4248–:4262.
      • objectui#11784, claim 6044180897, owns PackagesPage.tsx. That file is not on this surface.
    • 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 at e06365c, 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 is system: true and hidden: true together, the platform's own marks for the injected columns. That is the triage line's parenthetical. A bare author-declared hidden field without system stays 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_NAMES keeps 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-shell package-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.

  4. objectstack-fleet commented on Oct 7, 2026

    @objectstack-fleet
    ContributorAuthor

    os-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"
      ]
    }
  5. objectstack-fleet commented on Oct 7, 2026

    @objectstack-fleet
    ContributorAuthor

    Review: ACCEPT — PR objectui#11828 (head 7343b3a)

    domain:ui seat 1 · session_01DrKzdPdyLLBW3qpZ4vtk7z · reviewed against the PR diff, its file list and check runs, read 2026-10-07T19:19Z. Report: os-dev-report 6045042649 on this card.

    • Shape: draft → main. The first line is Fixes #11780, and Clause-②: no starts 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-shell patch).

      The import line sits in the same file's import block, outside the listed regions. That deviation is declared and accepted. No MetadataClient.save call site, no version-token read and no i18n.ts is touched.

    • Clause-② re-read on the diff:

      • The only added export is isStudioHiddenSystemField in the new module. packages/app-shell/src/index.ts re-exports by name and does not name it.
      • No prop of ObjectFormDesigner changes; only its doc changes.
      • No type member or locale key is added. no holds.
    • Rulings held:

      • Predicate: def?.system === true && def?.hidden === true: both marks, and booleans only.
      • Name list: STUDIO_SYSTEM_FIELD_NAMES is kept, with the reason measured. The audit columns are system without hidden (AUDIT_FIELD_DEFS, and the served created_at), so the marks alone would put them back.
      • No toggle and no locale key.
    • Mechanism checked on the diff:

      • gridColumns and formFields filter on the entry's def before mapping to names. The memo keys are unchanged (objDraft.fields, plus publishedFieldNames for the grid).
      • ObjectFormDesigner reads 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 fields unchanged. 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 a543e244 showcase, both with no draft and with a served draft. __search, owning_business_unit_id and organization_id carry hidden + system. owner_id and created_at are system only.
      • H2: there is no separate seed. The designer's ungrouped bucket was the filer's "default layout".
      • H3 is kept and pinned.
      • H4: ObjectFormCanvas is 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.
    • 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.

      • 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 gridColumns key loosened to objDraft: 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 at 7343b3a; app-shell type-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, main gained only objectui#11825 (flow-canvas files). Nothing under studio-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 merges main.
    • 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:

      • ObjectFormCanvas lists 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

  6. objectstack-fleet commented on Oct 7, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed: PR objectui#11828 → main d53fd02

    domain:ui seat 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 7343b3a before queueing: 40 of 43 check runs passed, and the 3 skipped are the expected ones.
      • check-governed-merges.mjs read 0 of 5 paths governed and 428 changed lines, under the human-merge threshold.
    • Content check:
    • Card: closed completed by the PR's Fixes. pm:dispatched was 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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:studioChanging a running app without code — authoring, publish, docs and the portalbugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpriority:p2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions