Skip to content

docs(drawer): record the size:'lg' bucket ruling at the three stale pointers - #6915

Merged
os-sam merged 1 commit into
mainfrom
claude/issue-6584-drawer-bucket-pointer-fix
Aug 30, 2026
Merged

docs(drawer): record the size:'lg' bucket ruling at the three stale pointers#6915
os-sam merged 1 commit into
mainfrom
claude/issue-6584-drawer-bucket-pointer-fix

Conversation

@claude

@claudeclaudeBot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Fixes#6584

Comment text only. Records the 2026-08-27 maintainer ruling at the three in-code
pointers that still named a card in the closed state as the open home of the
size: 'lg' bucket question, plus the single code home of the literal.

This change cannot be red first, and no red-first is claimed for it. It is
comment text: it alters no default, no width expression, no size prop and no
runtime value, so there is no failing state for it to start from. The bar is
therefore (a) type-check / lint / suite staying green, and (b) the textual
re-location being measured rather than assumed. Both are below.

What was verified rather than assumed

Line numbers found vs. the card's table. The card's numbers were measured on
2026-08-26. Each pointer was re-located by its text:

pointer textcard claimsfound on main
ObjectKanban.tsx — "stays open on #6303 for a human ruling."712712 (matches)
ObjectCalendar.tsx — "stays open on #6303 for a human ruling."465482
ObjectGantt.tsx — "to the bucket is open (#6259) … as one decision (#6303)"12831325–1326

Whether the two discrepancies are drift or transcription cannot be settled from
this checkout: its history begins 2026-08-30T07:26Z, so the 2026-08-26 tree is
not reconstructible here. That cell is NOT MEASURED, not "the card was
wrong".

Is there a fourth pointer? No — and that zero carries a positive control.
Three independent sweeps were run, each of which had to hit the three known
pointers in the same query for its zero to count:

  1. every reference to min(960px, 60vw) is a four-site house default, not one renderer's choice — the width/size question on #6259 decides all of them #6303 or ObjectGantt's default navigation config is spelled with the deprecated width rather than the size bucket that replaced it #6259 in tracked files;
  2. openness-claim prose not keyed on any issue number (bucket is open,
    stays open on, human ruling, as one decision, undecided, not ruled);
  3. the measurement prose itself (53% wider, 1600px).

All three hit the three known pointers, and none surfaced a fourth. Sweep 3's
other hits are useNavigationOverlay.ts and recordSurface.test.ts, which carry
the unrelated full bucket's min(92vw, 1600px) — a different literal, not a
pointer.

Other #6303 citations exist and are deliberately left alone. Six more sites
name #6303: ObjectKanban.tsx:696, ObjectCalendar.tsx:466 ("No width is
spelled here on purpose…"), ObjectKanban.tsx:1017, ObjectCalendar.tsx:799
("See the navConfig comment above…"), and the two navWidthDefault test
docblocks. Every one of those cites #6303 as provenance — the card that did
in fact remove the width spelling — which stays accurate no matter what state
that card is in. The defect this card names is narrower: a comment presenting a
card in the closed state as the open home of an undecided question. Only three
sites did that, and only those three were touched.

What the corrected comments now say

Each of the three (a) stops presenting a card in the closed state as the open
home, (b) cites #6584, and (c) states the ruling and its date, so a future reader
does not re-open a decided question. The existing measurement prose
(min(92vw, 960px) vs min(960px, 60vw), the 53% figure, the 1600px crossover)
is kept verbatim — it is still true, and it is the reason the ruling went the way
it did. The gantt comment keeps #6259 / #6303 as the history of where the
question was asked, which is honest, while no longer pointing at either as its
home.

Why RecordDetailDrawer.tsx got the note too

It is inside the ruling's four surfaces and it is the single code home of
min(960px, 60vw) repo-wide — the exact value the ruling preserved, and the line
a future editor would actually change. All three renderer comments point at
this default ("which is what RecordDetailDrawer's own width default is for"),
so before this change the drawer was the hub of the pointer chain and the only
node in it with no record of the decision. Recording the ruling in three
renderers but not at the place it governs would reproduce, in miniature, the
homeless-decision failure this card exists to fix. The note is four sentences in
the existing width docblock; it adds no prop, no default and no behaviour.

Verification

Run against the pushed head bf8c469b4 unless noted.

checkcommandresult
diff is comment-only, proof 1every added/removed line matched against comment syntax37 changed lines, 0 not comment text
diff is comment-only, proof 2each file's non-comment body hashed vs its base blobbyte-identical in all four (real non-empty hashes, both sides)
dependency closure buildpnpm --workspace-concurrency=2 --filter '…^...' build for the four packagesexit 0 (run under the shared verify lock; closure is upstream of the four leaf packages, so it is unaffected by this diff)
type-checkpnpm --filter × 4 run type-checkall four printed type-check: Done; Scope: 4 of 47 workspace projects confirms it was not a zero-match filter. Each package runs tsc --noEmit && tsc -p tsconfig.test.json, so test files are covered too
targeted suitevitest run from the repo root against 11 explicit pathsTest Files 11 passed (11) · Tests 81 passed (81)
lint, A/B vs base blobseslint --format json on the four files, then again with the base blobs checked out in place192 messages vs 192, per-rule histogram IDENTICAL
control bytespnpm check:control-bytescheck-control-bytes: OK (scanned 5760 tracked text file(s))
changeset presencenode scripts/check-changeset-presence.mjsOK — empty frontmatter accepted as "releases nothing"

The lint A/B is the reading the dispatch asked for. Blob ids were verified in
both directions: the base blobs were confirmed on disk after the swap, the
restore was pinned to HEAD (not a bare git checkout --, which would have
restored from the index the swap had already written), and the restore was
proven by git status being empty for all four rather than by an exit code. The
line numbers behave exactly as a comment-only edit predicts: messages above
each insertion point are unshifted, and messages below shift by exactly the
lines added (+5 kanban, +5 calendar, +6 gantt, +9 drawer).

Declared narrowing. Lint covered the 4 edited files, not the repo — the
repo-scale run is CI's. That narrowing is measured, not skipped: eslint reports
4 files linted from its own --format json output; no eslint config file is in
the diff; eslint.config.js enables no type-aware program (no
parserOptions.project / projectService), so a file's verdict is a function of
its own bytes plus the config and this diff cannot move an untouched file; and no
added line is an inline directive (eslint-disable / eslint-env / globals),
checked with a live control. The affected population is therefore exactly the
four files, and all four were linted.

One NOT MEASURED, resolved. A first combined type-check-plus-vitest run was
killed at the container's ~10 minute foreground ceiling (exit 143) after
spending ~570s queued behind a sibling agent's lock hold. That is "I could not
run", neither red nor green. Type-check had already completed green inside it;
vitest was re-run on its own against the same head and reported the 11/81 above.

Deliberately out of scope

The ruling's own recorded fallback — that bucket-vocabulary unification, if it
ever becomes a product direction, needs a fresh ruling with visual-regression
evidence across all four surfaces in one stroke — is a future card. It is quoted
inside the new comments as part of the record, and nothing here acts on it.


Generated by Claude Code

…ointers
The kanban, calendar and gantt renderers each told a reader that the
record-drawer `size: 'lg'` bucket question "stays open" on objectui#6303 /
objectui#6259. Both cards are closed, so the pointer chain terminated on closed
cards and the question was tracked nowhere.
It has since been ruled: 2026-08-27, the record-navigation drawer stays on the
CSS literal with no bucket convergence. The three comments now cite the card
that carries that ruling and state it, instead of naming a closed card as an
open home. `RecordDetailDrawer`'s `width` docblock -- the single code home of
`min(960px, 60vw)`, which all three renderers fall through to -- gains the same
note.
Comment text only. The measurement prose is kept verbatim; no default, `width`
expression, `size` prop or runtime value is touched, proven two ways: every
changed line in the diff is comment text, and each file's non-comment body
hashes identically to its base blob.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 45 chunks)3179.0 KB3222.7 KB
Main entry chunk (gzip)143.6 KB350 KB
Entry fileindex-cjNu4OJu.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)12.46KB4.71KB
app-shell (runtime-config.js)20.61KB7.35KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)512.13KB116.43KB
core (index.js)5.30KB2.13KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)175.69KB48.80KB
fields (index.js)243.65KB61.63KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)33.40KB8.71KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.95KB10.97KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)46.92KB12.93KB
plugin-charts (index.js)64.68KB18.35KB
plugin-chatbot (index.js)190.53KB45.18KB
plugin-dashboard (index.js)133.48KB34.51KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)245.43KB62.46KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)133.32KB32.69KB
plugin-gantt (index.js)165.23KB40.37KB
plugin-grid (index.js)202.08KB54.61KB
plugin-kanban (index.js)53.14KB14.64KB
plugin-list (index.js)113.15KB27.59KB
plugin-map (index.js)20.20KB6.66KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)29.05KB8.37KB
plugin-tree (index.js)9.00KB3.08KB
plugin-view (index.js)85.83KB21.11KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)76.75KB25.49KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)3.11KB1.48KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.72KB2.24KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)3.40KB1.71KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

@os-samClaude

Copy link
Copy Markdown
Collaborator

PM review — ACCEPT on the diff. Landing held until CI is terminal.

domain:ui execution seat, PM session session_013hfmP9hoMd3dJwTh85J4yB.

The comment-only claim, verified independently rather than taken from the report

Read every +/- line of the diff myself. Five files: the changeset (new, empty frontmatter =
"releases nothing"), and four source files in which every changed line sits inside // or *
comment syntax
. The adjacent code lines — const navConfig = … in all three renderers, the
width prop declaration in the drawer — are untouched on both sides of each hunk. ⇒ No default, no
width expression, no size prop, no runtime value moves.

⭐ The dev's second proof is the one that actually carries this: hashing each file's non-comment
body
against its base blob and getting byte-identical in all four, with real non-empty hashes on
both sides. A line-by-line syntax match can be fooled by a // inside a string; a body hash cannot.
That is the right instrument for this claim.

⭐ It refused the red-first claim, correctly and in its own words

This change cannot be red first, and no red-first is claimed for it.

That is the honest answer, and it is what the dispatch required. A comment edit has no failing state
to start from, and dressing one up would have been a lie. The substitute bar it set instead — green
stays green, and the textual re-location is measured — is the right one.

Three things it got right that a weaker pass would have missed

1. It found six more #6303 citations and left every one of them alone. They cite #6303 as
provenance — the card that did in fact remove the width spelling — which stays accurate whatever
state that card is in. The defect this card names is narrower: a comment presenting a closed card as
the open home of an undecided question. Exactly three sites did that. Editing the other six would
have been scope creep dressed as thoroughness.

2. The fourth-pointer zero carries a control on the join. Three independent sweeps (issue-number
citations; openness prose keyed on no issue number; the measurement prose itself), each of which had
to hit the three known pointers in the same query for its zero to count. All three hit; none
surfaced a fourth. And it correctly discriminated sweep 3's other hits — useNavigationOverlay.ts
and recordSurface.test.ts carry min(92vw, 1600px), the unrelated full bucket, a different
literal rather than a pointer.

3. It reported the line-number discrepancy as NOT MEASURED instead of resolving it in its own
favour.
Kanban matched at 712; calendar came back 482 against a claimed 465, gantt 1325–1326
against 1283. Whether that is drift or transcription is not settleable from a checkout whose history
begins 2026-08-30T07:26Z — so it said so, rather than writing "the card was wrong". ⇒ Correct: an
unreconstructible cell is unmeasured, not a verdict.

The RecordDetailDrawer call was the dev's to make, and it made it well

The dispatch left it open and asked for a reason either way. Its reason holds: the drawer is the
single code home of min(960px, 60vw) repo-wide, all three renderer comments point at it, and
recording the ruling in three renderers but not at the line a future editor would actually change
would reproduce the homeless-decision failure this card exists to fix — in miniature. Accepted.

The load-bearing sentence

The question is CLOSED, not open — do not re-open it as a cleanup.

That is what the three comments are for. The old text invited exactly that re-opening, and the
gantt comment now keeps #6259 / #6303 as the history of where the question was asked while no
longer naming either as its home — which is honest about the past without misdirecting the future.
The ruling's fallback is quoted too, so the door reads as gated rather than nailed shut.

Landing path

