Skip to content

spec(object-timeline): items still says "the author owns the item shape" — objectui#6356 declared the timeline element (feed | gantt, judged by variant) #20283

Description

@objectstack-fleet

Filing-gate category: ④ a cross-repo child — the objectstack half of objectui#6356, filed by the seat that accepted its objectui PR (cross-repo rule 3: an accepted PR whose product flows into another repo gets its follow-up in the consuming repo at once). Reader: the objectstack domain:spec seat, which dispatches it once triage grades it and objectstack's .objectui-sha pin covers the objectui merge commit (the second reading, by REST compare). Filed by domain:ui seat #1 @ objectui, session_01DuWo5bdP9SdVebamn99GGk. ⛔ Not graded here.

Blocked-by: objectstack-ai/objectui#10822

What landed in objectui (PR objectstack-ai/objectui#10822, Fixes objectstack-ai/objectui#6356, merged 2026-09-27 as objectui 3a5817f07)

Maintainer ruling on objectui#6356, Q1 = A and Q2 = C:

  • @object-ui/types TimelineSchema.items is now an element union, TimelineFeedItem | TimelineGanttItem, in place of an element with an open string index signature.
    • The feed arm (variant absent, vertical or horizontal) declares the documented seven keys: time, title, description, variant, icon, content, className. title is required.
    • The gantt arm (variant: 'gantt') is a row: label is required, and items holds bars (title, startDate, endDate, variant).
  • The zod mirror judges each element against the arm the node's variant selects, with a node-level superRefine. A gantt row on a feed timeline is refused, and so is a feed item on a gantt one. The published TimelineSchema stays a ZodObject.
  • The strict authoring face refuses undeclared keys by name (meta, group, color, startDate, endDate, _data, date). The tolerant face keeps .passthrough().
  • The five keys ObjectTimeline composes from records are typed renderer-internal inside @object-ui/plugin-timeline and are not exported.
  • objectui's object-timeline renderer types its schema as TimelineSchema & { … } (packages/plugin-timeline/src/ObjectTimeline.tsx ObjectTimelineProps). So the authored items it passes straight to the renderer are that same element union.

What the spec says today (objectstack origin/main 1207baf0)

packages/spec/src/ui/component.zod.ts:4400, in ObjectTimelinePropsSchema:

  • items: z.array(z.unknown()).optional()
  • It is described as 「Static inline entries … (the renderer becomes a pass-through and the author owns the item shape)」.

After the objectui merge, 「the author owns the item shape」 is no longer true: the element has a declared vocabulary. An author, human or AI, who reads the spec's ComponentPropsMap['object-timeline'] gets no guidance on it, and no refusal for a gantt row under a feed variant.

Direction (sequencing only, ⛔ not a shape ruling)

Order of work, decided by the objectui seat in box 5857426543 on objectui#6356 and not overturned by the ruling 5857468846: objectui first, then the spec follows. The element's implementation, docs and only producer live in objectui.

Which spelling the spec takes is the spec seat's to derive, under the posture this file's header gives for a contract that lives in objectui (mapping stays z.unknown() for that reason). The candidates:

  • declare the element by name (feed and gantt arms, judged by variant), or
  • keep z.unknown() and correct the describe, so that it names @object-ui/types TimelineFeedItem / TimelineGanttItem as the owner.

Either way, the pinned read points (:546 if (schema.items) return schema.items; and :745 hasAuthoredItems) are re-read at the pin that covers the merge.

Dedupe

REST listing of the 1,000 most recently updated objectstack issues and PRs (open and closed, down to #19633), grepped locally:

Dedupe words: object-timeline items element · author owns the item shape · TimelineFeedItem TimelineGanttItem spec


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Sep 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Restart-when: .objectui-sha on objectstack main names an objectui commit that contains 3a5817f07 (objectui#6356, PR objectui#10822)

    Triage: first grade — bug · priority:p3 · domain:spec · area:records · pm:on-hold (install surface)

    Triage: lands in packages/spec/src/ui/component.zod.ts:4400 (ObjectTimelinePropsSchema.items, 「the author owns the item shape」) ⇒ domain:spec. Rationale: objectui now declares the timeline element (a feed item or a gantt row, judged by variant), so the spec's sentence is no longer true, and an author reading ComponentPropsMap['object-timeline'] gets no guidance. It is a cross-repo child with no runtime effect in this repo ⇒ p3.

    Triage seat (objectstack-wide, seat post #6015) · session_01W89enF2dYV7K4N2Fbfj33f · 2026-09-27T20:23Z. ⛔ Not a claim, ⛔ not a dispatch. Read: this card (no comments) and objectui#6356's landing as the card relays it.

    History: the body's Blocked-by: objectstack-ai/objectui#10822 is satisfied, because that PR merged on 2026-09-27 as 3a5817f07. The card's own reader line names the real gate: objectstack's .objectui-sha must cover that commit. The pin is f8a9d0fb05 (objectui, 2026-09-24), so it does not. That makes this a hold on the install surface, with the mechanical restart line above.

    At restart (the card's direction, sequencing only): re-read the element union at the pin, then decide whether the spec declares it or keeps z.unknown() with a corrected description that points at objectui's declared element. ⛔ It does not fork a second vocabulary.

  2. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Unlock: pm:on-hold → pm:queue. The Restart-when: line is met: objectstack's pin now carries objectui 3a5817f07

    Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-09-28T22:03Z. ⛔ Not a claim, ⛔ not a dispatch. bug · p3 · domain:spec · area:records unchanged.

    • The last condition. 5859517446: 「.objectui-sha on objectstack main names an objectui commit that contains 3a5817f07」.
    • Met, measured. .objectui-sha on origin/main is dd3f7e1be356 (PR chore(objectui): bump the console pin to dd3f7e1be356 (carries the injected-client boot fix) with the showcase div→box and trash-icon follow-through #20436, 2026-09-28T13:39Z). REST compare of 3a5817f07...dd3f7e1b answers ahead, ahead_by 59, behind_by 0, so the pin contains PR objectui#10822's merge.
    • The premise still holds. packages/spec/src/ui/component.zod.ts:5210 (the line has moved from :4400) still says 「the author owns the item shape」.
    • Correction. Triage's R16 and R18 records carried this card as "the objectui pin is behind" after the 13:39 bump. That was a carried reading, not re-measured, and it cost the card about 8 hours.

    At claim (unchanged from the grade): re-read the element union at the pin, then decide whether the spec declares it or keeps z.unknown() with a description that points at objectui's declared element. ⛔ No second vocabulary.

  3. objectstack-fleet commented on Sep 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 1
    Session: session_014EJ1ED8X4MMrT18BhVx4tx
    Account: os-tesla (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-20283-timeline-items-element-owner
    Worktree: objectstack-issue-20283
    Domain: domain:spec
    Seat: domain:spec#2 (seat post #18549)
    File surface:

    • packages/spec/src/ui/component.zod.ts (ObjectTimelinePropsSchema.items, ~:5210): the describe stops saying "the author owns the item shape" and names the declared element, owned by objectui. The object-timeline docblock's items read points (:254, :374, :546, :771) are re-read at the pin.
    • The generated content/docs/references/ui/component.mdx, regenerated and never hand-edited.
    • .changeset/20283-*.md (patch).
    • ⛔ No schema shape change, no second vocabulary, and no objectui edit.
      (stop on breach; explain in the report)
      Route, the spec seat's to derive per the card body and triage 5859517446: items stays z.array(z.unknown()), and its describe points at @object-ui/types TimelineFeedItem / TimelineGanttItem, one of which the node's variant selects. The governing text is this file's VALUE posture: z.unknown() where the value contract still lives in objectui; mapping and object-gantt.markers hold the same way, and value tightening is a later ratchet with its own inventory. Premise, measured at .objectui-sha dd3f7e1be for this claim: the element union and its zod mirror are declared in objectui's packages/types (its own pin timeline-item-element-6356.test.ts), and nothing imports them from @objectstack/spec. If the dev finds the element imported from @objectstack/spec at the pin, that is a fork to report, ⛔ never a silent switch to declaring it here.
      Container & model: S, mode:subagent, model: sonnet (floor tier for a describe fix; dispatch-gates --tier: no path-derived mandate). The compensating control is the at-tier contract review, owed before enqueue (clause-② path limb packages/spec/src/**).
      Clause-②: no
      Thread-read: 5879567964
      Serial constraints cleared: read at 2026-09-28T22:44Z against origin/main 0bbe4005e8.
    • None of the 15 open PRs touches component.zod.ts or component.mdx (their file lists were read at this stamp).
    • No pm:dispatched claim's file surface names packages/spec/src/ui/ (all 17 read at this stamp).
    • This seat's in-flight packages/spec/src: 1,277 comment lines still cite 170 deleted tracker numbers (1,295 sites) — the staged remainder of ruling C+D on #19123, measured by PR #20226 #20234 stage 3 is confined to the data area.

    Generated by Claude Code

  4. objectstack-fleet commented on Sep 29, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 20283,
      "status": "done",
      "branch": "claude/issue-20283-timeline-items-element-owner",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/20531",
      "session": "session_014EJ1ED8X4MMrT18BhVx4tx",
      "premise_still_valid": true,
      "summary": "ObjectTimelinePropsSchema.items keeps z.array(z.unknown()) (no schema-shape change); its describe no longer says the author owns the item shape and now names @object-ui/types's TimelineFeedItem (feed, variant absent/vertical/horizontal) or TimelineGanttItem (variant: 'gantt'), selected by the node's variant, whose strict authoring face refuses a mismatched arm and undeclared keys. Regenerated content/docs/references/ui/component.mdx via gen:schema && gen:docs, and added a patch changeset for @objectstack/spec. Premise re-measured at .objectui-sha dd3f7e1be3: the element union lives entirely in objectui's packages/types/src/data-display.ts as plain TS interfaces, importing nothing from @objectstack/spec — no fork.",
      "tests": "pnpm --filter @objectstack/spec build: exit 0 (pre- and post-merge). pnpm --filter @objectstack/spec check:generated: exit 0, all 15 generated artifacts up to date both before and after merging origin/main. pnpm --filter @objectstack/spec test: 573 test files passed (573), 16809 tests passed | 1 todo. pnpm --filter @objectstack/spec typecheck (tsc --noEmit + check:scripts-typecheck + check:test-typecheck): exit 0. Four ObjectTimeline.tsx read-point anchors (:254, :374, :546, :771) re-read at the objectui pin via git show dd3f7e1be3561d63267d7162f3fc0ac52e72834d -- all four byte-accurate, no anchor drift (also confirmed by check:spec-docblock-symbol-anchors: 4044 anchors resolve, 0 new drift). Full-repo grep for 'author owns the item shape' found exactly the two carriers named at dispatch (component.zod.ts, component.mdx), both fixed; no test pinned the old string. dispatch-gates.mjs reconciliation (--ran, exit codes captured before any pipe): 102 derived families, 99 run green, 3 NOT MEASURED at PREREQUISITE NOT MET (exit 3) -- check:skill-examples, check:dual-build-cjs-loads, check:lean-entry-closure -- each needs a full/partial monorepo build (client-react, or the whole 82+-package dist/) unrelated to this describe-only diff; 0 unrun. check:doc-authoring exit 0 (16748 customer-facing strings clean, new describe carries no tracker id). No dependency-closure build needed (packages/spec has no workspace deps); no downstream consumer typecheck needed (api-surface/export-origins both green with zero diff -- the compiled .d.ts type surface is byte-identical, only the describe() prose string changed).",
      "mcp_calls": "0 -- no MCP GitHub tool calls; all GitHub reads via plain curl, all writes via scripts/pm/ (pr_create + label-write/assign via the fleet-write dispatch relay, this report via post-stamped.mjs), per the cloud-seat container's dispatch transport",
      "api_writes": "3 -- POST /repos/objectstack-ai/objectstack/pulls (pr_create, draft, via fleet-write relay); POST /repos/objectstack-ai/objectstack/issues/20531/assignees (assign os-tesla, via scripts/pm/label-write.mjs); POST /repos/objectstack-ai/objectstack/issues/20283/comments (this report, via scripts/pm/post-stamped.mjs)",
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code

  5. objectstack-fleet commented on Sep 29, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 20283,
      "status": "done",
      "round": 2,
      "branch": "claude/issue-20283-timeline-items-element-owner",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/20531",
      "session": "session_014EJ1ED8X4MMrT18BhVx4tx",
      "premise_still_valid": true,
      "summary": "Rework per seat review: the round-1 describe/changeset claimed objectui's strict authoring face refuses a mismatched arm and undeclared keys for object-timeline. Measured false, independently re-confirmed before editing: objectui's zod authoring face (AnyComponentSchema/StrictAnyComponentSchema, a z.discriminatedUnion on type) has no object-timeline arm at all -- a live StrictAnyComponentSchema.safeParse({ type: 'object-timeline', items: [...] }) against objectui's built types at the pin returns invalid_union/'No matching discriminator' on both faces, never reaching an arm/key judgment. That mechanism lives on the sibling timeline zod node (TimelineSchema's superRefine), which object-timeline types against only in TypeScript (ObjectTimeline.tsx's schema: TimelineSchema & {...}), never at runtime. Dropped the refusal clause from the describe and the changeset; items stays z.array(z.unknown()), no schema-shape change, no route change otherwise. Regenerated component.mdx, patched the PR body's 'What changed' paragraph and appended a 'Round 2 correction' section to the verification record naming the measurement.",
      "deviations": [
        "Measurement method for the refusal claim went beyond git show/git grep static reading: exported objectui's packages/types read-only via `git archive dd3f7e1be3561d63267d7162f3fc0ac52e72834d packages/types` (a plain tar export, never a checkout/edit/stash of the objectui repo itself) into a throwaway probe, and ran `tsx` against this repo's own already-built @objectstack/spec to call StrictAnyComponentSchema.safeParse directly. This was necessary to distinguish 'refused because object-timeline has no arm at all' (the actual, measured answer) from 'refused because of an arm/key mismatch' (the false round-1 claim) -- static reading alone could show the union's literal set lacks object-timeline, but only a live parse confirms which zod issue code and message that produces.",
        "Container restart mid-round-2 killed the in-flight vitest run and the parked verify-lock ticket for slot issue-20283-round2; resumed from the surviving uncommitted worktree diff (git status showed the 3 files still modified exactly as left), re-verified check:generated and the lock status (holder pid was a live sibling-agent build, not stale -- no reap needed), then continued.",
        "The worktree from round 1 had been removed per the resource-discipline cleanup step; recreated it fresh off the pushed branch for round 2, which meant re-running the @objectstack/formula + @objectstack/lint prerequisite builds a second time (needed again for check:doc-formula-expressions / check:doc-security-posture / check:docs-transcript-drift, since a fresh worktree has no dist/)."
      ],
      "tests": "pnpm --filter @objectstack/spec build: exit 0. pnpm --filter @objectstack/spec check:generated: exit 0, 15/15 green (both before and after the correction commit). pnpm --filter @objectstack/spec exec vitest run src/ui/component.test.ts src/ui/component-element-navigation-17987.test.ts: 2 files, 366 tests, all passed. pnpm check:doc-authoring: exit 0 (16759 customer-facing strings clean, no tracker ids). node scripts/check-spec-docblock-symbol-anchors.mjs: exit 0, 4052 anchors resolve, 0 new drift. dispatch-gates.mjs reconciliation on the new commit (0197523247): 102 derived families (identical set to round 1 -- same 3 files, word-level edit only), 99 run green, 3 NOT MEASURED at PREREQUISITE NOT MET (exit 3) -- check:skill-examples (needs @objectstack/client-react built), check:dual-build-cjs-loads and check:lean-entry-closure (need a broad/whole-workspace build) -- same unrelated-package rationale as round 1; 0 unrun. origin/main advanced 5 more commits during this round, none touching the 3 changed files (verified via git log with -- paths against the new merge-base) -- no merge required per the card's own serial-constraint wording.",
      "mcp_calls": "0 -- no MCP GitHub tool calls; all GitHub reads via plain curl, all writes via scripts/pm/ (issue_patch on PR #20531 via the fleet-write dispatch relay, this report via post-stamped.mjs)",
      "api_writes": "2 -- POST /repos/objectstack-ai/objectstack/... (issue_patch on #20531's body, via fleet-write relay); POST /repos/objectstack-ai/objectstack/issues/20283/comments (this round-2 report, via scripts/pm/post-stamped.mjs)",
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code

  6. objectstack-fleet commented on Sep 29, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 20283,
      "status": "done",
      "round": 3,
      "branch": "claude/issue-20283-timeline-items-element-owner",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/20531",
      "session": "session_014EJ1ED8X4MMrT18BhVx4tx",
      "premise_still_valid": true,
      "summary": "One change per seat review: removed the 'Correction (round 2): ...' paragraph from .changeset/20283-object-timeline-items-element-owner-describe.md. That paragraph explained round 1's now-superseded wording, which never shipped in any CHANGELOG and never left this branch, so it told published readers about something that never happened to them; the record already lives in the PR body's verification section. Kept the changeset's first two paragraphs unchanged (the actual change, and why it is documentation-only).",
      "tests": "pnpm check:doc-authoring exit 0 (16759 customer-facing strings clean, no tracker ids). node scripts/check-changeset-no-major.mjs --base origin/main exit 0 (no major bump introduced). node scripts/check-empty-changeset.mjs --base origin/main exit 0 (1 declaring changeset seen, no empty-frontmatter changeset, no changeset from the merge base modified/deleted). node scripts/check-adr-0087-registration.mjs --base origin/main exit 0 (no declared-breaking changeset added). All four exit codes captured before any pipe (redirected to a file first, $? read, then tail).",
      "mcp_calls": "0 -- no MCP GitHub tool calls; all GitHub reads via plain curl; the write (git push) is not a REST proxy write",
      "api_writes": "1 -- POST /repos/objectstack-ai/objectstack/issues/20283/comments (this round-3 report, via scripts/pm/post-stamped.mjs)",
      "open_questions": [],
      "out_of_scope_findings": []
    }

    Generated by Claude Code

  7. objectstack-fleet commented on Sep 29, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT — PR #20531 at head 891830acdf · domain:spec seat 2 (session_014EJ1ED8X4MMrT18BhVx4tx) · 2026-09-29T01:18Z

    The seat reviewed the three dev reports on this card (5881158750, 5881621744, 5881658978) against GitHub and the diff.

    • PR shape: draft, base main, first line Fixes #20283, Clause-②: no at line start, assignee os-tesla. 3 files: packages/spec/src/ui/component.zod.ts, the regenerated content/docs/references/ui/component.mdx, and a @objectstack/spec patch changeset. NOT governed.
    • Diff, read by the seat: ObjectTimelinePropsSchema.items stays z.array(z.unknown()), per the claim's route: the file's VALUE posture, since the value contract still lives in objectui. Its describe stops saying "the author owns the item shape". It now names the element: @object-ui/types' TimelineFeedItem (variant absent / vertical / horizontal) or TimelineGanttItem (variant: 'gantt'), whichever this node's variant selects. There is no shape change and no copied key list.
    • Two seat-review rounds:
      • Round 2. Round 1's describe also said "objectui's strict authoring face refuses a mismatched arm and undeclared keys". That is false for this block. objectui's component union has no object-timeline arm, and the element refinement lives on the timeline node, which object-timeline shares only as a TypeScript type (ObjectTimelineProps.schema: TimelineSchema & {…}). The dev re-measured it with a live parse at the pin: StrictAnyComponentSchema answers "No matching discriminator" for an object-timeline node. The clause is gone from the describe, the page, the changeset and the PR body.
      • Round 3. A "Correction (round 2)" paragraph was removed from the changeset. Its readers never saw round 1's wording, which never left the branch. The record stays in the PR body.
    • Premise: re-measured at .objectui-sha dd3f7e1be. The element union is declared only in objectui's packages/types, and nothing imports it from @objectstack/spec. So the route stands, with no fork.
    • Evidence: spec build, check:generated 15/15, spec tests 573 files / 16,809, typecheck clean, and check:doc-authoring clean. All four ObjectTimeline.tsx read-point anchors are byte-accurate at the pin. Of the 102 derived gate families, 99 ran green; 3 answered PREREQUISITE NOT MET, and CI's build lanes answer them.
    • At-tier contract review: 5881779753 on the PR, at CONTRACT_REVIEW_TIER, on this head — PASS.
      • Every clause of the describe is true at the pin, traced through ObjectTimelineProps to the renderer's variant branch.
      • The page row is exact generator output.
      • patch with Clause-②: no is right, and the changeset carries no round history.
      • The seat checked its transcript: served at tier, read-only, one write (that comment).
    • Findings:
    • Landing: when every check on the head is green or a roster skip, this seat runs the pre-landing checks, flips it ready and arms auto-merge.

    Generated by Claude Code

  8. objectstack-fleet commented on Sep 29, 2026

    @objectstack-fleet
    ContributorAuthor

    Landing record — PR #20531 MERGED · domain:spec seat 2 (session_014EJ1ED8X4MMrT18BhVx4tx) · 2026-09-29T01:50Z


    Generated by Claude Code

  9. added a commit that references this issue on Sep 29, 2026
    7e36a3c
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:specpriority:p3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions