Skip to content

[AI-1677] flows.reviewer_vendor preference + vendor-less definition fallback - #433

Merged
alexeyzimarev merged 7 commits into
mainfrom
ai-1677-reviewer-vendor-preference
Aug 2, 2026
Merged

alexeyzimarev merged 7 commits into
mainfrom
ai-1677-reviewer-vendor-preference

Conversation

@alexeyzimarev

Copy link
Copy Markdown
Member

Summary

Three commits deliver a local fallback for the case a review-flow catalog definition names no reviewer vendor:

  • flows.reviewer_vendor config key + kcap config unset — a new per-profile preference (ProfileConfig/FlowsSettings.ReviewerVendor), set via kcap config set flows.reviewer_vendor <vendor> (warns, but does not reject, an unrecognized vendor token — the server has the authoritative list) and removed via the new kcap config unset <key> subcommand (currently only supports this key).
  • Preference-backed reviewer-vendor fallback in kcap mcp flows — when a vendor-less, non-dynamic, non-model-bearing start_review_flow/start_flow is refused by the server with the coded reviewer_vendor_required, the CLI retries exactly once with the saved flows.reviewer_vendor preference injected as an explicit vendor argument — indistinguishable from a caller-supplied one, so the existing vendor-echo check still asserts against it and defensively closes the run on a mismatch. The trigger (ShouldPreferenceRetry) is deliberately narrow: a start is non-idempotent, so it fires only for the structured code on a start that never named a vendor and never carried a model or definition_yaml — a model-bearing v3 start returns the same code for a blank vendor but must never have a preference silently shadow the vendor its pinned model belongs to, and no uncoded body, other code, or transport ambiguity can reach the retry. With nothing saved, the tool result asks the driver to prompt the user and offer to save the answer; a stale preference (reviewer_vendor_unavailable/unknown_vendor on the retry itself) gets a re-ask-and-re-save remedy instead of blaming an unrelated fault.
  • Shared settlement budget across the retry — the retry originally opened a second full 3-minute settlement window, so a worst-case call could spend 3m + 3m plus the poll cap, past the harness MCP tool timeout the deadline was sized against — in the worst shape available, the retry POST succeeds, a paid reviewer launches, and the harness has already given up and the driver starts the flow again. SendWithSettlementRetryAsync now takes an optional budgetStartedAt; the start arm takes one timestamp before the first send and threads it into the retry so both sends share one window, and an already-spent budget returns before posting at all. Every other caller is unchanged.
  • Skill text + conformance pins — agent-flows and review-flows SKILL.md now teach the definition-authored-vendor → saved-preference → reviewer_vendor_required chain (replacing the old "server default" framing), with matching updates to the anti-hallucination "do not claim a named reviewer ran" guidance and the tool-parameter tables; FlowsDriverSchemaConformanceTests pins the new wording.
  • README + config help — rewrites the two remaining Flows:Review:DefaultVendor references (the start_flow tool doc and the "restart your harness after upgrading" callout) to the landed vendor-resolution ladder, and adds kcap config unset + the flows.reviewer_vendor key to help-config.txt.

