feat: checkpoint egress trust gate for globally tracked repos (global enable: E) - #2030
feat: checkpoint egress trust gate for globally tracked repos (global enable: E)#2030peyton-alt wants to merge 15 commits into
Conversation
…gress predicate Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…d repos; y/n/A trust prompt at interactive pushes Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…cross status/doctor/session-start Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Entire-Checkpoint: 01M08T1GNCGPYG9T71HPB70R9S
…d push coverage Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR introduces a per-repository trust gate for checkpoint egress when a repo is enrolled via global tracking (no repo-level .entire setup), so session capture can be enabled machine-wide while checkpoint sync on git push remains opt-in per repo.
Changes:
- Adds a global trust store (
trust_all,trusted_origins,trusted_paths) and a newentire trustcommand (with revoke support) to manage checkpoint egress consent. - Enforces the trust gate at both checkpoint egress entry points (
prePushandPushQueuedCheckpointRefs), without blocking the user’s normal branch push. - Surfaces trust/hold state across CLI UX (status JSON + text, session-start banner, doctor output, global enable/disable warning flows) and documents the model.
Reviewed changes
Copilot reviewed 28 out of 28 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| docs/security-and-privacy.md | Documents the “global tracking + per-repo trust” model and expected push behavior. |
| cmd/entire/cli/trust_cmd.go | Implements entire trust and --revoke for recording/withdrawing egress consent. |
| cmd/entire/cli/trust_cmd_test.go | Unit tests for trust command behavior and messaging. |
| cmd/entire/cli/strategy/trust_prompt.go | Adds pre-push trust prompt plumbing and persistence logic. |
| cmd/entire/cli/strategy/trust_prompt_test.go | Tests prompt decision handling (non-interactive hold, yes/always/not-now, write failures). |
| cmd/entire/cli/strategy/refs_push_test.go | Extends queued-ref push tests to ensure untrusted repos are held at the non-prePush egress entry point. |
| cmd/entire/cli/strategy/manual_commit_push.go | Wires the trust gate into prePush and PushQueuedCheckpointRefs. |
| cmd/entire/cli/strategy/manual_commit_opf_rewrite_test.go | Updates OPF pre-push tests for the new gate setup requirements. |
| cmd/entire/cli/strategy/common_test.go | Adds shared test helpers for global enrollment + stderr capture + repo-level enable fixtures. |
| cmd/entire/cli/strategy/checkpoint_sync_remote_test.go | Adds end-to-end pre-push gate coverage for both checkpoint backends. |
| cmd/entire/cli/strategy/checkpoint_policy_test.go | Refactors stderr capture and updates fixtures for the new gate path. |
| cmd/entire/cli/status.go | Adds trust state/source + held checkpoint count to status output (text + JSON). |
| cmd/entire/cli/status_global_test.go | Tests trust state rendering and JSON field stability. |
| cmd/entire/cli/setup_global.go | Hooks global warn marker ack/retire into enable/disable global flows and adds disable messaging. |
| cmd/entire/cli/setup_global_test.go | Pins disable-global output to include the held-data consequence. |
| cmd/entire/cli/settings/trust.go | Implements trust identity derivation and the trust/egress gate predicates + writers. |
| cmd/entire/cli/settings/trust_test.go | Thorough unit coverage for identity derivation, gating rules, trust writes, and revoke behavior. |
| cmd/entire/cli/settings/global.go | Extends strict-decoded user settings schema with trust fields and rationale. |
| cmd/entire/cli/settings/global_test.go | Pins trust JSON tags via a strict load/save round-trip test. |
| cmd/entire/cli/root.go | Adds one-time global tracking detection warning and registers experimental trust command. |
| cmd/entire/cli/lifecycle.go | Adds a session-start banner line for untrusted globally-enrolled repos. |
| cmd/entire/cli/lifecycle_test.go | Tests banner suffix inclusion rules (untrusted only, codex single-line variant, etc.). |
| cmd/entire/cli/integration_test/checkpoint_sync_remote_test.go | Real-binary integration test: held push → entire trust → backlog drains (both backends). |
| cmd/entire/cli/global_warn.go | Implements one-time “global enabled” detection warning via a config-dir marker file. |
| cmd/entire/cli/global_warn_test.go | Tests marker lifecycle and root-command integration (enable/disable handshake). |
| cmd/entire/cli/doctor.go | Adds informational “sync held” doctor row for untrusted globally-enrolled repos, including held count. |
| cmd/entire/cli/doctor_global_test.go | Tests doctor output is INFO-only for held state and disappears after trust. |
| CLAUDE.md | Updates internal architecture docs to describe the new trust gate behavior. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 6b62828. Configure here.
…ke no-op, cover prompt-error and hand-edit tolerance Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…y, wizard warn ack, inactive-tier refusal, poisoned-path resilience Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rip rationale comments Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
298f35b to
c82ffe0
Compare
028696c to
1d3f451
Compare
# Conflicts: # CLAUDE.md # cmd/entire/cli/doctor_global_test.go # cmd/entire/cli/status_global_test.go # cmd/entire/cli/strategy/checkpoint_sync_remote_test.go
Trail 1074 finding: two marker blocks were committed in 922f4ec. The merge listed CLAUDE.md among its conflicts, but I read the output through `tail`, resolved only the files it showed, and `git add -A` staged the markers — no Go gate reads markdown, so nothing caught it. Both regions resolved on the merits, not by picking a side: the experimental-commands list takes main's shorter form (`search` is a real top-level command there now) plus this branch's `trust` entry; the checkpoint section takes main's rewritten single-remote bullet and its new reads-follow-the-election bullet, then this branch's egress trust-gate bullet, which sits directly above the OPF bullet it references. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Carry explicit repo activation intent through checkpoint egress, trust commands, and status. Incidental settings continue through the global trust gate; malformed activation settings hold data locally.
Carry the Claude SubagentStop user-hook completeness repair into the final trust-gate branch.

