Skip to content

Commit 46c6ca0

Browse files
committed
docs(qa): author the v18 line's capabilities into the platform checklist
48 `since: "v18"` items across 14 area files, grouped from the 714 consumed changesets under .changeset/pre/, the ADR-0087 step-18 registries and the landed ADR-0131 stages. Each item carries its permanent pins in automated.ref and the live steps that drive the capability against a booted showcase. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016NNWeTTi2eHhhrgDq9sJF8
1 parent 94114c1 commit 46c6ca0

14 files changed

Lines changed: 3521 additions & 0 deletions

‎docs/qa/platform-checklist/areas/access-security.json‎

Lines changed: 656 additions & 0 deletions
Large diffs are not rendered by default.

‎docs/qa/platform-checklist/areas/ai.json‎

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,74 @@
792792
"ref": "#22073"
793793
}
794794
]
795+
},
796+
{
797+
"id": "ai.mcp-coded-refusals-and-runtime-exposure",
798+
"title": "MCP on v18: a coded refusal on the data tools, list_actions and the record resource renders {error:{code,message,status}} (not the bare message), both MCP doors honour a runtime-authored object's apiEnabled:false including after a restart, and run_action withholds PERMISSION_DENIED details",
799+
"since": "v18",
800+
"status": "active",
801+
"revision": 1,
802+
"priority": "P2",
803+
"surface": "api",
804+
"personas": [
805+
"seeded admin (admin@objectos.ai / admin123) — the Default Organization owner and platform admin on a fresh boot"
806+
],
807+
"fixtures": {
808+
"app": "showcase",
809+
"requires": [
810+
"a fresh boot of the showcase: `pnpm dev -- --fresh -p PORT --seed-admin` (ephemeral DB; the seeded admin is printed)",
811+
"MCP enabled on the boot (ai.mcp-http-surface names the switch)",
812+
"a runtime-authored scratch object (PUT /api/v1/meta/object on a scratch boot) with apiEnabled:false"
813+
]
814+
},
815+
"steps": [
816+
"call the MCP get_record tool for a missing id; call query_records on the apiEnabled:false object",
817+
"restart the boot (same file DB) and repeat",
818+
"call run_action on an action the caller may not run"
819+
],
820+
"acceptance": [
821+
{
822+
"clause": "coded MCP refusals and runtime-object exposure — the permanent pins pass at the run subject sha (RUNNER rule 6: cite their output, never re-derive by hand)",
823+
"oracle": "test",
824+
"verify": "run each file named in automated.ref with its package's vitest (`pnpm --filter PKG exec vitest run --maxWorkers=2 FILE`, never through a bare `--`); every named file reports ≥1 test and 0 failed. A file that reports 0 tests or is not found is NOT a pass — it is a stale ref, fix the item",
825+
"evidence": "the vitest summary line per pin file, with the package name and the subject sha"
826+
},
827+
{
828+
"clause": "get_record for a missing id renders {error:{code:\"RECORD_NOT_FOUND\",status:404}}",
829+
"oracle": "api",
830+
"verify": "tool result body",
831+
"evidence": "the excerpt"
832+
},
833+
{
834+
"clause": "query_records on the runtime-authored apiEnabled:false object is refused before and after restart, and a deleted object leaves list_objects",
835+
"oracle": "api",
836+
"verify": "tool results across the restart",
837+
"evidence": "the excerpts"
838+
},
839+
{
840+
"clause": "run_action PERMISSION_DENIED carries no internal details",
841+
"oracle": "api",
842+
"verify": "tool result keys",
843+
"evidence": "the excerpt"
844+
}
845+
],
846+
"automated": {
847+
"kind": "unit",
848+
"ref": "packages/mcp/src/plugin.record-resource-exposure.test.ts + packages/mcp/src/mcp-action-refusal-details.test.ts + packages/objectql/src/plugin-runtime-object-metadata-copy.test.ts"
849+
},
850+
"source": [
851+
"packages/mcp/src/mcp-http-tools.ts",
852+
"packages/mcp/src/stdio-data-bridge.ts#enforceApiExposure",
853+
"v18 changesets (.changeset/pre/, consumed into 18.0.0-next.*): 23509-mcp-coded-refusal, 23661-runtime-object-metadata-copy, 23689-env-kernel-runtime-object-copy, 23529-mcp-action-tools-withhold-permission-details"
854+
],
855+
"history": [
856+
{
857+
"revision": 1,
858+
"date": "2026-10-16",
859+
"change": "initial — authored from the v18 line (18.0.0-next.*) delta: the capability landed on the v18 pre-release line and the ledger carried no `since: \"v18\"` item for it",
860+
"ref": "#23879"
861+
}
862+
]
795863
}
796864
]
797865
}

‎docs/qa/platform-checklist/areas/api-backend.json‎

Lines changed: 314 additions & 0 deletions
Large diffs are not rendered by default.

‎docs/qa/platform-checklist/areas/approvals.json‎

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1447,6 +1447,153 @@
14471447
"history": [
14481448
{ "revision": 1, "date": "2026-08-30", "change": "initial — the inbox's keyboard surface (documented in the page's own header and advertised by its hint bar) had no checklist coverage; the load-bearing halves are that r/a land the same server transition as the buttons and that quick-decidability gates hotkeys off rows whose decisions require typed outputs", "ref": "#sweep-2026-08-30" }
14491449
]
1450+
},
1451+
{
1452+
"id": "approvals.request-page-reply-and-reader-visibility",
1453+
"title": "Approval requests on v18: the request record page serves record:approval_decision and a Reply action that lands in its timeline, `enable.approvalsVisibleToReaders` lets a plain record reader see the record's requests read-only (and only then), the generic /data door serves request rows by approvals visibility, and titles shown to a reader use only what that reader may read",
1454+
"since": "v18",
1455+
"status": "active",
1456+
"revision": 1,
1457+
"priority": "P1",
1458+
"surface": "mixed",
1459+
"personas": [
1460+
"seeded admin (admin@objectos.ai / admin123) — the Default Organization owner and platform admin on a fresh boot",
1461+
"org member (a second sign-up on the same boot — joins the Default Organization as `member`, not platform admin)"
1462+
],
1463+
"fixtures": {
1464+
"app": "showcase",
1465+
"requires": [
1466+
"a fresh boot of the showcase: `pnpm dev -- --fresh -p PORT --seed-admin` (ephemeral DB; the seeded admin is printed)",
1467+
"a pending showcase approval request the member is NOT an approver on",
1468+
"for the reader leg: a scratch object (or showcase object via the scratch app) with enable.approvalsVisibleToReaders:true"
1469+
],
1470+
"knownGaps": [
1471+
"the console clause needs the vendored console — blocked(environment) while the .objectui-sha pin does not build against current spec (see records-forms.v18-semantic-defaults)"
1472+
]
1473+
},
1474+
"steps": [
1475+
"GET /api/v1/meta/page/sys_approval_request_detail and find record:approval_decision",
1476+
"as the pending approver POST /api/v1/approvals/requests/ID/comment {body}; read the timeline",
1477+
"as the member (non-participant) GET /api/v1/data/sys_approval_request/ID and list with a total",
1478+
"flip approvalsVisibleToReaders on the scratch object; as a plain reader list that record's requests; flip it off and repeat without restart"
1479+
],
1480+
"acceptance": [
1481+
{
1482+
"clause": "request page, reply, reader opt-in, generic-door read gate and reader-scoped titles — the permanent pins pass at the run subject sha (RUNNER rule 6: cite their output, never re-derive by hand)",
1483+
"oracle": "test",
1484+
"verify": "run each file named in automated.ref with its package's vitest (`pnpm --filter PKG exec vitest run --maxWorkers=2 FILE`, never through a bare `--`); every named file reports ≥1 test and 0 failed. A file that reports 0 tests or is not found is NOT a pass — it is a stale ref, fix the item",
1485+
"evidence": "the vitest summary line per pin file, with the package name and the subject sha"
1486+
},
1487+
{
1488+
"clause": "the request page carries record:approval_decision and the reply lands in the timeline (pending approver or submitter only)",
1489+
"oracle": "api",
1490+
"verify": "page body + timeline read",
1491+
"evidence": "excerpts"
1492+
},
1493+
{
1494+
"clause": "a non-participant's by-id read on /data/sys_approval_request → 404 and list totals exclude it",
1495+
"oracle": "api",
1496+
"verify": "status + total",
1497+
"evidence": "answers"
1498+
},
1499+
{
1500+
"clause": "the reader sees requests read-only with no actions only while the flag is on; the inbox is not widened",
1501+
"oracle": "api",
1502+
"verify": "list per flag state",
1503+
"evidence": "two lists"
1504+
},
1505+
{
1506+
"clause": "the console decision panel renders on the request page",
1507+
"oracle": "screenshot",
1508+
"verify": "request page after load",
1509+
"evidence": "one-line description"
1510+
}
1511+
],
1512+
"traps": [
1513+
"wrong-persona",
1514+
"stale-console-bundle"
1515+
],
1516+
"automated": {
1517+
"kind": "unit",
1518+
"ref": "packages/plugins/plugin-approvals/src/sys-approval-request-page.test.ts + packages/spec/src/ui/component-record-approval-decision-22472.test.ts + packages/plugins/plugin-approvals/src/record-reader-opt-in.integration.test.ts + packages/plugins/plugin-approvals/src/request-child-read-gate.integration.test.ts + packages/plugins/plugin-approvals/src/subject-title-reader-fls.integration.test.ts"
1519+
},
1520+
"source": [
1521+
"packages/plugins/plugin-approvals/src/sys-approval-request.page.ts",
1522+
"packages/plugins/plugin-approvals/src/request-read-gate.ts#bindRequestReadGate",
1523+
"packages/plugins/plugin-approvals/src/approval-service.ts",
1524+
"v18 changesets (.changeset/pre/, consumed into 18.0.0-next.*): 22472-spec-record-approval-decision, 22473-approval-request-page, 22560-platform-objects-approvals-visible-to-readers-form-row, 22560-plugin-approvals-declared-record-reader-tier, 22560-spec-approvals-visible-to-readers, 22559-approval-request-read-gate, 22589-approval-sibling-read-gates, 23594-subject-title-reader-fls, 23618-approval-title-family-served-fields, 23637-lookup-target-title-row-access"
1525+
],
1526+
"history": [
1527+
{
1528+
"revision": 1,
1529+
"date": "2026-10-16",
1530+
"change": "initial — authored from the v18 line (18.0.0-next.*) delta: the capability landed on the v18 pre-release line and the ledger carried no `since: \"v18\"` item for it",
1531+
"ref": "#23879"
1532+
}
1533+
]
1534+
},
1535+
{
1536+
"id": "approvals.act-door-and-admin-rescue-slate",
1537+
"title": "Approvals on v18: the email action door /approvals/act works through the dispatcher exactly as the self-hosted mount (GET renders, POST redeems, PUT 405 Allow: GET, POST, a dead link a 200 page, a policy-held session not 403'd before the token), and an approval over an unstaffed position opens on the org administrators as ordinary approvers",
1538+
"since": "v18",
1539+
"status": "active",
1540+
"revision": 1,
1541+
"priority": "P1",
1542+
"surface": "api",
1543+
"personas": [
1544+
"seeded admin (admin@objectos.ai / admin123) — the Default Organization owner and platform admin on a fresh boot",
1545+
"org member (a second sign-up on the same boot — joins the Default Organization as `member`, not platform admin)"
1546+
],
1547+
"fixtures": {
1548+
"app": "showcase",
1549+
"requires": [
1550+
"a fresh boot of the showcase: `pnpm dev -- --fresh -p PORT --seed-admin` (ephemeral DB; the seeded admin is printed)",
1551+
"an approval email action token (dev mail transport capture) for a pending request",
1552+
"an approval process whose approver is a position nobody holds (scratch process, default onEmptyApprovers)"
1553+
]
1554+
},
1555+
"steps": [
1556+
"GET /api/v1/approvals/act?token=T; POST the same; PUT the same; GET with a consumed token",
1557+
"submit a record into the unstaffed process; as the org admin GET /api/v1/approvals/requests (My Pending); decide it"
1558+
],
1559+
"acceptance": [
1560+
{
1561+
"clause": "the dispatcher act door and the admin_rescue slate — the permanent pins pass at the run subject sha (RUNNER rule 6: cite their output, never re-derive by hand)",
1562+
"oracle": "test",
1563+
"verify": "run each file named in automated.ref with its package's vitest (`pnpm --filter PKG exec vitest run --maxWorkers=2 FILE`, never through a bare `--`); every named file reports ≥1 test and 0 failed. A file that reports 0 tests or is not found is NOT a pass — it is a stale ref, fix the item",
1564+
"evidence": "the vitest summary line per pin file, with the package name and the subject sha"
1565+
},
1566+
{
1567+
"clause": "GET renders the action page, POST redeems, PUT → 405 with Allow: GET, POST, a dead token → a 200 page (not an error envelope)",
1568+
"oracle": "api",
1569+
"verify": "status + headers per verb",
1570+
"evidence": "four lines"
1571+
},
1572+
{
1573+
"clause": "the unstaffed request appears in each org admin's pending list and the decision is recorded via_override:false",
1574+
"oracle": "api",
1575+
"verify": "pending list + decision record",
1576+
"evidence": "excerpts"
1577+
}
1578+
],
1579+
"automated": {
1580+
"kind": "dogfood",
1581+
"ref": "packages/runtime/src/domains/approvals-act.test.ts + packages/plugins/plugin-approvals/src/action-page-member.integration.test.ts + packages/plugins/plugin-approvals/src/admin-rescue-named-slate.integration.test.ts + packages/qa/dogfood/test/approval-admin-rescue-slate.dogfood.test.ts"
1582+
},
1583+
"source": [
1584+
"packages/runtime/src/domains/approvals.ts",
1585+
"packages/core/src/security/auth-gate.ts",
1586+
"packages/plugins/plugin-approvals/src/approval-service.ts",
1587+
"v18 changesets (.changeset/pre/, consumed into 18.0.0-next.*): 22575-spec-approvals-action-page-member, 22577-approvals-act-allowlist, 22578-approvals-action-page-member, 22824-admin-rescue-named-slate"
1588+
],
1589+
"history": [
1590+
{
1591+
"revision": 1,
1592+
"date": "2026-10-16",
1593+
"change": "initial — authored from the v18 line (18.0.0-next.*) delta: the capability landed on the v18 pre-release line and the ledger carried no `since: \"v18\"` item for it; approvals.approver-resolution-matrix still says admin_rescue is decidable only via the privileged override — stale against 22824 (reported, not edited here)",
1594+
"ref": "#23879"
1595+
}
1596+
]
14501597
}
14511598
]
14521599
}

0 commit comments

Comments
 (0)