Skip to content

refactor(plugin-gantt): delete the taskListWidth tombstone, keep the one fact it held - #7511

Merged
os-project-manager merged 1 commit into
mainfrom
claude/issue-7421-tasklistwidth-tombstone
Sep 3, 2026
Merged

refactor(plugin-gantt): delete the taskListWidth tombstone, keep the one fact it held#7511
os-project-manager merged 1 commit into
mainfrom
claude/issue-7421-tasklistwidth-tombstone

Conversation

@os-project-manager

Copy link
Copy Markdown
Collaborator

Fixes #7421

Head sha 73ef5ec7a. Every reading below was taken on that tree.

What changed

Two lines out, two lines in, one file:

  • Outconst taskListWidth_LEGACY_REMOVED = null; from the GanttView body (and the whitespace-only line it left behind).
  • In — the one fact its trailing comment was carrying, moved to the site that owns it. The useResizeObserver call site now names the observed container width as the source the auto-sized row height, base column width and task-list pane width all derive from. Triage asked for exactly this: "the trailing comment records where the value went. If that fact is not already stated at the useResizeObserver call site, carry it there rather than deleting it with the line." It was not stated there — checked at the call site, GanttView.tsx:875, which had no comment at all.

Plus an empty-frontmatter changeset: packages/plugin-gantt/src is released source, so the presence gate wants a declaration, and there is nothing to release.

Liveness probe, with the control that fired

The premise holds. Probed the declaration form and the read sites separately, never the bare word:

probe shape result
declaration git grep -E '\b(const|let|var|function|class|interface|type|enum)\s+taskListWidth_LEGACY_REMOVED\b' 1packages/plugin-gantt/src/GanttView.tsx:2323, its own binding
read sites the same grep for the identifier, minus lines matching the binder form 0
control taskListWidth identical two shapes 3 declaration lines, 20 read sites
control rowHeight identical two shapes 2 declaration lines, 360 read sites

Both controls fired in the same run as the zero, so the zero is a reading. objectstack was swept too: 0 files / 0 lines for taskListWidth_LEGACY_REMOVED and for the bare taskListWidth, in a run where the controls gantt (94 files / 359 lines) and rowHeight (34 / 74) fired — no spec, zod or type declaration of this key exists in the platform repo.

The word-count trap this card sits on, measured rather than trusted: in GanttView.tsx, \btaskListWidth\b goes 21 to 20 across this diff, not 21 to 0, because the tombstone's own comment said taskListWidth once. A word count would read that as "the key survives". The declaration-form count goes 1 to 0.

Reverse verification

Committed first, then mutated: the pre-fix file restored from the base commit under trap … EXIT INT TERM with an absolute path.

  • Mutation proved on disk — blob 756df02d3 becomes 96033b44f; the deleted text greps 0 to 1, the injected comment greps 1 to 0.
  • Restore proved by state, not by exit code — blob back to 756df02d3, byte-equal to HEAD's; git diff HEAD prints nothing; the greps read 0 and 1 again.
  • No rebuild leg is owed here: both gates read source directly (ESLint lints the file, Vitest resolves packages/plugin-gantt/src through the root config), so no dist/ sits between the mutation and the reading.

What moved, and what stayed:

reading tombstone present tombstone deleted
eslint . on the package 354 problems (0 errors), GanttView.tsx 17 353 problems (0 errors), GanttView.tsx 16
the specific message 2323:9 warning 'taskListWidth_LEGACY_REMOVED' is assigned a value but never used @typescript-eslint/no-unused-vars absent
control warning 'currentDate' is assigned a value but never used present present
vitest run packages/plugin-gantt/src 62 files, 485 passed 62 files, 485 passed

⚠️ A correction to the card, from that table. The card says this line is something "the compiler and lint have no reason to complain about". Lint did complain: ESLint flagged it as @typescript-eslint/no-unused-vars. It never failed CI because unused vars sit at warning severity in this repo, while #7332 lifted only unused imports to error. The card's conclusion is unaffected — but the line was not invisible to the tooling, it was one row inside a 353-warning backlog.

No behavioural pin exists here and none was invented. The deleted binding was null with zero readers, so nothing observable distinguishes the two trees — and the table shows it: the suite is 485-green on both sides. The honest red/green is the lint reading above, from a rule that already existed.

Gates, each quoted from its own verdict line

Dependency closure built first (pnpm --filter '@object-ui/plugin-gantt^...' build, exit 0), so nothing below is a could-not-run.

  • pnpm --filter @object-ui/plugin-gantt type-check — exit 0, running tsc --noEmit && tsc -p tsconfig.test.json (both, the second being the test project).
  • pnpm --filter @object-ui/plugin-gantt lint — exit 0: ✖ 353 problems (0 errors, 353 warnings), all pre-existing, none in the lines this diff touches.
  • pnpm exec vitest run --maxWorkers=2 packages/plugin-gantt/src from the repo root (a package-cwd run is refused, objectui#3378) — Test Files 62 passed (62) / Tests 485 passed (485).
  • node scripts/check-changeset-presence.mjs✅ 1 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s) … Every one of them has an EMPTY frontmatter — declared as releasing nothing, which is the explicit exemption and a complete answer to this gate.
  • node scripts/check-changeset-no-major.mjs✅ No changeset declares a 'major' bump.
  • node scripts/check-control-bytes.mjs✅ check-control-bytes: OK (scanned 6195 tracked text file(s); skipped 85 binary).

