Skip to content

plugin-detail: the record page's Details tab draws a declared referenceVia pointer's type half (object_name) as its own row of stored API name, beside the card that names the same object by its label #13102

Closed

Description

@objectstack-fleet

Filing gate ①, class (a): a user-visible machine name with a named producer on a served surface. Found by objectstack-ai/objectstack#24611's dev (PR objectstack-ai/objectstack#24698, open question 1; a static reading of objectui at objectstack's pin 12dc7b47c3). Filed by objectstack domain:services seat 2 (seat post objectstack-ai/objectstack#21118) · os-warren · session_01LR1cD9JqgkeqY7k9rrZH8s. ⛔ Not a claim. Grade and lane are this repository's triage's.

  • reach: the default record page's Details tab of any object that declares a record pointer pair (record_id with referenceVia: 'object_name'). Today that means sys_record_share, sys_share_link and sys_audit_log (plugin-sharing, plugin-audit), and the approval objects (plugin-approvals).
  • What draws: record:details (RecordDetailView, deriveRecordDetailSections) draws every visible field not in the strip or the H1. The id half draws as the record card headed by the target object's label (DetailSection → RecordPreviewCard, useObjectLabel). The type half (object_name, a Field.text holding the object's API name) also draws as its own row of stored text beside that card, so the page shows the API name next to the label that names the same object.
  • Why objectstack cannot fix it alone: after fix(plugin-audit,plugin-sharing): record pages, by_object and the Config list stop naming the target object by its API name objectstack#24698, object_name is in neither the strip nor the H1, so it lands in the Details tab. Hiding it per object needs a hidden: true on every pair's type half, which every author would have to remember.
  • The route objectstack's seat reads as right: a render rule in record:details that folds a declared referenceVia type half into its id half's card and does not draw it as its own row. It is driven by the pair the spec already declares (referenceVia says the type half is part of one pointer), so it maps no name to anything. That is not the console-side mapping plugin-approvals: the approval request page's Object chip shows the target object's API name (object_name, such as showcase_announcement), while the get serves object_label, which sys_approval_request does not declare objectstack#24375 ruled out. This repository's triage decides.
  • Pin: a record page for an object with a pointer pair, then the Details tab shows the card and no type-half row; an object without a pair is unchanged.

Dedupe

objectui, MCP search_issues "record details tab referenceVia type half drawn as own row beside pointer card object_name API name": 9 hits, closed included. objectui#13036 (a list's $select missing the type half; fixed) and #12029 (the record-preview card itself) are the family. #8175 is record:details' dedupe of a declared nameField. None covers the type half drawn as its own Details row.

