From 810b3cff69343f765dc2ecfd49eb26c6d31c53cf Mon Sep 17 00:00:00 2001 From: "@permadeath.com" Date: Wed, 23 Sep 2026 11:03:50 -0400 Subject: [PATCH] docs(agentd): say what pending lists, and how long a report is kept The daemon and command-line pages and the oauth epic describe pending, pending --all, and the reports kept for a record a later poll delivers. Co-Authored-By: Claude Opus 5.5 (1M context) Change-Id: Id98be8a9bbf8cba6bdfc6ea10801290580ee18c1 --- docs/agentd.md | 15 ++++++++++++--- docs/cli.md | 20 +++++++++++--------- plan/oauth.md | 4 +++- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/docs/agentd.md b/docs/agentd.md index 92537f19..f312ad38 100644 --- a/docs/agentd.md +++ b/docs/agentd.md @@ -251,6 +251,10 @@ is offered only once a report from its own context has named it. Anyone can push a request that names an account, so one the agent never saw waits unshown until it expires. A named request the daemon is not holding yet is fetched with `bot.did.getAuthorization`, sooner than the poll would find it. +When that fetch fails, the report is kept in memory for two minutes, as long +as a pushed request lives, and a record a later poll delivers in that time is +shown to the context that named it. At most 512 such reports are kept, and +past that the oldest is dropped. The agent answers with `didbot oauth approve ` or `didbot oauth decline `. The token names one request, is good once, and is not an @@ -286,8 +290,12 @@ the request, so these act on it whether or not a report named it. The daemon refuses a URL on any origin but this deployment's, then uses the record it holds, or fetches it through `bot.did.getAuthorization` as whichever of its accounts the record names, which is the same authenticated fetch a report -makes. `didbot oauth pending` names no context, so it lists every sign-in the -daemon holds. +makes. + +`didbot oauth pending` names no context, so it lists the sign-ins held for +every context here, and only those their own context reported seeing. +`didbot oauth pending --all` lists the rest as well, each line starting +`not-seen-by-any-agent-here`. `didbot oauth` is the only agent-facing command, and everything in it names a decision — a token, or the URL of one. There is no `--as ` anywhere in it, and nothing left that takes @@ -310,7 +318,8 @@ multiplex and one credential, not one per context. `didbot-oauth`, run by name, works there with no daemon and no hook. Set `DIDBOT_PDS` to the server and either `DIDBOT_ACCOUNT_TOKEN` or `DIDBOT_ACCOUNT_TOKEN_FILE` to that account's own session, and `pending`, `show`, `approve` and `decline` work as they do -otherwise, against the same routes as the same `AccountSelf` credential. Passing +otherwise, against the same routes as the same `AccountSelf` credential. Here +`pending` lists every sign-in waiting for that account. Passing `--direct` insists on that mode; without it a running daemon is preferred, and the environment is consulted only when nothing answers on the socket. This is the bare binary's mode: `didbot oauth` removes both credential variables diff --git a/docs/cli.md b/docs/cli.md index e1f754ec..15993157 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -439,13 +439,14 @@ the socket between them. printed -`didbot oauth pending` prints one line per request waiting for this agent, -each with its token. `didbot oauth approve ` lets one in and -`didbot oauth decline [--reason WHY]` turns it down. A token names one -request, is good once, and is not an account: the daemon acts as the account -named by the record it holds that token in. When no hook saw the client -print its URL and the poll has not come back, `didbot oauth show ` looks -the request up by that URL, and `didbot oauth approve --url ` and +`didbot oauth pending` prints one line per request an agent on this host +reported seeing, each with its token; `--all` adds the requests none did, each +line starting `not-seen-by-any-agent-here`. `didbot oauth approve ` lets +one in and `didbot oauth decline [--reason WHY]` turns it down. A +token names one request, is good once, and is not an account: the daemon acts +as the account named by the record it holds that token in. When no hook saw +the client print its URL, `didbot oauth show ` looks the request up by +that URL, and `didbot oauth approve --url ` and `didbot oauth decline --url [--reason WHY]` settle it. `didbot register ` makes the machine it runs on an account at @@ -481,8 +482,9 @@ host's document. A host with no daemon runs the binary by name. With `DIDBOT_PDS` and either `DIDBOT_ACCOUNT_TOKEN` or `DIDBOT_ACCOUNT_TOKEN_FILE` set, `didbot-oauth pending`, -`show`, `approve` and `decline` talk to that server as that one account; -`--direct` insists on it rather than trying the socket first. Through the +`show`, `approve` and `decline` talk to that server as that one account, and +`pending` lists every request waiting for it; `--direct` insists on it rather +than trying the socket first. Through the dispatcher both credential variables are removed before the hand-off, so `didbot oauth` reaches the socket and nothing else. An account whose document names an OpenID Connect identity signs in with `--token-file ` diff --git a/plan/oauth.md b/plan/oauth.md index 957beb95..a7d2d5f9 100644 --- a/plan/oauth.md +++ b/plan/oauth.md @@ -388,7 +388,9 @@ as above, and for that one the page says the sign-in was approved. is accepted rather than hidden. `seen_request_uris` on a report is what the daemon may show that context: a held request is offered only once its own context has named it, and one no poll has delivered yet is - fetched with `getAuthorization`. + fetched with `getAuthorization`, or remembered for two minutes when + that fails. `didbot oauth pending` lists only what its own context + named, and `--all` adds the rest, marked. - [x] **The granular atproto scope grammar.** `crates/didbot-scope`, re-exported as `didbot_serve::oauth::scope`: `Scope::parse`/`ScopeSet::parse` read the wire grammar directly, not a -- 2.51.2