Skip to content

fix(plugin-timeline,i18n): a past date on a timeline is "Earlier", not "Overdue" (objectui#11676) - #11700

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-11676-timeline-past-bucket
Oct 6, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-11676-timeline-past-bucket

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Part of #11676. This lands the neutral-bucket half and its pins. The due-date half (the card's second pin: a due-date timeline marks an open past-due record "Overdue" but not a closed one) stays open: nothing the timeline reads declares a due date or a closed record, so it needs a decision, and that question is on the card with options. The card stays open when this merges.
Clause-②: yes

What changed

Without a groupByField, ObjectTimeline groups entries into date buckets, and dateBucket returned timeline.bucket.overdue for any day before today, whatever the bucketed field meant. The showcase's Activity Timeline (startDateField: 'created_at') drew all its tasks under "Overdue", the Done ones included.

  • packages/plugin-timeline/src/ObjectTimeline.tsx: in dateBucket, a day before today now returns t('timeline.bucket.earlier'). Today, Tomorrow, This week, Next week, Later and No date are unchanged. A comment above dateBucket records why: "Overdue" needs two facts that nothing the timeline reads declares, and neither a field name nor a status value is read as one.
  • packages/plugin-timeline/src/useTimelineTranslation.ts: new default row 'timeline.bucket.earlier': 'Earlier'. The overdue row stays, with a note that it has no call site until the card's open question is decided.
  • packages/i18n/src/locales/*.ts (all ten packs): new key timeline.bucket.earlier, placed after overdue. Values: en Earlier, zh 更早, ja 以前, ko 이전, de Früher, fr Plus tôt, es Antes, pt Antes, ru Ранее, ar سابقاً.
  • Tests: new __tests__/ObjectTimeline.pastBucket-11676.test.tsx. Two existing pins now expect the new label: objectTimelineInputs-11168.test.tsx (date buckets without groupByField) and the two west-of-UTC cases in ObjectTimeline.dateOnlyZone-10866.test.tsx.
  • .changeset/11676-timeline-past-bucket.md: minor for @object-ui/plugin-timeline and @object-ui/i18n.

Premises checked on main (57d82cb)

  • dateBucket returned timeline.bucket.overdue for every ts before today, and the grouping fed it m.startDate only. Confirmed.
  • What the timeline config carries: the spec's TimelineConfigSchema (strict, @objectstack/spec 17.6.0 as installed) has startDateField, endDateField, titleField, groupByField, colorField and scale. ListViewTimelineConfig adds only the legacy dateField. None of them is a due-date role or a closed-state marker. The spec's SelectOptionSchema (label, value, description, color, default, visibleWhen) has no closed or terminal flag. The only terminal in the spec is on record:path stages, a page component the timeline never reads.
  • Signals that exist but do not qualify: objectui's own dueLike key, declared in @object-ui/types and read by @object-ui/fields' resolveDueLike. The spec's FieldSchema does not declare it, so an object served by the platform cannot carry it. Its reader also falls back to a field-name regex, and the card rules out guessing from field names. The timeline's built-in status / priority chips are chosen by field name, and nothing declares which status values are closed.
  • Producers: the only in-tree timeline configurations are the showcase's created_at timeline and its copy in objectstack's lint fixtures. No due-date timeline exists in either repo's examples.

Built declarations (Clause-② reading)

Both packages were built at the base and again at the head, and every dist/**/*.d.ts was compared byte for byte:

  • @object-ui/i18n: locales/en.d.ts gains one member, readonly earlier: "Earlier", under timeline.bucket. TranslationKeys = typeof en therefore gains timeline.bucket.earlier. The other nine pack declarations each gain their own earlier, and locales/index.d.ts gains the same member in each pack type. Nothing else changed: every diff line is an addition.
  • @object-ui/plugin-timeline: all five emitted declarations (index, ObjectTimeline, renderer, renderHandoff, useTimelineTranslation) are byte-identical, base to head. TIMELINE_DEFAULT_TRANSLATIONS is typed Record of string to string, so a new row does not change its type. Only the bundle changed: dist/index.js contains timeline.bucket.earlier 2 times, against 0 at the base.

Verification (head 047cf47)

  • pnpm exec vitest run packages/plugin-timeline/: 44 files passed, 552 tests passed, 34 skipped.
  • pnpm exec vitest run packages/i18n/: 79 files passed, 1290 tests passed, 13 skipped.
  • pnpm exec vitest run scripts/__tests__/date-only-zone-pins-10183.test.ts scripts/__tests__/defaults-population-parity-7904.test.ts packages/app-shell/src/__tests__/defaults-maps-mirror-en-pack.test.tsx: 3 files, 46 tests passed. The first one drives the forked west and east zone cases of ObjectTimeline.dateOnlyZone-10866.test.tsx, which the plain run skips.
  • pnpm --filter @object-ui/plugin-timeline type-check and pnpm --filter @object-ui/i18n type-check: exit 0. tsc -p tsconfig.test.json --listFiles lists all 44 timeline test files, the new one included.
  • pnpm --filter @object-ui/plugin-timeline lint and pnpm --filter @object-ui/i18n lint: exit 0. Read as JSON: 50 and 110 files, 0 errors. The new test file has 0 warnings.
  • Root gates, all exit 0: check:i18n-keys, check:i18n-drift, check:i18n-dead-keys (report-only), check:new-line-citations (0 new), check:control-bytes, check:changeset-claims, check:pending-changeset-literals, check:test-path-roots, check:vi-mock-specifiers, check:vi-mock-inherit, check:vi-mock-override-shape, check:unreferenced-sources, node scripts/check-changeset-no-major.mjs, node scripts/check-changeset-presence.mjs.
  • NOT MEASURED: check:eager-locale-catalogues. It answered PREREQUISITE NOT MET because it needs a full console build. That gate checks which catalogues are loaded eagerly, and this diff does not change that. CI runs it.

Ablation (one run, committed tree, restored). scripts/ablation-replace.mjs (objectstack) replaced t('timeline.bucket.earlier') with t('timeline.bucket.overdue') in dateBucket. The anchor was found once and the blob changed. Then the new pin file and objectTimelineInputs-11168.test.tsx were run. Predicted: red in 5 cases (the 4 new ones and the 11168 date-bucket row). Observed: 5 failed and 65 passed, exactly those 5. After the restore the blob equals HEAD and git diff HEAD is empty. The tests import ../ObjectTimeline from source, so no build was involved.

Acceptance notes

  • The due-date half is the open question on the card. Recommendation there: no timeline "Overdue" until a declared signal exists. Nothing produces a due-date timeline today, and "Overdue" can only be judged correctly if a due-date role and a closed state are both declared, in the spec first.
  • timeline.bucket.overdue has no call site after this change. It stays in the defaults row and all ten packs because the decision either reuses it or retires it. check:i18n-dead-keys lists it as needs-review, a report-only reading.
  • On an axis with only past dates, such as created_at, everything before today now shares one "Earlier" header. Finer past buckets such as Yesterday or Last week would be a separate capability, so this change does not add them.
  • The docs (content/docs/plugins/plugin-timeline.mdx) and the published config description in plugin-timeline/src/index.tsx say only that entries "group into date buckets" and name no bucket, so neither went stale. This change does not edit them.

Generated by Claude Code

…t "Overdue"

Without a groupByField, ObjectTimeline buckets entries by date, and every
day before today went under timeline.bucket.overdue whatever the bucketed
field meant: the showcase's created_at timeline drew all ten tasks under
"Overdue", Done records included.

"Overdue" needs two facts (the date is a due date, the record is open) and
nothing the timeline reads declares either: TimelineConfigSchema has no
due-date role and no closed-state marker. A past day now buckets as the
neutral timeline.bucket.earlier, translated in all ten packs; no field
name or status value is guessed. The overdue key stays, with no call site,
pending the card's open question on the due-date half.

Part of objectui#11676.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FngvPpdrnhHMdHHq6vwwju
@github-actions

github-actions Bot commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 331 chunks) 3322.4 KB 3330.4 KB
Main entry chunk (gzip) 152.7 KB 350 KB
Entry file index-Bq63SeuU.js —
Status PASS —

The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it.


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 17.22KB 6.37KB
app-shell (runtime-config.js) 22.52KB 7.86KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.11KB 3.87KB
auth (ActiveOrganizationStorage.js) 27.95KB 10.04KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.22KB 10.61KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.40KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.72KB 2.24KB
auth (SocialSignInButtons.js) 9.70KB 3.93KB
auth (UserMenu.js) 3.39KB 1.21KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.70KB 10.94KB
auth (createAuthenticatedFetch.js) 8.54KB 3.46KB
auth (index.js) 3.63KB 1.64KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 27.11KB 7.97KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.28KB 2.60KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.50KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 574.72KB 137.94KB
core (index.js) 10.00KB 3.96KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 232.57KB 64.51KB
fields (index.js) 262.75KB 66.62KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 2.59KB 1.22KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.24KB 2.27KB
i18n (pickLocalized.js) 9.86KB 3.95KB
i18n (provider.js) 39.35KB 12.88KB
i18n (translateFn.js) 0.20KB 0.18KB
i18n (useDisplayLocale.js) 3.52KB 1.76KB
i18n (useObjectLabel.js) 35.66KB 9.49KB
i18n (useSafeTranslation.js) 7.14KB 2.92KB
layout (index.js) 41.18KB 11.71KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 6.62KB 2.45KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 5.52KB 2.10KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 13.86KB 5.00KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.52KB 2.26KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.33KB 3.07KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 16.04KB 3.92KB
plugin-calendar (index.js) 53.17KB 15.46KB
plugin-charts (index.js) 84.26KB 23.05KB
plugin-chatbot (index.js) 198.81KB 47.14KB
plugin-dashboard (index.js) 143.75KB 38.87KB
plugin-designer (index.js) 231.41KB 48.84KB
plugin-detail (index.js) 247.23KB 65.04KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 177.09KB 45.89KB
plugin-gantt (index.js) 179.16KB 45.06KB
plugin-grid (index.js) 238.48KB 65.51KB
plugin-kanban (index.js) 52.17KB 16.37KB
plugin-list (index.js) 116.72KB 29.10KB
plugin-map (index.js) 25.60KB 8.62KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 44.12KB 12.29KB
plugin-timeline (index.js) 38.83KB 11.71KB
plugin-tree (index.js) 14.51KB 5.15KB
plugin-view (index.js) 90.23KB 22.73KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.81KB 3.58KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 120.63KB 39.56KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.50KB 2.06KB
react (schema-input.js) 4.31KB 2.07KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (body-dialect.js) 4.50KB 1.99KB
sdui-parser (codegen.js) 9.45KB 3.76KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 7.30KB 3.12KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 25.28KB 7.80KB
sdui-parser (provenance.js) 3.84KB 1.90KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 23.87KB 7.83KB
types (ai.js) 4.39KB 2.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 4.12KB 1.61KB
types (authoring-nodes.js) 0.20KB 0.19KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (cloud.js) 0.20KB 0.18KB
types (complex.js) 4.44KB 2.07KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (dashboard-widget-layout.js) 2.06KB 0.96KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 1.13KB 0.65KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 5.78KB 2.70KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 5.00KB 2.39KB
types (navigation.js) 0.20KB 0.18KB
types (node-slots.js) 7.18KB 2.34KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 2.52KB 1.31KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 4.99KB 1.96KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 19.93KB 7.25KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

  • ✅ Core packages should be < 50KB gzipped
  • ✅ Component packages should be < 100KB gzipped
  • ⚠️ Plugin packages should be < 150KB gzipped

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 047cf475a179b7ff5cc569bf2dad97012e989e09
Local-runs: none

