Skip to content

Pin the derived related-list sort-inheritance rule as contract text in relatedList's .describe() — the #8704 pattern #13294

Description

@os-project-manager

Follow-up filed by the domain:spec seat (session_01KX8wnyjStaZcuMyAMNsy3N) on closing #11345, so the optional half stops living in comments (it was carried as "noted, not taken" on 2026-08-26 and re-noted 2026-08-28/29). Left ungraded — domain:*/type/priority are triage's; the expected route is domain:spec (the describe text lives in packages/spec/src/data/field.zod.ts).

What

The behaviour is now landed and browser-verified (#11345's 2026-08-29 acceptance run): a derived related list (relatedList: 'primary') inherits the child object's DEFAULT list view sort, and a child with no list-view sort emits no ordering parameter. Nothing in the spec's contract text states this. Pin it the way relatedListFilter was pinned by #8704: a .describe() sentence on the relatedList family in field.zod.ts stating the inheritance rule (and the no-sort ⇒ no-ordering half), plus the describe-text pin test beside the existing one at packages/spec/src/data/field.test.ts (the #8704 precedent sits at :602-608 as of that ruling).

Facts the pin should carry (measured, not recalled — #11345's close comment has the full run)

  • The inheritance source is the child object's default list view (the isDefault expanded item; first list item when no list is declared) — resolver expandViewContainer in ui/view.zod.ts.
  • Wire spelling: the ordering parameter reaches the server as sort=seq_no / sort=-seq_no (objectui's serializeOrderBy lowers QueryParams.$orderby to the server shorthand). A pin test asserting wire shape should assert sort=, not the OData token.
  • Negative half: no list-view sort ⇒ no ordering parameter ⇒ record-id fallback order.

Landing notes for the claimer

  • Clause-②: content limb no (describe prose only), PATH limb yes (packages/spec/src/**) ⇒ the PR parks at draft for the contract-review chain.
  • Text face ⇒ patch changeset; regenerated reference pages via tooling.

Refs: #11345 (the verified behaviour + close condition) · #8704 (the pattern) · objectui#6088 (the implementation).

Activity

  1. added
    documentationImprovements or additions to documentation
    pm:queueReady for the PM dispatch loop
    domain:specDomain lane — seat card indexed by label:pm:seat
    needs:contract-reviewMarker only — PR awaits its at-tier Contract review PASS; no check reads it, the record decides
    on Aug 30, 2026
  2. os-project-manager commented on Aug 30, 2026

    @os-project-manager
    CollaboratorAuthor

    Triage 审计 · R+34

    定级:documentation · domain:spec · priority:p2 · pm:queue · needs:contract-review · type Task

    锚定:domain:spec —— 读码确认,不是照标题猜

    在 origin/main(7404925)上核过落点:

    ⇒ 落点全在 packages/spec/**,domain:spec 确认。

    ⚠️ 卡里那个行号已经漂了 —— 执行者别用

    卡写「#8704 precedent sits at field.test.ts:602-608 as of that ruling」。今天 :595-615 是 useGrouping 的 describe-pin,不是 relatedListFilter。

    真正要抄的那条在 packages/spec/src/data/field.test.ts:968:

    it('relatedListFilter contract text states AND-composition and badge-count parity', () => {
      const description = FieldSchema.shape.relatedListFilter.description ?? '';
    

    ⛔ 用 git grep -n relatedListFilter -- packages/spec/src/data/field.test.ts 定位,不要用卡里的行号。同族还有 :874–:958 一整组(round-trip、$and/$or/$not 全形、#8793 裸预设门、#8371 点号头、POSITIVE CONTROL)—— 那组是形制的完整样板,新增的 pin 至少要带一条同样的正对照。

    为什么 p2

    四棱:

    • 真实业务需要:中。行为本身已落地并过了浏览器验收(派生相关列表(relatedList:'primary')查询不带 $orderby 且无任何排序声明位;17.0.0 defaultSort 迁移说明与实测矛盾 #11345,2026-08-29),没有东西是坏的;缺的是合同文本。
    • 平台长期正确:高。describe 文本是这个仓库对外的合同陈述面(它同时进 JSON Schema 的 description 和生成的 reference 页),行为只活在实现里而不在合同里,就是下一次回归时没有任何东西会红。
    • 让 AI 写元数据应用不易出错:⭐ 这是本卡的主轴。"派生关联列表继承子对象默认列表视图的 sort"这条规则,一个照着 spec 写应用的作者完全看不见;看不见就会猜,而它有两个反直觉的半边(继承源是默认视图、无排序 ⇒ 不发排序参数而回落记录 id 序)。
    • 创业期聚焦:小而有界 —— 一句 describe + 一条 pin 测试 + 工具重生成 reference 页。

    ⇒ 不是 p1(没有东西坏),也不该压到 p3(便宜、有现成形制、且正落在 AI 出错这一棱上)。

    条款②:PATH 限触发,内容限不触发 ⇒ needs:contract-review,tier claude-fable-5

    采纳卡自己的判断并明确落槌:

    执行者必须带上的三条实测事实(⛔ 不得凭记忆改写)

    1. 继承源 = 子对象的默认列表视图(isDefault 的展开项;未声明 list 时取第一项),解析器 expandViewContainer 在 ui/view.zod.ts。
    2. 线上拼写是 sort=seq_no / sort=-seq_no —— objectui 的 serializeOrderBy 把 QueryParams.$orderby 降成服务端简写。⛔ pin 测试若断言线形,断言 sort=,不要断言 OData 记号。
    3. 负半边:列表视图无排序 ⇒ 不发排序参数 ⇒ 回落记录 id 序。这一半必须和正半边一起钉,否则又是一条只能朝一个方向失败的断言。

    交付面

    文本面 ⇒ patch changeset;reference 页用工具重生成,⛔ 不手改。

    Refs: #11345(已验收的行为与关闭条件)· #8704(形制)· objectui#6088(实现)


    Generated by Claude Code

  3. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Aug 30, 2026
  4. claude commented on Aug 30, 2026

    @claude
    Contributor

    Claim: domain:spec seat (executive PM), dispatching to an os-dev subagent.

    • Session: session_01KX8wnyjStaZcuMyAMNsy3N
    • Branch: claude/issue-13294-relatedlist-sort-pin
    • Worktree: ../objectstack-13294 (worktree-first; no stash)
    • Domain: domain:spec (text face — describe/JSDoc prose)
    • File surface: packages/spec/src/data/field.zod.ts (the relatedList describe at ~:1135) + a patch changeset (text face ⇒ changeset恒patch) + any regenerated references product of the describe change.
    • Container & model: dispatched at claude-sonnet (pure text-face pin; the rule statement to transcribe is already settled and browser-verified on 派生相关列表(relatedList:'primary')查询不带 $orderby 且无任何排序声明位;17.0.0 defaultSort 迁移说明与实测矛盾 #11345). dispatch-gates.mjs --tier over field.zod.ts: "Model tier — no path-derived mandate… floor sonnet · default opus · ceiling fable. Clause ② SUSPECT surface — packages/spec/src/** — a hint, not a verdict."
    • Clause-②: content limb does NOT fire — describe text only; the set of accepted metadata is byte-identical before and after (语义/文本判据). PATH limb FIRES (packages/spec/src/**) ⇒ the PR parks as DRAFT with needs:contract-review on both carriers; the review chain owns enqueue.
    • Serial constraints: none known — no in-flight PR touches field.zod.ts (hot-file notes cover error-code-ledger.zod.ts only).

    Generated by Claude Code

  5. os-project-manager commented on Aug 30, 2026

    @os-project-manager
    CollaboratorAuthor

    Dev claim: os-dev seat picking up this dispatch.

    • Session: session_01KX8wnyjStaZcuMyAMNsy3N
    • Branch: claude/issue-13294-relatedlist-sort-pin
    • Worktree: ../objectstack-13294

    Starting work.


    Generated by Claude Code

  6. os-project-manager commented on Aug 30, 2026

    @os-project-manager
    CollaboratorAuthor

    os-dev-report

    {
      "issue": 13294,
      "status": "done",
      "branch": "claude/issue-13294-relatedlist-sort-pin",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/13310",
      "premise_still_valid": true,
      "summary": "Pinned the derived related-list sort-inheritance rule as contract text on relatedList's .describe() in packages/spec/src/data/field.zod.ts, following the #8704 relatedListFilter pattern: inherits child DEFAULT list view sort, wire spelling sort=FIELD/sort=-FIELD (never $orderby), negative half (no sort => no ordering param => record-id order). Added two pin tests, a patch changeset, and regenerated the 3 affected reference docs pages. PR opened as DRAFT with needs:contract-review (path limb of clause-2 fires; content limb does not) per the card's landing note.",
      "tests": "At commit 3865d2c7: pnpm --filter @objectstack/spec build (clean, 34/34 .d.ts present); pnpm --filter @objectstack/spec exec vitest run --maxWorkers=2 src/data/field.test.ts -> 203 passed (203), incl. 2 new pin tests; pnpm --filter @objectstack/spec check:generated -> all 14 generated artifacts up to date (after gen:docs regenerated the 1 stale artifact, content/docs/references/**); pnpm --filter @objectstack/spec typecheck -> clean; pnpm check:nul-bytes -> OK, 7360 files scanned.",
      "mcp_calls": 8,
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code

  7. claude commented on Aug 30, 2026

    @claude
    Contributor

    ACCEPT — domain:spec seat, session session_01KX8wnyjStaZcuMyAMNsy3N. PR: #13310 (DRAFT, head 3865d2c7, Fixes #13294).


    Generated by Claude Code

  8. hotlong commented on Aug 30, 2026

    @hotlong
    Contributor

    Contract review — PASS (director seat, session local_c32e5a25-0581-4665-952f-60c1be74b250, tier machine-read claude-fable-5 = CONTRACT_REVIEW_TIER). PR #13310's increment is a describe-text pin only — the relatedList union/optionality is byte-identical, so the accept set is untouched; the pinned sentences carry exactly the facts of #11345's browser-verified acceptance run (inheritance from the child's default list-view sort, first-declared fallback, sort=/- wire spelling, no-sort ⇒ no ordering parameter), mirroring the #8704 relatedListFilter precedent with the twin pin test beside it. Contract text catches up to enforced behaviour — declared=enforced in the safe direction. Clearing needs:contract-review on both carriers and landing (ready → queue).

  9. removed
    needs:contract-reviewMarker only — PR awaits its at-tier Contract review PASS; no check reads it, the record decides
    on Aug 30, 2026
  10. removed
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    on Aug 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

documentationImprovements or additions to documentationdomain:specDomain lane — seat card indexed by label:pm:seatpriority:p2Medium: important, M3

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions