Repository navigation
showcase my-work: the personal work queue authors filters: (plural) and no $filter ever reaches the wire — the grid lists every row #7750
Description
Activity
- addedbugSomething isn't workingSomething isn't working
on Aug 11, 2026 Claimed —
domain:metadataseat.- Session:
session_01BaTeBCjaoTDmDWFVmSY2jL - Branch:
claude/issue-7750-my-work-filter-spelling - Worktree:
../objectstack-7750(dedicated) - File surface:
examples/app-showcase/src/ui/pages/my-work.page.ts— the fix is one word,filters:→filter:.
The one-word fix is not the interesting part; the verification bound is, and the dispatch requires it stated honestly rather than papered over. objectui#4041 (
9154d9e) retired the plural spelling and pinned that the declaredfilterreaches$filter— but it landed after the console pin this run served (09987b680), so on a console built at the old pinfilterwas not yet a reachable declared input. End-to-end verification therefore depends on the vendoredpackages/console/distbeing rebuilt (#7752).So the dev checks which pin the worktree vendors: if it carries
9154d9e, drive the page and show$filteron the wire before and after. If it does not, ⛔ no fabricated end-to-end claim and ⛔ no rebuilding the vendored console to manufacture one — report the bound, pin what is checkable inside this repo, and reference #7752.Premise re-verification required before implementing: that line 52 still reads
filters:on currentmain, and thatfiltersreally does appear exactly once across the showcase while every other page usesfilter. If other sites exist, the card is under-scoped and that is worth knowing before one line is changed.Scope, carried verbatim so nobody over-escalates it: ⛔ this is not an authorization bypass — the unfiltered read is still RLS-constrained and the caller sees only rows they may see. The defect is that a declared personal-scope filter silently never applies. ⛔ Not to be relabelled as a security fix.
⛔ #7751 is out of scope — the general problem (a typo'd key accepted without complaint) is the larger card and is filed separately. Not folded in, and no validation added to the block schema here.
Generated by Claude Code
- Session:
{ "issue": 7750, "status": "done", "branch": "claude/issue-7750-my-work-filter-spelling", "pr": "https://github.com/objectstack-ai/objectstack/pull/7764", "premise_still_valid": true, "summary": "One word in examples/app-showcase/src/ui/pages/my-work.page.ts: the personal work queue's object-grid authored the plural `filters:` and now authors `filter:`, the key the block both publishes and reads. Premise confirmed on origin/main (8f1851e): line 52 still read `filters:`, and at the repo-root pin .objectui-sha=6314e87f2 the renderer declares `{ name: 'filter' }` (plugin-grid/src/index.tsx:117), reads schema.filter (ObjectGrid.tsx:472) plus legacy schema.defaultFilters (655-657), with ZERO occurrences of schema.filters. ONE SUB-CLAIM OF THE CARD IS IMPRECISE AND THE CORRECTION IS WORTH KEEPING: `filters` does NOT appear exactly once in the showcase — it appears at three other authored sites, all of which are legitimate DECLARED plural keys on different surfaces (ObjectNavItem.filters, spec/src/ui/app.zod.ts:421; react-tier ListView filters, spec/src/ui/react-blocks.ts:217). Read as 'exactly one object-grid authors the plural' the card holds and the fix is correctly one line; read literally it does not. The vocabulary genuinely splits by tier, which is why the typo was easy to make — context for #7751, not fixed here. Scope held: no validation added to the block schema, #7751 untouched, and this is NOT relabelled as an authorization bypass (the unfiltered read stayed RLS-constrained; the defect is that a declared personal-scope filter silently never applied).", "tests": "VERIFICATION BOUND, STATED HONESTLY — NO END-TO-END CLAIM. packages/console/dist/ is gitignored and ABSENT from a fresh clone, so this worktree vendors no console at all; producing one means rebuilding it, which the card prohibits as a way to manufacture an E2E claim. Tracked as #7752. No run in this repo can show $filter on the wire until that lands. WHAT WAS CHECKABLE WAS MEASURED, NOT ASSUMED: the card's pin-ancestry claim holds — GET /repos/objectstack-ai/objectui/compare/9154d9e...6314e87f2 returns status=ahead, behind_by=0, merge_base=9154d9e90f9c, so objectui#4041 IS an ancestor of the repo-root pin; the plugin-grid sources quoted above were read at that exact pin. || LOCAL RUNS: `pnpm --filter @objectstack/example-showcase test` -> 'Test Files 20 passed (20) / Tests 189 passed (189)'. `typecheck` (tsc --noEmit) -> clean, no output. Build closure `pnpm --filter '@objectstack/example-showcase^...' build` -> green (SUFFIX form = upstream dependencies, the correct direction for a build closure; no downstream consumer sweep was needed, this change exports nothing). Full package build per the ratchet's own named fix -> 'Tasks: 70 successful, 70 total'. || RATCHETS (the card flagged these): `pnpm check:type-check-debt` first REFUSED naming its own fix ('cannot run: 1 workspace dependency ... has no built type entry point'), so the workspace was built and it was re-run -> '33 ledger entries re-measured, 1786 raw tsc errors total, NONE ABOVE ITS RECORDED NUMBER'. NO LEDGER RAISED; the 10 'can be lowered' lines are pre-existing surplus, deliberately left untouched. `pnpm check:query-options-erasure` -> 'ratchet holds: 67 unswept non-test sites, none new; baseline key set verified against 8f1851e: no files added'. `node scripts/check-nul-bytes.mjs` -> OK (7124 files), plus a targeted control-byte self-scan of both changed files -> clean. || TEST_DEBT was avoided by DESIGN: the three pins were added to the EXISTING examples/app-showcase/test/my-work-visibility.test.ts, not a new file. || REVERSE VERIFICATION, direction predicted BEFORE running as ordinary 'Red' (the assertions read the authored key directly, so no ??-chain inversion applies) — prediction held exactly: reverting the page to origin/main turned ALL THREE new pins red while the four pre-existing tests stayed green: 'x authors `filter` (singular) -> expected {objectName: showcase_task, ...} to have property \"filter\"' / 'x carries no spelling the renderer drops -> `filters` is not the key object-grid reads' / 'x still scopes the queue to the signed-in user -> expected undefined to deeply equal [[owner_id, =, ...]]' / 'Test Files 1 failed (1) Tests 3 failed | 4 passed (7)'. Fix restored via `git checkout HEAD -- <path>` (NEVER git stash), tree clean, suite green again at 189/189. || ONE ESLINT FINDING IS PRE-EXISTING, NOT MINE: '58:3 Definition for rule @typescript-eslint/no-implied-eval was not found' reproduces BYTE-IDENTICALLY on the unmodified origin/main copy of the same file, and line 58 sits above every line this PR adds. || CI GATE STATUS AT REPORT TIME, RECORDED HONESTLY: in_progress. On head 10eb592c, ESLint = in_progress and TypeScript Type Check = in_progress — the two gates the PM reads. Already green: Check Changeset (success — the skip-changeset label landed ahead of its re-read), Console Pin Freshness, ADR maintainer approval, Check PR Size, Check Documentation Links, 'No other open PR may claim the same issue'. Still running: Build Core, Test Core (1-3/3), Dogfood Regression Gate (1-3/3), Dogfood Verify CLI, Temporal Conformance. Per the draft-PR-time reporting contract I did NOT idle-poll CI.", "changeset": "NONE — skip-changeset label applied instead, and read back. @objectstack/example-showcase is private:true and absent from the `fixed` group in .changeset/config.json (verified: 0 occurrences), so a showcase-only change releases nothing. Same call #7568 made earlier today on this package. Label written as a UNION read-back, never a bare set; final read-back after the bots settled: ['size/s', 'tests', 'skip-changeset'].", "open_questions": [], "out_of_scope_findings": [ "NOT FILED as a new issue, deliberately — it belongs to the already-open #7751 and filing discipline says comment on a hit rather than open a twin, while this card says #7751 is out of scope. Recorded here for the PM to route: the plural/singular split is real VOCABULARY drift across tiers, not just one author's typo. `object-grid` declares `filter` (singular), while `ObjectNavItem.filters` (spec/src/ui/app.zod.ts:421) and the react-tier `ListView.filters` (spec/src/ui/react-blocks.ts:217) both declare the plural — so an author moving between tiers on the same page is switching spelling with no signal. Worth noting for #7751: the spec ALREADY has the loud-rejection pattern this needs — the context-selector `optionsSource` (spec/src/ui/app.zod.ts:1066) is a strictObject carrying `aliases: { filters: 'filter', where: 'filter' }`, which rejects the typo by name with the fix in the message. SDUI blocks get none of it because `object-grid` is not in `ComponentPropsMap` at all and `packages/lint/src/validate-component-props.ts` SKIPS unregistered types by design (documented in its own header, lines 84-95) — that skip is the exact hole #7751 describes." ] }
Generated by Claude Code
- added a commit that references this issue
on Aug 11, 2026 ACCEPT — patch verified, PR #7764 flipped ready, auto-merge armed.
The patch is what I asked for and slightly better. Rather than reword one shared string, you split the shared assertion into per-key
{ key, why }pairs so each spelling carries its own reason, and the new JSDoc states the distinction outright —filtersis DEAD (zero read points, dropped before the wire),defaultFiltersis ALIVE (the legacy pathobject-gridstill reads and lowers to$filter, pinned absent because this page authors the current key, not because the legacy one is inert). The added warning is the part that will actually do work later: a future author debugging a filter bug must not read this test as licence to treatdefaultFiltersas a no-op nor reach for it as a workaround. Both failure directions, named.Confirmed the constraints held: the page fix is byte-identical, no assertion's truth value changed, and the diff is still the same two files.
Your correction to the card's "exactly once" sub-claim stands as the record.
filtersappears at three other authored sites in the showcase, all legitimate declared plural keys on other surfaces (ObjectNavItem.filters, react-tierListView.filters). The card is correctly scoped, but not for the reason it gave — read literally the claim is false, read as "exactly oneobject-gridauthors the plural" it holds. Reporting that instead of quietly smoothing it over is what let it become useful downstream.And it was useful downstream. I routed the vocabulary-drift finding to #7751 rather than opening a twin, with all three of its claims verified against
origin/mainfirst. I also added the consequence you didn't state, which changes what closing #7751 costs:validate-component-props.ts's skip of unregistered types is deliberate and load-bearing — its own header says so, and turning it off would fail 87 legitimate nodes. So the hole is upstream of the lint rule, in SDUI block props not being knowable to this repo's linter, and the existingoptionsSourcealias machinery only helps once they are.The verification bound was the right call and I want it on record as such.
packages/console/dist/is gitignored and absent from a fresh clone, so no run in this repo can show$filteron the wire until #7752 lands. You measured what was checkable — the pin ancestry, viacompare/9154d9e...6314e87f2returningstatus: ahead, behind_by: 0— and declined to manufacture the rest. A fabricated end-to-end claim here would have been worth less than no claim, because it would have retired the card while leaving the actual gap unmeasured.Changeset skip independently re-verified:
@objectstack/example-showcaseisprivate: trueand appears zero times in thefixedgroup.Close-out on merge: archive
session_01BaTeBCjaoTDmDWFVmSY2jL.
Generated by Claude Code
- added a commit that references this issue
on Aug 17, 2026 - added a commit that references this issue
on Oct 7, 2026
Symptom
The showcase's personal work queue is not personal. Open
/_console/apps/showcase_app/page/showcase_my_workwith the network recorder on, having first created a task owned by another user.$filter=[["owner_id","=","<current user>"]]on the grid's query.$filterat all, and the grid lists every row including the foreign-owned probe.Reproduced twice with fresh logins. Contrast on the same run:
active-projects'interfaceConfig.filterBydoes reach the wire, so the page-level plumbing is fine.Scope, stated precisely
Carried verbatim from the run so nobody over-escalates it:
The general half is filed separately as #7751.
Root cause — a key-name mismatch
examples/app-showcase/src/ui/pages/my-work.page.ts:52authors the plural key:objectui's
ObjectGridreads onlyschema.filter(packages/plugin-grid/src/ObjectGrid.tsx:472, lowered throughtoFilterNode) and the legacyschema.defaultFilters(line 657).schema.filtershas zero read points in that file.filtersappears exactly once in the whole showcase — this line; every other page usesfilter.Stale-premise check. Re-verified on
objectstackorigin/main(00e9196): line 52 still readsfilters:. Re-verified onobjectuiorigin/main(33c32bf): the renderer still reads onlyfilter/defaultFilters, andschema.filtersstill has no reader — so this is not a stale-bundle artefact.New since the run, and it changes the fix. objectui#4041 (commit
9154d9e, 2026-08-10) retired the plural spelling from the block's published vocabulary:packages/plugin-grid/src/index.tsx:117now declares{ name: 'filter', type: 'array', label: 'Filter' }, withgridFilterInputSpelling.test.tsxpinning that the declared name reaches$filter. At the time this page was authored,filterswas whatobject-gridpublished, so the author was following the manifest — that excuse is now gone, and the one-word fix (filters:→filter:) lands on the declared, pinned, lowered path.9154d9elanded after the console pin this run served (09987b680, 2026-08-09) and is present in the repo-root pin6314e87f2. On a console built at the old pin,filterwas not yet a reachable declared input, so the fix cannot be verified end-to-end until the vendoredpackages/console/distis rebuilt — see #7752.Reproduction
showcase_taskowned by user B./_console/apps/showcase_app/page/showcase_my_workwith the network recorder on.$filterparameter.Source
Extracted from the QA run #7695 (framework 92f26f7, console 09987b680).