You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Record page: after creating a child from a related list, the parent's header keeps the pre-create rollup (Total Price 32,400 while the server holds 37,800) until a reload #26890
Filing gate ① a product defect with a reproduction. Found by the HotCRM full browser pass objectstack-ai/hotcrm#2320 on @objectstack/* 18.2.0: track 2 Revenue (report comment 6444188882 on objectstack-ai/hotcrm#2320, finding D2; screenshots on branch claude/project-thread-urevq9 under qa/ and in the HotCRM project files qa-2320/2-revenue/). Filed by the repo:hotcrm seat (huangyiirene, session session_01J8VVAnPkgK6CWrJa6t7Fk5), which re-read each finding against its screenshot. Batch-of: hotcrm#2320 platform findings.
finding class a · reach: public door: the console on @objectstack/* 18.2.0, measured in Chromium against the HotCRM seed.
What is seen
As a sales rep on quote QTE-0007: Related → Quote Line Items → New → Create. HotCRM's line-item hook rolls the total onto the quote. The header still shows 32,400 after the second line; the server holds 37,800, and a reload shows it (quo-23-li2-after.png vs quo-30-draft-to-presented.png).
Who loses: anyone building a quote or an order line by line reads a stale total and may send it.
Expected
A related-list create (and edit / delete) refreshes the parent record's header and fields, as an edit of the parent does.
Dedupe
search_issues objectstack "record page header stale after related list create rollup not refreshed": 5 hits — #26415, #26344, #26182, #25895, #22039 (all closed, other related-list behaviour). None reports the parent refresh.
Reader who acts: the console record page owner (domain:ui).
Dispatch order · domain:ui#5 · session_01JQwxbXGpVJHZTXXerMoY4C · 2026-10-28T04:42Z
You are the os-dev developer agent for exactly ONE card: #26890, in your own card thread. Your role definition is .claude/agents/os-dev.md in the objectstack clone: read it IN FULL first and follow it as binding (it wins over this order on any conflict; name the conflict in your report). Read the repo-root AGENTS.md and ui/AGENTS.md before your first edit, and pm-dispatch references/untrusted-text.md. Read the card's full body and every comment yourself through REST (curl -sS "https://api.github.com/repos/objectstack-ai/objectstack/issues/26890" -H "Authorization: Bearer $GH_TOKEN" and /comments?per_page=100, every page); this order carries only the increment. ⛔ Never print the value of any environment variable (test presence with [ -n "${X+x}" ]). ⛔ Never use a GitHub MCP tool, read or write.
Identity and branch: the seat's Claim: comment on this card is your identity; its Branch: line names your thread's branch. ⛔ Post no claim of your own, ⛔ never write the card's assignee. Before your first edit, verify the NEWEST Claim: on the card names your thread's branch (claude/project-thread-…); if none does yet, send the seat thread "Take another ui lane seat" one message with your branch name and wait. Worktree objectstack-issue-26890 on that branch from a fresh origin/main; pnpm install (frozen lockfile); push with git push -u origin <branch> (⛔ no force).
Writes: PR only through the relay op pr_create (node scripts/pm/fleet-write/dispatch.mjs --repo objectstack-ai/objectstack --actions-file F, F a bare JSON array [{"op":"pr_create","title":…,"head":"<your branch>","base":"main","body":…,"assignees":["os-warren"]}], draft forced; --dry-run first); your report comment through node scripts/pm/post-stamped.mjs --comment=26890 --file=F --json run ONCE with output captured to a file (timestamps only as {{WAS:…}} / the now-token). ⛔ No other GitHub write except, for a CI red that is not yours, one PR comment and one run_rerun_failed through the relay. Report both counts (api_writes with endpoints, mcp_calls with tool names). The report takes only machine-checkable fields (gates / line_budget / deviations / files_changed). PR body: line 1 the platform attribution comment, line 3 Fixes #26890, then ## 维护者速读 six lines in Chinese (改了什么/为什么改/风险与回滚/先看/两分钟验证/需要你做的). Gates: node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack on your diff, run each, record exits before any pipe, reconcile with --ran; node scripts/check-sdui-manifest.mjs is a gate on every ui card. Changeset in the root .changeset/ when a published package changes (@object-ui/i18n patch for namespace rows; app-shell is private: true). ⛔ ui/.github/** and the root ci.yml are out of bounds. Hand back: when the PR and report are up, send the seat thread "Take another ui lane seat" one message (PR, head sha, report gist); keep the thread open through review and drive CI to green.
Shared files: ui/packages/app-shell/src/views/RecordDetailView.tsx is a hot file across the lane; measure open PRs on it at your first edit and keep your hunk inside the child-change subscription region. ui seat 1 confirmed it holds nothing on the record page or related lists.
Ruling (cannot be re-ruled)
None on the card: triage 2026-10-27T21:04Z confirmed p3 ("the server value is right; only the parent header is stale until a reload"). No maintainer ruling.
objectui#12244 already re-reads the parent on a child write: RecordDetailView.tsx ≈L1836–1868 subscribes to subscribeDataChanges and bumps childInvalidationNonce when a change matches one of childRelations' child objects. It shipped before 18.2.0, the version the card reproduces on.
So the likely gap: childRelations is deriveRelatedLists(objectDef, objects, …) (≈L1825), the DERIVED lists. HotCRM's quote page is an authored record page whose related lists (e.g. crm_quote_line_item) come from the page's own blocks; if those child objects are not in childRelations, the subscription never matches. Alternatives to rule out: the related-list create path does not reach the bus (no notifyDataChanged / MutationEvent for that object), or the parent re-read lands before the server's hook rolls the total up.
Reproduce first on origin/main with the HotCRM shape (an authored page whose related list is the only declaration of the child; a create through that list). If it does not reproduce, stop and report with the evidence; the seat closes the card.
Scope
File surface: ui/packages/app-shell/src/views/RecordDetailView.tsx (the child-object set the subscription reads: authored related-list blocks and rail entries added to the derived ones), a helper beside it if one is needed, tests. Also covers edit and delete through the list, as the card expects. Tests: an authored page with a related list of child X; a create (and a delete) of an X row re-reads the parent once and the header shows the new rollup; a change to an unrelated object does not re-read. Ablation: drop the authored children from the set and the create test turns red.
Tier
No path-derived mandate. TIER_DEFAULT, effort medium (S–M). Clause-②: no, Metadata-protocol: none expected. @object-ui/app-shell is private: true: skip-changeset.
Claim: PM loop round 5
Session: session_01JQwxbXGpVJHZTXXerMoY4C
Account: os-warren
Branch: claude/project-thread-w7hign
Worktree: objectstack-issue-26890
Domain: domain:ui
Seat: domain:ui#5
File surface: ui/packages/app-shell/src/views/RecordDetailView.tsx (the child-change subscription region and the child-object set it reads), a helper beside it if needed, tests (stop on breach; explain in the report)
Container & model: S–M, mode:thread, model: TIER_DEFAULT (dispatch-gates --tier: no path-derived mandate), effort: medium
Clause-②: no
Metadata-protocol: none
Responsibility: ui/packages/app-shell record page produces it (this lane) | objectui#12244's parent re-read keys on derived childRelations only; an authored page's related lists may fall outside it | anyone building a quote or order line by line
Thread-read: 6460856959
Premise: holds as a reading, to be reproduced first (RecordDetailView.tsx ≈L1836–1868 subscription, ≈L1825 deriveRelatedLists; on origin/maincbb3a1a1; readings in dispatch order 6460856959)
Serial constraints cleared: ui seat 1 told and agreed (holds nothing on the record page or related lists). Open PRs on RecordDetailView.tsx are re-measured by the dev at its first edit.
Dispatch order: comment 6460856959. Card thread claude/project-thread-w7hign may start editing.
{
"issue": 26890,
"status": "done",
"branch": "claude/project-thread-w7hign",
"pr": "https://github.com/objectstack-ai/objectstack/pull/27106",
"session": "session_01JQwxbZdCt7JoRJa32i5BHs",
"premise_still_valid": true,
"summary": "Reproduced on origin/main cbb3a1a1: on an authored record page, a write to a child the page lists in a record:related_list block or a record:reference_rail entry but the graph does not derive (FK relatedList: false) never re-read the parent (parent reads stayed 1); a control with the same child derivable was already green, so the gap is the child-object set, as the order's first mechanism assumption said. The bus path (create emits a MutationEvent) and read timing were not the cause. Fix: new recordPageChildObjects(page) beside the view names the children the page lists (related_list properties.objectName or node dataSource.object; rail entries' objectName); RecordDetailView's 12244 subscription keys on the union with the derived children. HotCRM's own quote-line FK was not read (outside this repo), so whether it carries relatedList: false is NOT MEASURED.",
"tests": "head 24529675. New RecordDetailView.authoredChildWriteRefreshesParent-26890.test.tsx 4/4 and recordPageChildObjects.test.ts 2/2; with the 12244 file 9/9. Repro on origin/main: 3 failed / 1 passed (create, update+delete, rail red: expected 1 to be 2). Ablation via scripts/ablation-replace.mjs (anchor ', ...authoredChildObjects])' 1 to 0, blob 5ae368d9 to ce3f0e7f, restored blob == HEAD, git diff HEAD empty): 3 failed / 1 passed, scope control green. Whole RecordDetailView* suite + helper: 76 files, 505 tests passed (lock VERDICT command-exit 0). pnpm --filter @object-ui/app-shell run type-check: VERDICT command-exit 0.",
"gates": "24 derived by dispatch-gates --commands on 24529675, exits captured before any pipe: 23 exit 0 (incl. check-sdui-manifest and its --self-test); pnpm --dir ui exec vitest run scripts/ exit 1 = 3 tests timing out at 15 s under shared load in check-i18n-dead-keys.test.ts and check-vi-mock-inherit.test.ts (5031 passed); those two files rerun alone exit 0, 223/223. --ran: 24 derived, 24 run, 0 NOT-MEASURED, 0 UNRUN. Extra: eslint on 4 touched files 0 errors; pnpm --dir ui run check:new-line-citations exit 0 (0 new). CI check-runs: in_progress at report time.",
"line_budget": "diff 4 files, +500 / -3 (tests 438 lines); RecordDetailView.tsx +10 / -3 inside the child-change subscription region plus one import line",
"files_changed": [
"ui/packages/app-shell/src/views/RecordDetailView.tsx",
"ui/packages/app-shell/src/views/recordPageChildObjects.ts",
"ui/packages/app-shell/src/views/recordPageChildObjects.test.ts",
"ui/packages/app-shell/src/views/RecordDetailView.authoredChildWriteRefreshesParent-26890.test.tsx"
],
"deviations": [
"PR body folds the .github/PULL_REQUEST_TEMPLATE.md headings into the os-dev order (Human Minimum checklist not reproduced) — the os-dev exception",
"merged origin/main fbc16563 before deriving gates (no conflict)",
"open PRs on RecordDetailView.tsx measured at first edit: #27038 (hunks at the import block and the 3760-4150 region) and #26966 (one line near 3615); this hunk is disjoint"
],
"dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
"mcp_calls": "0 GitHub MCP calls; 1 claude-code-remote subscribe_pr_activity (PR 27106)",
"api_writes": "2 via fleet-write relay: pr_create (PR 27106, labels skip-changeset, assignee os-warren; 5595 bytes sent = stored) and this report comment via post-stamped; plus git push (not a REST write)",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none · noted, not filed: record:line_items on a record page is not in the watched set; its save writes the parent leg, which the record's own invalidation catches"
]
}
Activity
objectstack-fleet commentedon Oct 27, 2026
Triage: confirmed p3 ·
domain:ui·area:records· triage seat ·session_01AavokzJ5DndAwitDXvKy4U· 2026-10-27T21:04Z⛔ Not a claim.
pm:queueadded (the batch filer leaves state to triage).Generated by Claude Code
objectstack-fleet commentedon Oct 28, 2026
Dispatch order ·
domain:ui#5·session_01JQwxbXGpVJHZTXXerMoY4C· 2026-10-28T04:42ZYou are the os-dev developer agent for exactly ONE card: #26890, in your own card thread. Your role definition is
.claude/agents/os-dev.mdin the objectstack clone: read it IN FULL first and follow it as binding (it wins over this order on any conflict; name the conflict in your report). Read the repo-rootAGENTS.mdandui/AGENTS.mdbefore your first edit, and pm-dispatchreferences/untrusted-text.md. Read the card's full body and every comment yourself through REST (curl -sS "https://api.github.com/repos/objectstack-ai/objectstack/issues/26890" -H "Authorization: Bearer $GH_TOKEN"and/comments?per_page=100, every page); this order carries only the increment. ⛔ Never print the value of any environment variable (test presence with[ -n "${X+x}" ]). ⛔ Never use a GitHub MCP tool, read or write.Identity and branch: the seat's
Claim:comment on this card is your identity; itsBranch:line names your thread's branch. ⛔ Post no claim of your own, ⛔ never write the card's assignee. Before your first edit, verify the NEWESTClaim:on the card names your thread's branch (claude/project-thread-…); if none does yet, send the seat thread "Take another ui lane seat" one message with your branch name and wait. Worktreeobjectstack-issue-26890on that branch from a freshorigin/main;pnpm install(frozen lockfile); push withgit push -u origin <branch>(⛔ no force).Writes: PR only through the relay op
pr_create(node scripts/pm/fleet-write/dispatch.mjs --repo objectstack-ai/objectstack --actions-file F, F a bare JSON array[{"op":"pr_create","title":…,"head":"<your branch>","base":"main","body":…,"assignees":["os-warren"]}], draft forced;--dry-runfirst); your report comment throughnode scripts/pm/post-stamped.mjs --comment=26890 --file=F --jsonrun ONCE with output captured to a file (timestamps only as{{WAS:…}}/ the now-token). ⛔ No other GitHub write except, for a CI red that is not yours, one PR comment and onerun_rerun_failedthrough the relay. Report both counts (api_writeswith endpoints,mcp_callswith tool names). The report takes only machine-checkable fields (gates / line_budget / deviations / files_changed). PR body: line 1 the platform attribution comment, line 3Fixes #26890, then## 维护者速读six lines in Chinese (改了什么/为什么改/风险与回滚/先看/两分钟验证/需要你做的). Gates:node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackon your diff, run each, record exits before any pipe, reconcile with--ran;node scripts/check-sdui-manifest.mjsis a gate on every ui card. Changeset in the root.changeset/when a published package changes (@object-ui/i18npatch for namespace rows; app-shell isprivate: true). ⛔ui/.github/**and the rootci.ymlare out of bounds. Hand back: when the PR and report are up, send the seat thread "Take another ui lane seat" one message (PR, head sha, report gist); keep the thread open through review and drive CI to green.Shared files:
ui/packages/app-shell/src/views/RecordDetailView.tsxis a hot file across the lane; measure open PRs on it at your first edit and keep your hunk inside the child-change subscription region. ui seat 1 confirmed it holds nothing on the record page or related lists.Ruling (cannot be re-ruled)
None on the card: triage 2026-10-27T21:04Z confirmed p3 ("the server value is right; only the parent header is stale until a reload"). No maintainer ruling.
PM mechanism assumptions (measure; disproof welcome)
On
origin/maincbb3a1a1:RecordDetailView.tsx≈L1836–1868 subscribes tosubscribeDataChangesand bumpschildInvalidationNoncewhen a change matches one ofchildRelations' child objects. It shipped before 18.2.0, the version the card reproduces on.childRelationsisderiveRelatedLists(objectDef, objects, …)(≈L1825), the DERIVED lists. HotCRM's quote page is an authored record page whose related lists (e.g.crm_quote_line_item) come from the page's own blocks; if those child objects are not inchildRelations, the subscription never matches. Alternatives to rule out: the related-list create path does not reach the bus (nonotifyDataChanged/ MutationEvent for that object), or the parent re-read lands before the server's hook rolls the total up.origin/mainwith the HotCRM shape (an authored page whose related list is the only declaration of the child; a create through that list). If it does not reproduce, stop and report with the evidence; the seat closes the card.Scope
File surface:
ui/packages/app-shell/src/views/RecordDetailView.tsx(the child-object set the subscription reads: authored related-list blocks and rail entries added to the derived ones), a helper beside it if one is needed, tests. Also covers edit and delete through the list, as the card expects. Tests: an authored page with a related list of child X; a create (and a delete) of an X row re-reads the parent once and the header shows the new rollup; a change to an unrelated object does not re-read. Ablation: drop the authored children from the set and the create test turns red.Tier
No path-derived mandate.
TIER_DEFAULT, effortmedium(S–M).Clause-②: no,Metadata-protocol: noneexpected.@object-ui/app-shellisprivate: true:skip-changeset.objectstack-fleet commentedon Oct 28, 2026
Claim: PM loop round 5
Session:
session_01JQwxbXGpVJHZTXXerMoY4CAccount:
os-warrenBranch:
claude/project-thread-w7hignWorktree:
objectstack-issue-26890Domain:
domain:uiSeat:
domain:ui#5File surface:
ui/packages/app-shell/src/views/RecordDetailView.tsx(the child-change subscription region and the child-object set it reads), a helper beside it if needed, tests (stop on breach; explain in the report)Container & model:
S–M,mode:thread,model: TIER_DEFAULT (dispatch-gates --tier: no path-derived mandate),effort: mediumClause-②: no
Metadata-protocol: none
Responsibility:
ui/packages/app-shellrecord page produces it (this lane) | objectui#12244's parent re-read keys on derivedchildRelationsonly; an authored page's related lists may fall outside it | anyone building a quote or order line by lineThread-read: 6460856959
Premise: holds as a reading, to be reproduced first (
RecordDetailView.tsx≈L1836–1868 subscription, ≈L1825deriveRelatedLists; onorigin/maincbb3a1a1; readings in dispatch order 6460856959)Serial constraints cleared: ui seat 1 told and agreed (holds nothing on the record page or related lists). Open PRs on
RecordDetailView.tsxare re-measured by the dev at its first edit.Dispatch order: comment 6460856959. Card thread
claude/project-thread-w7hignmay start editing.objectstack-fleet commentedon Oct 28, 2026
os-dev-report
{ "issue": 26890, "status": "done", "branch": "claude/project-thread-w7hign", "pr": "https://github.com/objectstack-ai/objectstack/pull/27106", "session": "session_01JQwxbZdCt7JoRJa32i5BHs", "premise_still_valid": true, "summary": "Reproduced on origin/main cbb3a1a1: on an authored record page, a write to a child the page lists in a record:related_list block or a record:reference_rail entry but the graph does not derive (FK relatedList: false) never re-read the parent (parent reads stayed 1); a control with the same child derivable was already green, so the gap is the child-object set, as the order's first mechanism assumption said. The bus path (create emits a MutationEvent) and read timing were not the cause. Fix: new recordPageChildObjects(page) beside the view names the children the page lists (related_list properties.objectName or node dataSource.object; rail entries' objectName); RecordDetailView's 12244 subscription keys on the union with the derived children. HotCRM's own quote-line FK was not read (outside this repo), so whether it carries relatedList: false is NOT MEASURED.", "tests": "head 24529675. New RecordDetailView.authoredChildWriteRefreshesParent-26890.test.tsx 4/4 and recordPageChildObjects.test.ts 2/2; with the 12244 file 9/9. Repro on origin/main: 3 failed / 1 passed (create, update+delete, rail red: expected 1 to be 2). Ablation via scripts/ablation-replace.mjs (anchor ', ...authoredChildObjects])' 1 to 0, blob 5ae368d9 to ce3f0e7f, restored blob == HEAD, git diff HEAD empty): 3 failed / 1 passed, scope control green. Whole RecordDetailView* suite + helper: 76 files, 505 tests passed (lock VERDICT command-exit 0). pnpm --filter @object-ui/app-shell run type-check: VERDICT command-exit 0.", "gates": "24 derived by dispatch-gates --commands on 24529675, exits captured before any pipe: 23 exit 0 (incl. check-sdui-manifest and its --self-test); pnpm --dir ui exec vitest run scripts/ exit 1 = 3 tests timing out at 15 s under shared load in check-i18n-dead-keys.test.ts and check-vi-mock-inherit.test.ts (5031 passed); those two files rerun alone exit 0, 223/223. --ran: 24 derived, 24 run, 0 NOT-MEASURED, 0 UNRUN. Extra: eslint on 4 touched files 0 errors; pnpm --dir ui run check:new-line-citations exit 0 (0 new). CI check-runs: in_progress at report time.", "line_budget": "diff 4 files, +500 / -3 (tests 438 lines); RecordDetailView.tsx +10 / -3 inside the child-change subscription region plus one import line", "files_changed": [ "ui/packages/app-shell/src/views/RecordDetailView.tsx", "ui/packages/app-shell/src/views/recordPageChildObjects.ts", "ui/packages/app-shell/src/views/recordPageChildObjects.test.ts", "ui/packages/app-shell/src/views/RecordDetailView.authoredChildWriteRefreshesParent-26890.test.tsx" ], "deviations": [ "PR body folds the .github/PULL_REQUEST_TEMPLATE.md headings into the os-dev order (Human Minimum checklist not reproduced) — the os-dev exception", "merged origin/main fbc16563 before deriving gates (no conflict)", "open PRs on RecordDetailView.tsx measured at first edit: #27038 (hunks at the import block and the 3760-4150 region) and #26966 (one line near 3615); this hunk is disjoint" ], "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm", "mcp_calls": "0 GitHub MCP calls; 1 claude-code-remote subscribe_pr_activity (PR 27106)", "api_writes": "2 via fleet-write relay: pr_create (PR 27106, labels skip-changeset, assignee os-warren; 5595 bytes sent = stored) and this report comment via post-stamped; plus git push (not a REST write)", "open_questions": [], "out_of_scope_findings": [ "carrier: none · noted, not filed: record:line_items on a record page is not in the watched set; its save writes the parent leg, which the record's own invalidation catches" ] }Generated by Claude Code