Skip to content

QA P0 release sweep 2026-10-01 — checklist re-point for query-contract-matrix clause 6 + the run's checklist-accuracy findings and fixture gaps (anchor for #21056) #21060

Description

@objectstack-fleet

Filing gate: ③ a maintainer-directed task — the maintainer, after the P0 run, chose to file every extraction including this anchor (Claude Code session session_01MRdbfpy4sQT8bUjmMhxsN7, 2026-10-01, selected option verbatim: 「全部立卡(推荐)」). Reader: the lane owning docs/qa/platform-checklist/** (checklist edits: revise the item, bump revision, append history, keep pnpm check:platform-checklist green). Dedupe: no open sweep anchor for this run (searched "QA run platform checklist sweep wave anchor tracking release", open + closed; #9296 is the August regression epic).

QA-source: #21056 · api-backend.query-contract-matrix · acceptance[5]

This card is the wave anchor for run #21056 (RUNNER "Extraction obligation": checklist-accuracy findings and fixture gaps close out here, not as separate cards). Product defects from the run are extracted separately: #21052, #21057, #21058, objectstack-ai/objectui#11326, objectstack-ai/objectui#11327.

1. Re-point (owns a red row) — api-backend.query-contract-matrix acceptance[5]

Disposition stale spec, independently verified. The clause (rev 2, 2026-08-18) expects 400 INVALID_FILTER for a scalar $nin comparand on the POST /query door in both spellings. Since #20116 the refusal happens in the request schema (FilterConditionSchema.superRefine(checkFilterConditionComparands); the AST arm via lowerFoldedTransportValues), and the POST door answers schema failures 400 VALIDATION_FAILED with a fields[] entry at query.where… naming operator, field and expected array — a posture pinned by rest-server-repeated-filter-param.test.ts and analytics-filter-refusal-envelope.test.ts. GET $filter still answers INVALID_FILTER. Revise: POST both spellings → 400 VALIDATION_FAILED + fields[]; GET → 400 INVALID_FILTER; both never 500, never widen. Also: step 5 / acceptance[2] — dotted fields: ['account.name'] is refused 400 INVALID_FIELD by design (prescribes expand); negative[0] — {"filter": …} is now a declared transport alias, so use an undeclared key (400 INVALID_FIELD). Residual for the maintainer, not a defect: GET and POST answer different codes for the same condition (#8001 family).

2. Checklist-accuracy findings

  • Personas, all member-persona items + recipe search:qa-contributor-bound-member step 1: stock audience posture is invite_only; POST /api/v1/auth/sign-up/email answers 403 SELF_REGISTRATION_CLOSED. Every "fresh sign-up" needs admin invite-member first (or admin create-user + change-password, which returns mustChangePassword:true).
  • access-security.crud-permission-matrix: automated.ref still says "25 showcase_* rows / 100 cells", clause/fixture say "31 rows"; actual access-matrix.json 47 rows, the pin judges 41 showcase_* rows = 164 cells (87 allow / 77 deny). acceptance[1] should list 405 OBJECT_API_METHOD_NOT_ALLOWED for sys_user create/delete (every caller). acceptance[5] (guest create-without-read) is unobservable on stock — add to knownGaps or re-point to the public-form lane. automated.ref's "pinned on both sides" for delegate sys_user_position writes does not hold on the dev boot (the pin runs with no organization — see [finding] The delegated-admin gate resolves an EMPTY subtree on a stock objectstack dev boot — seeded business units are organization-less while every session carries an active organization, so every in-scope delegated write is refused #21057). Probe delegate edit/delete on a row the delegate created (others' rows hit the ownership floor).
  • access-security.write-path-guards acceptance[5]: "drops the field for the batch" → per row: only the locked row's field is dropped, reported in results[i].droppedFields.
  • access-security.owd-sharing-matrix step 1 / crud-permission-matrix persona recipe: grant the position, not the set directly (reason with the maintainer; see [showcase][security] An owner-isolation policy in the showcase's contributor permission set does not hold for every way a member can hold the set — detail withheld pending maintainer #21052).
  • access-security.rls-both-sides: the private "D11" handle collides with a public "D11" row in FOLLOW-UPS.md §7c; history/cross-references say "clause 5" (0-based) where runs say clause 6 (1-based).
  • access-security.anonymous-deny-surfaces: the pin does not cover /batch or /security/explain (both 401 rest-flat live) — extend it.
  • ai.mcp-stdio-fail-closed: no single showcase persona carries both RLS-hidden rows and an FLS-masked field on one object (use contributor for RLS, client_liaison for FLS); details.forbiddenFields is not on either wire; step 1 names no host command (os dev prints banner lines to stdout — use os start).
  • api-backend.packaged-action-disabled-dispatch knownGaps: the MCP door IS drivable live over HTTP (POST /api/v1/mcp, tools/call run_action).
  • platform-core.seed-integrity step 5 / platform-core.boot-health step 4: no SeedLoader lines at the default log level — name the banner Seeds: row or --log-level info [Seeder] Seed loading complete {…errored}. boot-health acceptance[2] "no ⚠" collides with the two stock unbound — disabled by deployment policy lines; name the misauthored classes instead.
  • cli.dev-boot-contract: steps 5/7/8 (touch sources, nothing-chosen DB, legacy dev.db) are unsafe in a shared tree — prescribe a scratch copy of the app; name the expected exit code (SIGINT → 0 under pnpm exec, --fresh SIGINT → 130); the "Dev admin … seeded" banner reprints on later boots and is not seeding evidence.
  • integration-system.datasource-credential-refusal-matrix: knownGaps "the wizard can plant a legacy alias row" is false (400) — planting needs a stopped-server sys_metadata write; acceptance[6] "PUT the response back" — the admin door is PATCH-only; acceptance[3] should name the admin door (the console reads hasSecret / redactedConfigKeys there); step 5 path GET /api/v1/meta/datasource/{name}; source omits the composed twin 18.datasource-credentialsref-mongo-composed-no-username-refused.ts, and the url-branch entry still says the composed branch is "Deliberately NOT refused" (stale since Composed-branch twin of #9041: external.credentialsRef bound + discrete mongo fields naming no username is the same silent no-op, unrefused #9147).
  • platform-core.console-login: acceptance[2].verify still says "after clearing cookies" (rev 3 step 5 expires with POST /auth/sign-out); acceptance[0] "nav + header" — /_console/home has a launcher, not a sidebar.
  • platform-core.nav-surfaces-render: the pin's playwright.config.ts hardcodes PORT = 3000 (no baseURL / executablePath override); its non-chart check can pass on the boot splash (22/49 first <main> texts were "Initializing application…"); SURFACES covers 31 of 49 served destinations — add the 18 hand-walked ones.
  • platform-core.builtin-apps-nav-render: counts moved (Setup 45, Account 8; acceptance[4] "7 vs 7" → 8 vs 8); member fixture cannot be a fresh sign-up — record the seeded plain persona (demo-personas.ts); Browse Marketplace needs egress to cloud.objectos.ai (knownGap).
  • records-forms.crud-roundtrip: acceptance[6]'s readonly-column half is unobservable on the stock seed (no approval_status; lead_score null everywhere); the own-row invoice must not point at the run's account (later delete → 409 DELETE_RESTRICTED); list quick-search text persists across reloads.
  • approvals.account-app-entry: acceptance[6] should say 中文(中国) (zh-CN) — no zh option exists; acceptance[1] tab labels listed only in zh; acceptance[5] fixture → use a persona-owned invoice set to sent (unreadable rows render no link); the seeded sign-off request was routed before the persona held finance — launch a new one.
  • studio-authoring.first-run-loop: object name is repairs_repair_ticket (package namespace), not repair_ticket; knownGaps "a new app scaffolds ZERO nav items" is stale (checkbox default on); step 9 — the UI hides New object / Add field on read-only packages, so the server probe is a forged request; the New object dialog now requires an OWD choice; acceptance[0]'s cited objectui pin targets testids that do not exist at the pin.
  • RUNNER "Environment facts": CRUD tail is now 15 verified … 1 needs-fixture, 8 skipped; verify --rls probes 10 of 10 positions (digits only).

3. Fixture gaps and environment (record, no edit needed unless chosen)

No Postgres/MySQL/Mongo runnable in the sandbox (a wire-level fake PG served the connect legs); sandbox egress denies cloud.objectos.ai and map tiles; the container's Node v22.22.0 is below the pinned objectui's jsdom engine floor; runner port ranges must avoid the egress proxy's 127.0.0.1:41333.


Generated by Claude Code

Activity

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

Metadata

Metadata

Assignees

Labels

area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratedocumentationImprovements or additions to documentationdomain:devxpriority:p1High: required for production / M2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions