Skip to content

feat(source): add --skip-local-storage to stop shipping Local Storage - #150

Closed
Dannyxlm wants to merge 2 commits into
mvanhorn:mainfrom
Dannyxlm:source-local-storage-opt-out
Closed

Dannyxlm wants to merge 2 commits into
mvanhorn:mainfrom
Dannyxlm:source-local-storage-opt-out

Conversation

@Dannyxlm

Copy link
Copy Markdown

Summary

Adds agentcookie source --skip-local-storage, or AGENTCOOKIE_SKIP_LOCAL_STORAGE=1 for a LaunchAgent. With either set, pushes stop packing the browser profile's Local Storage leveldb, and the watcher stops watching that directory. A Linux sink (or any sink with skip_chrome_sqlite) never applies Local Storage. On our Mac it was 64 MB, so each push was ~90 MB: 150 GB uploaded in 16.5 h, plus context deadline exceeded on slower uplinks. With the flag, each push is ~1.8 MB and the sidecar receives the same cookies.

This is part 1 of #149.

Verified

  • go build ./...
  • go vet ./...
  • go test ./... (all 26 packages), plus go test -race ./internal/cli/ ./internal/config/
  • golangci-lint run ./internal/cli/... (v2.11.4): 0 issues
  • New TestSourcePushLocalStorageOptOut:
    • the default config still ships the tarball;
    • with the env var set, the envelope's LocalStorageTarball is empty and the cookie set is identical.
    • It fails without the change.
  • Live: the same skip, made with a config-only workaround (a non-existent browser.profile), on a v1.3.0 Mac source → v1.3.0 Linux sink. nettop showed ~90 MB → ~1.8 MB per push, with 0 failures after the switch.

Notes

  • Opt-in only. Without the flag, nothing changes.
  • No source.yaml key. I first tried local_storage: false, but TestSourceConfigYAMLKeysUnchangedForOlderBinaries (and strict decoding in older binaries) argue against new keys. So this follows the --skip-dbsc-suspect / AGENTCOOKIE_SKIP_DBSC_SUSPECT pattern instead.
  • Wire format unchanged. LocalStorageTarball is simply empty.
  • Sync filtering unchanged. The blocklist/allowlist behave exactly as before.
  • Possible follow-up: if you'd rather the sink tell the source it doesn't apply Local Storage, so it's skipped automatically, I'm happy to rework it that way.

(Prepared with my AI agent, Ava, while debugging our setup.)

Every push packs the source profile's Local Storage leveldb into the
envelope, and the watcher also pushes on Local Storage writes. A Linux
sink (or any sink with skip_chrome_sqlite) never applies it. On one Mac
the directory was 64 MB, so each push was ~90 MB (150 GB uploaded in
16.5 h), and slow uplinks overran the watcher's 60 s push budget.

--skip-local-storage (or AGENTCOOKIE_SKIP_LOCAL_STORAGE=1 for a
LaunchAgent) skips the pack and stops watching the directory. Default
behavior, source.yaml keys and the wire format are unchanged.

Refs mvanhorn#149
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-12T18:51:22.728989Z d269a9b PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@greptile-apps

greptile-apps Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

[Medium impact] The PR appears safe to merge; both previous findings are addressed and no new actionable issues remain.

Summary

Adds --skip-local-storage and AGENTCOOKIE_SKIP_LOCAL_STORAGE=1 to omit Local Storage from pushes and stop watching its directory.

  • Source pushes can skip Local Storage without dropping cookies.

Reviews (2) · Last reviewed commit: "test(source): compare full cookie sets, ..." · Reviewed by Greptile

Comment thread docs/faq.md Resolved
Comment thread internal/cli/source_test.go Resolved

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d269a9b51d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

t.Fatal(err)
}

