Skip to content

fix: tighten the faq-bot responder and the catalogue's publish gates - #95

Merged
rmyndharis merged 2 commits into
mainfrom
fix/responder-and-catalog-gates
Aug 12, 2026
Merged

fix: tighten the faq-bot responder and the catalogue's publish gates#95
rmyndharis merged 2 commits into
mainfrom
fix/responder-and-catalog-gates

Conversation

@rmyndharis

Copy link
Copy Markdown
Owner

Four defects: two in how the FAQ responder decides to answer, two in what the catalogue is willing to publish.

faq-bot — answering things it cannot answer

A sticker, image or voice note arrives with an empty body. No rule can match one, so the fallback replied to a picture with "I did not understand" — and returning true claimed the event, so a plugin that could actually handle media never saw it. The guard now requires text, which is how chat-flow already guards the same hook.

The fallback cooldown slot is claimed before the send. When the send threw, the window was spent on a reply that never arrived and the chat stayed silent for its full duration — by default ten minutes. The slot is now released on failure. A message matching a rule is retried on the next message anyway, so this costs at most one send attempt per message rather than one per window.

catalog — two things nothing was checking

manifest.id was never compared to the directory name. Every path in this repo is built from the directory — the plugin folder, the zip, the release tag — while manifest.id is what the host installs under and what the catalogue publishes. A mismatch would have the download URL point at one plugin while the installed plugin called itself another.

manifest.repository had no constraint on its host, and the catalogue derives every download URL from it. Pointing it at a foreign repo would have the catalogue hand users an archive nobody here built or checksummed. The author field is deliberately unaffected — a plugin may credit anyone; the artifact has to come from a repo this project publishes.

Verification

  • 582 tests pass, typecheck clean, catalog up to date, all 10 plugins build and load.
  • Both catalogue gates were probed with fixture manifests: a mismatched id and a foreign repository host are each refused by name, and a correct manifest draws no complaint.
  • Both faq-bot fixes are test-first; the cooldown test drives a failing send and then a working one, and would pass trivially without the fix only if the slot were never claimed.

…failed send

A sticker, image or voice note arrives with an empty body. No rule can match one, so the fallback
answered a picture with "I did not understand" — and returning true claimed the event, so a plugin that
could actually handle media never saw it. The guard now requires text, the way chat-flow's does.

The fallback cooldown slot is claimed before the send. When the send threw, the window was spent anyway
and the chat stayed silent over a reply that never arrived. The slot is released on failure: a message
that matches a rule is retried on the next message too, so this costs at most one send attempt each.
Every path in this repo is built from the directory name — the plugin folder, the zip, the release tag —
while `manifest.id` is what the host installs under and what the catalogue publishes. Nothing compared
them, so a mismatch would have the download URL point at one plugin while the installed plugin called
itself another.

The download URL is also derived from `manifest.repository`, and nothing constrained its host. Pointing
it at a foreign repo would have the catalogue hand users an archive nobody here built or checksummed.
The author field is unaffected: a plugin may credit anyone, but the artifact has to come from a repo
this project publishes.
@rmyndharis
rmyndharis merged commit 4d1bc9c into main Aug 12, 2026
1 check passed
@rmyndharis
rmyndharis deleted the fix/responder-and-catalog-gates branch August 12, 2026 10:39
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