Skip to content

fix: 22 validated bug fixes from adversarial bug hunt - #272

Merged
jkyberneees merged 3 commits into
mainfrom
fix/bug-hunt-2026-09-26
Sep 27, 2026
Merged

jkyberneees merged 3 commits into
mainfrom
fix/bug-hunt-2026-09-26

Conversation

@jkyberneees

Copy link
Copy Markdown
Contributor

Summary

Fixes 22 bugs (1 high, 11 medium, 10 low) found by a 6-agent adversarial bug hunt, all validated RED-first (failing test before fix, green after), plus an adversarial diff review whose blockers are addressed in this PR.

High

  • Torn WS frames after write timeout — dead conn write state was deleted while a parked sender still blocked; the next write re-created live state and raced a concurrent Send on the same conn.

Medium

  • validateSessionToken minted+persisted a token before comparing on 401 probes (legacy-session rewrite / token rotation under attacker control); strict path on legacy sessions now denies outright.
  • saveLocked left messages trimmed after a failed index write (permanent ErrConflict).
  • VectorIndex.Search ran the remote Embed under the index mutex (one slow embed stalled all saves).
  • expandEnv ate the byte after a bare $ ("cost: $ 5" → "cost: $5").
  • ParseEnvelope returned (nil,nil) for BOM-prefixed envelopes (unvalidated file:// refs to the model).
  • Danger denylist raw prefix match ("git push" bypassed "git push").
  • trustAll bypassed classes TrustShortcutAllowed excludes (3 legacy tests re-pinned to the documented contract).
  • browser tool lazy-init data race.
  • multi_grep swallowed root walk errors (returned count:0).
  • budget RecordExternal overflow (negative observed cost).
  • skills cache never GC'd other projects' entries.

Low (10)

mcpclient stdout-pipe leak on Start failure; redact fused secret names (MYAPITOKEN); session audit fail-closed on unreadable files; JSON export omits auth_token; trust grants record approvals (friction engages); ClassifyURL trailing-dot hostnames; browser snapshot rune-boundary truncation; batch_patch truthful preview hunks; bg_start malformed-JSON error message; memory AddFact consistent trim.

Test plan

  • 17 new test files, all RED-verified before fixes.
  • Full suite green: go build ./..., go vet ./..., go test ./internal/..., go test ./cmd/odek/ (93s), race runs on changed packages.

WebSocket/session: torn frames after write timeout (dead conn state
re-created while a parked sender blocks) - dead latch is now sticky;
validateSessionToken mints before compare on 401 probes (file rewrite +
token rotation under attacker control) - compare/deny before any write;
strict path on legacy sessions now denies outright. saveLocked restores
Messages/boundary on failed save (permanent ErrConflict). VectorIndex
Search embeds outside the mutex.

Config/artifact: expandEnv no longer eats the byte after a bare '$';
ParseEnvelope strips UTF-8 BOM (envelope JSON with file:// refs was
delivered unvalidated).

Danger/approvals: denylist match collapses internal whitespace
("git  push" bypass); trustAll honors TrustShortcutAllowed (excluded
classes always prompt - 3 legacy tests re-pinned to the documented
contract); trust grants record approvals so friction engages; ClassifyURL
strips trailing-dot hostnames (169.254.169.254.).

Tools: browser lazy-init race (mutex); browser snapshot rune-boundary
truncation; multi_grep surfaces root walk errors; batch_patch preview
renders truthful hunks at the real offset; bg_start distinguishes
malformed JSON from empty command.

Hardening: mcpclient closes stdout pipe on Start failure; redact detects
fused secret names (MYAPITOKEN); session audit load fails closed on
unreadable files (no history rewrite); JSON session export omits
auth_token; budget RecordExternal rejects/clamps non-finite or
overflowing external costs; skills cache GCs other projects' entries;
AddFact trims once so merge detection, dedup, and corpus agree.

Adversarial diff review: blockers fixed (strict-bootstrap dead path,
gofmt); low findings noted for follow-up.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
odek 206bfec Commit Preview URL

Branch Preview URL
Sep 27 2026, 09:06 AM

- session: saveLocked snapshot is now an element copy — trimToFileCapLocked
  compacts the slice in place, so a header-copy snapshot restored shifted
  contents after a failed post-trim save.
- redact: fused-name suffix match uses >= so bare PASSWORD/TOKEN/SECRET
  env names register as sensitive.
- serve: dead-latched WS write states are swept past 4096 entries (dead +
  not held by a parked sender), bounding memory on connection-churning
  clients; the sticky-dead invariant below the cap is unchanged.

Deferred (next hunt): budget clamp can silently mask real overruns under
repeated negative external deltas (needs per-delta clamp + event);
patchPreviewDiff hunk header byte/line math; fused-name plurals.
Test files and functions renamed from bug-hunt workflow markers to
descriptive names (bughunt/redbugs/bugfix/TestRED_ dropped); comments
rewritten to state current behavior as invariants instead of narrating
the historical defect. Semantics unchanged; all touched packages green.
@jkyberneees
jkyberneees merged commit d8f171e into main Sep 27, 2026
10 checks passed
@jkyberneees
jkyberneees deleted the fix/bug-hunt-2026-09-26 branch September 27, 2026 09:12
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