You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Filed unassigned and ungraded by the #12510 dev (session session_01UjujZN219uFzBhSYfMykCd), measured while repairing the declaredCode drop at the same call site. ⛔ Not graded, not routed. Reported, not touched — out of that card's scope.
Measured
Ref: 9a2f3dfe4 plus this branch's own commit f2063854a (claude/issue-12510-sharing-error-declared-code). One producer, driven through the real routes on both doors:
throw { code: 'CLOSE_PERIOD_LOCKED', status: 409,
userMessage: 'Ask finance to reopen the period.' }
share door : 409 {"success":false,"error":{"code":"RESOURCE_CONFLICT",
"message":"invoices still open","declaredCode":"CLOSE_PERIOD_LOCKED"}}
/data door : 409 {"error":"invoices still open","code":"RESOURCE_CONFLICT",
"declaredCode":"CLOSE_PERIOD_LOCKED",
"userMessage":"Ask finance to reopen the period."}
throw { code: 'CLOSE_PERIOD_LOCKED', status: 409,
issues: [{ path: 'invoices', message: 'inv_1 is still open' }] }
share door : 409 {"success":false,"error":{"code":"RESOURCE_CONFLICT",
"message":"two rows still reference it","declaredCode":"CLOSE_PERIOD_LOCKED"}}
/data door : 409 {"error":"two rows still reference it","code":"RESOURCE_CONFLICT",
"declaredCode":"CLOSE_PERIOD_LOCKED",
"issues":[{"path":"invoices","message":"inv_1 is still open"}]}
respondSharingError (packages/rest/src/rest-server.ts, inside registerSharingEndpoints) asks classifiedRefusalAnswer — the flat /data door's own classification — and re-dresses status, code, the message and, since #12510, declaredCode. The classification's body is holding two more declared channels for the same throw and neither reaches the nested envelope.
Two channels, and they are NOT the same difficulty
userMessage — mechanical, and the landed idiom exists. The flat door attaches it through withDeclaredUserMessage (packages/rest/src/error-response.ts, contract: a hook refusal has no way to mark its message user-facing — the console's 403 substitution (ruled in #3821) needs a producer-side opt-in channel #9934) and the dispatcher door passes thrown.userMessage straight through. sendError's extra now admits it (packages/types/src/response-envelope.ts), and that writer's own docblock records the caller obligation: unlike declaredCode, userMessage carries no invariant for the caller to re-derive — declaredUserMessage has already decided presence. So the repair is the same one-line re-dress declaredCode just got, reading refusal.body.userMessage (the classification's own field, already truncated by truncateClientMessage).
⚠️The structured context is a SHAPE decision, not a mechanical carry. The flat dialect puts the producer's context at the body's top level as issues; the nested ADR-0112 envelope's channel is ApiError.details (which is what PR fix(rest): the package door carries the demoted producer code on declaredCode (#12405) #12508 forwards at the package door). So this half is not "forward the same key" — someone has to rule how the flat issues maps onto nested details at this door, or whether it should. ⛔ Please do not treat it as a rename.
Why it is worth a card rather than a line in the #12510 PR
Same class, different declared channel, and the repo has been filing this class per channel and per door: #12404 (the Pick itself) and #12502 (the same drop at package-routes' sendThrownError) are both closed. Neither covers this family. #12510 was ruled to be declaredCode at this door, and its contract-review posture was reasoned for that one field.
Dedupe
Semantic search over this repo's issues for the nested-envelope userMessage drop returns four cards — #12404, #12502, #9267, #3983 — all closed, none about the record-share family. ⚠️ The REST list endpoints answer 403 from a dev seat ({"message":"GitHub access is not enabled for this session"}), so the sweep ran through the MCP path only; a local grep of packages/rest/src finds no in-source tracking reference for this family either.
⛔ The first is expected to return zero — that zero IS the finding, so reverse-check it with a term known present in the same file (sendEnvelopeError answers several) before believing it.
Filed unassigned and ungraded by the #12510 dev (session
session_01UjujZN219uFzBhSYfMykCd), measured while repairing thedeclaredCodedrop at the same call site. ⛔ Not graded, not routed. Reported, not touched — out of that card's scope.Measured
Ref:
9a2f3dfe4plus this branch's own commitf2063854a(claude/issue-12510-sharing-error-declared-code). One producer, driven through the real routes on both doors:respondSharingError(packages/rest/src/rest-server.ts, insideregisterSharingEndpoints) asksclassifiedRefusalAnswer— the flat/datadoor's own classification — and re-dressesstatus,code, the message and, since #12510,declaredCode. The classification's body is holding two more declared channels for the same throw and neither reaches the nested envelope.Two channels, and they are NOT the same difficulty
userMessage— mechanical, and the landed idiom exists. The flat door attaches it throughwithDeclaredUserMessage(packages/rest/src/error-response.ts, contract: a hook refusal has no way to mark its message user-facing — the console's 403 substitution (ruled in #3821) needs a producer-side opt-in channel #9934) and the dispatcher door passesthrown.userMessagestraight through.sendError'sextranow admits it (packages/types/src/response-envelope.ts), and that writer's own docblock records the caller obligation: unlikedeclaredCode,userMessagecarries no invariant for the caller to re-derive —declaredUserMessagehas already decided presence. So the repair is the same one-line re-dressdeclaredCodejust got, readingrefusal.body.userMessage(the classification's own field, already truncated bytruncateClientMessage).issues; the nested ADR-0112 envelope's channel isApiError.details(which is what PR fix(rest): the package door carries the demoted producer code ondeclaredCode(#12405) #12508 forwards at the package door). So this half is not "forward the same key" — someone has to rule how the flatissuesmaps onto nesteddetailsat this door, or whether it should. ⛔ Please do not treat it as a rename.Why it is worth a card rather than a line in the #12510 PR
Same class, different declared channel, and the repo has been filing this class per channel and per door: #12404 (the
Pickitself) and #12502 (the same drop atpackage-routes'sendThrownError) are both closed. Neither covers this family. #12510 was ruled to bedeclaredCodeat this door, and its contract-review posture was reasoned for that one field.Dedupe
Semantic search over this repo's issues for the nested-envelope⚠️ The REST list endpoints answer 403 from a dev seat (
userMessagedrop returns four cards — #12404, #12502, #9267, #3983 — all closed, none about the record-share family.{"message":"GitHub access is not enabled for this session"}), so the sweep ran through the MCP path only; a local grep ofpackages/rest/srcfinds no in-source tracking reference for this family either.Severity not judged.
Re-check
⛔ The first is expected to return zero — that zero IS the finding, so reverse-check it with a term known present in the same file (
sendEnvelopeErroranswers several) before believing it.