Declared narrowing. The repo lint job is turbo run lint, i.e. per-package eslint .; only the one package this diff touches was linted. The three readings that make that a measurement rather than a skip: the population comes from ESLint's own config resolution, not from my guess — eslint . --format json reports 92 files linted in packages/plugin-gantt; the counts above are that run's; and eslint.config.js configures no type-aware linting (no parserOptions.project, no projectService), so this diff cannot move the verdict of any file it does not contain. CI runs the full farm regardless.

Not in scope

Clause-②: no. The diff removes a function-local const and adds a comment — no exported symbol, prop, type, zod schema or spec key moves, so nothing on the published accept surface changes. The declaration check was derived, not assumed from the _LEGACY_REMOVED spelling; the sweep is in the claim comment on the card.

#7228 — the same file's other dead sizing arm, columnWidthForContainer returning 110 from all three branches — is deliberately untouched here and remains open.

🤖 Generated with Claude Code

https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC


Generated by Claude Code

…one fact it held

`GanttView` carried `const taskListWidth_LEGACY_REMOVED = null` in its body, left
behind by the finished task-list-width refactor. Measured on `origin/main`
`a27d153c2`: the identifier occurred exactly once in the repo — its own declaration
— and zero times in a read position, in a probe run where the same shape returned 20
read sites for the live `taskListWidth` and 360 for `rowHeight`. Nothing in
objectstack declared it either (0 files, controls `gantt` 94 and `rowHeight` 34 fired
in that run). It bound `null`, so it carried no state, no side effect and no
contract surface.

What it did carry was a false signal: a name spelling `_LEGACY_REMOVED`, sitting a
few hundred lines below the real derivation, reads as a seam retained for a reason
recorded elsewhere, and the next reader goes looking for that reason.

Its trailing comment held one fact worth keeping — the width now comes from the
container `useResizeObserver` — and that fact was stated nowhere at the observer
call site. It moves there instead of dying with the line: the observed container
width is named as the source the auto-sized row height, base column width and
task-list pane width all derive from.

Pure deletion of an inert binding plus a comment: no behaviour changes, so the
changeset declares an empty frontmatter (releasing nothing).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EMrWaQw3XS5DxTHxp4yRyC
@github-actions github-actions Bot added the plugin label Sep 3, 2026
@github-actions

github-actions Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 50 chunks) 3181.9 KB 3191.4 KB
Main entry chunk (gzip) 143.2 KB 350 KB
Entry file index-nXe7vDDx.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) 15.67KB 5.75KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.06KB 3.86KB
auth (ActiveOrganizationStorage.js) 25.05KB 9.16KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.18KB 10.59KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.65KB 2.22KB
auth (SocialSignInButtons.js) 9.61KB 3.89KB
auth (UserMenu.js) 3.41KB 1.23KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.80KB
auth (createAuthenticatedFetch.js) 8.46KB 3.43KB
auth (index.js) 3.19KB 1.44KB
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) 5.13KB 2.35KB
collaboration (CommentThread.js) 26.08KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 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) 516.19KB 117.80KB
core (index.js) 6.12KB 2.42KB
create-plugin (index.js) 10.08KB 3.26KB
data-objectstack (index.js) 178.20KB 49.60KB
fields (index.js) 242.42KB 61.26KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (currency.js) 1.22KB 0.64KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 4.28KB 1.75KB
i18n (index.js) 3.44KB 1.39KB
i18n (pickLocalized.js) 7.62KB 3.26KB
i18n (provider.js) 26.89KB 9.04KB
i18n (useDisplayLocale.js) 2.85KB 1.45KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 38.98KB 10.98KB
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.55KB 0.62KB
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) 2.53KB 0.85KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useResponsiveConfig.js) 1.37KB 0.63KB
mobile (useSpecGesture.js) 4.32KB 1.64KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 11.71KB 4.29KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.24KB 2.16KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 5.12KB 1.74KB
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) 15.75KB 3.80KB
plugin-calendar (index.js) 48.12KB 13.34KB
plugin-charts (index.js) 70.87KB 19.72KB
plugin-chatbot (index.js) 196.19KB 46.43KB
plugin-dashboard (index.js) 132.82KB 34.64KB
plugin-designer (index.js) 212.87KB 43.19KB
plugin-detail (index.js) 251.07KB 64.12KB
plugin-editor (index.js) 2.46KB 1.10KB
plugin-form (index.js) 132.87KB 32.66KB
plugin-gantt (index.js) 167.50KB 41.08KB
plugin-grid (index.js) 209.25KB 56.71KB
plugin-kanban (index.js) 52.71KB 14.55KB
plugin-list (index.js) 113.33KB 27.60KB
plugin-map (index.js) 20.55KB 6.80KB
plugin-markdown (index.js) 13.72KB 4.69KB
plugin-report (index.js) 43.51KB 11.94KB
plugin-timeline (index.js) 30.84KB 8.85KB
plugin-tree (index.js) 9.40KB 3.23KB
plugin-view (index.js) 85.22KB 20.93KB
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.66KB 3.50KB
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) 81.07KB 26.86KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 3.63KB 1.70KB
react (schema-input.js) 2.32KB 1.24KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 5.41KB 2.34KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 4.93KB 2.24KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (parse.js) 20.57KB 5.88KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 10.35KB 3.60KB
types (ai.js) 0.20KB 0.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 0.99KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 2.74KB 1.41KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
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 (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
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) 4.74KB 2.25KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 2.59KB 1.31KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
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 (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

finding(plugin-gantt): taskListWidth_LEGACY_REMOVED is a declared-and-never-read const null left behind by a finished refactor

2 participants