Skip to content

QA run · records-forms (FULL area) · a86db175 · 2026-08-10 · 15 PASS / 12 PARTIAL / 4 FAIL / 1 BLOCKED #7439

Description

@baozhoutao

Full records-forms area run of the checklist-test skill — all 32 runnable items driven against a live showcase + vendored console (6 opus subagents, one isolated boot each). Supersedes the api-subset run #7399. 4 real regressions (all in the vendored console / objectui), each reproduced ≥2× with root cause. Convention labels: qa-run + bug (labels not yet created in this repo).

Result: 15 PASS · 12 PARTIAL · 4 FAIL · 1 BLOCKED (of 32 runnable; +1 pre-blocked import-job-undo-cancel fixture). Screenshots were judgment aids only — this report is text; every verdict rests on a server-truth/network/test oracle.

Environment

framework a86db175 — branch claude/platform-test-checklist-ocwugl (PR #7304)
console vendored dist built from objectui 09987b68 (.objectui-sha)
app · driver showcase · SqlDriver(better-sqlite3) · fresh isolated file DB + port per item · admin@objectos.ai
browser Playwright/Chromium (executablePath pin) · console loaded via localhost (trusted-origin)

🔴 FAIL — 4 regressions (all in the vendored console / objectui)

1. upload-guard-blocks-confirm — image param has no client-side max-size guard
p_cover (declared maxSize 5 MB) accepts an oversized file: a 6.3 MB PNG fires a full presigned → PUT → complete upload with no rejection, while p_attachments (10 MB) correctly rejects >10 MB with zero uploads. Reproduced 2×.
Repro: Field Zoo → Specimen–Full row → run "Action Param Gallery"; set a >5 MB image on Cover image (p_cover). Expected: rejected before any upload (like p_attachments for >10 MB). Actual: full upload + preview, no "5.0 MB" error. Root cause: the image-param widget lacks the client maxSize guard the file-param widget has.

2. kanban-drag-persistence — rejected drag doesn't roll the card back
An illegal Kanban drag (Backlog→In Progress) is correctly rejected server-side (PATCH 400 invalid_transition, toast shown, server stays backlog), but the card stays stuck in the target column until a manual reload. Reproduced 3× (switcher + dedicated Board view).
Repro: showcase_task → Kanban; drag a Backlog card onto In Progress. Expected: card returns to Backlog on the 400. Actual: card stuck in In Progress >5 s. Root cause: objectui plugin-kanban/src/ObjectKanban.tsx handleCardMove gates revert-on-failure behind if (!hasExternalData); the ListView-hosted (console) path has hasExternalData=true, so rollback is skipped.

3. saved-view-management — renaming a draft view doesn't persist
Create-kanban / pin / delete all work (200), but rename of a freshly-created draft view is rejected and silently lost; set-default fires no write at all. Reproduced 2×.
Repro: create a Kanban view via the + tab (draft), then tab menu → Rename. Expected: new label persists. Actual: client updateView GETs the base view without preview=draft → 404 → treats as create → writes an invalid partial {label,name,object} → PUT → 422; re-read (preview=draft) still shows the old label. Root cause: objectui data-objectstack/src/index.ts updateView() reads the base view without preview=draft then writes an invalid partial.

4. bulk-select-all-matching — Clear leaves row checkboxes ticked (#3056 drift)
Clicking Clear in the bulk-actions bar empties the toolbar but leaves the row checkboxes data-state="checked" (header stays indeterminate) — stranded ticks with no toolbar. Reproduced 2×.
Repro: showcase_contact list → tick 3 rows → click Clear. Expected: bar and checkboxes both reset. Actual: bar removed, checkboxes stay checked. Root cause: objectui plugin-grid/src/ObjectGrid.tsx onClearSelection does setSelectedRows([]) + setSelectAllMatching(false) but omits the setSelectionResetKey bump that resetSelection() (delete/dispatch paths) performs.
Note: this item's cross-page-banner clauses (0/1/2/4) are blocked(fixture) — no seeded object exceeds the 100-row page window and no view exposes pageSizeOptions, so "select all matching" is unreachable in the stock console.


🟡 Notable finding inside PARTIAL

object-hook-lifecycle — hook ['log'] capability output is not observable. Hook bodies fire ([BodyRunner] hook fired) and don't throw, but the named log lines (ctx.log.info("task completed: …"), "project over budget: …") never appear even at --log-level debug. Hook lifecycle + condition semantics are all correct (beforeInsert defaults/trim, afterUpdate two-root previous.done gating #4784, total-record merge, fail-closed condition #4775). Clauses 2/4/5 are partial only because their named-log oracle can't be captured. Worth a separate look at body-runner.ts log:engineCtx.logger wiring.


Full verdict table (32 runnable + 1 pre-blocked)

item pri · surface verdict
validation-rule-type-matrix P1 api ✅ pass (6 rule types, exact codes)
named-import-mapping P2 api ✅ pass (mapped + idempotent + 404)
field-type-matrix P1 mixed ✅ pass (dogfood 46/46 + widgets + mask + refs)
conditional-rules-header P1 mixed ✅ pass (requiredWhen/readonlyWhen/visibleWhen both ends)
conditional-rules-grid P1 browser ✅ pass (row-scoped required + parent-lock + receipt ref)
master-detail-atomic-save P1 browser ✅ pass (single atomic /batch, roll-up, all-or-nothing)
related-list-server-pagination P1 browser ✅ pass (paged child queries, 403-vs-200 both persona)
action-param-widgets P1 mixed ✅ pass (10 real widgets, malformed bag rejected)
import-wizard-encoding-and-hints P2 browser ✅ pass (GBK + required-hint + degrade + live import)
form-dirty-guard P2 browser ✅ pass (prompt iff dirty; discardGuard 14/14)
adhoc-filter-sort-builder P1 browser ✅ pass (merge under AND, per-user key, uf__tab, #1964)
concurrent-edit-conflict P1 mixed ✅ pass (OCC 409 both surfaces, 1 PATCH 2 keys, occSave 8/8)
lookup-picker-create-new P2 browser ✅ pass (nested create, real id adopt, scoped $search, both-sides)
field-type-constraints P1 mixed ✅ pass (8/8; 2 non-enforcement gaps recorded honestly)
encrypted-field-behavior P1 mixed ✅ pass (ciphertext, read-mask, no-op echoed-mask, fail-closed pins)
crud-roundtrip P0 browser 🟡 partial — clone RLS-404 / enable.clone:false blocked(fixture)
list-view-capabilities P1 browser 🟡 partial — server $skip unreachable (no object >100-row page)
view-type-gallery P1 browser 🟡 partial — map basemap env-blocked; kanban summarize-total; smoke env
form-view-gallery P1 browser 🟡 partial — tabbed/wizard/split/drawer/modal have no UI opener (fixture)
cascading-options P1 mixed 🟡 partial — role-gate allow-side: 'admin' position never seeded
action-location-matrix P1 browser 🟡 partial — record_header/more/related unreachable on stock page; global_nav unproven
gantt-interactions P2 browser 🟡 partial — auto-schedule/lock/veto need fixtures (matches knownGaps)
calendar-interactions P1 browser 🟡 partial — quick-create needs project; real-403 unreachable
record-discussion-mentions P1 browser 🟡 partial — mention-bell/recipient-scoping need a 2nd real user
grid-personalization P2 browser 🟡 partial — column resize/reorder not reproduced; rowColor has no colors map
object-hook-lifecycle P1 mixed 🟡 partial — ['log'] output not observable (see finding); scratch-hook fixtures
cascading-multilevel-and-clear P1 mixed 🟡 partial — clear-on-switch flaky; recorded gaps; 3-level fixture
upload-guard-blocks-confirm P2 browser 🔴 fail — p_cover 5 MB guard missing
kanban-drag-persistence P2 browser 🔴 fail — no rollback on rejected drag
saved-view-management P2 browser 🔴 fail — draft view rename lost
bulk-select-all-matching P2 browser 🔴 fail — Clear leaves checkboxes ticked (#3056)
record-edit-undo P2 browser ⛔ blocked — automation-input trap (undo toast unsurfaceable; unit-pinned)
import-job-undo-cancel P1 browser ⛔ pre-blocked (fixture) — not run

Fixture gaps to close (make more clauses runnable)

  • A seeded object >100 rows (or a view exposing pageSizeOptions) → unlocks list-view $skip + the whole bulk-select-all-matching cross-page banner.
  • Bind an admin position to the seeded admin (or point the gate at a seeded position) → cascading-options allow-side.
  • A second sign-up-able user → record-discussion-mentions bell/recipient; related-list RLS both-sides (already worked around); non-admin gates.
  • Wire UI openers for the tabbed/wizard/split/drawer form views → form-view-gallery.
  • Gantt view with dependenciesField/lockField/parentField; a scratch throwing/duplicate-event hook; a 3-level cascade object; a rowColor.colors map.

Screenshots

None — every clause rests on an api/network/log/test oracle or DOM-after-screenshot. Per RUNNER.md the report is text-only; the 4 fails carry reproduction rules above instead of images.

Activity

  1. os-zhuang commented on Aug 10, 2026

    @os-zhuang
    Contributor

    Triage audit — run-record, labeled tracking; the four FAILs are split to execution cards in the repo where the fix lands (file-at-destination rule; all four root-cause in vendored-console/objectui code, each re-verified at objectui origin/main @ 92c0b1f before filing):

    QA item Execution card Verified anchor
    kanban-drag-persistence objectstack-ai/objectui#4138 ObjectKanban.tsx:589 revert gated on !hasExternalData
    saved-view-management objectstack-ai/objectui#4139 data-objectstack/src/index.ts:3012 read without draft qualifier, create-equivalent catch
    bulk-select-all-matching objectstack-ai/objectui#4140 ObjectGrid.tsx:2956/:2994 omit the selectionResetKey bump :1946 performs
    upload-guard-blocks-confirm objectstack-ai/objectui#4141 guard exists in FileField.tsx:52; paramToField.ts:85 delivers maxSize to both widgets

    The one framework-side observation (object-hook-lifecycle PARTIAL, ctx.log output unobservable) is recorded as #7448 (finding + domain:cli, anchored body-runner.ts:339/:377).

    Dedup: searched objectui open issues per defect (kanban / updateView / clear-selection / maxSize) — zero duplicates; #4025 (kanban $top) and ui#4110 (InboxPopover) are different defects. tracking on this card keeps the run record out of the triage scan window, matching how the two prior QA-run records (#7399, #7326 — both all-pass) exited via close; this one stays open as the aggregation record until its four cards land. Fixture gaps listed in the body are QA-harness work, not dispatchable defects — left with the record.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  2. huangyiirene commented on Aug 11, 2026

    @huangyiirene
    Collaborator

    Closing — extraction has been complete since the 2026-08-10 triage pass (four FAILs → objectstack-ai/objectui#4138–#4141, the framework observation → #7448), and each card has its own lifecycle in the objectui queue.

    One disposition superseded, recorded rather than silently overridden: the triage comment above kept this record open "until its four cards land". Maintainer instruction of 2026-08-11 (chat, verbatim): 「QA run 相关的 issue 如果任务已经分拆出去了,是不是应该直接关闭」 — ruled that an extracted run record closes at extraction, not at its cards' landing; the cards' progress is tracked on the cards. Same exit as the all-pass run records #7399 / #7326.


    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