Refusal return contract: pin the fragment, carry the attempt id, document it #7

Merged
heimdall merged 1 commit from heimdall/refusal-return-contract into main 2026-11-08 13:51:45 +00:00
Member

Pins and documents what a landing page reads after a refusal (Heimdall main 61671d7). Not merged, not deployed.

  • Tests: decline and provider access_denied each parse the #return-link fragment and assert heimdall_status=error, heimdall_error=consent_refused, heimdall_refused_by=viewer|provider, and no heimdall_completion_code; a browser_completion attempt refused either way carries heimdall_attempt_id.
  • src/app.ts (refuseConsent): the attempt id is passed for browser_completion handoffs too, not only backend_callback. The attempt test failed before this change.
  • Docs: "Refusal return contract (for app authors)" in docs/joystick-consent-flow.md: fragment keys, postMessage payload, no auto-redirect, backend callback and denialCode.
  • Also fixes a type error in my earlier store.test.ts test (narrowing a receipt union).

Mutants, each alone under 8 GB ulimit -v, timeout 300: drop refused_by, swap by, completion code set on the error path, heimdall_error=provider_error, attempt id reverted to backend_callback only: 5/5 killed.
Suite 530 pass / 19 fail, the known environmental 19.

🤖 Generated with Claude Code

Pins and documents what a landing page reads after a refusal (Heimdall main 61671d7). Not merged, not deployed. - Tests: decline and provider `access_denied` each parse the `#return-link` fragment and assert `heimdall_status=error`, `heimdall_error=consent_refused`, `heimdall_refused_by=viewer|provider`, and no `heimdall_completion_code`; a `browser_completion` attempt refused either way carries `heimdall_attempt_id`. - `src/app.ts` (`refuseConsent`): the attempt id is passed for `browser_completion` handoffs too, not only `backend_callback`. The attempt test failed before this change. - Docs: "Refusal return contract (for app authors)" in `docs/joystick-consent-flow.md`: fragment keys, postMessage payload, no auto-redirect, backend callback and `denialCode`. - Also fixes a type error in my earlier `store.test.ts` test (narrowing a receipt union). Mutants, each alone under 8 GB `ulimit -v`, `timeout 300`: drop `refused_by`, swap `by`, completion code set on the error path, `heimdall_error=provider_error`, attempt id reverted to `backend_callback` only: 5/5 killed. Suite 530 pass / 19 fail, the known environmental 19. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
The consent_refused page's return link is tested for heimdall_status,
heimdall_error, heimdall_refused_by and no completion code, for both a decline
and a provider access_denied. A browser_completion refusal now carries
heimdall_attempt_id. The contract for app authors is in the consent doc.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
GameCult/Heimdall!7
No description provided.