Skip to content

feat(advisor): remember the chosen repo scope across invocations#808

Merged
benw5483 merged 1 commit into
mainfrom
feat/advisor-repo-sticky-scope
Jul 15, 2026
Merged

feat(advisor): remember the chosen repo scope across invocations#808
benw5483 merged 1 commit into
mainfrom
feat/advisor-repo-sticky-scope

Conversation

@benw5483

@benw5483 benw5483 commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Summary

The actual advisor command now remembers which repository your questions are scoped to, so you set it once and every later question from the same working tree stays scoped without re-passing --repo.

  • The active scope is stored per repository. Whether you set it explicitly with --repo <name|id> or let auto-detection resolve it from the origin remote, a later bare actual advisor "<question>" reuses it.
  • --show-scope prints the active scope for the current repository and exits.
  • --repo none runs at the organization level and pins that choice; --repo auto forgets the pin and reverts to git-remote auto-detection.
  • --org (without --repo) runs a single question at the organization level without changing the remembered scope.
  • The question itself is optional when you only want to inspect or change the scope, e.g. actual advisor --repo my-service.

Behavior

Each query resolves its scope in this order: an explicit --repo value, then an explicit --org, then the scope remembered for this repository, then git-remote auto-detection, then an organization-level fallback. The CLI always states whether an answer is repo-scoped or organization-scoped, and it never silently guesses when a remote matches more than one connected repository. It lists the candidates instead.

none and auto are reserved --repo keywords. To scope to a repository literally named none or auto, pass its UUID or owner/name form.

Test plan

  • cargo test --lib advisor config::sticky covers the scope controls, persistence, precedence, and the reserved keywords.
  • cargo clippy -- -D warnings is clean.
  • cargo llvm-cov reports 100% per-file line coverage on the changed files.
  • Manual: actual advisor --repo <name> then a bare actual advisor "<question>" from the same repo, and confirm the second call reuses the scope; --show-scope reflects each change.

Persistence uses the existing config file, keyed per repository with the same scheme the other per-repo settings use.


Generated by the operator's software factory.
• On behalf of: @benw5483

Design note: scope persistence

The remembered scope persists in the CLI's existing per-user config file (keyed per repository by a hash of the origin remote URL), so it survives across shell sessions until you change it with --repo auto or --repo none. The alternative we considered is shell-ephemeral persistence: a session-scoped file cleared when the shell exits. We chose the durable per-repository model because it reuses how the CLI already stores per-repo state, and because re-pinning in every new shell would undercut the "set it once" goal. If reviewers prefer the ephemeral model, swapping the storage layer is a contained change. Feedback welcome.

@benw5483 benw5483 marked this pull request as ready for review July 13, 2026 21:50
@benw5483 benw5483 force-pushed the feat/advisor-repo-autodetect branch 2 times, most recently from b119b19 to e3ae442 Compare July 14, 2026 20:50
Base automatically changed from feat/advisor-repo-autodetect to main July 15, 2026 14:31
`actual advisor` now remembers which repository your questions are scoped
to, so you set it once and every later question from the same working tree
stays scoped without re-passing `--repo`.

- The active scope is stored per repository. Whether you set it with
  `--repo <name|id>` or let auto-detection resolve it from the `origin`
  remote, a later bare `actual advisor "<question>"` reuses it.
- `--show-scope` prints the active scope for the current repository and exits.
- `--repo none` runs at the organization level and pins that choice;
  `--repo auto` forgets the pin and reverts to git-remote auto-detection.
- `--org` without `--repo` runs a single question at the organization level
  without changing the remembered scope.
- The question is optional when a scope command is used on its own, e.g.
  `actual advisor --repo my-service`.

Scope resolution order: an explicit `--repo`, then an explicit `--org`, then
the scope remembered for the repository, then git-remote auto-detection, then
an organization-level fallback. `none` and `auto` are reserved `--repo`
keywords; a repository literally named that is still reachable via its UUID
or `owner/name` form. The scope persists in the existing config file, keyed
per repository with the same SHA-256-of-origin-URL scheme the other per-repo
settings use.

Per-file line coverage stays at 100%.

Generated by the operator's software factory.
City: factory-main · Agent: local-core.builder-1
On behalf of: @benw5483
Co-Authored-By: <operator-factory-bot> <factory-bot@<operator-domain>.invalid>
@benw5483 benw5483 force-pushed the feat/advisor-repo-sticky-scope branch from d00a1e2 to 14c7aab Compare July 15, 2026 14:42
@austinborn

Copy link
Copy Markdown
Contributor

Wanted to provide some clarifications my agent shared, but otherwise this looks good:

  1. First query on a freshly-cloned repo, does it identify the scope? Yes, via auto-detection. With no --repo and no remembered pin, it runs git remote get-url origin in your working directory, parses the owner/name (handles both SSH and HTTPS remote forms), and matches that against your org's connected repos (match_remote_to_repos in advisor.rs). A clean match is repo-scoped; no match or an ambiguous one falls back to org-level. So a fresh clone whose origin matches a connected repo is auto-scoped on the very first question, no pin needed.

  2. Does the sticky scope persist across restarts and instances? Yes. It's written to the existing on-disk config file, in a sticky_repo_scope map keyed per repo by the SHA-256 of the origin URL (the same compute_repo_key scheme the other per-repo settings use). Because it's on disk and keyed per repo, it survives restarts, is shared across CLI instances, and each repo keeps its own remembered scope independently.

  3. Does the scope only apply when the tool itself is invoked from within a given repo, or is the repo_dir passed into the tool as well? It's the working directory, always. There is an internal repo_dir, but it's just std::env::current_dir(); no --repo-dir or path argument exists on the command (AdvisorArgs only has query / org / repo / show-scope / base-url). Both the auto-detection and the per-repo key come from the origin of whatever git repo your cwd sits in (a subdirectory is fine, since git walks up to the root). Run it outside a git repo and there's no origin, so it can't key or auto-detect and drops to org-level.

@benw5483 benw5483 added this pull request to the merge queue Jul 15, 2026
Merged via the queue into main with commit 7468ee5 Jul 15, 2026
10 of 11 checks passed
@benw5483 benw5483 deleted the feat/advisor-repo-sticky-scope branch July 15, 2026 16:19
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