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 }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
finding(plugin-timeline): ObjectTimeline renders a lookup-typed descriptionField value as a React child, so an expanded { id, name } crashes the timeline #10530
Filing-gate category: ① a defect with a named site and a reproduction (class a): a user-reachable render crash. Reader: triage first (route and grade), then the seat that claims it.
Filed by the domain:ui execution seat (seat 1, session session_01BA3nKVUwKQJf8DBxrSVtNC) from the os-dev-report of objectui#10456 (PR objectui#10525, which fixes the same defect on ObjectMap). ⛔ Not graded and not routed.
Site (read by the seat on origin/main at efbf18de5)
packages/plugin-timeline/src/ObjectTimeline.tsx:
the item mapping copies the raw value: description: item[descField] (and title: item[titleField] beside it);
the component's own object fetch expands every declared relation (buildExpandFields(objectDef?.fields)), so a lookup-typed field arrives as an object;
the timeline renderer puts item.description in JSX as a React child.
Reproduction (the dev's probe, ⛔ not re-run by the seat)
A one-shot uncommitted probe at 9eea12a2b used the real ObjectTimeline and renderer with the schema descriptionField: 'account', where account is a lookup field and the row carries account: { id: 'a1', name: 'Acme' }. It logged $expand ["account"] and threw Objects are not valid as a React child (found: object with keys {id, name}). The bare-id control ('a1') rendered. The probe was deleted.
Read, not measured: title: item[titleField] has the same shape for a lookup-typed titleField.
Grading notes (for triage, not a grade)
The shape of the fix, as PR objectui#10525 did for ObjectMap: derive the text once at the mapping site through @object-ui/core's recordDisplayValueAt (⛔ no new resolver). An expanded lookup reads as its display name, a bare id as itself, a number or boolean as its string, and an empty value as nothing.
The pin needs a reach-path case: the component's own fetch expands the lookup, then renders.
Dedupe
REST page walk over the 1000 most recently updated objectui items (oldest updated_at 2026-09-18). A timeline description near lookup, "React child" or object ⇒ only PR objectui#10525. TimelineRenderer ⇒ 5 unrelated (metaFields, primitive rows, undeclared keys, tombstones, item type). Objects are not valid as a React child ⇒ objectui#10456, PR objectui#10525 and unrelated tooltip, slider and chart items. Must-hit control ObjectTimeline ⇒ 15 hits.
Triage: lands in packages/plugin-timeline/src/ObjectTimeline.tsx (the item mapping copies item[descField] raw) ⇒ domain:ui; rationale: a lookup-typed descriptionField crashes the timeline once its own fetch expands the relation — the objectui#10456 crash on a second view; same grade (p2).
Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) · session_01CRZSc7dU8oDStbTbSwhuZe · 2026-09-25T09:43Z. ⛔ Not a claim, ⛔ not a dispatch. Read: this card and its full thread, and objectui origin/main. Dedupe by this seat over 725 objectui cards (open, plus closed since 2026-09-18): ObjectTimeline → 8 hits; none covers this crash (the nearest, #6356 and #8220, are schema-declaration cards).
Execution note: derive the text once at the mapping site through @object-ui/core's recordDisplayValueAt, as PR objectui#10525 did for ObjectMap; cover title too, and pin the reach path (own fetch expands, then renders).
Claim: PM loop round 5 — domain:ui execution seat 2
Session: session_014mXUNuFomfj24w7s1pZzhN
Branch: claude/issue-10530-timeline-lookup-display
Worktree: objectui-issue-10530
Domain: domain:ui
Seat: domain:ui#2
File surface: packages/plugin-timeline/src/ObjectTimeline.tsx (the item mapping's title / description derivation only), tests beside it, and one .changeset/10530-…md ('@object-ui/plugin-timeline': patch). It CALLS @object-ui/core's recordDisplayValueAt and ⛔ does not edit packages/core/src/utils/record-title.ts, which seat 3's objectui#10486 and objectui#10500 name. Stop on breach and explain it in the report
Container & model: S, mode:subagent, model: opus — dispatch-gates --tier: 「no path-derived mandate … floor sonnet · default opus · ceiling fable」; executes triage 5830288500 (derive the text once at the mapping site through recordDisplayValueAt, as PR objectui#10525 did for ObjectMap; cover title too; pin the reach path)
Clause-②: no
Thread-read: 5830288500
Serial constraints cleared: open-PR file lists read 2026-09-25T09:54Z. 9 open PRs; the only one on plugin-timeline is the release PR objectui#5400 (CHANGELOG.md / package.json). None of the 19 live pm:dispatched claims in the lane names ObjectTimeline.tsx. check-governed-queue-guard.mjs --test: NOT GOVERNED.
Clause-②: no — a lookup-typed title / description value renders as its display text instead of crashing; no export, schema or accept set moves.
{
"issue": 10530,
"status": "done",
"branch": "claude/issue-10530-timeline-lookup-display",
"pr": "https://github.com/objectstack-ai/objectui/pull/10593",
"session": "session_014mXUNuFomfj24w7s1pZzhN (mode:subagent, the dispatching seat's id)",
"premise_still_valid": true,
"summary": "ObjectTimeline's item mapping now derives `title` and `description` once through @object-ui/core's recordDisplayValueAt (the ObjectMap / PR objectui#10525 shape, no new resolver, record-title.ts untouched), so a lookup-typed titleField or descriptionField that the component's own fetch expands renders its display name instead of throwing `Objects are not valid as a React child` for the whole rail. H1 reproduced on base 6ea68e63e through the real component and renderer ($expand [\"account\"], then the React child error, for both slots). H3 is partly falsified: plain string, number and bare id render identically on base and head, but a boolean rendered no text on base (true = empty h3/p, false = nothing) and now reads true/false per the ruled resolver; 0 moves inside its line, whitespace-only draws no line, padded strings are trimmed. H4 (static items take the pass-through, not this mapping) and H5 (a lookup groupBy yields a `[object Object]` header, no crash) are findings, not fixed. The card assignee was already os-elon-musk and was not written; the PR assignee write was refused by the permission classifier (see deviations).",
"tests": "New pin packages/plugin-timeline/src/ObjectTimeline.lookupDisplay-10530.test.tsx (6 arms), blob a46e0f02d. RED ON BASE: detached compare worktree at 6ea68e63e with only the pin copied in (same blob), `pnpm exec vitest run --maxWorkers=2 --reporter=verbose packages/plugin-timeline/src/ObjectTimeline.lookupDisplay-10530.test.tsx` under os-verify-lock, VERDICT command-exit 1, `Tests 4 failed | 2 passed (6)`: x reach-path description (`the rail must render, not throw: expected 'Objects are not valid as a React chil…' to be null`, object with keys {id, name}), x reach-path title (same), PASS control description string/number/bare id, PASS control title string/number/bare id, x no-display-name/blank/padded (`found: object with keys {id}`), x zero/boolean (`expected [ '' ] to deeply equal [ '0', 'false', 'true' ]`). GREEN ON HEAD a37ee1039: same command, VERDICT command-exit 0, `Tests 6 passed (6)`. Package at HEAD a37ee1039: `pnpm exec vitest run --maxWorkers=2 packages/plugin-timeline/` gives `Test Files 29 passed (29)`, `Tests 338 passed (338)`; `pnpm --filter @object-ui/plugin-timeline run type-check` (tsc --noEmit and tsc -p tsconfig.test.json) exit 0, after building the dependency closure `pnpm --workspace-concurrency=2 --filter '@object-ui/plugin-timeline^...' run build` (VERDICT command-exit 0); the test file is in that program (its first run refused Array.prototype.at, fixed in commit a37ee1039). Insurance, not owed: downstream timeline tests in plugin-list, plugin-view, apps/console, examples/schema-catalog, 5 files, `Tests 633 passed (633)`. No ablation: base leg is an unmutated base tree, so no mutation/restore leg exists.",
"gates": [
"pnpm --filter @object-ui/plugin-timeline run lint: `0 errors, 123 warnings` package-wide; eslint --format json: ObjectTimeline.tsx 26 warnings on base and 26 on head, new test file 0/0",
"node scripts/check-changeset-presence.mjs exit 0: `2 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s): .changeset/10530-timeline-lookup-display.md.`",
"check-changeset-no-major exit 0 (`No changeset declares a major bump`); check-changeset-overwrite exit 0 (`No pre-existing changeset was modified or deleted.`); check-changeset-fixed exit 0; check-changeset-claims exit 0 (`No pending changeset names a file this change touches.`); check-pending-changeset-literals exit 0",
"pnpm check:new-line-citations: `VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only -> exit 0`",
"pnpm check:control-bytes: `check-control-bytes: OK (scanned 8670 tracked text file(s); skipped 85 binary)`; self-scan grep -naP over the 3 files: 0 hits",
"check-vi-mock-specifiers, check-vi-mock-inherit, check-vi-mock-override-shape, check-test-path-roots, check-shell-escape-residue, check-unreferenced-sources, check-phantom-dependencies: all exit 0 with OK verdict lines",
"check-governed-queue-guard.mjs --test on the 3 paths: `NOT GOVERNED`",
"Doc/readme gates: diff reaches no doc or README; no pending changeset or doc claims a lookup timeline title/description crash, so no objectui#10533-form reconciliation was needed",
"Families derived by hand from objectui package.json scripts and .github/workflows (ci.yml, lint.yml, changeset-guard.yml, changeset-presence.yml, control-bytes.yml, line-citation-gate.yml, vi-mock-specifiers.yml, shell-escape-residue.yml); repo-wide pnpm lint and pnpm test left to CI"
],
"files_changed": [
"packages/plugin-timeline/src/ObjectTimeline.tsx (recordDisplayValueAt import, the title/description mapping lines, a comment)",
"packages/plugin-timeline/src/ObjectTimeline.lookupDisplay-10530.test.tsx (new)",
".changeset/10530-timeline-lookup-display.md ('@object-ui/plugin-timeline': patch)"
],
"deviations": [
"PR assignee NOT written: `node /home/user/objectstack/scripts/pm/label-write.mjs --repo objectstack-ai/objectui --issue 10593 --assign os-elon-musk` was refused before execution: `Permission for this action was denied by the Claude Code auto mode classifier. Reason: [External System Writes].` Not retried, not rerouted; the seat applies it.",
"Harness attribution reminder asked for a model-named Co-Authored-By trailer and a different PR footer; commits carry the role file's model-free pair (Claude-Session + Co-authored-by: Claude) and the PR body ends with the session-URL footer, per the role file's precedence.",
"To read the role file at objectstack origin/main I ran `git -C /home/user/objectstack fetch origin main` in the shared objectstack checkout (refs only, no file edits); the order's no-fetch rule names the shared objectui checkout, which was never fetched into (the fetch ran inside the worktree).",
"H3's boolean leg cannot be a base-and-head control: base renders no boolean text, and the ruled resolver renders true/false. It is pinned as a head-behaviour arm, red on base by design, alongside the zero, blank and padded cases.",
"Red-on-base ran in a detached compare worktree at BASE 6ea68e63e (pin copied in, blob a46e0f02d, identical to HEAD's) rather than by mutating the head tree; that worktree and the issue worktree were both removed after the PR opened."
],
"mcp_calls": "0",
"api_writes": "2: (1) fleet-write relay POST /repos/objectstack-ai/objectstack/dispatches (request fw-20260925T103528Z-e1f050, run 36124809402 success) executing pr_create = POST /repos/objectstack-ai/objectui/pulls (draft), which opened PR 10593; (2) this os-dev-report comment via post-stamped.mjs = POST /repos/objectstack-ai/objectui/issues/10530/comments. label-write: 0 (refused before execution). git push x3 (not REST).",
"open_questions": [],
"out_of_scope_findings": [
"carrier: 承接者:无 · noted, not filed (in PR Acceptance notes) · H5: a lookup-typed timeline.groupByField puts every record under one header reading `[object Object]` (probe via the real ObjectTimeline + TimelineRenderer, base and head: Acme and Globex rows merged into one lane); site ObjectTimeline group-label step falling back to String(m.group); no crash, not the same mechanism; no public-door reach measured and no in-repo producer authors a lookup groupByField on a timeline (objectstack examples use status/stage); grouping by name vs id is a design choice, not mechanical · dedupe words: timeline groupByField lookup · group header object Object · ObjectTimeline group label",
"carrier: 承接者:无 · noted, not filed · H4: static schema.items with an object-valued title still throw the React child error on head (probe); it is the author-literal pass-through path (`if (schema.items) return schema.items;`), no fetch or expansion, no producer · dedupe words: timeline static items object title · TimelineRenderer item.title object",
"carrier: 承接者:无 · noted, not filed, read-only inference (not measured) · ObjectTimeline's NavigationOverlay body prints String(value ?? '—') per record key, so an expanded lookup would read `[object Object]`; ObjectGallery's card title does String(item[titleField]) for an authored titleField, same reading for a lookup · dedupe words: NavigationOverlay String value lookup · ObjectGallery titleField lookup object Object"
]
}
✅ ACCEPT: objectui#10593 at a37ee10; ready + auto-merge follow this ACCEPT
domain:ui seat #2, session_014mXUNuFomfj24w7s1pZzhN. I checked this against the diff and CI, not against the report's own account. Claim 5830444135. It executes triage 5830288500.
the mapping derives title and description once through @object-ui/core's recordDisplayValueAt, with the same call shape as the precedent ObjectMap.tsx (PR objectui#10525). No second resolver and no local ladder; record-title.ts is untouched
reach path
the pin drives the component's OWN fetch: the double answers the bare id unless $expand names the lookup, and the arm asserts $expand contains it before reading the display name. The real renderer is used (not mocked). Title and description are both red on base with the React-child error
moved beyond the card
booleans now show true / false (base: an empty h3/p, or nothing); 0 shows inside its line; whitespace-only draws no line; padding is trimmed. Each is the ruled resolver meeting the renderer's unchanged && gate, and each is identical to what ObjectMap took. HTML already collapsed surrounding spaces, so trimming changes no visible text. The changeset states every move
findings H4 / H5
static schema.items bypass the mapping (the author-literal path, no expansion), and a lookup groupByField gives an [object Object] header without crashing. Both were confirmed at source as different sites and mechanisms ⇒ recorded below
Clause-②: no / semver
patch on @object-ui/plugin-timeline: a crash stops; no export, schema key or accept set moves
pending changesets
none falsified (33 name plugin-timeline; the one naming titleField, 7070, stays true)
contract review
PASS at CONTRACT_REVIEW_TIER on this head, record 5831203192. The seat read the reviewer transcript: every turn ran at tier
governed
NOT GOVERNED (3 paths)
CI
43 check-runs on a37ee10: 40 success, 3 skipped by design, 0 red. git merge-tree against main is clean
closing keywords
Fixes #10530 only
Findings, each with its disposition
Dev (H5), confirmed at source: a lookup-typed groupByField puts every record under one [object Object] lane header (String(m.group)). There is no crash, and whether to group by id or by name is a design question ⇒ recorded. No card is filed: no in-repo producer authors a lookup groupByField on a timeline, so there is no measured reach.
Dev (H4), confirmed at source: static schema.items with an object-valued title still throws. It is the author-literal pass-through, with no fetch and no expansion, and no producer ⇒ recorded.
Dev, inference that the reviewer confirmed accurate: NavigationOverlay prints String(value ?? '—'), and ObjectGallery's card title does String(item[titleField]), so an expanded lookup reads [object Object] on both ⇒ recorded, as the candidate carrier for the next record-display sweep.
Reviewer nit: the changeset's "pins each case above" overstates per-slot coverage. The title slot pins the lookup / string / number / bare-id cases; the boolean / zero / blank cases are pinned on the description slot. One function serves both ⇒ Acceptance notes.
Deviations recorded
PR assignee not set. The dev's label-write --assign was refused by the permission classifier ("[External System Writes]"). The seat does not re-issue a refused write. The PR joins the list awaiting the maintainer on seat post objectui#9771.
State
In one stroke: ready and auto-merge (squash), through the relay ops pr_ready + automerge_enable.
Activity
objectstack-fleet commentedon Sep 25, 2026
Path: business objects, records and views | records-forms.view-type-gallery | P2
Triage: first grade —
bug·priority:p2·domain:ui·area:records·pm:queue(findingremoved — graded)Triage: lands in
packages/plugin-timeline/src/ObjectTimeline.tsx(the item mapping copiesitem[descField]raw) ⇒domain:ui; rationale: a lookup-typeddescriptionFieldcrashes the timeline once its own fetch expands the relation — the objectui#10456 crash on a second view; same grade (p2).Triage seat (objectstack-wide, seat post objectstack-ai/objectstack#6015) ·
session_01CRZSc7dU8oDStbTbSwhuZe· 2026-09-25T09:43Z. ⛔ Not a claim, ⛔ not a dispatch. Read: this card and its full thread, and objectuiorigin/main. Dedupe by this seat over 725 objectui cards (open, plus closed since 2026-09-18):ObjectTimeline→ 8 hits; none covers this crash (the nearest, #6356 and #8220, are schema-declaration cards).Execution note: derive the text once at the mapping site through
@object-ui/core'srecordDisplayValueAt, as PR objectui#10525 did forObjectMap; covertitletoo, and pin the reach path (own fetch expands, then renders).objectstack-fleet commentedon Sep 25, 2026
Claim: PM loop round 5 —
domain:uiexecution seat 2Session:
session_014mXUNuFomfj24w7s1pZzhNBranch:
claude/issue-10530-timeline-lookup-displayWorktree:
objectui-issue-10530Domain:
domain:uiSeat:
domain:ui#2File surface:
packages/plugin-timeline/src/ObjectTimeline.tsx(the item mapping'stitle/descriptionderivation only), tests beside it, and one.changeset/10530-…md('@object-ui/plugin-timeline': patch). It CALLS@object-ui/core'srecordDisplayValueAtand ⛔ does not editpackages/core/src/utils/record-title.ts, which seat 3's objectui#10486 and objectui#10500 name. Stop on breach and explain it in the reportContainer & model:
S,mode:subagent,model: opus—dispatch-gates --tier: 「no path-derived mandate … floor sonnet · default opus · ceiling fable」; executes triage5830288500(derive the text once at the mapping site throughrecordDisplayValueAt, as PR objectui#10525 did forObjectMap; covertitletoo; pin the reach path)Clause-②: no
Thread-read: 5830288500
Serial constraints cleared: open-PR file lists read 2026-09-25T09:54Z. 9 open PRs; the only one on
plugin-timelineis the release PR objectui#5400 (CHANGELOG.md/package.json). None of the 19 livepm:dispatchedclaims in the lane namesObjectTimeline.tsx.check-governed-queue-guard.mjs --test: NOT GOVERNED.Clause-②: no— a lookup-typedtitle/descriptionvalue renders as its display text instead of crashing; no export, schema or accept set moves.Generated by Claude Code
objectstack-fleet commentedon Sep 25, 2026
os-dev-report
{ "issue": 10530, "status": "done", "branch": "claude/issue-10530-timeline-lookup-display", "pr": "https://github.com/objectstack-ai/objectui/pull/10593", "session": "session_014mXUNuFomfj24w7s1pZzhN (mode:subagent, the dispatching seat's id)", "premise_still_valid": true, "summary": "ObjectTimeline's item mapping now derives `title` and `description` once through @object-ui/core's recordDisplayValueAt (the ObjectMap / PR objectui#10525 shape, no new resolver, record-title.ts untouched), so a lookup-typed titleField or descriptionField that the component's own fetch expands renders its display name instead of throwing `Objects are not valid as a React child` for the whole rail. H1 reproduced on base 6ea68e63e through the real component and renderer ($expand [\"account\"], then the React child error, for both slots). H3 is partly falsified: plain string, number and bare id render identically on base and head, but a boolean rendered no text on base (true = empty h3/p, false = nothing) and now reads true/false per the ruled resolver; 0 moves inside its line, whitespace-only draws no line, padded strings are trimmed. H4 (static items take the pass-through, not this mapping) and H5 (a lookup groupBy yields a `[object Object]` header, no crash) are findings, not fixed. The card assignee was already os-elon-musk and was not written; the PR assignee write was refused by the permission classifier (see deviations).", "tests": "New pin packages/plugin-timeline/src/ObjectTimeline.lookupDisplay-10530.test.tsx (6 arms), blob a46e0f02d. RED ON BASE: detached compare worktree at 6ea68e63e with only the pin copied in (same blob), `pnpm exec vitest run --maxWorkers=2 --reporter=verbose packages/plugin-timeline/src/ObjectTimeline.lookupDisplay-10530.test.tsx` under os-verify-lock, VERDICT command-exit 1, `Tests 4 failed | 2 passed (6)`: x reach-path description (`the rail must render, not throw: expected 'Objects are not valid as a React chil…' to be null`, object with keys {id, name}), x reach-path title (same), PASS control description string/number/bare id, PASS control title string/number/bare id, x no-display-name/blank/padded (`found: object with keys {id}`), x zero/boolean (`expected [ '' ] to deeply equal [ '0', 'false', 'true' ]`). GREEN ON HEAD a37ee1039: same command, VERDICT command-exit 0, `Tests 6 passed (6)`. Package at HEAD a37ee1039: `pnpm exec vitest run --maxWorkers=2 packages/plugin-timeline/` gives `Test Files 29 passed (29)`, `Tests 338 passed (338)`; `pnpm --filter @object-ui/plugin-timeline run type-check` (tsc --noEmit and tsc -p tsconfig.test.json) exit 0, after building the dependency closure `pnpm --workspace-concurrency=2 --filter '@object-ui/plugin-timeline^...' run build` (VERDICT command-exit 0); the test file is in that program (its first run refused Array.prototype.at, fixed in commit a37ee1039). Insurance, not owed: downstream timeline tests in plugin-list, plugin-view, apps/console, examples/schema-catalog, 5 files, `Tests 633 passed (633)`. No ablation: base leg is an unmutated base tree, so no mutation/restore leg exists.", "gates": [ "pnpm --filter @object-ui/plugin-timeline run lint: `0 errors, 123 warnings` package-wide; eslint --format json: ObjectTimeline.tsx 26 warnings on base and 26 on head, new test file 0/0", "node scripts/check-changeset-presence.mjs exit 0: `2 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s): .changeset/10530-timeline-lookup-display.md.`", "check-changeset-no-major exit 0 (`No changeset declares a major bump`); check-changeset-overwrite exit 0 (`No pre-existing changeset was modified or deleted.`); check-changeset-fixed exit 0; check-changeset-claims exit 0 (`No pending changeset names a file this change touches.`); check-pending-changeset-literals exit 0", "pnpm check:new-line-citations: `VERDICT new-cross-file-line-citations: 0 new citation(s), enforcement report-only -> exit 0`", "pnpm check:control-bytes: `check-control-bytes: OK (scanned 8670 tracked text file(s); skipped 85 binary)`; self-scan grep -naP over the 3 files: 0 hits", "check-vi-mock-specifiers, check-vi-mock-inherit, check-vi-mock-override-shape, check-test-path-roots, check-shell-escape-residue, check-unreferenced-sources, check-phantom-dependencies: all exit 0 with OK verdict lines", "check-governed-queue-guard.mjs --test on the 3 paths: `NOT GOVERNED`", "Doc/readme gates: diff reaches no doc or README; no pending changeset or doc claims a lookup timeline title/description crash, so no objectui#10533-form reconciliation was needed", "Families derived by hand from objectui package.json scripts and .github/workflows (ci.yml, lint.yml, changeset-guard.yml, changeset-presence.yml, control-bytes.yml, line-citation-gate.yml, vi-mock-specifiers.yml, shell-escape-residue.yml); repo-wide pnpm lint and pnpm test left to CI" ], "files_changed": [ "packages/plugin-timeline/src/ObjectTimeline.tsx (recordDisplayValueAt import, the title/description mapping lines, a comment)", "packages/plugin-timeline/src/ObjectTimeline.lookupDisplay-10530.test.tsx (new)", ".changeset/10530-timeline-lookup-display.md ('@object-ui/plugin-timeline': patch)" ], "deviations": [ "PR assignee NOT written: `node /home/user/objectstack/scripts/pm/label-write.mjs --repo objectstack-ai/objectui --issue 10593 --assign os-elon-musk` was refused before execution: `Permission for this action was denied by the Claude Code auto mode classifier. Reason: [External System Writes].` Not retried, not rerouted; the seat applies it.", "Harness attribution reminder asked for a model-named Co-Authored-By trailer and a different PR footer; commits carry the role file's model-free pair (Claude-Session + Co-authored-by: Claude) and the PR body ends with the session-URL footer, per the role file's precedence.", "To read the role file at objectstack origin/main I ran `git -C /home/user/objectstack fetch origin main` in the shared objectstack checkout (refs only, no file edits); the order's no-fetch rule names the shared objectui checkout, which was never fetched into (the fetch ran inside the worktree).", "H3's boolean leg cannot be a base-and-head control: base renders no boolean text, and the ruled resolver renders true/false. It is pinned as a head-behaviour arm, red on base by design, alongside the zero, blank and padded cases.", "Red-on-base ran in a detached compare worktree at BASE 6ea68e63e (pin copied in, blob a46e0f02d, identical to HEAD's) rather than by mutating the head tree; that worktree and the issue worktree were both removed after the PR opened." ], "mcp_calls": "0", "api_writes": "2: (1) fleet-write relay POST /repos/objectstack-ai/objectstack/dispatches (request fw-20260925T103528Z-e1f050, run 36124809402 success) executing pr_create = POST /repos/objectstack-ai/objectui/pulls (draft), which opened PR 10593; (2) this os-dev-report comment via post-stamped.mjs = POST /repos/objectstack-ai/objectui/issues/10530/comments. label-write: 0 (refused before execution). git push x3 (not REST).", "open_questions": [], "out_of_scope_findings": [ "carrier: 承接者:无 · noted, not filed (in PR Acceptance notes) · H5: a lookup-typed timeline.groupByField puts every record under one header reading `[object Object]` (probe via the real ObjectTimeline + TimelineRenderer, base and head: Acme and Globex rows merged into one lane); site ObjectTimeline group-label step falling back to String(m.group); no crash, not the same mechanism; no public-door reach measured and no in-repo producer authors a lookup groupByField on a timeline (objectstack examples use status/stage); grouping by name vs id is a design choice, not mechanical · dedupe words: timeline groupByField lookup · group header object Object · ObjectTimeline group label", "carrier: 承接者:无 · noted, not filed · H4: static schema.items with an object-valued title still throw the React child error on head (probe); it is the author-literal pass-through path (`if (schema.items) return schema.items;`), no fetch or expansion, no producer · dedupe words: timeline static items object title · TimelineRenderer item.title object", "carrier: 承接者:无 · noted, not filed, read-only inference (not measured) · ObjectTimeline's NavigationOverlay body prints String(value ?? '—') per record key, so an expanded lookup would read `[object Object]`; ObjectGallery's card title does String(item[titleField]) for an authored titleField, same reading for a lookup · dedupe words: NavigationOverlay String value lookup · ObjectGallery titleField lookup object Object" ] }Generated by Claude Code
objectstack-fleet commentedon Sep 25, 2026
✅ ACCEPT: objectui#10593 at
a37ee10; ready + auto-merge follow this ACCEPTdomain:uiseat #2,session_014mXUNuFomfj24w7s1pZzhN. I checked this against the diff and CI, not against the report's own account. Claim5830444135. It executes triage5830288500.titleanddescriptiononce through@object-ui/core'srecordDisplayValueAt, with the same call shape as the precedentObjectMap.tsx(PR objectui#10525). No second resolver and no local ladder;record-title.tsis untouched$expandnames the lookup, and the arm asserts$expandcontains it before reading the display name. The real renderer is used (not mocked). Title and description are both red on base with the React-child errortrue/false(base: an emptyh3/p, or nothing);0shows inside its line; whitespace-only draws no line; padding is trimmed. Each is the ruled resolver meeting the renderer's unchanged&&gate, and each is identical to what ObjectMap took. HTML already collapsed surrounding spaces, so trimming changes no visible text. The changeset states every moveschema.itemsbypass the mapping (the author-literal path, no expansion), and a lookupgroupByFieldgives an[object Object]header without crashing. Both were confirmed at source as different sites and mechanisms ⇒ recorded belowClause-②: no/ semverpatchon@object-ui/plugin-timeline: a crash stops; no export, schema key or accept set movesplugin-timeline; the one namingtitleField,7070, stays true)CONTRACT_REVIEW_TIERon this head, record5831203192. The seat read the reviewer transcript: every turn ran at tiera37ee10: 40 success, 3 skipped by design, 0 red.git merge-treeagainst main is cleanFixes #10530onlyFindings, each with its disposition
groupByFieldputs every record under one[object Object]lane header (String(m.group)). There is no crash, and whether to group by id or by name is a design question ⇒ recorded. No card is filed: no in-repo producer authors a lookupgroupByFieldon a timeline, so there is no measured reach.schema.itemswith an object-valuedtitlestill throws. It is the author-literal pass-through, with no fetch and no expansion, and no producer ⇒ recorded.NavigationOverlayprintsString(value ?? '—'), andObjectGallery's card title doesString(item[titleField]), so an expanded lookup reads[object Object]on both ⇒ recorded, as the candidate carrier for the next record-display sweep.Deviations recorded
label-write --assignwas refused by the permission classifier ("[External System Writes]"). The seat does not re-issue a refused write. The PR joins the list awaiting the maintainer on seat post objectui#9771.State
In one stroke:
readyand auto-merge (squash), through the relay opspr_ready+automerge_enable.Generated by Claude Code
fix(plugin-timeline): a lookup-typed title or description renders its…