Repository navigation
Commit 65f4756
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
0 commit comments