From ae0c48de76c3a0e36a1c2944ea65b99ced4d40ce Mon Sep 17 00:00:00 2001 From: Rian Stockbower Date: Sun, 21 Jun 2026 18:48:10 -0400 Subject: [PATCH 01/27] Rethink credential storage and reviewer entity init model --- docs/init-config-surface.md | 19 +- docs/init-ux-contract.md | 30 +- internal/cmd/configcmd/configcmd.go | 46 +- internal/cmd/configcmd/configcmd_test.go | 16 +- internal/cmd/credentialcmd/credentialcmd.go | 595 ++++++++++++++---- .../cmd/credentialcmd/credentialcmd_test.go | 359 ++++++----- .../cmd/credentialcmd/init_inventory_test.go | 18 +- internal/cmd/credentialcmd/init_menu.go | 6 +- internal/cmd/credentialcmd/init_profile_v2.go | 24 +- .../init_reviewer_entity_editor.go | 28 +- internal/cmd/mecmd/mecmd_test.go | 101 +-- internal/config/config.go | 464 ++++++++++++-- internal/config/config_test.go | 370 ++++++----- internal/config/init_surface_doc_test.go | 1 - internal/identity/identity.go | 37 +- 15 files changed, 1513 insertions(+), 601 deletions(-) diff --git a/docs/init-config-surface.md b/docs/init-config-surface.md index 12416ae3..7b354f7f 100644 --- a/docs/init-config-surface.md +++ b/docs/init-config-surface.md @@ -48,25 +48,16 @@ intentionally unsupported. | config.repository_profiles[].match.host | Route wizard derives from selected profile host or pasted PR URL. | Existing `cr config route set --host`. | Required for a route. Existing host is pre-populated and normalized. | Must match the target profile's `git.host`. Host edits on a profile with routes are blocked or reconciled by #185. | #177 route helper, #185 PR URL derivation and host/profile validation tests. | | config.repository_profiles[].match.namespace | Route wizard asks for owner/org or derives from PR URL. | Existing `cr config route set --namespace`. | Required for a route. Existing namespace is pre-populated. | Overwrite validates non-empty and preserves repo-vs-namespace route identity. | #177 route helper. #185 namespace route tests. | | config.repository_profiles[].match.repos[] | Route wizard supports namespace-wide route when omitted or repo-specific routes when provided. | Existing repeatable `cr config route set --repo` and `cr config route unset --repo`. | Omitted means namespace-wide route. Existing repos are pre-populated in deterministic order. | Preserve on skip. Add/edit/remove dedupes and sorts via shared route helper. Clear repos converts only when the user explicitly chooses namespace-wide routing. | #177 route helper. #185 repo route and namespace conversion tests. | -| config.profiles. | Core profile wizard selects existing profile, creates a new profile, or renames an existing profile. | Existing global `--profile` with `cr init --non-interactive` owns scripted create/replace. Scripted rename is intentionally unsupported by init and belongs to future profile-management command design. | When `cr init` starts without a global `--profile`, it suggests `default` as the new profile name. Existing profile names are pre-populated. | Create requires a valid profile body. Rename preserves credential locations by default, updates repository routes, and does not delete old credential-store entries. | #177 profile rename helper. #180 tests create/select/rename and validation. | +| config.profiles. | Core profile wizard selects existing profile, creates a new profile, or renames an existing profile. | Existing global `--profile` with `cr init --non-interactive` owns scripted create/replace. Scripted rename is intentionally unsupported by init and belongs to future profile-management command design. | New profile names start blank. Existing profile names are pre-populated. | Create requires a valid profile body. Rename preserves credential locations by default, updates repository routes, and does not delete old credential-store entries. | #177 profile rename helper. #180 tests create/select/rename and validation. | | config.profiles..git.host | Core profile wizard edits Git host. | Existing `cr init --git-host`; existing route commands own route-safe scripted changes. | Current init defaults to `github.com`. Existing value is pre-populated. | Set validates non-empty normalized host. If routes reference the profile and reconciliation is not selected, block or defer the edit. | #180 blocks/defer route-unsafe host edits. #185 implements reconciliation tests. | | config.profiles..git.auth_mode | Core profile wizard chooses `pat` or `github_app`; `oauth_device` remains reserved. | `cr init --git-auth-mode`, parallel to existing reviewer auth mode. Current init otherwise defaults user Git auth to PAT. | Existing value is pre-populated. New profile defaults to `pat`. | Overwrite only to supported v1 modes. Switching auth modes re-plans credential keys but does not delete old secrets. | #179 credential-ref/key-spec planner. #180 auth-mode prompt tests. | | config.profiles..git.credential.store | User Git auth chooses an existing credential store before any secret ingress. | Interactive credential-writing flows and scripted `cr set-credential --store`. | New profiles start with `local-os` selected. Existing store id is pre-populated. | Must be `local-os` or a configured store id. Store setup is not available inline from this flow. | #356 explicit destination tests. | | config.profiles..git.credential.name | User Git auth names the credential bundle before any secret ingress. | Interactive credential-writing flows and scripted `cr set-credential --name`. | New profile defaults to `codereview/`. Existing name is pre-populated and preserved by default. | Must use the `codereview/` credential grammar. It must differ from other credentials in the same profile when the store also matches. | #356 explicit credential-location tests. | | config.profiles..git.identity_cache | Not shown as an editable init field. Preserve only. | Intentionally unsupported for init and config mutation. Runtime identity refresh owns it. | Existing cache is preserved. New profiles omit it. | Preserve unless a future explicit cache invalidation ticket owns behavior. Profile rename does not rewrite cache contents. | Preserve-only regression in #177/#180. | -| config.profiles..reviewer_credentials | Optional reviewer credential section. Wizard supports skip, preserve, enable, edit, or clear reviewer config. | Existing `cr init --reviewer-credential-ref` and `--reviewer-auth-mode` own enable/edit. `cr init --disable-reviewer` owns scripted removal. | Omitted means posting uses Git credentials. Existing section is pre-populated. | Clear removes the whole section. Enable requires auth mode and credential location. The store/name pair must differ from Git and LLM credential locations. | #179 planner and #180 optional section tests. #181 secret ingress tests. | -| config.profiles..reviewer_credentials.auth_mode | Reviewer wizard chooses PAT or GitHub App; `oauth_device` remains reserved. | Existing `cr init --reviewer-auth-mode`. | Current init defaults reviewer mode to `pat` when reviewer credentials are requested. Existing value is pre-populated. | Overwrite only to supported v1 modes. Switching modes re-plans key specs and preserves old secrets unless explicit overwrite/migration occurs. | #179 credential bundle tests for PAT and GitHub App. | -| config.profiles..reviewer_credentials.credential.store | Reviewer Git auth chooses an existing credential store before any secret ingress. | Interactive credential-writing flows and scripted `cr set-credential --store`. | New reviewer credentials start with `local-os` selected unless the user chooses another configured store. Existing store id is pre-populated. | Must be `local-os` or a configured store id. Store setup is not available inline from this flow. | #356 explicit destination tests. | -| config.profiles..reviewer_credentials.credential.name | Reviewer Git auth names the credential bundle before any secret ingress. | Interactive credential-writing flows and scripted `cr set-credential --name`. | New reviewer section defaults to `codereview/-reviewer`, or `codereview/