Repository navigation
Checklist studio authoring
github-actions[bot] edited this page Nov 12, 2026
·
1 revision
Generated by
pnpm gen:checklist-statusfromdocs/qa/platform-checklist/areas/*.json. ⛔ Do not edit this page — edits go to the area JSON and this page follows on the next run. This page isChecklist-studio-authoring.
Studio authoring — the admin/maker loop: packages, objects, views, record pages, draft→publish
51 active · 0 planned
| id | title | priority | status | personas |
|---|---|---|---|---|
studio-authoring.first-run-loop |
The first-run authoring loop closes: package → object → record → app → publish → end-user, zero code, zero restarts | P0 | active | admin (seeded admin@objectos.ai), end user (same account driving the published app) |
studio-authoring.object-designer-roundtrip |
Object designer round-trip: field add/edit/reorder persists to metadata, identifiers derive and survive typing | P1 | active | admin |
studio-authoring.view-authoring-live |
List + form view authoring goes live in the running app on publish — no server restart | P1 | active | admin (authors), end user (consumes the published views). A runtime-authored object grants no non-admin persona any access, so a non-admin list render needs a permission-set grant on it first; without one, score the end-user surfaces as the admin and say so (QA run #24571) |
studio-authoring.record-page-roundtrip |
Record-page authoring round-trip: created bound to its object, seeded from the default layout, block-edited, published, rendered | P1 | active | admin (authors), end user (opens the record). The viewer is the admin unless a member is used: every signed-in member reads showcase_account through the showcase's everyone baseline, showcase_member_default (allowRead; examples/app-showcase/src/security/permission-sets.ts MemberDefaultPermissionSet, which the dev CLI adds to every member per request). QA run #29893 (at 589049b0) drove the member leg as phone.demo@example.com and the authored page rendered; record which viewer each run used |
studio-authoring.draft-publish-lifecycle |
Metadata draft→publish lifecycle: drafts staged not served, publish flips visibility atomically, conflicts and invalid drafts refused, and the history/audit/diff/rollback forensics tell the truth | P1 | active | admin (authors drafts), end user (must not see drafts) |
studio-authoring.authoring-validation-not-persisted |
An invalid authored shape is rejected at save with a LOCATED error and is not persisted | P1 | active | admin |
studio-authoring.org-override-registry-gate |
The metadata type registry gates runtime writes: allowEnvironmentOverlay=false kinds refuse overlay (403 NOT_OVERRIDABLE), allowRuntimeCreate=false kinds refuse creation (403 NOT_CREATABLE) — both sides | P1 | active | admin |
studio-authoring.expression-editors |
The Studio CEL editors reach the SAME verdict as the engine: formula result-type inference, previous. completion in conditional rules, and RLS lint + test-run — the editor UI, not a second grammar | P1 | active | admin |
studio-authoring.permission-matrix-editor-ux |
Permission-matrix editor UX: field-filter + bulk apply to EXACTLY the visible fields, and the Bulk column never clips at narrow widths | P2 | active | admin |
studio-authoring.custom-page-render-and-blocks |
Declarative custom pages render their real block COMPOSITION (not just 'no error'): each declared block resolves its renderer and binds its data source, data-bound blocks show seeded rows (API cross-check), and a block that cannot bind degrades with a NAMED error, never a blank region | P2 | active | admin (seeded admin@objectos.ai) driving the published showcase app as an end user |
studio-authoring.page-variables-and-actions |
Page variables + page-level actions are runtime-live: variables initialize empty, an interactive writer updates one and dependent visibleWhen predicates re-evaluate WITHOUT reload, and a page action reads the live variable snapshot to POST resolved values that create a real record | P2 | active | admin (seeded admin@objectos.ai) driving the published showcase app as an end user |
studio-authoring.custom-page-source-tiers |
Source-authored page tiers render by the RIGHT path: kind:'html' source is PARSED-never-executed (static, in-browser sdui-parser compile), kind:'react' source is EXECUTED behind its capability gate (live data + interactivity) — command-center-jsx / capability-map (html) vs crm-workbench (react) | P2 | active | admin (seeded admin@objectos.ai) driving the published showcase app as an end user |
studio-authoring.packaged-automation-studio-lock |
Studio Automations pillar on a read-only package: a packaged flow is NOT editable in place — New lands in the base's .custom pair, autosave never writes the base, the header switch is the activation-ledger switch (a toggle, no metadata write), and inspector edits are inert or announced, never silently discarded | P1 | active | admin (opens Studio on the read-only package) |
studio-authoring.metadata-diagnostics-sweep |
The metadata governance sweep: GET /meta/diagnostics reports every STORED item failing spec validation with located errors, refuses outages and bad spellings loudly instead of answering '0 problems', and the Studio diagnostics page + directory tile badges paint the same numbers | P2 | active | admin (the governance surface is Studio's) |
studio-authoring.doc-on-app-menu |
A doc on the app menu follows the reader's audience: an admin authors a doc and puts it (or its book) on an app menu; a member who may read it sees it and opens it in its book; a member outside its audience does not see the entry and gets a refusal — never "not found", never a blank page — on the direct route | P1 | active | seeded admin (authors the doc, the books and the app navigation), member holding the gating permission set (the reader), member not holding it (the outsider) |
studio-authoring.picklist-bound-select |
A picklist authored in a package is used by two objects' select fields from the designer: both forms offer its options, the bound field refuses inline options, and a GET → edit → PUT of an object with a bound field saves | P2 | active | seeded admin (authors the objects in Studio; the picklist is authored in a package) |
studio-authoring.meta-save-preconditions-and-draft-rows |
Metadata save preconditions on v18: the item read serves its version and sending it back as If-Match saves, If-None-Match: * refuses an existing item 409 METADATA_CONFLICT with currentVersion, any other If-None-Match is 400, pending-draft rows carry the draft's label, and every stored row records its acting user |
P1 | active | seeded admin (admin@objectos.ai / admin123) — the Default Organization owner and platform admin on a fresh boot |
studio-authoring.multi-package-item-rows |
One item name, one stored row PER PACKAGE (ADR-0048) on v18: a package-less save resolves its owning package and an ambiguous one is 409, a dropStorage delete while another package's row remains is 409 and keeps the table, a save into the wrong package is 422 OBJECT_OVERLAY_PACKAGE_MISMATCH, a sealed packaged name answers one ruled 403 NOT_OVERRIDABLE text, and revert discards a Studio package's drafts | P1 | active | seeded admin (admin@objectos.ai / admin123) — the Default Organization owner and platform admin on a fresh boot |
studio-authoring.save-door-runs-authoring-rules |
The metadata save door runs the build's authoring rules on v18 — a page with an unknown component prop, a page with both details and tabs slots, a second default record page, a chart list view with no dataset, an object predicate that does not compile, a protection block or a lock change, and a non-http(s) URL target are each refused 4xx at PUT (drafts still admitted where the rule says so) |
P1 | active | seeded admin (admin@objectos.ai / admin123) — the Default Organization owner and platform admin on a fresh boot |
studio-authoring.held-edit-leave-guard |
Studio asks before an unsent edit is left behind: a held (incomplete) or dirty edit in any pillar survives a pillar switch, a rail switch, the package switcher, Home and a reload — or is discarded only after the author confirms | P1 | active | admin (authors in a writable package) |
studio-authoring.held-edit-publish-refusal |
Publish refuses while an edit is held: the refusal names what the held edit needs, nothing is published and no draft changes — and once the edit is finished, Publish goes | P1 | active | admin (authors in a writable package) |
studio-authoring.automations-rail-and-new-flow |
The Automations rail groups flows by the object they watch, searches by label and name, says when nothing matches, and explains its glyphs and dots in a legend; New automation's presets refuse until the watched object is chosen, and a new flow starts Off | P2 | active | admin (authors in a writable package) |
studio-authoring.flow-edge-type-authoring |
Flow edges are authored in Studio as the spec types them — Normal, Fault, Conditional and Back-edge write default / fault / conditional / back with their label, condition and default-branch flag — and an invalid edge condition is flagged before publish, not only by it | P2 | active | admin (authors in a writable package) |
studio-authoring.org-scope-flows |
Flows outside any package have their own Studio scope: /studio/~org offers only the Automations pillar, lists only package-less flows, opens them editable, saves drafts bound to no package and publishes each by reference | P2 | active | admin |
studio-authoring.flow-status-matches-runtime |
The flow state Studio shows is the state the deployment runs: the rail dot and the header read what GET /api/v1/automation/_status reports — Switched on, Switched off, Not running here with the platform's reason — and an enabled record-triggered flow actually runs | P1 | active | admin |
studio-authoring.validation-rules-authoring |
Validation rules authored in Studio's Validations tab — the presets and all six rule types — save spec-valid, hold until their condition is given, and enforce on the write path once published, severity and the active switch included | P1 | active | admin (authors the rules and drives the writes) |
studio-authoring.hooks-tab-authoring |
Hooks authored in Studio's Hooks tab save pinned and keep their name — a rename is held with the way back named — and their options take effect at runtime: the Run-only-when condition, the retry policy and On Error | P2 | active | admin (authors the hooks and drives the writes) |
studio-authoring.actions-tab-presets |
Actions authored in Studio's Actions tab work on the record: the four presets are written at once or held until their target is given, a held one is dropped unsent by Delete, and each published preset does its job in the app — while the advanced editor writes actions the console can run | P1 | active | admin (authors the actions), member (clicks them in the app) |
studio-authoring.object-api-tab-curl |
The Data pillar's API tab is a truthful REST reference: five endpoints under /api/v1/data/OBJECT, an example body built from the object's draft fields that the write path accepts, and copied cURL commands that succeed once a token is put in | P2 | active | admin |
studio-authoring.summary-field-authoring |
A summary (roll-up) field authored in Studio is held until it names its child object and function, offers only numeric child fields for sum and avg, and once published computes and recomputes from the children | P2 | active | admin |
studio-authoring.api-written-keys-survive-studio-save |
A Studio save never drops what another door wrote: keys a draft carries that Studio has no control for — written through the metadata API — are still in the draft, byte for byte, after an unrelated Studio edit autosaves the same item | P1 | active | admin |
studio-authoring.interfaces-create-dialogs |
The Interfaces create dialogs work end to end: Create app derives its identifier and scaffolds one menu entry per package object (none when the box is cleared), New dashboard / report / page write spec-valid drafts linked from the menu, a report without a dataset or a measure and an identifier already taken are refused in the dialog, and everything opens in the published app | P1 | active | admin (authors), admin as end user (opens the published app) |
studio-authoring.dashboard-widget-and-filter-types |
A package dashboard renders every widget type the spec declares — those Studio offers and those written through the API — and every global-filter type renders its control and re-scopes the widgets bound to it; Studio's two widget-type entries offer the same set | P2 | active | admin (authors, then views the published board) |
studio-authoring.report-authoring-options |
Reports authored in Studio render every report type from the same dataset — tabular, summary, matrix and joined — and their runtimeFilter, order and chart take effect in the published app, while a joined report refuses a chart and a block with no dataset | P2 | active | admin (authors, then views the published report) |
studio-authoring.app-and-nav-properties |
App and menu-entry keys reach the running app: branding, areas and context selectors render; an entry's viewName, recordId / recordMode, filters, badge, requiresObject and visible each change what the entry does or who sees it; hidden takes an app off the switcher and nothing else — and Studio's menu-entry inspector edits them | P2 | active | admin (authors), member (sees the published app) |
studio-authoring.authored-page-slots-and-variables |
Pages authored in a package take the page model's full shape: a slotted record page renders its slot overrides on the object's records, and page variables of all six types drive visibleWhen on the rendered page — at first render and live as a writer changes them | P2 | active | admin (authors, then views the published pages) |
studio-authoring.access-permission-set-lifecycle |
Permission sets are created, found and locked honestly in Studio's Access pillar: the New dialog derives the identifier and refuses one already taken — published or draft — the rail searches and shows its empty states, and on a read-only package New lands in its .custom pair while the packaged set offers no edit and the server refuses the forged write, and New similar on a packaged set copies it under a new name into that pair | P2 | active | admin |
studio-authoring.access-facets-runtime |
The Access pillar's facet tabs author what the runtime enforces: System capabilities chips grant a capability a gated action checks, a Row-level security policy (with its Test dry-run) scopes a member's reads and writes, and Tab visibility hides an app — from the member's app list and from the launcher alike | P1 | active | admin (authors the set), member M (holds it) |
studio-authoring.access-owd-and-suggestions |
The Access pillar's org-wide defaults panel and sharing suggestions do what they say: the OWD panel lists every package object, saves only the changed one and offers controlled-by-parent only with a master; a package's suggested set is granted to Everyone, revoked or dismissed from the pillar, with immediate effect | P2 | active | admin, member M (for the suggestion's runtime effect) |
studio-authoring.no-entry-property-matrix |
Authorable keys Studio has no control for still work when another door writes them: per metadata type, each key written into a package draft through the metadata API is stored, served after publish and takes its runtime effect | P2 | active | admin (writes the keys), member (the runtime legs that need a non-admin: field requiredPermissions, fileAccessDelegate, defaultRowScope) |
studio-authoring.removed-key-save-door-refusal |
A removed metadata key is refused at the save door at its real location, with a prescription, and nothing is stored — for the 33 keys QA run #26715 drove across nine types — whether the key still carries its tombstone or its retirement kit has aged out | P1 | active | admin |
studio-authoring.uninstalled-package-refused |
A write that names a package nobody installed is refused, for every metadata type as it already is for flows: the save door answers WRITABLE_PACKAGE_REQUIRED and stores nothing, publish-drafts on that id promotes nothing, and Studio opened on it says the package does not exist instead of rendering a writable builder | P1 | active | admin |
studio-authoring.package-customize-restore-display |
Customize a read-only base's view, dashboard or report in Studio: the edit lands in .custom as a declared override, every read serves it, the pair's export carries the declaration, and 'Restore package original' brings the base back | P1 | active | admin (holds manage_metadata; single posture), end user (renders the customized and the restored item) |
studio-authoring.package-extension-field-c |
Add a field to a read-only base object in Studio: it is written as an extension in .custom named xxx__c, a base field changes only within the display-property whitelist, and __c is refused outside a .custom pair |
P1 | active | admin (holds manage_metadata; single posture) |
studio-authoring.package-customization-counts-and-marks |
The Studio landing says 'n customized, m switched off' for each read-only base, and the All metadata lists mark the pair's items 'Customized' or 'Added' with an 'only customizations' filter — every number read from GET /packages/:id/customizations | P2 | active | admin |
studio-authoring.currency-home-amount-editor |
Studio's Home currency amount editor on a record-mode amount offers only the fields the engine can write, saves the three homeAmount pointers, and clears them | P2 | active | seeded admin (admin@objectos.ai / admin123): every step |
studio-authoring.currency-field-repointed-refusal |
A save that re-points a stored record-mode amount's currencyField answers 409 DESTRUCTIVE_CHANGE with the currency_field_repointed finding, naming what it does to stored rows and the remedies, and force lifts it | P2 | active | seeded admin (admin@objectos.ai / admin123): every call |
studio-authoring.action-preflight-authoring-refusals |
The action save door refuses a contradictory preflight at its located path: no params, beside execution 'aggregate', a hole outside the closed set (its own sentence for ${result.*}), an undeclared param, an unclosed hole, a URL off this origin, a non-GET method, and each seed contradiction |
P1 | active | seeded admin (admin@objectos.ai / admin123), over REST |
studio-authoring.page-row-table-block |
A row-table block draws the rows a page api binding answers: columns in authored order, enum values through the label map, datetimes in the display zone, a missing value as "—", the empty label, and an error panel for rows that are not a list or a format it does not draw |
P2 | active | seeded admin (admin@objectos.ai / admin123), signed in through the form |
studio-authoring.page-api-binding-reread-after-action |
A page's api-bound elements read again after the page's own successful action: one more GET, the old rows kept while it is in flight, the new answer drawn in place; a failed action reads nothing |
P2 | active | seeded admin (admin@objectos.ai / admin123), signed in through the form |
studio-authoring.dataset-member-vocabulary |
A dataset member's synonyms and description: the save door refuses a repeated synonym, one another member answers to, an untrimmed or overlong one and an overlong description, Studio's dataset form edits both, and list_datasets matches a saved synonym | P2 | active | seeded admin (admin@objectos.ai / admin123), over REST and in Studio, the same admin holding an osk_ API key, over MCP HTTP |
Neither a verified capability nor a declared gap — counted in neither column above.
| id | title | priority | status | personas |
|---|---|---|---|---|
studio-authoring.packaged-display-class-direct-edit |
Packaged views and dashboards are 'yours to edit directly' (ADR-0126 Regime O): the designer live-edits the PACKAGED artifact, publish reaches the end user, reset-overlay returns the shipped base — while a Regime-C flow in the same surface stays locked | P2 | retired | admin (authors the overlay in the designer), end user (renders the published change) |