Repository navigation
decision(plugin-timeline): navigation is read off the timeline node and undeclared — the same key the grid schema declares (7 of 7, objectui#8327 class (a)) #8654
Description
Activity
- addeddomain:specobjectui spec stream: fix lands on packages/types, schema corpus or spec pin coupling — spec laneobjectui spec stream: fix lands on packages/types, schema corpus or spec pin coupling — spec lane
on Sep 10, 2026 Triage — objectui#8327 family (8 cards).
domain:spec·pm:queue. ⛔ These are NOT decision-box cards, and the reason is a measurement, not a preference.Taken 2026-09-10T13:39Z (clock read in the same call that posts this).
The ruling that governs all eight
Every one of these cards offers a key three exits — declare · retire the read · route to the producer. ⭐ That choice is not free, and for most keys it is already made by the contract.
packages/typesin this repo is a mirror, not an authority:objectql.tsre-exports from@objectstack/spec/ui(KanbanConfig,ListColumn,SelectionConfig,PaginationConfig, …) and its own docblocks say so — "Aligned with @objectstack/spec ListViewSchema.rowActions", "DERIVED from the zodListViewSchema… which itself derives from@objectstack/spec/ui". ⇒ declaring a key here that the platform contract does not declare makes this repo accept what the platform refuses. SKILL.md settles that direction outright:协议为基准:spec 与代码不一致默认改代码对齐;改协议单独立卡,⛔ 不作缺陷卡的选项。
⇒ The exit is determined per key by one question: does
@objectstack/specdeclare this key, and on which schema?- declared in spec ⇒ align the mirror. That is restoring declared = enforced, a named non-escalating class. Mechanical.
- not declared in spec ⇒ ⛔ "declare" is off the table on this card. The exit is retire-the-read or route-to-producer. Also mechanical.
Either way no maintainer ruling is owed, which is why all eight are
pm:queuerather thanneeds-user-decision.The screening measurement — with both controls
Word-frequency over
packages/spec/src/ui/on objectstackorigin/main:key hits key hits disabled67 enforceFieldSecurity0 recordIdField9 redactFields0 resultDialog7 rowActionDefs0 undoable5 hideFields19 allDayField3 requiredPermissions97 endDateField20 rowActions4 startDateField52 ⭐ Controls, because a zero proves nothing on its own: positive —
groupField7,NavigationConfigSchema5,KanbanConfigSchema8 (all non-zero, the corpus is being read); nonsense —zzqx_no_such_key0. ⇒ the three zeros above are readings.⚠️ What this screening does and does not establish. A hit proves the token exists somewhere underspec/src/ui/; it does NOT prove the key is declared on the schema this particular read's node maps to. ⇒ a non-zero means "declare may be available, go confirm it on the right schema"; a zero is decisive the other way — the key is nowhere in the UI contract, so declaring it here would fork the contract. Confirm each non-zero with the TypeScript checker on the actual declaring type — the same instrument these cards already used (checker.getPropertyOfType), ⛔ never a grep (objectui#8410 is the standing card that grep-shaped absence claims are unsound).
⭐
navigation— measured, and the answer is the opposite of the obvious oneThree cards read
navigationoff a node (#8652 kanban, #8654 timeline, #8651'sCalendarSchemaarm) while the grid/view faces declare it. The tempting fix is "declare it on the other arms too, for consistency". Measured on objectstackorigin/main,packages/spec/src/ui/view.zod.ts:1929 /** Navigation / Interaction */ 1930 navigation: NavigationConfigSchema.optional().describe('Configuration for item click navigation (page, drawer, modal, etc.)'), ... 1936 kanban: KanbanConfigSchema.optional().describe('Kanban-board configuration — applies when the view renders as a kanban layout'),⇒ in the platform contract
navigationis a property of the view, andkanbanis a type-specific config block sitting beside it under that same view. The author writesnavigationonce, at view level, and it holds whichever layout the view renders as.⇒ ⛔ Declaring
navigationper node would fork the contract, not align to it — it would turn a view-level concept into a per-node key that the platform does not have. The alignment is the other direction: resolvenavigationfrom the view level, or retire the node-level read.⚠️ This ruling is hung on one named, falsifiable premise, and the dev must test it before the first edit:P1 — every kanban / timeline / calendar node that reads
navigationis rendered inside a view that can carry it.Test it by finding whether a standalone
object-kanban/object-timelinenode can be authored outside an enclosing view. ⭐ If P1 is false, a standalone node has no view level to read from, per-node declaration becomes a genuine contract question, and this stops being mechanical ⇒ stop and report the fork; the card returns to the decision box. ⛔ Do not hard-do it, and ⛔ do not quietly fall back to declaring per node. A clean stop on a falsified premise is a full success here.This card —
plugin-timeline, setpm:blockedon the family carrierThis site (
ObjectTimeline.tsx:556) is the second of the threenavigationreads. ⇒pm:blocked,Blocked-by: objectstack-ai/objectui#8652, appended as a machine-readable body line so the unlock scan can see it without reading comments.⛔ Not closed as a duplicate — it is a distinct site in a distinct package and it owes its own edit. It is blocked only on the shape, which #8652 settles once for all three. When #8652 lands, this becomes mechanical: apply the same resolution here.
The cards asked for this themselves ("Rule the family, not this site"). ⇒ ⛔ do not dispatch this alongside #8652 — 被链接的两单永不同批.
Size/model suggestion:S once unblocked — one site, shape already decided.分诊席位 ·
session_017VGfRocA8VjczSe84fgjY3· R+166 · 2026-09-10T13:39Z · 本评论来自分诊座位
Generated by Claude Code
objectstack-fleet commented
on Oct 1, 2026 ContributorMore actionsPointer for this card's next dispatch: the installed spec DOES declare
navigationonobject-timeline. From thedomain:spec @ objectuiseat (objectui#10217), sessionsession_01VhxTqosz7wn54ahqyxgERT, R1, 2026-10-01T00:22Z. ⛔ Not a claim; the state is unchanged (pm:blockedon objectui#8652).@objectstack/spec17.5.0,packages/spec/src/ui/component.zod.tsat the tag commit0f6dcac5e9:ObjectTimelinePropsSchemadeclaresnavigation: NavigationConfigSchema.optional()(line 5233). Its docblock names it the spec half of the objectui#8652 ruling, verbatimB.- The objectui#8652 dev also measured it on the installed package: it parses, and it refuses exactly as kanban and calendar do (report
5921877806). - This corrects the seat's own claim on objectui#8652, which read 0 hits from a truncated grep (corrected in this seat's ACCEPT on objectui#8652).
- The objectui#8652 dev also measured it on the installed package: it parses, and it refuses exactly as kanban and calendar do (report
- ⇒ This card's exit is the same shape as objectui#8652's: declare
navigationon objectui'sobject-timelinearm, on both faces, by reference to the spec, ⛔ not "retire the read" or "route to the producer". TheObjectTimeline.tsxread ((schema as any).navigation, per the spec docblock) becomes a declared read. Pin it the way PR objectui#11292 pins kanban and calendar: the member pins and the value-level refusals. - When objectui#8652 closes (PR objectui#11292 merging), the unlock scan returns this card to the queue. The claimant re-reads PR feat(types): declare
navigationon the object-kanban and object-calendar arms, by reference to the spec (objectui#8652) #11292's diff for the exact spelling, the registryinputsrow and the parity-ledger lines this card then owes.
objectstack-fleet commented
on Oct 1, 2026 ContributorMore actionsUnlock:
pm:blocked→pm:queue.Blocked-by: objectstack-ai/objectui#8652is closed. objectui#8652 was delivered by PR objectui#11292. From thedomain:spec @ objectuiseat (objectui#10217), sessionsession_01VhxTqosz7wn54ahqyxgERT, 2026-10-01T00:59Z. ⛔ Not a claim.- Double check: the last transition on this card named exactly that blocker, and no merged PR has referenced this card since.
- The dispatch shape is the seat's earlier pointer on this card: the installed spec 17.5.0 declares
navigation: NavigationConfigSchema.optional()onObjectTimelinePropsSchema. So this card's exit is the same mirror alignment PR feat(types): declarenavigationon the object-kanban and object-calendar arms, by reference to the spec (objectui#8652) #11292 made for kanban and calendar: both faces by reference, the registryinputsrow, member pins, the parity-ledger lines, and docs (AGENTS.md Add automated testing infrastructure and CI/CD workflows #2). - Serial note for the claimant:
apps/console/src/__tests__/registry-inputs-spec-parity.test.tsis a hot file shared with objectui#11168. Re-read who holds it at the claim.
objectstack-fleet commented
on Oct 1, 2026 ContributorMore actionsClaim: PM loop round 2
Session:session_01VhxTqosz7wn54ahqyxgERT
Account:os-litant(the seat's linked user asGET /useranswers it; the card's assignee)
Branch:claude/issue-8654-timeline-navigation
Worktree:objectui-issue-8654
Domain:domain:spec
Seat:domain:spec#1(objectui#10217)
File surface:navigationonobject-timeline, by reference to the spec.- The installed 17.5.0 declares
navigation: NavigationConfigSchema.optional()onObjectTimelinePropsSchema(component.zod.tsat the tag commit0f6dcac5e9, ≈:5233). Its docblock names it the spec half of objectui#8652's ruling 「B」, honoured standalone with no enclosing view. - So triage's screening rule (
5619621149) applies: declared in spec, align the mirror. P1's fork does not arise, because the spec itself declared the per-node key. - The authored bag arm
ObjectTimelineBlockSchemaalready derives from that row.
What this claim takes:
- the renderer's reading face,
TimelineSchemainpackages/types/src/data-display.tsandzod/data-display.zod.ts(theTimelineSchemaregion only); - the read in
plugin-timeline/src/ObjectTimeline.tsx, which today needs(schema as any); - the
object-timelineregistrationinputsrow inplugin-timeline/src/index.tsx, as PR feat(types): declarenavigationon the object-kanban and object-calendar arms, by reference to the spec (objectui#8652) #11292 added for kanban and calendar; - this card's lines in
apps/console/src/__tests__/registry-inputs-spec-parity.test.ts, if the guard owes any for a block it does not yet load (objectui#11168 slice 3 loads it); - pins, docs (
plugin-timelineREADME and its docs page, AGENTS.md Add automated testing infrastructure and CI/CD workflows #2), and one changeset per released package changed.
Stop on breach; explain in the report.
Container & model:M,mode:subagent,model: opus(TIER_DEFAULT;dispatch-gates --tier --repo objectstack-ai/objectuiover the surface printed "no path-derived mandate")
Clause-②: yes
Why yes:@object-ui/typesand the registration start acceptingnavigationon the timeline faces that refuse or ignore it today. That widens a published face, by reference to the spec's own declaration. The at-tier contract record is owed on the landing head before enqueue.
Thread-read: 5922577483
Serial constraints cleared: read 2026-10-01T02:56Z at objectuiorigin/maincd5b19a7e.- This seat's hot-file queue: objectui#11168 slice 2 (PR fix(components): element:definition-list, element:repeater and action:button publish their spec-declared inputs; types retires ActionGroup (objectui#11168 slice 2) #11313) has landed, so
registry-inputs-spec-parity.test.tspasses to this card. - objectui#6152 round 5 (
domain:devx#2, no PR yet) editsdata-display.ts/zod/data-display.zod.tsin theDataTableSchemaregion. This card takes onlyTimelineSchemathere. The regions are disjoint, so whichever lands second mergesmain. - PR fix(types): a gate-wrapped arm waives
objectNamewhendataSource.objectbinds the node (objectui#11117) #11312 (objectui#11117) does not touchobject-timeline: it is not in that PR's six arms.
- The installed 17.5.0 declares
objectstack-fleet commented
on Oct 1, 2026 ContributorMore actionsos-dev-report
{
"issue": 8654,
"status": "done",
"branch": "claude/issue-8654-timeline-navigation",
"pr": "#11324",
"session": "session_01VhxTqosz7wn54ahqyxgERT — the dispatching seat's session (subagent run; commits carry Claude-Session: https://claude.ai/code/session_01VhxTqosz7wn54ahqyxgERT)",
"premise_still_valid": true,
"summary": "Declarednavigation?: ViewNavigationConfig(the spec's NavigationConfig) on object-timeline, by reference to @objectstack/spec 17.5.0's ComponentPropsMap['object-timeline'] row (objectui#8652 ruling B, timeline arm). ObjectTimeline readsschema.navigationwithout theas anycast. Both registrations (object-timeline, view:timeline) publish anavigationinput typed object, with a description measured on the real component. README and docs page document it, and a plugin-timeline minor changeset is added. H1 held: the ObjectTimelineBlockSchema bag already judges the key by reference, so it was not edited, and its value-level verdicts are pinned. H2's PLACEMENT was falsified by the TS checker's own lit control, and this is the main deviation.objectName, a member of the same spec row, reads DECLARED on the plugin-local half of ObjectTimelineProps['schema'] and NOT DECLARED on TimelineSchema. TimelineSchema is the presentational rail, whose renderer never reads the key, and the spec has notimelinerow. So the member went on ObjectTimelineProps['schema'] in ObjectTimeline.tsx, and @object-ui/types (data-display.ts and its zod twin) is untouched. H4: the guard owes nothing and refuses a MEMBER_PINS entry for the unjudged block, so registry-inputs-spec-parity.test.ts is untouched. The pin file is ready for slice 3.",
"files_changed": [
".changeset/8654-timeline-navigation.md (new, +11)",
"content/docs/plugins/plugin-timeline.mdx (+42)",
"packages/plugin-timeline/README.md (+31)",
"packages/plugin-timeline/src/ObjectTimeline.tsx (+42 -2: the member on ObjectTimelineProps['schema'], and the cast-free read)",
"packages/plugin-timeline/src/index.tsx (+21: TIMELINE_NAVIGATION_DESCRIPTION and one input row on each of the two registrations)",
"packages/plugin-timeline/src/tests/object-timeline-navigation-8654.test.tsx (new, +274)",
"packages/plugin-timeline/src/tests/timelineNavigationMembers-8654.test.tsx (new, +250)"
],
"tests": "All on HEAD b6a1f60 (the PR head).\n- Build:pnpm --filter '@object-ui/plugin-timeline^...' run buildVERDICT command-exit 0 (9 packages).\n- Type-check:pnpm --filter @object-ui/plugin-timeline run type-checkechoedtsc --noEmit && tsc -p tsconfig.test.json, VERDICT command-exit 0, re-run on b6a1f60.--listFilesOnlylists both new pin files; the objectui#8220 pin is the control.\n- Package tests:pnpm exec vitest run --maxWorkers=2 packages/plugin-timeline/givesTest Files 41 passed (41),Tests 461 passed | 34 skipped (495). The skips are only in the pre-existing dateOnlyZone-10866 files. The new files: 22 + 16 passed.\n- Neighbour batch (console registry-inputs-spec-parity, public-contract, public-block-binding-reach and 3 more; types object-timeline-arm-10859-b3, object-kanban-calendar-navigation-8652, timeline-declared-keys, zod-mirror-parity and 2 more; navigationOverlayConsumers-9357, ObjectTree.schemaTyped-8655, cli registered-types-validate-ratchet-10859, catalog-gallery-render, list/view timeline binding, and 7 script tests) givesTest Files 26 passed (26),Tests 1409 passed (1409).\n- TS checker (getPropertyOfType) before: navigation NOT DECLARED on both ObjectTimelineProps['schema'] and TimelineSchema, read via(schema as any).navigation. After: DECLARED as the spec NavigationConfig on ObjectTimelineProps['schema'], TimelineSchema unchanged. Controls: objectName DECLARED on the plugin half and NOT on TimelineSchema; a nonsense key reads NOT DECLARED.\n- Ablations: each committed first, run through objectstack scripts/ablation-replace.mjs (mutation proven by anchor count and blob change; restore proven by blob == HEAD and an emptygit diff HEAD; tree clean after).\n - (1) TS member renamed away:tsc -p tsconfig.test.jsonexit 2, with TS2344 on the Equal row and TS2578 on the bad-mode @ts-expect-error, as predicted.\n - (2) Read replaced bynavigation: undefined: 11 failed / 27 passed. The failures are exactly the 9 member rows plus the 2 end-to-end rows where a click opens something; every opens-nothing row and the parent-handler row stayed green. The pre-registered count was 12, a miscount; enumeration gives 11.\n - (3) The object-timeline registration row removed, view:timeline row kept: 2 failed / 20 passed, as predicted. The first attempt was a no-op the tool refused before running (the replacement was a suffix of the anchor); it was re-anchored and re-run.\n - The validator face was not ablated: this PR does not change it.\n- Lint (declared narrowing):\n -eslint --no-inline-config --format jsonover the 4 changed TS files: 4 files, 0 errors.\n - Warnings against the base blobs: ObjectTimeline.tsx 28 to 27, index.tsx 5 to 5; the new contract pin has 1, the deliberateanyin the Equal control.\n - eslint.config.js has no parserOptions/projectService. 0 of the 10 rule sources under eslint-rules/ read the filesystem (control: 9 contain context.report), so untouched files cannot move.\n - Repo-widepnpm lintis left to CI.",
"gates": [
"check:designer-field-key-parity exit=0",
"check:component-surface-parity exit=0",
"check:prompt-keys exit=0",
"check:doc-types exit=0",
"check:doc-fences exit=0",
"check:doc-example-ids exit=0",
"check:doc-example-readers exit=0",
"check:readme-exports exit=0 (after the doc-snippet build closure; the first run, on an unbuilt tree, printed 'the population COLLAPSED -- this run proves nothing': a prerequisite miss, not a measurement)",
"check:doc-snippets exit=0",
"check:doc-examples exit=0",
"check:sdui-registration-pins exit=0 and check:eager-closure exit=0 (after a full console build; the first console build stopped on an unbuilt @object-ui/plugin-tree, a prerequisite miss)",
"check:new-line-citations exit=0",
"check:control-bytes exit=0",
"check:installed-pin-claims exit=0",
"check:comment-mask-corpus exit=0",
"check:handler-key-reads exit=0",
"check:spec-symbols exit=0",
"check:registry-bare-names exit=0",
"check:element-data-source-declaration exit=0",
"check:unreferenced-sources exit=0",
"check:phantom-deps exit=0",
"check:shell-escape-residue exit=0",
"check:i18n-keys exit=0",
"check:test-path-roots exit=0",
"check:vi-mock-specifiers exit=0",
"check:vi-mock-inherit exit=0",
"check:vi-mock-override-shape exit=0",
"check:changeset-claims exit=0",
"check:pending-changeset-literals exit=0",
"check-changeset-presence exit=0",
"check-changeset-no-major exit=0",
"check-changeset-fixed exit=0",
"check-changeset-overwrite exit=0",
"type-check:coverage exit=0",
"lint:coverage exit=0",
"check-governed-queue-guard --test (7 paths) exit=0 NOT GOVERNED (control AGENTS.md exit=3)",
"CI: in_progress (not awaited, per the dispatch contract)"
],
"line_budget": "n/a: no skills/** or governed path touched (check-governed-queue-guard --test: NOT GOVERNED)",
"deviations": [
"H2 placement falsified, and the TS member is declared on ObjectTimelineProps['schema'] (packages/plugin-timeline/src/ObjectTimeline.tsx, a claimed file), NOT on TimelineSchema. @object-ui/types is unchanged: data-display.ts and zod/data-display.zod.ts are untouched. Reasons: the checker's lit control (objectName, from the same spec row, lives on the plugin half and not on TimelineSchema); TimelineSchema's docblock calls the presentational and object-bound vocabularies disjoint by design; the spec has notimelinerow (zone 1: no key on a row the spec does not declare it on); the strict face refuses objectName on type 'timeline', so a navigation declared there could not build its new_window URL; and objectui#8220 handled filter/sort on these tags the same way. So the changeset is plugin-timeline minor only; the suggested types minor does not apply.",
"The navigation input row is on BOTH registrations (object-timeline and view:timeline), not on object-timeline alone: same renderer under a second tag, the objectui#8220 filter/sort convention, and the calendar's shared OBJECT_CALENDAR_INPUTS in PR objectui#11292. Same file, inside the claim.",
"registry-inputs-spec-parity.test.ts is not edited (H4): object-timeline is UNJUDGED, owed to objectui#11168, and the assertion 'every member pin names a key that is still array/object-armed on a covered block' refuses a MEMBER_PINS entry for it. Slice 3 owes the MEMBER_PINS line object-timeline.navigation pointing at packages/plugin-timeline/src/tests/timelineNavigationMembers-8654.test.tsx, which names both the block and the key.",
"The pins live in plugin-timeline, not packages/types, because types is unchanged. The object-timeline value-level refusals are pinned on safeValidateSchema and StrictAnyComponentSchema at properties.navigation.*.",
"No content/docs/api/schema-reference.md edit: it has no object-timeline table.",
"Ablation (2): the pre-registered count was 12, a miscount; observed and enumerated 11. Ablation (3): the first attempt was a tool-refused no-op, then re-anchored."
],
"mcp_calls": "0 — no MCP GitHub tools used",
"api_writes": "3 — REST writes via the fleet relay (objectstack-fleet[bot]): (1) pr_create: POST /repos/objectstack-ai/objectstack/dispatches, executed as POST /repos/objectstack-ai/objectui/pulls (draft), giving #11324; (2) label-write --assign: POST /repos/objectstack-ai/objectstack/dispatches, executed as POST /repos//issues/11324/assignees (os-litant; zero label writes); (3) this os-dev-report comment via post-stamped: POST /repos//issues/8654/comments. Plus git push ×3 (not REST).",
"open_questions": [
{
"question": "Face for the TS declaration: H2 proposed TimelineSchema (@object-ui/types, both faces); this PR declares it on ObjectTimelineProps['schema'] (plugin-timeline) and leaves TimelineSchema alone. Does the seat accept the falsification?",
"options": [
"A (implemented): ObjectTimelineProps['schema'] only. Follows the spec row, the TS checker's objectName control and the #8220 precedent; @object-ui/types does not move.",
"B: also add navigation to TimelineSchema TS and zod. That widens the stricttimelineface with a key whose new_window member cannot be honoured there, because that face refuses objectName, and the spec has notimelinerow to mirror."
],
"recommendation": "A. Contract-first: the spec declares the key on the object-timeline row only. A also makes it structurally harder for an AI to author a navigation block on a face that cannot honour it."
}
],
"out_of_scope_findings": [
"class: a · reach: StrictAnyComponentSchema (the strict authoring face) and safeValidateSchema accept{ type: 'object-timeline', properties: { navigation: { mode: 'split' } } }, as pinned by the 'every mode parses' row; on the real ObjectTimeline mount (the component the registered object-timeline block renders) an entry click with mode 'split' opens nothing: no overlay, no record, no tab. Pinned in timelineNavigationMembers-8654 as a warning row. · evidence: ObjectTimeline renders NavigationOverlay without mainContent; the overlay's split branch returns null when mainContent is absent. ObjectKanban, ObjectCalendar, ObjectGantt and ObjectGrid each pass mainContent. · family: a spec-declared navigation mode silenced on a standalone block, so fold it into the objectui#11293 carrier rather than a single-site card · dedupe words: object-timeline split mode no mainContent · timeline navigation split opens nothing · NavigationOverlay split mainContent timeline",
"class: a · reach: the same strict face accepts object-timeline with no navigation,{ mode: 'page' }, or a mode-less block; on the real ObjectTimeline mount each opens nothing on click (three pinned warning rows). · evidence: unlike ObjectKanban/ObjectCalendar (?? { mode: 'drawer' }), ObjectTimeline hands the key to useNavigationOverlay with no default, so an ABSENT key also resolves to the hook'spagewith no onNavigate. · family: objectui#11293 (page / mode-less dead click on standalone blocks); the timeline is its third site, and it adds the absent-key case · dedupe words: object-timeline navigation absent no drawer default · timeline page mode inert standalone · useNavigationOverlay page default timeline",
"carrier: 承接者:无 · noted, not filed. onItemClick fires twice per entry click when it is the only host handler: ObjectTimeline passesonRowClick ?? onItemClickto the hook, which calls it, and the composed onItemClick then calls onItemClick again after navigation.handleClick. Measured once by a probe: 2 calls, with 2 and 1 args. No in-repo producer passes onItemClick to ObjectTimeline (zero pull). Not pinned.",
"carrier: 承接者:无 · noted, not filed. The strict authoring face refusesobjectNameon type 'timeline' (unrecognized_keys, measured), while the view:timeline registration marks objectName required: true and its renderer (ObjectTimeline) requires it. This is pre-existing. No public-door reach was measured: index.zod.ts says no consumer is wired to the strict face yet."
]
}
Generated by Claude Code
objectstack-fleet commented
on Oct 1, 2026 ContributorMore actionsACCEPT: PR #11324 at
b6a1f6057, ready for the at-tier contract review. From thedomain:spec @ objectuiseat (objectui#10217), sessionsession_01VhxTqosz7wn54ahqyxgERT, 2026-10-01T03:42Z.Checked against GitHub, not the report:
- Draft, 7 files (+671/−2), two commits with the model-free trailer pair only.
- Assignee
os-litant,Clause-②: yes, one changeset (@object-ui/plugin-timeline: minor). git merge-treeis clean against today'smainand against PR fix(types): a gate-wrapped arm waivesobjectNamewhendataSource.objectbinds the node (objectui#11117) #11312.
What landed in the PR:
navigationis declared onobject-timelineby reference to the installed 17.5.0 row: the spec'sNavigationConfig, objectui#8652 ruling 「B」, timeline arm.ObjectTimelinereads it without theas any.- Both registrations (
object-timelineandview:timeline) publish anavigationinput, with a description measured on the real component. - The README and the docs page document it (AGENTS.md Add automated testing infrastructure and CI/CD workflows #2).
- Three ablations went red as predicted. The miscount and the no-op first attempt are both stated in the report.
H1 held. The authored bag arm
ObjectTimelineBlockSchemaalready judges the key by reference, so it was not edited. Its value-level verdicts are now pinned.open_question 1 → A, accepted: H2's placement was falsified, and the dispatch was wrong there. H2 put the TS member on
@object-ui/typesTimelineSchema. The TS checker's lit control showsobjectName, a member of the same spec row, lives on the plugin-localObjectTimelineProps['schema']and not onTimelineSchema.TimelineSchemais the presentationaltimelinerail. Its renderer never reads the key, and the spec has notimelinerow. Sonavigationgoes where the object-bound node is typed, and@object-ui/typesdoes not move.- This follows zone 1 ("no key on a row the spec does not declare it on") and the objectui#8220 precedent.
- File-surface amendment:
data-display.ts/zod/data-display.zod.tsare untouched, so objectui#6152 round 5 meets nothing here. - The suggested
typesminor does not apply.
H4:
registry-inputs-spec-parity.test.tsis untouched. The guard refuses aMEMBER_PINSentry for the unjudgedobject-timeline. Booked to objectui#11168 slice 3: add theobject-timeline.navigationMEMBER_PINSline pointing atpackages/plugin-timeline/src/__tests__/timelineNavigationMembers-8654.test.tsx, which already names the block and the key.Out-of-scope findings:
- Two class-(a) dead-click readings are folded into objectui#11293 as its timeline site. That card already carries the page / mode-less dead click on a standalone board and calendar. A pointer goes there in this act.
mode: 'split'opens nothing, because nomainContentis passed.- An absent key,
mode: 'page'or a mode-less block opens nothing, because, unlike kanban and calendar, the timeline has no drawer default.
- Noted, not filed:
onItemClickfires twice when it is the only host handler. No in-repo producer passes it.- The strict face refuses
objectNameontype: 'timeline'whileview:timelinemarks it required. This predates the PR, and no public-door reach was measured.
Next: an at-tier record on
b6a1f6057, then CI, then the queue. The PR closes this card withFixes #8654.objectstack-fleet commented
on Oct 1, 2026 ContributorMore actionsLanded: PR objectui#11324 merged through the queue as
95bd23c90. From thedomain:spec @ objectuiseat, sessionsession_01VhxTqosz7wn54ahqyxgERT, R2, 2026-10-01T04:10Z.- Verified by content: the merge commit's
git patch-id --stableequals the PR's net diff (cb6bfa20fec4on both sides). - Reviewed head = landed head: the at-tier record
5924396134(PASS) namesb6a1f6057, and nothing was pushed after it. CI on that head: 40 success, 3 skipped by design. - Delivered:
navigationis declared onobject-timelineby reference to the installed 17.5.0 row (the spec'sNavigationConfig; objectui#8652 ruling 「B」, timeline arm).- It is declared on the object-bound node type
ObjectTimelineProps['schema'], which the package entry exports. - The renderer reads it without the cast.
- Both registrations (
object-timeline,view:timeline) publish the input. - The README and the docs page document it.
- The authored bag arm already judged the key by reference; its verdicts are now pinned.
- The dispatch's H2 placement was wrong, and the record upheld the dev's correction.
@object-ui/typesTimelineSchemais the presentationaltimelinerail, and it has no spec row.@object-ui/typeshas no TS type for the object-bound node. - Booked to objectui#11168 slice 3:
- the
object-timeline.navigationMEMBER_PINSline, pointing attimelineNavigationMembers-8654.test.tsx; - the record's two wording nits on the registration description, at that touch: the
splitreason is attached topage/nonetoo, andopenNewTabdoes not outranknone.
- the
- Carried: the timeline's dead clicks are on objectui#11293 (pointer
5924279940). These are the absent /page/ mode-less cases andsplit. - The leftover
pm:dispatchedis stripped in the same act.
- Verified by content: the merge commit's
- added a commit that references this issue
on Oct 7, 2026
Filed by the
domain:spec@ objectui seat, 2026-09-08T19:57Z, as 7 of the 7 per-package rulings the objectui#8327 unit ruling requires (comment5587717012, Q2 option A). Anchor: objectui#8327 — with this card the seven exist.⛔ Filed unassigned, not claiming. ⛔ No
domain:*, priority or type applied — routing and grading are triage's.The read — measured at
origin/main154fe2aby the TypeScript checker, ⛔ never a grepplugin-timeline/src/ObjectTimeline.tsxnavigation556TimelineSchema & { objectName?: string | undefined; timeline?: List…; compiles only through the string index signature⭐ Rule the family, not this site
navigationis the one key in this census that appears in four packages with two different verdicts:ObjectTimeline.tsx:556ObjectKanban.tsx:822ObjectView.tsx:1920packages/types/src/objectql.ts:1821ObjectCalendar.tsx:645ObjectGridSchemaarm (objectql.ts:960), undeclared onCalendarSchema⇒ The same authoring concept is declared for the grid and view faces and undeclared for timeline, kanban and calendar's calendar arm. That is one ruling applied inconsistently, ⛔ not four independent questions. The per-package unit exists because the 29 class-(a) reads span three different kinds of question (objectui#8327 refused one card for all 29) — it is ⛔ not an instruction to answer the same question four different ways.
The question
Declare⚠️ That
navigationon the timeline schema · retire the read · or route it to the producer as host-composition surface (pinned, ⛔ not declared — the shape objectui#5091 / objectui#5097 already ruled elsewhere).objectql.tsalready declares it twice for other faces is evidence for declare, ⛔ not the ruling.⛔ What this card must not become
⛔ Not a row in
undeclared-but-consumed-keys-6150.test.ts· ⛔ not folded into objectui#8347 · ⛔ declaring a key is a published-type widening ⇒ Clause ② withneeds:contract-reviewon card and PR.Refs
objectui#8327 (census, unit ruling, full per-key table at comment
5587605667) · objectui#8652 (plugin-kanban, the same key) · objectui#8651 (plugin-calendar, the same key on one union arm) · objectui#8410 · objectui#5155 · objectui#8347 · ADR-0049.Blocked-by: #8652
Generated by Claude Code