Repository navigation
QA run · studio-authoring (20/20) · 3fcafcd3 · 2026-10-27 · 17 PASS / 1 PARTIAL / 1 FAIL / 1 BLOCKED / 0 NOT-RUN #26715
Copy link
Copy link
Closed
Labels
Description
Run record — the Studio full sweep the maintainer asked for: every Studio pillar in a real browser, plus every top-level property of Studio's 12 metadata types (per discriminator value), plus the whole studio-authoring area. Text only; screenshots were live oracles and are not linked.
Env fingerprint
- Framework
3fcafcd3b8d93621e400ff2759551ae3930bb7bb. The console was built fromui/in the same tree (pnpm console:build; the rootpnpm builddoes not populatepackages/console/dist). - App:
examples/app-showcase,objectstack dev --seed-admin,OS_PORTexported. Each session had its own port and file DB (coordinator 41733; Data 47391; Automations 49109; Interfaces 47613/47614; Access 47631). Adminadmin@objectos.ai; non-admin personas created per session. - Runner: coordinator session
session_01J8VVAkZns5rNnK2rtszzbQ, plus four parallel QA sessions (Data, Automations, Interfaces, Access) and two gap-fill agents (view; object/field/hook/action). - Traps met:
stale-console-bundle: a console build was needed.auth-state-leak: the language preference is stored server-side and a stale storage seed opened English; identity was re-proved per persona.
- Not counted as defects: the server was reaped twice and restarted on the same DB.
Scope
- Selector: area
studio-authoring(20 items, 0 planned). All 20 judged. - Additional coverage, not in the title: the Studio UI clause list (pillar chrome, Data D1–D12, Automations E1–E6, Interfaces F1–F6, Access G1–G6); the property matrix (455 top-level properties across object, field, hook, action, view, app, page, dashboard, report, dataset, flow and permission); the 33 removed keys.
Per-item verdicts (revision · verdict · text evidence)
| item | rev | verdict | evidence |
|---|---|---|---|
| first-run-loop | 7 | PASS | 6/6 clauses. New package → object → field → publish → record → app → Home tile, zero restarts (one boot banner) |
| object-designer-roundtrip | 8 | PASS | option label rename persists; keyboard and drag reorder publish in order; label → API name; empty option row ignored |
| view-authoring-live | 3 | PASS | draft receipt state:draft; invisible pre-publish; live after publish on a single boot |
| record-page-roundtrip | 9 | PASS | Interfaces session |
| draft-publish-lifecycle | 8 | PARTIAL | c0–c7 and c9–c11 pass. c8: /diff names the top-level widgets key, not widgets[0].title — a checklist-accuracy gap, not a product defect |
| authoring-validation-not-persisted | 4 | PASS | 422 located refusals; nothing persisted; corrected shapes 200 |
| org-override-registry-gate | 5 | PASS | 5/5. Codes are served SCREAMING_SNAKE where the item spells them lowercase (accuracy note) |
| expression-editors | 5 | FAIL | lint parity: RLS USING f_formula > 5 shows "Valid CEL" and autosaves; publish refuses rls-predicate-unenforceable → #26707 |
| permission-matrix-editor-ux | 5 | PASS | acc0–acc5 pass. acc3's wording assumes unruled fields are not editable; that is disputed and carried by a security card (detail withheld pending maintainer) |
| custom-page-render-and-blocks | 1 | PASS | Interfaces session |
| page-variables-and-actions | 1 | PASS | Interfaces session |
| custom-page-source-tiers | 4 | PASS | Interfaces session (react gate checked on a second boot with OS_PAGE_REACT_ENABLED=false) |
| packaged-automation-studio-lock | 4 | PASS | A1–A4. Forged draft PUT → 403 ITEM_LOCKED; package-less → 403 NOT_OVERRIDABLE; pin 10/10 when run from ui/ with --root . |
| packaged-display-class-direct-edit | 3 | PASS | Interfaces session |
| metadata-diagnostics-sweep | 9 | PASS | c0–c7. A planted malformed row is located; the outage pin passes 10/10 |
| doc-on-app-menu | 6 | PASS | Interfaces session. The Studio path is not usable (pickers hide gated docs) — accuracy note |
| picklist-bound-select | 3 | BLOCKED{fixture} | the showcase ships no picklist (GET /meta/picklist items []); PUT picklist → 403 code-only |
| meta-save-preconditions-and-draft-rows | 2 | PASS | If-Match / If-None-Match matrix; _drafts labels; history actors |
| multi-package-item-rows | 2 | PASS | two-package dashboard; package-less save/delete 409; mismatch 422; revert semantics |
| save-door-runs-authoring-rules | 3 | PASS | located 422s plus a "did you mean"; draft-then-publish refusal; pins pass |
Pins (RUNNER rule 6), all green at 3fcafcd3:
meta-save-preconditions-and-draft-rows: 5 files.multi-package-item-rows: 9 files.save-door-runs-authoring-rules: 8 files.- The automation lock pin (10/10).
celAuthoring.test.ts(40/40).- 23 jsdom pins for four items.
Reproduction rules for FAIL
expression-editorslint parity: the reproduction is on Studio/metadata: a draft the editors, the draft_diagnosticsand the Problems tab all call valid is refused only at publish — and one such draft rolls back the whole package release #26707 (instance 3).- Security-class findings follow rule 2's carve-out: item / clause /
detail withheld pending maintainer. They are listed below by card only and were dispatched at once.
Product defects extracted (each its own card; this record holds the evidence index)
Security (detail withheld pending maintainer; dispatched directly on the maintainer's instruction): #26596, #26597, #26698, #26706.
Defect cards (39, Batch-of: studio-qa-2026-10-27; each carries its own reproduction):
- Studio: an edit the Data, Automations or Interfaces pillar is still holding (not yet saveable) is discarded silently when the builder leaves the pillar, switches item or reloads — no confirm, no beforeunload #26705 (F1) — Studio: an edit the Data, Automations or Interfaces pillar is still holding (not yet saveable) is discarded silently when the builder lea…
- Studio/metadata: a draft the editors, the draft
_diagnosticsand the Problems tab all call valid is refused only at publish — and one such draft rolls back the whole package release #26707 (F2) — Studio/metadata: a draft the editors, the draft_diagnosticsand the Problems tab all call valid is refused only at publish — and one s… - metadata: the save door and the package publish door accept a package id that is not installed (object, dashboard, page …), storing and even publishing items into a phantom package; Studio renders a writable builder for it #26708 (F3) — metadata: the save door and the package publish door accept a package id that is not installed (object, dashboard, page …), storing and e…
- spec: the view save door silently strips unknown top-level keys from the view envelope (200, not stored) while object, page and dashboard bodies refuse them 422 unrecognized_keys #26711 (S1) — spec: the view save door silently strips unknown top-level keys from the view envelope (200, not stored) while object, page and dashboard…
- spec:
app.hidden: trueon a stored app is rewritten to_unpublished: trueby the appHiddenToUnpublished conversion replayed on stored rows — after publish-drafts the app shows again; after a per-item publish it vanishes for non-builders #26712 (S2) — spec:app.hidden: trueon a stored app is rewritten to_unpublished: trueby the appHiddenToUnpublished conversion replayed on stored… - runtime:
POST /api/v1/packages/:id/publish-drafts?dryRun=trueignores the unknown query parameter and performs a real publish #26713 (S3) — runtime:POST /api/v1/packages/:id/publish-drafts?dryRun=trueignores the unknown query parameter and performs a real publish - objectql: a lookup with
deleteBehavior: "restrict"is overridden when the same parent is also the child's master_detail target — deleting the parent cascade-deletes the child instead of refusing 409 #26718 (S4) — objectql: a lookup withdeleteBehavior: "restrict"is overridden when the same parent is also the child's master_detail target — deleti… - spec: a chart list view on object A accepts a dataset bound to another object or another package without refusal #26719 (S5) — spec: a chart list view on object A accepts a dataset bound to another object or another package without refusal
- spec docs: permission.zod.ts says the built-in admin permission sets grant export, but default-permission-sets withholds it — admin gets 403 EXPORT_NOT_PERMITTED and no Export control #26720 (S6) — spec docs: permission.zod.ts says the built-in admin permission sets grant export, but default-permission-sets withholds it — admin gets …
- console: an api-type action target with
${ctx.recordId}is sent uninterpolated (…/$%7Bctx.recordId%7D) — url targets interpolate, api targets do not #26722 (G6) — console: an api-type action target with${ctx.recordId}is sent uninterpolated (…/$%7Bctx.recordId%7D) — url targets interpolate, api… - metadata: an action saved through the metadata door keeps
requiresFeature/requiresMembershipReachraw — never lowered intovisible— so the button shows to everyone (save-door sibling of #25744) #26723 (G7) — metadata: an action saved through the metadata door keepsrequiresFeature/requiresMembershipReachraw — never lowered into `visible… - metadata: an object bound to a datasource that does not exist publishes successfully, and is then silently unregistered (data calls 404 "not registered"); Studio still lists it #26724 (G9) — metadata: an object bound to a datasource that does not exist publishes successfully, and is then silently unregistered (data calls 404 "…
- spec: an object may declare two actions with the same name — Studio creates duplicates and the draft publishes #26725 (G10) — spec: an object may declare two actions with the same name — Studio creates duplicates and the draft publishes
- Studio hooks: a hook cannot be granted
capabilitiesin the Studio editor, and a hook refused for a missing capability answers the client 500 INTERNAL_ERROR instead of a located 4xx #26726 (G11) — Studio hooks: a hook cannot be grantedcapabilitiesin the Studio editor, and a hook refused for a missing capability answers the clien… - spec liveness ledger drift:
field.settledWhenis gradedplannedbut is live (the console overdue colour reads it);object.tenancyhas no ledger row #26727 (L1) — spec liveness ledger drift:field.settledWhenis gradedplannedbut is live (the console overdue colour reads it);object.tenancyh… - Studio Data › Actions: ticking "Expose to AI agents" writes a flat
aiExposedkey the spec refuses — every later save of the object answers 422 until reload, unticking does not recover #26728 (U1) — Studio Data › Actions: ticking "Expose to AI agents" writes a flataiExposedkey the spec refuses — every later save of the object answ… - Studio Data › Settings › Lifecycle field is a dead end: picking a Studio-authored select is refused 422 because its options need
kind, and the options editor has nokindcontrol #26729 (U2) — Studio Data › Settings › Lifecycle field is a dead end: picking a Studio-authored select is refused 422 because its options needkind, … - Studio publish refusals: shown only as a ~4 s toast with engine-internal text; the Pending changes panel keeps no refusal; "Show me" does not focus the offending input and the dashboard/report refusal strip has no "Show me" #26730 (U3) — Studio publish refusals: shown only as a ~4 s toast with engine-internal text; the Pending changes panel keeps no refusal; "Show me" does…
- Studio Data › Validations: new state_machine / format / json_schema rules save immediately with
field: created_atand an empty message (an empty transition row persists and publishes); the conditional rule'swhenis captioned as a fail condition #26731 (U5) — Studio Data › Validations: new state_machine / format / json_schema rules save immediately withfield: created_atand an empty message … - Studio a11y: several inputs have no accessible name — form designer group title, field inspector Description and Help text, Interfaces nav inspector "Link to object" combobox and "Label" #26732 (U7) — Studio a11y: several inputs have no accessible name — form designer group title, field inspector Description and Help text, Interfaces na…
- Studio rails: a search with no matches shows a blank list with no "no matches" message (object rail, permission-set rail) #26733 (U8) — Studio rails: a search with no matches shows a blank list with no "no matches" message (object rail, permission-set rail)
- Studio Data › Actions: a "Run a script" action is saved without
type, so the console treats it as not executable — clicking it sends no request #26734 (G2) — Studio Data › Actions: a "Run a script" action is saved withouttype, so the console treats it as not executable — clicking it sends no… - Studio Data › Actions: "Add field value" adds no row, so an update action's
patchcannot be authored in Studio (the published action is a no-op) #26735 (G3) — Studio Data › Actions: "Add field value" adds no row, so an update action'spatchcannot be authored in Studio (the published action is… - Studio Data › Actions: switching what an action does (or its Type) leaves an invalid draft that blocks every later save of the object with no message; Body Shape is a free-text box that writes an invalid value #26736 (G4) — Studio Data › Actions: switching what an action does (or its Type) leaves an invalid draft that blocks every later save of the object wit…
- Studio Automations: with the right panel hidden, selecting a node shows its configuration nowhere — the config drawer only reopens on mobile #26737 (U9) — Studio Automations: with the right panel hidden, selecting a node shows its configuration nowhere — the config drawer only reopens on mobile
- Studio Interfaces: the list-view inspector's Filter "Add filter" adds no row — no list-view filter can be authored in Studio #26738 (U10) — Studio Interfaces: the list-view inspector's Filter "Add filter" adds no row — no list-view filter can be authored in Studio
- Studio Interfaces: the navigation-item inspector cannot author
visible(shown read-only),viewName,recordId/recordMode,filters,badge/badgeVariant,requires*ororder— the Setup AppNavInspector has them #26740 (U11) — Studio Interfaces: the navigation-item inspector cannot authorvisible(shown read-only),viewName,recordId/recordMode, `filte… - Studio Interfaces: the page picker for a navigation entry lists draft record pages, producing a nav entry that is broken once published #26743 (U12) — Studio Interfaces: the page picker for a navigation entry lists draft record pages, producing a nav entry that is broken once published
- Studio Interfaces: dashboard widget types differ between the Add menu (11), the Type picker (10, no scatter) and the spec (20); the page block picker lacks 8 of 34 standard blocks; widget dataset help mentions a nonexistent "inline object query" #26745 (U13) — Studio Interfaces: dashboard widget types differ between the Add menu (11), the Type picker (10, no scatter) and the spec (20); the page …
- Studio Interfaces: an object nav entry without its own label is titled by the object's machine name in the item header ("repairs_repair_ticket · Object") while the rail shows the object label #26746 (U15) — Studio Interfaces: an object nav entry without its own label is titled by the object's machine name in the item header ("repairs_repair_t…
- console: a
type: "api"action withopensInNewTab+newTabUrlopens no tab and POSTs to its target instead #26747 (G8) — console: atype: "api"action withopensInNewTab+newTabUrlopens no tab and POSTs to its target instead - Studio Access › Tab visibility: the tab-name input keeps only the first character typed (typing
showcase_appsaves{"s":"hidden"}) #26748 (A2) — Studio Access › Tab visibility: the tab-name input keeps only the first character typed (typingshowcase_appsaves{"s":"hidden"}) - Studio Access: creating a permission set whose derived id equals an already-published set puts a blank draft over the live set (publishing it would wipe its grants), and Studio offers no way to discard it #26836 (A3) — Studio Access: creating a permission set whose derived id equals an already-published set puts a blank draft over the live set (publishin…
- Studio Access: saving a permission set drops draft values written by another door (
description,packageId) — the save starts from the published body and copies back only editor-managed keys #26837 (A4) — Studio Access: saving a permission set drops draft values written by another door (description,packageId) — the save starts from the… - console Home launcher ignores a permission set's
tabPermissions: hidden— it reads/api/v1/meta/appwhile the hide is applied only in/api/v1/me/apps#26838 (A5) — console Home launcher ignores a permission set'stabPermissions: hidden— it reads/api/v1/meta/appwhile the hide is applied only in… - Studio Access: the permission matrix lists no objects while the package's objects are still drafts ("0 objects"), so a new package cannot be secured before its first publish #26840 (A8) — Studio Access: the permission matrix lists no objects while the package's objects are still drafts ("0 objects"), so a new package cannot…
- Studio Access polish: jargon duplicate-draft refusal, OWD banner outliving revert, stale set label in the rail, clipped field counter, no re-grant for a dismissed suggestion #26846 (A9) — Studio Access polish: jargon duplicate-draft refusal, OWD banner outliving revert, stale set label in the rail, clipped field counter, no…
- console forms: form-view keys that save and publish are not rendered —
buttons,layout: "horizontal",drawerSide/drawerWidth;defaultsapply only on the full-page /new; a tabbed form with subforms losesdefaultTab/tabPosition#26843 (R1) — console forms: form-view keys that save and publish are not rendered —buttons,layout: "horizontal",drawerSide/drawerWidth; `… - console list view:
sharing.lockedByis never shown and the Share button has no handler #26844 (R2) — console list view:sharing.lockedByis never shown and the Share button has no handler
Property-matrix totals (L1 Studio control · L2 round-trip · L3 runtime effect, for live properties)
- object, field, hook, action (Data session + gap-fill):
- Every no-entry property was written through the draft/publish API and its runtime effect measured.
- object 18: 3 controls; L2 18/18; L3 15 pass, 3 hit by defects.
- field 28: 4 controls; L2 28/28; L3 21 pass, 1 inconclusive (
dimensions), 1 not exercised (mailAssociation), 1 not observable. - hook 6/6/6.
- action: L3 24 pass, 4 fail, 2 not exercised.
- view (61 properties, gap-fill): 3 Studio controls / 58 no-entry. L2 59 pass, 2 refused by design. L3 48 pass, 5 partial, 4 fail.
- flow: 11 Studio gaps (description, successMessage, errorMessage, version, type, variables, runAs, requiredPermissions, errorHandling,
nodes[].inputSchema,nodes[].boundaryConfig), all API-verified. 0 fail. Connector, wait, boundaryConfig and edge-type L3 not run. - app / page / dashboard / report / dataset (Interfaces):
- app: 11 gaps, 1 fail.
- page: 2 gaps.
- dashboard: 1 gap; 9 widget types have no Studio entry.
- report: 13/13.
- dataset: no Studio editor by design; all API L3 pass.
- permission (36): 24 controls / 12 no-entry; the API-verified ones work at runtime. Round-trip failures are carried by cards.
- Removed keys: 33/33 refused at their real location with a retirement prescription.
Fixture gaps / checklist accuracy
These go to the checklist through the coverage PR that follows this run; they are not extracted as cards.
picklist-bound-selectneeds a picklist fixture.packaged-automation-studio-lock's pin must run fromui/with--root ..org-override-registry-gatespells codes in lowercase.draft-publish-lifecyclec8 expects key-level diff granularity.permission-matrix-editor-uxacc3 and acc5 wording; step-1 path.doc-on-app-menu: the Studio path is impossible; create-user needsmustChangePassword:false.object-designer-roundtripstep 1 routes through Setup.
Off-clause probe
- Duration: the four parallel sessions ran about 06:58–08:22 UTC and the two gap-fill agents until about 09:30 UTC, with coordinator probes before and between them.
- Doors: every Studio pillar in the browser (desktop, 900px and 390px widths; light and dark; en and zh-CN);
/api/v1/meta/*save/publish/discard/history/diff/rollback/audit/diagnostics;/api/v1/packages/*;/api/v1/data/*;/api/v1/security/explain. - Boundary classes: phantom and read-only packages; draft-only items; a held edit vs departure; unknown keys; retired keys; foreign references; non-admin personas; runtime changes to metadata already in use.
- Findings: the cards above. Observations not filed (by design or open ledger questions):
- multiselect/checkboxes save
options:[](spec-derived); - the publish-drafts 200 +
success:falseenvelope; - plain DELETE of a draft-only item answers "nothing to delete" (folded into UX feedback);
defaultRowScopehides rows from the platform admin (needs a ruling);systemFields.audit:falserows still carry timestamps;- a one-character option value is refused (
too_small).
- multiselect/checkboxes save
Reactions are currently unavailable
Activity
objectstack-fleet commentedon Oct 28, 2026
devx seat 2 · pointer · 2026-10-28T03:28Z
This run's checklist-author pass, PR #26848, is taken over by devx seat 2 on the maintainer's word (「这个你也接手 26848」). Claim: PR comment 6459900913. Cloud session
session_01QSeKYkS7Zv7Z3r6tzUFzSfmergesmain, resolves thestudio-authoring.jsonconflict, re-verifies every item against currentmain, and checks that eachknownGapscard it cites is still open.Generated by Claude Code
objectstack-fleet commentedon Oct 29, 2026
Close-out (checklist-test §5) · 2026-10-29T02:13Z
expression-editors→ Studio/metadata: a draft the editors, the draft_diagnosticsand the Problems tab all call valid is refused only at publish — and one such draft rolls back the whole package release #26707, closedcompleted.completed.draft-publish-lifecyclec8, BLOCKED{fixture}picklist-bound-select, and the record's checklist-accuracy and fixture notes went through this run's coverage PR qa(checklist): studio-authoring accuracy fixes + 23 items from the Studio QA run #26848. devx seat 2 took that PR over (comment 6459921648), and it merged on 2026-10-28.Every verdict has a disposition, so the record closes
completed. Closed by the PM seatsession_012YjcDon6BvR9MN93ZsFq3Uin a close-out sweep the maintainer approved (「同意」).Generated by Claude Code