Skip to content

Commit 93e6c1a

Browse files
docs(qa): 18.0 sweep anchor round 17 — the ledger's remaining checklist-text findings, the console pin's stale citations and 79 "showcase isolated" respellings (#25003)
Refs #24579 Clause-②: no Round 17 of the 18.0 sweep's wave anchor (claim `6303585734`, PM loop round 32). It applies the ledger's remaining checklist-text findings: #24903's follow-through (PR #24967), round 16's carried findings (PR #24963's acceptance notes), PR #24982's pin findings after the console pin moved to objectui `cf153eb2e535`, round 14's widening candidates (PR #24857), and round 12's "showcase isolated" spellings (landing record `6287983829`). Only checklist text changes. 85 items in 10 area files each take one `revision` bump and one `history` row, and each row names its source and finding. There is no product code, test, pin, changeset text or `RUNNER.md` change, and no new item. - Base `e4d604efd3`. `origin/main` `4fe3af9d7e` is merged in `6c4b8526af`. Its five commits touch no `docs/qa/**` path and none of the sources these edits cite. - Every item, pin and objectui spec named below was re-read at the base, or at the console pin for objectui, before it was written. objectui was read with `git show` from a full scratch clone (`--is-shallow-repository` false). - A scripted span editor made every edit. It is round 16's editor, unchanged, and it never re-serialises a file. For each area file it re-parses the result and asserts four things: - A1: the new document equals the old one with the declared ops applied. - A2: every other item and top-level key is value-equal. - A3: each edited item's changed paths lie inside its declared fields (array edits by exact index), plus `revision` and the one new history row. - A4: the text outside the edited items is byte-identical. - A whole-branch check against the base agrees: 85 items changed, each with revision +1 and exactly one appended row, and no other path changed. - The new history rows carry the placeholder ref `#PENDING-24579R17`, because a row's `ref` names this PR and the PR had no number yet. The next commit on this branch swaps in this PR's number and changes nothing else. The gates are re-run on that head, and the report comment on #24579 records them. ## Changes | finding | item | field | old → new | evidence read at `e4d604efd3` | |:--|:--|:--|:--|:--| | #24903 (PR #24967): the repaired production-guard case | `cli.dev-automigrate-policy` | `automated.ref`; `fixtures.knownGaps[2]` removed | the production case "scores NOTHING (knownGaps[2])" → the case, beside its development control, scores `acceptance[2]` at the driver layer, partial; `steps[3]`'s production boot stays the live leg | `sql-driver-schema-drift.test.ts` (blob `1f2ed8c72ca2`): under `NODE_ENV=production` with `autoMigrate: 'safe'`, `SqlDriver.initObjects` over in-memory better-sqlite3 keeps a `current_user` column DEFAULT, still reports it `safe` / `drop_column_default`, and its stub logger's warning carries the stable prefix. The remedy after the em dash is unasserted, and no boot log is read. The guard is `reconcileAndWarnDrift` in `sql-driver.ts`. | | PR #24963 (a): a P0 api clause's readonly half "scored from the pins" | `records-forms.crud-roundtrip` | `acceptance[6]` (clause, verify, evidence); `automated` removed; `fixtures.knownGaps[1]` added | "Score that half from the pins in `automated`, never as blocked(fixture) … no live run can stage it" → drive it at the clone door on a source row whose `lead_score` the run planted in its own file DB with node:sqlite, else `blocked(fixture)`. The pins move to `knownGaps[1]` as evidence of their own layers, and `automated` goes, because no pin holds a full clause | `protocol.readonly-insert.test.ts` drives `cloneData` over a stub engine. `engine-insert-static-readonly-strip.test.ts` drives a real engine over a recording driver, with no HTTP. `cloneData` (`protocol.ts`) copies the source row whole into `engine.insert` and answers the engine's drop as `droppedFields`. `lead_score` is `readonly` with no `defaultValue` (`contact.object.ts`). | | PR #24963 (b): `automated.ref` claims "acceptance[0]'s NARROWING half ONLY" | `cli.datasource-introspect-codegen` | `automated` removed; `fixtures.knownGaps[3]` added; `knownGaps[2]` and `acceptance[0].verify` re-pointed | a ref holding half a clause → no ref; the knownGap names each pin's layer and when `automated` may return (round 15's form) | `remote-tables-twin.equivalence.test.ts`: the real `ExternalDatasourceService` over a fake introspector, through the real `HonoHttpServer` (route layer). `external-datasource-service.test.ts`: the service. `envelope-unwrap.test.ts`: the CLI over a stubbed fetch. `acceptance[0]` scores the CLI's printed listing against a served datasource. | | PR #24963 (c), anchor comment `6290946648`: "a second signed-up user" | `records-forms.record-discussion-mentions` | `personas[1]`, `fixtures.knownGaps[0]` | a second signed-up user, and the mention and bell clauses `blocked(fixture)` without one → a user the admin mints with `POST /api/v1/auth/admin/create-user`, which then changes its password; ⛔ never `blocked(fixture)` on the 403 | `audience-posture.ts` `resolveAudience`: no `auth.audience` declared ⇒ `invite_only`, and an uninvited sign-up answers 403 `SELF_REGISTRATION_CLOSED`. `admin-user-endpoints.ts` `runAdminCreateUser`: `mustChangePassword` defaults true. `steps[13]` (revision 5) already uses this door. | | PR #24982: a citation absent at both pins | `approvals.record-page-decisions` | `source[2]`; `fixtures.knownGaps[0]` added | `RecordDetailView.approvalDecisionActions.test.tsx` → objectui `RecordDetailView.approvalDeclaredActions.test.tsx` (blob `9519ae70f743`), plus this repo's `sys-approval-request.object.test.ts` for the one-dialog half; the knownGap says that the rest of the item still describes the retired header buttons | objectui `99782f961` (objectui#3055) deleted the file and retired `buildApprovalDecisionActions`, moving the record page onto `sys_approval_request`'s declared actions. It is an ancestor of `616df6598b42` and of `cf153eb2e535` (exit 0, exit 0; control, `cf153eb2e535` as an ancestor of `99782f961`: exit 1). | | PR #24982: a changed blob | `automation.setup-packaged-automation-board` | none; the ref is confirmed | unchanged | `PackagedAutomationPage.test.tsx` `b321640a6100` → `aeb3e5f94e38` (objectui#13185, objectui#13279). It still stubs fetch, and its new cases (the Activation cell's "Not running here", the clone result's next steps) widen the mocked half only. `PackagedActionsSection.test.tsx` is unchanged. | | PR #24982: the current pin | `records-forms.crud-roundtrip` | `acceptance[4].verify` | console pin `616df6598b42` → `cf153eb2e535` | `e2e/live/record-history-display.spec.ts` is blob `7ebc45106cff` at both pins | | PR #24982: the current pin | `studio-authoring.first-run-loop` | `acceptance[0].verify` | `.objectui-sha 616df65` → `cf153eb2e535` | `e2e/live/studio-object-designer.spec.ts` is blob `58a7f1cbf024` at both pins. `studio-pkg-chip`, `package-form-id-input` and `package-form-submit` are still declared in app-shell's `StudioDesignSurface.tsx` and `PackageFormDialog.tsx`. Over the range, `e2e/live/` changes only `ci/backend.env`. | | PR #24857: widening candidate `studio-editor` | `studio-authoring.record-page-roundtrip` | `automated.ref`; `acceptance[1].verify` | "acceptance[0] ONLY … studio-editor.spec.ts … has never been in this ref" → plus `e2e/live/studio-editor.spec.ts` for `acceptance[1]`, carrier-neutrally | "Add block opens a block-type picker with configurable block kinds" (blob `19f9cc131654`) drives the live editor and asserts that the dialog offers Card, Section and Record details, which is `acceptance[1]`'s whole dom oracle. It edits a copy of `showcase_project_workspace`, an app page, but the picker offers one static catalogue whatever the page: `AddBlockButton` reads `TYPES_BY_CATEGORY` (objectui `block-types.ts`). | | round 12: "showcase isolated" read as the posture | 79 items in 9 area files | the one step that boots (`steps[0]`, or `steps[1]` in three items) | "boot showcase isolated" → "boot the showcase on its own port and DB", and four context variants | below | ## The "showcase isolated" respelling **79 respelled, 0 left as the posture.** Every non-history hit of "showcase isolated" was read in its item, and each names the dogfood §0 own-port boot. None is the `isolated` tenancy posture. The clearest case is `access-security.activation-write-operator-gate` `steps[0]`, which read "boot showcase isolated; … PROVE the posture is `single`". The 80th hit is a history row (`access-security.sharing-rules-widen` `history[3]`), and it is left as history. The spelling names the boot by what it is, in `RUNNER.md`'s own words for it: the trap table's counter for `shared-browser-tab` is "own port/DB (skill §0)". One hit already named the canonical boot line, and it now says "RUNNER's canonical checklist boot", `RUNNER.md`'s term for that invocation. The new spelling holds for every boot command the items use, `os serve` included (`records-forms.encrypted-field-behavior`). | old | new | hits | |:--|:--|--:| | `boot showcase isolated` | `boot the showcase on its own port and DB` | 66 | | `boot showcase isolated against a file DB` | `boot the showcase on its own port against its own file DB` | 4 | | `boot showcase isolated on …` | `boot the showcase on its own port and DB, on …` | 3 | | `boot the showcase isolated` | `boot the showcase on its own port and DB` | 3 | | `boot showcase isolated (own port + file DB per dogfood skill §0)` and its comma twin | `boot the showcase on its own port and file DB (dogfood skill §0)` | 2 | | `boot the showcase isolated (RUNNER canonical boot line: own port, own file DB, --seed-admin)` | `boot the showcase with RUNNER's canonical checklist boot (own port, own file DB, --seed-admin)` | 1 | By area: access-security 10, api-backend 13, approvals 17, automation 17, dashboards 1, integration-system 4, platform-core 1, records-forms 13, studio-authoring 3. ## Items left alone, with reasons - `integration-system.datasource-admin-lifecycle` (PR #24963 (d)): neither pin is added, because neither holds its clause's whole oracle at that clause's layer. - `admin-routes-auth-guard.test.ts` drives all 11 routes three times on one real `HonoHttpServer` mount: anonymous 401 `UNAUTHENTICATED`, unentitled 403 `PERMISSION_DENIED` naming the capability, entitled success, and the service method never called on a refusal. But its `auth` service is a double (`createSessionAuthService`), and its grants come from an engine double (`createGrantsEngine`, "the RBAC tables `resolveAuthzContext` reads, as a minimal engine double"). `acceptance[1]` is an api clause on a booted server, so the pin holds its route-layer half only. The ref's sentence "Neither drives the capability floor … drive os dev for every api clause" stays true of the two pins it names. - `datasource-route-ledger.conformance.test.ts` enumerates the registrar against a capturing mock `IHttpServer` and compares the result with `DATASOURCE_ROUTE_LEDGER`. That is `acceptance[8]`'s ledger half, which its `verify` already cites. The 404 `RESOURCE_NOT_FOUND` half is never driven, so it holds no whole clause. - `records-forms.master-detail-atomic-save` (PR #24857's `form-view-subforms` candidate): no widening. At `cf153eb2e535` (blob `9485f378abd7`) the spec drives the stock New Invoice dialog with ONE line. It records only `/api/v1/batch` requests, reads `batches[0]` and never counts them. It asserts the parent op, a `{$ref: 0}` child, the auto-filled description and unit price, and the computed amount in the payload, and it re-reads nothing. So it misses `acceptance[0]`'s "one batch, not N writes" and two lines, `acceptance[5]`'s stored-row read, and `acceptance[1]` and `[2]` entirely. The ref keeps `acceptance[4]`. - `automation.setup-packaged-automation-board` `automated.ref`: confirmed, as the table says. The item's revision bump is its `steps[0]` respelling, and its history row records the confirmation. - Not this round, as the dispatch says: a fresh-install item for #24827's order and the live generation-0 refusal; the liveness row of `auth.emailAndPassword.resetPasswordTokenExpiresIn`; the fixture gaps of #24838 and #24841. ## PM hypotheses, measured 1. "Round 14's two widening candidates still widen nothing." Half holds. `form-view-subforms.spec.ts` widens nothing (above). `studio-editor.spec.ts` asserts `acceptance[1]` of `studio-authoring.record-page-roundtrip` whole at its layer, so that ref widens. 2. "Fewer than five of the ~80 'isolated' hits are the posture." This holds: 0 of 79. ## Acceptance notes - Some edits were located beyond the dispatch's field list, inside items it names: - `approvals.record-page-decisions` `fixtures.knownGaps[0]`. Once `source[2]` names the declared-actions test, the steps and clauses contradict it. They describe `buildApprovalDecisionActions` (`approve_request` / `reject_request` in `record_header`, ordered -100 / -99, behind a client-side `canDecide`). At `cf153eb2e535` the record page renders `sys_approval_request`'s declared actions through `DeclaredActionsBar` above the page body: `approval_approve`, `approval_reject` and the other levers at `record_section`, gated by the server's `viewer` block. The knownGap says so, and no step or clause was rewritten. Re-deriving them is the anchor's call. Carrier: #24579. - `records-forms.crud-roundtrip`: `automated` is removed under round 15's rule, the same reading the dispatch names for (b). `acceptance[6].evidence` names the planted-row evidence. - `cli.datasource-introspect-codegen`: `knownGaps[2]` and `acceptance[0].verify` said "the pins in `automated`", and now point at `knownGaps[3]`. - `automation.setup-packaged-automation-board` `steps[3]` reads "confirm every switch reads On … 31 On / 1 Off". At `cf153eb2e535` the Activation cell reads "Not running here", with the switch still checked, for a flow the engine left unarmed (objectui#13159, `packagedFlows.ts` `activationReading`). On a default boot the engine reports a deployment-policy `unboundCause` for `showcase_scheduled_digest` and `showcase_task_due_reminder` (RUNNER.md, the scheduled-work entry). The switch reading still holds, but a count of the cell's "On" badges will not. Noted, not applied, because the dispatch scoped this item to its ref. Carrier: #24579. - Outside this round's spelling, 65 other non-history texts contain "isolated". Of these, 41 are the posture, 2 are other senses ("owner-isolated", "the isolated env"), and 22 name the own-port boot or its DB in other words: "an isolated boot on a file DB", "discard the isolated DB", "a dogfood-§0 isolated boot". Those 22 sit in 17 items: `access-security.platform-owner-email-anchor`, `automation.connector-dispatch-matrix`, `automation.packaged-flow-subflow-disable-refusal`, `automation.packaged-flow-clone-contract`, `platform-core.boot-health`, `platform-core.seed-integrity`, `platform-core.interrupted-migration-boot-report`, `platform-core.manifest-install-contract`, `platform-core.activation-ledger-registration-home`, `platform-core.activation-ledger-row-contract`, `platform-core.marketplace-install-local-lifecycle`, `platform-core.runtime-config-boot-read`, `platform-core.lifecycle-retention-sweep`, `platform-core.seed-mode-matrix`, `records-forms.field-group-visible-when`, `records-forms.field-unique-enforcement` and `studio-authoring.metadata-diagnostics-sweep`. The same reading risk applies. They are outside the claim's file surface, which names the "showcase isolated" spelling, so they are untouched. Carrier: #24579. - The dispatch's `records-forms.record-page-roundtrip` is `studio-authoring.record-page-roundtrip`: no `records-forms` item has that id, and PR #24857's note names the `studio-authoring` one. - The crud-roundtrip planting recipe and its expected answers (`droppedFields` naming `lead_score` with reason `readonly`, and the clone carrying no `lead_score`) are derived from source and were not replayed. The verify says so. - The objectui specs were read, not run. Their verdicts at `cf153eb2e535` are NOT MEASURED. ## Gates The derived list is `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack`. It is computed on the actual change set: 10 paths against merge base `4fe3af9d7`, at head `6c4b8526af`. It gives 13 commands. Each one ran at that head with its exit code captured before any pipe, and each exited 0: `node scripts/check-ci-filter-parity.mjs` · `node scripts/check-closing-keyword-parity.mjs` · `node scripts/check-closing-keyword-parity.mjs --self-test` · `node scripts/check-comment-mask-corpus.mjs` · `pnpm --filter @objectstack/lint run check:doc-formula-expressions` · `pnpm check:cross-package-test-inputs` · `pnpm check:doc-authoring` · `pnpm check:driver-memory-census` · `pnpm check:gitlink-declared` · `pnpm check:nul-bytes` · `pnpm check:platform-checklist` · `pnpm check:refd-timer-probe` · `pnpm check:watch-hint-literal` The first run of `check:doc-formula-expressions` refused with exit 3, a prerequisite: `@objectstack/formula` and `@objectstack/lint` were not built. Both were built under the shared verify lock (`VERDICT command-exit 0`, held 101 s, waited 0 s), and the rerun exited 0. The `--ran` reconciliation reads "13 derived, 13 run, 0 NOT-MEASURED, 0 UNRUN". No per-PR CI job runs `pnpm check:platform-checklist`, so this local reading is its evidence: | reading | base `e4d604efd3` | head `6c4b8526af` | |:--|:--|:--| | items | 16 areas, 328 items (323 active, 1 planned) | 16 areas, 328 items (323 active, 1 planned) | | line citations | 0 survive across 21 swept documents | 0 survive across 21 swept documents | | symbol anchors | 975/985 against 433 cited sources, 10 on the named residual (#16898), 18 file floors held | 975/985 against 433 cited sources, 10 on the named residual (#16898), 18 file floors held | The new texts add no symbol anchor and no line citation. `git merge-tree --write-tree origin/main HEAD` exited 0 against `4fe3af9d7e`. No open PR touches `docs/qa/platform-checklist/`. All 14 open PRs' file lists were read over REST; the three with more than 100 files were read page by page, at 349, 367 and 206 files, each equal to its `changed_files`. So there was no second merge-tree to run. There is no ablation, because no tested behaviour changed. `skip-changeset` was re-measured: `docs/qa/**` appears in none of the 73 non-private manifests' `files[]` (86 tracked `package.json` files), and the repo root is private. --- _Generated by [Claude Code](https://claude.ai/code/session_01FM29ZqLTrnPNXxijioZwMp)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 91e7286 commit 93e6c1a

10 files changed

Lines changed: 606 additions & 210 deletions

File tree

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

Lines changed: 76 additions & 21 deletions
Large diffs are not rendered by default.

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

Lines changed: 104 additions & 26 deletions
Large diffs are not rendered by default.

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

Lines changed: 92 additions & 47 deletions
Large diffs are not rendered by default.

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

Lines changed: 124 additions & 37 deletions
Large diffs are not rendered by default.

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

Lines changed: 15 additions & 12 deletions
Large diffs are not rendered by default.

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1154,7 +1154,7 @@
11541154
"title": "Scheduled report dispatch: the dispatcher ticks on a stock boot, a due schedule runs under the OWNER's authority or FAILS CLOSED with the refusal recorded on the row — never an RLS-bypassed run — and the delivery/bookkeeping contract (format fork, subject template, next-run advance) holds",
11551155
"since": "v15.1",
11561156
"status": "retired",
1157-
"revision": 2,
1157+
"revision": 3,
11581158
"priority": "P1",
11591159
"surface": "api",
11601160
"personas": [
@@ -1175,7 +1175,7 @@
11751175
]
11761176
},
11771177
"steps": [
1178-
"boot showcase isolated (dogfood §0); read the boot log for the dispatcher registration line — 'dispatcher registered with job service' or 'dispatcher registered (setInterval fallback)', with its intervalMs — and for the email arm (LogTransport line, or the 'no email service — schedules will fire without delivery' warn)",
1178+
"boot the showcase on its own port and DB (dogfood §0); read the boot log for the dispatcher registration line — 'dispatcher registered with job service' or 'dispatcher registered (setInterval fallback)', with its intervalMs — and for the email arm (LogTransport line, or the 'no email service — schedules will fire without delivery' warn)",
11791179
"as a fresh member: POST /api/v1/reports (a report over an object the member can read, e.g. showcase_task) then POST /api/v1/reports/:id/schedule with { recipients: ['<member email>'], intervalMinutes: 1, format: 'csv', subjectTemplate: '{{name}}: {{rows}} on {{date}}' } — record the receipt's next_run_at (first fire = create time + interval; an invalid cronExpression is refused eagerly at create, not left to fall back silently at 3am)",
11801180
"wait past next_run_at + one dispatcher tick, then as the member GET /api/v1/reports/:id/schedules and read the row's last_status / last_error / last_sent_at / next_run_at",
11811181
"capture the server log lines for the tick (ReportService.dispatchDue warn/error lines)",
@@ -1252,6 +1252,12 @@
12521252
"date": "2026-09-25",
12531253
"change": "retired — the saved-report stack it exercised was removed (#20102); see retiredReason",
12541254
"ref": "#20102"
1255+
},
1256+
{
1257+
"revision": 3,
1258+
"date": "2026-10-20",
1259+
"change": "steps[0] respelled: 'boot showcase isolated' → 'boot the showcase on its own port and DB'. Round 12's out-of-scope finding (landing record 6287983829 on wave anchor #24579): the phrase 'showcase isolated' named the dogfood §0 own-port boot, and a runner read it as the `isolated` tenancy posture (OS_TENANCY_POSTURE=isolated). The new spelling names that boot by what it is, in RUNNER.md's own words for it (the trap table's counter: own port/DB, skill §0), and names no posture. Read at base e4d604efd3. No clause changed",
1260+
"ref": "#25003"
12551261
}
12561262
],
12571263
"retiredReason": "Capability removed (ADR-0049 enforce-or-remove; maintainer ruling 2026-09-25, #20102): the saved-report schedule dispatcher this item drove left with the rest of the saved-report stack (sys_report_schedule, the /api/v1/reports schedule routes, @objectstack/plugin-reports), which had zero consumers. The platform has no scheduled delivery of a report today; scheduled delivery for `report` metadata is explicitly NOT built by that ruling — a real need is a new card on the metadata kind, and a new item with it."

‎docs/qa/platform-checklist/areas/integration-system.json‎

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,7 +1123,7 @@
11231123
"title": "A declared external datasource federates: its objects query in place over REST, read-only",
11241124
"since": "v16",
11251125
"status": "active",
1126-
"revision": 4,
1126+
"revision": 5,
11271127
"priority": "P1",
11281128
"surface": "api",
11291129
"personas": [
@@ -1136,7 +1136,7 @@
11361136
]
11371137
},
11381138
"steps": [
1139-
"boot showcase isolated; sign in as admin",
1139+
"boot the showcase on its own port and DB; sign in as admin",
11401140
"GET /api/v1/meta and confirm the federated objects are registered",
11411141
"GET /api/v1/data/<external object> and read fixture rows",
11421142
"attempt a write (POST/PATCH) against the read-only external object; capture the refusal",
@@ -1182,7 +1182,8 @@
11821182
},
11831183
{ "revision": 2, "date": "2026-08-18", "change": "re-worded clause 3 and step 5 for this item's declared api surface. Both named the Setup → Datasources console page inside an item whose surface is api, so the clause could only ever be scored by a substitution the item did not authorize. The datasources admin API is what the page renders from, so it is now the oracle and the page is the optional substitution — surface left as api rather than widened to mixed, since every other clause here is a server read (#9417)", "ref": "#9386" },
11841184
{ "revision": 3, "date": "2026-10-16", "change": "acceptance[0].verify corrected (checklist-accuracy finding of QA run #23922, wave #23878): 'filters/$top work as on a native object' — OData $filter is refused 400 INVALID_FILTER on /data (the filter must be JSON), while the JSON filter param and top work, which is what #23922 used. The verify text names the working spellings and the refusal. Not loosened: a filter that returns the unfiltered set still FAILS", "ref": "#24036" },
1185-
{ "revision": 4, "date": "2026-10-20", "change": "checklist-accuracy findings of QA run #24575 (18.0 sweep, 5b14b7f3; wave anchor #24579 §3). acceptance[2]'s oracle still read 'screenshot' and its evidence 'screenshot', although revision 2 made the datasources API the oracle; both now name the API reads. steps[4] names the console route for the substitution (…/setup/datasources is not one). fixtures.requires[0] says where the fixture DB is provisioned. Not loosened: the clause and its verify are unchanged", "ref": "#24717" }
1185+
{ "revision": 4, "date": "2026-10-20", "change": "checklist-accuracy findings of QA run #24575 (18.0 sweep, 5b14b7f3; wave anchor #24579 §3). acceptance[2]'s oracle still read 'screenshot' and its evidence 'screenshot', although revision 2 made the datasources API the oracle; both now name the API reads. steps[4] names the console route for the substitution (…/setup/datasources is not one). fixtures.requires[0] says where the fixture DB is provisioned. Not loosened: the clause and its verify are unchanged", "ref": "#24717" },
1186+
{ "revision": 5, "date": "2026-10-20", "change": "steps[0] respelled: 'boot showcase isolated' → 'boot the showcase on its own port and DB'. Round 12's out-of-scope finding (landing record 6287983829 on wave anchor #24579): the phrase 'showcase isolated' named the dogfood §0 own-port boot, and a runner read it as the `isolated` tenancy posture (OS_TENANCY_POSTURE=isolated). The new spelling names that boot by what it is, in RUNNER.md's own words for it (the trap table's counter: own port/DB, skill §0), and names no posture. Read at base e4d604efd3. No clause changed", "ref": "#25003" }
11861187
]
11871188
},
11881189
{
@@ -1346,7 +1347,7 @@
13461347
"title": "External-datasource schema introspection happy path: remote-tables lists live tables with columnCount (?schema= honoured since #7955), object-draft renders a reviewable *.object.ts, both route spellings answer as one operation behind the platform auth floor",
13471348
"since": "v16",
13481349
"status": "active",
1349-
"revision": 4,
1350+
"revision": 5,
13501351
"priority": "P1",
13511352
"surface": "api",
13521353
"personas": [
@@ -1365,7 +1366,7 @@
13651366
]
13661367
},
13671368
"steps": [
1368-
"boot showcase isolated via os dev; sign in as the admin holding manage_platform_settings; also mint an authenticated session holding no capability",
1369+
"boot the showcase on its own port and DB via os dev; sign in as the admin holding manage_platform_settings; also mint an authenticated session holding no capability",
13691370
"GET /api/v1/datasources/showcase_external/remote-tables — record the table set with per-table columnCount",
13701371
"repeat with ?schema=main and with a repeated ?schema=a&schema=b — record status + set for each (see knownGaps for what SQLite can and cannot show here)",
13711372
"GET /api/v1/datasources/showcase_external/external/tables (the twin spelling) — compare the set against step 2",
@@ -1452,6 +1453,12 @@
14521453
"date": "2026-10-20",
14531454
"change": "fixtures.knownGaps[0] corrected — checklist-accuracy finding of QA run #24615 (18.0 sweep round 2, ba4afcc2; wave anchor #24579 §3, round 2 part 2). It said a schema-qualified Postgres fixture would make ?schema= narrowing live-scoreable; measured on PostgreSQL 16, the SQL driver's Postgres introspection returns bare names from current_schemas(false) too, so narrowing stays unobservable live. That is the product defect #24664, split from #24619 row (c); acceptance[1] states the #7955 contract and stays as written, scored by its pin. No clause changed",
14541455
"ref": "#24717"
1456+
},
1457+
{
1458+
"revision": 5,
1459+
"date": "2026-10-20",
1460+
"change": "steps[0] respelled: 'boot showcase isolated' → 'boot the showcase on its own port and DB'. Round 12's out-of-scope finding (landing record 6287983829 on wave anchor #24579): the phrase 'showcase isolated' named the dogfood §0 own-port boot, and a runner read it as the `isolated` tenancy posture (OS_TENANCY_POSTURE=isolated). The new spelling names that boot by what it is, in RUNNER.md's own words for it (the trap table's counter: own port/DB, skill §0), and names no posture. Read at base e4d604efd3. No clause changed",
1461+
"ref": "#25003"
14551462
}
14561463
]
14571464
},
@@ -1588,7 +1595,7 @@
15881595
"title": "A recipient preference muting the inbox channel for a topic suppresses delivery (no inbox row, no dead-letter fake); flipping it back resumes; a sys_notification_template renders through a delivery",
15891596
"since": "v16",
15901597
"status": "active",
1591-
"revision": 3,
1598+
"revision": 4,
15921599
"priority": "P2",
15931600
"surface": "mixed",
15941601
"personas": [
@@ -1608,7 +1615,7 @@
16081615
]
16091616
},
16101617
"steps": [
1611-
"boot showcase isolated; personas admin + assignee; establish the happy path first (or lean on notify-inbox-delivery): reassign a showcase_task to the assignee → showcase_task_assigned_notify fires topic 'task.assigned' on channel 'inbox' → one sys_inbox_message for the assignee, visible in GET /api/v1/notifications",
1618+
"boot the showcase on its own port and DB; personas admin + assignee; establish the happy path first (or lean on notify-inbox-delivery): reassign a showcase_task to the assignee → showcase_task_assigned_notify fires topic 'task.assigned' on channel 'inbox' → one sys_inbox_message for the assignee, visible in GET /api/v1/notifications",
16121619
"author a suppression row via POST /api/v1/data/sys_notification_preference: { user_id: <assigneeId>, topic: 'task.assigned', channel: 'inbox', enabled: false } — this is the 'category' the task names; the model's field is `topic` (most-specific-wins over the built-in default-ON)",
16131620
"re-fire the notify flow (reassign the task to the same assignee again); GET /api/v1/notifications as the assignee and confirm NO new inbox row landed",
16141621
"read the messaging outbox / dead-letter surface and confirm there is no dead-letter row for the muted (recipient, 'inbox') — a deliberate mute is a DROP by the preference filter, not a dead-letter (dead-letter is reserved for unimplemented channels, #3197)",
@@ -1683,6 +1690,12 @@
16831690
"date": "2026-10-16",
16841691
"change": "steps[6] and acceptance[4].clause corrected (checklist-accuracy finding of QA run #23922, wave #23878). 'with locale fallback' overstated the ladder: the store walks only DOWN (en-US → en → en), so a recipient with no locale resolves the deployment default 'en' and an en-US-only template row is never used — #23922 authored its row at 'en'. The step now says where to author the row, and the clause names the ladder. Not loosened: the render must still carry the template's substituted subject and body",
16851692
"ref": "#24036"
1693+
},
1694+
{
1695+
"revision": 4,
1696+
"date": "2026-10-20",
1697+
"change": "steps[0] respelled: 'boot showcase isolated' → 'boot the showcase on its own port and DB'. Round 12's out-of-scope finding (landing record 6287983829 on wave anchor #24579): the phrase 'showcase isolated' named the dogfood §0 own-port boot, and a runner read it as the `isolated` tenancy posture (OS_TENANCY_POSTURE=isolated). The new spelling names that boot by what it is, in RUNNER.md's own words for it (the trap table's counter: own port/DB, skill §0), and names no posture. Read at base e4d604efd3. No clause changed",
1698+
"ref": "#25003"
16861699
}
16871700
]
16881701
},
@@ -1944,7 +1957,7 @@
19441957
"title": "Setup → Datasources federation UI (ADR-0015 §6.4): SchemaBrowser mirrors the remote-table listing, ImportObjectDialog lands a REAL object through the metadata channel, Refresh catalog and ValidationPanel drive the three previously-uncovered federation routes (import / refresh-catalog / validate) behind their capability floors",
19451958
"since": "v16",
19461959
"status": "active",
1947-
"revision": 4,
1960+
"revision": 5,
19481961
"priority": "P1",
19491962
"surface": "mixed",
19501963
"personas": [
@@ -1966,7 +1979,7 @@
19661979
]
19671980
},
19681981
"steps": [
1969-
"boot showcase isolated via os dev with the console; sign in as the entitled admin; pre-capture the API ground truth: GET /api/v1/datasources/showcase_external/external/tables and POST .../external/validate",
1982+
"boot the showcase on its own port and DB via os dev with the console; sign in as the entitled admin; pre-capture the API ground truth: GET /api/v1/datasources/showcase_external/external/tables and POST .../external/validate",
19701983
"type the datasource's engine EDIT route directly, /_console/apps/setup/metadata/datasource/showcase_external — no entry from the Setup list reaches it: Setup → Datasources (…/metadata/datasource, which the left-nav names, objectui#3660/register.ts) is the custom DatasourceResourcePage list, whose rows offer Test / Sync objects / Edit / Delete and neither open the item nor render the panel (objectui DatasourceResourcePage.tsx, at the sweep pin 4016370a and the shipped pin 12dc7b47c340; QA run #24615). On the edit route the ExternalDatasourcePanel renders (DatasourcePreview.tsx keys it off schemaMode !== 'managed') with the schemaMode badge and the read-only/writes-allowed pill; screenshot FIRST, then read the DOM",
19711984
"Tables tab: SchemaBrowser loads the remote tables (mount + explicit Refresh only — never a timer); compare the rendered list name-by-name and columnCount-by-columnCount against the pre-captured listing",
19721985
"header 'Refresh catalog': click it and capture the POST /api/v1/datasources/showcase_external/external/refresh-catalog on the network; the snapshot timestamp renders from the returned catalog.snapshotAt",
@@ -2070,6 +2083,12 @@
20702083
"date": "2026-10-20",
20712084
"change": "checklist-accuracy findings of QA run #24615 (18.0 sweep round 2, ba4afcc2, driven by hand at the console pin 4016370a; wave anchor #24579 §3, round 2 part 2), re-read in objectui at the shipped pin 12dc7b47c340. steps[1]: no entry from the Setup list reaches the panel (DatasourceResourcePage rows never open the item), so the step names the engine edit route. acceptance[0] (clause, verify, evidence): the save-first guidance is unreachable (datasource is not in CREATE_MODE_CANVAS_TYPES), so the clause scores the observable half, no name-less call, and records the guidance half not-run. steps[7]: the quoted refusal was POST /meta/_migrate-stored's; the item save door answers 403 FORBIDDEN 'Saving a metadata item requires…'. knownGaps[3] carries #24615's drift recipe that needs no scratch copy; knownGaps[4] (new) records that a repeated import answers 201 and overwrites, which no clause scores. acceptance[3].verify's comma-range line citation names the handler instead (the line-citation rot class). Not loosened: every other clause and negative is unchanged",
20722085
"ref": "#24717"
2086+
},
2087+
{
2088+
"revision": 5,
2089+
"date": "2026-10-20",
2090+
"change": "steps[0] respelled: 'boot showcase isolated' → 'boot the showcase on its own port and DB'. Round 12's out-of-scope finding (landing record 6287983829 on wave anchor #24579): the phrase 'showcase isolated' named the dogfood §0 own-port boot, and a runner read it as the `isolated` tenancy posture (OS_TENANCY_POSTURE=isolated). The new spelling names that boot by what it is, in RUNNER.md's own words for it (the trap table's counter: own port/DB, skill §0), and names no posture. Read at base e4d604efd3. No clause changed",
2091+
"ref": "#25003"
20732092
}
20742093
]
20752094
},

0 commit comments

Comments
 (0)