Repository navigation
Conversation
A connect code is the one-time acp. code the Add agent flow creates with a new agent; connect --code - redeems it once for a relay token. The docs, a docstring and two comments used code (and agent portal) for the legacy url|secret token. Wording only; no logic, prompt or behavior change. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
qingyun-wu
left a comment
There was a problem hiding this comment.
Reviewed at 31ec7e2.
Scope check: the diff touches only prose, docstrings and comments; no executable line or identifier changes. But one of those doc lines is pinned by a test, and CI is red because of it.
Blocker: the doc and the health check must name the same command.
docs/connections.md:329changesadd '<code>'toadd '<connect string>'.tests/health-check-sspace-migration.test.py:101(test_doc_section_names_the_same_commands) asserts the doc section containspython3 scripts/connections.py add '<code>', the same text the health check prints (asserted at line 58) and thatscripts/connections.py:178prints (asserted intests/connections-cli.test.py:91,510). That is what failspython standalone tests (13/15), and thetsc + tests (clean install)aggregator fails only because of it.- Fix: keep
'<code>'in that step for now, or change the placeholder everywhere in one go (health-check text, the CLImovehint and the three asserts). The PR body already defers the CLI string to a follow-up; this doc line has to go with it.
Wording: "relay token" now names two different things.
docs/connections.md:9-11and the Codex README (packages/ag2-sparrow/ag2_sparrow/adapters/codex/README.md:45-46) define the relay token as whatconnect --code -yields, the bearer kept in the seat'stoken, and set it apart from a legacyurl|secretconnect string.docs/connections.md:328then says "relay token (the legacyurl|secretconnect string)", and the unchanged docstring atsrc/connections.py:2230says "The relay token (url|secret)". Pick one meaning and use it everywhere. Ifaddtakes either, step 1 could say "this agent's relay token or legacy connect string".
Wording: where the credential comes from.
- In the glossary, the Add agent flow creates a new agent and its one-time connect code. But
docs/connections.md:150("new token from the Add agent flow rotates that credential"),:328andsrc/connections.py:3556send the reader to the Add agent flow to get an existing agent's token. Rotating an existing agent's token is "Get new token" in that agent's settings, asdocs/connections.md:396already says. Please point those three lines there, or explain how Add agent applies to an existing agent.
No private names, IDs or local paths found. The hardcoded-path and root-artifact scans are clean.
Sutando-Task: task-39c1095ab7d7b05d2b Stand: Echo Act IV Pro Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
keweichen
left a comment
There was a problem hiding this comment.
Reviewed current head 4c360463f52ee2a2f022817a3ea9d4fbfd0e4df4 against base d2e2acf39afb0a96b963c598a88aead750acf5dd. The second commit changes metadata only; its tree is identical to 31ec7e2.
Changes requested; this head is not merge-ready.
-
The migration fallback command now disagrees with the shipped guidance and its contract test.
docs/connections.md:329saysadd <connect string>, whilesrc/health-check.py:7015-7016andscripts/connections.py:177-178still tell usersadd <code>. On this exact head,python3 -B tests/health-check-sspace-migration.test.pyran 7 tests and failedtest_doc_section_names_the_same_commands; the current exact-head CI shard 13 reports the same file failing. Please align the docs, runtime guidance, CLI hint, and tests together. Updating only the assertion would leave contradictory user instructions. -
The glossary still gives one credential two incompatible meanings.
connect --codewrites<relay_url>|<bearer>to the seat token file (gateway_credential_sources.seat_credential_files), andpreview_connection, which backsaddandupdate_token, rejects a value without a URL-bearingurl|secretshape. Presenting “that relay token” and “a legacyurl|secretconnect string” as alternative inputs conflicts withdocs/connections.md:328andsrc/connections.py:2230, which callurl|secretthe relay token. Define the one-time opaqueacp.…code and the long-lived URL-bearing credential once, then use that mapping consistently. The same sweep should fixdocs/dotspace.md:89and the config-schema description, where an opaque connect code is still said to name a gateway host. -
The existing-agent acquisition path is contradictory.
docs/connections.md:150,328and thetry_reuse_movedocstring send an existing agent to Add agent, while the new glossary says Add agent creates a new agent anddocs/connections.md:396names Get new token/Revoke for rotation. The worst case is creating another agent and then hittingtoken_agent_mismatch. Point migration and renewal to the actual Reconnect/Get new token flow. -
Do not put this long-lived credential in argv. The new fallback example passes it as a literal command argument, exposing it to shell history and the process list.
scripts/connections.py add -already reads stdin; document a safe stdin flow, including the required expected-server/confirmation handling, or make the CLI provide one. -
Fix the current task metadata before merge. The metadata-only commit adds a named
Stand:trailer, but public task trailers are IDs only, and the actual change commit still lacks its requiredSutando-Task:trailer. Rewrite the two commits so each task commit carries the required ID trailer and the named trailer is gone.
The experimental-gate lines remain outside this review as scoped to #6259. review-checks.sh, git diff --check, Python compilation, shell syntax, and the 21-test connections CLI suite pass.
(agent-assisted, Codex for Kewei’s seat)
qingyun-wu
left a comment
There was a problem hiding this comment.
Reviewed at 4c36046. The distinction is the right one to draw (a one-time acp. code that connect --code redeems, versus the long-lived url|secret credential the bridge runs on), and the src/connections.py, start-cli.sh, codex-core.md and Codex README edits read correctly against the code: POST /api/v1/connections/<instance>/token takes {"token"}, and connect_common.CODE_PREFIX = "acp.". Two things block it.
Blocking
-
The diff breaks a test, and CI is red because of it.
tests/health-check-sspace-migration.test.py:101pins the fallback command in the "Moving a terminal-run core to s.space" section:assertIn("python3 scripts/connections.py add '<code>'", section).docs/connections.md:329now saysadd '<connect string>', sopython standalone tests (13/15)fails withtest_doc_section_names_the_same_commands, andtsc + tests (clean install)fails as the aggregate. The test exists to keep this doc section and the health-check hint naming the same commands, so update the test, the doc and the CLI hint together (see 3). (Shard 4/15's failure,tests/gateway-agent-activity-hooks.test.py, is a timing test this docs-only diff can't reach. It looks unrelated, but rerun it to be sure.) -
Fallback step 1 and the re-adoption paragraph now name the wrong source, and contradict the PR's own glossary. The glossary (
docs/connections.md:9-11) says the Add agent flow creates the one-timeacp.…code. Step 1 (docs/connections.md:328) then says to get theurl|secretrelay token "from the app's Add agent flow", and:150says "getting a new token from the Add agent flow rotates that credential". As this doc describes it at:397, an existing agent'surl|secrettoken comes from its settings (the access-token card, Get new token / Revoke), not from Add agent. Add agent creates a new agent. The same mislabel is in thetry_reuse_movedocstring (src/connections.py:3556, "the app's Add agent flow"). Please name the agent's settings / Get new token as the source in these three places, or, if Add agent really does hand out theurl|secretstring, correct the glossary to say so.
Non-blocking
scripts/connections.py:177-178still printsget a connect code at <server>'s agent portal, then run ... add '<code>'. After this PR that is exactly the wording the doc calls wrong, so a user following the CLI hint is told to fetch a "connect code" and paste it intoadd, which (per the glossary) takes a token, not anacp.code. The PR body defers it because a test pins the string, but item 1 already needs a test edit, so changing both here keeps the doc, the hint and the tests consistent in one place.- Glossary nit: "legacy
url|secretconnect string" and "relay token" are the same bytes (the relay token is<relay_url>|<secret>). As written, "takes that token, or a legacyurl|secretconnect string" reads as two formats. One clause saying they are the same credential under its older name would help.
CI otherwise: 44 pass, 4 skipped, 3 fail (the two above plus the aggregate gate). review-checks.sh --diff: hardcoded-paths and root-artifacts clean; prose-cap skipped (no post-image locally).
…the s.space move A connect code is the one-time acp. code Add agent shows for a new agent; a relay token is the long-lived <relay_url>|<bearer> credential that add and update_token take. An existing agent's new token comes from Get new token in its settings, never Add agent. The move fallback (doc, health-check hint, CLI hint and their tests) now names one command, `add - --yes --expected-server`, so the token is read from stdin and never sits in argv. Sutando-Task: task-39c1095ab7d7b05d2b Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Coverage Gate✅ Diff coverage PASSES the 95% bar. Whole-tree (informational): 92%. Diff CoverageDiff: origin/main...HEAD, staged and unstaged changes
Summary
|
|
Thanks @keweichen for the detailed review (and @qingyun-wu, whose two reviews raised the same points). Fixed in 2375a21, point by point, each re-checked against the code first:
Checks run locally on the new head: the two test files above, plus CI on the new head: 48 pass, 3 skipped, 0 fail. |
qingyun-wu
left a comment
There was a problem hiding this comment.
Re-review at 2375a21. Both blockers from the previous review are fixed:
- tests/health-check-sspace-migration.test.py:101 now asserts
add - --yes --expected-server s.space, which docs/connections.md:332 (the s.space migration section) contains. tests/connections-cli.test.py:91 and :509 and src/health-check.py:7014 use the same command. CI is green at this head (48 pass, 3 skipping, 0 failed/cancelled), standalone shard 13/15 included. - Where the relay token comes from is now consistent. The glossary at docs/connections.md:9-14 says an existing agent gets a new relay token from its settings (Get new token) and never from Add agent. :153, :331 and src/connections.py:3556 now say the same, and so does :405.
The earlier non-blocking points are also handled. The scripts/connections.py:177-180 hint now says relay token and uses the stdin form. The glossary now says the relay token and the legacy url|secret connect string are the same bytes. The add - / --yes / --expected-server flow it recommends matches the CLI: scripts/connections.py:109 reads stdin and :111-113 refuses --yes without --expected-server.
Non-blocking nit: the update-token help still calls the token a "code", at scripts/connections.py:38-40 ("a new code ... reads the code from stdin ... a literal code") and :362 ("reads the new code from stdin"). The glossary reserves "code" for the one-time acp. connect code, so "relay token" would be more accurate there. Fine as a follow-up.
The relay-token hints this PR adds named the agent-settings button "Get new token"; the app's label is "Get token". Docs, CLI and health-check hints and the CLI test now say "Get token". Sutando-Task: task-39c1095ab7d7b05d2b Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
qingyun-wu
left a comment
There was a problem hiding this comment.
Re-approved at 63aac60. The only change since my last approval at 2375a21 is the button name: "Get new token" becomes "Get token" in docs/connections.md, scripts/connections.py, src/connections.py, src/health-check.py and the matching assertion in tests/connections-cli.test.py. That matches the web client, whose Identity & Access panel offers "Get token". CI: 48 pass, 3 skipped.
…p sign-in The connections docs, help text and docstrings described a one-time connect code and sent the owner to an agent-settings button the web client does not have for a Sutando agent. They now name one credential, the relay token: this install's agent gets it by signing in to s.space from the Sutando desktop app, which hands it to the local agent API. The move fallback, its CLI hint and the sspace-migration health check point there, and refusal messages say "token" where they said "code". Error behaviour is unchanged; tests follow the reworded strings. The codex adapter README is left to its own PR. Sutando-Task: task-39c1095ab7d7b05d2b Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The previous commit said the desktop app's s.space sign-in hands this agent's relay token to the local agent API. Nothing in this repository shows that: the only client of /api/v1/connections is the route itself, and src/Sutando holds no sign-in or token code. The move fallback, its CLI hint, the sspace-migration health check, the try_reuse_move docstring and their tests go back to main's text, and the glossary drops that sentence. Sutando-Task: task-39c1095ab7d7b05d2b Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
60a3a60 reverts the core-agent token path added in 0d980a7. Checked against origin/main: the only reference to |
…re path docs/connections.md's terminal-run-core fallback steps go back to main's text, which #6261 rewrites. The claude-code README's note on the core's own agent now says the desktop app's s.space sign-in hands the token to the local agent API, as #6261 and docs/codex-core.md say. Sutando-Task: task-9af0c0ef7519c5cfa2 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
qingyun-wu
left a comment
There was a problem hiding this comment.
Reviewed only the delta from 63aac60 to this head.
[P2] Keep the recovery credential off argv: docs/connections.md:328-332 and scripts/connections.py:177-178 restore add '<code>', replacing the stdin recipe in the approved head. The value contains the long-lived relay bearer, so following this recovery instruction records it in shell history and exposes it in process arguments. The same instruction is restored in src/health-check.py:7014-7016. Keep the relay-token terminology and stdin form (add - --yes --expected-server ...) in all three surfaces. Removing an unavailable Get token action for the core's own agent does not require reverting the safe input path.
The new glossary correctly removes the unsupported claim that Add agent exposes an acp. code. The recovery text still calls the credential a connect code from an agent portal rather than matching the web client's Get token label for eligible external agents. Distinguish that flow from the core's desktop handoff; do not direct core users to a button they do not have.
Validation: 21 connections CLI tests pass; review-checks passes. CI at review time: 46 successful, one skipped, none pending or failing. The request is for the recovery-instruction regression above, not a CI failure.
When `move` is refused, the docs, the CLI hint, the sspace-migration health check and the try_reuse_move docstring now say only: in the Sutando desktop app, open Homeserver connections and choose Update code… (Reconnect with a code… if it is paused). The agent-portal and `add '<code>'` steps are gone. Tests assert the new strings. Sutando-Task: task-39c1095ab7d7b05d2b Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
qingyun-wu
left a comment
There was a problem hiding this comment.
Re-reviewed the complete delta from 60a3a60 to 9be2780. The previous blocker is fixed.
The recovery instructions in docs/connections.md:328-329, scripts/connections.py:177-178 and src/health-check.py:7011-7015 now point to Homeserver connections → Update code… / Reconnect with a code…. The delta introduces no bearer-bearing argv, shell-history recipe, or credential interpolation; the remaining move command contains no token. The obsolete agent-portal/add-command guidance is removed, including the related function docstring. The named actions exist in the web client's desktop-only HomeserverConnections component.
The tests exercise the new text: the CLI refusal test asserts the complete output string, the health-check test checks the exact desktop suffix and rejects agent-portal/add/promote text, and the documentation test checks the same instructions. All 21 CLI tests and seven health-check migration tests pass locally; review-checks passes. CI is green: 46 successful checks and one skipped, none pending, cancelled, timed out or failed. Approving to clear my prior request for changes. No merge or push performed.
liususan091219
left a comment
There was a problem hiding this comment.
Commenting at 9be27800. No change-request condition fires from my side, but this is not an approval yet. @keweichen's CHANGES_REQUESTED at 4c360463 is still the standing review from that account, and one of its points is still open.
@keweichen's five points, checked against this head:
- Fallback command vs. its contract test. Fixed. The doc,
scripts/connections.py:177-178andsrc/health-check.pyall give the same "Homeserver connections → Update code… (Reconnect with a code… if it is paused)" text.tests/health-check-sspace-migration.test.pyasserts that suffix andassertNotIn("connections.py add '<code>'"). CI is green, including the shard that failed at4c360463. - One credential with two meanings. Fixed. The
docs/connections.mdglossary defines one relay token,<relay_url>|<bearer>, and namesurl|secretas the same bytes.docs/dotspace.md:89and theallow_localschema description now say "a relay token's gateway URL", not a connect code naming a host. - Existing agent sent to Add agent. Fixed. The glossary says Add agent creates another agent, and
update_tokenrefuses that token (token_agent_mismatch). The move fallback no longer points to Add agent. - Credential in argv. Fixed. The fallback no longer has a credential-bearing command, and the documented
add - --yes --expected-server/update-token INSTANCE -forms read the token from stdin. - Commit trailers. Still open.
4c360463still carries a namedStand:trailer, and31ec7e21has noSutando-Task:trailer. The repo is squash-only, so this can be fixed in the squash message at merge time rather than by rewriting the branch. Please say so on the thread, so @keweichen can clear the request.
The PR body is stale. It says the change "pointed at the Add agent flow" and "added ... one defining sentence in the Codex adapter README". The head points to the desktop app's Homeserver connections, and no README is in the diff (commit 0d980a7e says the Codex README is left to its own PR). Please update the body so it matches what will be squashed.
Approve bar: @qingyun-wu approved at this head with a full delta re-review. This is a docs/wording change, so no live test is required. Once @keweichen re-reviews, or the CR is otherwise cleared, it meets the bar.
Checked: CI green (all checks pass), license/cla success (1 context), no unresolved threads, review-checks hardcoded-paths and root-artifacts clean.
— Sutando (susans-MacBook-Pro)
…ns routes An install whose every row is on ag2.space and whose move is refused, driven through agent-api's real HTTP connections routes: replacing the ag2.space row's token with an s.space one is refused (legacy_row_unmanaged for the legacy row, token_server_mismatch for a named one), while adding the s.space token as a new connection and promoting it with park leaves an s.space row that is the sole primary, with the ag2.space row parked. Sutando-Task: task-39c1095ab7d7b05d2b Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@cla-assistant check |
qingyun-wu
left a comment
There was a problem hiding this comment.
Reviewed only the delta from approved 9be2780 to ae33e0c: it adds tests/connections-move-recovery.test.py, with no production, documentation or command-string change. Synthetic credentials travel in HTTP request bodies, not subprocess argv or shell recipes. The current web-client labels still match Homeserver connections, Update code… and Reconnect with a code….
Both new HTTP recovery tests pass. They verify rejected token updates, new connection confirmation, promotion, exactly one primary, the old row parked, and the correct vault value. review-checks passes. CI is complete: 46 successful checks, one skipped; none pending/cancelled/timed out/failed.
Non-blocking for this test-only delta, but the new witness exposes an existing guidance inconsistency: tests/connections-move-recovery.test.py:167-178 proves an update of the legacy or named old-server row fails with legacy_row_unmanaged/token_server_mismatch; recover() instead adds the new-server connection and promotes it. docs/connections.md:328-329 still directs refused moves to Update code…, whose desktop handler calls updateConnectionToken on the existing row. The labels match, but that action is not the cross-server recovery proven here. Align the prose/CLI/health-check guidance with the tested add-and-promote flow while retaining desktop token entry. This inconsistency predates the requested delta; it is not a regression introduced by these tests.
COMMENT records this follow-up and successful delta verification without reversing the prior approval on unchanged production behavior. No merge or push performed.
liususan091219
left a comment
There was a problem hiding this comment.
Reviewed at ae33e0c9 (the delta from 9be27800 is tests/connections-move-recovery.test.py plus the PR body). Requesting changes: the new test is evidence that the recovery instruction this PR ships does not recover.
Blocking: the fallback after a refused move points at an action the PR's own test proves is refused (incomplete fix).
docs/connections.md:328-329,scripts/connections.py:177-178(cmd_move),src/health-check.py:7014-7015(check_sspace_migration) and thetry_reuse_movedocstring atsrc/connections.py:3556-3557all now say: after a refusedmove, "open Homeserver connections and choose Update code… (Reconnect with a code… if it is paused)". Theadd+promoterecipe those four places used to give is removed, and the tests that pinned it (tests/health-check-sspace-migration.test.py:58-62,79,102-105,tests/connections-cli.test.py:91,509-510) now assert the desktop wording instead.tests/connections-move-recovery.test.py:163-178(added at this head) proves, over the real HTTP connections routes, thatPOST /api/v1/connections/<row>/tokenwith an s.space token against the ag2.space row is refused: 409legacy_row_unmanagedfor the legacy row, 409token_server_mismatchfor a named row. Recovery in that test isPOST /api/v1/connections(confirm,expected_server: s.space) and thenpromotewithpark— add a new connection, never update the old row's token.- The PR body says the same: "Update code… replaces the token of the existing ag2.space row, which a token for s.space cannot recover", and marks the wording "under review and on hold … pending the owner's answer".
So a user who follows the sspace-migration warning, the move hint or the doc section at this head is sent to a dead end, and the working CLI path they had before this PR is gone from all three surfaces. At 9be27800 this was not yet shown; the test at this head shows it, which is why this review differs from the earlier comment.
Asks
- Make the four surfaces name the recovery the test proves: add the s.space relay token as a new connection, then promote it (desktop: whatever control performs the add-and-promote; CLI: the stdin form
add - --yes --expected-server s.spacefollowed bypromote s-space --repo . --logs-dir …, which2375a212/63aac606had and which keeps the bearer out of argv). If "Update code…" is to stay in the text, say for which case it applies (same server, rotated token) and do not offer it as the cross-server recovery. - Keep the three asserting tests pinned to that text, so the doc, the CLI hint and the health-check cannot drift apart again (that is what
test_doc_section_names_the_same_commandsandtest_commands_parse_with_the_real_cliexist for). - Settle the on-hold wording before asking for merge; while it is on hold, this is not mergeable as-is.
Not blocking / status
- The new test is behavioural (real HTTP server, real
connectionsmodule, fakes only at the vault, gateway probe, resolver and spawn); it is the right shape. TheSUTANDO_WORKSPACE=in itsisolate_os_environcall is the established test-isolation pattern, not a live default. - @keweichen's CHANGES_REQUESTED at
4c360463still stands from that account; points 1-4 are fixed at this head, point 5 (commit trailers: a namedStand:trailer on4c360463, noSutando-Task:on31ec7e21) is still open and can be fixed in the squash message. @qingyun-wu's approval stands from9be27800with a delta verification at this head. - Checked: CI 46 pass / 1 skip,
license/clasuccess (1 context), no unresolved threads, hardcoded-path scan over the added lines clean.
— Sutando (susans-MacBook-Pro)
What changed, and why
The connections docs, help text and docstrings used "code", "connect code" and "agent portal" for what is the agent's relay token (
<relay_url>|<bearer>). This PR:docs/connections.mdthat defines only the relay token (taken byadd/update_token; the CLI reads it on stdin with-);src/connections.pyfrom "code" to "token" (for example "the token is for agent …", "holds the NEW token", "relaunched on the unchanged token"); error codes, behaviour and identifiers are unchanged;moveat the Sutando desktop app instead of the agent portal /add '<code>': themovefallback indocs/connections.md, thescripts/connections.py movehint, thesspace-migrationhealth-check message and the last line oftry_reuse_move's docstring now say "in the Sutando desktop app, open Homeserver connections and choose Update code… (Reconnect with a code… if it is paused)". This wording is under review and on hold: Update code… replaces the token of the existing ag2.space row, which a token for s.space cannot recover (see the new test below). The final wording is pending the owner's answer;tests/connections-move-recovery.test.py, an end-to-end regression over agent-api's real HTTP connections routes: with every row on ag2.space andmoverefused, replacing the ag2.space row's token with an s.space token is refused (legacy_row_unmanagedfor the legacy row,token_server_mismatchfor a named row), while adding the s.space token as a new connection (POST /api/v1/connections, confirm,expected_server: s.space) and promoting it withparkleaves an s.space row that is the sole primary, with the ag2.space row parked.Look first
docs/connections.md(glossary, themovefallback),scripts/connections.py(movehint),src/health-check.py(check_sspace_migration),tests/connections-move-recovery.test.py.Behavior proven
tests/connections-move-recovery.test.py(2 tests; a mutation that reconnects instead of promoting fails both).tests/connections-cli.test.py,tests/health-check-sspace-migration.test.py,tests/connections.test.pyassert the new text.Feature/documentation consistency
docs/catalog.jsonlast_verifiednot bumped (wording and a test; no feature change).Evidence / tests
Run locally under
env -i,nice -n 19:tests/health-check-sspace-migration.test.py7 OK;tests/connections-cli.test.py21 OK;tests/connections.test.py361 OK (2 skipped);tests/dotspace-literal-guard.test.py7 OK;tests/connections-move-recovery.test.py2 OKbash scripts/review-checks.sh --diff <full PR diff>: PASS;ruff checkon the touched Python: cleanNot touched (on purpose)
docs/codex-core.md's MCPagent_linklink code: a different flow from the relay token.Live path: N/A. Written by Claude for Chi Wang, who is accountable for it.
🤖 Generated with Claude Code