Skip to content

docs(plugin-detail): state the driver's real arity rule and the arity-dependent parent scope (objectui#8937) - #9195

Merged
os-tesla merged 4 commits into
mainfrom
claude/issue-8937-spec-floor-and-residue
Sep 11, 2026
Merged

docs(plugin-detail): state the driver's real arity rule and the arity-dependent parent scope (objectui#8937)#9195
os-tesla merged 4 commits into
mainfrom
claude/issue-8937-spec-floor-and-residue

Conversation

@os-tesla

@os-tesla os-tesla commented Sep 11, 2026

Copy link
Copy Markdown
Collaborator

Part of objectui#8937 — two of the card's three findings are actioned; the third is not, because measurement falsified its premise and the lane accepted that. Details and readings below.

Rework round (2026-09-11). objectui#9184 (card objectui#8882) landed while this branch was open. It moved the arity compiler out of RelatedList.tsx into a new seam, packages/core/src/utils/parent-scope.ts, and carried the false sentence with it — in a fresh spelling (the driver that EXECUTES the query decides on) that origin/main had never held before. origin/main was merged in (⛔ never rebased, ⛔ never force-pushed) and the correction follows the claim to where it now lives. The ablation legs that pointed at the old address are re-anchored, not dropped, and a new pin exists specifically for the way this went wrong: a claim copied into a fresh file.

What landed (F2, F3)

F3 — the shipped README sentence. packages/plugin-detail/README.md is listed in that package's files[], so it reaches npm. It said the node's filter is AND-combined with { [relationshipField]: parentId }, full stop. Since objectui#7299 the parent condition is compiled to match the relationship field's arity, so a multi-valued relationship gets { [relationshipField]: { $contains: parentId } } instead. The paragraph now states both spellings and names the arbiter.

F2 — the false driver-arity claim, corrected where it now lives. Three sites carried it; all three are corrected and none of them changes a predicate or an assertion.

site before after
packages/core/src/utils/parent-scope.ts (the seam objectui#9184 created) isMultiValueField is "the same predicate the driver that executes the query decides on" states the driver's measured rule, records the divergence as a divergence, points at objectstack#17469
packages/plugin-detail/src/RelatedList.tsx (the pointer comment objectui#9184 left behind) "the driver that refuses the query decides on @objectstack/spec/data's isMultiValueField" says the seam does not buy agreement with storage, and where the measured rule is recorded
RelatedList.multiValueParentScope-7299.test.tsx (header, and the comment on its INERT case, which asserted = "is the correct predicate" for a shape the live driver refuses) same claim corrected; untouched by objectui#9184, re-verified after the merge

objectstack#17469 already exists and is open — ⛔ nothing re-filed.

The driver's real rule, measured on objectstack origin/main

protected isJsonField(type: string, field: any): boolean {
  if (!field.multiple && FILE_REFERENCE_TYPES.has(type)) return this.mediaColumnIsJson();
  return JSON_COLUMN_TYPES.has(type) || !!field.multiple;
}

JSON_COLUMN_TYPES is the spec's STRUCTURED_JSON_TYPES and MULTI_OPTION_TYPES plus the driver-internal object / array aliases; !!field.multiple is truthy on any type. The spec's predicate is MULTI_OPTION_TYPES.has(type) OR (MULTI_CAPABLE_TYPES.has(type) AND multiple === true), and MULTI_CAPABLE_TYPES is select / radio / lookup / user / file / image.

⇒ they disagree for a type outside that set carrying multiple: truemaster_detail / tree / text: objectui sends =, the driver stores a JSON column and refuses = with a 400 INVALID_FILTER. Not a regression: both surfaces sent = for that shape before objectui#7299 and objectui#8882 too.

What did NOT land, and why — F1's premise is false

The card's F1 says @objectstack/spec@^17.1.0 predates isMultiValueField (first shipped 17.3.0) and that consumers resolving 17.1.x/17.2.x take a runtime import failure. Measured against the published artifacts and against this repo's own floor gate, that is not so. The floor is already correct and packages/plugin-detail/package.json is untouched. The lane re-measured this independently with a third instrument and accepted the finding.

The reading was taken in the failing configuration, never off this repo's lockfile.

Reading 1 — isolated installs of each published 17.x, exact import form of the component's spec import. npm install @objectstack/spec@V into three empty scratch packages; resolution printed per run and confirmed to land inside each probe dir (no hoisting above them).

version import { isMultiValueField } from '@objectstack/spec/data' require() .d.mts / .d.ts declare it tsc --noEmit on the two spec import lines verbatim
17.1.0 exit 0, typeof === 'function' function yes / yes exit 0
17.2.0 exit 0, typeof === 'function' function yes / yes exit 0
17.3.0 exit 0, typeof === 'function' function yes / yes (not needed)

Controls, both lit. Negative: importing a name that cannot exist fails on every version with SyntaxError: The requested module '@objectstack/spec/data' does not provide an export named '__definitelyNotAnExport_8937' — exactly the failure shape F1 predicts, so the probe can produce it. Positive: AddressSchema, genuinely present in 17.2.x, imports cleanly. The tsc probe has its own negative control (error TS2305 ... has no exported member, exit 2).

Reading 2 — the export-set diff. @objectstack/spec/data exports 442 names on 17.1.0 and 17.2.0, 457 on 17.3.0. The 15 names 17.3.0 added are all credential / value-roundtrip symbols: BOUNDED_STRING_FIELD_TYPES, CANONICAL_CREDENTIAL_KEYS, CREDENTIAL_KEY_SPELLINGS, FIELD_GROUP_KEY_PATTERN, FORMER_CREDENTIAL_ALIASES, PASSTHROUGH_NESTED_CREDENTIAL_REFUSED, SYS_ACTIVITY_BUILTIN_TYPES, VALUE_DOMAIN_FIELD_TYPES, VALUE_ROUNDTRIP_CASES, VALUE_ROUNDTRIP_COLLISION_PAIRS, VALUE_ROUNDTRIP_FIELDS, VALUE_ROUNDTRIP_ROWS, refusedCredentialPaths, refusedCredentialPathsOfSchema, valueRoundTripDivergence. Nothing removed, and isMultiValueField is not among the additions.

Reading 3 — this repository's own gate says the same thing, re-run after the merge. pnpm check:spec-floors (scripts/check-spec-range-floors.mjs) exists for exactly this defect class (objectui#5793). It never resolves through the installed tree: it fetches the declared-minimum tarball from the registry and walks that manifest's own exports map under the import condition, judging the package's built artifact. Scoped to the two packages this branch touches, after building their closure:

scoped to: @object-ui/core, @object-ui/plugin-detail
counters: {"published":2,"floored":2,"artifacts":315,"scanned":90,"symbols":44}
findings: []
  @objectstack/spec@17.3.0 "."  "./api"  "./contracts"  "./data"  "./ui"    (core, floor ^17.3.0)
  @objectstack/spec@17.1.0 "./data"  "./ui"                                 (plugin-detail, floor ^17.1.0)
CONTROL plugin-detail @ ^17.0.0 -> RED  floor-too-low

The judged pairs include isMultiValueField from ./data, so the symbol F1 is about is in the judged set, not skipped. The control lights, so the gate can fail on this artifact. Earlier in the round the same control named its reason: dist/renderers/record-reference-rail.d.ts references ReferenceRailEntry, which @objectstack/spec@17.0.0 does not export.

^17.1.0 is not merely passing, it is the lowest floor that passes — the honest one, set deliberately by objectui#5793 ("floors track reality"). Raising it to ^17.3.0 would pass the gate too, because the gate only detects floor-too-low; it would narrow a published contract with nothing measured behind it and break consumers pinned to 17.1/17.2 for no reason. Under AGENTS.md #0.1 that is the wrong direction.

Also checked: declared @objectstack/spec floors across the tree are ^17.0.0 (22 sites), ^17.1.0 (plugin-detail, react), ^17.2.0 (data-objectstack), ^17.3.0 (core), ^17.4.0 (types) — nothing here would have been disturbed either way, and the question is moot now that the manifest is untouched.

Pins, and the ablation for each

All three pins re-derive on every run, never transcribe the sentence — a transcription pin only asserts that nobody edited the sentence, which is the failure mode these defects already are. They live in relatedListParentScopeResidue-8937.test.ts.

  • Pin one reads the returned literal out of composeParentScopeFilter and requires the shipped README paragraph to name exactly the operator set the seam composes, in both directions, plus the equality spelling exactly when a bare equality arm still exists. Re-anchored this round: the literal used to live in RelatedList.tsx.
  • Pin two reads the divergence list back out of the seam's header and re-derives it from the installed spec: each named type must be a real FieldType, must be in neither MULTI_CAPABLE_TYPES nor MULTI_OPTION_TYPES, and isMultiValueField({ type, multiple: true }) must still answer false. A CONTROL case asserts the same predicate answers true for lookup / user / multiselect, so the divergence cases cannot pass vacuously. Re-anchored this round for the same reason. ⚠️ This is the pin that will move: a settled objectstack#17469 most likely admits these types to the spec's multi-capable set, at which point the list stops being a divergence and this file reddens — which is the point.
  • Pin three is NEW, and it is the one that would have caught this rework's cause. Every tracked file under packages that names both the spec predicate and the driver must cite objectstack#17469, so the claim cannot be copied into a fresh file silently. A DISCRIMINATOR case proves the driver filter narrows rather than demanding the citation of every mention, and names the file that must stay on the excluded side (plugin-grid's multiValueFields.ts, which relates the predicate to the server-side write pipeline — a true claim about a different consumer).
    ⚠️ Pin three was first built to grep for the retired sentence and that version is recorded here because it measured degenerate: the two corrections rephrase the claim across a line break, a line-oriented grep therefore misses them, and the only match left in the tree was the pattern string matching itself. A sweep whose sole carrier is its own pattern asserts nothing. Keying on the two subjects instead is what no rewording moves.

Ablation, six legs, re-anchored. Each leg: mutate, prove the bytes reached disk by blob-hash change, run, restore with git checkout HEAD -- PATH, prove restoration by state (git diff HEAD empty and hash back to the HEAD blob). Exit codes are evidence for neither direction, and the harness carries a trap on EXIT/INT/TERM calling a restore function with absolute paths. Run from the committed state, so each restore leg has a real restore point.

leg status mutation target blob result
1 unchanged README reverted to the pre-fix sentence plugin-detail/README.md a5971ee9ee32ce RED — pin one, 2 failed / 6 passed
2 re-anchored the seam stops composing $contains core/src/utils/parent-scope.ts ce8bb582fbfc88 RED — pin one, 2 failed / 6 passed
3 re-anchored the seam's divergence paragraph deleted core/src/utils/parent-scope.ts ce8bb580e54a6d RED — pin two, 1 failed / 7 passed
4 re-anchored the seam names lookup, a type the spec already calls multi-valued core/src/utils/parent-scope.ts ce8bb583156412 RED — pin two, 1 failed / 7 passed
5 new an existing carrier drops the objectstack#17469 citation plugin-detail/src/RelatedList.tsx 66905f6d501975 RED — pin three, 1 failed / 7 passed
6 new a fresh file starts relating the predicate to the driver, uncited plugin-grid/src/hooks/multiValueFields.ts 6ce74fcaa0090d RED — pin three + discriminator, 2 failed / 6 passed

Legs 2–4 pointed at RelatedList.tsx before the merge and would have stopped discriminating there; they were re-anchored onto the seam rather than dropped. All six restored; git status --porcelain empty afterwards.

Second rework round — the gate this PR tripped, and the one it filed

Test (shard 1/4) was red on this branch's own omission, and it is the same failure mode as pin three one level up.

scripts/markdown-test-inputs.mjs is the ledger behind ci.yml's "does this change need a full run" step: that step excludes markdown paths, so a test that READS markdown and is not in the ledger can be skipped by a markdown-only pull request. The new pin reads packages/plugin-detail/README.md and was not registered — someone could have edited that README and the pin would never have run. The gate caught it before it shipped.

The declared set is measured, not inferred from the constants. Two of the three pins name the README by constant; pin three enumerates git grep -l isMultiValueField packages and opens every hit, so the population is derived and could be wider than the constants suggest. Measured on this branch:

paths the enumeration offers 18
of those, CHANGELOGs dropped before anything is opened 10
paths actually opened 8
markdown documents in the read set 1 — packages/plugin-detail/README.md, the same README the other two pins name
root CHANGELOG.md never in the population: the pathspec is packages; the scanner resolved it only from the bare literal in the drop filter

So the entry declares reads: ['packages/plugin-detail/README.md'] and records both CHANGELOG candidates as notRead rather than dropping them. No walker is declared: auditTree raises stale-walker when one is declared and the scanner sees no directory walk, and it sees none here.

Red, then green.

reading before after
node scripts/markdown-test-inputs.mjs --audit exit 1 — unadjudicated-test: …relatedListParentScopeResidue-8937.test.ts reads markdown the ledger does not describe (CHANGELOG.md, packages/plugin-detail/CHANGELOG.md, packages/plugin-detail/README.md) exit 0 — 47 candidate test files, all adjudicated; 41 declared entries, all present
vitest run scripts/__tests__/markdown-test-inputs.test.ts exit 1 — Tests 1 failed | 11 passed (12) exit 0 — Tests 12 passed (12)
--changed on packages/plugin-detail/README.md prints it: a markdown-only edit now forces the run
--changed CONTROL on packages/plugin-detail/CHANGELOG.md prints nothing, exit 0 — the other side of the answer

The second annotation on that shard: root-caused, ⛔ not called a flake

scripts/check-i18n-dead-keys.mjs:616
grep: …/.objectui-tmp/tsc-gate-3853-1W87E5/tsconfig.json: No such file or directory

Consumer: check-i18n-dead-keys.mjs runs a whole-tree filesystem grep -rFn (lines 606-616) whose TEXT_SWEEP_SKIP_DIRS (lines 428-431) is node_modules, .git, dist, build, coverage, .next, .turbo, .changeset.objectui-tmp is not in it (grep -c returns 0). Producer: packages/cli/src/__tests__/app-generator.test.ts's withGeneratedApp (lines 1386-1396) mkdtempSyncs REPO_ROOT/.objectui-tmp/tsc-gate-3853-…, writes a generated app including a tsconfig.json, and removes it in a finally — so it lives for one test inside the same shard. Convention control, lit: the sibling whole-tree sweep check-comment-mask-corpus.mjs line 246 already lists .objectui-tmp in its skip set.

⇒ a missing exclusion, not a flake: only whether the two overlap varies; given overlap the outcome is determined. This branch does not contribute — the diff touches neither script, neither the CLI test nor .gitignore; the new test shells out to git grep, which reads tracked files only, and .objectui-tmp is .gitignored (.gitignore:50) hence untracked, so it is never opened by it, and a read cannot create a directory. The error also names a different grep in a different process. Filed as objectui#9201 after a dedup search (see below); ⛔ nothing here skipped, disabled or quarantined.

Dedup channel, declared. The container's REST /search/issues answers 403 with sessions are bound to their configured repositories — the proxy's path whitelist, ⛔ not a statement about GitHub scope — so the dedup went through one targeted MCP search_issues instead. Nine hits, all about how that script classifies keys, none about the sweep racing a temp directory. The control query in the same session returned this card, objectui#8937, as its second hit, so the channel was alive when the dedup ran.

Verification

Run from the repo root with paths relative to it, per AGENTS.md; every exit code captured by redirecting to a file first, never through a pipe. All of this is post-merge; the ledger row is the second rework round.

what command exit reading
① dependency-closure build turbo run build --filter=@object-ui/plugin-detail --filter=@object-ui/core --concurrency=2, under the shared verify lock 0 Tasks: 12 successful, 12 total; lock printed VERDICT command-exit 0
② both affected packages + the cross-package source reader pnpm exec vitest run packages/plugin-detail/ packages/core/ packages/i18n/src/__tests__/residue-namespaces-3546.test.tsx, under the lock 0 Test Files 323 passed (323) · Tests 4848 passed (4848); lock printed VERDICT command-exit 0
② type-check pnpm --filter @object-ui/plugin-detail type-check · ... @object-ui/core ... 0 · 0 both logs echo their script name, so neither was a zero-match filter exiting 0 in silence. ⚠️ Both exit 2 against an unbuilt tree (TS6305 / TS2307) — a prerequisite, not a red; they pass once ① has run
② lint pnpm --filter @object-ui/plugin-detail lint · ... @object-ui/core ... 0 · 0 997 problems (0 errors) and 542 problems (0 errors), all pre-existing; the new test file contributes none
③ changeset trio check-changeset-presence · check-changeset-no-major · check-changeset-claims 0 · 0 · 0 presence: "4 source file(s) of 2 released package(s) changed, and this change declares 1 changeset(s)"
③ control bytes node scripts/check-control-bytes.mjs, plus a grep -naP sweep over the touched files 0 · 1 gate OK over 7393 tracked files; the grep found none (its exit 1 is the empty result)
③ new cross-file line citations node scripts/check-new-cross-file-line-citations.mjs 0 no new citation added — the corrected comments name files, never a file plus a line number
③ comment-mask corpus node scripts/check-comment-mask-corpus.mjs 0 4847 files; the single disagreement is the pre-existing apps/console/src/pages/DocsIndex.tsx residue objectui#7882 holds open, not this diff
③ doc fences · doc links check-doc-fence-languages.mjs · check-doc-links.mjs 0 · 0 fences judged over 227 documents
③ spec floors, scoped the gate's own analyze() over both packages, after ① 0 findings: []; the ^17.0.0 control is RED
③ governed surface check-governed-queue-guard.mjs --test over the six changed paths 0 NOT GOVERNED — 6 paths checked against 5 surfaces, none matched
NOT MEASURED pnpm check:readme-exports 1 a prerequisite failure, ⛔ not a red. It collapses its own population and says so: packagesRead: found 13, floor is 25, 24 unbuilt. It owns a whole-workspace build step inside .github/workflows/readme-exports.yml, and objectui#4846 rejected a per-PR full-repo build.
owned by CI pnpm lint (turbo, every package) · pnpm test (full) · check:spec-floors on its own workflow and the release path repo-wide scans; not narrowed here

⚠️ This repository has no scripts/pm/dispatch-gates.mjs — that script is objectstack's, and pointing it at this tree would return a confident answer about the wrong repository. The list above was derived by hand from this repo's root package.json check:* scripts and .github/workflows/.

Merge, not rebase

git merge origin/main at 759606e1d, one conflict (packages/plugin-detail/src/RelatedList.tsx, the docblock both sides edited), resolved by taking origin/main's pointer comment as the base — the function it described has moved — and correcting its one false clause in place. Landing of objectui#9184 was confirmed by content, not by sha: git cat-file -e origin/main:packages/core/src/utils/parent-scope.ts exits 0, with RelatedList.tsx as a lit positive control. ⛔ No rebase, ⛔ no force-push, at any point.

Status

⛔ Draft, ⛔ not enqueued, ⛔ no auto-merge — the lane arms it. Clause-② stays yes; needs:contract-review is attached and stays until the lane clears it. packages/plugin-detail/package.json is untouched. packages/plugin-detail/src/renderers/record-reference-rail.tsx is untouched (objectui#8883 is live on it).

Out of scope, noted

⛔ No new card is opened for the arity divergence — objectstack#17469 already owns it and is open.

Generated by Claude Code; this round's session is session_01UzHd6hDYatoDn17BuwKxnZ (recorded as prose, because a link-form footer does not survive a body edit).


Generated by Claude Code

…-dependent parent scope

Two published texts objectui#8886 left behind, both measured false on origin/main:

- packages/plugin-detail/README.md ships (it is in files[]) and said the node's
  `filter` is AND-combined with `{ [relationshipField]: parentId }`, full stop.
  Since objectui#7299 the parent condition is compiled to match the relationship
  field's arity, so a multi-valued one gets `{ $contains: parentId }` instead.
  The paragraph now states both spellings and names the arbiter.

- `parentRelationshipFieldDef`'s docblock, and the same sentence in the
  objectui#7299 test header, said the SQL driver decides arity on the spec's
  `isMultiValueField`. It does not: driver-sql gates the equality family on its
  own storage question, which reads `multiple` as truthy on ANY type. The two
  rules therefore disagree for a type outside MULTI_CAPABLE_TYPES carrying
  `multiple: true`; that divergence is now recorded as one and pointed at the
  upstream card that owns it (objectstack#17469).

No predicate moved and no wire changed. Both claims are pinned by re-derivation
rather than transcription, in relatedListParentScopeResidue-8937.test.ts.

The manifest floor finding on the same card is NOT actioned here: measurement
falsified its premise. See the pull request body.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UzHd6hDYatoDn17BuwKxnZ
@github-actions github-actions Bot added documentation Improvements or additions to documentation plugin tests labels Sep 11, 2026
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 51 chunks) 3111.9 KB 3134.8 KB
Main entry chunk (gzip) 144.2 KB 350 KB
Entry file index-DIZ2TtxX.js
Status PASS

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


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 16.69KB 6.21KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.06KB 3.86KB
auth (ActiveOrganizationStorage.js) 25.05KB 9.16KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.18KB 10.59KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.65KB 2.22KB
auth (SocialSignInButtons.js) 9.61KB 3.89KB
auth (UserMenu.js) 3.41KB 1.23KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.80KB
auth (createAuthenticatedFetch.js) 8.46KB 3.43KB
auth (index.js) 3.19KB 1.44KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 26.08KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 500.22KB 114.68KB
core (index.js) 8.28KB 3.31KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 209.38KB 57.92KB
fields (index.js) 247.41KB 62.43KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 1.22KB 0.64KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.21KB 2.26KB
i18n (pickLocalized.js) 7.62KB 3.26KB
i18n (provider.js) 32.15KB 10.49KB
i18n (useDisplayLocale.js) 2.85KB 1.45KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 38.84KB 10.95KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 2.53KB 0.85KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 4.39KB 1.66KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 13.52KB 4.88KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.24KB 2.16KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.39KB 3.10KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 14.81KB 3.63KB
plugin-calendar (index.js) 49.03KB 13.93KB
plugin-charts (index.js) 71.52KB 19.98KB
plugin-chatbot (index.js) 195.32KB 46.51KB
plugin-dashboard (index.js) 131.18KB 34.62KB
plugin-designer (index.js) 215.68KB 44.27KB
plugin-detail (index.js) 252.19KB 65.42KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 136.79KB 34.19KB
plugin-gantt (index.js) 166.94KB 41.04KB
plugin-grid (index.js) 211.56KB 57.50KB
plugin-kanban (index.js) 46.10KB 14.33KB
plugin-list (index.js) 112.58KB 27.65KB
plugin-map (index.js) 20.49KB 6.83KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 43.42KB 11.92KB
plugin-timeline (index.js) 30.10KB 8.74KB
plugin-tree (index.js) 9.54KB 3.31KB
plugin-view (index.js) 84.42KB 20.80KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.66KB 3.50KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 94.03KB 31.02KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.63KB 2.18KB
react (schema-input.js) 4.25KB 2.04KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 6.58KB 2.74KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 5.66KB 2.50KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (kanban-quick-add.js) 3.89KB 1.87KB
sdui-parser (parse.js) 25.28KB 7.80KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 14.82KB 4.99KB
types (ai.js) 0.20KB 0.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 1.00KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 2.93KB 1.49KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.25KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 4.73KB 2.28KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 14.27KB 5.47KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

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

objectui#9184 (card objectui#8882) moved the parent-scope compiler out of
RelatedList.tsx into @object-ui/core's parent-scope seam while this branch was
in flight, conflicting with this branch's docblock correction at the same spot.

Conflict resolution, packages/plugin-detail/src/RelatedList.tsx: origin/main's
pointer comment is taken as the base, because the function it described has
moved. Its one false clause is corrected in place -- it asserted that the
driver refusing the query decides on @objectstack/spec/data's
isMultiValueField, which measurement on objectstack origin/main falsifies. The
pointer now says where the measured rule, the divergence and the upstream card
are recorded, rather than restating a rule that no longer lives in this file.

Merge, never rebase (AGENTS.md).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UzHd6hDYatoDn17BuwKxnZ
…rage arity

objectui#9184 moved the arity compiler into @object-ui/core's parent-scope seam
and newly wrote the false claim into its header: that isMultiValueField is "the
same predicate the driver that executes the query decides on". Measured on
objectstack origin/main, driver-sql gates the equality family on its own
storage question, which reads `multiple` as truthy on ANY type -- so the two
rules diverge for a type outside MULTI_CAPABLE_TYPES carrying `multiple: true`
(master_detail / tree / text).

The seam now states the driver's measured rule, records that divergence as a
divergence rather than as agreement, and points at objectstack#17469, which
owns which of the two rules is right. No predicate and no assertion moved: the
arity rules are upstream business.

The pin re-anchors onto the seam, since the composition and the docblock it
judged both left RelatedList.tsx:

- pin one re-derives the operator set from composeParentScopeFilter's returned
  literal and holds the shipped README to exactly that set, both directions;
- pin two re-derives the divergence list from the INSTALLED spec, so it reddens
  when the spec side moves -- the likely settlement of the upstream card;
- pin three is new and is the one that would have caught this rework's cause:
  every file relating the spec predicate to the driver must cite the card that
  owns their disagreement, so the claim cannot be copied into a fresh file
  silently. A discriminator case proves the driver filter narrows rather than
  demanding the citation of every mention.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UzHd6hDYatoDn17BuwKxnZ
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 51 chunks) 3112.1 KB 3134.8 KB
Main entry chunk (gzip) 144.2 KB 350 KB
Entry file index-r_U7yDvF.js
Status PASS

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


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 16.69KB 6.21KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.06KB 3.86KB
auth (ActiveOrganizationStorage.js) 25.05KB 9.16KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.18KB 10.59KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.65KB 2.22KB
auth (SocialSignInButtons.js) 9.61KB 3.89KB
auth (UserMenu.js) 3.41KB 1.23KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.80KB
auth (createAuthenticatedFetch.js) 8.46KB 3.43KB
auth (index.js) 3.19KB 1.44KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 26.08KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 500.68KB 114.78KB
core (index.js) 8.52KB 3.41KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 209.38KB 57.92KB
fields (index.js) 247.41KB 62.43KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 1.22KB 0.64KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.21KB 2.26KB
i18n (pickLocalized.js) 7.62KB 3.26KB
i18n (provider.js) 32.15KB 10.49KB
i18n (useDisplayLocale.js) 2.85KB 1.45KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 38.84KB 10.95KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 2.53KB 0.85KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 4.39KB 1.66KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 13.52KB 4.88KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.24KB 2.16KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.39KB 3.10KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 14.81KB 3.63KB
plugin-calendar (index.js) 49.03KB 13.93KB
plugin-charts (index.js) 71.52KB 19.98KB
plugin-chatbot (index.js) 195.32KB 46.51KB
plugin-dashboard (index.js) 131.18KB 34.62KB
plugin-designer (index.js) 215.68KB 44.27KB
plugin-detail (index.js) 251.95KB 65.34KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 136.79KB 34.19KB
plugin-gantt (index.js) 166.94KB 41.04KB
plugin-grid (index.js) 211.56KB 57.50KB
plugin-kanban (index.js) 46.10KB 14.33KB
plugin-list (index.js) 112.58KB 27.65KB
plugin-map (index.js) 20.49KB 6.83KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 43.42KB 11.92KB
plugin-timeline (index.js) 30.10KB 8.74KB
plugin-tree (index.js) 9.54KB 3.31KB
plugin-view (index.js) 84.42KB 20.80KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.66KB 3.50KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 94.03KB 31.02KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.63KB 2.18KB
react (schema-input.js) 4.25KB 2.04KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 6.58KB 2.74KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 5.66KB 2.50KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (kanban-quick-add.js) 3.89KB 1.87KB
sdui-parser (parse.js) 25.28KB 7.80KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 14.82KB 4.99KB
types (ai.js) 0.20KB 0.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 1.00KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 2.93KB 1.49KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.25KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 4.73KB 2.28KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 14.27KB 5.47KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

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

Copy link
Copy Markdown
Collaborator Author

PM review — content ACCEPTED; ⛔ CI is RED and the failure is this PR's own

Read against git merge-base origin/main <head> = 759606e1d: 6 files, +399/−24.

Accepted: the sync is a real merge (e7c4d2fca Merge origin/main into claude/issue-8937-…), ⛔ no rebase; packages/plugin-detail/package.json untouched, so F1 stays closed by measurement rather than by edit; Clause-② --pair 9195 → both carriers agree.

⭐ The most valuable line in the report is the one admitting a failure: pin three was first built degenerate — a line-oriented grep for the retired sentence whose only surviving match was its own pattern string — and that was reported rather than shipped. It is independently corroborated: git grep "same predicate the driver" returns zero hits against another branch that demonstrably carries that exact claim, because the sentence wraps at the / driver. Keying on the two subjects is the right repair, and "a sweep whose sole carrier is its own pattern asserts nothing" is worth keeping.

The failure — Test (shard 1/4)

scripts/__tests__/markdown-test-inputs.test.ts:257
  kind:   "unadjudicated-test"
  test:   "packages/plugin-detail/src/__tests__/relatedListParentScopeResidue-8937.test.ts"
  detail: "reads markdown the ledger does not describe (CHANGELOG.md,
           packages/plugin-detail/CHANGELOG.md, packages/plugin-detail/README.md)."

Verified here with lit controls: the new pin reads packages/plugin-detail/README.md (:99), it appears 0 times in scripts/markdown-test-inputs.mjs, while the registered entries at :190 (core/src/adapters/README.md) and :252-253 (the plugin-calendar README pin) are both present — so the ledger and the probe are working and the omission is real.

⭐ Worth naming because it is the same defect one level up: a pin that reads markdown and is not in that registry can be skipped by a markdown-only PR. Someone could edit plugin-detail/README.md and pin one would never run. That is precisely the class pin three exists to close, and the gate caught it before it shipped.

A second annotation in the same shard — check-i18n-dead-keys.mjs:616, a grep failing on a vanished .objectui-tmp/tsc-gate-3853-…/tsconfig.json — looks like a scratch-directory race naming another card's gate. ⛔ I am not ruling it a flake: "flake" is not a root cause. The push for the ledger entry re-runs the shard; that run is the reading.

Coordination

PR #9200 (card objectui#8883) is in flight on record-reference-rail.tsx and carries a fourth copy of the false driver claim — pin three would redden on it. That PR is being corrected to cite objectstack#17469, so the two land compatibly. ⛔ Neither seat touches the other's file.

Arm held until CI reads pending: 0, failing: 0.


Generated by Claude Code

`Test (shard 1/4)` was red on this branch's own omission: the new pin reads
`packages/plugin-detail/README.md`, and a test that reads markdown without a
ledger entry can be SKIPPED by a markdown-only pull request -- ci.yml's
"needs a full run" step excludes markdown paths, so someone could edit that
README and the pin would never execute (objectui#8861).

That is the same failure mode the pin's own third case exists to prevent, one
level up, and this gate caught it before it shipped.

The declared set is MEASURED, not inferred from the constants. Two of the three
pins name the README by constant; the third enumerates
`git grep -l isMultiValueField packages` and opens every hit, so the population
is derived. Measured: the enumeration offers 18 paths, ten of them CHANGELOGs
dropped before anything is opened, and exactly one markdown document survives
into the read set -- the same README. The root `CHANGELOG.md` the scanner
resolves is never in the population: the pathspec is `packages`, and the bare
literal it resolved comes from the drop filter. Both CHANGELOG candidates are
therefore recorded as `notRead` rather than dropped, and no `walker` is
declared because the scanner sees no directory walk here.

Readings: `--audit` exit 1 before ("1 finding(s)", unadjudicated-test naming
all three paths) and exit 0 after ("47 candidate test files, all adjudicated").
The gate's own suite goes 1 failed / 11 passed -> 12 passed. `--changed` now
answers in both directions: it prints the README (a markdown-only edit forces
the run) and prints nothing for the CHANGELOG.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UzHd6hDYatoDn17BuwKxnZ
@github-actions

Copy link
Copy Markdown
Contributor

✅ Console Performance Budget

Metric Value Budget
Eager closure (gzip, 51 chunks) 3112.0 KB 3134.8 KB
Main entry chunk (gzip) 144.2 KB 350 KB
Entry file index-pq9HMKTu.js
Status PASS

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


📦 Bundle Size Report

Package Size Gzipped
app-shell (consoleActionDispatch.js) 0.20KB 0.19KB
app-shell (index.js) 16.69KB 6.21KB
app-shell (runtime-config.js) 20.68KB 7.36KB
app-shell (types.js) 0.01KB 0.04KB
app-shell (urlParams.js) 10.06KB 3.86KB
auth (ActiveOrganizationStorage.js) 25.05KB 9.16KB
auth (AuthContext.js) 0.31KB 0.24KB
auth (AuthGuard.js) 2.07KB 1.00KB
auth (AuthProvider.js) 40.18KB 10.59KB
auth (AuthShell.js) 3.49KB 1.40KB
auth (ForgotPasswordForm.js) 12.21KB 3.45KB
auth (LoginForm.js) 18.15KB 5.39KB
auth (PreviewBanner.js) 0.90KB 0.50KB
auth (RegisterForm.js) 6.65KB 2.22KB
auth (SocialSignInButtons.js) 9.61KB 3.89KB
auth (UserMenu.js) 3.41KB 1.23KB
auth (auth-gate-events.js) 1.29KB 0.66KB
auth (authStyles.js) 5.04KB 1.72KB
auth (createAuthClient.js) 40.21KB 10.80KB
auth (createAuthenticatedFetch.js) 8.46KB 3.43KB
auth (index.js) 3.19KB 1.44KB
auth (invitation-status.js) 1.22KB 0.70KB
auth (org-roles.js) 6.66KB 2.78KB
auth (phone-identifier.js) 1.11KB 0.66KB
auth (types.js) 0.59KB 0.35KB
auth (useAuth.js) 5.30KB 1.02KB
auth (useWorkspaceAdminStatus.js) 11.08KB 4.58KB
collaboration (CommentThread.js) 26.08KB 7.56KB
collaboration (LiveCursors.js) 3.17KB 1.27KB
collaboration (PresenceAvatars.js) 6.49KB 2.64KB
collaboration (PresenceProvider.js) 2.79KB 1.13KB
collaboration (index.js) 1.68KB 0.73KB
collaboration (useCollaborationTranslation.js) 6.05KB 2.52KB
collaboration (useCommentSearch.js) 1.98KB 0.88KB
collaboration (useConflictResolution.js) 7.75KB 1.86KB
collaboration (useMentionNotifications.js) 1.81KB 0.68KB
collaboration (usePresence.js) 6.33KB 1.84KB
collaboration (useRealtimeSubscription.js) 7.91KB 2.01KB
components (index.js) 500.68KB 114.78KB
core (index.js) 8.52KB 3.41KB
create-plugin (index.js) 27.94KB 9.51KB
data-objectstack (index.js) 209.38KB 57.92KB
fields (index.js) 247.41KB 62.43KB
i18n (LocalizationContext.js) 1.76KB 0.96KB
i18n (builtinAggregateLabels.js) 0.86KB 0.49KB
i18n (currency.js) 1.22KB 0.64KB
i18n (fallbackInterpolation.js) 6.25KB 2.77KB
i18n (i18n.js) 8.87KB 3.64KB
i18n (index.js) 5.21KB 2.26KB
i18n (pickLocalized.js) 7.62KB 3.26KB
i18n (provider.js) 32.15KB 10.49KB
i18n (useDisplayLocale.js) 2.85KB 1.45KB
i18n (useObjectLabel.js) 34.34KB 9.17KB
i18n (useSafeTranslation.js) 5.60KB 2.33KB
layout (index.js) 38.84KB 10.95KB
mobile (MobileProvider.js) 0.92KB 0.49KB
mobile (ResponsiveContainer.js) 0.94KB 0.38KB
mobile (breakpoints.js) 1.51KB 0.70KB
mobile (createOfflineDataSource.js) 5.61KB 1.75KB
mobile (index.js) 1.99KB 0.87KB
mobile (offlineQueue.js) 3.91KB 1.35KB
mobile (pwa.js) 0.97KB 0.49KB
mobile (serviceWorker.js) 1.48KB 0.62KB
mobile (serviceWorkerSource.js) 3.41KB 1.48KB
mobile (useBreakpoint.js) 1.54KB 0.65KB
mobile (useGesture.js) 6.96KB 1.98KB
mobile (useOfflineSync.js) 1.99KB 0.72KB
mobile (usePullToRefresh.js) 2.53KB 0.85KB
mobile (useResponsive.js) 0.72KB 0.42KB
mobile (useSpecGesture.js) 4.39KB 1.66KB
mobile (useTouchTarget.js) 1.01KB 0.54KB
permissions (MePermissionsProvider.js) 13.52KB 4.88KB
permissions (PermissionContext.js) 0.31KB 0.25KB
permissions (PermissionGuard.js) 0.89KB 0.45KB
permissions (PermissionProvider.js) 6.24KB 2.16KB
permissions (discardProofCache.js) 1.04KB 0.55KB
permissions (evaluator.js) 8.39KB 3.10KB
permissions (index.js) 0.93KB 0.41KB
permissions (store.js) 0.91KB 0.42KB
permissions (useFieldPermissions.js) 1.28KB 0.53KB
permissions (usePermissions.js) 4.83KB 2.27KB
plugin-ai (index.js) 14.81KB 3.63KB
plugin-calendar (index.js) 49.03KB 13.93KB
plugin-charts (index.js) 71.52KB 19.98KB
plugin-chatbot (index.js) 195.32KB 46.51KB
plugin-dashboard (index.js) 131.18KB 34.62KB
plugin-designer (index.js) 215.68KB 44.27KB
plugin-detail (index.js) 251.95KB 65.34KB
plugin-editor (index.js) 2.23KB 1.05KB
plugin-form (index.js) 136.79KB 34.19KB
plugin-gantt (index.js) 166.94KB 41.04KB
plugin-grid (index.js) 211.56KB 57.50KB
plugin-kanban (index.js) 46.10KB 14.33KB
plugin-list (index.js) 112.58KB 27.65KB
plugin-map (index.js) 20.49KB 6.83KB
plugin-markdown (index.js) 13.88KB 4.80KB
plugin-report (index.js) 43.42KB 11.92KB
plugin-timeline (index.js) 30.10KB 8.74KB
plugin-tree (index.js) 9.54KB 3.31KB
plugin-view (index.js) 84.42KB 20.80KB
providers (DataSourceProvider.js) 0.75KB 0.39KB
providers (MetadataProvider.js) 1.37KB 0.59KB
providers (ThemeProvider.js) 1.90KB 0.85KB
providers (UploadProvider.js) 11.66KB 3.50KB
providers (index.js) 0.45KB 0.23KB
providers (types.js) 0.01KB 0.04KB
react-runtime (index.js) 5.62KB 2.34KB
react (LazyPluginLoader.js) 4.47KB 1.63KB
react (SchemaRenderer.js) 94.03KB 31.02KB
react (data-invalidation.js) 5.05KB 2.08KB
react (index.js) 4.63KB 2.18KB
react (schema-input.js) 4.25KB 2.04KB
react (spec-input.js) 0.20KB 0.18KB
sdui-parser (codegen.js) 6.58KB 2.74KB
sdui-parser (dashboard-widget-options.js) 3.08KB 1.30KB
sdui-parser (index.js) 5.66KB 2.50KB
sdui-parser (input-type.js) 2.84KB 1.40KB
sdui-parser (kanban-quick-add.js) 3.89KB 1.87KB
sdui-parser (parse.js) 25.28KB 7.80KB
sdui-parser (provenance.js) 3.66KB 1.82KB
sdui-parser (types.js) 0.28KB 0.23KB
sdui-parser (validate.js) 14.82KB 4.99KB
types (ai.js) 0.20KB 0.17KB
types (api-types.js) 0.20KB 0.18KB
types (app.js) 2.87KB 1.00KB
types (base.js) 0.20KB 0.18KB
types (blocks.js) 0.20KB 0.18KB
types (complex.js) 2.93KB 1.49KB
types (crud.js) 0.20KB 0.18KB
types (dashboard-filter-alias.js) 6.23KB 2.74KB
types (data-display.js) 3.75KB 1.85KB
types (data-protocol.js) 0.20KB 0.19KB
types (data.js) 0.20KB 0.18KB
types (designer.js) 1.85KB 0.85KB
types (disclosure.js) 0.20KB 0.18KB
types (error-code.js) 1.54KB 0.88KB
types (expression.js) 0.20KB 0.18KB
types (feedback.js) 0.20KB 0.18KB
types (field-types.js) 0.20KB 0.18KB
types (form.js) 0.20KB 0.18KB
types (http-inflight.js) 8.87KB 3.73KB
types (http-retry.js) 4.32KB 2.02KB
types (icon-key-migration.js) 4.26KB 1.63KB
types (index.js) 4.74KB 2.25KB
types (layout.js) 0.20KB 0.18KB
types (managed-by.js) 0.19KB 0.18KB
types (mobile.js) 4.73KB 2.28KB
types (navigation.js) 0.20KB 0.18KB
types (objectql.js) 0.20KB 0.18KB
types (overlay.js) 0.20KB 0.18KB
types (permissions.js) 0.20KB 0.18KB
types (plugin-scope.js) 0.20KB 0.18KB
types (record-components.js) 0.20KB 0.19KB
types (record-semantics.js) 1.28KB 0.67KB
types (registry.js) 0.20KB 0.18KB
types (reports.js) 0.20KB 0.18KB
types (select-option.js) 0.20KB 0.19KB
types (spec-report.js) 5.05KB 1.93KB
types (spec-ui-namespace.js) 0.20KB 0.19KB
types (strict-authoring-face.js) 14.27KB 5.47KB
types (system-fields.js) 3.33KB 1.54KB
types (theme.js) 6.28KB 2.87KB
types (ui-action.js) 8.11KB 3.32KB
types (views.js) 0.20KB 0.18KB
types (widget.js) 0.20KB 0.18KB

Size Limits

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

Copy link
Copy Markdown
Collaborator Author

Second rework ACCEPTED — both claims re-measured here

Head d663a1e1d.

The ledger entry (scripts/markdown-test-inputs.mjs:274-279) is present and its reads set is derived, not copied off the file's constants — which is what I asked for, since pin three enumerates git grep -l isMultiValueField packages and opens whatever it finds:

reads: ['packages/plugin-detail/README.md'],
notRead: ['CHANGELOG.md', 'packages/plugin-detail/CHANGELOG.md'],

18 paths offered → 10 CHANGELOGs dropped before opening → 8 opened → 1 markdown in the read set. Recording the two CHANGELOG candidates as notRead rather than dropping them is the right call: it makes the exclusion auditable instead of invisible. And the --changed readings close it properly — the README forces the run, the CHANGELOG control prints nothing.

The i18n annotation is root-caused, not waved off, and I verified the load-bearing half myself:

reading value
.objectui-tmp in scripts/check-i18n-dead-keys.mjs 0 — absent from TEXT_SWEEP_SKIP_DIRS
.objectui-tmp in scripts/check-comment-mask-corpus.mjs (CONTROL) 2 — prose at :238, the skip-list entry at :246

⇒ the exclusion is an established convention in this tree that exactly one of the two whole-tree sweeps is missing. That is a defect with a name, not a flake, and the card's own argument for why is the right one: "the interleaving is what varies; the defect does not." Filed as #9201 with both halves measured, a lit convention control, and an honest scope limit (it does not claim to have surveyed other sweeps). ⭐ Nothing was skipped, disabled or quarantined to get green — which was the instruction and is the part that matters.

The self-report that the first suite invocation named a nonexistent file and the vitest guard refused rather than passing on a zero-match path is worth keeping too: that guard (objectui#3288) is the reason a mistyped path did not read as a green run.

⛔ Arm still held: 36 checks, 7 in progress, 0 failing. Not-red-yet is not green. I arm on pending: 0.


Generated by Claude Code

@os-tesla
os-tesla marked this pull request as ready for review September 11, 2026 17:35
@os-tesla
os-tesla added this pull request to the merge queue Sep 11, 2026
Merged via the queue into main with commit 1f4e029 Sep 11, 2026
38 checks passed
@os-tesla
os-tesla deleted the claude/issue-8937-spec-floor-and-residue branch September 11, 2026 17:53
os-tesla pushed a commit that referenced this pull request Sep 11, 2026
…arity

Brings in objectui#8937 (PR #9195), whose residue sweep pin now requires every
file naming both the spec arity predicate and the driver to cite
objectstack#17469.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UzHd6hDYatoDn17BuwKxnZ
os-tesla pushed a commit that referenced this pull request Sep 11, 2026
…e 8883 rail pin

objectui#8937's residue sweep (PR #9195, pin three) requires every tracked file
under `packages` that names both the spec arity predicate and the driver to
cite the card that owns their disagreement. This test file entered that
population when it landed and did not cite it, so the sweep reds on the
combined tree even though it is green on this branch's own base — which is what
ejected the PR from the merge queue.

The docblock now states the relationship it was implying: the spec gates on the
field TYPE, `driver-sql` decides storage on `!!field.multiple` whatever the
type, the two part company for a `multiple: true` def on a type outside the
spec's multi-capable set, and objectstack#17469 owns which is right. It also
records why these cases sit clear of that disagreement — they relate through a
`lookup` field, which both rules call multi-valued.

Prose only: the diff adds docblock lines and removes none. No predicate, no
assertion and no executable line moved.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UzHd6hDYatoDn17BuwKxnZ
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation package: core plugin tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants