Skip to content

Commit 40bba68

Browse files
docs(qa): approvals ledger — 19 checklist-accuracy edits from the 18.2.0 sweep (#26116)
<!-- claude-projects-attribution: {"github_login":"os-steve"} --> _Requested by **Steve** · [project thread](https://claude.ai/code/project/chan_01FdL1XeUyvVNxLreh3F4Qi9?thread=cmsg_01FdL1XeUyvVNxLreh3F4Qi93z9uWCcha6ic7Xyx4VeoJa)_ Fixes #25838 Clause-②: no Metadata-protocol: none Applies the 19 `docs/qa/platform-checklist/areas/approvals.json` lines of card #25838, the checklist-accuracy findings of the 18.2.0 release sweep (wave anchor #25807), and respells the retired objectui pin flow in the same file (#26052, #26035). Only checklist text changes: one file, ten items. Each item takes one `revision` bump and one `history` row, and each row names its run record (QA run #25812, #25815 or #25817, all at framework `6679644a`) and this card. No product code, test, pin, RUNNER.md or changeset changes. `skip-changeset`: `docs/qa/**` ships in no package. ## How it was done - Base `9753d163` (origin/main). `approvals.json` has no commit on main since `73432299` (2026-10-21), so it is unchanged since the card was filed and since the sweep's base `6679644a`. The card's "file unchanged since filing" assumption holds. - Every line was re-read against main before it was written: the pins and their harnesses under `packages/`, the flows in `examples/app-showcase`, and the console under `ui/` (the objectui paths the items cite, re-read at their `ui/` location). - **No line turned out to be a product defect.** All 19 are stale or over-claiming text, so nothing goes to `out_of_scope_findings` as a defect. - A scripted span editor made every edit and never re-serialised the file. It re-parses the result and asserts three things. The new document equals the old one with the declared ops applied. Every other item and top-level key is value-equal. The text outside the ten edited items is byte-identical. - The ten new history rows carry the placeholder ref `#PENDING-25838`. The next commit on this branch swaps in this PR's number and changes nothing else. ## Changes | run | item (rev) | finding | change | |:--|:--|:--|:--| | #25812 | `account-app-entry` (4→5) | "drawer" in steps 6–7 and acc[1], acc[3], acc[4]; two URL segments for acc[5] | steps[5]–[6], acceptance[1], [3], [4]: the row click or `?request=` navigates to `/apps/APP/sys_approval_request/record/ID` (objectui#12484; `ui/apps/console/src/pages/system/ApprovalsInboxPage.tsx` `requestPagePath`). acc[3]'s after-state is now "the decision actions stop rendering": their `visible` predicates read `record.viewer.can_act`, and no can_act=false explanation exists on the request page. acc[5] names `com.objectstack.account` and the alias `account` (`packages/apps/account/src/index.ts`). | | #26052 | same item | retired pin flow | fixtures.requires[0], steps[0], acceptance[0]: `pnpm console:build` from this tree replaces `pnpm objectui:build` + `.objectui-sha`. With no dist stamp left, acc[0] reads console:build's ready line at the run's framework SHA (`packages/console/build-dist.sh`). The stale `check:console-sha` remark is gone because that script no longer exists. acc[6]: AppHeader.tsx under `ui/`, not "at the console pin". | | #25815 | `decision-only-via-service` (2→3) | the ref is an engine unit, and every oracle is the api | `automated` removed. knownGaps[0] says what `resume-authority-gate.test.ts` asserts (AutomationEngine + InMemorySuspendedRunStore, stand-in `gated_pause` node) and when automated may return: an HTTP pin on the generic resume route plus the approvals API. | | #25815 | `email-action-token-door` (8→9) | a0, a1, a3 | a0: the FORBIDDEN arm is pinned with `'stranger'` (not an approver at all), and the at-rest read stays a run leg. a1: no pin asserts byte-identity of the timeline or `consumed_at`. a3: no pin asserts that a failed decide still burns the token, so it rests on source evidence only (`redeemActionToken`'s order). automated.ref's "Full clauses" is narrowed to acceptance[2] + negative[2], and knownGaps[0] is aligned. | | #25815 | `request-page-reply-and-reader-visibility` (2→3) | a1, a2 | a1.verify names the reply's HTTP legs: the row lands for the approver and the submitter, and the member gets 403 FORBIDDEN (`approvals-routes.ts` prefix map). The two service-layer pins are cited as evidence of their own layer only. automated.ref's acc[2] note: request-read-gate drives ObjectQL + `findData`/`getData` in-process, never `/data` over HTTP. Also #26052: knownGaps[0]'s pin-skew block no longer arises, because the console builds from this tree. | | #25815 | `status-mirror-field` (3→4) | a2; a0/a1/a3/a4 | automated.ref now scores negative[2] and acc[2] only, and states that acc[0], [1], [3], [4] have no automation. a2.verify: the integration pin drives only the dead-run sweep. For the SLA auto-decision half, the service-layer pin `'SLA auto-decision: stays user-less — no human did it'` proves only that the write is user-less. The live route is approvals.sla-escalation's shim recipe. | | #25817 | `approver-resolution-matrix` (6→7) | owner fallback does not discriminate | steps[7]'s example is now a `{type:'user'}` fallback on a non-administrator member. | | #25817 | `decision-action-matrix` (8→9) | knownGaps[0]; N1 quote; A0 "exactly one" | knownGaps[0]: both remaining org-less candidates are refuted. negative[1] quotes `'a reminder was already sent recently'` (`approval-service.ts` remind). acc[0] carves out the maxRevisions revise, which appends `revise` then `reject` (sendBack, audit-first). | | #25817 | `per-group-signoff` (9→10) | A3; steps 3/4; N0 | steps[3]–[4] use the request page and the "My Pending" tab. acc[3] reads the logged `mark_approved` step (ExpenseSignoffFlow's approve edge is an update_record). negative[0] names the unanimous invoice (admin×2) as the stock contrast. | | #25817 | `quorum-m-of-n` (6→7) | A2; unbinding | acc[2] reads the `return_to_draft` step and the report's draft status. fixtures.requires[1]: a fresh boot needs no unbinding. | | #25817 | `inbox-metadata-actions` (5→6) | steps 1/2/5, A0; Record vs Request cell | Same "drawer"/tab respelling, and the steps name the Request cell (opens the request page) vs the Record cell (opens the subject record, which also renders the bar). | **Edits beyond the card's literal field list, made for same-item consistency:** per-group-signoff acceptance[2] ("the drawer's group chips"), and inbox-metadata-actions acceptance[1] plus fixtures.requires[1]. They carry the same stale "drawer" or zh-only tab wording as the fields the card names, and leaving them would make each item contradict itself. Each history row says so. ## Acceptance notes - **"drawer" persists in five items this card does not name:** `quorum-m-of-n` (steps[8], acceptance[4]; #25817's A4 read the tally on the record page as "0 of 2 · 3 eligible"), `viewer-gating-submitter-side`, `notification-deep-link` (its title and ten fields), `dynamic-approver-routing` steps[3], and `inbox-keyboard-flow` (its title and thirteen fields). These are not edited here. Carrier: wave anchor #25807. - **`decision-action-matrix` acceptance[9].verify** still calls an org-less row "the shape every schedule / time-relative / api-trigger run mints". #25817 measured an api-hook approval on a tenancy-disabled object stamping the default organization. Only knownGaps[0] was on the card, so the parenthetical is left as it is. Carrier: #25807. - **`per-group-signoff` steps[5]** still offers "via the documented override path", which knownGaps[0] calls no longer acceptable. Not on the card, and left as it is. Carrier: #25807. - **`record-page-decisions` source[0]–[2]** cite objectui blobs "at the console pin cf153eb". That is the provenance of a past read, not an instruction to run the retired scripts, so it is left alone. Carrier: #26035. - History rows are append-only. Rows that quote the retired pin flow stay as written. ## Gates (head `95fe453c`; the ref-swap commit changes only the ten placeholder refs) - `pnpm check:platform-checklist` → exit 0 (`check-platform-checklist: OK — 16 areas, 329 items (324 active, 1 planned)`, both self-tests pass). - `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` derived 13 families, and all 13 ran to exit 0. `check:doc-formula-expressions` first answered exit 3 (PREREQUISITE: `@objectstack/formula` / `@objectstack/lint` unbuilt); it was re-run after the prescribed `turbo run build --filter=@objectstack/formula --filter=@objectstack/lint` and answered exit 0. `--ran` gave `13 derived famil(ies) accounted for — 13 run, 0 NOT-MEASURED (a DERIVED zero — all 13 recorded an exit code and none of them is 3)`. - CI-only families (Test Core shards, the type-check lanes) are left to this PR's checks. --- _Generated by [Claude Code](https://claude.ai/code/session_01VwduP3gdrCAQyEyLmPtrUN)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 3a3751b commit 40bba68

1 file changed

Lines changed: 102 additions & 60 deletions

File tree

0 commit comments

Comments
 (0)