Repository navigation
std/github: interact with PRs and stacks through github api - #301
Merged
nishu-builder merged 6 commits intoOct 5, 2026
Merged
nishu-builder merged 6 commits into
nishu-builder merged 6 commits into
Conversation
github(method, path, body?) makes one call to api.github.com, inline in the step, with the github-token secret llm-step is already granted for imports (design/agent-github.md, "PRs"). With publish_source pushing the commits, it is everything else a PR needs: find a branch's open PR, open one, change its base, link a stack. Nothing is checked out. - A GET runs, and a retry runs it again. Any other method is a write, pinned in a tool.start (github.json: the exact request) before it is sent. Only the attempt whose tool.start was appended sends it; an attempt that finds the call started and unfinished completes it as not confirmed and never sends it again. The pin carries a per-attempt nonce, since two attempts minting the same commit would each see their own append land and both send. - The body is pinned as the text sent, not as JSON: canonical JSON has no negative or fractional numbers, and a body a model writes must not be able to fail the pin. - Only api.github.com is reached, and redirects are not followed, so the token goes nowhere else. Paths are unrestricted; the token's scope is the boundary. publish_source now refuses a commit whose root tree has a .caos entry, such as an uncleared .caos/conflicts ledger. It reads the commit and its root tree, nothing else. /pr made this check; a squash carries a ledger into its commit, so a squashed layer needs it too. The agent guide opens PRs with the github tool, including the per-layer PRs and stack link for a squashed stack, and no longer suggests /pr, which the next change removes. SPEC.md lists the tool among the registered built-ins. Tests, run with cargo over llm-step and its spliced crates: request checks, rendering and truncation; a write pinned then sent once, with a lost acknowledgement on the pin; a write another attempt pinned, before this one or racing it, never sent again; a GET that is not pinned and does not follow a 302; publish_source's .caos check. A local HTTP server stands in for api.github.com. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CZGkTta5NYxhXcLPZwH3q1
This was referenced Oct 5, 2026
…ace-1xy4qn-github-tool
Review on #300: follow the general pattern. std/github is a tool like any other, run with run_tool(path="caos-std/github") and described by tool_help; llm-step's inline github tool and its tool.start pin go. - worker.go, on std/go (whose image carries the CA bundle): one call to api.github.com per run. Arguments method, path, body and at. The result is the status line and the body, cut at 100 kB on a character boundary; a response of any status is a result, and only a request with no response fails the run (for a write, saying it may still have arrived). Redirects are not followed and the host is fixed, so the token goes nowhere else. Arguments are checked before anything is sent: the method, an API path (a full api.github.com URL is accepted), no body on a GET, a body that is JSON. - at is required: the tool has no @in, so its ArgTree is its arguments, and a call repeating all of them returns the stored result (salt is reserved for the interpreter). - The token is /secret/github-token, granted by a second reader: line naming std/github. Also reverted from the previous commit: publish_source's .caos refusal, the SPEC.md registry entry, and agent-publish.md's note. publish_source's help points at caos-std/github; the agent guide opens PRs and links a stack with it, and no longer suggests /pr. Checked locally against a stand-in server, the worker built from this file with the API base, /cas/args and /secret paths read from the environment, and a fake caos: a POST sent once with its body verbatim and Accept, API version, Bearer and JSON content-type headers; a GET with no token sends no Authorization and a 401 gets the no-token hint; a 302 is reported and not followed; a 120 kB body is cut at 99,999 bytes, valid UTF-8; a bodiless PUT sends Content-Length 0; bad method, missing at, a GET body, a relative or spaced path and non-JSON bodies are refused before sending; a dead server fails the run, with the may-have- arrived advice for a write. go build, go vet and gofmt are clean, and llm-step's 46 tests pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CZGkTta5NYxhXcLPZwH3q1
…ace-1xy4qn-github-tool
…ace-1xy4qn-github-tool
nishu-builder
added this pull request to stack #306
October 5, 2026 07:30
std/github's results are kept by their arguments, so each call needs a value of its own among them. That was `at`, a parameter the model filled in; it read as a timestamp, and models invented dates for it. A reused value also silently returned an earlier call's result. A new help tag, `@call`, has llm-step bind the tool call's id as `call`. The id is unique to the call and the same when a call is recovered, so a retry still gets the stored result and a new call gets a fresh run. The model no longer sees the parameter. `call` is reserved, like `in` and `wc`. A caller outside llm-step passes --call itself. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Second of three, stacked on #300 (the design). This adds
std/github. The next PR removes/pr.After the review on #300, this replaces the first version of this PR, which built a
githubtool into llm-step and madepublish_sourcerefuse a.caosentry. Both are gone. Net, the PR is the new tool plus a few lines of agent guidance.std/githubis a std tool like any other. The agent runs it withrun_tool(path="caos-std/github"), andtool_helpdescribes it. It's a Go worker onstd/go, whose image carries the CA bundle. One run is one call toapi.github.com.method,path, an optional JSONbody, andat. They're checked before anything is sent: the method; an API path (a fullapi.github.comURL is accepted); no body on a GET; a body that is JSON.atis required. The tool has no@in, so its ArgTree is its arguments, and a call repeating all of them returns the stored result. (saltis the interpreter's.)/secret/github-token, granted by a secondreader:line namingstd/github. Without it, only public reads work. The host is fixed and redirects aren't followed, so the token goes nowhere else.Also in this PR:
caos-std/github, and no longer suggests/pr.publish_source's help points at the tool.std/README.mdlists the tool.Testing
worker.gowith three changes for the test: the API base,/cas/argsand the secret path read from the environment. It ran against a local stand-in server with a fakecaosonPATH:-1.5that canonical JSON couldn't hold) and the Accept, API-version,Bearerand JSON content-type headers;Authorization, and a 401 got the no-token hint;Content-Length: 0;at, a GET with a body, a relative or spaced path, and a non-JSON body were each refused before sending;go build,go vetandgofmt. llm-step's 46 tests pass.nix buildneeds flake inputs from GitHub repos this session can't reach. There is no stack test for the tool: covering a real call would need the worker to accept another API host, which would let the token leaveapi.github.com.api.github.com, so the stacks endpoint is still unexercised.🤖 Generated with Claude Code
https://claude.ai/code/session_01CZGkTta5NYxhXcLPZwH3q1