Compatibility

  • Old servers: the retry trigger fires on a code old servers already emit today (reviewer_vendor_required for an unconfigured/unnamed reviewer) — no server-side change is required for the fallback to work.
  • New servers: the companion server PR (kurrent-io/kcap-server#1272) makes vendor resolution definition-authored (explicit → definition's authored vendor → reviewer_vendor_required) instead of a server-wide configured default; this CLI's fallback composes with that unchanged.
  • MCP reconnect: as documented in the README's existing upgrade callout, a harness caches each MCP server's tool schema once at connect — restart the harness (or reconnect kcap-flows) after upgrading to see any tool-description wording change from this PR.

Test plan

  • dotnet build Capacitor.slnx — 0 errors (pre-existing Scriban.Signed NuGet advisory warnings only, unrelated to this branch)
  • Full unit suite (Capacitor.Cli.Tests.Unit) — 5161 total, 47 failed, 5090 passed, 24 skipped. The 47 failures are the known pre-existing baseline (Codex TOML / Uninstall / BorrowedReviewAuthBroker sandbox artifacts, reproduced at branch base) — zero new failures. ConfigCommandTests (26/26) and ReviewerVendorFallbackTests (42/42) — this PR's own coverage — pass fully.

Server PR: https://github.com/kurrent-io/kcap-server/pull/1272

🤖 Generated with Claude Code

alexeyzimarev and others added 5 commits August 2, 2026 18:13
A vendor-less catalog start whose definition names no reviewer is refused by
the server with the structured reviewer_vendor_required code. Retry that once
with the saved flows.reviewer_vendor preference, injected as an explicit
vendor so the request is indistinguishable from a named one — the echo check
asserts against it, and a mismatch still closes the run defensively.

The trigger is the safety boundary: a start is non-idempotent, so it fires
only for the structured code on a non-dynamic, non-model-bearing, vendor-less
start. A model-bearing v3 start is excluded by shape (it returns the same code
for a blank vendor, where a preference would shadow the vendor the pinned
model belongs to), and no uncoded body, other code, or transport ambiguity can
reach it. The retry is terminal either way: a stale preference gets the
re-ask-and-re-save remedy, anything else surfaces as itself.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The retry was opening a second full 3-minute settlement window, so a tool
call could spend 3m + 3m plus the poll cap — past the harness MCP tool
timeout the deadline was derived against, and in the worst shape available:
the retry POST succeeds, a paid reviewer launches, the harness has already
given up, and the driver starts the flow again.

SendWithSettlementRetryAsync gains an optional budgetStartedAt; the start arm
takes one timestamp before the first send and threads it into the retry, so
both sends share a single window and a spent one returns before posting at
all. Every other caller is unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The README's start_flow tool doc and the "restart after upgrade" callout
still described the removed Flows:Review:DefaultVendor server setting.
Rewrite both to the landed vendor-resolution ladder (explicit -> the
definition's authored vendor -> the CLI's saved flows.reviewer_vendor
preference, applied via one automatic retry -> coded
reviewer_vendor_required), matching the wording already landed in the
review-flows/agent-flows skills. Also teach kcap config's help text about
the new unset subcommand and the flows.reviewer_vendor key.
@linear-code

linear-code Bot commented Aug 2, 2026

Copy link
Copy Markdown

AI-1677

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Add saved reviewer-vendor fallback for vendor-less review-flow starts

✨ Enhancement 🐞 Bug fix 🧪 Tests 📝 Documentation ⚙️ Configuration changes 🕐 40+ Minutes

Grey Divider

AI Description

• Add per-profile flows.reviewer_vendor preference plus kcap config unset support.
• Retry vendor-less catalog flow starts once using the saved preference on
 reviewer_vendor_required.
• Share a single settlement budget across the retry and update docs/conformance tests.
Diagram

graph TD
  D["MCP driver/harness"] --> M["kcap McpFlowsServer"] --> A[["Flows API"]]
  A -- "reviewer_vendor_required" --> M --> C[("Profile config")]
  C --> M --> S["Shared settlement budget"] --> A
  A -- "vendor echo mismatch" --> M --> X["Best-effort close"] --> A

  subgraph Legend
    direction LR
    _cli["CLI component"] ~~~ _api[["HTTP API"]] ~~~ _cfg[("Stored config")]
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Always prompt the user when vendor is omitted
  • ➕ Zero risk of starting a paid/non-idempotent flow with an unintended vendor
  • ➕ No need for preference storage or retry logic
  • ➖ Degrades UX for vendor-less definitions (asks every time)
  • ➖ Harder for headless/automated drivers where prompting is expensive or impossible
2. Server-side default for vendor-less definitions
  • ➕ Centralized policy; no client retry complexity
  • ➕ Consistent behavior across all clients (not just kcap)
  • ➖ Reintroduces “silent default” ambiguity the PR is trying to avoid
  • ➖ Requires server config/admin work and still may not match user intent per profile
3. Persist preference per definition_id (mapping) instead of one global key
  • ➕ More precise; avoids applying a single default across unrelated definitions
  • ➕ Could support gradual migration if catalog definitions vary by team
  • ➖ More UI/CLI surface area (list/edit mappings)
  • ➖ More complex storage and decision logic; higher chance of surprising behavior

Recommendation: The PR’s approach (a narrowly-gated single retry on the structured reviewer_vendor_required code, only for vendor-less + model-less + non-dynamic starts) is the best balance of safety and usability. It preserves the definition-authored vendor as first choice, avoids shadowing model-pinned starts, and keeps non-idempotent risk bounded by retrying only when the server has provably minted no run. Sharing the settlement budget across the retry is a necessary correctness fix to prevent harness timeouts from causing duplicate paid launches.

Files changed (10) +905 / -42

Enhancement (2) +199 / -7
ProfileConfig.csAdd FlowsSettings and safe access for reviewer-vendor preference +14/-0

Add FlowsSettings and safe access for reviewer-vendor preference

• Extends the per-profile config model with a 'flows' section containing 'reviewer_vendor'. Adds 'EffectiveReviewerVendorPreference()' to treat null/blank/whitespace as “no preference” and to trim defensively.

src/Capacitor.Cli.Core/Config/ProfileConfig.cs

McpFlowsServer.csAdd preference-backed vendor retry and shared settlement budget for starts +185/-7

Add preference-backed vendor retry and shared settlement budget for starts

• Introduces a tightly-scoped single retry when a vendor-less, model-less, non-dynamic start is refused with structured 'reviewer_vendor_required'. Loads the saved preference (injected for tests), normalizes it, injects it as an explicit 'vendor', and preserves existing vendor-echo safety (including defensive close on mismatch). Updates settlement retry to accept an optional 'budgetStartedAt' so initial POST and preference retry share one elapsed settlement window, avoiding harness timeout hazards.

src/Capacitor.Cli/Commands/McpFlowsServer.cs

Tests (3) +618 / -10
ConfigCommandTests.csAdd unit tests for flows.reviewer_vendor set/unset and effective preference reading +55/-0

Add unit tests for flows.reviewer_vendor set/unset and effective preference reading

• Adds coverage ensuring 'flows.reviewer_vendor' is stored trimmed/lowercased, blank values are rejected, 'unset' clears the value, and 'EffectiveReviewerVendorPreference()' treats blanks as unset.

test/Capacitor.Cli.Tests.Unit/ConfigCommandTests.cs

FlowsDriverSchemaConformanceTests.csPin skill text to authored-vendor + flows.reviewer_vendor consequences +11/-10

Pin skill text to authored-vendor + flows.reviewer_vendor consequences

• Updates conformance assertions to require both “authored vendor” and 'flows.reviewer_vendor' to be mentioned in the safety-contract explanation, preventing regressions back to “server default” wording.

test/Capacitor.Cli.Tests.Unit/Mcp/FlowsDriverSchemaConformanceTests.cs

ReviewerVendorFallbackTests.csAdd comprehensive tests for preference retry gate, wiring, and budget sharing +552/-0

Add comprehensive tests for preference retry gate, wiring, and budget sharing

• Introduces a new test suite validating the pure retry trigger ('ShouldPreferenceRetry') across success/failure shapes and coded/uncoded bodies. Adds WireMock-backed integration tests proving the dispatch retries exactly once, injects the vendor explicitly, handles stale preferences, preserves auth error messaging, and closes runs on echo mismatch. Adds virtual-clock tests verifying the preference retry shares a single settlement budget and that an exhausted budget prevents any further POST.

test/Capacitor.Cli.Tests.Unit/ReviewerVendorFallbackTests.cs

Documentation (4) +36 / -20
README.mdDocument vendor resolution chain for start_flow and schema-staleness warning +2/-2

Document vendor resolution chain for start_flow and schema-staleness warning

• Updates 'start_flow' documentation to describe the new vendor resolution order: definition-authored vendor → saved 'flows.reviewer_vendor' preference (via one retry) → 'reviewer_vendor_required' error. Adjusts the stale-schema warning to reflect that omission no longer implies a single server default.

README.md

SKILL.mdTeach flows.reviewer_vendor fallback and updated “no vendor parameter” safety contract +14/-8

Teach flows.reviewer_vendor fallback and updated “no vendor parameter” safety contract

• Updates agent guidance to describe what happens when 'vendor' is omitted (authored vendor first, then saved preference, else coded refusal). Refines the “don’t claim a named reviewer ran” section to reflect the new resolution behavior and required recovery steps.

kcap/skills/agent-flows/SKILL.md

SKILL.mdUpdate reviewer-vendor selection rules and coded-error guidance +18/-10

Update reviewer-vendor selection rules and coded-error guidance

• Replaces “server default” framing with the authored-vendor → saved-preference → 'reviewer_vendor_required' chain and instructs saving via 'kcap config set flows.reviewer_vendor'. Adds/updates coded error entries (including 'reviewer_vendor_unresolvable') and aligns start tool parameter guidance with the new behavior.

kcap/skills/review-flows/SKILL.md

help-config.txtExpose config unset subcommand and flows.reviewer_vendor key in help text +2/-0

Expose config unset subcommand and flows.reviewer_vendor key in help text

• Updates CLI help text to include 'kcap config unset <key>' and documents the new 'flows.reviewer_vendor' config key and intent.

src/Capacitor.Cli.Core/Resources/help-config.txt

Other (1) +52 / -5
ConfigCommand.csImplement flows.reviewer_vendor set/unset with validation and warning +52/-5

Implement flows.reviewer_vendor set/unset with validation and warning

• Adds 'unset' subcommand (currently supporting 'flows.reviewer_vendor') and introduces 'ApplyUnset' as a pure function for testability. Adds normalization and non-blank enforcement for 'flows.reviewer_vendor', plus a warning when the vendor token isn’t recognized locally (server remains authoritative).

src/Capacitor.Cli/Commands/ConfigCommand.cs

@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: 5eb50878e4

ℹ️ 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".

Comment on lines +702 to +703
static async Task<string?> LoadReviewerVendorPreferenceAsync() =>
(await AppConfig.GetActiveProfileAsync())?.EffectiveReviewerVendorPreference();

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 Reload the preference instead of using the startup snapshot

In a long-lived kcap mcp flows process, ResolveServerUrl has already populated AppConfig.ResolvedProfile, so GetActiveProfileAsync() returns that cached Profile without rereading config.json. If the user follows the new guidance and sets, changes, or unsets flows.reviewer_vendor while the harness session remains open, subsequent vendor-less starts continue using the startup value (or keep reporting no preference) until the MCP server is restarted. Resolve the selected profile name once, but reload that profile's current settings when the fallback is triggered.

Useful? React with 👍 / 👎.

@qodo-code-review

qodo-code-review Bot commented Aug 2, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. AI-1677 in XML comment ✓ Resolved 📘 Rule violation ⚙ Maintainability
Description
A new XML doc comment references Linear issue AI-1677, which is prohibited in source comments.
This reduces portability of the codebase and violates the checklist requirement to avoid Linear
identifiers in comments.
Code

src/Capacitor.Cli.Core/Config/ProfileConfig.cs[R102-104]

+    /// <summary>AI-1677: the saved reviewer-vendor preference, with null/blank/whitespace
+    /// defensively read as "no preference" — a blank treated as set would consume the single
+    /// preference retry with an effectively vendor-less request and re-fail identically.</summary>
Evidence
PR Compliance ID 3 forbids Linear issue identifiers in code comments. The comment on
EffectiveReviewerVendorPreference() begins with AI-1677, which is a Linear ID.

CLAUDE.md: Do Not Reference Linear Issue Numbers in Code Comments
src/Capacitor.Cli.Core/Config/ProfileConfig.cs[102-104]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
A new XML doc comment includes a Linear issue identifier (`AI-1677`), which violates the rule forbidding Linear IDs in code comments.

## Issue Context
Comments should not reference internal Linear ticket numbers; if an issue reference is necessary, use a GitHub issue number/reference instead.

## Fix Focus Areas
- src/Capacitor.Cli.Core/Config/ProfileConfig.cs[102-104]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. Unset logs as crash 🐞 Bug ☼ Reliability
Description
kcap config unset throws on unsupported keys and the exception bubbles to the top-level crash
handler, producing crash.log entries for normal user mistakes (e.g., unset server_url). This
misclassifies user input errors as crashes and pollutes crash telemetry.
Code

src/Capacitor.Cli/Commands/ConfigCommand.cs[R125-126]

+            "flows.reviewer_vendor" => profile with { Flows = (profile.Flows ?? new FlowsSettings()) with { ReviewerVendor = null } },
+            _ => throw new ArgumentException($"Unknown or non-unsettable config key: {key}")
Evidence
ApplyUnset throws on any key other than flows.reviewer_vendor, and Unset does not catch it.
The top-level command dispatcher catches all exceptions and routes them to CrashReporter.Record,
so unsupported unset keys are recorded as crashes rather than clean user errors.

src/Capacitor.Cli/Commands/ConfigCommand.cs[72-86]
src/Capacitor.Cli/Commands/ConfigCommand.cs[123-127]
src/Capacitor.Cli/Program.cs[749-753]
src/Capacitor.Cli/CrashReporter.cs[54-76]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`kcap config unset <key>` currently throws `ArgumentException` for unknown/non-unsettable keys, which escapes `ConfigCommand` and is handled by the CLI-wide crash handler. This causes normal user errors to be logged as crashes (and written to crash.log), which is misleading and noisy.

### Issue Context
- `ConfigCommand.HandleAsync()` dispatches directly to `Unset()`.
- `Unset()` calls `ApplyUnset()`, whose default arm throws.
- `Program` has a catch-all that calls `CrashReporter.Record()`, so these user errors become crash records.

### Fix Focus Areas
- src/Capacitor.Cli/Commands/ConfigCommand.cs[15-25]
- src/Capacitor.Cli/Commands/ConfigCommand.cs[72-86]
- src/Capacitor.Cli/Commands/ConfigCommand.cs[123-127]

### Implementation notes
- Catch `ArgumentException` inside `Unset()` (or in `HandleAsync()` around the subcommand dispatch), print a normal user-facing error (and optionally `UnsetUsage()`), and return exit code 1.
- Keep `ApplyUnset()` throwing (useful as a pure function + tests), but prevent exceptions from reaching the global crash reporter.
- Add/adjust a unit test that exercises `Unset()`/`HandleAsync()` for an unsupported key and asserts it returns 1 and does not throw.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

3. Duplicate vendor token lists ✓ Resolved 🐞 Bug ⚙ Maintainability
Description
Reviewer-vendor tokens are duplicated (array in ConfigCommand vs string in McpFlowsServer), so
future vendor additions/renames can silently desync warnings vs user guidance. This creates
avoidable maintenance risk and inconsistent UX.
Code

src/Capacitor.Cli/Commands/ConfigCommand.cs[R62-65]

+            string[] knownVendors = ["agy", "claude", "codex", "copilot", "cursor", "gemini", "kiro", "opencode", "pi"];
+            var normalized = value.Trim().ToLowerInvariant();
+            if (!knownVendors.Contains(normalized))
+                await Console.Error.WriteLineAsync(
Evidence
The PR introduces two independent sources-of-truth for the same reviewer vendor tokens: one used to
warn on config set, and another used to format guidance for missing/stale preferences. This
duplication can drift and produce inconsistent CLI messaging.

src/Capacitor.Cli/Commands/ConfigCommand.cs[61-67]
src/Capacitor.Cli/Commands/McpFlowsServer.cs[667-678]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The canonical reviewer-vendor token list is defined in two separate places:
- `ConfigCommand.Set()` uses a `knownVendors` array for a warning.
- `McpFlowsServer` uses `ReviewerVendorTokens` for user guidance.

Even though both are aligned today, they can drift over time, leading to inconsistent messaging (warning says “unknown vendor” while guidance still lists it, or vice versa).

### Issue Context
The server is authoritative, but the CLI’s local guidance/warnings should remain internally consistent.

### Fix Focus Areas
- src/Capacitor.Cli/Commands/ConfigCommand.cs[61-67]
- src/Capacitor.Cli/Commands/McpFlowsServer.cs[667-678]

### Implementation notes
- Extract a single shared constant, e.g. `internal static readonly string[] ReviewerVendorTokens = [...]` in a shared location (could be `McpFlowsServer` as `internal`, or a small new helper type under `Capacitor.Cli.Core` or `Capacitor.Cli.Commands`).
- Generate the display string (`"claude, codex, ..."`) from that shared list.
- Use the same shared list for `knownVendors` warnings in `ConfigCommand.Set()`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

To customize comments, go to the Qodo configuration screen, or learn more in the docs.

Qodo Logo

Comment thread src/Capacitor.Cli.Core/Config/ProfileConfig.cs Outdated
Comment on lines +125 to +126
"flows.reviewer_vendor" => profile with { Flows = (profile.Flows ?? new FlowsSettings()) with { ReviewerVendor = null } },
_ => throw new ArgumentException($"Unknown or non-unsettable config key: {key}")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Remediation recommended

2. Unset logs as crash 🐞 Bug ☼ Reliability

kcap config unset throws on unsupported keys and the exception bubbles to the top-level crash
handler, producing crash.log entries for normal user mistakes (e.g., unset server_url). This
misclassifies user input errors as crashes and pollutes crash telemetry.
Agent Prompt
### Issue description
`kcap config unset <key>` currently throws `ArgumentException` for unknown/non-unsettable keys, which escapes `ConfigCommand` and is handled by the CLI-wide crash handler. This causes normal user errors to be logged as crashes (and written to crash.log), which is misleading and noisy.

### Issue Context
- `ConfigCommand.HandleAsync()` dispatches directly to `Unset()`.
- `Unset()` calls `ApplyUnset()`, whose default arm throws.
- `Program` has a catch-all that calls `CrashReporter.Record()`, so these user errors become crash records.

### Fix Focus Areas
- src/Capacitor.Cli/Commands/ConfigCommand.cs[15-25]
- src/Capacitor.Cli/Commands/ConfigCommand.cs[72-86]
- src/Capacitor.Cli/Commands/ConfigCommand.cs[123-127]

### Implementation notes
- Catch `ArgumentException` inside `Unset()` (or in `HandleAsync()` around the subcommand dispatch), print a normal user-facing error (and optionally `UnsetUsage()`), and return exit code 1.
- Keep `ApplyUnset()` throwing (useful as a pure function + tests), but prevent exceptions from reaching the global crash reporter.
- Add/adjust a unit test that exercises `Unset()`/`HandleAsync()` for an unsupported key and asserts it returns 1 and does not throw.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread src/Capacitor.Cli/Commands/ConfigCommand.cs Outdated
alexeyzimarev and others added 2 commits August 2, 2026 20:19
…file

The lookup went through the profile deserialized at process start, but
`kcap mcp flows` is long-lived and the `kcap config set` its own guidance
asks for is another process writing that file — so refuse → ask → save →
retry could never close inside a session. It now re-reads from disk on every
consultation, using the profile this process resolved.

Both fallback messages also name that profile. `kcap config set` writes to
the ACTIVE profile while the flows lane reads the repo/URL/env-resolved one;
when they differ a dutiful save lands where nothing reads it, and without the
name the symptom is a preference that silently never works. Changing the
write target is deliberately out of scope here — it affects every key.

Also: one shared vendor-token list behind the flows guidance and the config
warning, the config echo prints the normalized token it stored, and
help-config.txt regains three keys it had drifted away from.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The public-repo lint forbids Linear issue IDs in C# source; the rationale
stays, the token goes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@alexeyzimarev
alexeyzimarev merged commit 29437d4 into main Aug 2, 2026
6 checks passed
@alexeyzimarev
alexeyzimarev deleted the ai-1677-reviewer-vendor-preference branch August 2, 2026 20:09
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.

1 participant