Inputs read: card #11676 (body and all three comments: the claim, the os-dev-report, the seat's ACCEPT), PR #11700 (body, the 16-file list, the net diff against main), and the check-runs on the head. Head files were read as git objects (git show and git grep at the sha): no checkout, nothing built, nothing run. The net diff main...head (merge-base 57d82cb34, one commit on the branch) is line-identical to the API diff.

① Derived judgments

Accept-set: nothing moves. No schema, validator, prop type or registry input is touched; ObjectTimelineProps is unchanged; TimelineConfigSchema lives in the spec and is not edited. RIGHT: the diff implies no accept-set change and the PR claims none.

Public surface, @object-ui/i18n: a WIDENING, read right. en.ts ends as const with export type TranslationKeys = typeof en; the entry index.ts re-exports TranslationKeys (through i18n.ts) and the packs. Adding timeline.bucket.earlier to en adds one member to TranslationKeys, and the same key lands in the other nine packs the registry loads (zh, ja, ko, de, fr, es, pt, ru, ar): ten packs in the roster, ten in the diff, each +1 line, placed after overdue. A published pack publishes every key, so this is a widening by exactly one key and nothing else. No mirrored catalogue elsewhere in the tree carries the bucket keys (the only thisWeek hits outside the packs are gantt's own gantt.toolbar.thisWeek), so "translated in every locale" is complete at ten.

Public surface, @object-ui/plugin-timeline: NO DECLARATION CHANGE, read right. The entry index.tsx exports the primitives block, export * from './renderer' (TIMELINE_SCALES, resolveTimelineScale, generateTimeScaleHeaders, TimelineRenderer), ObjectTimeline, ObjectTimelineProps and ObjectTimelineRenderer. TIMELINE_DEFAULT_TRANSLATIONS and useTimelineTranslation are imported by ObjectTimeline.tsx and renderer.tsx and re-exported by neither, so the new defaults row is unreachable from the built entry declaration, which agrees with the dev's byte-identical d.ts measurement. What moves is published BEHAVIOUR: in dateBucket, the one arm for a day before today returns t('timeline.bucket.earlier') instead of t('timeline.bucket.overdue'); the other six arms (no date, today, tomorrow, this week, next week, later) and the groupByField branch are untouched, and the grouping still feeds dateBucket the start date only.

timeline.bucket.overdue: at main its only reader was ObjectTimeline.tsx:753; at the head no source outside the defaults row and the packs reads it. Keeping it is RIGHT: retiring the key would be a narrowing with its own clause, and the card's open question decides whether it returns or retires. Report-only check:i18n-dead-keys listing it as needs-review is the expected reading, and no check-run turns that into a failure.

Tests: the three expectation edits are exactly the pins the arm change implies (objectTimelineInputs-11168, one row; dateOnlyZone-10866, the two driven west-of-UTC cases). No stale Overdue expectation remains in the plugin's tests (the remaining mentions are comments describing the old behaviour). Nothing else in the tree pins the timeline's past-date header: every other Overdue at the head belongs to the fields package's dueLike cell affordance, a record:alert specimen title or a view label. The new pin file covers the card's first pin (a created_at timeline shows no "Overdue", Done rows included), the six unchanged buckets as a control, a past due_date on an open record staying "Earlier" (no name heuristic), and the zh pack label.

Docs: content/docs/plugins/plugin-timeline.mdx:211 and TIMELINE_CONFIG_DESCRIPTION in index.tsx say only that entries "group into date buckets" and name no bucket, so no published doc went stale; the only "Overdue" near the plugin outside source is a historical CHANGELOG.md entry. RIGHT to leave them.

② Semver level

Changeset .changeset/11676-timeline-past-bucket.md: @object-ui/i18n: minor, @object-ui/plugin-timeline: minor, no major. Changeset Bump Policy, Changeset Declaration, Changeset Claim Re-read and Changeset Fixed Group Check all concluded success on the head.

  • @object-ui/i18n at minor: RIGHT, a widening of TranslationKeys and of every pack by one key.
  • @object-ui/plugin-timeline at minor: RIGHT. The declaration surface does not widen, but a rendered header a consumer can see and pin changes from "Overdue" to "Earlier" for every past day, and a consumer's own override of timeline.bucket.overdue no longer reaches that header. objectui spells such a behaviour break out at minor, and the changeset spells it out; patch would understate it.
  • Prose checked sentence by sentence against the diff: "all ten language packs" (ten); "the exported en pack and the TranslationKeys type derived from it gain one member" (true); "timeline.bucket.overdue is kept in every pack, and the timeline no longer reads it" (true at the head); "No component prop or exported type changes" (true, entry export block read); "Today, Tomorrow, This week, Next week, Later and No date are unchanged" (true, one arm in the diff). Nothing claimed that the diff does not do; nothing done that the changeset hides.

Clause-②: yes sits at the start of a line in the PR body. RIGHT arm: one surface widens (@object-ui/i18n) and none narrows (no prop, type or key is removed; the overdue key stays published), so plain yes, not yes (narrowing).

③ Boundary flags

Dev deviations (4), each answered:

  1. Commit trailer is the model-free pair (Co-authored-by: Claude plus the Claude-Session: URL), read off the head commit. Not a contract matter; AGENTS.md governs the trailer. No action.
  2. PR opens Part of #11676, not Fixes: verified on the body; the card stays open on the due-date half. RIGHT under the order's valve, since the second pin ("overdue but not a closed one") cannot be built without a closed-state declaration, and nothing the timeline reads carries one.
  3. No docs edit: verified at the head (①, Docs). RIGHT.
  4. No labels written by the dev: not a contract matter. The PR's plugin, tests and package: i18n are the labeler's; needs:contract-review is the seat's.

open_questions (1), the due-date half: ESCALATED, properly. The seat's ACCEPT routes the card to pm:queue with pm:retriage after the landing, carrying options A, B and C. This head forecloses none of them: A retires a key this head keeps; B and C add a declared or a heuristic signal on top of the neutral bucket. One addendum the seat should carry into the retriage: the card's own "Done when" names "an end field" as a signal the config already carries, and endDateField IS declared (spec, docs line 211, TIMELINE_CONFIG_DESCRIPTION), yet options A, B and C do not weigh it as the due axis (B proposes a new due-date role instead). On its own it still cannot satisfy "but not a closed one", and the grouping buckets the start date only, so this is a gap in the option set for triage, not in the landing.

out_of_scope_findings (1), dueLike declared in @object-ui/types but not in the spec's FieldSchema: a read-only inference with no measured reach, carried in option C; noted, not filed. Nothing for this record.

Check-runs on the head at the writing of this record: 31 success, 3 skipped (Test (coverage), the coverage shard, dependabot), 0 failed, and 8 still in progress, NOT concluded here: Test (shard 1/8), Test (shard 3/8), Test (shard 4/8), Test (shard 5/8), Test (shard 7/8), Test (shard 8/8), Type Check, Spec Main Shape Gate. Their convergence is the seat's landing check. Build & E2E, Lint, Test (dist pins), Bundle Analysis (eager closure 3322.4 KB against a 3330.4 KB budget, PASS) and Docs Route Eager Closure Check concluded success, which covers the one gate the dev could not measure locally (check:eager-locale-catalogues).

Implemented-by: claude/issue-11676-timeline-past-bucket
Reviewed-by: session_01FngvPpdrnhHMdHHq6vwwju

VERDICT: PASS


Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 6, 2026 07:16
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 6, 2026 07:16
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 6, 2026
Merged via the queue into main with commit ce464d9 Oct 6, 2026
45 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-11676-timeline-past-bucket branch October 6, 2026 07:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants