Repository navigation
Description
Run record for the 18.0 release sweep, selector search (resolved with node scripts/checklist-select.mjs area:search --json), plan B (Tier 1 + Tier 2; Tier 3 deferred).
Environment fingerprint
- framework:
5b14b7f3ad8e2e0786d228772f473d07b36b2477(objectstack-ai/objectstack main), working tree clean - console:
.objectui-sha=4016370af3c9c9dafec2bc5299afd8e8079701b8, built withpnpm objectui:build;packages/console/dist/.objectui-shastamp equals the pin (pnpm check:console-shagreen), so the stale-console-bundle trap is ruled out for every console observation - app: showcase (examples/app-showcase), canonical boot
OS_PORT=PORT pnpm -C examples/app-showcase exec objectstack dev --ui --seed-admin -p PORT -d file:/tmp/qa18/ITEM/data.db; every hand-driven item had its own port and file DB (listed per item below); seed:--seed-admin(admin@objectos.ai) + showcase seed + per-item scratch fixtures - Tier 1 pins: vitest per package against the same tree (
pnpm exec vitest run FILES), 97 framework files / 2209 tests, 0 failed; objectui-side pins run inside a clone of objectui at4016370af3c9(unit vitest +playwright.live.config.tsagainst a showcase boot on :47431 through the objectui console dev server), RUNNER option (b) - browser: Playwright with
/opt/pw-browsers/chromium, own context per persona, sign-in through the form - timestamps: 2026-10-19, environment prep 12:26–12:43 UTC, testing 12:43–13:53 UTC; Tier 2 items were driven in parallel by sub-runners (≤ 3–4 browser items at once), each on its own port/DB
Scope
Selector search → 8 runnable item(s). Blocked items hidden by the resolver were not run (no --include-blocked).
Tiering (checklist-test SKILL §1): Tier 1 = item carries automated.ref (pin run, cited); Tier 2 = unpinned P0/P1 (hand-driven); Tier 3 = unpinned P2 (deferred, not-run).
| item | priority | surface | tier | revision | item verdict |
|---|---|---|---|---|---|
search.cross-field-object-search |
P1 | api | 1 | 3 | pass |
search.field-scoped-narrowing |
P1 | api | 1 | 1 | pass |
search.rls-both-personas |
P1 | api | 2 | 7 | pass |
search.pinyin-flag-both-sides |
P1 | mixed | 2 | 4 | pass |
search.freshness-and-empty |
P2 | mixed | 3 | 1 | not-run |
search.console-global-search |
P1 | mixed | 2 | 4 | pass |
search.command-palette-navigation |
P2 | browser | 3 | 3 | not-run |
search.global-search-skips-unreadable |
P1 | api | 1 | 2 | partial |
Per-clause verdicts
A = acceptance[n], N = negative[n]. Tier 1 rule: a clause is pass only when a passing pin covers it (server-side oracles, or clauses the ref names); clauses a ref says it does not cover, and UI-oracle clauses a server-side pin cannot see, are not-run. Evidence is text from the oracle — no images.
search.cross-field-object-search — pass (Tier 1 pin)
| clause | verdict | evidence |
|---|---|---|
| A0–N2 | pass | pin: showcase-search.dogfood.test.ts 5/5 passed |
search.field-scoped-narrowing — pass (Tier 1 pin)
| clause | verdict | evidence |
|---|---|---|
| A0–N1 | pass | pin: showcase-search.dogfood.test.ts 5/5 passed |
search.rls-both-personas — pass (hand-driven (port 47404 · file:/tmp/qa18/search-rls/data.db · member via invite-member → sign-up → admin POST /api/v1/data/sys_user_position {position contributor}))
| clause | verdict | evidence |
|---|---|---|
| A0 | pass | member GET INV-1003 → 404; member POST /api/v1/data/showcase_invoice/query {search:INV-1003} → 200 total 0; identical admin search → total 1 |
| A1 | pass | member owns 4 rows; paged search limit 2 → total 4 on every page, 4 distinct rows, never 16 |
| A2 | pass | member-created INV-QA-RLS found by the member's search, total 1 |
| A3 | pass | deny + allow + own-rows + paged totals evidence set captured per persona (identity re-proven via get-session before each cell) |
| N0–N1 | pass | no hit or total inflation for the member; deny side run as the member |
search.pinyin-flag-both-sides — pass (hand-driven (ports 47501 (OS_SEARCH_PINYIN_ENABLED=false) / 47502 (unset — zh-CN default ON) · file:/tmp/qa18/pinyin-off/data.db, file:/tmp/qa18/pinyin-on/data.db · OS_LOG_LEVEL=debug))
| clause | verdict | evidence |
|---|---|---|
| A0 | pass | ON: POST /api/v1/data/showcase_contact/query {search} zhangwei → [张伟], zw → [张伟], 张 → [张伟], wf → [王芳]; showcase_account huaning / hnkj / 华 → [华宁科技]; schema carries __search |
| A1 | pass | ON contrast: a contact with Latin name and company 华宁科技 — hnkj → 0 rows (company initials give no recall), huaning → 3 seeded rows via email, not the new row; 华宁 → 4 rows incl. the new row via company |
| A2 | pass | OFF: zw → 0, wf → 0, hnkj → 0; 张 → [张伟]; zhangwei / wangfang / huaning hit through Latin email columns only; no __search key; all 200 |
| A3 | pass | banner Plugins: 52 loaded (OFF) vs 53 (ON); roster diff is exactly PinyinSearchPlugin; OFF debug log has 0 pinyin lines outside the runner's own DB path |
| A4 | pass | ON log: [pinyin-search] companion hooks bound … then companion backfill complete {objects:67, scanned:168, updated:4}; first-boot recall needed no manual rebuild |
| N0–N1 | pass | no 500 on any OFF latin search; zw and zhangwei each verified separately on ON |
search.freshness-and-empty — not-run (Tier 3)
| clause | verdict | evidence |
|---|---|---|
| A0–A5, N0–N1 | not-run | Tier 3 deferred by the 18.0 release-sweep plan |
search.console-global-search — pass (hand-driven (port 47503 · file:/tmp/qa18/console-search/data.db · contributor member via the qa-contributor-bound-member recipe))
| clause | verdict | evidence |
|---|---|---|
| A0 | pass | Ctrl+K, Meta+K, header button, ?palette=1 and ?cmdk=1 each open the single command-palette overlay; header button while open stays open (idempotent); Escape strips the param; repeated Ctrl+K toggles closed by design (see accuracy finding) |
| A1 | pass | typing zhangwei sends GET /api/v1/search?q=zhangwei&limit=24&objects=… → 200; zero per-object fanout |
| A2 | pass | admin: zhangwei → 张伟 under Contact; huaning → 4 hits in Account and Contact sections; 张伟 and zw → 张伟 |
| A3 | pass | Enter on the default-selected top hit navigates to /_console/apps/com.example.showcase/showcase_contact/record/ID and the record page renders |
| A4 | pass | empty palette shows Recently viewed (张伟 Contact, 华宁科技 Account); empty input and 1-character input fire zero /api/v1/search requests |
| A5 | pass | member GET /api/v1/search?q=INV-1003 → 200 hits [] totalHits 0; palette No results found; member own-row control INV-QA-CS → own invoice; admin same query → INV-1003 invoice + line |
| A6 | pass | /apps/com.example.showcase/search?q=huaning → GET /api/v1/search 200, page reads 4 results with Account (1) and Contact (3) groups; no-hit query → designed empty state; zero console errors in this phase |
| N0–N4 | pass | no invisible-row hit or count leak for the member; per-object headings; empty input shows recents with no request; Enter navigates; deny side run as the member |
search.command-palette-navigation — not-run (Tier 3)
| clause | verdict | evidence |
|---|---|---|
| A0–A5, N0–N4 | not-run | Tier 3 deferred by the 18.0 release-sweep plan |
search.global-search-skips-unreadable — partial (Tier 1 pin)
| clause | verdict | evidence |
|---|---|---|
| A0–A2 | pass | pin: search-skip-unreadable.dogfood.test.ts 4/4 passed; protocol.search-skip-unreadable.test.ts 12/12 passed |
| A3, A4 | not-run | not covered by pin (ref: row scope (A3) and hidden-field (A4) have no end-to-end pin); not hand-driven in this Tier 1 pass |
| N0–N2 | pass | pin: search-skip-unreadable.dogfood.test.ts 4/4 passed; protocol.search-skip-unreadable.test.ts 12/12 passed |
| N3 | not-run | not covered by pin (ref: row scope (A3) and hidden-field (A4) have no end-to-end pin); not hand-driven in this Tier 1 pass |
| N4, N5 | pass | pin: search-skip-unreadable.dogfood.test.ts 4/4 passed; protocol.search-skip-unreadable.test.ts 12/12 passed |
Reproduction rules
No fail in this selector.
Derived item verdicts
5 pass · 1 partial (search.global-search-skips-unreadable: row scope A3 and the hidden-field case A4 have no end-to-end pin and were not hand-driven in this Tier 1 pass — the ref's own knownGaps) · 2 not-run (Tier 3).
Checklist-accuracy findings / fixture gaps (for the wave anchor card)
search.console-global-searchacceptance[0] says opening when already open is a no-op "not a toggle-closed" beside ⌘K/Ctrl+K; by source design (objectui CommandPaletteProvider) the keyboard accelerator toggles and only buttons, links, deep-links and programmatic callers are idempotent — scope the idempotence to the non-keyboard affordances or a runner will score the toggle as a FAIL.search.console-global-searchstep 3 / acceptance[2] suggest the palette query张: one character is below the palette's minLength 2, never reaches the wire and shows "No results found." — use张伟.- Area recipe
search:qa-contributor-bound-member: step 5 should name the invoice-number fieldname(number→ 400 INVALID_FIELD) and give a seeded account id example; the "system context" of steps 2–3 works as an admin REST read ofsys_userplus adminPOST /api/v1/data/sys_user_position {user_id, position: "contributor", organization_id}(sys_positionis not a registered object; position is plain text). search.pinyin-flag-both-sides: the roster now reads 52 loaded (flag off) vs 53 (on) at 5b14b7f (was 51/52); the one-plugin difference is what the clause scores. Neither boot prints a literalrequireslist — the banner roster is the readable form. The lookup-picker part of step 5 was not exercised.
Hand-off (items without a judged verdict)
search.freshness-and-empty(P2) — not-run: Tier 3 deferred by the 18.0 release-sweep plan.search.command-palette-navigation(P2) — not-run: Tier 3 deferred by the 18.0 release-sweep plan.
Generated by Claude Code
Activity
objectstack-fleet commentedon Oct 19, 2026
Parked-on: #24579 · this record's checklist-accuracy findings, fixture gaps, partial coverage gaps and not-run handover (wave anchor §2–§4)
Generated by Claude Code
objectstack-fleet commentedon Oct 19, 2026
Superseded-by: #24593
Round 2 at ba4afcc re-judged this record's unjudged A-class clauses (
search.global-search-skips-unreadableacceptance[3], [4], negative[3] — all pass) and carried every other verdict forward to #24593 (Carried-forward:lines there, valid for 5b14b7f).Generated by Claude Code
docs(qa): 18.0 sweep anchor round 4 — search's palette minLength and …