Record a Bot's decline only against a Bot the caller may reach - #382
Merged
Conversation
The declined route wrote a bot.declined row, marked "reportedBy: the Bot itself", for whatever agent id was in the path. Every other route on a Bot asks the store first and answers not found for one the caller cannot reach; this one did not, so any signed-in person could put a decline in any words against any coworker, including one they cannot see, and the trail would present it as the Bot's own word. Ask the store the same question before recording, and answer not found for a Bot the caller cannot reach, writing nothing.
kevin9327
requested review from
MikeRyanDev,
davidmckayv,
guidovizoso and
tylerslaton
as code owners
September 5, 2026 11:59
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
davidmckayv
approved these changes
Sep 5, 2026
davidmckayv
left a comment
Contributor
There was a problem hiding this comment.
Reviewed diff against current main; resolved CHANGELOG keep-both; validated locally (format + composed test run). CI green.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this changes
POST /api/agents/:agentId/declinedwrites abot.declinedrow, markedreportedBy: the Bot itself, for whatever id is in the path. Every other route on a Bot inagents/routes.tsasks the store first and answers 404 for a Bot the caller cannot reach (store.getrunsfindAccessibleProfile). This one did not.The Bot reports through the person's session (
report_refusalincomputer-tools.tsxposts to/api/agents/${bot.current}/declined), so the trail's only basis for calling the row the Bot's own word is that the person could have been talking to that Bot. Without the check, any signed-in person can write a decline, in any words, against any agent id: a coworker they cannot see, a system-owned one, or an id that does not exist. An administrator reading the trail seesThe Bot declinedwith the reason the person typed. The comment on the route already says this row is evidence rather than enforcement; this makes the evidence at least come from somebody who could reach the Bot.The route now calls
store.get(actor, agentId)before recording and answersAgent not found.(404, the same wording the other routes use, so the check does not confirm which ids exist), writing nothing. A legitimate report is unchanged: the Bot's own id is one the person can reach.Where it runs
Boundary and audit
a refused change writes nothingalready expects for the other routes.Changelog
A line under
Unreleased.Proof
bot-lifecycle-audit.test.tsgains two tests: a decline against a reachable Bot recordsbot.declinedwithreportedBy: the Bot itself; a decline against an id the store does not return answers 404 and writes nothing. The fake store in that file gains aget, which the route did not call before.bunx tsc --noEmitinserverandbunx biome checkon the changed files are clean.