mirror of
https://github.com/block/buzz.git
synced 2026-11-05 17:01:35 +00:00
a96ace4e55baa9c943cfbbfc323502ff2eff05f3
3 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
d1b7da45a2 |
feat(acp): add BUZZ_GIT_IDENTITY switch for agent commit identity (#8024)
🤖 This adds an operator switch for whose identity an agent's commits carry, and removes the reason agents were clearing their git identity env vars. Replaces #6177. Since #7819, every agent authors and signs commits as its nostr identity through `GIT_CONFIG_*` env vars, which beat repo and global config in every shell the agent runs. Operators had no way to opt out of that. **`BUZZ_GIT_IDENTITY=agent|user`.** It's read once in `GitEnvironment::install`. Unset or `agent` keeps today's behavior. `user` keeps only relay git auth (the credential helper and keyfile) and installs no identity, no `git-sign-nostr` and no signing config, so git uses the operator's own config. It also drops inherited `GIT_CONFIG_*` entries for the agent identity and signing keys, `author.*`/`committer.*`, and `include.path`/`includeIf.*.path`, so a nested agent in `user` mode can't pick up its parent agent's identity. Any other value fails startup with an error naming the variable and both allowed values. The resolved mode is forwarded in the managed env to MCP servers, which `buzz-agent` starts with a cleared env, so a nested `buzz-acp` launched from an MCP shell keeps the operator's choice instead of falling back to `agent`. **Known limitation:** in `user` mode, an operator whose own git config signs with `git-sign-nostr` has commits refused with a key-mismatch error, because the agent shell's `BUZZ_PRIVATE_KEY` (needed by the `buzz` CLI) loads ahead of `nostr.keyfile` and NIP-GS requires the signer to exit when the loaded key doesn't match `-u`. Nothing is signed with the wrong key. SSH and GPG signing are unaffected. **Desktop reserves `GIT_CONFIG*`.** User env overrides are layered onto the spawn command after the relay credential helper, so a single `GIT_CONFIG_COUNT=0` used to silently drop it. `GIT_CONFIG` and every `GIT_CONFIG_*` name are now reserved keys. **`session_new_forwards_complete_git_block_without_duplicate_names` no longer reads the runner's env.** Run inside an agent session, it picked up the session's own inherited `GIT_CONFIG_*` and failed. Agents worked around that by unsetting `GIT_CONFIG_COUNT`, and any commit made in that shell fell back to the human's git identity and signing key. The test now hides the runner's `GIT_CONFIG*` and `BUZZ_GIT_IDENTITY` under `ENV_LOCK` and restores them afterwards. **Agent instructions.** `base_prompt.md` and the nest `AGENTS.md` now say the runtime sets the agent's commit identity and signing, and that agents shouldn't override them with `user.*` config, `-c user.*`, `--author` or another signing key. Trailers are added only when the repository or the person the agent works for requires them. If a repository requires a different author, the agent tells the operator, who can switch to `BUZZ_GIT_IDENTITY=user`, instead of overriding the identity. The nest `AGENTS.md` scopes this to agents Buzz runs through its stock `buzz-acp` harness, and notes that custom harnesses get only relay git auth and control their own attribution. `NEST_AGENTS_VERSION` goes from 5 to 6. --------- Signed-off-by: Will Pfleger <pfleger.will@gmail.com> Co-authored-by: Duncan <dcfd242e557282d7a1e2cf2e6877522682f1e5c6156dc92ca7d90eaedd3b0f95@buzz.block.builderlab.xyz> |
||
|
|
ea1e97e65f |
feat(acp): run one prepared task from a file or stdin (#7851)
🤖 ## Summary Scripts, scheduled jobs, and other automation need to give an agent one prepared task and wait for a result without starting a long-running chat listener. This adds `buzz-acp run`: it reads a task from a local file or stdin, runs one fresh agent session with the configured tools and instructions, cleans up, and exits with a machine-readable status. ```sh buzz-acp run --task ./task.json cat task.json | buzz-acp run --task - ``` - The versioned JSON task specifies a task ID, intended agent public key, prepared prompt, and execution time limit. Invalid input or an identity mismatch is rejected before agent launch. Credentials, executable, tools, and permissions remain controlled by trusted launch settings, not the task document. - Each invocation uses the normal agent equipment: base/persona/team instructions, enabled memory, tools, model and effort settings, permissions, and Git identity, credentials, and signing. Both task and conversational modes obtain these capabilities from one shared runtime owner; new shared setup belongs there rather than in separate entry points. - Launch configuration reads have a separate ten-second bound and can be cancelled even when a prompt file blocks. A deadline covers adapter startup through the task turn. Interrupts and termination signals trigger bounded cleanup. Stdout contains one terminal JSON record; diagnostics stay on stderr. A normal turn ending is not proof that the task achieved its goal. - Normal invocation remains the conversational service. Task mode does not start chat subscriptions, presence, heartbeat turns, or a persistent agent pool. Tasks are trusted executable instructions, not sandboxed input. Reusing a task ID does not prevent duplicate execution, and uncertain outcomes must not be blindly retried. See [the task contract](crates/buzz-acp/TASKS.md) for the document format, exit codes, limits, and examples. URL retrieval, a task server, and a persistent execution ledger are outside this change. ### Related issue None found in the existing issue and PR search. ### Testing - At `4e86bbc97`: 964 unit tests and 22 integration tests passed, with three existing ignored tests. The package suite ran serially with inherited harness/Git options cleared. A final test-only shutdown-result assertion was then checked with the focused memory test and all-target Clippy. - All eight real-binary task tests independently passed on the exact candidate, including blocked configuration reads, file/stdin validation, session equipment, deadlines, cancellation, and cleanup. The memory test passed 20 repeated runs. Removing the oversized-input guard fails the new error assertion; restoring it passes. - Package all-target Clippy, formatting, file-size checks, and pre-push Rust/Tauri checks passed. All executed hosted checks passed on the updated head (54 successful, 28 skipped). The separate Codex review comment still requests authorization for this exact range. - Earlier revisions passed the release build and a real Goose 1.51.0 tool-use smoke test. No new release artifact or installed Janet runtime is claimed for this feedback revision. - Repository-wide `just ci` was previously attempted; workspace Clippy passed, then the desktop dependency check stopped on a local pnpm fetch failure. Hosted checks cover the applicable PR lanes. --------- Signed-off-by: Logan Johnson <loganj@squareup.com> Co-authored-by: Larry <627498bd4bd1f281a16431e3c6cce3b5c25b6692798c78672298aefbf2f8f8b5@buzz.block.builderlab.xyz> |
||
|
|
5621006bcf |
refactor: move agent Git bootstrap into ACP harness (#7819)
discovered in https://github.com/block/buzz/issues/7742#issuecomment-5783512985 ## Summary Goose uses its native shell, so it bypassed the Git identity and signing setup inside `buzz-dev-mcp`. Agent commits could use the host Git identity, while MCP shells had a separate config. This moves Git setup into `buzz-acp`, where both paths receive the same agent identity, Nostr signer, and relay-scoped credential helper. Before: ```text Buzz Desktop └─ buzz-acp ← Desktop supplied relay Git authentication ├─ Goose → native shell ← no agent Git author or signing setup └─ Buzz Agent └─ buzz-dev-mcp └─ shell ← MCP created the keyfile and Git signing config ``` After: ```text Buzz Desktop or Sprig └─ buzz-acp ← owns the keyfile, identity, signing, and scoped credentials ├─ Goose → native shell ← inherits the complete Git environment └─ Buzz Agent └─ buzz-dev-mcp └─ shell ← receives the same Git environment via mcpServers[].env ``` The harness keeps the signing key in a private temporary file and removes it on normal exit, startup failure, and graceful termination. It composes inherited `GIT_CONFIG_*` entries, forwards the complete block to MCP servers, and bundles the helpers through the ACP multicall entrypoint. For standard `buzz-acp` launches, Desktop and Sprig no longer write Git config. A custom Desktop ACP command bypasses the harness, so Desktop preserves its prior relay-scoped credential helper for that supported override. This changes Git settings for every ACP runtime. The startup signal path also changes so a termination during adapter initialization removes the keyfile. The temporary file can remain after SIGKILL or a machine crash. ### Related issue Related: #6177 covers stricter commit identity enforcement and touches the same Git paths. That PR and this one need to be reconciled before either lands. No issue was found for this runtime bootstrap gap. ### Testing - Ran the ignored `git_runtime_tests` with real Goose 1.50.0 and Buzz Agent ACP sessions. `real_goose_native_git_shell` passed again on this PR branch with `BUZZ_TEST_BIN_DIR` pointing to built binaries. Goose made a signed commit and tag through its native shell; Buzz Agent did the same through its MCP shell. Both verified signatures, identity, credential scoping, and keyfile cleanup. - Built the Linux Sprig image and ran `scripts/test-sprig-image.sh buzz-sprig:acp-git-bootstrap`. The container made and verified a signed commit and tag, then confirmed keyfile removal after SIGTERM. - `just ci` passed on the original branch. After rebasing onto `main` and addressing review feedback, the ACP Git bootstrap integration tests, focused desktop smoke test, custom-command regression test, formatting, and ACP/Desktop Clippy passed. The pre-push hook hit two timing-sensitive ACP deadline tests under parallel load; both passed alone and the complete ACP package passed serially (964 library, 2 Git bootstrap, 9 pool lifecycle tests). The push used `--no-verify` after those checks; GitHub CI is rerunning on the new head. - Under injected `BUZZ_ACP_ALLOWED_RESPOND_TO`, `BUZZ_ACP_LAZY_POOL`, and `BUZZ_ACP_IDLE_POOL_SLEEP`, the clean-env serial package command in `crates/buzz-acp/TESTING.md` passed: 964 active library tests, 2 Git bootstrap tests, and 9 pool lifecycle tests. Both named Databricks OAuth tests passed locally; another reviewer reproduced their environment-specific failures on `main`. - No authenticated relay clone or push was run. The local probes used disposable repositories and did not contact a relay. Generated with Codex --------- Signed-off-by: Salman Mohammed <smohammed@squareup.com> |