https://entire.io/gh/entireio/cli/trails/1074
What
Globally-enrolled repos (global tier on, no repo-level
.entiresetup) capture agent sessions locally but never sync checkpoint data atgit pushuntil the user trusts the repo once. Enrollment (hook install + local capture) and egress (checkpoint sync) become two separately-consented layers:global.enabled+ exclude lists govern the first, per-repo trust governs the second. Answers the residual consent risk from the T-167 security thread that the local_dev removal deliberately did not cover.How
settings.CheckpointEgressAllowed— repo-level setup passes (explicit enable was consent; zero change for existing users); globally-enrolled repos needtrust_all, all origin-URL keys trusted, or a path grant. Fail closed, warn open. Two call sites:prePush(above both storage backends; OPF never runs for held repos; the user's push is never blocked) andPushQueuedCheckpointRefs.trust_all/trusted_origins(exact normalized keys — mirror↔forge URL forms share one key) /trusted_paths, beside the exclude lists in the user-global settings. Identity is exclusive (origin XOR path): a path-trusted repo that gains a real origin re-asks; mixed origins with any unnormalizable URL key by path.trust_all) — on the OPF pre-push prompt seam; non-interactive pushes hold with one stderr line and exit 0.entire trust/--revoke(experimental-gated for soft launch, always runnable): revoke clears both key namespaces so revoked consent can't resurrect via a stale path entry, and calls out whentrust_allmasks it.global.enabledflips on (observational-generation marker;trust_allcopy variant; symmetric off-note), session-start banner line for untrusted repos, statustrust_state/trust_source, doctor info row with held count,disable --globalheld-data note, docs section insecurity-and-privacy.md.Notes for reviewers
entire trust→ backlog drains) on both storage backends. Full gates green: unit (9129), integration (498), e2e canary (Vogon 60/60).trust --reviewbatch flow lands after feat(binding): record cross-repo session evidence (activity-time binding, slice 1) #1959 (its data source is the binding session records);doctor migrate's push-now path surfaces the hold as a command error rather than an inline trust offer; wizard/--globalshims return at rollout.Part of #1098.
🤖 Generated with Claude Code
Note
Cursor Bugbot is generating a summary for commit 6b62828. Configure here.