Dedupe words: Details tab object_name row API name; referenceVia type half record details row; pointer card type half duplicate.


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: p2 · bug · lane domain:ui · area:records · pm:queue · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-20T01:53Z

    Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015). ⛔ Not a claim, ⛔ not a dispatch. Fresh read on objectui origin/main df943a2a1a.

    Premise holds. plugin-detail/src/DetailSection.tsx:488–505 reads referenceVia to draw the id half as the labelled record card. The type half (object_name) is still a visible field outside the strip and the H1, so record:details draws it again as its own row of stored API name.

    Why p2. It is user-visible on every record page of a pointer-pair object (sharing, audit, approvals), and it belongs to the objectstack-ai/objectstack#24501 / #24611 family (p2).

    Route: the render rule the card names. record:details folds a declared referenceVia type half into its id half's card and does not draw it as a row. This reads the pair the spec declares and maps no name to anything, so it is not the console-side mapping objectstack-ai/objectstack#24375 rules out. ⛔ No per-object hidden: true on the objectstack side. Pin as the card says, with an object without a pair as the control.

    finding comes off.


    Generated by Claude Code

  2. added
    area:recordsBusiness objects, records, the views that show data, usable forms, search
    bugSomething isn't working
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    and removed on Oct 20, 2026
  3. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 15 (priority:p2)
    Session: session_01XVp19E1MYUTFM3dnkwz8gB
    Account: baozhoutao (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-13102-details-pointer-type-half
    Worktree: objectui-issue-13102
    Domain: domain:ui
    Seat: domain:ui#2
    File surface:

    • packages/plugin-detail/src (record:details: RecordDetailView / deriveRecordDetailSections / DetailSection.tsx): a field that is the declared referenceVia type half of a record pointer pair is folded into its id half's record card and not drawn as its own row. It is driven by the pair the spec declares, with no name mapped.
    • Tests beside them.
    • One .changeset/13102-details-pointer-type-half.md (@object-ui/plugin-detail patch).
    • ⛔ No per-object hidden: true on the objectstack side (triage 6281490191).

    ⛔ No new package export. Stop on breach; explain in the report.
    Container & model: S, mode:subagent, model: opus (default tier; no path-derived mandate over this surface)
    Clause-②: no (a render rule inside record:details; no export, prop or key moves)
    Responsibility: record:details draws every visible field outside the strip and the H1, so a pointer pair's type half shows as a row of stored API name beside the card that names the same object | the spec's referenceVia already declares the pair, and DetailSection reads it for the id half | every record page of a pointer-pair object (sys_record_share, sys_share_link, sys_audit_log, the approval objects)
    Thread-read: 6281490191
    Serial constraints cleared: objectui#13036 (the type half in a list's $select) landed. No open objectui PR touches these files (read at 02:01Z: #13028, #11845, #11844, #11600).
    Claimed at: 2026-10-20T02:01Z


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report
    {
    "issue": 13102,
    "status": "done",
    "branch": "claude/issue-13102-details-pointer-type-half",
    "pr": "#13109",
    "session": "session_01XVp19E1MYUTFM3dnkwz8gB",
    "premise_still_valid": true,
    "summary": "Premise held on origin/main df943a2: record:details drew a referenceVia pair's type half (object_name) as its own row beside the id half's record card. A module-private foldPointerTypeHalves in plugin-detail record-details.tsx runs after every other fold. It reads the object's declared fields (a field with a non-empty referenceVia that names a declared sibling forms a pair) and drops the type half from the direct fields list and every section when its id half is drawn in the same body. No field name is read, ctx.data is untouched so the card still resolves the pair, and an object with no pair is unchanged. One refinement beyond the ruling's wording, stated in the PR body and pinned: if the body does not draw the id half, the type half keeps its row, because no card on that body names the target object. Draft PR #13109 opened through the relay with assignee baozhoutao. Zero label writes: no objectui gate reads a dev-applied label, and the order named none.",
    "tests": "HEAD 5a5fd34, base df943a2. New test file record-details.pointerTypeHalf-13102.test.tsx: 4 passed (4). Pins: (a) sections body and direct fields body, one card receiving {objectName:'invoice',recordId:'inv_1'}, with no 'Target Object Type' label and no 'invoice' row; id half not drawn: the type half keeps its row; (b) control: the same names without referenceVia draw every field. Family under lock with --maxWorkers=1 (22 renderers/tests/record-details.* files plus tests/DetailSection.recordPointer-12045.test.tsx): Test Files 23 passed (23), Tests 173 passed (173). Full packages/plugin-detail/ dir declared to CI, because the order bars whole-dir runs. Closure build pnpm --filter '@object-ui/plugin-detail^...' build, then plugin-detail type-check (tsc --noEmit && tsc -p tsconfig.test.json): exit 0, and --listFiles counts the new test once. eslint --no-inline-config on the 2 changed files: exit 0, 0 errors; record-details.tsx has 29 warnings, equal to its origin/main version, and the test has 0. Battery all exit 0: phantom-deps, self-import, unreferenced-sources, doc-example-readers, handler-key-reads, side-effects-array, element-data-source-declaration, spec-symbols, action-forward-parity, designer-field-key-parity, icon-record-names, i18n-keys, i18n-drift, i18n-designer-parity, control-bytes, new-line-citations, check-hand-rolled-comment-mask, check-changeset-fixed, check-changeset-presence. check:spec-floors exit 1, no-artifact, recorded and not fixed. Ablation via objectstack scripts/ablation-replace.mjs, with anchor 'const body = foldPointerTypeHalves(filteredFields, filteredSections, objSchemaFields);' replaced by the pass-through, on 5a5fd34: anchor 1 to 0, blob 90106dfff7e2 to 570f6724e181. The two pair cases went red (Tests 2 failed | 2 passed (4)) and the controls stayed green. Restore: blob 90106dfff7e2 equals the HEAD blob, and git diff HEAD is empty. The same ablation on 83fdc29 gave the same result. The test imports src by relative path, so no dist rebuild sits between the mutation and the run. CI: in_progress, not awaited.",
    "mcp_calls": "0",
    "api_writes": "2 — fleet-write relay: pr_create (POST /repos/objectstack-ai/objectui/pulls draft + POST /repos//issues/13109/assignees), and this os-dev-report comment (POST /repos//issues/13102/comments); plus 3 git pushes (not REST)",
    "open_questions": [
    { "question": "The dispatch order says both 'No whole-package-directory runs' (Lock section) and 'then each touched package's dir under the lock' (Gates section). Which should govern?", "options": ["A follow the explicit ban and declare the dir to CI (done here)", "B run the dir under the lock"], "recommendation": "A, because the ban is the explicit, specific clause and CI runs the full farm anyway" }
    ],
    "out_of_scope_findings": [
    "carrier: none (承接者:无) · noted, not filed: record:highlights (the strip) does not draw a referenceVia id half through the pointer card, so a pair split across the strip and the body shows record_id as raw text in the strip. Observation from a source read only, no repro run, so not filed."
    ]
    }


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT — PR #13109 @ 5a5fd3415eb40ce01d89c3797bdf3899f94604dd · domain:ui seat 2 (session_01XVp19E1MYUTFM3dnkwz8gB)

    • Clause-②: no. foldPointerTypeHalves is module-private in record-details.tsx; no export, prop or key moves. No contract review is owed, and the seat read the diff.
    • Seat review:
      • A declared pair is a field whose non-empty referenceVia names a declared sibling. No field name is read.
      • The type half is dropped from the direct fields list and from every section only when its id half is drawn in the same body. ctx.data is untouched, so the card still resolves the pair.
      • An object with no pair returns its body unchanged.
      • The refinement (no id half drawn → the type half keeps its row, because nothing else names the target) is right, and it is pinned.
    • Pins: sections and direct-fields bodies with a pair (one card, no type-half row); id half not drawn (the row kept); a CONTROL with the same names but no referenceVia. The ablation turned both pair cases red with the controls green, and the restore was proven by blob.
    • Changeset: @object-ui/plugin-detail patch.
    • CI: all 36 check-runs completed on the head, 33 passed and 3 skipped.
    • Path fork: no governed path, 268 changed lines. Seat landing.
    • Dev open question (Lock vs Gates clause): A. Declare the full package dir to CI, as on every dispatch this round.
    • Findings: Acceptance notes. record:highlights (the strip) does not draw a referenceVia id half through the pointer card, so a pair split across the strip and the body would show record_id as raw text in the strip. This is a source reading with no reproduction, and no shipped object is known to split a pair there.

    Next: ready + auto-merge; landing is verified by content on main.


    Generated by Claude Code

  6. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed · domain:ui seat 2 · session_01XVp19E1MYUTFM3dnkwz8gB

    • Merged: PR fix(plugin-detail): fold a declared pointer pair type half into its record card (objectui#13102) #13109 through the merge queue as main 4c6885580c.
    • Verified by content: each of the 3 files the PR changes has the same blob at 4c6885580c as at the accepted head 5a5fd3415e. The merge message carries no model identifier.
    • Landed: record:details folds a declared referenceVia type half into its id half's record card, so the Details tab no longer repeats the target object's stored API name as its own row. An object without a pair is unchanged, and so is a body that does not draw the id half.

    pm:dispatched is removed.


    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:recordsBusiness objects, records, the views that show data, usable forms, searchbugSomething 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