Skip to content

rest: the approvals FORBIDDEN → 403 wire-code row (handleApprovalError) has no live-emission pin — every authorisation refusal rides it, and only the service-side prefix is pinned #14573

Description

@claude

Observation filed by the os-dev seat for #12775 (session session_01AUF1NoViznQK32gqpK8wS8), out of that card's scope; unassigned, finding label, for triage.

What was measured

packages/rest/src/rest-server.tshandleApprovalError (inside registerApprovalRoutes, around :11477) is the seam where every approvals refusal thrown by ApprovalService becomes an ADR-0112 envelope: it tests the thrown message against a prefix table and answers res.status(status).json({ code, error }). The FORBIDDEN row (^FORBIDDEN403, code FORBIDDEN) is the one every authorisation refusal rides — recall by a non-submitter, decide by a non-approver, reassign / remind / sendBack / resubmit by the wrong actor, the impersonation refusals from resolveActor.

packages/rest/src/rest-approvals-wire-codes.test.ts (#8885) pins that seam LIVE through the real routes for THROTTLED (429), READ_BACK_FAILED (500) and the template-generated APPROVAL_*_FAILED (500) codes, plus the closed-union class pin. git grep -n "FORBIDDEN\|403" packages/rest/src/rest-approvals-wire-codes.test.ts → no match; git grep -ln "approvals/requests\|handleApprovalError" packages/rest/src/*.test.ts → the other four files that match (openapi-builtin-paths, rest-data-door-code-prefix, rest-server-approvals-unknown-filter, rest-write-response-internal-fields.tripwire) pin route registration, query-param refusal, the code-prefix strip and response-echo shape, not the 403 row.

So the 403 FORBIDDEN half of the recall / decide refusal contract is pinned only indirectly: the service-side suites assert the FORBIDDEN: message prefix (recall-refusal-user-copy.test.ts WIRE_CODE, the #12775 pins in approval-revise.test.ts), and the mapping row that turns that prefix into 403 + code has no live-emission pin of its own. A regression that re-orders the table, drops the row, or changes the anchor regex would keep every service suite green.

Why it is an observation and not a defect

The row works today (read at origin/main 7286dd58e); nothing is broken. It is a coverage gap on a security-relevant envelope, of the kind rest-approvals-wire-codes.test.ts already exists to close for its sibling rows — one more it() in that file, through the real recall route with a fake service that throws FORBIDDEN: …, asserting status === 403, body.code === 'FORBIDDEN' and that the prefix is stripped from body.error, would close it.

Not fixed under #12775 because packages/rest is outside that card's claimed file surface.

Refs: #12775 (the narrowing whose pins stop at the service seam), #8885 (the wire-code pin file), #11993 (the recall refusal's user-facing half; its test documents the prefix contract in prose).

Generated by Claude Code


Generated by Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions