Skip to content

Commit ffbd484

Browse files
LivXueclaude
andcommitted
fix(agent): keep the credential verdict a preserved snapshot just measured
`_test_record` keeps a previous record's capabilities when a verify fails, so one flaky Test does not cost a row its menu and statefulness. It rebuilt that record from `previous` and copied only the verdict fields, and `needs_auth` was not among them -- it arrived on main with #554, after this helper was written. An agent that worked and has since been logged out therefore stayed `needs_auth: false` through the very Test that detected the refusal, and the page went on offering it a Connect the agent would decline. `needs_auth` travels with the verdict, not with the capabilities: a menu measured earlier is still the best account of what the agent can do, but whether it will open a session without a credential is a fact about this handshake alone. Co-authored-by: Claude (claude-opus-5[1m]) <noreply@anthropic.com>
1 parent 4113b72 commit ffbd484

2 files changed

Lines changed: 47 additions & 0 deletions

File tree

‎raven/agent/subagent/probe.py‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -613,6 +613,13 @@ def _test_record(snapshot: Any, previous: Any) -> Any:
613613
stale=False,
614614
status=snapshot.status,
615615
detail=snapshot.detail,
616+
# Travels with the verdict, not with the capabilities, and is the one
617+
# flag here that must: a menu measured earlier is still the best account
618+
# of what the agent can do, but whether it will open a session without a
619+
# credential is a fact about this handshake alone. Kept from `previous`,
620+
# an agent that worked and has since been logged out goes on reading as
621+
# connectable after the very Test that detected the refusal.
622+
needs_auth=snapshot.needs_auth,
616623
measured_at_ms=snapshot.measured_at_ms,
617624
elapsed_ms=snapshot.elapsed_ms,
618625
)

‎tests/test_subagent_acp.py‎

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,46 @@ async def fake_verify(_cfg: Any) -> CapabilitySnapshot:
464464
assert (await probe_one(cfg, source="config")).status == "missing", "the verdict itself is on the row"
465465

466466

467+
async def test_a_refusal_after_a_success_records_the_new_authentication_verdict(tmp_path: Path, monkeypatch) -> None:
468+
"""Keeping the previous capabilities must not keep its credential verdict.
469+
470+
``needs_auth`` is a fact about this measurement, not a capability the older
471+
record still vouches for: an agent that worked and has since been logged
472+
out answers the handshake by refusing, and a record that kept the old
473+
``False`` leaves the page offering a Connect the agent will decline. The
474+
menu and the statefulness are the previous record's; the verdict, its
475+
detail and this flag are the new one's."""
476+
path = tmp_path / "caps.json"
477+
monkeypatch.setattr("raven.acp_client.capabilities.default_snapshot_path", lambda: path)
478+
cfg = stub_config("a")
479+
good = await verify_agent(cfg)
480+
SnapshotStore(path=path).record(good)
481+
assert good.needs_auth is False and good.available_models
482+
483+
refused = replace(
484+
good,
485+
status="attention",
486+
detail="sign in to the agent first",
487+
needs_auth=True,
488+
can_resume=False,
489+
available_models=(),
490+
model_choices=(),
491+
measured_at_ms=good.measured_at_ms + 1,
492+
)
493+
494+
async def fake_verify(_cfg: Any) -> CapabilitySnapshot:
495+
return refused
496+
497+
monkeypatch.setattr("raven.acp_client.capabilities.verify_agent", fake_verify)
498+
await run_test(cfg, source="config")
499+
500+
kept = SnapshotStore(path=path).load([cfg])["a"]
501+
assert kept.needs_auth is True, "the refusal the handshake just measured"
502+
assert kept.can_resume is True and kept.available_models == good.available_models, (
503+
"and the capabilities the older record still vouches for"
504+
)
505+
506+
467507
async def test_a_failed_test_after_a_config_edit_keeps_the_capabilities_the_roster_was_trusting(
468508
tmp_path: Path, monkeypatch
469509
) -> None:

0 commit comments

Comments
 (0)