Skip to content

QA run · area:records-forms (40/40) · 94114c1f · 2026-10-16 · 39 PASS / 1 PARTIAL / 0 FAIL / 0 BLOCKED / 0 NOT-RUN #23949

Closed

Description

@objectstack-fleet

Run record for the full-checklist wave anchored on #23878 (selector all, run per area). Runner session session_01K3qUoyh1xFGoWzAACPMbXJ, dispatched by the domain:devx seat 1 PM. Protocol: .claude/skills/checklist-test/SKILL.md + docs/qa/platform-checklist/RUNNER.md.

Environment fingerprint

  • framework: 94114c1f269f6b3d885f24b6f4689dce29504574 (origin/main at run start; pnpm install --frozen-lockfile && pnpm build, 75/75 green)
  • resolver: node scripts/checklist-select.mjs all at that sha → 272 runnable · 2 blocked hidden · 1 planned
  • .objectui-sha: daeb77fc84dd824e74c95b87cdede85afdb248e7. ⚠ pnpm objectui:build FAILS on this sha (Console pin does not build on main: objectui daeb77fc imports checkPageComponentViewData, deleted from spec by #23784 #23908). Browser/mixed verdicts ran on a console built at that same pin against @objectstack/spec from a35f7a67^ (the commit before the deletion), served from a linked worktree at 94114c1f with identical framework dists. check:console-sha matches.
  • app: showcase · boot OS_PORT=P objectstack dev --ui --seed-admin -p P -d file:…/data.db · per-runner port and DB · seeded admin + demo personas
  • browser: Playwright 1.63 on /opt/pw-browsers/chromium (Chromium 141), one context per persona
  • timestamp: 2026-10-16 (UTC) · runners:
  • g15 records-forms-1: ports [41280] · sequential · env 9 min / test 64 min
  • G16 records-forms-2: ports [41300] · sequential · env 6 min / test 59 min

Scope

Selector area:records-forms (from the all resolution) · 40 runnable item(s):

  • records-forms.crud-roundtrip r9 · P0 · browser → pass
  • records-forms.field-type-matrix r2 · P1 · mixed → pass
  • records-forms.list-view-capabilities r2 · P1 · browser → pass
  • records-forms.view-type-gallery r1 · P1 · browser → pass
  • records-forms.form-view-gallery r3 · P1 · browser → pass
  • records-forms.conditional-rules-header r2 · P1 · mixed → pass
  • records-forms.conditional-rules-grid r3 · P1 · browser → pass
  • records-forms.cascading-options r3 · P1 · mixed → pass
  • records-forms.master-detail-atomic-save r3 · P1 · browser → pass
  • records-forms.related-list-server-pagination r4 · P1 · browser → pass
  • records-forms.action-param-widgets r2 · P1 · mixed → pass
  • records-forms.upload-guard-blocks-confirm r2 · P2 · browser → pass
  • records-forms.import-wizard-encoding-and-hints r6 · P2 · browser → pass
  • records-forms.action-location-matrix r10 · P1 · browser → pass
  • records-forms.validation-rule-type-matrix r2 · P1 · api → pass
  • records-forms.gantt-interactions r4 · P2 · browser → partial
  • records-forms.kanban-drag-persistence r1 · P2 · browser → pass
  • records-forms.form-dirty-guard r3 · P2 · browser → pass
  • records-forms.named-import-mapping r1 · P2 · api → pass
  • records-forms.adhoc-filter-sort-builder r2 · P1 · browser → pass
  • records-forms.calendar-interactions r2 · P1 · browser → pass
  • records-forms.concurrent-edit-conflict r2 · P1 · mixed → pass
  • records-forms.record-discussion-mentions r3 · P1 · browser → pass
  • records-forms.grid-personalization r3 · P2 · browser → pass
  • records-forms.saved-view-management r2 · P2 · browser → pass
  • records-forms.bulk-select-all-matching r3 · P2 · browser → pass
  • records-forms.lookup-picker-create-new r2 · P2 · browser → pass
  • records-forms.import-job-undo-cancel r3 · P2 · mixed → pass
  • records-forms.object-hook-lifecycle r4 · P1 · mixed → pass
  • records-forms.field-type-constraints r1 · P1 · mixed → pass
  • records-forms.cascading-multilevel-and-clear r2 · P1 · mixed → pass
  • records-forms.encrypted-field-behavior r2 · P1 · mixed → pass
  • records-forms.field-group-visible-when r3 · P1 · mixed → pass
  • records-forms.field-unique-enforcement r2 · P1 · api → pass
  • records-forms.delete-behavior-matrix r1 · P1 · api → pass
  • records-forms.record-clone-contract r1 · P2 · api → pass
  • records-forms.field-history-tracking r1 · P1 · mixed → pass
  • records-forms.import-transform-matrix r2 · P2 · api → pass
  • records-forms.predicate-relationship-traversal r2 · P1 · api → pass
  • records-forms.script-action-hook-refusal-toast r1 · P2 · browser → pass

Blocked and hidden by the resolver (not driven): records-forms.record-edit-undo. Each carries its own blocked fixture reason in the ledger.

Planned (not runnable, not counted): records-forms.picklist-shared-across-objects.

Per-clause verdicts

item # clause (short) verdict evidence
crud-roundtrip 0 create returns id; re-read verbatim pass UI POST /data/showcase_account 201 body {name,industry:finance,status:active,sales_region:amer}; filtered GET n=1 same values, website null
crud-roundtrip 1 update persists only edited field pass PATCH body {"annual_revenue":1234567} 200; full-row diff = annual_revenue null→1234567 + updated_at only
crud-roundtrip 2 delete authoritative pass row menu Delete + alertdialog confirm → DELETE 200; filtered GET records 0 total 0
crud-roundtrip 3 list reflects mutations after reload pass post-reload list showed the new row (1 hit); after delete the reloaded list + quick-search shows only the -华宁/-clone rows
crud-roundtrip 4 History shows display values pass History tab: UPDATE "Annual Revenue: — → 1234567"; CREATE "Industry: Finance / Lifecycle: Active / Sales Region: AMER", actor Dev Admin; no value→null rows
crud-roundtrip 5 unicode round-trip + searchable pass name os-qa-g15-…-华宁 re-read identical; $search 华宁 → [华宁科技, the new row]; UI search huaning finds both
crud-roundtrip 6 clone 201 new id, values copied, engine cols re-derived, owned by cloner pass clone 201 id≠sourceId, sourceId=source; business fields equal, id/created_at/updated_at differ; clone by org-admin persona → owner_id=cloner; readonly half: pins 11+21 passed
crud-roundtrip 7 clone RLS-gated 404 pass contributor-bound member: GET INV-1003 404 RECORD_NOT_FOUND, list 0 then 1 own row; POST INV-1003/clone → 404 RECORD_NOT_FOUND; admin invoice count 14→14
field-type-matrix 0 HTTP round-trip matrix (pin) pass field-zoo-roundtrip + value-shape in the dogfood batch: 101 passed, 0 failed; matrix declares no xfail rows
field-type-matrix 1 per-variant widget table pass 48 f_* controls typed on Specimen Full (date→input[date], color→input[color], file→input[file], signature→canvas, rating→stars…; table in zoo-table.txt); autonumber read-only on detail
field-type-matrix 2 constrained types reject server-side pass f_select not-a-value → 400 invalid_option; name "" → 400 required; zoo count 2→2
field-type-matrix 3 credentials masked on read pass pin masked checks pass; raw GET f_password "••••••••", f_secret "••••••••" (dev boot has a CryptoProvider; secret write 201)
field-type-matrix 4 computed/system materialize pass created zoo row: f_formula 31.5 (42×75/100), f_autonumber "0004"
field-type-matrix 5 relational types refuse dangling id pass fabricated f_lookup / f_master_detail / f_tree → 400 reference_not_found each; pin round-trips real ids
field-type-matrix 6 summary on real carriers pass INV-1001..1004 total == sum(line.amount) (1619.96/198/299.94/450); EXP-2001 total 1500.5 approved 960
list-view-capabilities 0 per-variant evidence pass 11 variants each have their own trace/screenshot (filter, search, sort, paging, switcher, inline edit, export, viz, bulk, row actions, conditional formatting)
list-view-capabilities 1 saved-view filter AST + server count pass GET showcase_task?…filter=[["status","equals","in_progress"]] 200, total 2 (Build homepage, Ingest pipeline); count bar "2 records"
list-view-capabilities 2 quick-search is server-side, pinyin recall pass GET showcase_account?top=50&search=huaning 200 → 华宁科技 (+ the CJK test row)
list-view-capabilities 3 paging top/skip, partition pass showcase_inquiry (60 rows): top=50 then top=50&skip=50; 50+10 ids, overlap 0, union 60 = all 60, no unpaged fetch
list-view-capabilities 4 string-form sort renders + server-ordered pass Task List view: GET …sort=-estimate_hours 200, rows 88,88,60,40,30,24,18,16,16,8,8,8 (descending), 0 pageerrors
list-view-capabilities 5 inline edit PATCH only edited cell pass Grid view dblclick Estimate → Save All(1) → PATCH {"estimate_hours":13} 200; re-read diff estimate_hours 12→13 (+audit only)
list-view-capabilities 6 export = declared formats, filtered rows pass grant qa_task_export bound (before: 403 EXPORT_NOT_PERMITTED); Display → Export as CSV/XLSX/JSON; each GET …/export?format=X&filter=in_progress 200; CSV 2 rows, JSON 2 items, XLSX header+2
list-view-capabilities 7 viz switcher exactly six pass Layout menu: Grid, Kanban, Gallery, Calendar, Timeline, Gantt; each re-rendered task records (10/10/8-in-month/10/10/10), 0 pageerrors
list-view-capabilities 8 bulk dispatch by mode pass Mark Done on 3 rows → 3 POST /actions/showcase_task/showcase_mark_done; Recalculate Selection → 1 POST /api/v1/apps/showcase/recalc {"_selectedIds":[3 ids]} 200
list-view-capabilities 9 legacy rowActions live, no dup pass Legacy Row Actions menu: Mark Done, Reassign…, Quick View (once), Recalculate Estimate; Recalc → POST /apps/showcase/recalc {recordId} 200; Quick View opens its modal page
view-type-gallery 0 9 types render real visualization pass named views Board/Cards/Calendar/Activity Timeline/Schedule/Work Locations/Hours by Status + Grid + Org Chart each screenshotted showing their own structure; none fell back to grid
view-type-gallery 1 kanban columns + summarize totals pass 5 columns × 2 cards; Estimate sums 16/108/100/150/24 = API group-by of estimate_hours (backlog/todo/in_progress/in_review/done)
view-type-gallery 2 temporal placement pass Design system due 10-18 → calendar 18, created 10-02 → timeline 10/2, gantt 10/4–10/18 = start/end; Build homepage 10-26 / 10-08 / 10/10–10/26; progress shown on bars
view-type-gallery 3 map markers + chart SVG from dataset pass map: 10 markers for 10 located tasks (basemap tiles blocked by egress, markers drawn); chart: 16 recharts bars after GET meta/dataset/showcase_task_metrics + POST analytics/dataset/query 200
view-type-gallery 4 tree renders hierarchy pass Org Chart expanded: Acme > Go-To-Market > Marketing, Sales > Enterprise Sales; Acme > Product & Engineering > Frontend Guild > Design Systems, Platform — matches API parent links
view-type-gallery 5 smoke pin green pass SMOKE_API_URL=:41280 playwright test --grep view surfaces → 7 passed (All Views, Task Board, Task Calendar, Task Gallery, Team Schedule, Activity Timeline, Work Map)
form-view-gallery 0 each layout renders its mechanics; drawer/modal on task-desk pass simple: Task, 2 cols; tabbed: 3 tabs; wizard on /new: "Step 1 of 3"; split: panes at x=417 / x=865; task-desk: 384px right drawer + modal dialog
form-view-gallery 1 wizard step order + one save pass Next with empty title → "Title is required", stays on step 1; walk 3 steps = 0 writes; final Save → 1 POST /data/showcase_task 201
form-view-gallery 2 visibleWhen notes live, full width pass priority Urgent → notes mounts (width 896 vs title 440); back to Medium → unmounts
form-view-gallery 3 every save persists pass simple PATCH {title} 200; tabbed PATCH {title}; split PATCH {title}; drawer PATCH {priority:medium}; wizard POST 201; each re-read shows only the edited key changed
form-view-gallery 4 tab/step nav keeps unsaved values pass tabbed: typed title survives Overview→Schedule→Overview; wizard: Back to step 1 keeps "qa-g15 wizard task"
conditional-rules-header 0 requiredWhen live + blocked submit pass INV-1002 edit: status Draft→Sent puts the required marker on issued_on; Save with it empty → field error "required", 0 writes
conditional-rules-header 1 requiredWhen server-side pass POST invoice status sent w/o issued_on → 400 VALIDATION_FAILED fields[issued_on/required]; 0 rows persisted
conditional-rules-header 2 readonlyWhen client lock + server strip pass paid INV-1003 form shows tax_rate as read-only text; PATCH tax_rate 99 → 200, x-objectstack-dropped-fields tax_rate;reason=readonly_when; tax_rate 8 before and after
conditional-rules-header 3 visibleWhen paid_on pass paid_on absent from the draft form; present and required on the paid form
conditional-rules-header 4 row-action gating by CEL pass INV-1003 row menu [Edit(disabled), Submit for Sign-off] — no Delete; INV-1002 [Edit, Delete, Submit for Sign-off]; detail Edit disabled on paid
conditional-rules-header 5 one rule both ends pass form block ↔ API 400 on the same issued_on predicate; client-locked tax_rate = server-stripped field
conditional-rules-grid 0 row-scoped requiredWhen flags per row + blocked save pass row1 qty 120 + empty description → aria-invalid + "Description is required"; row2 (qty 1) unflagged; Save → batch 400 description/required, nothing written
conditional-rules-grid 1 server enforces same rule pass direct POST line qty 120 no description → 400 description/required; atomic batch [valid line, violating line] → 400; line count unchanged
conditional-rules-grid 2 parent-scoped readonlyWhen live pass status→Paid in form: Qty/Unit Price inputs LOCKED, product picker loses buttons; back to Draft: all editable, no reload
conditional-rules-grid 3 receipt cell stores managed file pass upload → presigned/raw PUT/complete 200; batch line update receipt=‹sys_file id>; re-read receipt {id,name small.pdf,size 45}; GET storage/files/‹id> 200 application/pdf 45 bytes
conditional-rules-grid 4 saved batch persists, siblings identical pass line pos0 changed description/quantity/amount only; line pos1 (distinct position) 0 changed keys; count 2→2
cascading-options 0 dependsOn gates + live re-filter + clear pass province shows "Select country first" until country set; cn → [Zhejiang, Guangdong]; pick Zhejiang then switch to us → value cleared, options [California, Texas]
cascading-options 1 server invalid_option + in-set accepted pass POST cn+ca → 400 fields[province/invalid_option], 0 persisted; cn+zj → 201, re-read cn/zj
cascading-options 2 role gate both sides pass org_admin persona: options Standard+Restricted, POST restricted 201, re-read restricted; plain member: Standard only, POST restricted → 400 tier/invalid_option
cascading-options 3 dependent lookup scoped by account pass contact picker disabled "Select Account first"; Northwind → GET showcase_contact?top=50&filter=[account=Northwind] total 26, 26 options; Contoso → total 2, 2 options
cascading-options 4 legal selection persists pass created cn/zj row re-read country=cn province=zj
master-detail-atomic-save 0 one atomic batch with child refs pass Save → 1 POST /api/v1/batch atomic:true: invoice create + 2 line creates with invoice {"$ref":0}
master-detail-atomic-save 1 rows readable + autofill persisted pass re-read invoice Northwind/draft; lines WIDGET-A "Standard widget" 29.99×3=89.97, SERVICE-HR "Professional services, per hour" 150×2=300
master-detail-atomic-save 2 total server roll-up on create/add/delete pass total 389.97 = sum; add WIDGET-B×2 → 489.95; delete it → 389.97
master-detail-atomic-save 3 failing child aborts all pass line with no product → batch 400 product/required, toast "Product is required", dialog stays; filtered GET 0 invoices; line count 8→8
master-detail-atomic-save 4 derived subform on stock New form pass New Invoice dialog renders data-testid line-items grid (Product/Description/Service Start/Qty/Unit Price/Receipt/Amount)
master-detail-atomic-save 5 amount live + persisted pass qty 3 → amount cell 89.97 before save; stored amount 89.97
related-list-server-pagination 0 server top/skip scoped by parent pass showcase_contact?top=5&skip=0&filter=[account=Northwind], then skip=5…25; 0 child requests without top
related-list-server-pagination 1 pager = server total, pages partition pass pager "Page 1 of 6"/"Page 2 of 6", total 26 = direct filtered count 26; 6 pages 26 ids, 26 unique
related-list-server-pagination 2 related lists derived pass Northwind detail tabs Details/Invoices/Projects/Related(28)/History with no hand-built page
related-list-server-pagination 3 declared relatedList config honored pass Invoices tab label "Invoices", columns Invoice Number/Status/Total/Issued On; request select=id,name,status,total,issued_on
related-list-server-pagination 4 row navigation + re-read pass clicked Prospect 17 → /showcase_contact/record/‹id>; GET that id = Prospect 17, account Northwind
related-list-server-pagination 5 read gate both ends pass contributor: no Contacts section, page count probe 403, forged child GET 403 PERMISSION_DENIED; manager: Contacts 26 renders, forged GET 200 26 rows
action-param-widgets 0 per-param real widget pass text input; richtext RichTextField textarea; select combobox; date input[date]; 2 lookups record picker; color input[color]; autonumber read-only "—"; image/file input[file]
action-param-widgets 1 accept/multiple are DOM attributes pass p_cover accept="image/" no multiple; p_attachments accept="application/pdf,image/" multiple
action-param-widgets 2 contract enforced at dispatch pass bad p_priority → 400 VALIDATION_ERROR "Invalid option"; conformant → 200 received [p_text,p_priority,recordId,objectName]; pin in dogfood batch passed
action-param-widgets 3 required p_text both ends pass dialog Confirm empty → "Title is required", 0 action POSTs; direct POST without p_text → 400 "p_text is required"
upload-guard-blocks-confirm 0 Confirm disabled mid-upload pass 8MB PDF with upload throttled to 600KB/s: PUT storage/_local/raw in flight, button "Uploading…" disabled, forced click → 0 action POSTs; enabled after complete
upload-guard-blocks-confirm 1 dispatch carries file ref pass POST /actions/…/showcase_action_param_gallery 200, params.p_attachments ["‹file id>"], received includes p_attachments
upload-guard-blocks-confirm 2 maxSize enforced before the wire pass 11MB → "exceeds max size (10.0 MB)"; 14.5MB PNG → "exceeds max size (5.0 MB)"; 0 storage requests in that window
upload-guard-blocks-confirm 3 dialog usable after rejection pass small.pdf then: presigned/PUT/complete 200 → dispatch 200
import-wizard-encoding-and-hints 0 GBK decode (pin) pass importParsers.test.ts 57/57 passed at objectui daeb77fc
import-wizard-encoding-and-hints 1 unmapped required disables Next + hint (pin) pass importMissingRequiredHint.test.tsx 2/2 passed at daeb77fc
import-wizard-encoding-and-hints 2 legacy fallback notice (pin-only) pass importLegacyReferenceGuard.test.tsx 3/3 passed at daeb77fc, incl "blocks the import and writes nothing when a lookup column is mapped"
import-wizard-encoding-and-hints 3 completed import lands readable rows pass wizard on showcase_contact with a GBK CSV: preview showed 测试联系人甲/经理; POST …/import 200 created 2; GET by email → 测试联系人甲 经理, 测试联系人乙 工程师
action-location-matrix 0 every hosted location renders its actions pass toolbar Reassign…; row Mark Done/Reassign…/Quick View; header Mark Done/Log Time/Archive; ⋯ Open Docs/Recalc Estimate/Recalc Selection; related row Log Time; section Mark Done/Log Time/Archive
action-location-matrix 1 placement exclusive pass record_more-only actions absent from header/toolbar; toolbar has only Reassign…; Log Time absent from task-list rows; quick-actions bar has no Recalculate Estimate (not named)
action-location-matrix 2 each location dispatches pass flow wizard paused→resume 200 (assignee set); Quick View modal; Mark Done 200 done=true; Log Time → /forms/showcase_task.form; Open Docs → tab objectstack.ai; Recalc Selection POST 200, est 20→88
action-location-matrix 3 row-level CEL both sides pass not-done task: Mark Done in row menu + header; done task: absent from both (Reopen instead); after header Mark Done the reload shows no Mark Done
action-location-matrix 4 empty locations = nowhere pass half (b): showcase_new_task ("New Task") on none of the six surfaces; recalc_selection under ⋯ only, not on the toolbar; half (a) blocked(fixture) per knownGaps (no packaged locations-less action)
validation-rule-type-matrix 0 per-type field codes pass all 400 VALIDATION_FAILED: invalid_initial_state, invalid_transition (project + account), invalid_format (tax_id, email), json_schema_violation, invalid_json, rule_violation (cross_field/script/conditional)
validation-rule-type-matrix 1 error targets declared field pass state_machine→status; format→tax_id/billing_email; json_schema→support_config; cross_field→start_date (=fields[0]); script/conditional→_record (no declared field)
validation-rule-type-matrix 2 no rejected write persists pass every rejected create 0 rows by name; rejected PATCHes leave full row byte-identical
validation-rule-type-matrix 3 happy-path twins land pass planned 201, planned→active 200, valid tax_id/email/support_config 201, end≥start 201, spent 110/100 201, churned+reason 200
validation-rule-type-matrix 4 advisory warning flags, not blocks pass PATCH health green→red 200, re-read red; boot.log WARN "Validation rule 'project_health_progression' (warning): Health changed by more than one step"
gantt-interactions 0 bar drag PATCH + re-read pass drag Build homepage +2 days → PATCH {start_date:2026-10-12,end_date:2026-10-28} 200; API re-read matches; after reload grid shows 10/12–10/28 and bar x 351→571
gantt-interactions 1 auto-schedule confirm-first (pin) pass GanttView.autoscheduledlg 4/4 (nothing written before confirm / cancel discards / confirm applies) + countinterp.i18n 5/5 at daeb77fc
gantt-interactions 2 locked task survives (pin) pass scheduling.selfextent 8/8 (locked task in skippedLocked) + GanttView.dnd 21/21 (summary drag skips locked) at daeb77fc; direct leaf-drag sub-leg blocked(fixture) per knownGaps
gantt-interactions 3 vetoed update leaves no write blocked(fixture) no host onBeforeTaskUpdate veto or server-side date rule on stock fixtures; no pin covers acceptance[3]
kanban-drag-persistence 0 drop issues update, re-read confirms pass Content backlog Backlog→To Do: PATCH {"status":"todo"} 200; API status todo
kanban-drag-persistence 1 survives reload pass after reload the card renders in the TO DO column
kanban-drag-persistence 2 rejected move reverts with error pass Evidence collection To Do→Done: PATCH {"status":"done"} 400 invalid_transition; toast "Invalid task status transition."; card back in TO DO; API todo
form-dirty-guard 0 accidental close guarded; Cancel and clean close do not prompt pass dirty Escape/X/backdrop → "Discard changes?" [Keep editing, Discard]; Keep editing keeps value; dirty footer Cancel closes, no prompt; clean Escape/X/backdrop/Cancel close, no prompt
form-dirty-guard 1 discard row identical, save persists pass after 3 discards + Cancel the Globex row is byte-identical; Save → PATCH {"annual_revenue":42424242} 200, no other keys changed
form-dirty-guard 2 unit pin pass discardGuard.test.tsx 14/14 passed at objectui daeb77fc
named-import-mapping 0 foreign headers land on mapped fields pass POST …/import mappingName showcase_inquiry_feed → created 2; rows name/email/company/message from Full Name/E-mail/…; Channel Webform→website, Partner Referral→referral
named-import-mapping 1 re-import idempotent pass same file again → created 0 updated 2; row count 2→2 (table 5→5)
named-import-mapping 2 unknown mapping fails loudly pass mappingName no_such_mapping → 404 MAPPING_NOT_FOUND "No mapping artifact named "no_such_mapping" is registered"; 0 rows
adhoc-filter-sort-builder 0 toolbar filter merges with view filter pass filter=["and",[[status equals in_progress]],["and",[priority = urgent],[estimate_hours > 4]]] → Ingest pipeline only; an empty Title row was dropped
adhoc-filter-sort-builder 1 sort reaches request, server-ordered pass SortBuilder Due Date Z→A → sort=-due_date; due dates come back descending, null last
adhoc-filter-sort-builder 2 filter + sort survive in-app nav pass nav Accounts → Tasks → In Progress: request re-issued with the same merged filter; restored from the per-user list preference
adhoc-filter-sort-builder 3 cache user-scoped pass state in sys_user_preference ui.list.showcase_task for the admin user_id + localStorage list-state:‹admin id>:showcase_task; second account on the same browser gets only the view filter
adhoc-filter-sort-builder 4 uf_* URL params reproduce rows pass Task Workbench ?uf_status=in_progress,in_review → 4 rows; Task Triage ?uf__tab=urgent → 2 rows; same URLs in a fresh context → same filter and same ids
records-forms.calendar-interactions 0 card drag issues PATCH + API re-read + reload pass drag Design system Oct18->21: PATCH /data/showcase_task/Lagl1ncaGxg_ESUF {"due_date":"2026-10-21"} 200; GET due_date 2026-10-21; post-reload card on Wed 21
records-forms.calendar-interactions 1 failing PATCH reverts optimistic move + error toast pass scratch hook rejects "QA cal reject": card at Thu15 right after drop, PATCH 400, card back on Tue13, 1 error toast with the hook sentence, API due_date still 2026-10-13
records-forms.calendar-interactions 2 month/week/day re-render same records by date pass Week Oct11-17 shows QA cal reject (13th); week Oct18-24 shows Warehouse schema Mon19 + Design system Wed21 (API 2026-10-19/21); Day Oct16 empty (no task due 16)
records-forms.calendar-interactions 3 empty-day quick-create inserts real row with clicked date pass click Oct23 cell -> Create Task dialog date input 2026-10-23; POST body due_date 2026-10-23 -> 201 6ZYPjBnt3Wlx0KBE; GET due_date 2026-10-23
records-forms.concurrent-edit-conflict 0 losing save refused 409 CONCURRENT_UPDATE, A intact pass two sessions on Hooli: A PATCH If-Match 12:41:40.671Z -> 200; B PATCH same If-Match -> 409 CONCURRENT_UPDATE currentVersion 13:04:03; re-read website = A value
records-forms.concurrent-edit-conflict 1 conflict dialog with structured choice pass modal form: "Save conflict" dialog, Keep editing / Overwrite; inline: ConcurrentUpdateDialog with YOUR EDIT / CURRENT VALUE, Reload / Overwrite
records-forms.concurrent-edit-conflict 2 Reload discards B edit and refetches pass inline stale save on Wayne Enterprises -> 409 -> Reload: no PATCH/PUT after click, page shows https://concurrent-a.example (A value), API final = concurrent value
records-forms.concurrent-edit-conflict 3 Overwrite re-keys ifMatch to 409 currentVersion, one winner pass Globex: B 409 currentVersion 13:05:13.479Z; Overwrite retry PATCH If-Match 13:05:13.479Z body {website:ow-b-a} -> 200; final re-read = B value
records-forms.concurrent-edit-conflict 4 inline two-surface edit is ONE PATCH with exactly the 2 keys + If-Match pass dblclick Website (body) -> header Annual Revenue also editable, 1 Save bar; 1 PATCH {"website":"https://inline-b.example","annual_revenue":31000000} If-Match 2026-10-16T12:41:40.671Z -> 200
records-forms.concurrent-edit-conflict 5 inline stale ifMatch -> 409 + same dialog pass concurrent API PATCH between read and save; inline PATCH If-Match 13:06:46.049Z -> 409 CONCURRENT_UPDATE; ConcurrentUpdateDialog rendered
records-forms.record-discussion-mentions 0 comment persists to sys_comment pass POST sys_comment 201 id 1261609c; GET sys_comment by thread_id showcase_account:1tE_vGstZ_g7MAvn -> 1 row with the body, mentions [usr_showcase_auditor_demo]
records-forms.record-discussion-mentions 1 optimistic row reconciles by id, no dupe/phantom pass client POST carried id 1261609c...; server 201 same id; marker leaf count sampled every 100ms for 3s then +2.5s = 1 every sample
records-forms.record-discussion-mentions 2 sys_activity interleaves oldest-first pass feed after edit: Updated Account (13:03:10) -> comment (13:09:16) -> "Industry: Finance -> Retail" (13:09:22), matching sys_activity timestamps
records-forms.record-discussion-mentions 3 mentioned user bell + deep link + unread decrement pass auditor.demo inbox badge 3, "Dev Admin mentioned you" with the comment; click -> POST /notifications/read, url /apps/com.example.showcase/showcase_account/record/1tE_vGstZ_g7MAvn; badge 3 -> 2
records-forms.record-discussion-mentions 4 recipient-scoped both sides pass phone.demo inbox "You are all caught up", no mention; forged GET sys_inbox_message filter user_id=usr_showcase_auditor_demo as phone.demo -> 200 total 0
records-forms.record-discussion-mentions 5 new comment on feeds-disabled parent -> 403 FEEDS_DISABLED, 0 rows pass qa-feeds-disabled recipe replayed; POST sys_comment thread qa_nofeeds:gehNATIV87z6Mhk7 -> 403 code FEEDS_DISABLED; thread read total 0; control POST on Initech thread -> 201
records-forms.record-discussion-mentions 6 re-thread onto feeds-disabled parent refused, thread_id unchanged pass PATCH sys_comment/1261609c thread_id qa_nofeeds:... -> 403 FEEDS_DISABLED; re-read thread_id showcase_account:1tE_vGstZ_g7MAvn; control re-thread onto enabled 200; body-edit control 200
records-forms.record-discussion-mentions 7 4 FeedFilterMode values show exact subsets pass All Activity=comments+changes; Comments Only=2 comments; Field Changes=2 change rows only; Tasks Only=empty (record has no task rows); back to All restores every row
records-forms.record-discussion-mentions 8 author-extended activity type rendered in all feed, not dropped pass scratch qa_ov activityMilestones type qa_custom_escalation; sys_activity row type qa_custom_escalation "QA escalated: ov1"; all-feed renders it with generic (lightning) presentation
records-forms.grid-personalization 0 column resize persists across reload (reorder/pin n/a on stock) pass Assignee 240->373px, kept after reload (fresh context too); stored in localStorage grid-columns-showcase_task + pref ui.list.showcase_task; reorder/pin n/a on stock
records-forms.grid-personalization 1 row-height persists across reload pass Density set Compact, row height 45->41px; after reload Density=Compact, rows 41px; pref perView.showcase_task.grid.rowHeight=compact
records-forms.grid-personalization 2 group-by headers + totals match API + clears cleanly pass group Status: Backlog 3 / To Do 59 / In Progress 2 / In Review 2 / Done 2 = API counts over 68 rows (per-bucket server finds); Clear -> 0 group headers, 1 thead, 50 rows
records-forms.grid-personalization 3 row-color rules paint rows and survive reload pass grid view rowColor priority: after reload Medium rows bg oklch(0.932 0.032 255.6) (blue-100), Low row oklch(0.968 0.007 247.9) (slate-100)
records-forms.grid-personalization 4 column-state key not user-scoped (by design) pass localStorage key grid-columns-showcase_task carries no user id (but see accuracy: widths/rowHeight also land in user-scoped sys_user_preference)
records-forms.saved-view-management 0 create kanban stages draft, Publish makes it live pass PUT /meta/view/showcase_task.qa_kanban_g16?mode=draft (kanban, groupByField status) 200 -> ?preview=draft; POST .../publish 200; plain reload shows the 5 status columns
records-forms.saved-view-management 1 rename/default/pin/delete each write and survive reload; default unsets prior pass rename PUT 200; default: 2 PUTs, kanban isDefault true, showcase_task.default false; pin PUT isPinned true; delete DELETE x2 200, meta 404; each survives reload
records-forms.saved-view-management 2 non-admin lacks mutation affordances pass phone.demo on showcase_task: Add View 0, View actions buttons 0, More menu has no Manage all views
records-forms.saved-view-management 3 forged non-admin PUT refused server-side pass phone.demo PUT /meta/view/showcase_task.qa_forged_g16 -> 403 FORBIDDEN requires manage_metadata; ?mode=draft -> 403; admin GET live and ?state=draft -> 404
records-forms.bulk-select-all-matching 0 cross-page banner reports server total pass 55 scratch "QA bulk NN" tasks; search find total 55, page renders 50; banner "All 50 on this page are selected. Select all 55 matching" -> "All 55 matching records are selected"
records-forms.bulk-select-all-matching 1 select-all-matching resolves every matching id pass resolve find GET ...?top=500&skip=0&search=QA+bulk (no page top/skip); aggregate POST carried 55 distinct ids = API $search total 55
records-forms.bulk-select-all-matching 2 aggregate = 1 dispatch with all ids; per-record fans out pass aggregate: 1 POST /api/v1/apps/showcase/recalc with 55 _selectedIds (flow acted=55); Mark Done: 55 POSTs /actions/showcase_task/showcase_mark_done, API done 55/55
records-forms.bulk-select-all-matching 3 clear resets both selection sources pass 50 row boxes checked before Clear; after Clear 0 checked boxes, bulk bar gone, no banner
records-forms.bulk-select-all-matching 4 fan-out bounded at HARD_CAP 5000 pass collected 55 lt = cap; HARD_CAP=5000 read at objectui ObjectGrid.tsx:5252-5264 (slice to cap); weak: set far below the cap
records-forms.lookup-picker-create-new 0 zero-hit user-facing lookup offers create-new opening full form pass BU parent picker zero-hit term: popover "No options found" + "Create new" with the typed term; click opens "Create Business Unit" full form (5 fields)
records-forms.lookup-picker-create-new 1 picker adopts new id; parent re-read resolves it pass child POST 201 iMVTWcsHizaVbfoE; parent field shows qa-bu-quick-c; parent POST 201 rKJbQvkc_pVTtaGL; GET parent.parent = iMVTWcsHizaVbfoE
records-forms.lookup-picker-create-new 2 typed search is a scoped server find pass GET /data/showcase_business_unit?populate=parent&top=50&search=QaZeroHitc8f7j (debounced: one request per settled term)
records-forms.lookup-picker-create-new 3 system reference offers no quick-create pass field zoo f_user (sys_user) picker, term zzQaNoUser: GET /data/sys_user?...search=zzQaNoUser, popover "No records found", 0 Create new
records-forms.import-job-undo-cancel 0 undoable job reaches terminal state with per-row results pass gated console spec 1 passed twice (pinRun); API job succeeded 30/30, results[] 30 per-row entries, list entry undoable true, no revertedAt key
records-forms.import-job-undo-cancel 1 undo removes exactly the imported rows pass marker count pre 0 / post-import 30 / post-undo 0; qa_imp total 2 -> 32 -> 2 (pre-existing rows untouched); undo deleted 30
records-forms.import-job-undo-cancel 2 cancel mid-job leaves coherent partial pass 3000-row job cancelled: status cancelled processed 400 created 400; 400 committed rows, 0 torn (every row name/a pair consistent)
records-forms.import-job-undo-cancel 3 job list distinguishes undoable/reverted pass before undo {undoable:true} no revertedAt key; after undo {undoable:false, revertedAt:2026-10-16T12:49:52.179Z}
records-forms.object-hook-lifecycle 0 beforeInsert stamps source=web pass POST showcase_inquiry without status/source -> 201; GET source=web, status=new
records-forms.object-hook-lifecycle 1 one multi-event hook trims insert and update pass POST title " os-qa-g16mvayqg8l " -> "os-qa-g16mvayqg8l"; PATCH padded -> "os-qa-g16mvayqg8l-upd"
records-forms.object-hook-lifecycle 2 afterUpdate audit fires on completing update pass OS_LOG_LEVEL=info boot: PATCH Content backlog done false->true -> log "INFO [hook showcase_audit_task_completion] task completed: Content backlog"
records-forms.object-hook-lifecycle 3 audit does not fire on non-transition edit pass priority-only PATCH on Audit current IA and on App wireframes (done:true): 0 new "task completed" lines after 4s settle each
records-forms.object-hook-lifecycle 4 over-budget warn fires pass PATCH Data Platform spent 650000 -> "WARN [hook showcase_warn_over_budget] project over budget: Data Platform (650000 / 600000)"
records-forms.object-hook-lifecycle 5 record = stored+payload; under-budget no warn pass spent-only PATCH fired with stored budget 600000; Website Relaunch spent 70000 -> 0 warn lines
records-forms.object-hook-lifecycle 6 onError abort on throwing beforeInsert rolls back pass scratch qa_h_abort on qa_hk_abort: POST -> 400 {"error":"qa scratch abort hook refused"}; count 0 -> 0
records-forms.object-hook-lifecycle 7 onError log async throw does not roll back pass scratch qa_h_log: PATCH val 2 -> 200, re-read val 2; log ERROR "[hook] handler failed (onError=log; suppressing)" hook qa_h_log
records-forms.object-hook-lifecycle 8 unevaluable condition fails closed pass scratch qa_h_cond condition int(record.name)>0, name abc: POST -> 500 INTERNAL_ERROR, count 0 -> 0; log "HookConditionError: ... could not evaluate its condition ... operation aborted"
records-forms.object-hook-lifecycle 9 same object+event runs lowest priority first pass scratch afterInsert qa_h_p10 / qa_h_p90: log p10 at 12:49:28.135Z then p90 at 12:49:28.178Z
records-forms.field-type-constraints 0 length is reject-not-truncate pass 201-char name -> 400 max_length {maxLength:200,actual:201}, count 2->2; 200-char -> 201, re-read length 200
records-forms.field-type-constraints 1 number range both sides pass f_number -1 min_value {min:0}; 1001 max_value {max:1000}; abc invalid_number; 500 re-reads 500
records-forms.field-type-constraints 2 KNOWN GAP scale not enforced (recorded) pass f_currency 1234.567 (scale 2) -> 201, GET 1234.567 unrounded - gap holds as recorded, no new enforcement
records-forms.field-type-constraints 3 closed-set rejects on 2 carriers pass f_select not-a-value -> invalid_option options[low,medium,high]; invoice status archived -> invalid_option options[draft,sent,paid,void]; counts zoo 5->5 invoice 12->12
records-forms.field-type-constraints 4 multiselect array shape pass "red" -> ["red"]; {x:1} -> invalid_type; ["red","purple"] -> invalid_option naming purple; ["red","blue"] -> ["red","blue"]
records-forms.field-type-constraints 5 dangling reference rejected; existing id verbatim pass f_lookup nonexistent -> reference_not_found; real account id re-reads equal (out-of-scope acceptance shown in cascading clause 4)
records-forms.field-type-constraints 6 autonumber server-assigned, client value ignored pass POST f_autonumber HACK-9999 -> stored 0009, header x-objectstack-dropped-fields f_autonumber;reason=readonly; PATCH HACK-1 -> 200, still 0009
records-forms.field-type-constraints 7 formula read-only; summary maintained cache pass f_number 42 f_percent 75 f_formula 999 -> f_formula 31.5; new invoice total 777 kept, self-healed to 0 then 35 = line sum (2x10+3x5); seeded invoices 4/4 total = line sums
records-forms.cascading-multilevel-and-clear 0 select client clear-on-change pass New Cascading Select: cn -> province options Zhejiang,Guangdong, pick Zhejiang; switch us -> province "Select an option", options California,Texas; submit body province null
records-forms.cascading-multilevel-and-clear 1 select server written-value gate pass POST {cn,ca} -> 400 invalid_option province "option ca is not available"; {cn,zj} -> 201
records-forms.cascading-multilevel-and-clear 2 KNOWN GAP parent-only PATCH keeps stale child (recorded) pass create {cn,zj}; PATCH {country:us} -> 200; GET country us province zj - gap holds as recorded
records-forms.cascading-multilevel-and-clear 3 lookup twin re-queries scoped and clears pass contact picker GET filter ["account","=",Northwind id] -> 26 options; pick Nora West; switch account Contoso -> contact field empty, GET filter Contoso id -> 2 options (Cara Ito, Carl Fox)
records-forms.cascading-multilevel-and-clear 4 KNOWN GAP lookup scope not server-enforced (recorded) pass POST invoice account Contoso + Northwind contact -> 201 stored; fabricated contact -> 400 reference_not_found target showcase_contact
records-forms.cascading-multilevel-and-clear 5 legal cascade persists consistently pass {cn,zj} re-reads cn/zj; invoice Northwind + Northwind contact re-reads both ids
records-forms.encrypted-field-behavior 0 secret write stores ciphertext pass POST f_secret topsecret-value -> 201 resp mask; SQLite column f_secret = secret:sec_7107e0f1...; sys_secret row alg aes-256-gcm kms local:v1 ciphertext v2:...; 0 sys_secret rows containing plaintext
records-forms.encrypted-field-behavior 1 reads mask for every reader pass GET f_secret and f_password both "••••••••"; f_password at rest plaintext (column p@ssw0rd!), masked on read
records-forms.encrypted-field-behavior 2 echoed mask is a no-op pass PATCH f_secret=mask -> 200; column still secret:sec_7107e0f1...; sys_secret row version 1, updated_at == created_at
records-forms.encrypted-field-behavior 3 fail-closed without provider (pin-only) pass packages/objectql/src/secret-fields.test.ts green in batch (fail-closed case) - no stock boot runs unwired (knownGap)
records-forms.encrypted-field-behavior 4 credential column not aggregable pass POST /data/showcase_field_zoo/query groupBy f_secret -> 400 INVALID_FIELD "Cannot aggregate credential field(s)"; max(f_password) -> 400 same; control groupBy f_select -> 200
records-forms.field-group-visible-when 0 both spellings accepted; served as authored pass PUT qa_group_gate bare "record.kind == pro" -> 200, GET same bare string; PUT envelope {dialect:cel,source} -> 200, GET envelope; batch20 normalization test green
records-forms.field-group-visible-when 1 visibleOn refused with prescription pass PUT visibleOn -> 422 INVALID_METADATA unrecognized_keys naming visibleWhen + "FALSE hides the whole group, header included"; re-read still the envelope
records-forms.field-group-visible-when 2 derivation carries predicate verbatim pass spec field-group-layout.test.ts "visibleWhen passthrough" 5 cases green (bare + envelope)
records-forms.field-group-visible-when 3 console gates section on form and detail pass form: kind basic -> no "Pro details"; flip pro -> section appears live; back basic -> gone. detail (highlightFields [kind]): basic record no Pro details, pro record shows Pro details card
records-forms.field-group-visible-when 4 display-tier: hidden values survive save pass basic record pro_a PREFILL-A / pro_b PREFILL-B; form edit of note only -> PATCH {"note":"display-tier-probe-a"}; re-read pro_a/pro_b unchanged
records-forms.field-unique-enforcement 0 colliding create refused 409 UNIQUE_VIOLATION, count unchanged pass POST sku A-1 twice -> 409 UNIQUE_VIOLATION, developerMessage "Duplicate record refused on qa_unique: a unique constraint already holds these values. No record was written."; no driver text; count 1->1
records-forms.field-unique-enforcement 1 NULL-distinct pass two POSTs without sku -> 201, 201
records-forms.field-unique-enforcement 2 update onto taken value refused; no self-collision pass PATCH r2 sku A-1 -> 409, re-read B-1; PATCH r1 nick only -> 200
records-forms.field-unique-enforcement 3 updateMany refuses whole batch before mutating pass POST /data/qa_unique/updateMany atomic stamping C-1 on 2 rows -> failed 2 (ROLLED_BACK + UNIQUE_VIOLATION), both rows unchanged M-1/M-2; predicate driver path from memory pin
records-forms.field-unique-enforcement 4 scope matrix both families pass memory-unique-constraint.test.ts 26 passed + sql 8577/respelling 65 passed; live global gsku dup -> 409; two-org live probe not provisioned
records-forms.field-unique-enforcement 5 autonumber collision converges pass memory-unique-constraint.test.ts resync case green (pin verdict)
records-forms.delete-behavior-matrix 0 set_null clears scalar FK pass contact -> account; DELETE account 200; contact re-read 200 account null
records-forms.delete-behavior-matrix 1 multi-value removes member, writes remainder pass f_lookups [a2,a3]; DELETE a2 200; f_lookups [a3]
records-forms.delete-behavior-matrix 2 master_detail cascades pass invoice with 2 lines; DELETE invoice 200; line list total 0
records-forms.delete-behavior-matrix 3 restrict 409 DELETE_RESTRICTED envelope pass scratch restrict child: 409 DELETE_RESTRICTED, dependentObject qa_restrict_child, dependentCount 1, developerMessage names deleteBehavior cascade; parent kept (admin shape)
records-forms.delete-behavior-matrix 4 required FK escalates to restrict pass account referenced by invoice: DELETE -> 409 DELETE_RESTRICTED dependentObject showcase_invoice dependentCount 1 "account is required"; control unreferenced account DELETE 200
records-forms.delete-behavior-matrix 5 master_detail + set_null closed at both seams pass PUT qa_md_setnull master_detail deleteBehavior set_null -> 422 INVALID_METADATA (not stored, GET 404); seam coercion+log from engine-cascade-delete pins
records-forms.record-clone-contract 0 enable.clone gate both ways pass qa_noclone clone -> 403 CLONE_DISABLED "Cloning is disabled for object qa_noclone", count 1->1; showcase_account clone -> 201
records-forms.record-clone-contract 1 overrides win but cannot forge protected columns pass override name lands; forged created_by/created_at re-derived (caller, now); readonly approval override "approved" -> clone holds default "pending"
records-forms.record-clone-contract 2 201 body bare per CloneDataResponseSchema pass top-level keys object,id,sourceId,record; id != sourceId; sourceId = source; no wrapper
records-forms.record-clone-contract 3 internal fields never ride the 201 (pin) pass metadata-protocol search-clone-schema-conformance 8 passed + protocol.write-response-internal-fields.tripwire 18 passed; rest search-clone-route conformance 6 passed (no internal-field object live)
records-forms.record-clone-contract 4 not-found refusals are the shared ones pass unknown id -> 404 RECORD_NOT_FOUND; unregistered object -> 404 OBJECT_NOT_FOUND, identical to list on the same name
records-forms.field-history-tracking 0 tracked edit lands old->new summary with labels pass PATCH Contoso industry technology->finance: sys_activity updated "Industry: Technology -> Finance" (labels, not keys); History tab renders the same
records-forms.field-history-tracking 1 untracked edit has no field diff pass PATCH website only: sys_activity "Updated Account Contoso" (generic, no website diff)
records-forms.field-history-tracking 2 History tab gates on object-level flag both ways pass account detail tabs Details/Invoices/Projects/Related/History; task detail renders no tab strip, no History
records-forms.field-history-tracking 3 derived history op follows get+trackHistory pass /auth/me/permissions apiOperations: showcase_account includes history; showcase_task lacks it
records-forms.field-history-tracking 4 tracked reference renders titles (pin) pass plugin-audit audit-lookup-summary.test.ts green (3-file batch 44 passed); no stock tracked lookup
records-forms.import-transform-matrix 0 each supported transform does its documented conversion pass none: Full Name/E-mail copied; map: Webform -> website, "Carrier Pigeon" passthrough; constant: a=CONST (source SRC_IGNORED dropped); split " left , right " -> b=left c=right; join x1,"",z1 -> x1-z1
records-forms.import-transform-matrix 1 javascript refused loudly before any row pass qa_imp_js import -> 400 UNSUPPORTED_TRANSFORM "...no server-side sandbox..."; qa_imp count 1->1
records-forms.import-transform-matrix 2 lookup copies raw value, resolves downstream pass Account=Northwind -> acct = Northwind id wc8Pg3BYCnfyC2a_; NoSuchAccountQA row failed reference_not_found (row 2), not landed
records-forms.import-transform-matrix 3 format guard pass JSON rows via csv mapping -> 400 MAPPING_FORMAT_MISMATCH naming csv and json; xlsxBase64 via same mapping -> 200 created 1 with every transform applied
records-forms.predicate-relationship-traversal 0 write passes when parent does not trip pass POST invoice account Initech (active) -> 201, readable; no fault
records-forms.predicate-relationship-traversal 1 refused with authored message, not a fault pass churned account -> 400 VALIDATION_FAILED rule_violation "This account has churned - reactivate it before invoicing." (no could-not-be-evaluated)
records-forms.predicate-relationship-traversal 2 repoint on update judged on merged record pass PATCH existing invoice account -> churned id -> 400 same authored message; account unchanged
records-forms.predicate-relationship-traversal 3 unreadable parent still enforces (pin) pass objectql engine-predicate-relationship.test.ts green (system-authority read, accept/refuse, prior-row FK)
records-forms.script-action-hook-refusal-toast 0 refusal is 4xx carrying the hook sentence pass POST /api/v1/actions/showcase_task/showcase_reopen_task -> 400 VALIDATION_ERROR message = TASK_REOPEN_REFUSAL verbatim (2 fresh runs)
records-forms.script-action-hook-refusal-toast 1 exactly one new error toast with the sentence pass baseline 0 live toasts; within 1.2s 1 node data-type=error text = TASK_REOPEN_REFUSAL; delta 1 (both runs)
records-forms.script-action-hook-refusal-toast 2 toast belongs to this request pass only non-GET in window: POST /api/v1/actions/showcase_task/showcase_reopen_task; toast text == error.message
records-forms.script-action-hook-refusal-toast 3 record left unchanged pass Audit current IA before done true/progress 100/updated_at 12:49:18.931Z; after identical (both runs)

Reproduction rules (fails)

None: no clause failed.

Derived item verdicts

39 pass · 1 partial · 0 fail · 0 blocked · 0 not-run (of 40).

Pin runs (Tier 1, RUNNER rule 6):

  • records-forms.crud-roundtrip: packages/metadata-protocol: vitest run src/protocol.readonly-insert.test.ts → 11 passed; packages/objectql: vitest run src/engine-insert-static-readonly-strip.test.ts → 21 passed
  • records-forms.field-type-matrix: cd packages/qa/dogfood && pnpm exec vitest run test/field-zoo-roundtrip.dogfood.test.ts test/field-zoo-value-shape.test.ts test/action-params-contract.dogfood.test.ts test/showcase-search.dogfood.test.ts --maxWorkers=1 → 4 files, 101 passed / 0 failed
  • records-forms.view-type-gallery: examples/app-showcase: OS_TEST_CHROMIUM_EXECUTABLE_PATH=/opt/pw-browsers/chromium SMOKE_API_URL=http://localhost:41280 pnpm exec playwright test --grep "<7 view surfaces>" → 7 passed / 0 failed
  • records-forms.action-param-widgets: cd packages/qa/dogfood && pnpm exec vitest run test/field-zoo-roundtrip.dogfood.test.ts test/field-zoo-value-shape.test.ts test/action-params-contract.dogfood.test.ts test/showcase-search.dogfood.test.ts --maxWorkers=1 → 4 files, 101 passed / 0 failed
  • records-forms.import-wizard-encoding-and-hints: objectui checkout daeb77fc (repo root): pnpm exec vitest run <10 files> --maxWorkers=1 → 124 passed / 0 failed (import files: importParsers 57, importMissingRequiredHint 2, importLegacyReferenceGuard 3)
  • records-forms.gantt-interactions: objectui checkout daeb77fc (repo root): pnpm exec vitest run <10 files> --maxWorkers=1 → 124 passed / 0 failed (gantt: autoscheduledlg 4, summaryedit 8, deptypes 2, selfextent 8, countinterp 5, dnd 21)
  • records-forms.form-dirty-guard: objectui checkout daeb77fc (repo root): pnpm exec vitest run <10 files> --maxWorkers=1 → 124 passed / 0 failed (discardGuard.test.tsx 14)
  • records-forms.calendar-interactions: objectui daeb77fc (checkout /home/user/objectstack-qa-console/.cache/objectui-daeb77fc84dd, run from repo root): pnpm exec vitest run --maxWorkers=1 packages/plugin-calendar/src/CalendarView.dnd.test.tsx -> 8 passed (in an 8-file batch, 56/56)
  • records-forms.concurrent-edit-conflict: objectui daeb77fc (checkout /home/user/objectstack-qa-console/.cache/objectui-daeb77fc84dd, run from repo root): vitest run packages/plugin-form/src/occSave.test.tsx -> 8 passed. e2e/live/inline-edit-polish-2572.spec.ts not run (driven by hand instead)
  • records-forms.record-discussion-mentions: framework: plugin-audit vitest capability-gate-update-verb.test.ts (+2 audit files) 44 passed; qa/dogfood comments-permission-matrix.dogfood.test.ts (4-file batch 64 passed). objectui daeb77fc (checkout /home/user/objectstack-qa-console/.cache/objectui-daeb77fc84dd, run from repo root): recordActivityFeed.test.ts 61 passed
  • records-forms.grid-personalization: objectui daeb77fc (checkout /home/user/objectstack-qa-console/.cache/objectui-daeb77fc84dd, run from repo root): vitest groupedPagination/groupedBooleanLabel/inlineEditPersistence.test.tsx -> 7+2+1 passed
  • records-forms.bulk-select-all-matching: objectui daeb77fc (checkout /home/user/objectstack-qa-console/.cache/objectui-daeb77fc84dd, run from repo root): vitest objectBulkActionDispatch/BulkActionBar/bulkActionRefresh.test.tsx -> 12+7+11 passed
  • records-forms.lookup-picker-create-new: objectui daeb77fc (checkout /home/user/objectstack-qa-console/.cache/objectui-daeb77fc84dd, run from repo root): vitest LookupField.dependsOn.test.tsx 6 passed + RecordPickerDialog.filterOptions.test.tsx 12 passed
  • records-forms.import-job-undo-cancel: objectui daeb77fc e2e/import-console/import-console-undo.spec.ts (scratch copy in GROUPDIR/pw, playwright 1.62.1, executablePath /opt/pw-browsers/chromium, IMPORT_CONSOLE_LIVE=1, LIVE_IMPORT_APP=showcase_app LIVE_IMPORT_OBJECT=qa_lead) -> 1 passed (21.2s) and 1 passed (10.2s); gate-off control -> 1 skipped
  • records-forms.object-hook-lifecycle: framework: qa/dogfood showcase-public-form + hook-error-format (in 4-file batch 64 passed); objectql hook-binder.test.ts 26 passed
  • records-forms.field-type-constraints: framework: objectql engine-lookup-referential-integrity + engine-autonumber-runtime-owned (in 8-file batch 242 passed); qa/dogfood field-zoo-roundtrip (4-file batch 64 passed)
  • records-forms.cascading-multilevel-and-clear: framework: objectql rule-validator.option-visibility.test.ts (in 8-file batch 242 passed). objectui e2e/live/cascading-options.spec.ts not run (driven by hand)
  • records-forms.encrypted-field-behavior: framework: objectql secret-fields.test.ts (in 8-file batch 242 passed); qa/dogfood field-zoo-roundtrip (64 passed)
  • records-forms.field-group-visible-when: framework: spec vitest object-strictness-batch20 + field-group-layout -> 70 passed; objectui daeb77fc (checkout /home/user/objectstack-qa-console/.cache/objectui-daeb77fc84dd, run from repo root): record-details.groupVisibleWhen-11630.test.tsx 12 passed, sectionVisibleWhen-6111.test.tsx 25 passed
  • records-forms.field-unique-enforcement: framework: driver-memory memory-unique-constraint.test.ts 26 passed; driver-sql 8577-tenant-scoped + organization-respelling 65 passed
  • records-forms.delete-behavior-matrix: framework: objectql engine-cascade-delete + -atomic + -multivalue-probe (in 8-file batch 242 passed)
  • records-forms.record-clone-contract: framework: metadata-protocol search-clone-schema-conformance 8 + write-response tripwire 18; rest search-clone-route-schema-conformance 6 passed
  • records-forms.field-history-tracking: framework: plugin-audit audit-lookup-summary + audit-option-label-summary (44 passed in 3-file batch)
  • records-forms.predicate-relationship-traversal: framework: objectql engine-predicate-relationship.test.ts (in 8-file batch 242 passed)
  • records-forms.script-action-hook-refusal-toast: framework: examples/app-showcase test/task-reopen-hook-refusal.test.ts 5 passed; runtime nested-hook-refusal-is-a-rejection.test.ts 5 passed; objectui daeb77fc (checkout /home/user/objectstack-qa-console/.cache/objectui-daeb77fc84dd, run from repo root): consoleServerAction.errorToast.test.ts 6 passed

Fixture gaps

  • records-forms.gantt-interactions clause 3: no veto path on stock: the task gantt has no host onBeforeTaskUpdate and showcase_task has no date rule the server would refuse; no objectui pin covers acceptance[3]
  • records-forms.gantt-interactions clause 2: direct drag of a locked LEAF bar still unreachable live (stock view declares no lockField) — sub-leg blocked(fixture); clause scored from pins
  • records-forms.action-location-matrix clause 4: half (a) needs a PACKAGED action with no locations key; none ships on stock (knownGaps) — scored on half (b)
  • records-forms.field-unique-enforcement clause 4: live two-organization collision probe not provisioned (needs 2 orgs); scored from memory + SQL pins
  • records-forms.delete-behavior-matrix clause 3: lesser-persona DELETE_RESTRICTED shape (count may be omitted) not driven; admin shape observed
  • records-forms.cascading-multilevel-and-clear clause null: no 3-level dependsOn fixture (knownGap, no clause)

Observation (not a clause fail, not filed)

records-forms.conditional-rules-grid: on a grid save blocked client-side (quantity 120 with an empty required description), the client still sent the batch. The server refused it with 400 and wrote nothing, so the authority held. The objectui pin asserts only the inline required flag. This is noted for the next author of the item, not extracted: no user-visible wrong result.

Checklist-accuracy findings from this area close out on the wave anchor #23878; they are not extracted.

Activity

  1. objectstack-fleet commented on Oct 16, 2026

    @objectstack-fleet
    ContributorAuthor

    Close-out for this record (checklist-test §5), 2026-10-16T18:19Z. 39 pass · 1 partial · 0 fail of 40. There is no fail row. The one partial's gap is parked on the wave anchor:

    Parked-on: #23878 · records-forms.gantt-interactions · clause 3 blocked(fixture) — no veto path on stock: the task gantt has no host onBeforeTaskUpdate, showcase_task has no date rule the server refuses, and no objectui pin covers acceptance[3]
    

    The record's one observation (conditional-rules-grid: a client-blocked grid save still sends the batch, which the server refuses with 400 and writes nothing) was rechecked on #23878 (6218243967, item 13). It is by design: there is no user-visible wrong result. The other fixture gaps and the checklist-accuracy findings close out on #23878. Closed by the domain:devx seat 1 PM (seat post #6023) · os-sales · session_014eFvbvGK4FjXvscggDNTD4, as part of the paced close-out of the #23878 wave.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions