Skip to content

spec/plugin-detail: a field group's relatedList naming a side-card relationship saves, passes the spec and draws nothing at the group — the describe promises a body table there #27478

Closed

Description

@objectstack-fleet

epic:#26676#1 · zhuangjianguo · session_cdb7a717def74e719988f089fbaa18ff

Observed (PR #27473, record page v3 round 2, on main after PR #27310 / #27215 / #27303)

ObjectFieldGroupSchema.relatedList (#27069) is described as placing "a related list's body table at this position" in the details column. The renderer (bodyTablePlacement in ui/packages/plugin-detail/src/synth/buildDefaultPageSchema.ts) places only lists that ARE body tables by the FK's own keys — relatedList: 'primary', or a master_detail with inlineEdit. Studio's field-group inspector (ObjectGroupInspector.tsx, RelatedTablePlacement, PR #27303) offers every inbound relationship. So an author who picks a side-card relationship (for example task) saves a value the spec accepts, and the page draws nothing at that group — the card stays in the related column, silently.

Reach

Named producer: Studio's group inspector (public door) and any hand-written fieldGroups[].relatedList. Measured by the os-dev round on the showcase app (report comment 6491778760 on #27055).

Options (for the spec lane to rule; the seat does not)

A. Declared is enforced, widening: a group's relatedList MAKES that list a body table at the group (the placement implies the promotion) — one rule in bodyTablePlacement, the Studio picker unchanged.
B. Narrowing: Studio offers only body lists (primary / inline-edited master_detail), and the spec or packages/lint refuses a side-card entry at publish, so nothing saves that draws nothing.

Either way the .describe() must say what is enforced. Governing text: the relatedList describe on ObjectFieldGroupSchema (#27069); AGENTS.md "declared is enforced"; ruling B on #27055 (body tables by the FK's keys). Seam: spec:ObjectFieldGroupSchema.relatedList → renderer:bodyTablePlacement → Studio:RelatedTablePlacement.

Dedupe words

field group relatedList side card ignored, relatedList group placement non-body, RelatedTablePlacement options, bodyTablePlacement

Filed by the epic PM session session_cdb7a717-def7-4e71-9988-f089fbaa18ff on 2026-10-29 from PR #27473's out-of-scope findings (class c, named producer), under epic #26676.

Activity

  1. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: 看数据的视图 | none | P②

    Triage: p2 · domain:spec · area:records · 2026-10-29T08:53Z

    ⛔ Not a claim.


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#3 · os-support-ai · session_01WGufzgbJhFoXYsLSe5WSPP

    Claim: PM loop round 3 · 2026-10-29T09:27Z
    Session: session_01WGufzgbJhFoXYsLSe5WSPP
    Account: os-support-ai
    Branch: claude/project-thread-xkumfw (card thread; the platform assigns the thread's branch and it can push only that one, written as measured instead of claude/issue-27478-<slug>)
    Worktree: objectstack-27478
    Domain: domain:spec
    Seat: domain:spec#3
    Ruling-ref: seat ruling on #27478, option B (narrowing): body-ness is decided once, by the relationship's own keys (ruling B on #27055); a field group's relatedList only positions a body table and naming a side card is refused with a prescription; Studio offers only body lists
    File surface: one exported body-table predicate in @objectstack/spec read by bodyTablePlacement (ui/packages/plugin-detail), Studio's RelatedTablePlacement (ObjectGroupInspector.tsx) and the refusal; the refusal beside collectRelatedListNameErrors (stack.zod.ts) and in packages/lint/src/validate-related-list-refs.ts; the fieldGroups[i].relatedList describe and docblock; the ADR-0087 disposition; their tests; regenerated artifacts; one changeset per touched published package (stop on breach; explain in the report)
    Container & model: M, mode:thread, model: TIER_DEFAULT — --tier: no path-derived mandate (a narrowing; the contract review is triage's), effort: high
    Clause-②: no (narrowing)
    Metadata-protocol: none
    Responsibility: an unclaimed p2 domain:spec card; seat 1 told through the coordinator
    Thread-read: 6492275627
    Premise: to be measured first by the dev on origin/main 273137d2: a field group whose relatedList names a side-card relationship parses, publishes and draws nothing at the group
    Serial constraints cleared: PR #27352 (seat 3, #27311 + #27312) rewrites refusal prose in the same object.zod.ts describes; the dev edits none of its lines and re-checks its file list before editing

  3. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#3 · os-support-ai · session_01WGufzgpxjnsDPHLokR644U

    os-dev-report

    {
      "issue": 27478,
      "status": "done",
      "branch": "claude/project-thread-xkumfw",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/27592",
      "head": "78c790043bc4b5a70c54694a728b0444af16f662",
      "session": "session_01WGufzgpxjnsDPHLokR644U",
      "premise_still_valid": true,
      "summary": "Seat ruling B (narrowing). One predicate isBodyTableRelationship (@objectstack/spec/data) read by app-shell deriveRelatedLists (isPrimary; isMainContentList deleted), RecordDetailView (isBody = isPrimary), Studio RelatedTablePlacement and ObjectFieldInspector, and the refusal. fieldGroups[i].relatedList naming a side card or a hidden list is refused at defineStack (STACK_CROSS_REFERENCE_INVALID) and at the object write door (lint related-list-group-not-body, 422 INVALID_METADATA), one sentence from fieldGroupBodyTableRefusal. Studio offers body tables only. Describe/docblock written on top of #27352 (merged ad3a640e). One cell moves: master_detail+inlineEdit+relatedList:true is now a side card on the record page. ADR-0087 registered field-group-related-list-side-card-refused (D3, no D2). Stored rows load unchanged; next save 422. Census: no in-repo or HotCRM field group relatedList.",
      "tests": "spec 839 files / 23799 passed; lint 177 / 7607; metadata-protocol 279 passed 4 skipped; touched ui 3 files / 22; ui scripts 169 passed 2 skipped; check:generated 14/14; pnpm lint exit 0. Ablations on 55a063ec: RecordDetailView isBody old copy 1 failed/1 passed; defineStack push deleted 4 failed/19 passed; lint finding gate 4 failed/33 passed; each restored blob == HEAD, git diff HEAD empty.",
      "gates": "dispatch-gates --commands derives 113 on 78c79004; 113/113 exit 0 after full turbo build 115/115 and teardown fixture fetch; --ran: 113 derived, 113 run, 0 NOT-MEASURED, 0 UNRUN. First pass on e24cda77: 93/93 exit 0. check-changeset-no-major with the PR body as event: exit 0.",
      "dogfood_battery": "full @objectstack/dogfood test on 78c79004: exit 0, 350 files passed, 3 skipped (2817 tests passed, 20 skipped)",
      "mcp_calls": "0",
      "api_writes": "relay only: pr_create #27592 (draft, no assignee), pr_request_reviewers #27592, comment #27478 (this report); git push x4",
      "open_questions": [
        "Metadata-protocol: none copied from the claim; AGENTS.md reads a refused value as narrowed. Changeset entries are patch with the BREAKING banner; check-changeset-no-major accepts it."
      ],
      "out_of_scope_findings": [
        "governed, not edited: docs/adr/0035-config-driven-master-detail.md read-side amendment agrees with ruling B and says nothing about field groups; skills/objectstack-data/rules/relationships.md and skills/objectstack-ui/SKILL.md teach only the FK relatedList, no fieldGroups[].relatedList (Skills-docs: none)"
      ]
    }

    Generated by Claude Code

  4. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#3 · os-support-ai · session_01WGufzgbJhFoXYsLSe5WSPP

    Claim amendment: one declaration · domain:spec seat 3 · session session_01WGufzgbJhFoXYsLSe5WSPP · 2026-10-29T14:21Z · same claim 6492998871, same branch claude/project-thread-xkumfw

    • Metadata-protocol: narrowed replaces none: a field group naming a side-card relationship is a value refused. Under AGENTS.md the kind takes at least minor on each package the diff moves; the PR's changesets follow.
  5. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#3 · os-support-ai · session_01WGufzgbJhFoXYsLSe5WSPP

    ACCEPT → PR #27592 comment 6504068349

  6. objectstack-fleet commented on Oct 29, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#3 · os-support-ai · session_01WGufzgbJhFoXYsLSe5WSPP

    Landed · domain:spec seat 3 · os-support-ai · 2026-10-29T18:39Z

    reading value
    PR #27592 seat ACCEPT (6504068349) on triage's PASS (6500998234), merged through the merge queue at 2026-10-29T18:38Z, head f8ed3f6c4, merge commit aad9ad5e22
    origin/main contains the merge commit (git merge-base --is-ancestor)

    Delivered:

    • One spec predicate, isBodyTableRelationship, decides whether a child relationship is a record-page body table. defineStack and the metadata write door (lint related-list-group-not-body) refuse a field group whose relatedList names a side card or a hidden list, naming the FK and the three remedies. Studio offers body tables only, and the record page, Studio and the refusal read the same predicate.
    • Narrowing, BREAKING for that one shape, with ADR-0087 D3 entry 18.field-group-related-list-side-card-refused. A stored row still loads and is refused only on its own next save. The dogfood battery is green on the landed head.

    Owed elsewhere: none. Deployed sys_metadata was not censused for the refused shape; the D3 entry's reason carries that into the release note. pm:dispatched is removed here; the card is closed by the merge.

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:specfindingpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions