Skip to content

wr-risk-scorer: external-comms gate hashes an empty draft for --body-file, so that path can never clear #408

Description

@tompahoward

external-comms gate hashes an empty draft for --body-file, so that path can never clear

hooks/external-comms-gate.sh keys its marker on sha256(DRAFT + "\n" + SURFACE). For a Bash tool call it extracts DRAFT by regex over the command text. A file path is opaque to that regex, so gh issue create --body-file X yields DRAFT="" and the gate hashes the empty string.

The reviewer subagent, meanwhile, was handed the real draft and its marker is keyed on the real draft's hash. The two keys can never match. The gate re-blocks forever, and its deny message directs you to do the thing you just did.

The source comment says the empty draft is acceptable:

# When absent (npm publish, --body-file, editor flow already filtered),
# DRAFT="" is acceptable: the agent will be invoked with command
# context and read whatever body source the call uses.

That is true for the leak-scan half. An empty draft passes the regex pre-filter trivially. It is not true for the marker half, which is the half that gates the call. Still present on 0.18.6: the only occurrence of body-file in the file is that comment.

What it costs

The failure presents as a persistence bug, not an extraction bug. We hit it closing a four-year-old issue. The voice-tone gate cleared while the risk gate did not, which read as a per-evaluator marker race, so we went looking at the P402 background-agent trap and then at trailing-whitespace theories before reading the extraction code. Several cycles on a session that was otherwise done.

Our briefing already carried a warning about this for the gh issue create case and we walked into it anyway. That says something about how hard it is to recall at the moment of use, and it is the argument for fixing the message rather than the docs.

Two options, either is fine

Read the file. The path is right there in the command text and is readable at hook time. --body-file <path> becomes a supported form and the marker keys on real content.

Or fail loudly. If reading files from the hook is not wanted, detect --body-file and deny with a directive that names it: say the form is unsupported and to inline the body instead. A deny message that names the cause costs nothing and would have saved the whole diagnostic detour.

We would take either. The second is smaller and removes the misleading message, which is the part that cost us.

One thing worth checking on your side

Our install has skills at 0.17.0 while the gate hook that fired was from the 0.9.0 cache directory. Several versions are present locally and the one that runs is not always the newest, so a fix may need a cache-invalidation story alongside it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions