You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Triage first-touch grade (concentrated batch; triage seat, session session_01NYoiJGd1MxXdcvM4EGAMrS): promoted to pm:queue, type Task — not blocked: the body's Blocked-by: #4814 is already satisfied (#4814 closed 08-17 via merged PR #4915, ruling A′ retired the owner spelling). Premise re-verified on the merged ref, not the card text: origin/main:packages/plugin-grid/src/components/bulkParamToField.ts:51 now reads USER_WIDGET_TYPES = new Set(['user']) with a tombstone comment at :45 — so the owner cell of this card's table is done, and the remaining ask is exactly the #4790-shaped convergence: single definition (core EXPANDABLE_FIELD_TYPES as the reference half + per-surface widget-hint extension), per-consumer normalization, and an identity pin (assert same object, so a member-identical private copy can't fake it).
The tree / picker-hint divergences remain measured-but-asymptomatic; the card's own analysis of why is the spec for which cells the shared table must and must not contain. Size/model suggestion: S–M, sonnet/opus.
Session: session_01RV6yuVCxymHYE16PL9vQkE
Branch: claude/issue-4815-data-source-widget-types-convergence
Worktree: objectui-issue-4815
Domain: repo:objectui
File surface: packages/plugin-grid/src/** + packages/core/src/** (the shared reference table) + their tests (stop on breach; explain in the report)
Container & model: S–M, mode:subagent, model: opus (taking the triage seat's upper suggestion — the identity-pin design is the hard part, not the edit)
Clause-②: no — this converges private copies onto one definition. It changes no contract surface and widens nothing published. If your implementation turns out to change which widget types are treated as data-source-bearing anywhere, that is a behaviour change: stop and report it rather than absorbing it into a "convergence".
Serial constraints cleared: packages/plugin-grid and packages/core are both free. Open PRs hold disjoint surfaces, each measured by git diff --name-only origin/main...: PR #5290apps/console, PR #5294packages/plugin-view, PR #5295.github/workflows + scripts/ + root manifests, PR #5297packages/plugin-map, PR #5298packages/components + packages/types, PR #5300 / #5303packages/plugin-dashboard, PR #5302packages/cli, PR #5310packages/plugin-report (consumes @object-ui/core but does not modify it — verified on its diff), PR #5311packages/plugin-form.
Not blocked — verified, not assumed
The body carries Blocked-by: #4814. That is satisfied: #4814 closed 2026-08-17 via merged PR #4915 (ruling A′ retired the owner spelling). The triage seat re-verified the premise on the merged ref rather than from the card text — origin/main:packages/plugin-grid/src/components/bulkParamToField.ts:51 now reads USER_WIDGET_TYPES = new Set(['user']) with a tombstone at :45. So the owner cell of the card's table is already done; do not re-do it.
⚠️ That reading is two days old. Re-derive on current origin/main before editing — the card's own table may have moved again. Treat every figure in the card as a previous round's reading needing re-verification, not as fact.
DATA_SOURCE_WIDGET_TYPES is the fourth private copy of "which widgets need a DataSource", with a different member set from the form rules and zero gate. Three deliverables:
Single definition — core's EXPANDABLE_FIELD_TYPES as the reference half, plus a per-surface widget-hint extension.
Per-consumer normalization.
An identity pin — ⚠️assert the same object, not the same members. A member-identical private copy must fail the test. This is the whole point: a value-equality assertion would pass against exactly the defect this card exists to remove, which makes it worse than no test.
The card's own analysis of the tree / picker-hint divergences is the spec for which cells the shared table must and must not contain — those remain measured-but-asymptomatic and are not yours to resolve. Read that analysis before choosing membership.
Verification
Counter-probe every zero with a known-present neighbouring term.
Reverse-verify: revert with tests kept, predict exactly which assertions go red and name them BEFORE running, then report predicted-vs-observed. Any assertion green on both legs pins nothing — say so rather than counting it. In particular, prove the identity pin actually discriminates: a leg where a member-identical copy is substituted should go red.
State whether a build artifact sits between your edit and the thing under test, per leg — this spans two packages, so check whether the tests resolve @object-ui/core via the root vitest.config.mts alias to src or via package exports to dist.
Changeset: patch. ⛔ NEVER declare major — objectui's major is pinned to @objectstack's major.
⛔ Do not edit content/docs/releases/, docs/adr/**, .claude/**, skills/**, AGENTS.md, CLAUDE.md.
{
"issue": 4815,
"status": "done",
"branch": "claude/issue-4815-data-source-widget-types-convergence",
"pr": "https://github.com/objectstack-ai/objectui/pull/5314",
"premise_still_valid": true,
"summary": "Re-derived the card's table on current origin/main (de4e29a81) rather than trusting the two-day-old reading: the `owner` cell is indeed already done (USER_WIDGET_TYPES = new Set(['user']) with the #4814 tombstone above it), and the rest of the premise holds — DATA_SOURCE_WIDGET_TYPES was still a private union of LOOKUP_WIDGET_TYPES and USER_WIDGET_TYPES with three consumers and no gate. Delivered the #4790-shaped convergence: `widgetNeedsDataSource()` now reads core's EXPANDABLE_FIELD_TYPES and feeds all three consumers (isLookupishParam, fieldNeedsDataSource, and bulkParamToField's reference_to/display_field branch); core's expand-fields TSDoc gains the fourth consumer. No reachable behaviour change, verified rather than assumed: `tree` is the one differing cell and can never be a widget key here (absent from the fields widget map, mapFieldTypeToFormType sends it to field:lookup), and the three form-only widget-hint pickers are deliberately NOT absorbed — pulling them in would change which widgets get a DataSource, i.e. a behaviour change per the roll-back clause. Both boundaries are pinned by tests.",
"tests": "All at 455a274f6 (final commit, clean tree). UNION: `pnpm exec vitest run` (canonical root invocation) over 8 affected files — bulkParamToField, bulkActionDialogParams, bulkActionDialogRecord, bulkActionSchemaMultiple, bulkFanoutHostParams, core expand-fields, core unmaterialized-fields, form-data-source-wiring => `Test Files 8 passed (8) / Tests 80 passed (80)`; `pnpm --filter @object-ui/plugin-grid --filter @object-ui/core type-check` => both `Done` (script name echoed in the output, so not a zero-match silent pass); eslint on the 3 changed files => 0 errors (5 pre-existing no-explicit-any warnings on untouched lines); check:control-bytes / check:phantom-deps / check:self-import / check:esm-specifiers => pass; direct control-byte grep of the changed files => clean. REVERSE VERIFICATION, predicted before running, both legs matched exactly: Leg A (revert bulkParamToField.ts to origin/main, keep tests) predicted the 2 identity assertions red and 13 green, observed `Tests 2 failed | 13 passed (15)` with `AssertionError: expected [] to include 'lookup'` and `isLookupishParam never consulted the shared set`. Leg B — the discrimination leg — substituted a MEMBER-IDENTICAL copy (`new Set([...EXPANDABLE_FIELD_TYPES])`, members equal by construction), predicted the same 2 red, observed `Tests 2 failed | 13 passed (15)`; every membership-shaped assertion stayed green against that copy, which is the empirical proof that a toEqual-style pin would have passed ON the defect. Stated rather than counted: the other 3 new assertions are green on BOTH legs by design (normalization closure + the two deliberate boundaries) — they guard a future widening, not this convergence, and pin nothing about it. REBUILD QUESTION, per leg: no build artifact sits between any edit and the runner — the canonical root invocation loads vitest.config.mts, whose resolve.alias maps @object-ui/core to packages/core/src, and the test imports bulkParamToField relatively. Proved directly, not read off the config: with packages/core/dist moved aside entirely the run is still 15/15 green (and both earlier green runs predate any build — dist did not exist). Both red legs are therefore self-proving. The pin also holds under the other resolution regime (package-cwd run, @object-ui/core via package exports to dist): 15/15.",
"open_questions": [],
"out_of_scope_findings": [
"filed as #5312: app-shell's paramToField.ts:97 (`LOOKUP_WIDGET_TYPES.has(type) || type === 'user'`) is now the LAST private copy of this rule, and its 'moves in lockstep with plugin-grid's bulkParamToField twin' comment stopped being mechanically true the moment this PR landed the twin on core — asymptomatic today for the same reason (tree unreachable, owner retired), outside this card's file surface",
"filed as #5313: assertCanonicalVitestInvocation does not cover the 11 packages that own a standalone vitest.config.ts (plugin-grid among them) — measured, not inferred: `cd packages/plugin-grid && pnpm exec vitest run <file>` ran with Vitest root = the package dir and was NOT refused, contradicting the guard docstring's explicit universality claim; related to the open #3240 but not resolved by it"
]
}
Activity
os-support-ai commentedon Aug 18, 2026
Triage first-touch grade (concentrated batch; triage seat, session
session_01NYoiJGd1MxXdcvM4EGAMrS): promoted topm:queue, type Task — not blocked: the body'sBlocked-by: #4814is already satisfied (#4814 closed 08-17 via merged PR #4915, ruling A′ retired theownerspelling). Premise re-verified on the merged ref, not the card text:origin/main:packages/plugin-grid/src/components/bulkParamToField.ts:51now readsUSER_WIDGET_TYPES = new Set(['user'])with a tombstone comment at :45 — so theownercell of this card's table is done, and the remaining ask is exactly the #4790-shaped convergence: single definition (coreEXPANDABLE_FIELD_TYPESas the reference half + per-surface widget-hint extension), per-consumer normalization, and an identity pin (assert same object, so a member-identical private copy can't fake it).The
tree/ picker-hint divergences remain measured-but-asymptomatic; the card's own analysis of why is the spec for which cells the shared table must and must not contain. Size/model suggestion: S–M, sonnet/opus.Generated by Claude Code
os-support-ai commentedon Aug 19, 2026
Claim: PM loop round 15
Session:
session_01RV6yuVCxymHYE16PL9vQkEBranch:
claude/issue-4815-data-source-widget-types-convergenceWorktree:
objectui-issue-4815Domain:
repo:objectuiFile surface:
packages/plugin-grid/src/**+packages/core/src/**(the shared reference table) + their tests (stop on breach; explain in the report)Container & model: S–M,
mode:subagent,model: opus(taking the triage seat's upper suggestion — the identity-pin design is the hard part, not the edit)Clause-②: no — this converges private copies onto one definition. It changes no contract surface and widens nothing published. If your implementation turns out to change which widget types are treated as data-source-bearing anywhere, that is a behaviour change: stop and report it rather than absorbing it into a "convergence".
Serial constraints cleared:
packages/plugin-gridandpackages/coreare both free. Open PRs hold disjoint surfaces, each measured bygit diff --name-only origin/main...: PR #5290apps/console, PR #5294packages/plugin-view, PR #5295.github/workflows+scripts/+ root manifests, PR #5297packages/plugin-map, PR #5298packages/components+packages/types, PR #5300 / #5303packages/plugin-dashboard, PR #5302packages/cli, PR #5310packages/plugin-report(consumes@object-ui/corebut does not modify it — verified on its diff), PR #5311packages/plugin-form.Not blocked — verified, not assumed
The body carries
Blocked-by: #4814. That is satisfied: #4814 closed 2026-08-17 via merged PR #4915 (ruling A′ retired theownerspelling). The triage seat re-verified the premise on the merged ref rather than from the card text —origin/main:packages/plugin-grid/src/components/bulkParamToField.ts:51now readsUSER_WIDGET_TYPES = new Set(['user'])with a tombstone at:45. So theownercell of the card's table is already done; do not re-do it.origin/mainbefore editing — the card's own table may have moved again. Treat every figure in the card as a previous round's reading needing re-verification, not as fact.Scope — the #4790-shaped convergence
DATA_SOURCE_WIDGET_TYPESis the fourth private copy of "which widgets need a DataSource", with a different member set from the form rules and zero gate. Three deliverables:EXPANDABLE_FIELD_TYPESas the reference half, plus a per-surface widget-hint extension.The card's own analysis of the
tree/ picker-hint divergences is the spec for which cells the shared table must and must not contain — those remain measured-but-asymptomatic and are not yours to resolve. Read that analysis before choosing membership.Verification
@object-ui/corevia the rootvitest.config.mtsalias tosrcor via package exports todist.Changeset:
patch. ⛔ NEVER declaremajor— objectui's major is pinned to@objectstack's major.⛔ Do not edit
content/docs/releases/,docs/adr/**,.claude/**,skills/**,AGENTS.md,CLAUDE.md.Generated by Claude Code
refactor(plugin-grid,core): the bulk dialog's data-source rule derive…
os-support-ai commentedon Aug 19, 2026
{ "issue": 4815, "status": "done", "branch": "claude/issue-4815-data-source-widget-types-convergence", "pr": "https://github.com/objectstack-ai/objectui/pull/5314", "premise_still_valid": true, "summary": "Re-derived the card's table on current origin/main (de4e29a81) rather than trusting the two-day-old reading: the `owner` cell is indeed already done (USER_WIDGET_TYPES = new Set(['user']) with the #4814 tombstone above it), and the rest of the premise holds — DATA_SOURCE_WIDGET_TYPES was still a private union of LOOKUP_WIDGET_TYPES and USER_WIDGET_TYPES with three consumers and no gate. Delivered the #4790-shaped convergence: `widgetNeedsDataSource()` now reads core's EXPANDABLE_FIELD_TYPES and feeds all three consumers (isLookupishParam, fieldNeedsDataSource, and bulkParamToField's reference_to/display_field branch); core's expand-fields TSDoc gains the fourth consumer. No reachable behaviour change, verified rather than assumed: `tree` is the one differing cell and can never be a widget key here (absent from the fields widget map, mapFieldTypeToFormType sends it to field:lookup), and the three form-only widget-hint pickers are deliberately NOT absorbed — pulling them in would change which widgets get a DataSource, i.e. a behaviour change per the roll-back clause. Both boundaries are pinned by tests.", "tests": "All at 455a274f6 (final commit, clean tree). UNION: `pnpm exec vitest run` (canonical root invocation) over 8 affected files — bulkParamToField, bulkActionDialogParams, bulkActionDialogRecord, bulkActionSchemaMultiple, bulkFanoutHostParams, core expand-fields, core unmaterialized-fields, form-data-source-wiring => `Test Files 8 passed (8) / Tests 80 passed (80)`; `pnpm --filter @object-ui/plugin-grid --filter @object-ui/core type-check` => both `Done` (script name echoed in the output, so not a zero-match silent pass); eslint on the 3 changed files => 0 errors (5 pre-existing no-explicit-any warnings on untouched lines); check:control-bytes / check:phantom-deps / check:self-import / check:esm-specifiers => pass; direct control-byte grep of the changed files => clean. REVERSE VERIFICATION, predicted before running, both legs matched exactly: Leg A (revert bulkParamToField.ts to origin/main, keep tests) predicted the 2 identity assertions red and 13 green, observed `Tests 2 failed | 13 passed (15)` with `AssertionError: expected [] to include 'lookup'` and `isLookupishParam never consulted the shared set`. Leg B — the discrimination leg — substituted a MEMBER-IDENTICAL copy (`new Set([...EXPANDABLE_FIELD_TYPES])`, members equal by construction), predicted the same 2 red, observed `Tests 2 failed | 13 passed (15)`; every membership-shaped assertion stayed green against that copy, which is the empirical proof that a toEqual-style pin would have passed ON the defect. Stated rather than counted: the other 3 new assertions are green on BOTH legs by design (normalization closure + the two deliberate boundaries) — they guard a future widening, not this convergence, and pin nothing about it. REBUILD QUESTION, per leg: no build artifact sits between any edit and the runner — the canonical root invocation loads vitest.config.mts, whose resolve.alias maps @object-ui/core to packages/core/src, and the test imports bulkParamToField relatively. Proved directly, not read off the config: with packages/core/dist moved aside entirely the run is still 15/15 green (and both earlier green runs predate any build — dist did not exist). Both red legs are therefore self-proving. The pin also holds under the other resolution regime (package-cwd run, @object-ui/core via package exports to dist): 15/15.", "open_questions": [], "out_of_scope_findings": [ "filed as #5312: app-shell's paramToField.ts:97 (`LOOKUP_WIDGET_TYPES.has(type) || type === 'user'`) is now the LAST private copy of this rule, and its 'moves in lockstep with plugin-grid's bulkParamToField twin' comment stopped being mechanically true the moment this PR landed the twin on core — asymptomatic today for the same reason (tree unreachable, owner retired), outside this card's file surface", "filed as #5313: assertCanonicalVitestInvocation does not cover the 11 packages that own a standalone vitest.config.ts (plugin-grid among them) — measured, not inferred: `cd packages/plugin-grid && pnpm exec vitest run <file>` ran with Vitest root = the package dir and was NOT refused, contradicting the guard docstring's explicit universality claim; related to the open #3240 but not resolved by it" ] }Generated by Claude Code
Generated by Claude Code
refactor(app-shell): paramToField's reference-bearing rule derives fr…
refactor(plugin-grid,core): the bulk dialog's data-source rule derive…
refactor(app-shell): paramToField's reference-bearing rule derives fr…