Skip to content

Setup's grant listings say each connection's kind - #106

Merged
gabosarmiento merged 3 commits into
mainfrom
claude/serene-noether-ztphvm-connection-kind
Nov 5, 2026
Merged

gabosarmiento merged 3 commits into
mainfrom
claude/serene-noether-ztphvm-connection-kind

Conversation

@kiff-qa

@kiff-qa kiff-qa commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Change

Coach connected a vendor the account already uses through a different kind of connection: a provider's app, live only, where the account's other tafs use the vendor's own sign-in, in test. It couldn't tell: Setup's grant listings (asked-grants, agents/{agent}/grants) gave each connection's server and status, not how it reaches its vendor.

They now say it, read-only, from the grant:

  • kind: vendor_sign_in (the vendor's own MCP server), provider (a provider's app), key (a REST key) or browser.
  • provider: its entry, to ask for the same app again, and mode with mode_words, the same as the grant's own view.
  • key: api with the description's URL, base and where the key goes, to ask for the same again. Never the key.
  • A vendor's own sign-in has no mode planque knows, so none is given.

connectorMode is shared with the grant's view, so both say the same mode.

GET /v1/accounts/{tenant}/connections (second commit): the same facts for any of the account's keys or sessions, as its catalog is, so tafs cloud can give them to Coach when a conversation starts (it reads them with the person's session and keeps the tafs that person may see). Each live connection's agent, vendor, kind, server/entry/api, status and a provider's mode/mode_words. No grant id, approval, text, tool or key. The catalog already tells the same callers which apps are connected, with their grant id; this adds the taf's agent and the kind. Read-only, no new credential, nothing written.

Validation

  • TestSetupsListingSaysEachConnectionsKind: a vendor sign-in (kind, server, no entry, api or mode); a REST key (kind and api, and the listing never carries the key); a provider's app (kind, entry, unknown mode with its words, then test after a permitted call returned a test object).
  • TestTheAccountsConnectionsSayEachKind: a person's session and a taf's key both read every live connection, whoever asked for it, each with its kind and what asks for the same again, never an id, text, approval, tool or the key; another account's key gets 403, no key 401; a disconnected connection is left out.
  • The existing listing tests pass unchanged.
  • gofmt -l . clean, go vet ./..., go vet -tags live ./live, go test -race ./... green.

Compatibility and rollout

Additive fields on two read routes, and one new read route. Setup reads them once kiff/agents' planque tool and the next connect-an-app version say so; those go into the next Eval and Upgrade. Deploy this first.

  • Public text, fixtures, logs, and screenshots contain no secrets or customer data.
  • Relevant tests and documentation are updated; Unreleased notes added when needed.
  • Requested changes are addressed; a maintainer must review the final revision.

Generated by Claude Code

So Coach can offer a new taf the kind of connection the account already
uses for a vendor: the vendor's own sign-in, a provider's app (with its
entry and mode, as the grant's own view says them), a REST key (with its
API's public facts, never the key) or a browser.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AwzHttNtz5jHCN5ufuPEt3
GET /v1/accounts/{tenant}/connections lists how the account's tafs reach
their vendors, for any of the account's keys or sessions, as its catalog
is: each live connection's agent, vendor, kind, what asks for the same
again and its mode. No grant id, approval, text, tool or key. Setup's
listings share the same view.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@gabosarmiento gabosarmiento left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Read at ef6520a. Setup's grant listings now say each connection's kind: vendor_sign_in with its server, provider with entry, mode and mode_words, or key with the API's URL, base and auth placement, never the key. The mode comes from the first permitted call's object (#105). A key grant carries no mode, and a provider's app no api; the tests pin each. Approved.

@gabosarmiento gabosarmiento left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Re-read at a8ea074. GET …/connections is read-only metadata (agent, vendor, kind, server/entry/api, status, mode), for the account's keys or sessions as its catalog is, with no grant id, approval, tool text or key. tafs cloud filters it to the tafs the person may see before Coach reads it. The tests pin each kind's fields. Approved. On merge, I write the squash message without the session trailer.

@agentgabo agentgabo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

agentgabo: changes requested at a8ea074, one point. I'm sorry this came late.

Blocking: GET …/connections lists grants that never connected.

  • accountConnections keeps every grant but failed and disconnected. That includes pending and approved requests that never got a sign-in: a connection Setup asked for, not one the account has.
  • tafs cloud gives this list to Coach as "the account's existing connections", so Coach would offer it as "already connected". That's the owner's complaint from this afternoon ("why is the agent saying Stripe sign-in and AgentMail are already connected?"). The status field is there, but the start block shouldn't rely on Coach reading it right.
  • Fix: keep only the grants that hold a sign-in: connected, listed, needs_reconnect, and pending with signed_in. That's the same set the apps call a taf's connections. Add a negative case to TestTheAccountsConnectionsSayEachKind: a pending grant with no sign-in is left out.

Not blocking:

  • Who may read it: agentKey lets any of the account's taf keys read every taf's connections: agents, vendors, API bases. tafs cloud filters by the tafs the person may see, but a taf's own key reading directly isn't filtered. That's fine for one owner. With shared tafs (groups, per-taf grants) it should narrow to the caller's own agent, or to sessions. Worth a line in the README now.
  • setupGrant embeds connection (whose Server is omitempty) and declares its own Server with the same JSON name. The outer one wins, so the output is right. A comment saying the embedded one is shadowed on purpose would save the next reader the double take.

Fine as is: connectorMode is shared with the grant view, so the two can't disagree. The key is never in the listing (tested). A vendor's own sign-in gives no mode. 403 for another account and 401 with no key are both tested. go test -race is green in CI.

A grant asked for and never signed in to is Setup's request, not a
connection the account has: listing it would let Coach offer it as
already connected. The route now keeps connected, listed and
needs_reconnect grants, and pending ones whose sign-in is held, the set
the apps call a taf's connections. The README says who may read it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

kiff-qa commented Nov 5, 2026

Copy link
Copy Markdown
Contributor Author

Thanks, all three points are taken in 23823d8:

  • Blocking, fixed. GET …/connections keeps only grants that hold a sign-in: connected, listed, needs_reconnect, and pending with signed_in (holdsSignIn). TestTheAccountsConnectionsSayEachKind now asks for a new connection with no sign-in and checks it isn't listed, both while pending and once approved on the phone without a vendor sign-in. Under the old filter the test fails with exactly that grant listed; with the fix it passes.
  • Who may read it: the README row now says a taf's own key reads every taf's connections, which suits one owner, and that with tafs shared between people it should narrow to the caller's own agent, or to sessions.
  • The shadowed Server: commented on setupGrant: it shadows connection's on purpose, since Setup's listings always gave the request's server.

gofmt, go vet ./..., go vet -tags live ./live, go test -race ./... green locally. Re-requested your review.


Generated by Claude Code

@kiff-qa
kiff-qa requested a review from agentgabo November 5, 2026 19:51

@agentgabo agentgabo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

agentgabo: approving at 23823d8. My point is fixed. holdsSignIn keeps connected, listed, needs_reconnect and pending with a held sign-in, the same set the apps call a taf's connections. The new negative case covers both pending with no sign-in and approved-but-not-signed-in, and neither is listed. The README now states the shared-tafs caveat, and the shadowed Server has its comment. CI was still running when I approved; merge only on green.

@gabosarmiento gabosarmiento left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Re-approved at 23823d8: only connections that hold a sign-in are listed, with the test for both pending and approved-but-not-signed-in. Good.

@gabosarmiento
gabosarmiento merged commit a0b4fa6 into main Nov 5, 2026
1 check passed
@gabosarmiento
gabosarmiento deleted the claude/serene-noether-ztphvm-connection-kind branch November 5, 2026 20:26
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.

4 participants