if _, err := fx.push(); err != nil {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Clear the inherited skip env before testing the default

When the suite is run with the newly documented AGENTCOOKIE_SKIP_LOCAL_STORAGE=1 already exported, this first “default” push also skips packing because skipLocalStorage() reads the inherited process environment, so the assertion that the tarball is present fails before t.Setenv changes anything. Clear the variable at the start of the test (then set it to 1 for the second push) so users or CI exercising this environment-based feature can still run the suite.

Useful? React with 👍 / 👎.

…ndexedDB

Addresses review on mvanhorn#150: the default-push case clears an inherited AGENTCOOKIE_SKIP_LOCAL_STORAGE, the test compares whole Cookies slices instead of hosts, and the FAQ notes IndexedDB stays opt-in.
@Dannyxlm

Copy link
Copy Markdown
Author

Thanks for the reviews. dba41c2 addresses all three: the default-push case now clears an inherited AGENTCOOKIE_SKIP_LOCAL_STORAGE (verified by running the test with it exported), the test compares the full Cookies slices from both envelopes, and the FAQ notes that IndexedDB stays opt-in via AGENTCOOKIE_SYNC_INDEXEDDB=1. go vet, go test -race ./internal/cli/ and golangci-lint are clean.

@mvanhorn

Copy link
Copy Markdown
Owner

Thanks @Dannyxlm, this is a great find and a clean fix. Your two commits are cherry-picked onto #153 with your authorship kept, and you are credited as co-author. That PR also adds --skip-secrets (#151) so a normal source can run cookie-only. The rest of #149 is in #152 (live_cdp.enabled: false on Linux) and a push-cadence PR (unchanged-push dedup and the 60s watch budget). Leaving this open until #153 merges.

mvanhorn added a commit that referenced this pull request Oct 15, 2026
…secrets (#153)

* feat(source): add --skip-local-storage to stop shipping Local Storage

Every push packs the source profile's Local Storage leveldb into the
envelope, and the watcher also pushes on Local Storage writes. A Linux
sink (or any sink with skip_chrome_sqlite) never applies it. On one Mac
the directory was 64 MB, so each push was ~90 MB (150 GB uploaded in
16.5 h), and slow uplinks overran the watcher's 60 s push budget.

--skip-local-storage (or AGENTCOOKIE_SKIP_LOCAL_STORAGE=1 for a
LaunchAgent) skips the pack and stops watching the directory. Default
behavior, source.yaml keys and the wire format are unchanged.

Refs #149

* test(source): compare full cookie sets, isolate env; clarify FAQ on IndexedDB

Addresses review on #150: the default-push case clears an inherited AGENTCOOKIE_SKIP_LOCAL_STORAGE, the test compares whole Cookies slices instead of hosts, and the FAQ notes IndexedDB stays opt-in.

* feat(source): add --skip-secrets for a cookie-only source

A normal source always loaded the secrets bus and shipped it to every
push sink and, through GET /pull, to every paired teammate. Owners who
keep tokens in a password manager had no way to say "never ship
secrets from this source" short of running a CDP source.

agentcookie source --skip-secrets (or AGENTCOOKIE_SKIP_SECRETS) skips
loadSecretsPayload on every push and, in --watch, starts neither the
secrets-bus watcher nor the discovery watcher, so no manifest or carried
file is read. The env var fails closed: any value other than empty or 0
turns it on, and an unusual value warns once. Source state records
whether the last push skipped secrets and how many CLIs it shipped, and
doctor reports it as "Secrets push". Docs cover the cookie-only recipe
and note that the switch does not remove secrets already delivered.

Requested by @jnyross in #151.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01LgVWtkXgDGWMh6L95d8piN

* refactor(source): tidy the --skip-secrets switch and doctor wording

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01LgVWtkXgDGWMh6L95d8piN

* fix(source): keep the secrets summary on dry runs; move skip switches

A --dry-run cycle sends nothing, but it overwrote the recorded secrets
summary, so doctor could say "shipping N cli(s)" for secrets that never
left the machine. Dry runs now leave it alone. The skip switch helpers
move to source_skip.go to keep source.go from growing.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01LgVWtkXgDGWMh6L95d8piN

* fix(source): keep the secrets summary when a cycle fails before publishing

Addresses review feedback on #153.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01LgVWtkXgDGWMh6L95d8piN

* fix(source): carry the saved secrets summary into a new source run

Addresses review feedback on #153.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01LgVWtkXgDGWMh6L95d8piN

---------

Co-authored-by: Dannyxlm <[email protected]>
Co-authored-by: Matt Van Horn <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
@mvanhorn

Copy link
Copy Markdown
Owner

Landed in #153 (squash 48725d6) with your two commits credited as co-author. Thanks again @Dannyxlm, the measurements made this an easy call. It ships in the next release along with the rest of #149.

@mvanhorn mvanhorn closed this Oct 15, 2026
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.

2 participants