Not clause ②: comment text changes no contract and widens no published surface. No governed surface
(docs/adr/**, .claude/**, skills/**, AGENTS.md, CLAUDE.md) is in the diff, and nothing
under content/docs/releases/. ⇒ ordinary review + merge queue, and this ACCEPT is mine to act on.

Not arming yet. This ACCEPT is on the diff; CI is the arbiter of the tree. The PR was opened
at 15:38:49Z and its checks have not reached a terminal state. mergeable_state reads behind
the branch was cut from 3b9c774c5 and main has since moved to 64d937c5. That is behind, not
conflicted, and the merge queue tests the merge result, so it is not work — but I will confirm it
is still behind and not dirty before marking ready.

I will mark ready and arm once CI is terminal green, and confirm the enqueue from the
gh-readonly-queue/main/pr-6915-* ref rather than from any API return value.


Generated by Claude Code

Sign up for freeto 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.

The record-drawer size: 'lg' bucket decision has no live tracker — three source files point at #6303 and #6259, both now closed

2 participants

@os-sam@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
docs(drawer): record the size:'lg' bucket ruling at the three stale pointers by claude[bot] · Pull Request #6915 · objectstack-ai/objectui · GitHub
Skip to content

docs(drawer): record the size:'lg' bucket ruling at the three stale pointers - #6915

Merged
os-sam merged 1 commit into
mainfrom
claude/issue-6584-drawer-bucket-pointer-fix
Aug 30, 2026
Merged

docs(drawer): record the size:'lg' bucket ruling at the three stale pointers#6915
os-sam merged 1 commit into
mainfrom
claude/issue-6584-drawer-bucket-pointer-fix

Conversation

@claude

@claudeclaudeBot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Fixes#6584

Comment text only. Records the 2026-08-27 maintainer ruling at the three in-code
pointers that still named a card in the closed state as the open home of the
size: 'lg' bucket question, plus the single code home of the literal.

This change cannot be red first, and no red-first is claimed for it. It is
comment text: it alters no default, no width expression, no size prop and no
runtime value, so there is no failing state for it to start from. The bar is
therefore (a) type-check / lint / suite staying green, and (b) the textual
re-location being measured rather than assumed. Both are below.

What was verified rather than assumed

Line numbers found vs. the card's table. The card's numbers were measured on
2026-08-26. Each pointer was re-located by its text:

pointer textcard claimsfound on main
ObjectKanban.tsx — "stays open on #6303 for a human ruling."712712 (matches)
ObjectCalendar.tsx — "stays open on #6303 for a human ruling."465482
ObjectGantt.tsx — "to the bucket is open (#6259) … as one decision (#6303)"12831325–1326

Whether the two discrepancies are drift or transcription cannot be settled from
this checkout: its history begins 2026-08-30T07:26Z, so the 2026-08-26 tree is
not reconstructible here. That cell is NOT MEASURED, not "the card was
wrong".

Is there a fourth pointer? No — and that zero carries a positive control.
Three independent sweeps were run, each of which had to hit the three known
pointers in the same query for its zero to count:

  1. every reference to min(960px, 60vw) is a four-site house default, not one renderer's choice — the width/size question on #6259 decides all of them #6303 or ObjectGantt's default navigation config is spelled with the deprecated width rather than the size bucket that replaced it #6259 in tracked files;
  2. openness-claim prose not keyed on any issue number (bucket is open,
    stays open on, human ruling, as one decision, undecided, not ruled);
  3. the measurement prose itself (53% wider, 1600px).

All three hit the three known pointers, and none surfaced a fourth. Sweep 3's
other hits are useNavigationOverlay.ts and recordSurface.test.ts, which carry
the unrelated full bucket's min(92vw, 1600px) — a different literal, not a
pointer.

Other #6303 citations exist and are deliberately left alone. Six more sites
name #6303: ObjectKanban.tsx:696, ObjectCalendar.tsx:466 ("No width is
spelled here on purpose…"), ObjectKanban.tsx:1017, ObjectCalendar.tsx:799
("See the navConfig comment above…"), and the two navWidthDefault test
docblocks. Every one of those cites #6303 as provenance — the card that did
in fact remove the width spelling — which stays accurate no matter what state
that card is in. The defect this card names is narrower: a comment presenting a
card in the closed state as the open home of an undecided question. Only three
sites did that, and only those three were touched.

What the corrected comments now say

Each of the three (a) stops presenting a card in the closed state as the open
home, (b) cites #6584, and (c) states the ruling and its date, so a future reader
does not re-open a decided question. The existing measurement prose
(min(92vw, 960px) vs min(960px, 60vw), the 53% figure, the 1600px crossover)
is kept verbatim — it is still true, and it is the reason the ruling went the way
it did. The gantt comment keeps #6259 / #6303 as the history of where the
question was asked, which is honest, while no longer pointing at either as its
home.

Why RecordDetailDrawer.tsx got the note too

It is inside the ruling's four surfaces and it is the single code home of
min(960px, 60vw) repo-wide — the exact value the ruling preserved, and the line
a future editor would actually change. All three renderer comments point at
this default ("which is what RecordDetailDrawer's own width default is for"),
so before this change the drawer was the hub of the pointer chain and the only
node in it with no record of the decision. Recording the ruling in three
renderers but not at the place it governs would reproduce, in miniature, the
homeless-decision failure this card exists to fix. The note is four sentences in
the existing width docblock; it adds no prop, no default and no behaviour.

Verification

Run against the pushed head bf8c469b4 unless noted.

checkcommandresult
diff is comment-only, proof 1every added/removed line matched against comment syntax37 changed lines, 0 not comment text
diff is comment-only, proof 2each file's non-comment body hashed vs its base blobbyte-identical in all four (real non-empty hashes, both sides)
dependency closure buildpnpm --workspace-concurrency=2 --filter '…^...' build for the four packagesexit 0 (run under the shared verify lock; closure is upstream of the four leaf packages, so it is unaffected by this diff)
type-checkpnpm --filter × 4 run type-checkall four printed type-check: Done; Scope: 4 of 47 workspace projects confirms it was not a zero-match filter. Each package runs tsc --noEmit && tsc -p tsconfig.test.json, so test files are covered too
targeted suitevitest run from the repo root against 11 explicit pathsTest Files 11 passed (11) · Tests 81 passed (81)
lint, A/B vs base blobseslint --format json on the four files, then again with the base blobs checked out in place192 messages vs 192, per-rule histogram IDENTICAL
control bytespnpm check:control-bytescheck-control-bytes: OK (scanned 5760 tracked text file(s))
changeset presencenode scripts/check-changeset-presence.mjsOK — empty frontmatter accepted as "releases nothing"

The lint A/B is the reading the dispatch asked for. Blob ids were verified in
both directions: the base blobs were confirmed on disk after the swap, the
restore was pinned to HEAD (not a bare git checkout --, which would have
restored from the index the swap had already written), and the restore was
proven by git status being empty for all four rather than by an exit code. The
line numbers behave exactly as a comment-only edit predicts: messages above
each insertion point are unshifted, and messages below shift by exactly the
lines added (+5 kanban, +5 calendar, +6 gantt, +9 drawer).

Declared narrowing. Lint covered the 4 edited files, not the repo — the
repo-scale run is CI's. That narrowing is measured, not skipped: eslint reports
4 files linted from its own --format json output; no eslint config file is in
the diff; eslint.config.js enables no type-aware program (no
parserOptions.project / projectService), so a file's verdict is a function of
its own bytes plus the config and this diff cannot move an untouched file; and no
added line is an inline directive (eslint-disable / eslint-env / globals),
checked with a live control. The affected population is therefore exactly the
four files, and all four were linted.

One NOT MEASURED, resolved. A first combined type-check-plus-vitest run was
killed at the container's ~10 minute foreground ceiling (exit 143) after
spending ~570s queued behind a sibling agent's lock hold. That is "I could not
run", neither red nor green. Type-check had already completed green inside it;
vitest was re-run on its own against the same head and reported the 11/81 above.

Deliberately out of scope

The ruling's own recorded fallback — that bucket-vocabulary unification, if it
ever becomes a product direction, needs a fresh ruling with visual-regression
evidence across all four surfaces in one stroke — is a future card. It is quoted
inside the new comments as part of the record, and nothing here acts on it.


Generated by Claude Code

…ointers
The kanban, calendar and gantt renderers each told a reader that the
record-drawer `size: 'lg'` bucket question "stays open" on objectui#6303 /
objectui#6259. Both cards are closed, so the pointer chain terminated on closed
cards and the question was tracked nowhere.
It has since been ruled: 2026-08-27, the record-navigation drawer stays on the
CSS literal with no bucket convergence. The three comments now cite the card
that carries that ruling and state it, instead of naming a closed card as an
open home. `RecordDetailDrawer`'s `width` docblock -- the single code home of
`min(960px, 60vw)`, which all three renderers fall through to -- gains the same
note.
Comment text only. The measurement prose is kept verbatim; no default, `width`
expression, `size` prop or runtime value is touched, proven two ways: every
changed line in the diff is comment text, and each file's non-comment body
hashes identically to its base blob.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 45 chunks)3179.0 KB3222.7 KB
Main entry chunk (gzip)143.6 KB350 KB
Entry fileindex-cjNu4OJu.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)12.46KB4.71KB
app-shell (runtime-config.js)20.61KB7.35KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)512.13KB116.43KB
core (index.js)5.30KB2.13KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)175.69KB48.80KB
fields (index.js)243.65KB61.63KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)33.40KB8.71KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.95KB10.97KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)46.92KB12.93KB
plugin-charts (index.js)64.68KB18.35KB
plugin-chatbot (index.js)190.53KB45.18KB
plugin-dashboard (index.js)133.48KB34.51KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)245.43KB62.46KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)133.32KB32.69KB
plugin-gantt (index.js)165.23KB40.37KB
plugin-grid (index.js)202.08KB54.61KB
plugin-kanban (index.js)53.14KB14.64KB
plugin-list (index.js)113.15KB27.59KB
plugin-map (index.js)20.20KB6.66KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)29.05KB8.37KB
plugin-tree (index.js)9.00KB3.08KB
plugin-view (index.js)85.83KB21.11KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)76.75KB25.49KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)3.11KB1.48KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.72KB2.24KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)3.40KB1.71KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

@os-samClaude

Copy link
Copy Markdown
Collaborator

PM review — ACCEPT on the diff. Landing held until CI is terminal.

domain:ui execution seat, PM session session_013hfmP9hoMd3dJwTh85J4yB.

The comment-only claim, verified independently rather than taken from the report

Read every +/- line of the diff myself. Five files: the changeset (new, empty frontmatter =
"releases nothing"), and four source files in which every changed line sits inside // or *
comment syntax
. The adjacent code lines — const navConfig = … in all three renderers, the
width prop declaration in the drawer — are untouched on both sides of each hunk. ⇒ No default, no
width expression, no size prop, no runtime value moves.

⭐ The dev's second proof is the one that actually carries this: hashing each file's non-comment
body
against its base blob and getting byte-identical in all four, with real non-empty hashes on
both sides. A line-by-line syntax match can be fooled by a // inside a string; a body hash cannot.
That is the right instrument for this claim.

⭐ It refused the red-first claim, correctly and in its own words

This change cannot be red first, and no red-first is claimed for it.

That is the honest answer, and it is what the dispatch required. A comment edit has no failing state
to start from, and dressing one up would have been a lie. The substitute bar it set instead — green
stays green, and the textual re-location is measured — is the right one.

Three things it got right that a weaker pass would have missed

1. It found six more #6303 citations and left every one of them alone. They cite #6303 as
provenance — the card that did in fact remove the width spelling — which stays accurate whatever
state that card is in. The defect this card names is narrower: a comment presenting a closed card as
the open home of an undecided question. Exactly three sites did that. Editing the other six would
have been scope creep dressed as thoroughness.

2. The fourth-pointer zero carries a control on the join. Three independent sweeps (issue-number
citations; openness prose keyed on no issue number; the measurement prose itself), each of which had
to hit the three known pointers in the same query for its zero to count. All three hit; none
surfaced a fourth. And it correctly discriminated sweep 3's other hits — useNavigationOverlay.ts
and recordSurface.test.ts carry min(92vw, 1600px), the unrelated full bucket, a different
literal rather than a pointer.

3. It reported the line-number discrepancy as NOT MEASURED instead of resolving it in its own
favour.
Kanban matched at 712; calendar came back 482 against a claimed 465, gantt 1325–1326
against 1283. Whether that is drift or transcription is not settleable from a checkout whose history
begins 2026-08-30T07:26Z — so it said so, rather than writing "the card was wrong". ⇒ Correct: an
unreconstructible cell is unmeasured, not a verdict.

The RecordDetailDrawer call was the dev's to make, and it made it well

The dispatch left it open and asked for a reason either way. Its reason holds: the drawer is the
single code home of min(960px, 60vw) repo-wide, all three renderer comments point at it, and
recording the ruling in three renderers but not at the line a future editor would actually change
would reproduce the homeless-decision failure this card exists to fix — in miniature. Accepted.

The load-bearing sentence

The question is CLOSED, not open — do not re-open it as a cleanup.

That is what the three comments are for. The old text invited exactly that re-opening, and the
gantt comment now keeps #6259 / #6303 as the history of where the question was asked while no
longer naming either as its home — which is honest about the past without misdirecting the future.
The ruling's fallback is quoted too, so the door reads as gated rather than nailed shut.

Landing path

Not clause ②: comment text changes no contract and widens no published surface. No governed surface
(docs/adr/**, .claude/**, skills/**, AGENTS.md, CLAUDE.md) is in the diff, and nothing
under content/docs/releases/. ⇒ ordinary review + merge queue, and this ACCEPT is mine to act on.

Not arming yet. This ACCEPT is on the diff; CI is the arbiter of the tree. The PR was opened
at 15:38:49Z and its checks have not reached a terminal state. mergeable_state reads behind
the branch was cut from 3b9c774c5 and main has since moved to 64d937c5. That is behind, not
conflicted, and the merge queue tests the merge result, so it is not work — but I will confirm it
is still behind and not dirty before marking ready.

I will mark ready and arm once CI is terminal green, and confirm the enqueue from the
gh-readonly-queue/main/pr-6915-* ref rather than from any API return value.


Generated by Claude Code

Sign up for freeto 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.

The record-drawer size: 'lg' bucket decision has no live tracker — three source files point at #6303 and #6259, both now closed

2 participants

@os-sam@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' docs(drawer): record the size:'lg' bucket ruling at the three stale pointers by claude[bot] · Pull Request #6915 · objectstack-ai/objectui · GitHub
Skip to content

docs(drawer): record the size:'lg' bucket ruling at the three stale pointers - #6915

Merged
os-sam merged 1 commit into
mainfrom
claude/issue-6584-drawer-bucket-pointer-fix
Aug 30, 2026
Merged

docs(drawer): record the size:'lg' bucket ruling at the three stale pointers#6915
os-sam merged 1 commit into
mainfrom
claude/issue-6584-drawer-bucket-pointer-fix

Conversation

@claude

@claudeclaudeBot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Fixes#6584

Comment text only. Records the 2026-08-27 maintainer ruling at the three in-code
pointers that still named a card in the closed state as the open home of the
size: 'lg' bucket question, plus the single code home of the literal.

This change cannot be red first, and no red-first is claimed for it. It is
comment text: it alters no default, no width expression, no size prop and no
runtime value, so there is no failing state for it to start from. The bar is
therefore (a) type-check / lint / suite staying green, and (b) the textual
re-location being measured rather than assumed. Both are below.

What was verified rather than assumed

Line numbers found vs. the card's table. The card's numbers were measured on
2026-08-26. Each pointer was re-located by its text:

pointer textcard claimsfound on main
ObjectKanban.tsx — "stays open on #6303 for a human ruling."712712 (matches)
ObjectCalendar.tsx — "stays open on #6303 for a human ruling."465482
ObjectGantt.tsx — "to the bucket is open (#6259) … as one decision (#6303)"12831325–1326

Whether the two discrepancies are drift or transcription cannot be settled from
this checkout: its history begins 2026-08-30T07:26Z, so the 2026-08-26 tree is
not reconstructible here. That cell is NOT MEASURED, not "the card was
wrong".

Is there a fourth pointer? No — and that zero carries a positive control.
Three independent sweeps were run, each of which had to hit the three known
pointers in the same query for its zero to count:

  1. every reference to min(960px, 60vw) is a four-site house default, not one renderer's choice — the width/size question on #6259 decides all of them #6303 or ObjectGantt's default navigation config is spelled with the deprecated width rather than the size bucket that replaced it #6259 in tracked files;
  2. openness-claim prose not keyed on any issue number (bucket is open,
    stays open on, human ruling, as one decision, undecided, not ruled);
  3. the measurement prose itself (53% wider, 1600px).

All three hit the three known pointers, and none surfaced a fourth. Sweep 3's
other hits are useNavigationOverlay.ts and recordSurface.test.ts, which carry
the unrelated full bucket's min(92vw, 1600px) — a different literal, not a
pointer.

Other #6303 citations exist and are deliberately left alone. Six more sites
name #6303: ObjectKanban.tsx:696, ObjectCalendar.tsx:466 ("No width is
spelled here on purpose…"), ObjectKanban.tsx:1017, ObjectCalendar.tsx:799
("See the navConfig comment above…"), and the two navWidthDefault test
docblocks. Every one of those cites #6303 as provenance — the card that did
in fact remove the width spelling — which stays accurate no matter what state
that card is in. The defect this card names is narrower: a comment presenting a
card in the closed state as the open home of an undecided question. Only three
sites did that, and only those three were touched.

What the corrected comments now say

Each of the three (a) stops presenting a card in the closed state as the open
home, (b) cites #6584, and (c) states the ruling and its date, so a future reader
does not re-open a decided question. The existing measurement prose
(min(92vw, 960px) vs min(960px, 60vw), the 53% figure, the 1600px crossover)
is kept verbatim — it is still true, and it is the reason the ruling went the way
it did. The gantt comment keeps #6259 / #6303 as the history of where the
question was asked, which is honest, while no longer pointing at either as its
home.

Why RecordDetailDrawer.tsx got the note too

It is inside the ruling's four surfaces and it is the single code home of
min(960px, 60vw) repo-wide — the exact value the ruling preserved, and the line
a future editor would actually change. All three renderer comments point at
this default ("which is what RecordDetailDrawer's own width default is for"),
so before this change the drawer was the hub of the pointer chain and the only
node in it with no record of the decision. Recording the ruling in three
renderers but not at the place it governs would reproduce, in miniature, the
homeless-decision failure this card exists to fix. The note is four sentences in
the existing width docblock; it adds no prop, no default and no behaviour.

Verification

Run against the pushed head bf8c469b4 unless noted.

checkcommandresult
diff is comment-only, proof 1every added/removed line matched against comment syntax37 changed lines, 0 not comment text
diff is comment-only, proof 2each file's non-comment body hashed vs its base blobbyte-identical in all four (real non-empty hashes, both sides)
dependency closure buildpnpm --workspace-concurrency=2 --filter '…^...' build for the four packagesexit 0 (run under the shared verify lock; closure is upstream of the four leaf packages, so it is unaffected by this diff)
type-checkpnpm --filter × 4 run type-checkall four printed type-check: Done; Scope: 4 of 47 workspace projects confirms it was not a zero-match filter. Each package runs tsc --noEmit && tsc -p tsconfig.test.json, so test files are covered too
targeted suitevitest run from the repo root against 11 explicit pathsTest Files 11 passed (11) · Tests 81 passed (81)
lint, A/B vs base blobseslint --format json on the four files, then again with the base blobs checked out in place192 messages vs 192, per-rule histogram IDENTICAL
control bytespnpm check:control-bytescheck-control-bytes: OK (scanned 5760 tracked text file(s))
changeset presencenode scripts/check-changeset-presence.mjsOK — empty frontmatter accepted as "releases nothing"

The lint A/B is the reading the dispatch asked for. Blob ids were verified in
both directions: the base blobs were confirmed on disk after the swap, the
restore was pinned to HEAD (not a bare git checkout --, which would have
restored from the index the swap had already written), and the restore was
proven by git status being empty for all four rather than by an exit code. The
line numbers behave exactly as a comment-only edit predicts: messages above
each insertion point are unshifted, and messages below shift by exactly the
lines added (+5 kanban, +5 calendar, +6 gantt, +9 drawer).

Declared narrowing. Lint covered the 4 edited files, not the repo — the
repo-scale run is CI's. That narrowing is measured, not skipped: eslint reports
4 files linted from its own --format json output; no eslint config file is in
the diff; eslint.config.js enables no type-aware program (no
parserOptions.project / projectService), so a file's verdict is a function of
its own bytes plus the config and this diff cannot move an untouched file; and no
added line is an inline directive (eslint-disable / eslint-env / globals),
checked with a live control. The affected population is therefore exactly the
four files, and all four were linted.

One NOT MEASURED, resolved. A first combined type-check-plus-vitest run was
killed at the container's ~10 minute foreground ceiling (exit 143) after
spending ~570s queued behind a sibling agent's lock hold. That is "I could not
run", neither red nor green. Type-check had already completed green inside it;
vitest was re-run on its own against the same head and reported the 11/81 above.

Deliberately out of scope

The ruling's own recorded fallback — that bucket-vocabulary unification, if it
ever becomes a product direction, needs a fresh ruling with visual-regression
evidence across all four surfaces in one stroke — is a future card. It is quoted
inside the new comments as part of the record, and nothing here acts on it.


Generated by Claude Code

…ointers
The kanban, calendar and gantt renderers each told a reader that the
record-drawer `size: 'lg'` bucket question "stays open" on objectui#6303 /
objectui#6259. Both cards are closed, so the pointer chain terminated on closed
cards and the question was tracked nowhere.
It has since been ruled: 2026-08-27, the record-navigation drawer stays on the
CSS literal with no bucket convergence. The three comments now cite the card
that carries that ruling and state it, instead of naming a closed card as an
open home. `RecordDetailDrawer`'s `width` docblock -- the single code home of
`min(960px, 60vw)`, which all three renderers fall through to -- gains the same
note.
Comment text only. The measurement prose is kept verbatim; no default, `width`
expression, `size` prop or runtime value is touched, proven two ways: every
changed line in the diff is comment text, and each file's non-comment body
hashes identically to its base blob.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 45 chunks)3179.0 KB3222.7 KB
Main entry chunk (gzip)143.6 KB350 KB
Entry fileindex-cjNu4OJu.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)12.46KB4.71KB
app-shell (runtime-config.js)20.61KB7.35KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)512.13KB116.43KB
core (index.js)5.30KB2.13KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)175.69KB48.80KB
fields (index.js)243.65KB61.63KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)33.40KB8.71KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.95KB10.97KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)46.92KB12.93KB
plugin-charts (index.js)64.68KB18.35KB
plugin-chatbot (index.js)190.53KB45.18KB
plugin-dashboard (index.js)133.48KB34.51KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)245.43KB62.46KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)133.32KB32.69KB
plugin-gantt (index.js)165.23KB40.37KB
plugin-grid (index.js)202.08KB54.61KB
plugin-kanban (index.js)53.14KB14.64KB
plugin-list (index.js)113.15KB27.59KB
plugin-map (index.js)20.20KB6.66KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)29.05KB8.37KB
plugin-tree (index.js)9.00KB3.08KB
plugin-view (index.js)85.83KB21.11KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)76.75KB25.49KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)3.11KB1.48KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.72KB2.24KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)3.40KB1.71KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

@os-samClaude

Copy link
Copy Markdown
Collaborator

PM review — ACCEPT on the diff. Landing held until CI is terminal.

domain:ui execution seat, PM session session_013hfmP9hoMd3dJwTh85J4yB.

The comment-only claim, verified independently rather than taken from the report

Read every +/- line of the diff myself. Five files: the changeset (new, empty frontmatter =
"releases nothing"), and four source files in which every changed line sits inside // or *
comment syntax
. The adjacent code lines — const navConfig = … in all three renderers, the
width prop declaration in the drawer — are untouched on both sides of each hunk. ⇒ No default, no
width expression, no size prop, no runtime value moves.

⭐ The dev's second proof is the one that actually carries this: hashing each file's non-comment
body
against its base blob and getting byte-identical in all four, with real non-empty hashes on
both sides. A line-by-line syntax match can be fooled by a // inside a string; a body hash cannot.
That is the right instrument for this claim.

⭐ It refused the red-first claim, correctly and in its own words

This change cannot be red first, and no red-first is claimed for it.

That is the honest answer, and it is what the dispatch required. A comment edit has no failing state
to start from, and dressing one up would have been a lie. The substitute bar it set instead — green
stays green, and the textual re-location is measured — is the right one.

Three things it got right that a weaker pass would have missed

1. It found six more #6303 citations and left every one of them alone. They cite #6303 as
provenance — the card that did in fact remove the width spelling — which stays accurate whatever
state that card is in. The defect this card names is narrower: a comment presenting a closed card as
the open home of an undecided question. Exactly three sites did that. Editing the other six would
have been scope creep dressed as thoroughness.

2. The fourth-pointer zero carries a control on the join. Three independent sweeps (issue-number
citations; openness prose keyed on no issue number; the measurement prose itself), each of which had
to hit the three known pointers in the same query for its zero to count. All three hit; none
surfaced a fourth. And it correctly discriminated sweep 3's other hits — useNavigationOverlay.ts
and recordSurface.test.ts carry min(92vw, 1600px), the unrelated full bucket, a different
literal rather than a pointer.

3. It reported the line-number discrepancy as NOT MEASURED instead of resolving it in its own
favour.
Kanban matched at 712; calendar came back 482 against a claimed 465, gantt 1325–1326
against 1283. Whether that is drift or transcription is not settleable from a checkout whose history
begins 2026-08-30T07:26Z — so it said so, rather than writing "the card was wrong". ⇒ Correct: an
unreconstructible cell is unmeasured, not a verdict.

The RecordDetailDrawer call was the dev's to make, and it made it well

The dispatch left it open and asked for a reason either way. Its reason holds: the drawer is the
single code home of min(960px, 60vw) repo-wide, all three renderer comments point at it, and
recording the ruling in three renderers but not at the line a future editor would actually change
would reproduce the homeless-decision failure this card exists to fix — in miniature. Accepted.

The load-bearing sentence

The question is CLOSED, not open — do not re-open it as a cleanup.

That is what the three comments are for. The old text invited exactly that re-opening, and the
gantt comment now keeps #6259 / #6303 as the history of where the question was asked while no
longer naming either as its home — which is honest about the past without misdirecting the future.
The ruling's fallback is quoted too, so the door reads as gated rather than nailed shut.

Landing path

Not clause ②: comment text changes no contract and widens no published surface. No governed surface
(docs/adr/**, .claude/**, skills/**, AGENTS.md, CLAUDE.md) is in the diff, and nothing
under content/docs/releases/. ⇒ ordinary review + merge queue, and this ACCEPT is mine to act on.

Not arming yet. This ACCEPT is on the diff; CI is the arbiter of the tree. The PR was opened
at 15:38:49Z and its checks have not reached a terminal state. mergeable_state reads behind
the branch was cut from 3b9c774c5 and main has since moved to 64d937c5. That is behind, not
conflicted, and the merge queue tests the merge result, so it is not work — but I will confirm it
is still behind and not dirty before marking ready.

I will mark ready and arm once CI is terminal green, and confirm the enqueue from the
gh-readonly-queue/main/pr-6915-* ref rather than from any API return value.


Generated by Claude Code

Sign up for freeto 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.

The record-drawer size: 'lg' bucket decision has no live tracker — three source files point at #6303 and #6259, both now closed

2 participants

@os-sam@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' docs(drawer): record the size:'lg' bucket ruling at the three stale pointers by claude[bot] · Pull Request #6915 · objectstack-ai/objectui · GitHub
Skip to content

docs(drawer): record the size:'lg' bucket ruling at the three stale pointers - #6915

Merged
os-sam merged 1 commit into
mainfrom
claude/issue-6584-drawer-bucket-pointer-fix
Aug 30, 2026
Merged

docs(drawer): record the size:'lg' bucket ruling at the three stale pointers#6915
os-sam merged 1 commit into
mainfrom
claude/issue-6584-drawer-bucket-pointer-fix

Conversation

@claude

@claudeclaudeBot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Fixes#6584

Comment text only. Records the 2026-08-27 maintainer ruling at the three in-code
pointers that still named a card in the closed state as the open home of the
size: 'lg' bucket question, plus the single code home of the literal.

This change cannot be red first, and no red-first is claimed for it. It is
comment text: it alters no default, no width expression, no size prop and no
runtime value, so there is no failing state for it to start from. The bar is
therefore (a) type-check / lint / suite staying green, and (b) the textual
re-location being measured rather than assumed. Both are below.

What was verified rather than assumed

Line numbers found vs. the card's table. The card's numbers were measured on
2026-08-26. Each pointer was re-located by its text:

pointer textcard claimsfound on main
ObjectKanban.tsx — "stays open on #6303 for a human ruling."712712 (matches)
ObjectCalendar.tsx — "stays open on #6303 for a human ruling."465482
ObjectGantt.tsx — "to the bucket is open (#6259) … as one decision (#6303)"12831325–1326

Whether the two discrepancies are drift or transcription cannot be settled from
this checkout: its history begins 2026-08-30T07:26Z, so the 2026-08-26 tree is
not reconstructible here. That cell is NOT MEASURED, not "the card was
wrong".

Is there a fourth pointer? No — and that zero carries a positive control.
Three independent sweeps were run, each of which had to hit the three known
pointers in the same query for its zero to count:

  1. every reference to min(960px, 60vw) is a four-site house default, not one renderer's choice — the width/size question on #6259 decides all of them #6303 or ObjectGantt's default navigation config is spelled with the deprecated width rather than the size bucket that replaced it #6259 in tracked files;
  2. openness-claim prose not keyed on any issue number (bucket is open,
    stays open on, human ruling, as one decision, undecided, not ruled);
  3. the measurement prose itself (53% wider, 1600px).

All three hit the three known pointers, and none surfaced a fourth. Sweep 3's
other hits are useNavigationOverlay.ts and recordSurface.test.ts, which carry
the unrelated full bucket's min(92vw, 1600px) — a different literal, not a
pointer.

Other #6303 citations exist and are deliberately left alone. Six more sites
name #6303: ObjectKanban.tsx:696, ObjectCalendar.tsx:466 ("No width is
spelled here on purpose…"), ObjectKanban.tsx:1017, ObjectCalendar.tsx:799
("See the navConfig comment above…"), and the two navWidthDefault test
docblocks. Every one of those cites #6303 as provenance — the card that did
in fact remove the width spelling — which stays accurate no matter what state
that card is in. The defect this card names is narrower: a comment presenting a
card in the closed state as the open home of an undecided question. Only three
sites did that, and only those three were touched.

What the corrected comments now say

Each of the three (a) stops presenting a card in the closed state as the open
home, (b) cites #6584, and (c) states the ruling and its date, so a future reader
does not re-open a decided question. The existing measurement prose
(min(92vw, 960px) vs min(960px, 60vw), the 53% figure, the 1600px crossover)
is kept verbatim — it is still true, and it is the reason the ruling went the way
it did. The gantt comment keeps #6259 / #6303 as the history of where the
question was asked, which is honest, while no longer pointing at either as its
home.

Why RecordDetailDrawer.tsx got the note too

It is inside the ruling's four surfaces and it is the single code home of
min(960px, 60vw) repo-wide — the exact value the ruling preserved, and the line
a future editor would actually change. All three renderer comments point at
this default ("which is what RecordDetailDrawer's own width default is for"),
so before this change the drawer was the hub of the pointer chain and the only
node in it with no record of the decision. Recording the ruling in three
renderers but not at the place it governs would reproduce, in miniature, the
homeless-decision failure this card exists to fix. The note is four sentences in
the existing width docblock; it adds no prop, no default and no behaviour.

Verification

Run against the pushed head bf8c469b4 unless noted.

checkcommandresult
diff is comment-only, proof 1every added/removed line matched against comment syntax37 changed lines, 0 not comment text
diff is comment-only, proof 2each file's non-comment body hashed vs its base blobbyte-identical in all four (real non-empty hashes, both sides)
dependency closure buildpnpm --workspace-concurrency=2 --filter '…^...' build for the four packagesexit 0 (run under the shared verify lock; closure is upstream of the four leaf packages, so it is unaffected by this diff)
type-checkpnpm --filter × 4 run type-checkall four printed type-check: Done; Scope: 4 of 47 workspace projects confirms it was not a zero-match filter. Each package runs tsc --noEmit && tsc -p tsconfig.test.json, so test files are covered too
targeted suitevitest run from the repo root against 11 explicit pathsTest Files 11 passed (11) · Tests 81 passed (81)
lint, A/B vs base blobseslint --format json on the four files, then again with the base blobs checked out in place192 messages vs 192, per-rule histogram IDENTICAL
control bytespnpm check:control-bytescheck-control-bytes: OK (scanned 5760 tracked text file(s))
changeset presencenode scripts/check-changeset-presence.mjsOK — empty frontmatter accepted as "releases nothing"

The lint A/B is the reading the dispatch asked for. Blob ids were verified in
both directions: the base blobs were confirmed on disk after the swap, the
restore was pinned to HEAD (not a bare git checkout --, which would have
restored from the index the swap had already written), and the restore was
proven by git status being empty for all four rather than by an exit code. The
line numbers behave exactly as a comment-only edit predicts: messages above
each insertion point are unshifted, and messages below shift by exactly the
lines added (+5 kanban, +5 calendar, +6 gantt, +9 drawer).

Declared narrowing. Lint covered the 4 edited files, not the repo — the
repo-scale run is CI's. That narrowing is measured, not skipped: eslint reports
4 files linted from its own --format json output; no eslint config file is in
the diff; eslint.config.js enables no type-aware program (no
parserOptions.project / projectService), so a file's verdict is a function of
its own bytes plus the config and this diff cannot move an untouched file; and no
added line is an inline directive (eslint-disable / eslint-env / globals),
checked with a live control. The affected population is therefore exactly the
four files, and all four were linted.

One NOT MEASURED, resolved. A first combined type-check-plus-vitest run was
killed at the container's ~10 minute foreground ceiling (exit 143) after
spending ~570s queued behind a sibling agent's lock hold. That is "I could not
run", neither red nor green. Type-check had already completed green inside it;
vitest was re-run on its own against the same head and reported the 11/81 above.

Deliberately out of scope

The ruling's own recorded fallback — that bucket-vocabulary unification, if it
ever becomes a product direction, needs a fresh ruling with visual-regression
evidence across all four surfaces in one stroke — is a future card. It is quoted
inside the new comments as part of the record, and nothing here acts on it.


Generated by Claude Code

…ointers
The kanban, calendar and gantt renderers each told a reader that the
record-drawer `size: 'lg'` bucket question "stays open" on objectui#6303 /
objectui#6259. Both cards are closed, so the pointer chain terminated on closed
cards and the question was tracked nowhere.
It has since been ruled: 2026-08-27, the record-navigation drawer stays on the
CSS literal with no bucket convergence. The three comments now cite the card
that carries that ruling and state it, instead of naming a closed card as an
open home. `RecordDetailDrawer`'s `width` docblock -- the single code home of
`min(960px, 60vw)`, which all three renderers fall through to -- gains the same
note.
Comment text only. The measurement prose is kept verbatim; no default, `width`
expression, `size` prop or runtime value is touched, proven two ways: every
changed line in the diff is comment text, and each file's non-comment body
hashes identically to its base blob.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 45 chunks)3179.0 KB3222.7 KB
Main entry chunk (gzip)143.6 KB350 KB
Entry fileindex-cjNu4OJu.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)12.46KB4.71KB
app-shell (runtime-config.js)20.61KB7.35KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)512.13KB116.43KB
core (index.js)5.30KB2.13KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)175.69KB48.80KB
fields (index.js)243.65KB61.63KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)33.40KB8.71KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.95KB10.97KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)46.92KB12.93KB
plugin-charts (index.js)64.68KB18.35KB
plugin-chatbot (index.js)190.53KB45.18KB
plugin-dashboard (index.js)133.48KB34.51KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)245.43KB62.46KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)133.32KB32.69KB
plugin-gantt (index.js)165.23KB40.37KB
plugin-grid (index.js)202.08KB54.61KB
plugin-kanban (index.js)53.14KB14.64KB
plugin-list (index.js)113.15KB27.59KB
plugin-map (index.js)20.20KB6.66KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)29.05KB8.37KB
plugin-tree (index.js)9.00KB3.08KB
plugin-view (index.js)85.83KB21.11KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)76.75KB25.49KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)3.11KB1.48KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.72KB2.24KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)3.40KB1.71KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

@os-samClaude

Copy link
Copy Markdown
Collaborator

PM review — ACCEPT on the diff. Landing held until CI is terminal.

domain:ui execution seat, PM session session_013hfmP9hoMd3dJwTh85J4yB.

The comment-only claim, verified independently rather than taken from the report

Read every +/- line of the diff myself. Five files: the changeset (new, empty frontmatter =
"releases nothing"), and four source files in which every changed line sits inside // or *
comment syntax
. The adjacent code lines — const navConfig = … in all three renderers, the
width prop declaration in the drawer — are untouched on both sides of each hunk. ⇒ No default, no
width expression, no size prop, no runtime value moves.

⭐ The dev's second proof is the one that actually carries this: hashing each file's non-comment
body
against its base blob and getting byte-identical in all four, with real non-empty hashes on
both sides. A line-by-line syntax match can be fooled by a // inside a string; a body hash cannot.
That is the right instrument for this claim.

⭐ It refused the red-first claim, correctly and in its own words

This change cannot be red first, and no red-first is claimed for it.

That is the honest answer, and it is what the dispatch required. A comment edit has no failing state
to start from, and dressing one up would have been a lie. The substitute bar it set instead — green
stays green, and the textual re-location is measured — is the right one.

Three things it got right that a weaker pass would have missed

1. It found six more #6303 citations and left every one of them alone. They cite #6303 as
provenance — the card that did in fact remove the width spelling — which stays accurate whatever
state that card is in. The defect this card names is narrower: a comment presenting a closed card as
the open home of an undecided question. Exactly three sites did that. Editing the other six would
have been scope creep dressed as thoroughness.

2. The fourth-pointer zero carries a control on the join. Three independent sweeps (issue-number
citations; openness prose keyed on no issue number; the measurement prose itself), each of which had
to hit the three known pointers in the same query for its zero to count. All three hit; none
surfaced a fourth. And it correctly discriminated sweep 3's other hits — useNavigationOverlay.ts
and recordSurface.test.ts carry min(92vw, 1600px), the unrelated full bucket, a different
literal rather than a pointer.

3. It reported the line-number discrepancy as NOT MEASURED instead of resolving it in its own
favour.
Kanban matched at 712; calendar came back 482 against a claimed 465, gantt 1325–1326
against 1283. Whether that is drift or transcription is not settleable from a checkout whose history
begins 2026-08-30T07:26Z — so it said so, rather than writing "the card was wrong". ⇒ Correct: an
unreconstructible cell is unmeasured, not a verdict.

The RecordDetailDrawer call was the dev's to make, and it made it well

The dispatch left it open and asked for a reason either way. Its reason holds: the drawer is the
single code home of min(960px, 60vw) repo-wide, all three renderer comments point at it, and
recording the ruling in three renderers but not at the line a future editor would actually change
would reproduce the homeless-decision failure this card exists to fix — in miniature. Accepted.

The load-bearing sentence

The question is CLOSED, not open — do not re-open it as a cleanup.

That is what the three comments are for. The old text invited exactly that re-opening, and the
gantt comment now keeps #6259 / #6303 as the history of where the question was asked while no
longer naming either as its home — which is honest about the past without misdirecting the future.
The ruling's fallback is quoted too, so the door reads as gated rather than nailed shut.

Landing path

Not clause ②: comment text changes no contract and widens no published surface. No governed surface
(docs/adr/**, .claude/**, skills/**, AGENTS.md, CLAUDE.md) is in the diff, and nothing
under content/docs/releases/. ⇒ ordinary review + merge queue, and this ACCEPT is mine to act on.

Not arming yet. This ACCEPT is on the diff; CI is the arbiter of the tree. The PR was opened
at 15:38:49Z and its checks have not reached a terminal state. mergeable_state reads behind
the branch was cut from 3b9c774c5 and main has since moved to 64d937c5. That is behind, not
conflicted, and the merge queue tests the merge result, so it is not work — but I will confirm it
is still behind and not dirty before marking ready.

I will mark ready and arm once CI is terminal green, and confirm the enqueue from the
gh-readonly-queue/main/pr-6915-* ref rather than from any API return value.


Generated by Claude Code

Sign up for freeto 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.

The record-drawer size: 'lg' bucket decision has no live tracker — three source files point at #6303 and #6259, both now closed

2 participants

@os-sam@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' docs(drawer): record the size:'lg' bucket ruling at the three stale pointers by claude[bot] · Pull Request #6915 · objectstack-ai/objectui · GitHub
Skip to content

docs(drawer): record the size:'lg' bucket ruling at the three stale pointers - #6915

Merged
os-sam merged 1 commit into
mainfrom
claude/issue-6584-drawer-bucket-pointer-fix
Aug 30, 2026
Merged

docs(drawer): record the size:'lg' bucket ruling at the three stale pointers#6915
os-sam merged 1 commit into
mainfrom
claude/issue-6584-drawer-bucket-pointer-fix

Conversation

@claude

@claudeclaudeBot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Fixes#6584

Comment text only. Records the 2026-08-27 maintainer ruling at the three in-code
pointers that still named a card in the closed state as the open home of the
size: 'lg' bucket question, plus the single code home of the literal.

This change cannot be red first, and no red-first is claimed for it. It is
comment text: it alters no default, no width expression, no size prop and no
runtime value, so there is no failing state for it to start from. The bar is
therefore (a) type-check / lint / suite staying green, and (b) the textual
re-location being measured rather than assumed. Both are below.

What was verified rather than assumed

Line numbers found vs. the card's table. The card's numbers were measured on
2026-08-26. Each pointer was re-located by its text:

pointer textcard claimsfound on main
ObjectKanban.tsx — "stays open on #6303 for a human ruling."712712 (matches)
ObjectCalendar.tsx — "stays open on #6303 for a human ruling."465482
ObjectGantt.tsx — "to the bucket is open (#6259) … as one decision (#6303)"12831325–1326

Whether the two discrepancies are drift or transcription cannot be settled from
this checkout: its history begins 2026-08-30T07:26Z, so the 2026-08-26 tree is
not reconstructible here. That cell is NOT MEASURED, not "the card was
wrong".

Is there a fourth pointer? No — and that zero carries a positive control.
Three independent sweeps were run, each of which had to hit the three known
pointers in the same query for its zero to count:

  1. every reference to min(960px, 60vw) is a four-site house default, not one renderer's choice — the width/size question on #6259 decides all of them #6303 or ObjectGantt's default navigation config is spelled with the deprecated width rather than the size bucket that replaced it #6259 in tracked files;
  2. openness-claim prose not keyed on any issue number (bucket is open,
    stays open on, human ruling, as one decision, undecided, not ruled);
  3. the measurement prose itself (53% wider, 1600px).

All three hit the three known pointers, and none surfaced a fourth. Sweep 3's
other hits are useNavigationOverlay.ts and recordSurface.test.ts, which carry
the unrelated full bucket's min(92vw, 1600px) — a different literal, not a
pointer.

Other #6303 citations exist and are deliberately left alone. Six more sites
name #6303: ObjectKanban.tsx:696, ObjectCalendar.tsx:466 ("No width is
spelled here on purpose…"), ObjectKanban.tsx:1017, ObjectCalendar.tsx:799
("See the navConfig comment above…"), and the two navWidthDefault test
docblocks. Every one of those cites #6303 as provenance — the card that did
in fact remove the width spelling — which stays accurate no matter what state
that card is in. The defect this card names is narrower: a comment presenting a
card in the closed state as the open home of an undecided question. Only three
sites did that, and only those three were touched.

What the corrected comments now say

Each of the three (a) stops presenting a card in the closed state as the open
home, (b) cites #6584, and (c) states the ruling and its date, so a future reader
does not re-open a decided question. The existing measurement prose
(min(92vw, 960px) vs min(960px, 60vw), the 53% figure, the 1600px crossover)
is kept verbatim — it is still true, and it is the reason the ruling went the way
it did. The gantt comment keeps #6259 / #6303 as the history of where the
question was asked, which is honest, while no longer pointing at either as its
home.

Why RecordDetailDrawer.tsx got the note too

It is inside the ruling's four surfaces and it is the single code home of
min(960px, 60vw) repo-wide — the exact value the ruling preserved, and the line
a future editor would actually change. All three renderer comments point at
this default ("which is what RecordDetailDrawer's own width default is for"),
so before this change the drawer was the hub of the pointer chain and the only
node in it with no record of the decision. Recording the ruling in three
renderers but not at the place it governs would reproduce, in miniature, the
homeless-decision failure this card exists to fix. The note is four sentences in
the existing width docblock; it adds no prop, no default and no behaviour.

Verification

Run against the pushed head bf8c469b4 unless noted.

checkcommandresult
diff is comment-only, proof 1every added/removed line matched against comment syntax37 changed lines, 0 not comment text
diff is comment-only, proof 2each file's non-comment body hashed vs its base blobbyte-identical in all four (real non-empty hashes, both sides)
dependency closure buildpnpm --workspace-concurrency=2 --filter '…^...' build for the four packagesexit 0 (run under the shared verify lock; closure is upstream of the four leaf packages, so it is unaffected by this diff)
type-checkpnpm --filter × 4 run type-checkall four printed type-check: Done; Scope: 4 of 47 workspace projects confirms it was not a zero-match filter. Each package runs tsc --noEmit && tsc -p tsconfig.test.json, so test files are covered too
targeted suitevitest run from the repo root against 11 explicit pathsTest Files 11 passed (11) · Tests 81 passed (81)
lint, A/B vs base blobseslint --format json on the four files, then again with the base blobs checked out in place192 messages vs 192, per-rule histogram IDENTICAL
control bytespnpm check:control-bytescheck-control-bytes: OK (scanned 5760 tracked text file(s))
changeset presencenode scripts/check-changeset-presence.mjsOK — empty frontmatter accepted as "releases nothing"

The lint A/B is the reading the dispatch asked for. Blob ids were verified in
both directions: the base blobs were confirmed on disk after the swap, the
restore was pinned to HEAD (not a bare git checkout --, which would have
restored from the index the swap had already written), and the restore was
proven by git status being empty for all four rather than by an exit code. The
line numbers behave exactly as a comment-only edit predicts: messages above
each insertion point are unshifted, and messages below shift by exactly the
lines added (+5 kanban, +5 calendar, +6 gantt, +9 drawer).

Declared narrowing. Lint covered the 4 edited files, not the repo — the
repo-scale run is CI's. That narrowing is measured, not skipped: eslint reports
4 files linted from its own --format json output; no eslint config file is in
the diff; eslint.config.js enables no type-aware program (no
parserOptions.project / projectService), so a file's verdict is a function of
its own bytes plus the config and this diff cannot move an untouched file; and no
added line is an inline directive (eslint-disable / eslint-env / globals),
checked with a live control. The affected population is therefore exactly the
four files, and all four were linted.

One NOT MEASURED, resolved. A first combined type-check-plus-vitest run was
killed at the container's ~10 minute foreground ceiling (exit 143) after
spending ~570s queued behind a sibling agent's lock hold. That is "I could not
run", neither red nor green. Type-check had already completed green inside it;
vitest was re-run on its own against the same head and reported the 11/81 above.

Deliberately out of scope

The ruling's own recorded fallback — that bucket-vocabulary unification, if it
ever becomes a product direction, needs a fresh ruling with visual-regression
evidence across all four surfaces in one stroke — is a future card. It is quoted
inside the new comments as part of the record, and nothing here acts on it.


Generated by Claude Code

…ointers
The kanban, calendar and gantt renderers each told a reader that the
record-drawer `size: 'lg'` bucket question "stays open" on objectui#6303 /
objectui#6259. Both cards are closed, so the pointer chain terminated on closed
cards and the question was tracked nowhere.
It has since been ruled: 2026-08-27, the record-navigation drawer stays on the
CSS literal with no bucket convergence. The three comments now cite the card
that carries that ruling and state it, instead of naming a closed card as an
open home. `RecordDetailDrawer`'s `width` docblock -- the single code home of
`min(960px, 60vw)`, which all three renderers fall through to -- gains the same
note.
Comment text only. The measurement prose is kept verbatim; no default, `width`
expression, `size` prop or runtime value is touched, proven two ways: every
changed line in the diff is comment text, and each file's non-comment body
hashes identically to its base blob.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 45 chunks)3179.0 KB3222.7 KB
Main entry chunk (gzip)143.6 KB350 KB
Entry fileindex-cjNu4OJu.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)12.46KB4.71KB
app-shell (runtime-config.js)20.61KB7.35KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)512.13KB116.43KB
core (index.js)5.30KB2.13KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)175.69KB48.80KB
fields (index.js)243.65KB61.63KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)33.40KB8.71KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.95KB10.97KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)46.92KB12.93KB
plugin-charts (index.js)64.68KB18.35KB
plugin-chatbot (index.js)190.53KB45.18KB
plugin-dashboard (index.js)133.48KB34.51KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)245.43KB62.46KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)133.32KB32.69KB
plugin-gantt (index.js)165.23KB40.37KB
plugin-grid (index.js)202.08KB54.61KB
plugin-kanban (index.js)53.14KB14.64KB
plugin-list (index.js)113.15KB27.59KB
plugin-map (index.js)20.20KB6.66KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)29.05KB8.37KB
plugin-tree (index.js)9.00KB3.08KB
plugin-view (index.js)85.83KB21.11KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)76.75KB25.49KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)3.11KB1.48KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.72KB2.24KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)3.40KB1.71KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

@os-samClaude

Copy link
Copy Markdown
Collaborator

PM review — ACCEPT on the diff. Landing held until CI is terminal.

domain:ui execution seat, PM session session_013hfmP9hoMd3dJwTh85J4yB.

The comment-only claim, verified independently rather than taken from the report

Read every +/- line of the diff myself. Five files: the changeset (new, empty frontmatter =
"releases nothing"), and four source files in which every changed line sits inside // or *
comment syntax
. The adjacent code lines — const navConfig = … in all three renderers, the
width prop declaration in the drawer — are untouched on both sides of each hunk. ⇒ No default, no
width expression, no size prop, no runtime value moves.

⭐ The dev's second proof is the one that actually carries this: hashing each file's non-comment
body
against its base blob and getting byte-identical in all four, with real non-empty hashes on
both sides. A line-by-line syntax match can be fooled by a // inside a string; a body hash cannot.
That is the right instrument for this claim.

⭐ It refused the red-first claim, correctly and in its own words

This change cannot be red first, and no red-first is claimed for it.

That is the honest answer, and it is what the dispatch required. A comment edit has no failing state
to start from, and dressing one up would have been a lie. The substitute bar it set instead — green
stays green, and the textual re-location is measured — is the right one.

Three things it got right that a weaker pass would have missed

1. It found six more #6303 citations and left every one of them alone. They cite #6303 as
provenance — the card that did in fact remove the width spelling — which stays accurate whatever
state that card is in. The defect this card names is narrower: a comment presenting a closed card as
the open home of an undecided question. Exactly three sites did that. Editing the other six would
have been scope creep dressed as thoroughness.

2. The fourth-pointer zero carries a control on the join. Three independent sweeps (issue-number
citations; openness prose keyed on no issue number; the measurement prose itself), each of which had
to hit the three known pointers in the same query for its zero to count. All three hit; none
surfaced a fourth. And it correctly discriminated sweep 3's other hits — useNavigationOverlay.ts
and recordSurface.test.ts carry min(92vw, 1600px), the unrelated full bucket, a different
literal rather than a pointer.

3. It reported the line-number discrepancy as NOT MEASURED instead of resolving it in its own
favour.
Kanban matched at 712; calendar came back 482 against a claimed 465, gantt 1325–1326
against 1283. Whether that is drift or transcription is not settleable from a checkout whose history
begins 2026-08-30T07:26Z — so it said so, rather than writing "the card was wrong". ⇒ Correct: an
unreconstructible cell is unmeasured, not a verdict.

The RecordDetailDrawer call was the dev's to make, and it made it well

The dispatch left it open and asked for a reason either way. Its reason holds: the drawer is the
single code home of min(960px, 60vw) repo-wide, all three renderer comments point at it, and
recording the ruling in three renderers but not at the line a future editor would actually change
would reproduce the homeless-decision failure this card exists to fix — in miniature. Accepted.

The load-bearing sentence

The question is CLOSED, not open — do not re-open it as a cleanup.

That is what the three comments are for. The old text invited exactly that re-opening, and the
gantt comment now keeps #6259 / #6303 as the history of where the question was asked while no
longer naming either as its home — which is honest about the past without misdirecting the future.
The ruling's fallback is quoted too, so the door reads as gated rather than nailed shut.

Landing path

Not clause ②: comment text changes no contract and widens no published surface. No governed surface
(docs/adr/**, .claude/**, skills/**, AGENTS.md, CLAUDE.md) is in the diff, and nothing
under content/docs/releases/. ⇒ ordinary review + merge queue, and this ACCEPT is mine to act on.

Not arming yet. This ACCEPT is on the diff; CI is the arbiter of the tree. The PR was opened
at 15:38:49Z and its checks have not reached a terminal state. mergeable_state reads behind
the branch was cut from 3b9c774c5 and main has since moved to 64d937c5. That is behind, not
conflicted, and the merge queue tests the merge result, so it is not work — but I will confirm it
is still behind and not dirty before marking ready.

I will mark ready and arm once CI is terminal green, and confirm the enqueue from the
gh-readonly-queue/main/pr-6915-* ref rather than from any API return value.


Generated by Claude Code

Sign up for freeto 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.

The record-drawer size: 'lg' bucket decision has no live tracker — three source files point at #6303 and #6259, both now closed

2 participants

@os-sam@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' docs(drawer): record the size:'lg' bucket ruling at the three stale pointers by claude[bot] · Pull Request #6915 · objectstack-ai/objectui · GitHub
Skip to content

docs(drawer): record the size:'lg' bucket ruling at the three stale pointers - #6915

Merged
os-sam merged 1 commit into
mainfrom
claude/issue-6584-drawer-bucket-pointer-fix
Aug 30, 2026
Merged

docs(drawer): record the size:'lg' bucket ruling at the three stale pointers#6915
os-sam merged 1 commit into
mainfrom
claude/issue-6584-drawer-bucket-pointer-fix

Conversation

@claude

@claudeclaudeBot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Fixes#6584

Comment text only. Records the 2026-08-27 maintainer ruling at the three in-code
pointers that still named a card in the closed state as the open home of the
size: 'lg' bucket question, plus the single code home of the literal.

This change cannot be red first, and no red-first is claimed for it. It is
comment text: it alters no default, no width expression, no size prop and no
runtime value, so there is no failing state for it to start from. The bar is
therefore (a) type-check / lint / suite staying green, and (b) the textual
re-location being measured rather than assumed. Both are below.

What was verified rather than assumed

Line numbers found vs. the card's table. The card's numbers were measured on
2026-08-26. Each pointer was re-located by its text:

pointer textcard claimsfound on main
ObjectKanban.tsx — "stays open on #6303 for a human ruling."712712 (matches)
ObjectCalendar.tsx — "stays open on #6303 for a human ruling."465482
ObjectGantt.tsx — "to the bucket is open (#6259) … as one decision (#6303)"12831325–1326

Whether the two discrepancies are drift or transcription cannot be settled from
this checkout: its history begins 2026-08-30T07:26Z, so the 2026-08-26 tree is
not reconstructible here. That cell is NOT MEASURED, not "the card was
wrong".

Is there a fourth pointer? No — and that zero carries a positive control.
Three independent sweeps were run, each of which had to hit the three known
pointers in the same query for its zero to count:

  1. every reference to min(960px, 60vw) is a four-site house default, not one renderer's choice — the width/size question on #6259 decides all of them #6303 or ObjectGantt's default navigation config is spelled with the deprecated width rather than the size bucket that replaced it #6259 in tracked files;
  2. openness-claim prose not keyed on any issue number (bucket is open,
    stays open on, human ruling, as one decision, undecided, not ruled);
  3. the measurement prose itself (53% wider, 1600px).

All three hit the three known pointers, and none surfaced a fourth. Sweep 3's
other hits are useNavigationOverlay.ts and recordSurface.test.ts, which carry
the unrelated full bucket's min(92vw, 1600px) — a different literal, not a
pointer.

Other #6303 citations exist and are deliberately left alone. Six more sites
name #6303: ObjectKanban.tsx:696, ObjectCalendar.tsx:466 ("No width is
spelled here on purpose…"), ObjectKanban.tsx:1017, ObjectCalendar.tsx:799
("See the navConfig comment above…"), and the two navWidthDefault test
docblocks. Every one of those cites #6303 as provenance — the card that did
in fact remove the width spelling — which stays accurate no matter what state
that card is in. The defect this card names is narrower: a comment presenting a
card in the closed state as the open home of an undecided question. Only three
sites did that, and only those three were touched.

What the corrected comments now say

Each of the three (a) stops presenting a card in the closed state as the open
home, (b) cites #6584, and (c) states the ruling and its date, so a future reader
does not re-open a decided question. The existing measurement prose
(min(92vw, 960px) vs min(960px, 60vw), the 53% figure, the 1600px crossover)
is kept verbatim — it is still true, and it is the reason the ruling went the way
it did. The gantt comment keeps #6259 / #6303 as the history of where the
question was asked, which is honest, while no longer pointing at either as its
home.

Why RecordDetailDrawer.tsx got the note too

It is inside the ruling's four surfaces and it is the single code home of
min(960px, 60vw) repo-wide — the exact value the ruling preserved, and the line
a future editor would actually change. All three renderer comments point at
this default ("which is what RecordDetailDrawer's own width default is for"),
so before this change the drawer was the hub of the pointer chain and the only
node in it with no record of the decision. Recording the ruling in three
renderers but not at the place it governs would reproduce, in miniature, the
homeless-decision failure this card exists to fix. The note is four sentences in
the existing width docblock; it adds no prop, no default and no behaviour.

Verification

Run against the pushed head bf8c469b4 unless noted.

checkcommandresult
diff is comment-only, proof 1every added/removed line matched against comment syntax37 changed lines, 0 not comment text
diff is comment-only, proof 2each file's non-comment body hashed vs its base blobbyte-identical in all four (real non-empty hashes, both sides)
dependency closure buildpnpm --workspace-concurrency=2 --filter '…^...' build for the four packagesexit 0 (run under the shared verify lock; closure is upstream of the four leaf packages, so it is unaffected by this diff)
type-checkpnpm --filter × 4 run type-checkall four printed type-check: Done; Scope: 4 of 47 workspace projects confirms it was not a zero-match filter. Each package runs tsc --noEmit && tsc -p tsconfig.test.json, so test files are covered too
targeted suitevitest run from the repo root against 11 explicit pathsTest Files 11 passed (11) · Tests 81 passed (81)
lint, A/B vs base blobseslint --format json on the four files, then again with the base blobs checked out in place192 messages vs 192, per-rule histogram IDENTICAL
control bytespnpm check:control-bytescheck-control-bytes: OK (scanned 5760 tracked text file(s))
changeset presencenode scripts/check-changeset-presence.mjsOK — empty frontmatter accepted as "releases nothing"

The lint A/B is the reading the dispatch asked for. Blob ids were verified in
both directions: the base blobs were confirmed on disk after the swap, the
restore was pinned to HEAD (not a bare git checkout --, which would have
restored from the index the swap had already written), and the restore was
proven by git status being empty for all four rather than by an exit code. The
line numbers behave exactly as a comment-only edit predicts: messages above
each insertion point are unshifted, and messages below shift by exactly the
lines added (+5 kanban, +5 calendar, +6 gantt, +9 drawer).

Declared narrowing. Lint covered the 4 edited files, not the repo — the
repo-scale run is CI's. That narrowing is measured, not skipped: eslint reports
4 files linted from its own --format json output; no eslint config file is in
the diff; eslint.config.js enables no type-aware program (no
parserOptions.project / projectService), so a file's verdict is a function of
its own bytes plus the config and this diff cannot move an untouched file; and no
added line is an inline directive (eslint-disable / eslint-env / globals),
checked with a live control. The affected population is therefore exactly the
four files, and all four were linted.

One NOT MEASURED, resolved. A first combined type-check-plus-vitest run was
killed at the container's ~10 minute foreground ceiling (exit 143) after
spending ~570s queued behind a sibling agent's lock hold. That is "I could not
run", neither red nor green. Type-check had already completed green inside it;
vitest was re-run on its own against the same head and reported the 11/81 above.

Deliberately out of scope

The ruling's own recorded fallback — that bucket-vocabulary unification, if it
ever becomes a product direction, needs a fresh ruling with visual-regression
evidence across all four surfaces in one stroke — is a future card. It is quoted
inside the new comments as part of the record, and nothing here acts on it.


Generated by Claude Code

…ointers
The kanban, calendar and gantt renderers each told a reader that the
record-drawer `size: 'lg'` bucket question "stays open" on objectui#6303 /
objectui#6259. Both cards are closed, so the pointer chain terminated on closed
cards and the question was tracked nowhere.
It has since been ruled: 2026-08-27, the record-navigation drawer stays on the
CSS literal with no bucket convergence. The three comments now cite the card
that carries that ruling and state it, instead of naming a closed card as an
open home. `RecordDetailDrawer`'s `width` docblock -- the single code home of
`min(960px, 60vw)`, which all three renderers fall through to -- gains the same
note.
Comment text only. The measurement prose is kept verbatim; no default, `width`
expression, `size` prop or runtime value is touched, proven two ways: every
changed line in the diff is comment text, and each file's non-comment body
hashes identically to its base blob.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 45 chunks)3179.0 KB3222.7 KB
Main entry chunk (gzip)143.6 KB350 KB
Entry fileindex-cjNu4OJu.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)12.46KB4.71KB
app-shell (runtime-config.js)20.61KB7.35KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)512.13KB116.43KB
core (index.js)5.30KB2.13KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)175.69KB48.80KB
fields (index.js)243.65KB61.63KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)33.40KB8.71KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.95KB10.97KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)46.92KB12.93KB
plugin-charts (index.js)64.68KB18.35KB
plugin-chatbot (index.js)190.53KB45.18KB
plugin-dashboard (index.js)133.48KB34.51KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)245.43KB62.46KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)133.32KB32.69KB
plugin-gantt (index.js)165.23KB40.37KB
plugin-grid (index.js)202.08KB54.61KB
plugin-kanban (index.js)53.14KB14.64KB
plugin-list (index.js)113.15KB27.59KB
plugin-map (index.js)20.20KB6.66KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)29.05KB8.37KB
plugin-tree (index.js)9.00KB3.08KB
plugin-view (index.js)85.83KB21.11KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)76.75KB25.49KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)3.11KB1.48KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.72KB2.24KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)3.40KB1.71KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

@os-samClaude

Copy link
Copy Markdown
Collaborator

PM review — ACCEPT on the diff. Landing held until CI is terminal.

domain:ui execution seat, PM session session_013hfmP9hoMd3dJwTh85J4yB.

The comment-only claim, verified independently rather than taken from the report

Read every +/- line of the diff myself. Five files: the changeset (new, empty frontmatter =
"releases nothing"), and four source files in which every changed line sits inside // or *
comment syntax
. The adjacent code lines — const navConfig = … in all three renderers, the
width prop declaration in the drawer — are untouched on both sides of each hunk. ⇒ No default, no
width expression, no size prop, no runtime value moves.

⭐ The dev's second proof is the one that actually carries this: hashing each file's non-comment
body
against its base blob and getting byte-identical in all four, with real non-empty hashes on
both sides. A line-by-line syntax match can be fooled by a // inside a string; a body hash cannot.
That is the right instrument for this claim.

⭐ It refused the red-first claim, correctly and in its own words

This change cannot be red first, and no red-first is claimed for it.

That is the honest answer, and it is what the dispatch required. A comment edit has no failing state
to start from, and dressing one up would have been a lie. The substitute bar it set instead — green
stays green, and the textual re-location is measured — is the right one.

Three things it got right that a weaker pass would have missed

1. It found six more #6303 citations and left every one of them alone. They cite #6303 as
provenance — the card that did in fact remove the width spelling — which stays accurate whatever
state that card is in. The defect this card names is narrower: a comment presenting a closed card as
the open home of an undecided question. Exactly three sites did that. Editing the other six would
have been scope creep dressed as thoroughness.

2. The fourth-pointer zero carries a control on the join. Three independent sweeps (issue-number
citations; openness prose keyed on no issue number; the measurement prose itself), each of which had
to hit the three known pointers in the same query for its zero to count. All three hit; none
surfaced a fourth. And it correctly discriminated sweep 3's other hits — useNavigationOverlay.ts
and recordSurface.test.ts carry min(92vw, 1600px), the unrelated full bucket, a different
literal rather than a pointer.

3. It reported the line-number discrepancy as NOT MEASURED instead of resolving it in its own
favour.
Kanban matched at 712; calendar came back 482 against a claimed 465, gantt 1325–1326
against 1283. Whether that is drift or transcription is not settleable from a checkout whose history
begins 2026-08-30T07:26Z — so it said so, rather than writing "the card was wrong". ⇒ Correct: an
unreconstructible cell is unmeasured, not a verdict.

The RecordDetailDrawer call was the dev's to make, and it made it well

The dispatch left it open and asked for a reason either way. Its reason holds: the drawer is the
single code home of min(960px, 60vw) repo-wide, all three renderer comments point at it, and
recording the ruling in three renderers but not at the line a future editor would actually change
would reproduce the homeless-decision failure this card exists to fix — in miniature. Accepted.

The load-bearing sentence

The question is CLOSED, not open — do not re-open it as a cleanup.

That is what the three comments are for. The old text invited exactly that re-opening, and the
gantt comment now keeps #6259 / #6303 as the history of where the question was asked while no
longer naming either as its home — which is honest about the past without misdirecting the future.
The ruling's fallback is quoted too, so the door reads as gated rather than nailed shut.

Landing path

Not clause ②: comment text changes no contract and widens no published surface. No governed surface
(docs/adr/**, .claude/**, skills/**, AGENTS.md, CLAUDE.md) is in the diff, and nothing
under content/docs/releases/. ⇒ ordinary review + merge queue, and this ACCEPT is mine to act on.

Not arming yet. This ACCEPT is on the diff; CI is the arbiter of the tree. The PR was opened
at 15:38:49Z and its checks have not reached a terminal state. mergeable_state reads behind
the branch was cut from 3b9c774c5 and main has since moved to 64d937c5. That is behind, not
conflicted, and the merge queue tests the merge result, so it is not work — but I will confirm it
is still behind and not dirty before marking ready.

I will mark ready and arm once CI is terminal green, and confirm the enqueue from the
gh-readonly-queue/main/pr-6915-* ref rather than from any API return value.


Generated by Claude Code

Sign up for freeto 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.

The record-drawer size: 'lg' bucket decision has no live tracker — three source files point at #6303 and #6259, both now closed

2 participants

@os-sam@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' docs(drawer): record the size:'lg' bucket ruling at the three stale pointers by claude[bot] · Pull Request #6915 · objectstack-ai/objectui · GitHub
Skip to content

docs(drawer): record the size:'lg' bucket ruling at the three stale pointers - #6915

Merged
os-sam merged 1 commit into
mainfrom
claude/issue-6584-drawer-bucket-pointer-fix
Aug 30, 2026
Merged

docs(drawer): record the size:'lg' bucket ruling at the three stale pointers#6915
os-sam merged 1 commit into
mainfrom
claude/issue-6584-drawer-bucket-pointer-fix

Conversation

@claude

@claudeclaudeBot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Fixes#6584

Comment text only. Records the 2026-08-27 maintainer ruling at the three in-code
pointers that still named a card in the closed state as the open home of the
size: 'lg' bucket question, plus the single code home of the literal.

This change cannot be red first, and no red-first is claimed for it. It is
comment text: it alters no default, no width expression, no size prop and no
runtime value, so there is no failing state for it to start from. The bar is
therefore (a) type-check / lint / suite staying green, and (b) the textual
re-location being measured rather than assumed. Both are below.

What was verified rather than assumed

Line numbers found vs. the card's table. The card's numbers were measured on
2026-08-26. Each pointer was re-located by its text:

pointer textcard claimsfound on main
ObjectKanban.tsx — "stays open on #6303 for a human ruling."712712 (matches)
ObjectCalendar.tsx — "stays open on #6303 for a human ruling."465482
ObjectGantt.tsx — "to the bucket is open (#6259) … as one decision (#6303)"12831325–1326

Whether the two discrepancies are drift or transcription cannot be settled from
this checkout: its history begins 2026-08-30T07:26Z, so the 2026-08-26 tree is
not reconstructible here. That cell is NOT MEASURED, not "the card was
wrong".

Is there a fourth pointer? No — and that zero carries a positive control.
Three independent sweeps were run, each of which had to hit the three known
pointers in the same query for its zero to count:

  1. every reference to min(960px, 60vw) is a four-site house default, not one renderer's choice — the width/size question on #6259 decides all of them #6303 or ObjectGantt's default navigation config is spelled with the deprecated width rather than the size bucket that replaced it #6259 in tracked files;
  2. openness-claim prose not keyed on any issue number (bucket is open,
    stays open on, human ruling, as one decision, undecided, not ruled);
  3. the measurement prose itself (53% wider, 1600px).

All three hit the three known pointers, and none surfaced a fourth. Sweep 3's
other hits are useNavigationOverlay.ts and recordSurface.test.ts, which carry
the unrelated full bucket's min(92vw, 1600px) — a different literal, not a
pointer.

Other #6303 citations exist and are deliberately left alone. Six more sites
name #6303: ObjectKanban.tsx:696, ObjectCalendar.tsx:466 ("No width is
spelled here on purpose…"), ObjectKanban.tsx:1017, ObjectCalendar.tsx:799
("See the navConfig comment above…"), and the two navWidthDefault test
docblocks. Every one of those cites #6303 as provenance — the card that did
in fact remove the width spelling — which stays accurate no matter what state
that card is in. The defect this card names is narrower: a comment presenting a
card in the closed state as the open home of an undecided question. Only three
sites did that, and only those three were touched.

What the corrected comments now say

Each of the three (a) stops presenting a card in the closed state as the open
home, (b) cites #6584, and (c) states the ruling and its date, so a future reader
does not re-open a decided question. The existing measurement prose
(min(92vw, 960px) vs min(960px, 60vw), the 53% figure, the 1600px crossover)
is kept verbatim — it is still true, and it is the reason the ruling went the way
it did. The gantt comment keeps #6259 / #6303 as the history of where the
question was asked, which is honest, while no longer pointing at either as its
home.

Why RecordDetailDrawer.tsx got the note too

It is inside the ruling's four surfaces and it is the single code home of
min(960px, 60vw) repo-wide — the exact value the ruling preserved, and the line
a future editor would actually change. All three renderer comments point at
this default ("which is what RecordDetailDrawer's own width default is for"),
so before this change the drawer was the hub of the pointer chain and the only
node in it with no record of the decision. Recording the ruling in three
renderers but not at the place it governs would reproduce, in miniature, the
homeless-decision failure this card exists to fix. The note is four sentences in
the existing width docblock; it adds no prop, no default and no behaviour.

Verification

Run against the pushed head bf8c469b4 unless noted.

checkcommandresult
diff is comment-only, proof 1every added/removed line matched against comment syntax37 changed lines, 0 not comment text
diff is comment-only, proof 2each file's non-comment body hashed vs its base blobbyte-identical in all four (real non-empty hashes, both sides)
dependency closure buildpnpm --workspace-concurrency=2 --filter '…^...' build for the four packagesexit 0 (run under the shared verify lock; closure is upstream of the four leaf packages, so it is unaffected by this diff)
type-checkpnpm --filter × 4 run type-checkall four printed type-check: Done; Scope: 4 of 47 workspace projects confirms it was not a zero-match filter. Each package runs tsc --noEmit && tsc -p tsconfig.test.json, so test files are covered too
targeted suitevitest run from the repo root against 11 explicit pathsTest Files 11 passed (11) · Tests 81 passed (81)
lint, A/B vs base blobseslint --format json on the four files, then again with the base blobs checked out in place192 messages vs 192, per-rule histogram IDENTICAL
control bytespnpm check:control-bytescheck-control-bytes: OK (scanned 5760 tracked text file(s))
changeset presencenode scripts/check-changeset-presence.mjsOK — empty frontmatter accepted as "releases nothing"

The lint A/B is the reading the dispatch asked for. Blob ids were verified in
both directions: the base blobs were confirmed on disk after the swap, the
restore was pinned to HEAD (not a bare git checkout --, which would have
restored from the index the swap had already written), and the restore was
proven by git status being empty for all four rather than by an exit code. The
line numbers behave exactly as a comment-only edit predicts: messages above
each insertion point are unshifted, and messages below shift by exactly the
lines added (+5 kanban, +5 calendar, +6 gantt, +9 drawer).

Declared narrowing. Lint covered the 4 edited files, not the repo — the
repo-scale run is CI's. That narrowing is measured, not skipped: eslint reports
4 files linted from its own --format json output; no eslint config file is in
the diff; eslint.config.js enables no type-aware program (no
parserOptions.project / projectService), so a file's verdict is a function of
its own bytes plus the config and this diff cannot move an untouched file; and no
added line is an inline directive (eslint-disable / eslint-env / globals),
checked with a live control. The affected population is therefore exactly the
four files, and all four were linted.

One NOT MEASURED, resolved. A first combined type-check-plus-vitest run was
killed at the container's ~10 minute foreground ceiling (exit 143) after
spending ~570s queued behind a sibling agent's lock hold. That is "I could not
run", neither red nor green. Type-check had already completed green inside it;
vitest was re-run on its own against the same head and reported the 11/81 above.

Deliberately out of scope

The ruling's own recorded fallback — that bucket-vocabulary unification, if it
ever becomes a product direction, needs a fresh ruling with visual-regression
evidence across all four surfaces in one stroke — is a future card. It is quoted
inside the new comments as part of the record, and nothing here acts on it.


Generated by Claude Code

…ointers
The kanban, calendar and gantt renderers each told a reader that the
record-drawer `size: 'lg'` bucket question "stays open" on objectui#6303 /
objectui#6259. Both cards are closed, so the pointer chain terminated on closed
cards and the question was tracked nowhere.
It has since been ruled: 2026-08-27, the record-navigation drawer stays on the
CSS literal with no bucket convergence. The three comments now cite the card
that carries that ruling and state it, instead of naming a closed card as an
open home. `RecordDetailDrawer`'s `width` docblock -- the single code home of
`min(960px, 60vw)`, which all three renderers fall through to -- gains the same
note.
Comment text only. The measurement prose is kept verbatim; no default, `width`
expression, `size` prop or runtime value is touched, proven two ways: every
changed line in the diff is comment text, and each file's non-comment body
hashes identically to its base blob.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 45 chunks)3179.0 KB3222.7 KB
Main entry chunk (gzip)143.6 KB350 KB
Entry fileindex-cjNu4OJu.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)12.46KB4.71KB
app-shell (runtime-config.js)20.61KB7.35KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)512.13KB116.43KB
core (index.js)5.30KB2.13KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)175.69KB48.80KB
fields (index.js)243.65KB61.63KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)33.40KB8.71KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.95KB10.97KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)46.92KB12.93KB
plugin-charts (index.js)64.68KB18.35KB
plugin-chatbot (index.js)190.53KB45.18KB
plugin-dashboard (index.js)133.48KB34.51KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)245.43KB62.46KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)133.32KB32.69KB
plugin-gantt (index.js)165.23KB40.37KB
plugin-grid (index.js)202.08KB54.61KB
plugin-kanban (index.js)53.14KB14.64KB
plugin-list (index.js)113.15KB27.59KB
plugin-map (index.js)20.20KB6.66KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)29.05KB8.37KB
plugin-tree (index.js)9.00KB3.08KB
plugin-view (index.js)85.83KB21.11KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)76.75KB25.49KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)3.11KB1.48KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.72KB2.24KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)3.40KB1.71KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

@os-samClaude

Copy link
Copy Markdown
Collaborator

PM review — ACCEPT on the diff. Landing held until CI is terminal.

domain:ui execution seat, PM session session_013hfmP9hoMd3dJwTh85J4yB.

The comment-only claim, verified independently rather than taken from the report

Read every +/- line of the diff myself. Five files: the changeset (new, empty frontmatter =
"releases nothing"), and four source files in which every changed line sits inside // or *
comment syntax
. The adjacent code lines — const navConfig = … in all three renderers, the
width prop declaration in the drawer — are untouched on both sides of each hunk. ⇒ No default, no
width expression, no size prop, no runtime value moves.

⭐ The dev's second proof is the one that actually carries this: hashing each file's non-comment
body
against its base blob and getting byte-identical in all four, with real non-empty hashes on
both sides. A line-by-line syntax match can be fooled by a // inside a string; a body hash cannot.
That is the right instrument for this claim.

⭐ It refused the red-first claim, correctly and in its own words

This change cannot be red first, and no red-first is claimed for it.

That is the honest answer, and it is what the dispatch required. A comment edit has no failing state
to start from, and dressing one up would have been a lie. The substitute bar it set instead — green
stays green, and the textual re-location is measured — is the right one.

Three things it got right that a weaker pass would have missed

1. It found six more #6303 citations and left every one of them alone. They cite #6303 as
provenance — the card that did in fact remove the width spelling — which stays accurate whatever
state that card is in. The defect this card names is narrower: a comment presenting a closed card as
the open home of an undecided question. Exactly three sites did that. Editing the other six would
have been scope creep dressed as thoroughness.

2. The fourth-pointer zero carries a control on the join. Three independent sweeps (issue-number
citations; openness prose keyed on no issue number; the measurement prose itself), each of which had
to hit the three known pointers in the same query for its zero to count. All three hit; none
surfaced a fourth. And it correctly discriminated sweep 3's other hits — useNavigationOverlay.ts
and recordSurface.test.ts carry min(92vw, 1600px), the unrelated full bucket, a different
literal rather than a pointer.

3. It reported the line-number discrepancy as NOT MEASURED instead of resolving it in its own
favour.
Kanban matched at 712; calendar came back 482 against a claimed 465, gantt 1325–1326
against 1283. Whether that is drift or transcription is not settleable from a checkout whose history
begins 2026-08-30T07:26Z — so it said so, rather than writing "the card was wrong". ⇒ Correct: an
unreconstructible cell is unmeasured, not a verdict.

The RecordDetailDrawer call was the dev's to make, and it made it well

The dispatch left it open and asked for a reason either way. Its reason holds: the drawer is the
single code home of min(960px, 60vw) repo-wide, all three renderer comments point at it, and
recording the ruling in three renderers but not at the line a future editor would actually change
would reproduce the homeless-decision failure this card exists to fix — in miniature. Accepted.

The load-bearing sentence

The question is CLOSED, not open — do not re-open it as a cleanup.

That is what the three comments are for. The old text invited exactly that re-opening, and the
gantt comment now keeps #6259 / #6303 as the history of where the question was asked while no
longer naming either as its home — which is honest about the past without misdirecting the future.
The ruling's fallback is quoted too, so the door reads as gated rather than nailed shut.

Landing path

Not clause ②: comment text changes no contract and widens no published surface. No governed surface
(docs/adr/**, .claude/**, skills/**, AGENTS.md, CLAUDE.md) is in the diff, and nothing
under content/docs/releases/. ⇒ ordinary review + merge queue, and this ACCEPT is mine to act on.

Not arming yet. This ACCEPT is on the diff; CI is the arbiter of the tree. The PR was opened
at 15:38:49Z and its checks have not reached a terminal state. mergeable_state reads behind
the branch was cut from 3b9c774c5 and main has since moved to 64d937c5. That is behind, not
conflicted, and the merge queue tests the merge result, so it is not work — but I will confirm it
is still behind and not dirty before marking ready.

I will mark ready and arm once CI is terminal green, and confirm the enqueue from the
gh-readonly-queue/main/pr-6915-* ref rather than from any API return value.


Generated by Claude Code

Sign up for freeto 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.

The record-drawer size: 'lg' bucket decision has no live tracker — three source files point at #6303 and #6259, both now closed

2 participants

@os-sam@claude
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); docs(drawer): record the size:'lg' bucket ruling at the three stale pointers by claude[bot] · Pull Request #6915 · objectstack-ai/objectui · GitHub
Skip to content

docs(drawer): record the size:'lg' bucket ruling at the three stale pointers - #6915

Merged
os-sam merged 1 commit into
mainfrom
claude/issue-6584-drawer-bucket-pointer-fix
Aug 30, 2026
Merged

docs(drawer): record the size:'lg' bucket ruling at the three stale pointers#6915
os-sam merged 1 commit into
mainfrom
claude/issue-6584-drawer-bucket-pointer-fix

Conversation

@claude

@claudeclaudeBot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Fixes#6584

Comment text only. Records the 2026-08-27 maintainer ruling at the three in-code
pointers that still named a card in the closed state as the open home of the
size: 'lg' bucket question, plus the single code home of the literal.

This change cannot be red first, and no red-first is claimed for it. It is
comment text: it alters no default, no width expression, no size prop and no
runtime value, so there is no failing state for it to start from. The bar is
therefore (a) type-check / lint / suite staying green, and (b) the textual
re-location being measured rather than assumed. Both are below.

What was verified rather than assumed

Line numbers found vs. the card's table. The card's numbers were measured on
2026-08-26. Each pointer was re-located by its text:

pointer textcard claimsfound on main
ObjectKanban.tsx — "stays open on #6303 for a human ruling."712712 (matches)
ObjectCalendar.tsx — "stays open on #6303 for a human ruling."465482
ObjectGantt.tsx — "to the bucket is open (#6259) … as one decision (#6303)"12831325–1326

Whether the two discrepancies are drift or transcription cannot be settled from
this checkout: its history begins 2026-08-30T07:26Z, so the 2026-08-26 tree is
not reconstructible here. That cell is NOT MEASURED, not "the card was
wrong".

Is there a fourth pointer? No — and that zero carries a positive control.
Three independent sweeps were run, each of which had to hit the three known
pointers in the same query for its zero to count:

  1. every reference to min(960px, 60vw) is a four-site house default, not one renderer's choice — the width/size question on #6259 decides all of them #6303 or ObjectGantt's default navigation config is spelled with the deprecated width rather than the size bucket that replaced it #6259 in tracked files;
  2. openness-claim prose not keyed on any issue number (bucket is open,
    stays open on, human ruling, as one decision, undecided, not ruled);
  3. the measurement prose itself (53% wider, 1600px).

All three hit the three known pointers, and none surfaced a fourth. Sweep 3's
other hits are useNavigationOverlay.ts and recordSurface.test.ts, which carry
the unrelated full bucket's min(92vw, 1600px) — a different literal, not a
pointer.

Other #6303 citations exist and are deliberately left alone. Six more sites
name #6303: ObjectKanban.tsx:696, ObjectCalendar.tsx:466 ("No width is
spelled here on purpose…"), ObjectKanban.tsx:1017, ObjectCalendar.tsx:799
("See the navConfig comment above…"), and the two navWidthDefault test
docblocks. Every one of those cites #6303 as provenance — the card that did
in fact remove the width spelling — which stays accurate no matter what state
that card is in. The defect this card names is narrower: a comment presenting a
card in the closed state as the open home of an undecided question. Only three
sites did that, and only those three were touched.

What the corrected comments now say

Each of the three (a) stops presenting a card in the closed state as the open
home, (b) cites #6584, and (c) states the ruling and its date, so a future reader
does not re-open a decided question. The existing measurement prose
(min(92vw, 960px) vs min(960px, 60vw), the 53% figure, the 1600px crossover)
is kept verbatim — it is still true, and it is the reason the ruling went the way
it did. The gantt comment keeps #6259 / #6303 as the history of where the
question was asked, which is honest, while no longer pointing at either as its
home.

Why RecordDetailDrawer.tsx got the note too

It is inside the ruling's four surfaces and it is the single code home of
min(960px, 60vw) repo-wide — the exact value the ruling preserved, and the line
a future editor would actually change. All three renderer comments point at
this default ("which is what RecordDetailDrawer's own width default is for"),
so before this change the drawer was the hub of the pointer chain and the only
node in it with no record of the decision. Recording the ruling in three
renderers but not at the place it governs would reproduce, in miniature, the
homeless-decision failure this card exists to fix. The note is four sentences in
the existing width docblock; it adds no prop, no default and no behaviour.

Verification

Run against the pushed head bf8c469b4 unless noted.

checkcommandresult
diff is comment-only, proof 1every added/removed line matched against comment syntax37 changed lines, 0 not comment text
diff is comment-only, proof 2each file's non-comment body hashed vs its base blobbyte-identical in all four (real non-empty hashes, both sides)
dependency closure buildpnpm --workspace-concurrency=2 --filter '…^...' build for the four packagesexit 0 (run under the shared verify lock; closure is upstream of the four leaf packages, so it is unaffected by this diff)
type-checkpnpm --filter × 4 run type-checkall four printed type-check: Done; Scope: 4 of 47 workspace projects confirms it was not a zero-match filter. Each package runs tsc --noEmit && tsc -p tsconfig.test.json, so test files are covered too
targeted suitevitest run from the repo root against 11 explicit pathsTest Files 11 passed (11) · Tests 81 passed (81)
lint, A/B vs base blobseslint --format json on the four files, then again with the base blobs checked out in place192 messages vs 192, per-rule histogram IDENTICAL
control bytespnpm check:control-bytescheck-control-bytes: OK (scanned 5760 tracked text file(s))
changeset presencenode scripts/check-changeset-presence.mjsOK — empty frontmatter accepted as "releases nothing"

The lint A/B is the reading the dispatch asked for. Blob ids were verified in
both directions: the base blobs were confirmed on disk after the swap, the
restore was pinned to HEAD (not a bare git checkout --, which would have
restored from the index the swap had already written), and the restore was
proven by git status being empty for all four rather than by an exit code. The
line numbers behave exactly as a comment-only edit predicts: messages above
each insertion point are unshifted, and messages below shift by exactly the
lines added (+5 kanban, +5 calendar, +6 gantt, +9 drawer).

Declared narrowing. Lint covered the 4 edited files, not the repo — the
repo-scale run is CI's. That narrowing is measured, not skipped: eslint reports
4 files linted from its own --format json output; no eslint config file is in
the diff; eslint.config.js enables no type-aware program (no
parserOptions.project / projectService), so a file's verdict is a function of
its own bytes plus the config and this diff cannot move an untouched file; and no
added line is an inline directive (eslint-disable / eslint-env / globals),
checked with a live control. The affected population is therefore exactly the
four files, and all four were linted.

One NOT MEASURED, resolved. A first combined type-check-plus-vitest run was
killed at the container's ~10 minute foreground ceiling (exit 143) after
spending ~570s queued behind a sibling agent's lock hold. That is "I could not
run", neither red nor green. Type-check had already completed green inside it;
vitest was re-run on its own against the same head and reported the 11/81 above.

Deliberately out of scope

The ruling's own recorded fallback — that bucket-vocabulary unification, if it
ever becomes a product direction, needs a fresh ruling with visual-regression
evidence across all four surfaces in one stroke — is a future card. It is quoted
inside the new comments as part of the record, and nothing here acts on it.


Generated by Claude Code

…ointers
The kanban, calendar and gantt renderers each told a reader that the
record-drawer `size: 'lg'` bucket question "stays open" on objectui#6303 /
objectui#6259. Both cards are closed, so the pointer chain terminated on closed
cards and the question was tracked nowhere.
It has since been ruled: 2026-08-27, the record-navigation drawer stays on the
CSS literal with no bucket convergence. The three comments now cite the card
that carries that ruling and state it, instead of naming a closed card as an
open home. `RecordDetailDrawer`'s `width` docblock -- the single code home of
`min(960px, 60vw)`, which all three renderers fall through to -- gains the same
note.
Comment text only. The measurement prose is kept verbatim; no default, `width`
expression, `size` prop or runtime value is touched, proven two ways: every
changed line in the diff is comment text, and each file's non-comment body
hashes identically to its base blob.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013hfmP9hoMd3dJwTh85J4yB
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

MetricValueBudget
Eager closure (gzip, 45 chunks)3179.0 KB3222.7 KB
Main entry chunk (gzip)143.6 KB350 KB
Entry fileindex-cjNu4OJu.js
StatusPASS

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

PackageSizeGzipped
app-shell (consoleActionDispatch.js)0.20KB0.19KB
app-shell (index.js)12.46KB4.71KB
app-shell (runtime-config.js)20.61KB7.35KB
app-shell (types.js)0.01KB0.04KB
app-shell (urlParams.js)10.06KB3.86KB
auth (ActiveOrganizationStorage.js)25.05KB9.16KB
auth (AuthContext.js)0.31KB0.24KB
auth (AuthGuard.js)2.07KB1.00KB
auth (AuthProvider.js)40.18KB10.59KB
auth (AuthShell.js)3.49KB1.40KB
auth (ForgotPasswordForm.js)12.21KB3.45KB
auth (LoginForm.js)18.15KB5.39KB
auth (PreviewBanner.js)0.90KB0.50KB
auth (RegisterForm.js)6.65KB2.22KB
auth (SocialSignInButtons.js)9.61KB3.89KB
auth (UserMenu.js)3.41KB1.23KB
auth (auth-gate-events.js)1.29KB0.66KB
auth (authStyles.js)5.04KB1.72KB
auth (createAuthClient.js)40.21KB10.80KB
auth (createAuthenticatedFetch.js)8.46KB3.43KB
auth (index.js)3.19KB1.44KB
auth (invitation-status.js)1.22KB0.70KB
auth (org-roles.js)6.66KB2.78KB
auth (phone-identifier.js)1.11KB0.66KB
auth (types.js)0.59KB0.35KB
auth (useAuth.js)5.30KB1.02KB
auth (useWorkspaceAdminStatus.js)5.13KB2.35KB
collaboration (CommentThread.js)26.08KB7.56KB
collaboration (LiveCursors.js)3.17KB1.27KB
collaboration (PresenceAvatars.js)6.49KB2.64KB
collaboration (PresenceProvider.js)2.79KB1.13KB
collaboration (index.js)1.68KB0.73KB
collaboration (useCollaborationTranslation.js)6.05KB2.52KB
collaboration (useCommentSearch.js)1.98KB0.88KB
collaboration (useConflictResolution.js)7.75KB1.86KB
collaboration (useMentionNotifications.js)1.81KB0.68KB
collaboration (usePresence.js)6.33KB1.84KB
collaboration (useRealtimeSubscription.js)7.91KB2.01KB
components (index.js)512.13KB116.43KB
core (index.js)5.30KB2.13KB
create-plugin (index.js)10.08KB3.26KB
data-objectstack (index.js)175.69KB48.80KB
fields (index.js)243.65KB61.63KB
i18n (LocalizationContext.js)1.76KB0.96KB
i18n (currency.js)1.22KB0.64KB
i18n (fallbackInterpolation.js)6.25KB2.77KB
i18n (i18n.js)4.28KB1.75KB
i18n (index.js)3.44KB1.39KB
i18n (pickLocalized.js)7.62KB3.26KB
i18n (provider.js)26.89KB9.04KB
i18n (useDisplayLocale.js)2.85KB1.45KB
i18n (useObjectLabel.js)33.40KB8.71KB
i18n (useSafeTranslation.js)5.60KB2.33KB
layout (index.js)38.95KB10.97KB
mobile (MobileProvider.js)0.92KB0.49KB
mobile (ResponsiveContainer.js)0.94KB0.38KB
mobile (breakpoints.js)1.51KB0.70KB
mobile (createOfflineDataSource.js)5.61KB1.75KB
mobile (index.js)1.55KB0.62KB
mobile (offlineQueue.js)3.91KB1.35KB
mobile (pwa.js)0.97KB0.49KB
mobile (serviceWorker.js)1.48KB0.62KB
mobile (serviceWorkerSource.js)3.41KB1.48KB
mobile (useBreakpoint.js)1.54KB0.65KB
mobile (useGesture.js)6.96KB1.98KB
mobile (useOfflineSync.js)1.99KB0.72KB
mobile (usePullToRefresh.js)2.53KB0.85KB
mobile (useResponsive.js)0.72KB0.42KB
mobile (useResponsiveConfig.js)1.37KB0.63KB
mobile (useSpecGesture.js)4.32KB1.64KB
mobile (useTouchTarget.js)1.01KB0.54KB
permissions (MePermissionsProvider.js)11.71KB4.29KB
permissions (PermissionContext.js)0.31KB0.25KB
permissions (PermissionGuard.js)0.89KB0.45KB
permissions (PermissionProvider.js)6.24KB2.16KB
permissions (discardProofCache.js)1.04KB0.55KB
permissions (evaluator.js)5.12KB1.74KB
permissions (index.js)0.93KB0.41KB
permissions (store.js)0.91KB0.42KB
permissions (useFieldPermissions.js)1.28KB0.53KB
permissions (usePermissions.js)4.83KB2.27KB
plugin-ai (index.js)15.75KB3.80KB
plugin-calendar (index.js)46.92KB12.93KB
plugin-charts (index.js)64.68KB18.35KB
plugin-chatbot (index.js)190.53KB45.18KB
plugin-dashboard (index.js)133.48KB34.51KB
plugin-designer (index.js)212.87KB43.19KB
plugin-detail (index.js)245.43KB62.46KB
plugin-editor (index.js)2.46KB1.10KB
plugin-form (index.js)133.32KB32.69KB
plugin-gantt (index.js)165.23KB40.37KB
plugin-grid (index.js)202.08KB54.61KB
plugin-kanban (index.js)53.14KB14.64KB
plugin-list (index.js)113.15KB27.59KB
plugin-map (index.js)20.20KB6.66KB
plugin-markdown (index.js)13.72KB4.69KB
plugin-report (index.js)43.51KB11.94KB
plugin-timeline (index.js)29.05KB8.37KB
plugin-tree (index.js)9.00KB3.08KB
plugin-view (index.js)85.83KB21.11KB
providers (DataSourceProvider.js)0.75KB0.39KB
providers (MetadataProvider.js)1.37KB0.59KB
providers (ThemeProvider.js)1.90KB0.85KB
providers (UploadProvider.js)11.66KB3.50KB
providers (index.js)0.45KB0.23KB
providers (types.js)0.01KB0.04KB
react-runtime (index.js)5.62KB2.34KB
react (LazyPluginLoader.js)4.47KB1.63KB
react (SchemaRenderer.js)76.75KB25.49KB
react (data-invalidation.js)5.05KB2.08KB
react (index.js)3.11KB1.48KB
react (schema-input.js)2.32KB1.24KB
react (spec-input.js)0.20KB0.18KB
sdui-parser (codegen.js)5.41KB2.34KB
sdui-parser (dashboard-widget-options.js)3.08KB1.30KB
sdui-parser (index.js)4.93KB2.24KB
sdui-parser (input-type.js)2.84KB1.40KB
sdui-parser (parse.js)20.57KB5.88KB
sdui-parser (provenance.js)3.66KB1.82KB
sdui-parser (types.js)0.28KB0.23KB
sdui-parser (validate.js)10.35KB3.60KB
types (ai.js)0.20KB0.17KB
types (api-types.js)0.20KB0.18KB
types (app.js)2.87KB0.99KB
types (base.js)0.20KB0.18KB
types (blocks.js)0.20KB0.18KB
types (complex.js)2.74KB1.41KB
types (crud.js)0.20KB0.18KB
types (dashboard-filter-alias.js)6.23KB2.74KB
types (data-display.js)3.75KB1.85KB
types (data-protocol.js)0.20KB0.19KB
types (data.js)0.20KB0.18KB
types (designer.js)1.85KB0.85KB
types (disclosure.js)0.20KB0.18KB
types (error-code.js)1.54KB0.88KB
types (feedback.js)0.20KB0.18KB
types (field-types.js)0.20KB0.18KB
types (form.js)0.20KB0.18KB
types (http-inflight.js)8.87KB3.73KB
types (http-retry.js)4.32KB2.02KB
types (icon-key-migration.js)4.26KB1.63KB
types (index.js)4.72KB2.24KB
types (layout.js)0.20KB0.18KB
types (managed-by.js)0.19KB0.18KB
types (mobile.js)2.59KB1.31KB
types (navigation.js)0.20KB0.18KB
types (objectql.js)0.20KB0.18KB
types (overlay.js)0.20KB0.18KB
types (permissions.js)0.20KB0.18KB
types (plugin-scope.js)0.20KB0.18KB
types (record-components.js)0.20KB0.19KB
types (record-semantics.js)1.28KB0.67KB
types (registry.js)0.20KB0.18KB
types (reports.js)0.20KB0.18KB
types (spec-report.js)5.05KB1.93KB
types (spec-ui-namespace.js)0.20KB0.19KB
types (system-fields.js)3.33KB1.54KB
types (theme.js)6.28KB2.87KB
types (ui-action.js)3.40KB1.71KB
types (views.js)0.20KB0.18KB
types (widget.js)0.20KB0.18KB

Size Limits

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

@os-samClaude

Copy link
Copy Markdown
Collaborator

PM review — ACCEPT on the diff. Landing held until CI is terminal.

domain:ui execution seat, PM session session_013hfmP9hoMd3dJwTh85J4yB.

The comment-only claim, verified independently rather than taken from the report

Read every +/- line of the diff myself. Five files: the changeset (new, empty frontmatter =
"releases nothing"), and four source files in which every changed line sits inside // or *
comment syntax
. The adjacent code lines — const navConfig = … in all three renderers, the
width prop declaration in the drawer — are untouched on both sides of each hunk. ⇒ No default, no
width expression, no size prop, no runtime value moves.

⭐ The dev's second proof is the one that actually carries this: hashing each file's non-comment
body
against its base blob and getting byte-identical in all four, with real non-empty hashes on
both sides. A line-by-line syntax match can be fooled by a // inside a string; a body hash cannot.
That is the right instrument for this claim.

⭐ It refused the red-first claim, correctly and in its own words

This change cannot be red first, and no red-first is claimed for it.

That is the honest answer, and it is what the dispatch required. A comment edit has no failing state
to start from, and dressing one up would have been a lie. The substitute bar it set instead — green
stays green, and the textual re-location is measured — is the right one.

Three things it got right that a weaker pass would have missed

1. It found six more #6303 citations and left every one of them alone. They cite #6303 as
provenance — the card that did in fact remove the width spelling — which stays accurate whatever
state that card is in. The defect this card names is narrower: a comment presenting a closed card as
the open home of an undecided question. Exactly three sites did that. Editing the other six would
have been scope creep dressed as thoroughness.

2. The fourth-pointer zero carries a control on the join. Three independent sweeps (issue-number
citations; openness prose keyed on no issue number; the measurement prose itself), each of which had
to hit the three known pointers in the same query for its zero to count. All three hit; none
surfaced a fourth. And it correctly discriminated sweep 3's other hits — useNavigationOverlay.ts
and recordSurface.test.ts carry min(92vw, 1600px), the unrelated full bucket, a different
literal rather than a pointer.

3. It reported the line-number discrepancy as NOT MEASURED instead of resolving it in its own
favour.
Kanban matched at 712; calendar came back 482 against a claimed 465, gantt 1325–1326
against 1283. Whether that is drift or transcription is not settleable from a checkout whose history
begins 2026-08-30T07:26Z — so it said so, rather than writing "the card was wrong". ⇒ Correct: an
unreconstructible cell is unmeasured, not a verdict.

The RecordDetailDrawer call was the dev's to make, and it made it well

The dispatch left it open and asked for a reason either way. Its reason holds: the drawer is the
single code home of min(960px, 60vw) repo-wide, all three renderer comments point at it, and
recording the ruling in three renderers but not at the line a future editor would actually change
would reproduce the homeless-decision failure this card exists to fix — in miniature. Accepted.

The load-bearing sentence

The question is CLOSED, not open — do not re-open it as a cleanup.

That is what the three comments are for. The old text invited exactly that re-opening, and the
gantt comment now keeps #6259 / #6303 as the history of where the question was asked while no
longer naming either as its home — which is honest about the past without misdirecting the future.
The ruling's fallback is quoted too, so the door reads as gated rather than nailed shut.

Landing path

Not clause ②: comment text changes no contract and widens no published surface. No governed surface
(docs/adr/**, .claude/**, skills/**, AGENTS.md, CLAUDE.md) is in the diff, and nothing
under content/docs/releases/. ⇒ ordinary review + merge queue, and this ACCEPT is mine to act on.

Not arming yet. This ACCEPT is on the diff; CI is the arbiter of the tree. The PR was opened
at 15:38:49Z and its checks have not reached a terminal state. mergeable_state reads behind
the branch was cut from 3b9c774c5 and main has since moved to 64d937c5. That is behind, not
conflicted, and the merge queue tests the merge result, so it is not work — but I will confirm it
is still behind and not dirty before marking ready.

I will mark ready and arm once CI is terminal green, and confirm the enqueue from the
gh-readonly-queue/main/pr-6915-* ref rather than from any API return value.


Generated by Claude Code

Sign up for freeto 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.

The record-drawer size: 'lg' bucket decision has no live tracker — three source files point at #6303 and #6259, both now closed

2 participants

@os-sam@claude