Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions docs/qa/platform-checklist/areas/api-backend.json
Original file line number Diff line number Diff line change
Expand Up @@ -3205,7 +3205,7 @@
"title": "/meta read doors on v18: GET /meta/app/PACKAGE_ID returns that package's app, `?member=` selects one bundle member on by-name doors, an unknown query parameter on any by-name door is refused 400, `?package=all` folds to the no-parameter answer, and the object definition marks an FLS-denied field unsortable for that caller",
"since": "v18",
"status": "active",
"revision": 4,
"revision": 5,
"priority": "P2",
"surface": "api",
"personas": [
Expand All @@ -3216,7 +3216,7 @@
"app": "showcase",
"requires": [
"a fresh boot of the showcase: `pnpm dev -- --fresh -p PORT --seed-admin` (ephemeral DB; the seeded admin is printed)",
"a showcase email template with two locale members: the showcase ships only the en-US member of showcase_task_done_email (examples/app-showcase/src/system/emails), so author the zh-CN member with PUT /api/v1/meta/email_template/showcase_task_done_email carrying `locale: 'zh-CN'` in the BODY — the save door's closed set is force, package, mode and surface, so ?member= is a READ parameter only"
"a showcase email template with two locale members: the showcase ships only the en-US member of showcase_task_done_email (examples/app-showcase/src/system/emails), so author the zh-CN member into the showcase's customization pair: POST /api/v1/packages/com.example.showcase/ensure-customization, then PUT /api/v1/meta/email_template/showcase_task_done_email?package=com.example.showcase.custom carrying `locale: 'zh-CN'` in the BODY and no `overrides` (the base ships no zh-CN member, so a declared override is refused 403 NOT_OVERRIDABLE, and a package-less PUT onto the shipped name is refused 403 NOT_OVERRIDABLE since ADR-0146 D11; packages/qa/dogfood/test/meta-read-doors-live.dogfood.test.ts authors it the same way) — the save door's closed set is force, package, mode and surface, so ?member= is a READ parameter only"
]
},
"steps": [
Expand Down Expand Up @@ -3296,6 +3296,12 @@
"date": "2026-10-27",
"change": "acceptance[1]–[4] are pinned at the layer their oracle names (the release-18.2.0 Tier 1 sweep #26468 scored a1–a4 partial: every pin but the data-sort dogfood stopped above the Hono adapter, and that one used a scratch permission set, not client_liaison). The new meta-read-doors-live.dogfood.test.ts drives each step through the HTTP stack of its own showcase boot, client_liaison bound through a sys_user_position row; automated.ref and acceptance[4].verify name it. Measured at base 74db43ef. No clause changed",
"ref": "#26572"
},
{
"revision": 5,
"date": "2026-11-04",
"change": "fixtures.requires[1] corrected: the bare PUT of a zh-CN member onto the shipped showcase_task_done_email is package-less, which ADR-0146 D11 refuses 403 NOT_OVERRIDABLE. The member is now authored into com.example.showcase.custom with no `overrides`, the shape meta-read-doors-live.dogfood.test.ts already uses. Measured on a fresh showcase boot at base 232d3bb5ef: package-less PUT 403; pair PUT with overrides 403 (the base ships no zh-CN member); pair PUT without overrides 200, then ?member=zh-CN serves it and ?member=en-US the shipped member. No clause changed",
"ref": "#30129"
}
]
},
Expand Down
10 changes: 8 additions & 2 deletions docs/qa/platform-checklist/areas/integration-system.json
Original file line number Diff line number Diff line change
Expand Up @@ -897,15 +897,15 @@
"title": "Email templates resolve from the registry (no sys_email_template row since ADR-0131 D6/D10), resolve (name, locale) with en-US fallback, render {{path}} holes, gate on required variables and active:false, survive admin edits across redeploys — and the raw POST /api/v1/email/send door authenticates, requires manage_platform_settings, bounds sentBy, from, headers, organizationId and identityMail, refuses anonymous, and 400s malformed input",
"since": "v15",
"status": "active",
"revision": 14,
"revision": 15,
"priority": "P2",
"surface": "mixed",
"fixtures": {
"app": "showcase",
"requires": [
"the shipped fixture: showcase_task_done_email (subject '✅ Task done: {{title}}', variables title required / project optional — examples/app-showcase/src/system/emails/index.ts). It declares no `category`: that key and `isSystem` are RETIRED (#22876, ADR-0049 — retiredKey() tombstones on the template schema), so a template authored with either is refused at parse with the prescription",
"a capturable email channel (dev transport / log capture — no real SMTP needed)",
"a second-locale scratch copy (same name, locale zh-CN) for the i18n-bundle clause",
"a zh-CN member of the shipped template for the i18n-bundle clause, authored into the showcase's customization pair: POST /api/v1/packages/com.example.showcase/ensure-customization (201 the first time, 200 after), then PUT /api/v1/meta/email_template/showcase_task_done_email?package=com.example.showcase.custom with the shipped body carrying locale: 'zh-CN' and NO `overrides`. The base ships en-US alone, so a zh-CN member is the pair's own item, not an override: declaring `overrides` for it answers 403 NOT_OVERRIDABLE ('… ships no email_template named … with locale 'zh-CN'', declared_package_ships_no_such_item, packages/metadata-protocol/src/protocol-packaged-base-refusal.ts), and a package-less PUT of it answers 403 NOT_OVERRIDABLE since ADR-0146 D11. Reset it with DELETE /api/v1/meta/email_template/showcase_task_done_email?package=com.example.showcase.custom&member=zh-CN",
"for acceptance[5]'s declared-source half a WRITABLE copy of the showcase (a scratch copy under /tmp, never the tree): the stock app is a read-only code package, so a run cannot edit its declared template source. QA run #23166 scored that half partial for want of one; the admin-edit half runs on stock"
],
"knownGaps": [
Expand Down Expand Up @@ -1090,6 +1090,12 @@
"date": "2026-11-04",
"change": "steps[3], [4], [6] and [9], acceptance[3].verify, acceptance[5].clause and acceptance[7].verify corrected from QA run #29890 (W5-FAIL, at 589049b0). (1) ADR-0146 D11: a package-less PUT of the shipped template answers 403 NOT_OVERRIDABLE, so the admin edit is an override saved in com.example.showcase.custom through the ensure door. (2) A non-string display name is 400 VALIDATION_FAILED since #29891, and every message the service refuses 400 VALIDATION_FAILED leaves a sys_email row 'failed' ('rejected before delivery: …'). (3) The clause's no-locale branch is unreachable over HTTP: the email channel always names the recipient's locale or the deployment default. (4) A member is read with ?member=, which ?locale= does not select. Read at base f68b47ca",
"ref": "#29906"
},
{
"revision": 15,
"date": "2026-11-04",
"change": "fixtures.requires[2] corrected: the 'same name, locale zh-CN' scratch copy was written package-less onto the shipped name, which ADR-0146 D11 refuses 403 NOT_OVERRIDABLE. The zh-CN member is now authored into com.example.showcase.custom with no `overrides`, since the base ships no zh-CN member and a declared override of one is refused 403 NOT_OVERRIDABLE (declared_package_ships_no_such_item). Measured on a fresh showcase boot at base 232d3bb5ef: package-less zh-CN PUT 403; ensure-customization 201; pair PUT with overrides 403; pair PUT without overrides 200, served by ?member=zh-CN; a scratch api notify flow then sent the zh-CN wording to a zh-CN-locale recipient and the en-US wording to an en-US one (sys_email 'sent'); DELETE ?package=…custom&member=zh-CN 200, then ?member=zh-CN 404. No clause changed",
"ref": "#30129"
}
]
},
Expand Down
12 changes: 9 additions & 3 deletions docs/qa/platform-checklist/areas/platform-core.json
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,7 @@
"title": "The built-in apps a stock boot REGISTERS (Setup / Account) render every merged-nav destination; app-level and entry-level gates are enforced, not errored — and Studio's deliberate absence is asserted, never hunted",
"since": "v15",
"status": "active",
"revision": 12,
"revision": 13,
"priority": "P0",
"surface": "browser",
"personas": [
Expand All @@ -631,10 +631,10 @@
"steps": [
"as admin, GET /api/v1/meta/app?id=setup and extract every merged nav destination — Setup is a SHELL of empty group anchors (packages/platform-objects/src/apps/setup.app.ts: group_overview/apps/people_org/access_control/approvals/configuration/diagnostics/integrations/advanced) filled by SETUP_NAV_CONTRIBUTIONS (setup-nav.contributions.ts) plus capability-plugin contributions (plugin-security Positions/Permission Sets, plugin-sharing Sharing Rules/Record Shares, plugin-approvals, plugin-webhooks)",
"GET /api/v1/meta/app with NO query first and record the names actually served — a stock boot answers exactly showcase_app, setup, account. Then GET /api/v1/meta/app?id=account (account.app.ts — Profile + Inbox/Security/Developer groups). ⚠️ GET /api/v1/meta/app?id=studio answers 200 {\"items\":[]} on every stock boot and that is the expected result (knownGap): record the absence as an assertion and move on — do NOT install @objectstack/studio to make the step runnable",
"as admin, hand-walk each destination in each app. EXPAND every nav group first: some render collapsed by default — Setup's Advanced group and Account's Developer group declare `expanded: false` (packages/platform-objects/src/apps/setup.app.ts, account.app.ts), and QA run #24557 found Setup's Configuration group collapsed as well — so a walk that never expands them never reaches their entries. Then navigate, wait for render, SCREENSHOT FIRST, then read the DOM — assert no pageerror, no 'failed to load', no blank <main>, no 'no actions configured' placeholder",
"as admin, hand-walk each destination in each app. At a window narrower than 1416 px (1280 px included) the console folds the sidebar to its icon rail, and Setup and Account open that way (ui/packages/app-shell/src/layout/consoleSidebarRail.ts CONSOLE_SIDEBAR_RAIL_BELOW_WIDTH, objectstack#27593; QA run #29877 met it at 1280 px): press the sidebar toggle at the app bar's left edge (Ctrl/⌘+B) to unfold it before expanding any group. EXPAND every nav group first: some render collapsed by default — Setup's Advanced group and Account's Developer group declare `expanded: false` (packages/platform-objects/src/apps/setup.app.ts, account.app.ts), and QA run #24557 found Setup's Configuration group collapsed as well — so a walk that never expands them never reaches their entries. Then navigate, wait for render, SCREENSHOT FIRST, then read the DOM — assert no pageerror, no 'failed to load', no blank <main>, no 'no actions configured' placeholder",
"Setup detail: confirm each settings URL entry (nav_settings_* → /apps/setup/system/settings/<namespace>) opens the settings namespace form — the 11 namespaces of a stock single-posture boot, localization/company/branding/auth/mail/sms/storage/ai/knowledge/lifecycle/feature_flags: the nav_settings_* entries of packages/platform-objects/src/apps/setup-nav.contributions.ts, plus nav_settings_branding, which packages/services/service-settings/src/settings-service-plugin.ts contributes only where no organization wall stands, and Users / Organization / Business Units / Teams / Sessions / OAuth Applications render. User preferences and identity links are not Setup destinations: open a user from Users and confirm the user page's Preferences and Linked Accounts tabs render that user's rows",
"Studio detail is NOT walked from here — the app is not registered on a stock boot (knownGap), so there is no merged nav to render. Its metadata:resource lists and component surfaces (App Builder, All Metadata Types, Packages, API Console, Flow Runs, Public Forms) are reached through the console surface at /_console/studio/<pkg>/<pillar> and are covered by area studio-authoring. What THIS item asserts about Studio is the absence itself, per clause 6",
"Account detail: confirm Profile (account:profile_card), Notifications (sys_inbox_message/mine), Approvals (nav_account_approvals, the approvals:inbox component, served as …/component/approvals/inbox — the Approvals Inbox, not the sys_approval_request grid; account.app.ts), Linked Accounts (sys_account), Active Sessions (sys_session/mine), API Keys (sys_api_key/mine), OAuth Applications (sys_oauth_application/mine) and Connect an Agent (nav_connect_agent) each render — 8 Account destinations and 50 Setup destinations for the admin on a stock single-org showcase boot, as QA run #28545 read them at eeec88d1 (GET /api/v1/meta/app leaves, which match the nav source minus its gates; 48 re-measured at 3fd80337 for #28338, QA run #27481 read 44 and 8, QA run #24557 read 42 at 5b14b7f3, 45 on 2026-10-01, and #9453 recorded 43 and 7). Recount from the payload each run",
"Account detail: confirm Profile (account:profile_card), Notifications (sys_inbox_message/mine), Approvals (nav_account_approvals, the approvals:inbox component, served as …/component/approvals/inbox — the Approvals Inbox, not the sys_approval_request grid; account.app.ts), Linked Accounts (sys_account), Active Sessions (sys_session/mine), API Keys (sys_api_key/mine), OAuth Applications (sys_oauth_application/mine) and Connect an Agent (nav_connect_agent) each render — 8 Account destinations and 46 Setup destinations for the admin on a stock single-org showcase boot, as QA run #29877 read them at 589049b0 and a fresh showcase boot re-read them at 232d3bb5ef (GET /api/v1/meta/app leaves, which match the nav source minus its gates). Since QA run #28545's reading Setup's Packaged automation page retired under ADR-0146 D11, leaving Packaged Actions (nav_packaged_actions, automation:packaged-actions; #28785), and its unfiltered Packages entry moved to Studio (#29547) (47 for #28927, 50 at eeec88d1 for QA run #28545, 48 re-measured at 3fd80337 for #28338, QA run #27481 read 44 and 8, QA run #24557 read 42 at 5b14b7f3, 45 on 2026-10-01, and #9453 recorded 43 and 7). Recount from the payload each run",
"confirm the gated entries resolve to ABSENT-not-erroring for the admin: nav_organizations (requiresService org-scoping) is absent in single-org mode; nav_jwks Signing Keys is ABSENT for EVERY persona, admin included — the entry was removed in #7544 because sys_jwks declares apiEnabled:false, so its list answers OBJECT_API_DISABLED (404) for all callers and no permission gate could prune it; SSO Providers is absent unless OS_SSO_ENABLED (knownGap)",
"sign in as the plain member: attempt to open Setup (app name setup) — capture the app-level refusal (App.requiredPermissions setup.access); open Account (declares no requiredPermissions) — capture it opening. Studio is not part of this comparison: it is absent for EVERY persona including the admin, so a member failing to reach it proves nothing about the gate (the same reasoning #7544 applied to nav_jwks)",
"as the member, GET /api/v1/meta/app for a reachable app and confirm every manage_platform_settings-gated entry (API Keys, the manage_platform_settings settings URLs) is ABSENT from the member's payload — the server prunes, the client does not merely hide. JWKS is deliberately NOT in this list any more: it is absent for admins too, so finding it absent for a member proves nothing about the gate (#7544)",
Expand Down Expand Up @@ -761,6 +761,12 @@
"date": "2026-11-01",
"change": "Two QA run #28545 (W3-C1R) findings. negative[3], stale since #27507: the member's settings route no longer renders inside the app shell it was opened from. AppContent.tsx holds a Setup pseudo-route until Setup's access verdict, then draws the 'You don't have access to this app' screen above the layout, with no shell; the page never mounts, so the wire half is driven directly (GET /api/settings/NAMESPACE, 403 SETTINGS_FORBIDDEN, kept as the scored part). Counts: steps[4] lists the 11 namespaces a stock boot serves (sms and lifecycle added; setup-nav.contributions.ts plus the unwalled-only branding entry), and steps[5] carries #28545's 50 Setup and 8 Account destinations, which stay 'recount from the payload each run'. The namespace list is read from source; the 50 is #28545's live reading. No clause weakened. Read from source at base 6b9c1ca991. Wave anchor #27377, wave-3 accuracy slice S9 (#28641); finding parked in anchor comment 6554042054",
"ref": "#28545"
},
{
"revision": 13,
"date": "2026-11-04",
"change": "steps[2] and steps[5] corrected, two QA run #29877 (W5-P0, at 589049b0) findings parked in comment 6600018008 on #27377 that #29906 did not carry; revision 7's steps[2]/[5] row is an older, different fix. steps[5]: Setup serves 46 destinations (Account 8), not 50; Packaged automation retired under ADR-0146 D11 (#28785) and the unfiltered Packages entry left Setup (#29547). steps[2]: below 1416 px, 1280 px included, Setup and Account open on the icon rail (consoleSidebarRail.ts CONSOLE_SIDEBAR_RAIL_BELOW_WIDTH), so the walk unfolds the sidebar before it expands groups. The 46 / 8 re-read on a fresh showcase boot at base 232d3bb5ef (GET /api/v1/meta/app?id=setup / ?id=account, groups excluded); the rail threshold read from source, not driven live. No clause changed",
"ref": "#30129"
}
]
},
Expand Down
Loading
Loading