Skip to content

fix(consent): a malformed consent request is reported, not ignored - #111

Merged
stormer78 merged 1 commit into
mainfrom
fix/malformed-consent-payload-is-reportable
Aug 7, 2026
Merged

fix(consent): a malformed consent request is reported, not ignored#111
stormer78 merged 1 commit into
mainfrom
fix/malformed-consent-payload-is-reportable

Conversation

@stormer78

Copy link
Copy Markdown
Contributor

parseTaskConsentRequest returned "not-a-task-consent-request" for two completely different situations:

  • a message not addressed to this handler — safe to ignore
  • a genuine consent request whose payload is unusable — a human is waiting on it

dispatchInbound keys on that reason to decide whether to stay quiet:

if (consent.reason !== "not-a-task-consent-request") { console.warn(...); return; }
// Anything else is ignored.   ← silent

So a malformed consent request was discarded in total silence — no prompt, no log — and handleInbound's finally then cleared its pending record.

How this presented

Indistinguishable from a message that never arrived:

Signal Result
[pnm inbound] received … task-consent/request/0.1 (#105) arrival confirmed
refusing task-consent request: absent — the reason routed to the silent branch
handling threw (#108) absent — nothing threw
consent window opened / could not open (#106, #107) absent — never got that far
pending-approval badge (#110) zerofinally had already cleared the record

That badge counting zero is what localised it. If the flow were hung in sendMessage, the record would still be there and the badge would have read one. Zero meant dispatchInbound had returned — and only one return path produces no log at all.

The change

Malformed payloads now return "malformed-payload", so the existing warn path reports them along with their detail. "not-a-task-consent-request" keeps its single honest meaning: not addressed to this handler.

The test that pinned the old shared reason now pins the distinction and the detail, with the reasoning recorded — it was asserting the exact behaviour that hid this.

What this does not do

It does not make the request valid. The next run should log refusing task-consent request: malformed-payload payload is missing required members — and that names the field the VTA is not sending as the plugin expects. Given the payload is minted in consent_request.rs and validated here, a cross-service mismatch is the likely next finding.

Lint clean, 223 tests pass, builds.

parseTaskConsentRequest returned "not-a-task-consent-request" for two
completely different situations: a message not addressed to this handler,
and a genuine consent request whose payload is unusable.

dispatchInbound keys on that reason to decide whether to stay quiet:

    if (consent.reason !== "not-a-task-consent-request") { warn; return; }
    // Anything else is ignored.   <- silent

So a malformed consent request was discarded in total silence -- no
prompt, no log -- and handleInbound's finally then cleared its pending
record. The result is indistinguishable from a message that never
arrived, which is how it presented: arrival logged by #105, then nothing
at all, and a pending-approval badge (#110) that counted zero because the
record was already gone.

Malformed payloads now return "malformed-payload", so the existing warn
path reports them with their detail. The silent reason keeps its single
honest meaning: not addressed to this handler.

The test that pinned the old shared reason now pins the distinction and
the detail, with the reasoning recorded -- it was asserting the exact
behaviour that hid this.

Signed-off-by: Glenn Gore <glenn.g@affinidi.com>
@stormer78
stormer78 merged commit 1924646 into main Aug 7, 2026
3 checks passed
@stormer78
stormer78 deleted the fix/malformed-consent-payload-is-reportable branch August 7, 2026 15:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant