Commit graph Heimdall/tests/private-command-diagnostics.test.ts
Author SHA1 Message Date
Meta Vens
f6baadec0c Tests: refresh failures surface as the typed ManagedCredentialRefreshFailed; seven providers
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 11:20:18 +02:00
Meta Vens
1c38d12050 Add Joystick as a confidential, rotating managed-connection provider
Joystick joins the catalog (Basic client auth, rotatesRefreshTokens), resolves
identity by channel id, and is a streampixels managed-connection provider only:
it is not an identity provider for the profile (ruling signin-waits-for-public-bot).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 11:13:40 +02:00
Meta Vens
35f804f7ef Pin provider errors and Bifrost's reply exactly; defend errorIdentity's filters
Soul pass 5, S5-4: the provider-error tests proved only that the word
CANARY was absent, so a message carrying a 16-byte slice of the body (X1,
X2) passed, and the Bifrost success reply was checked with
objectContaining, so a 9-byte body head (X5) rode along. Each provider
error's message is now pinned exactly, the Bifrost success reply is pinned
as exactly status, supportFact and bifrostStatus, and every canary body
starts with the canary, so any prefix of it shows.

S5-5: errorIdentity's class and code filters had no test (X3, X4). Cases
now show a code or class name that carries input, is too long, is not a
string, or comes from a thrown non-Error or null is dropped, and a short
identifier survives.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 18:57:17 +02:00
Meta Vens
963150f537 Audit events never carry a completion code
Soul pass 5, S5-3: auth_completion_created stored completion.code, which
the unauthenticated redeem route turns into the session until it expires
(300 s by default), so the audit trail could redeem a live sign-in. The
two auth_completion_redeemed events (the HTTP redeem route and the private
command plane's redeem by attempt) stored the spent code as well.

All three payloads drop it. Nothing reads audit payloads back: the store
has no audit read, and no repository indexed by VoidBot consumes these
events. The event's sessionId already names the completion (one per
callback), so no replacement key is added. This matches Heimdall's own
witness contract, which says codes are redacted from audit exports.

Tests drive a sign-in through the HTTP redeem route and through the plane,
pin each payload exactly, and check the code appears in no audit event.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 18:56:35 +02:00
Meta Vens
698f5dfc0e Private command diagnostics carry class and code, never a message
Soul pass 4, F1: a provider's 2xx refresh answer that was not JSON made
JSON.parse quote the text around the fault, a refresh-token fragment among
it, and the plane returned that message in the reply's diagnostics. Those
travel outside the sealed envelope and Ghostlight logs them.

The plane's diagnostic is now fixed text plus the error's class and code,
through errorIdentity, which the failed-callback audit event now shares.
Every provider body Heimdall parses goes through readProviderJson: a
non-2xx answer or a body that is not JSON becomes a ProviderResponseError
(status and code, provider_status or provider_body_not_json) and no
parser message survives. This replaces ProviderHttpError and the separate
parses in the Discord guild lookup and the YouTube channel lookup.

Soul's canary probe is committed inverted: a refresh against a malformed
2xx body and against a 400 whose body holds the canary; no byte of it may
appear in the reply or its decoded failure payload.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 17:07:16 +02:00