Skip to content

Commit 65f4756

Browse files
docs(qa): approvals checklist — opening notifies approvers (approval.requested); the token-door item re-pointed after sys_approval_token left the data API (#22631, QA half) (#22656)
Part of #22631 Clause-②: no The non-governed half of #22631: `docs/qa/platform-checklist/areas/approvals.json` only. Two items move. The deep-link item stops saying that opening a request notifies nobody, because `openNodeRequest` publishes `approval.requested` to each concrete approver on the slate the request opens on since PR #22625 (`e8c6666870`). The token-door item is re-pointed after PR #22633 (`86da194919`, #22616) closed `sys_approval_token` to the automatic API. The Tier H half (ADR-0043 and the automation skill) is PR #22652. #22631 remains open until both PRs land. Dispatched by the `domain:skills` seat PM, session `session_01RdnZdPZH9ByduzPRWuH9tN`. Claim `6095805515`, triage `6095381775`, token-door note `6095140961`, remedy `6095111901` on #22616. `docs/qa/**` is `domain:devx`'s surface, carried here under the cross-domain exception path the triage named. ## Measured first - At `origin/main` `3d0eeefa` the file read as the card quotes: `notifies NOBODY` 1 hit (`:341`), `has no approval.opened member` 1 hit (`:394`), `approval.opened` 3 hits (`:341`, `:394`, and the revision-4 history row at `:400`); control `approval.reminder` 3 hits. - `packages/plugins/plugin-approvals/src/approval-service.ts`: `'approval.requested'` is published at `:3349` inside `openNodeRequest` (`:2999`), one `this.notify()` per concrete approver on `openedOn`; `issueActionTokens` has one caller, `:4815` inside `remind()`. - `sys-approval-token.object.ts` `:115`–`:116` declares `apiEnabled: false` and `apiMethods: []`. PR #22633's changeset says every data-API verb answers `404 OBJECT_API_DISABLED` to every caller, the administrator included, and that "there is no replacement read, by design: a link's state is what its confirm page answers, and a decision taken through a link is recorded in the request's action history". So the remedy in 6095111901 holds in full, and nothing in the token-door item needed less than it says. - The expiry leg: `ACTION_TOKEN_TTL_MS = 72h` (`:815`); `ttlMs` is an option of `issueActionTokens` only (`:4857`), which `remind()` calls without it; the service clock is `opts.clock` on the constructor (`:1223`, `:1376`), and `approvals-plugin.ts` constructs `ApprovalService` without one (`:207` ff.); the plugin's source reads no `OS_TEST_*` and no `process.env`. Nothing drives expiry through a public door. The `expired` reason is pinned by `approval-service.test.ts` ("redeem: dead tokens — invalid, expired, decided request, reassigned slot": `issueActionTokens(…, { ttlMs: 1 })` under the fake clock), and `RESULT_COPY.expired` in `action-link-pages.ts` is the page that reason renders. - The token-capture seam the item rests on survives: `sys_notification` still declares `apiMethods: ['get', 'list']` (`packages/platform-objects/src/audit/sys-notification.object.ts` `:187`), so the raw links are still read from the persisted reminder payload. - The action history is `GET /api/v1/approvals/requests/:id/actions` (`packages/rest/src/rest-server.ts` `:12762`; `rest-route-ledger.ts` `:444`), which the item already used. ## What changed (17 anchored edits; the JSON re-parsed; no key reordered) ### `approvals.notification-deep-link`, revision 4 → 5 - The `knownGaps` entry ("opening a request notifies NOBODY on this build — there is no approval.opened topic …") is removed. Six of the file's 18 items carry no `knownGaps` key, so the key goes rather than an empty array. - The `source` note on `approval-service.ts#ApprovalService` names `approval.requested` on open (PR #22625) beside the nine sibling topics, every member inheriting the deep link. - Step 2 and the fixture note no longer say "opening a request emits nothing": the remind/reassign path notifies on demand, and a freshly opened request is a second source. The fixtures stay on remind/reassign. - The revision-4 history row stands as history; a revision-5 row records the change (`ref` `#22631`). ### `approvals.email-action-token-door`, revision 1 → 2 - Step 2 (mint): the `GET /api/v1/data/sys_approval_token` read becomes the remind response's `notified` count and the new remind row on `/:id/actions`, with the instruction not to read the object through the data API and that its `404 OBJECT_API_DISABLED` is the designed answer, not a finding. - Step 4 (prefetch safety): the "token row, consumed_at still null" re-read becomes the second GET rendering the confirm page rather than the "Already used" page, beside the `/:id` and `/:id/actions` re-reads. - Step 9 (expiry): no live door; cite the pinned `expired` reason and the `RESULT_COPY.expired` copy, and record the leg as `blocked(fixture)`. - Acceptance 1 (mint, hashed at rest): `oracle` `api` → `test`, pointing at `approval-token-internal-hash.integration.test.ts` and `sys-approval-token-generic-door.integration.test.ts`; the live half keeps the `sys_notification` payload read. - Acceptance 2, 4 and 5: the token-row reads move to the act door's outcome pages and `/:id/actions`; the five-shape capture becomes four live shapes plus the pinned expired reason. - Negative 4: the hashed-at-rest FAIL is re-anchored on storage (the engine's system read in the internal-hash test), and reading the data API's 404 as a defect is named a FAIL of the method. - `knownGaps[1]` (expiry) is rewritten with the exact reason above; `source` gains the token object's closed declaration and the three test files; a revision-2 history row records all of it, including the two steps that had contradicted the door before PR #22633 (the digest withheld since #21197; `update` never whitelisted). - Every clause keeps the file's `oracle` / `verify` / `evidence` shape, and every `oracle` value is in the gate's set. ## Verification (all at `3f630d4dc`) - PM-named: `pnpm check:platform-checklist` exit 1 (below); `node scripts/check-doc-route-spelling.mjs --advisory` exit 0; `pnpm check:corpus-claim-drift` exit 0. - `check:platform-checklist` is red on `origin/main` independently of this diff. Its 7 problems are 5 in `areas/access-security.json` (ABSENT SYMBOL: `protocol.ts#anonymousFormIntakeOrgScopeRefusal`, `#anonymousFormIntakeReopenRefusal`, `#envWideRawViewRows`) and 2 in `areas/attachments-storage.json` (ABSENT SYMBOL `attachment-access-hooks.ts#canEdit`; SYMBOL ANCHORS LOST, 27 against a floor of 28). The same 7 problems come back verbatim on a tree whose `approvals.json` is byte-identical to `3d0eeefa` (the sibling worktree at `af35cd5be`), and no problem names `approvals.json`. Origin: `b389e4355` (#22515) removed the two `protocol.ts` symbols, and `ce3d0ad41` (#22513) reshaped `canEdit`. Both files are outside this card's surface: reported to the seat, not touched here. Until they are repaired, `Lint & Repo Gates` stays red on this PR for a reason this diff does not own. - `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` (no paths; the change set is taken from the merge base) derived 13 commands. All 13 ran in the foreground, each exit captured before any pipe; `--ran` reconciliation: "13 derived, 13 run, 0 NOT-MEASURED, 0 UNRUN". 12 exit 0: `check-ci-filter-parity`, `check-closing-keyword-parity` (+ self-test), `check-comment-mask-corpus`, `check:doc-formula-expressions` (after its named prerequisite build through the verify lock, 4 of 4 tasks cached), `check:cross-package-test-inputs`, `check:doc-authoring`, `check:driver-memory-census`, `check:gitlink-declared`, `check:nul-bytes`, `check:refd-timer-probe`, `check:watch-hint-literal`. 1 exit 1: `check:platform-checklist`, above. - Not run locally: the repo-wide `pnpm lint` (no lintable source touched) and package suites (no package touched). ## Changeset Docs-only; `docs/qa/**` ships in no package's `files[]`. `skip-changeset` is applied through `label-write`. ## Acceptance notes - `check:platform-checklist` red on `main` (above). Class (b): the checklist's symbol-anchor contract ("every `path#symbol` citation resolves; the per-file anchor count is shrink-never") is violated by two area files. Reach: `pnpm check:platform-checklist` on `origin/main` `3d0eeefa` answers exit 1 with 7 problems. Carrier: the seat. Dedupe words: `access-security.json ABSENT SYMBOL anonymousFormIntakeOrgScopeRefusal`, `attachments-storage.json canEdit anchor floor 28`. - The `source` entries added for the three test files are bare paths (no `#symbol` half), so the item's resolvable-anchor count does not shrink; its six existing anchors are kept. --- _Generated by [Claude Code](https://claude.ai/code/session_01RdnZdPZH9ByduzPRWuH9tN)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent 156ddfa commit 65f4756

1 file changed

Lines changed: 27 additions & 25 deletions

File tree

0 commit comments

Comments
 (0)