Skip to content

Keep agent connector profiles safe across server upgrades - #907

Open
robzolkos wants to merge 5 commits into
mainfrom
feature/agent-connections-compatible
Open

robzolkos wants to merge 5 commits into
mainfrom
feature/agent-connections-compatible

Conversation

@robzolkos

@robzolkos robzolkos commented Oct 14, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Make connector state per profile and connection guidance safe to merge/release before the companion server change.

  • Separate each profile's ledger, cursor, durable hold and instance lock. Two profiles for one agent can run together; a second run of the same profile is refused.
  • Adopt the whole legacy state directory only after the credential proves the saved agent identity, under the legacy lock. Preserve checkpoints, held work and operator decisions; log both migration paths and warn fresh siblings where earlier state lives. Canonical account aliases meet one new-profile lock without losing older builds' literal account spelling.
  • Keep status/doctor/offline decisions on legacy state until adoption. Refuse unverified legacy shadow promotion: first run the selected profile with connect --shadow, verify, stop, then promote.
  • Name the profile in refusals and say disconnected in Basecamp, or replaced by a newer connection. Approval may add or replace: current servers, adding-OFF personal agents and shared agents still replace. No unconditional “each approval adds” promise, including the skill published on merge.
  • Warn about project overlap at guided project selection and in help: requests admitted by both connections can be answered twice. Overlap remains allowed; no lease/deduplication redesign.
  • Point lost-handover cleanup at the newest connection, not Disconnect all. Do not read/delete external credential files; on an add-capable server an old file or overwritten profile credential can remain live until its connection is disconnected.

Companion server integration: bc3 draft #13840. Exact-head GitHub checks have converged: 27 successful, 4 skipped, 1 neutral / 32 total, none failing or pending. Jeremy and the CLI team are requested for fresh review. Copilot's fresh request was quota-blocked, not a completed review. The CLI checks/source review do not clear the server's production/staging Ops, CI or activation gates.

CLI-first rollout / rollback

The secret remains opaque; no new server endpoint or feature flag is required by this CLI. Upgrade without reconnecting:

  1. Stop older connectors/supervisors for this account/agent on the host.
  2. Restart its existing profile on this build before adding another profile. Check the adoption WARN, resumed cursor, hold and status.
  3. Only add independent personal-agent connections after server support is confirmed. Until then, a second approval may replace the first; shared agents continue replacing even with adding enabled.

Operator upgrade, mixed-version and downgrade runbook: an older build restarted after adoption can recreate legacy state and miss the migrated hold/cursor. Downgrade offline, choosing one profile and restoring its whole normal/shadow directories to the old names; never overwrite existing ledgers or delete other profiles' state/credentials. Server switch-off disables adding, not existing added connections; server code downgrade after own-secret issuance is unsupported.

The consumer namespace intentionally stays per agent: it is a key in each isolated local profile ledger, never a server consumer. Renaming it would orphan migrated checkpoints.

Exact-head validation

Head: 13109a9413f7c2ac942e6f120a62cc663b24b330; tracked tree clean/frozen throughout the final run.

bin/ci exit 0, fresh temporary HOME/XDG, BASECAMP_NO_KEYRING=1. The script is only exec make check: this is a local CI pass, not a recorded GitHub signoff. No manual signoff. Exact-head public GitHub checks: 27 successful, 4 skipped, 1 neutral / 32 total, no failure/pending checks. Skipped/neutral checks are not test proof. Fresh human review remains pending; no merge-ready claim.

Check Result
Go top-level 4,930 passed / 4,935 total, 0 failures, 5 skips
Go including subtests 9,265 passed / 9,271 total, 0 failures, 6 skips
E2E/BATS 490 passed / 498 total, 0 failures, 8 skips
Focused migration/copy race suite 36/36 passed, no skips, exit 0
Deliberate regression probes 5/5 caught, each mutant exit 1; clean suite exit 0
Lint / surface / skill drift / provenance / tidy Passed; lint 0 issues; 19,565 surface entries unchanged

Go skips: opt-in callback preview; existing SDK redirect-classification skip pending re-pin; three subprocess entrypoints (credential-lock helper, fake MCP server, crash helper); one additional nested foreign-ownership test requiring root/chown. The helper entrypoints are invoked by their parent tests, but skips themselves are not proof. BATS skips: six PowerShell installer cases because pwsh is absent, and two unimplemented URL breadcrumb cases.

Independent exact-head adversarial source review: 8/8 state-reader classes rechecked, no actionable CLI finding. This is source review, not independently executed lifecycle/CI. The companion server's two findings were fixed in its reviewed source; server Ops clearance remains separate.

Genuine isolated lifecycle evidence — limited matrix

The final lifecycle report records 28 passed / 34 planned atomic observations, 6 explicitly unexecuted. Synthetic-only real processes, HTTP, browser approvals and WebSockets; isolated HOME/XDG/keyring and loopback network. No customer credentials or AI dispatch. These are lifecycle-agent/coordinator observations, not fake-server unit tests and not a claim of 34/34 runtime scenarios. The table below is the CLI-relevant subset, not another aggregate denominator.

Scenario actually exercised Observation
Released v0.13.2 on the old server Real browser approval, mint/me/projects, six-check setup and live feed subscription; 2/2 synthetic assignments admitted under a durable hold
Released v0.13.1 Existing A credential me on old server exit 0; real shared-agent approval/mint/me on integrated server. Not a separate old-server new-approval/feed proof
Earlier integrated CLI before server upgrade No re-pair; cursor, hold and 2/2 admitted records migrated; status/release exit 0; same-profile second connector exit 5; fresh event emitted one request. This baseline observation preceded final 13109a9
Integrated server adding OFF A freshly minted without re-pair; a second personal approval replaced the first as intended
Adding ON / shared agents Same-host new profile and separate-HOME connections; 3/3 disjoint project events each emitted one request. Same-name personal reapproval added; shared v0.13.1/new/v0.13.2 approvals still replaced
Own-secret authentication / scope Valid full-scope mint HTTP 200; cross-agent/tampered secrets rejected; refresh/introspection/revocation denied. Read-only write HTTP 403 while A retained full write access
#1 and own-row disconnect A stopped after original #1 disconnect; final 13109a9 B/C reconnected and emitted 2/2 fresh post-revocation requests. Later B-only disconnect stopped its final-CLI socket with disconnected-or-replaced copy while other connections survived
Deliberate project overlap Same event emitted once on each connector, 2/2, accepted policy. JSON setup prints no human warning; built help warning verified
Adding-only rollback 4/4 existing own-secret profiles freshly minted; legacy reapproval preserved all four; fresh event admission continued
Disconnect all 5/5 legacy/own connections stopped/refused

The two older admitted requests were retained after migration but excluded from handoff after release by the existing before_this_run age guard. Migration does not promise historical replay. Explicitly held records remaining held and accessible to release/discard are separately covered by automated tests.

Limits: guided selection warning is source/unit-covered, not real-TTY exercised. Genuine runtime full shadow adoption/promote/import/discard/all-operator-command coverage was not executed; automated CLI tests cover these paths. Runtime status/release/adoption were exercised. The six broader unexecuted runtime groups are shared Adminland rotation, stale browser forms across replacement races, concurrent HTTP mint/revoke/scope interleavings, actual replica lag/roles, full shadow/operator commands, and ONCE browser/HTTP/schema downgrade. Automated server/CLI coverage is separate, not counted as lifecycle proof. Final ReviewB/ReviewC connectors remain live for review.

Attribution / source consolidation

Preserve the original work, not its rollout-unsafe promises:

Rob Zolkos authorship and source provenance are preserved in the five coherent commits: 51fca73, 72e3abb, 222621a, 78c88a8, 13109a9. Existing source PRs/branches are not closed or rewritten by this consolidation.

Original-review replies

Point-by-point replacement-only replies to the latest review bodies, with pinned source/test links and explicit retained declines/human decisions:

The cross-repository comparison covered 36/36 Jeremy top-level points and their nested subfindings, plus older bot/body findings: 81 pre-reply source records (7 PR bodies, 40 reviews, 6 issue comments, 28 inline comments) and all 14 GraphQL threads (the same 28 inline comments, not extra findings). Empty bodies and the fresh Copilot quota failure were accounted for, not counted as approvals. Independent xhigh comparison found no additional in-scope source defect; this follow-up changed no source and reran no tests. Historical originals remain unchanged/open and no thread-resolution state was changed. This is a disposition map, not a claim that every literal proposal was implemented or accepted.

The old switch-on CLI release prerequisite is superseded by the compatible CLI-first plan: refusal/help/README/merge-published skill now cover replacement on old/adding-OFF/shared servers. Human release/review decisions remain pending; unsupported mixed builds and the stop/whole-directory downgrade procedure remain explicit.

Reuse Rob Zolkos’s profile migration and operator coverage from CLI #901 at 8ead732 (f78ef23 through 8ead732). Preserve checkpoints, held work and offline operator fallback. Apply Jeremy Daer’s October 14 review: refuse unverified legacy shadow promotion, log adoption and sibling state, distinguish legacy locks, cover working wrong-person credentials and shadow adoption, and document mixed-version/downgrade recovery.
Reuse safe copy and lost-handover tests from Rob Zolkos’s CLI #900 at 7ba7e96 (2765820 through 7ba7e96), without its unconditional adds promises. Approval may add or replace until personal-agent adds are enabled, and shared agents still replace. Apply Jeremy Daer’s review: name the refused profile and both causes, warn overlap at guided project selection, keep live credential files, distinguish the newest lost connection from Disconnect all, and contract-test the skill stop fragment.
Seed explicitly held work in migration tests, verify it stays held through normal/shadow adoption and release, then discard it through the selected profile. Cover canonical-account lock collisions and invalid adoption names. Clarify the existing pre-run handoff age guard: migrated state is preserved, not automatically replayed.
Older builds wrote account ids verbatim into state directory names. Find that original directory during adoption, but canonicalize the new profile path so numeric aliases cannot bypass its lock. Cover a padded legacy account migration and document downgrade spelling.
@robzolkos
robzolkos requested a review from a team as a code owner October 14, 2026 20:27
@robzolkos
robzolkos requested review from jeremy and a balanced review from Copilot October 14, 2026 20:27
@github-actions github-actions Bot added commands CLI command implementations tests Tests (unit and e2e) skills Agent skills auth OAuth authentication docs labels Oct 14, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auth OAuth authentication commands CLI command implementations docs skills Agent skills tests Tests (unit and e2e)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants