Home

boring / v2

publicBoring-Software-Inc/v2
Overview Code History Branches Pull requestsIssuesInsights Campfire Docs
main
HomeOverview Code PRsIssues

fix: comment-triggered runs lost their subject, and the bot jwt was skewed wrong

2 months ago

81e2a09
Authored
grim8/24/2026, 5:48:46 AM
Three improvements, taken from a parallel open-git implementation that never
left a laptop. Credit where due: all three were its ideas.

1. runs.subject_number was null for every comment-triggered run

run-workflows read it only from a change-request event, but a comment names its
change request too, in comment.subjectNumber. That column is load-bearing in
three places, and the third does real damage: sweep-actions SKIPS actions whose
subject is null, so a recorded block or comment was never delivered and the
give-up window eventually abandoned it. The run page's deep link and canRerun
were the visible half.

Fixed forward, plus a one-shot backfill that recovers the value from the STORED
normalized event rather than a forge call. Verified by building the broken case
in the database, repairing it, and re-running to prove it is idempotent.

2. the bot jwt backdated the wrong end

iat sat at now and exp was shortened to nine minutes, with a comment claiming
that bought clock-skew headroom. It buys none: if our clock runs ahead of
open-git's the problem is an iat in the FUTURE, and a shorter life does not move
it back. iat is now backdated 60s, matching the GitHub adapter, and exp sits on
the edge of the server's own 10-minute window.

3. the jwt test never verified the signature

It decoded the claims, asserted alg said RS256, and one assertion checked that
the test's own fixture was a PEM. A broken signer passed it. It now verifies
under the public key, and a tampered payload is asserted to fail.

Added the stub open-git e2e the other branch had: a real HTTP server that
verifies the app JWT before minting and requires the minted token afterwards,
so private key → jwt → verification → token → gate → comment all runs offline,
in CI, with no tunnel or credentials. Proven to have teeth by reintroducing the
iat bug: three tests go red, including the stub refusing the mint with a 401.

Not taken: jose. It is in the lockfile only transitively, so depending on it
directly needs a DECISIONS.md entry, and node:crypto verification gets the
coverage that was actually missing. Also not taken: their adapter files
reviews. Ours refuses, because open-git has no dismissal endpoint and the check
already gates.

Parent456c95e

7 files changed
  • apps/worker/src/jobs/run-workflows.ts+18−1
  • apps/worker/src/subject-number.test.ts+43−0
  • package.json+1−0
  • packages/forge-opengit/src/adapter.test.ts+52−11
  • packages/forge-opengit/src/client/auth.ts+11−6
  • packages/forge-opengit/src/e2e.test.ts+324−0
  • scripts/backfill-run-subject-number.ts+65−0