Commit Graph

3 Commits

Author SHA1 Message Date
Dragan Spiridonov 6d58837f4f fix(proxy): make the subscription plane reachable again after cloud routing (#2928)
* fix(proxy): disclose what enabling cloud routing actually decides, and let users pin a tier

Closes the terminal half of cognitum-one/meta-proxy#43 M5b, and adds the
`routing_mode` control ruflo never had.

meta-proxy ADR-321 rev-2 (shipped v0.6.0, #43 M2) applies tier selection to
ALL Cloud traffic. Before it, a deliberately configured Cloud plane forwarded
the client's own model name -- and since Claude Code names a frontier model by
default, every request was served at the top tier with no ceiling and no proxy
daily cap. Difficulty-routing all Cloud traffic is the fix for that defect, not
a regression, and it deliberately does not touch Passthrough or Local: those
are the user's own subscription and their own backend.

But ruflo never told anyone. `ruflo proxy config --cloud` said only that
prompts go to api.cognitum.one "and forwarded to the selected provider" -- so a
user could enable cloud routing still believing their model choice held. #43
M5a fixed the Developer Console selector; M5b ("equivalent disclosure to any
terminal flow that explicitly activates Cloud") is this command, and it was
still open.

The disclosure now answers the three things activating Cloud actually decides,
each of which has a different answer than the plane being left:

  - who processes the prompt (Cognitum, server-side)
  - who pays (the Cognitum account -- NOT the user's own Claude subscription,
    which is what Passthrough uses and is unaffected)
  - which model runs (the plane picks a tier per prompt rather than honoring
    the requested model)

`--routing-mode <auto|low|mid|high>` is rev-2's escape hatch. The console got a
control for it in meta-proxy#52; ruflo had none, so a ruflo user was stuck on
auto with no way to disagree -- and the scorer reads prompt SHAPE, not task
difficulty, so a short-but-hard prompt can under-escalate.

Setting a tier must never activate Cloud (ADR-321 Revision 3 keeps the plane
choice and this Cloud-only setting as separate controls), so `--routing-mode`
alone writes only `routing_mode`, asks for no consent it does not need, and
says the setting is inert until Cloud is on. `--routing-mode` with
`--local-only` is refused rather than silently resolved, and an unconfirmed
`--cloud` still writes nothing at all.

Wire values confirmed against meta-proxy's `RoutingMode` enum (`src/config.rs`,
same `#[serde(rename_all = "snake_case")]` treatment as `DataPlane`), and
`#[serde(default)]` there means an existing config that omits the field keeps
working and reads as auto. An unrecognized value already in the file reports as
auto rather than being echoed back, matching the proxy's own
degrade-to-safe-default behavior.

ADR-304 records both, and drops its inline copy of the disclosure text -- that
copy had already fallen behind the shipped string, and a reader could not tell
which was real. #43 M3 (a Cloud tier ceiling and daily cap) stays open upstream
as a product decision, so the disclosure makes no claim about caps either way.

Test: 9 proxy test files, 68 tests, all passing (was 56).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(proxy): make the subscription plane reachable again after cloud routing

`--local-only` was the only exit from the cloud plane, and it writes
`default_data_plane = "local"` -- the user's own Ollama/vLLM/SGLang backend.
`passthrough`, which is meta-proxy's own default AND the plane that uses the
user's own Claude subscription, was unreachable from this command by design
("passthrough is never written", ADR-304's 07-16 addendum).

So the undo we advertised was wrong. A user on passthrough who followed our own
disclosure -- "Disable anytime: ruflo proxy config --local-only" -- landed on a
THIRD state they never chose, pointed at a local backend that may not be
installed. Two consequences, neither visible:

  1. Their Claude subscription stops being used at all. That is the same harm
     cognitum-one/meta-proxy#51 closed on the login path ("silently switches a
     user away from Passthrough -- their own Claude subscription"), reached
     through a different door.

  2. Automatic quota failover silently stops applying. meta-proxy gates it on
     the plane (`src/routing.rs`: `automatic_eligible =
     cfg.default_data_plane == DataPlane::Passthrough`) because Passthrough is
     the only plane that sees Anthropic's own rate-limit headers (ADR-320). A
     user parked on `local` is opted out of ADR-321 entirely and is never told.

The no-flag report papered over the difference, printing one line -- "Cloud
routing is OFF -- requests never leave this machine (or use your own Claude
subscription on Passthrough)" -- for two planes that do not behave alike.

`--local-only` keeps its meaning exactly; the flag name and ADR-304 both
promise a local backend, and silently retargeting it would just be a second
surprise. Instead:

  - `--passthrough` is added, writing `default_data_plane = "passthrough"` and
    revoking cloud-routing consent the same way `--local-only` does.
  - The disclosure names both exits instead of presenting one as THE undo.
  - `--cloud` reads the plane it is leaving before overwriting it and prints
    the command to restore it. That read is the only moment ruflo knows where
    the user was, and it beats persisting a "previous plane" that could go
    stale against a hand-edited TOML.
  - `--local-only` now says the Claude subscription is not used on that plane,
    and how to choose it instead.
  - The no-flag report describes each plane distinctly and calls out the
    ADR-321 failover consequence while on `local`.
  - Plane flags are mutually exclusive -- more than one is refused rather than
    resolved by precedence, since any precedence would discard something the
    user explicitly asked for.

No default changes: a user who never runs this command is on passthrough,
exactly as before. ADR-304 records the decision and supersedes its own
"passthrough is never written" claim.

Test: 9 proxy test files, 80 tests, all passing (was 68).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(proxy): correct disclosure's who-pays claim (post-merge reapply)

Same fix as on #2927 — the disclosure asserted Passthrough "is the plane
in effect until you turn this on", which is false whenever the user is
already on --local-only. Reapplying after merging main (which already
had this fix on the pre-passthrough disclosure text) since this branch's
own commit still carried the original wording.

Co-Authored-By: RuFlo <ruv@ruv.net>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: ruv <ruv@ruv.net>
2026-08-11 13:03:23 -04:00
Dragan Spiridonov e1f7e4a232 fix(proxy): disclose what enabling cloud routing decides, and let users pin a tier (#2927)
* fix(proxy): disclose what enabling cloud routing actually decides, and let users pin a tier

Closes the terminal half of cognitum-one/meta-proxy#43 M5b, and adds the
`routing_mode` control ruflo never had.

meta-proxy ADR-321 rev-2 (shipped v0.6.0, #43 M2) applies tier selection to
ALL Cloud traffic. Before it, a deliberately configured Cloud plane forwarded
the client's own model name -- and since Claude Code names a frontier model by
default, every request was served at the top tier with no ceiling and no proxy
daily cap. Difficulty-routing all Cloud traffic is the fix for that defect, not
a regression, and it deliberately does not touch Passthrough or Local: those
are the user's own subscription and their own backend.

But ruflo never told anyone. `ruflo proxy config --cloud` said only that
prompts go to api.cognitum.one "and forwarded to the selected provider" -- so a
user could enable cloud routing still believing their model choice held. #43
M5a fixed the Developer Console selector; M5b ("equivalent disclosure to any
terminal flow that explicitly activates Cloud") is this command, and it was
still open.

The disclosure now answers the three things activating Cloud actually decides,
each of which has a different answer than the plane being left:

  - who processes the prompt (Cognitum, server-side)
  - who pays (the Cognitum account -- NOT the user's own Claude subscription,
    which is what Passthrough uses and is unaffected)
  - which model runs (the plane picks a tier per prompt rather than honoring
    the requested model)

`--routing-mode <auto|low|mid|high>` is rev-2's escape hatch. The console got a
control for it in meta-proxy#52; ruflo had none, so a ruflo user was stuck on
auto with no way to disagree -- and the scorer reads prompt SHAPE, not task
difficulty, so a short-but-hard prompt can under-escalate.

Setting a tier must never activate Cloud (ADR-321 Revision 3 keeps the plane
choice and this Cloud-only setting as separate controls), so `--routing-mode`
alone writes only `routing_mode`, asks for no consent it does not need, and
says the setting is inert until Cloud is on. `--routing-mode` with
`--local-only` is refused rather than silently resolved, and an unconfirmed
`--cloud` still writes nothing at all.

Wire values confirmed against meta-proxy's `RoutingMode` enum (`src/config.rs`,
same `#[serde(rename_all = "snake_case")]` treatment as `DataPlane`), and
`#[serde(default)]` there means an existing config that omits the field keeps
working and reads as auto. An unrecognized value already in the file reports as
auto rather than being echoed back, matching the proxy's own
degrade-to-safe-default behavior.

ADR-304 records both, and drops its inline copy of the disclosure text -- that
copy had already fallen behind the shipped string, and a reader could not tell
which was real. #43 M3 (a Cloud tier ceiling and daily cap) stays open upstream
as a product decision, so the disclosure makes no claim about caps either way.

Test: 9 proxy test files, 68 tests, all passing (was 56).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(proxy): correct disclosure's who-pays claim for --local-only users

The disclosure text asserted "[Passthrough] is the plane in effect until
you turn this on" — false whenever default_data_plane is already "local"
(i.e. exactly a --local-only user considering re-enabling cloud routing).
Reword to state Passthrough is the proxy's default and what the user's
Claude subscription is used by, without claiming it's necessarily the
plane currently in effect.

Co-Authored-By: RuFlo <ruv@ruv.net>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: ruv <ruv@ruv.net>
2026-08-11 12:48:26 -04:00
ruvnet f52ab6e906 feat(proxy): integrate Cognitum auth and meta-proxy lifecycle 2026-07-16 15:56:56 -04:00