sidegig
Apps, bookmarks and AI beside any page, with a measured sign-in code detector
- Situation
- Sidebar extensions usually open a second pane or put features behind a subscription.
- Task
- I wanted one free sidebar for every major browser, with a sign-in code reader I could trust.
- Action
- I built it with no runtime dependencies, tested the code reader on held-out email, and added prompt-injection defenses.
- Result
- More sign-in codes reach the sidebar: 77.3% on 150 synthetic held-out emails with one, up from 53.3%.

77.3%of sign-in codes found, up from 53.3% (150 synthetic held-out emails with a code)
You see a new sign-in code beside the page you are on, and CI fails if the detector gets worse.



How I built it
Built a labeled corpus and an eval script for the code detector, then a held-out set drafted by a local model, with its labels corrected by three written rules. The held-out set was never used to change the detector.
Required a code word next to a candidate, unless it is the whole subject, and masked phone numbers, dates, IP addresses and versions first.
Wrote page text, email and tab, history and bookmark titles into the prompt so they cannot close their wrapper or pose as a system, user or tool turn.
Added a setting, off by default: once a chat has read outside text, opening a link or calling an MCP tool waits for Allow, and the prompt shows the address or the tool's arguments first.
Ran both in CI. The code eval fails below the recorded scores, and the injection tests were checked to fail on the old code.
Why these choices
Rules for codes over a model call
The sign-in ticket has to work with no model connected. The held-out set measures the rules.
Clean-room clients over vendor SDKs
Clients are written from public API docs and the MCP spec, so the package has no runtime dependencies.
A rail on the page, not only the side panel
The browser's side panel cannot be narrower than 320 px or open on hover. The cost: no rail on browser-internal pages.
Fixture previews for every screenshot
No real account appears in the repo, so no personal data reaches it.
How it was measured
- Sign-in code precision330 held-out emails, 150 with a code
- Sign-in code recallsame 330 emails
- Held-out set, 330 emails (150 with a code): precision from 90.9% to 96.7% (95% CI 93.0 to 99.2%) and recall from 53.3% to 77.3% (95% CI 70.4 to 83.9%), seeded bootstrap (Oct 23, 2026).
- A local model drafted the held-out set, three written rules corrected its labels, and it was never used to change the detector.
Failures and limits
- On the template corpus the old detector scored 70.1% precision over 348 emails. I wrote the new rules after reading that corpus, so its perfect score after the fix is in-sample. The held-out numbers are the ones to read.
- Still missed on held-out mail: letters-only codes, short letter and digit mixes, and odd digit groups.
- The code-word rule also read zipcode, barcode and postcode as a code word, so a delivery email could show a ticket. Those words are excluded now, and the held-out scores did not move.
- The first wrapper let tags through when they were hidden with zero-width characters or soft hyphens, or written with lookalike brackets. Text is now normalized before the match. Even so, the wrapper is a prompt convention that makes a break-out harder, not a hard boundary.
- The injection defenses have no attack-success number yet. A 100-page attack set is committed, but the local test model writes its tool calls as plain text, which sidegig never runs, so no attack reached a tool. On 20 of the pages it wrote the attacker's link into a tool call 6 times with no defenses and 8 times with them: the wrapper did not cut intent at that sample size.
- Only the Chromium package has been installed and checked live. The Opera, Firefox and Safari packages are built, not installed.