Skip to content

Release/v3 - #124

Open
chandan25809-lyzr wants to merge 71 commits into
mainfrom
release/v3
Open

chandan25809-lyzr wants to merge 71 commits into
mainfrom
release/v3

Conversation

@chandan25809-lyzr

Copy link
Copy Markdown

gitagent 3: the Rust rewrite

gitagent becomes one static binary. It runs the same agent folders, hook scripts, schedules and SDK code as the TypeScript gitagent, scores higher than any published harness on Terminal-Bench 2.1, and adds a terminal console, parallel sub-agents with a live task board, schedules, and SDKs for any language over a line protocol.

This branch replaces the TypeScript tree. Merge with squash and tag the result v3.0.0. The full history stays on feat/v3-rust.

Benchmark

Terminal-Bench 2.1: 93.03% ±0.8 with Claude Opus 5.5, all 89 tasks, five runs each, code frozen at the published commit. The ± is the run-to-run variation, as on the official leaderboard. For comparison: Terminus 2 with the same model 87.6%, Codex CLI with GPT-6 Astra 87.4% ±0.9, and the highest published entry, Artificial Analysis's harness with Claude Fable 5.1 at maximum effort, 91.4%.

Every trial is public on the Harbor hub, one job per time limit; the README's Results section links them. The rules that keep the number honest are in docs/INTEGRITY.md and are checked by scripts/integrity-audit.sh: the agent never reads a task's tests or verifier output, benchmark mode uses only the built-in configuration, and a test fails if the prompt or tool list sent to the model in --bench ever changes.

What is new

  • One binary. curl to install; no Node or npm. Linux x86_64 and arm64 (static musl), macOS.
  • The loop that makes the score. Output shaped to a budget with spill files, old tool results cleared through the provider's context editing, reminders appended rather than inserted so the prompt cache stays warm (92% of input tokens cached in the headline run), a completion check that refuses "done" until a verification ran after the last change, a loop detector, a time budget, and an environment probe. README.md explains why these raise the score; docs/HOW-IT-WORKS.md has the mechanics.
  • A console in the terminal. gitagent -d <agent>: tool lines, approvals, / commands with suggestions, /help, a live task board for parallel work.
  • Parallel work. runtime.parallel_tasks: true gives the agent a plan tool: phases of tasks run as sub-agents, a reconciling step combines the results. Each task can carry its own turn limit; a task that runs out is warned first and comes back marked partial. max_parallel is a ceiling: a rate-limit refusal halves the number running at once, and it grows back as calls go through.
  • Schedules. gitagent schedule list|add|remove|enable|disable|run|start, cron and one-off, with per-schedule logs.
  • Repo mode. --repo <url>: work in a fresh clone on a session branch, commit, optionally push.
  • SDKs over IPC. gitagent --ipc speaks JSON lines on stdin and stdout. Python and TypeScript clients are in clients/; any language can drive it (the README shows a bash client). The TypeScript client keeps the 1.x query() and tool() API.
  • Compliance. Human-in-the-loop rules, escalation triggers, a kill switch, segregation of duties, spending limits with a monthly ledger, and an audit log, all from agent.yaml.
  • Sandbox. On Linux the agent's shell runs under Landlock and seccomp outside benchmark runs.
  • Learning between runs. gitagent learn turns finished runs into general lessons for the system prompt; learning: online does it per project.

Compatibility

Agent folders, agent.yaml (1.x settings included), SOUL.md, RULES.md, memory, skills, declared tools, hook scripts, schedules, workflows, sub-agents, config/<env>.yaml, .env, OpenGAP folders and .claude/ project layouts load unchanged. gitagent validate points out old spellings as warnings, never errors. The CLI flags -p, -d, -m, -e, --repo, --pat, --session and the slash commands work as before.

Not carried over: --voice and the remote --sandbox (the binary prints a one-line note), a plugin's entry JavaScript (plugins contribute tools, skills, hooks and prompt text through files), and the 1.x telemetry adapter (OTLP export replaces it). Exit codes: 2 for usage errors, 3 for provider failures, 130 on interrupt.

Layout

A Cargo workspace: cli, core, loader, provider, tools, terminal, shaper, context, guards, hooks, mcp, record, repo, sandbox, learn, sdk; clients/python and clients/typescript; gitagent_harbor/ (the Harbor shim); bench/ (the benchmark profiles, public job links and prices); profiles/ (per-model-family behaviour); prompts/; scripts/.

Checks

  • cargo test: 355 tests, including the benchmark guard test.
  • cargo clippy --all-targets, cargo fmt --check, scripts/integrity-audit.sh: clean.
  • Python client tests and the TypeScript type check pass.
  • Tried end to end with Claude Opus 5.5 on a 4,800-file monorepo: console, parallel plan with 16 sub-agent tasks, memory, repo scan.

Docs

README.md (why, install, use, CLI options, results, how it works, architecture, SDKs, migration, configuration, Harbor, troubleshooting), BLUEPRINT.md (requirements, design decisions, open questions), docs/HOW-IT-WORKS.md, docs/INTEGRITY.md, CONTRIBUTING.md.

Known gaps

  • Sub-agents loaded from their own folder keep their own spending ledger, so the parent's monthly cap does not cover them.
  • Plugin settings from agent.yaml do not reach a plugin's script tools (as in 1.x, which only passed them to entry JavaScript).
  • In repo mode, the agent's starter files are added to the clone, as 1.x did.
  • IPC sends each model call's text as one message, not token by token.

A single static binary that runs one agent loop over a persistent shell:
native tool calling with a text fallback, PTY sessions with end markers,
output shaping with spill files, an environment snapshot, batched masking
and compaction, time and loop guards, and an evidence-based stop check.
Provider adapters for Anthropic, OpenAI, Google and OpenAI-compatible
endpoints; per-family profiles in YAML; ATIF trajectories and counters
written every turn.

Also included: the Harbor shim and benchmark scripts for Terminal-Bench 2.1
(dev/held-out split, rounds, pricing, dashboard), the offline lesson
learner with its leakage audit, the .claude/ project-file layers, the
gitagent-sdk library API, a Landlock+seccomp sandbox, and the integrity
audit script.
…timeout multipliers, task versions, Hub link) and a compliance strip per round; Harbor's per-trial log is no longer shown
…ks, not only the dev ones; badge on such rounds; running jobs listed as unfinished
…provisional while its errored trials are relaunched
…itions of the published Terminal-Bench 2.1 run
…TS.md as fallback) ahead of the working instructions; model.preferred, runtime limits, model constraints and the skills list apply; schema problems are warnings; benchmark mode reads none of it
…AGENT_MODEL_BASE_URL outside benchmark mode, and model fallback (fallback_models, model.fallback) that switches on a fatal error or three transient errors in a row
…acker) are accepted in tool lists, with argument translation for hooks; the model keeps seeing gitagent's own names
…wn in the system prompt, and the memory tool (load, save) appends to them, moves lines beyond max_lines to memory/archive/, and commits each save on its own; on for agent directories or with memory: true, never in benchmark mode
…he model can call; scripts get the arguments as JSON on stdin, http tools send them as body or query with ${VAR} headers, 120 s default timeout, arguments checked against the input schema; tool lists keep the agent's own tool names; never in benchmark mode
…and end, pre and post tool use, pre and post response, on_error) and the 1.x ones (pre_query, post_tool_failure, file_changed); JSON in, allow/block/modify out, 1.x fields and names kept for old scripts; a failing hook blocks unless fail_open, compliance hooks run even with hooks off; the init message lists every offered tool; never in benchmark mode
…y's mcp_servers option are connected once per session (stdio, streamable HTTP, the older SSE transport; ${VAR} filled at connect time; 30 s to connect and list); their tools are offered as <server>__<tool>; a server that fails is left out with a warning; mcp_server tools in tools/*.yaml call their server; never in benchmark mode
…t waits for a person (human_in_the_loop always or conditional with action_type, error_detected and token_count_above triggers; requires_confirmation tools; pre_review_required responses); the terminal asks on /dev/tty, the library takes an approver, and nobody to ask means denied; kill_switch stops the run between steps (.gitagent/KILL, or Query::kill), exit code 130; the OpenGAP compliance lines go into the prompt; never in benchmark mode
… OpenGAP schema (closed objects, types, ranges, patterns), the skills, tools and sub-agents it names, SOUL.md, hooks/hooks.yaml and its scripts, every tools/*.yaml and skills/*/SKILL.md, and with --compliance the regulatory rules (risk tier, FINRA, SR 11-7, segregation of duties, financial governance); findings name the file and line; exit 1 on errors
…th working instructions for talking with a person (prompts/conversation.md); on in the interactive session, with --conversation, and in the library's conversation option; final replies pass the pre_response hooks and review approval like task_complete; benchmark runs never use it
…ent libraries; initialize with options, callbacks and client tools, then user turns in one conversation (conversation mode by default) streamed as delta, assistant, tool_use, tool_result and turn_end messages; steer, abort, kill and end; callback requests for hooks (onSessionStart, preQuery, preToolUse, postToolUse, postResponse, onError), approvals and client tools with timeouts; 1.x tool names on request; sessions stored and resumed with resume: true. The loop gains a steering queue, caller-run tools, a reason on the kill switch, and resuming from stored messages
…he agent directory and the output directory are made absolute, since hooks, tools and the shell run in other directories
…eft out with a warning instead of stopping the run; a scripted model gets no fallbacks
…ogress instead of dropping the conversation; a type mismatch in agent.yaml is a warning (name, version and description still apply) and YAML slips like version: 1.0 are put right; runtime.timeout applies; a tool script outside the agent directory is refused like a hook script; a tool result's error: false is not an error; a malformed client tool in IPC initialize is refused instead of crashing; a steer message arriving as a turn ends becomes the next message; the terminal approver reads on one thread so a timed-out question cannot take the next answer; IPC callback entries are freed when a request is given up; IPC costs use the library's arithmetic; memory saves run git without blocking the runtime
…p (--env, the env option, or GITAGENT_ENV); model_override, temperature_override, timeout_override, env_vars for tool and hook scripts, compliance_mode (the agent must pass validate --compliance to start) and audit_logging apply, other settings are kept; validate checks config/*.yaml; never in benchmark mode
…ys_load go into the system prompt after the skills (as information, not instructions; non-text or very long ones are listed instead), the others are listed for the file tools; examples/*.md follow under an Examples section, scenarios/ stays out; validate checks the index; never in benchmark mode
…d into .gitagent/parent/); the child's agent.yaml is merged over the parent's with skills and tools joined, SOUL.md is the nearest, RULES.md are the parents' then the child's, DUTIES.md, hooks, knowledge, examples and config files are the nearest that has them, skills and tools are joined with the child shadowing by name, memory is never shared; chains are followed with cycle detection; gitagent install fetches a git parent and the dependencies (git clones at their version, local copies) into their mounts; validate checks both
… with its own prompt, skills, tools, hooks and memory (the parent's model, supervision and tool hooks apply when it has none of its own), agents/<name>.md runs on the parent's prompt with its instructions; the agents: map in agent.yaml names them with description and delegation triggers, without one every entry is offered; the prompt lists them and the delegation mode (auto, explicit, router); validate checks sub-agent directories too
…the session-start procedure; hooks/teardown.md runs as one last turn of the session, on its conversation and shell, before on_session_end (one-shot runs, the interactive session, repo mode, IPC and the library); a failed teardown is reported and the run's own result stands
…and -r, --pat and --session for repo mode (GIT_TOKEN read too), .env files in ~/.gitagent and the agent directory loaded before a run (never in benchmark mode), gitagent init to start an agent directory, and the interactive session's /help, /memory, /skills, /agents, /tools, /skill:<name> and /quit with a banner naming the agent; --sandbox and --voice say they are not available
The interactive session opens with a box: the build (gitagent v2.0.0),
the agent with its version, model and branch, the directory it lives
in, and how to get help; the tools, skills and sub-agents follow under
it. The workspace version is 2.0.0: this is the second generation of
gitagent, the Rust one.
While the model works a small spinner shows how long it has been
thinking, cleared as soon as a tool line arrives. /new drops the
conversation and starts fresh in the same session; /clear clears the
screen. Both are listed by /help.
On a terminal the prompt is a line editor: typing `/` shows the
matching commands under the line with one line about each, `@` the
workflows, Tab or → completes the pick, ↑/↓ choose one (or walk this
session's history), Ctrl-A/E, Ctrl-U and Ctrl-W edit the line, Ctrl-C
clears it (or ends the session when it is empty). The terminal is put
in raw mode with stty only while a line is read, since the workspace
allows no unsafe code; piped input is read line by line as before, so
scripts and tests see no change. A bare `/` prints the guide.

/help is now a guide: the commands, how a turn reads ($ tool lines, ✗
errors, ● the closing status), skills and workflows by name, how
approvals pause the session, the editor keys, where the agent's files
live and what each is for, and the commands outside the session.
On a terminal the welcome box is preceded by "gitagent" in the classic
six-row line-drawn letters, in the theme colour, the letters pulled
together until they touch as figlet does; plain and piped terminals get
the box alone.
The page served by `gitagent ui` is redone around what makes gitagent
different: the agent is a folder of parts. The left column draws those
parts as a map (identity, rules, memory, skills, tools, hooks,
sub-agents, schedules, workflows, knowledge) around the agent, and each
lights up as the agent uses it; sub-agents the agent starts appear as
small circles that run, finish or fail. Clicking a part opens its files
in the middle, with an editor, and identity also shows the system
prompt the model receives. The middle is the conversation as one stream
of lines with tool calls to unfold, sub-agent cards and approvals
inline. The right column is the inbox, the schedules, the changes with
diffs and revert, and past sessions. Warm charcoal with the logo's one
colour, a light variant, and the logo in the corner. The server and its
API are unchanged.
With `runtime: {parallel_tasks: true}` in agent.yaml the agent gets a
`plan` tool: it writes phases of tasks, every task in a phase runs at
the same time as its own sub-agent (fresh context, own shell, up to
`runtime.max_parallel` at once), a later phase is given the earlier
results, and one more sub-agent reconciles everything into the answer
that comes back as the tool's result. `plan` events report each phase,
task and the reconciling step; the counters count plan runs, tasks and
failures, and every task's trajectory is kept under plans/<n>/tasks/.

In the interactive session a plan shows as a board that redraws in
place: the phase, one line per task with a spinner while it runs and
its result when done, finished phases folded to one line, then the
reconciling step. Piped output gets plain lines instead.

The web page (`gitagent ui`) is removed; the terminal is the interface.
The opening states the Terminal-Bench 2.1 result and what is new in 2.
A Results section gives the headline run beside the published harnesses,
the side-by-side with Terminus 2 on the same model and tasks, the
held-out check, the GPT-6 Astra rounds and the integrity rules. A
section on how a run works explains the loop and the mechanisms that
make it score well: the working method in the prompt, the stop check
with evidence, the output shaper, appended reminders that keep the
cache, the loop detector, server-side context editing and structured
compaction, shells kept open for the tests, the trajectory record and
the single static binary.
The README opens like a product page: the mascot, the name, badges, a
recording of a console session, the headline result and what is new in
2. A section tells how gitagent works as the story of one run: the
agent is a folder, the prompt is a method, one loop and one shell,
output shaped to a budget, reminders appended so the cache survives,
the loop detector, managed context, done means verified, shells kept
open for the checker, every run a record, and parallel work with a
recording of the task board. The results section has a chart beside
the published harnesses and the headline run broken down by the tasks'
time limits. Sections now read in order: install, use, how it works,
results, library, configuration, benchmark, development. The logo is
in the repository at 512 px; the recordings and chart live under
docs/media.
docs/HOW-IT-WORKS.md gives the mechanical account of the harness: the
prompt assembly order, the loop, the shell and its end marker, the
output shaper's steps and numbers, the loop detector's hash, the time
budget, the three masking modes and the context-editing request, the
compaction request and message, the stop check's patterns and verdict,
the snapshot probe, sub-agents and the plan engine, the records, the
sandbox, offline learning, memory, hooks and approvals.

The README puts Results before the story, adds a subsection on why
the score is higher than the other harnesses', uses 93.03% throughout,
and links to the detailed document. The results chart is redrawn with
a readable axis.
…dings

The results table and chart name the highest published Terminal-Bench
2.1 entry, Artificial Analysis's own harness with Claude Fable 5.1 at
maximum effort, and link every source: Vals.ai, the official
leaderboard at Snorkel, and Artificial Analysis.

The two recordings are re-made from a small billing service: the
console one shows a real fix (failing unit tests, the file read, an
edit, passing tests, the diff) and the task board one scans the
service's three source files for TODOs in parallel and checks them.
Both play faster.
…pace

A scripted model turn may carry `delay_ms`, so a demo shows the model
thinking before it answers; the provider releases its lock before the
wait, so parallel sub-agents are not held up. The README's recordings
are re-made from a pseudo-terminal with keystrokes typed one at a time
and real pauses: the prompt appears as it is typed, the thinking
indicator runs while the model works, and the tool lines arrive at the
speed they did.
bench/RESULTS.md stays on the benchmark machine, ignored by git; the
README's results point at the headline run's public job logs on the
Harbor hub instead.
The MIT licence from main, a contributing guide for the Rust workspace
(build, tests without keys, the four checks, the benchmark guard,
profile switches, 1.x compatibility, the crates), Contributing and
License sections in the README, and the install command now fetches
the script from main, since no v2 branch exists.
…troubleshooting

The workspace version is 3.0.0: the TypeScript packages already
published 2.x, so the Rust binary follows them as 3, matching the
Python and TypeScript clients.

The README opens with why gitagent (the agent is a git repository) and
what 3 is, then gains an Architecture section (the agent folder and an
annotated agent.yaml), SDKs for any language over the IPC protocol
(Python, TypeScript, a complete client in bash, the messages both ways,
and the Rust crate), a guide for coming from the TypeScript gitagent,
and Troubleshooting. The recordings and the results chart say 3.
TASKS.md, BLUEPRINT.md and AGENTS.md say gitagent 3, and no longer say
that the TypeScript gitagent's formats are dropped: they are accepted
for compatibility, only its code is not reused. The results chart has a
wider label column, so the longest label is no longer cut off.
The blueprint now describes gitagent 3 as built: agents as git
folders, one loop for every entry point, the requirements for the
agent and for the loop, a section on why the benchmark runs through
Harbor and how gitagent runs under it, the architecture and one run
start to finish, the design decisions with their reasons (compatibility,
hooks, IPC, parallel plans, schedules, the terminal as the interface,
the benchmark guard), the product surface, the code layout, the
configuration surfaces, the interfaces, observability, testing and the
open questions. The OpenAI profiles' cache key is "gitagent".
…d in

TASKS.md (the milestone checklist, all done) and docs/DEVIATIONS.md
(differences from the old blueprint) are removed: the new blueprint
describes what was built and docs/HOW-IT-WORKS.md the mechanics.
docs/LEARNING.md is folded into HOW-IT-WORKS's learning section.
docs/INTEGRITY.md keeps the rules and the audit without the details of
how tasks were divided. The README's development list points at the
blueprint, how it works and integrity.
Every flag of the binary, grouped by what it is for, and the six
subcommands, taken from gitagent --help.
The loop detector, the stop check (task mode) and the time budget are on in
the built-in profiles, and Claude clears old tool results server-side. The
snapshot stays a benchmark setting. The built-in config sets no time limit:
the console runs without one, and -p, schedules and the SDKs fall back to 30
minutes. Docs explain the defaults and how the benchmark passes each task's
time limit.
- A workflow step that calls a declared or MCP tool itself now passes the
  same checks as a model's call: kill switch, hooks, spending and role
  rules, approval.
- Spending: a payment is counted when it is let through and taken off if
  its call fails, under a lock, so payments running at once cannot pass
  the monthly cap together. An amount that cannot be read blocks the
  payment instead of skipping the rules.
- Hooks that fail closed (compliance, fail_open: false) block on output
  that is not an answer; plain hooks still allow, as in 1.x.
- Plan tasks and the reconciling step get the time actually left.
- A steps: mapping in a workflow runs in file order.
- The audit log records spending and role blocks.
- Schedules: a job never runs twice for the same time, and the local
  offset is read each time round, so daylight-saving changes are followed.
- Starting an agent in an existing repository commits only the files it
  created, never the user's uncommitted work.
- The console help no longer lists the removed web page.
…only

- Sub-agents are told when 80% of their turns are used and again before
  the last one, so one that runs out still hands back a summary
  (turn_warning; also on for the lead in the built-in profiles).
- The subagent tool and plan tasks take max_turns (up to 100), so the lead
  can size each task's limit.
- A task that runs out of turns is marked partial: on the task board, in
  the results the reconciler and the lead see, in plan_partial_tasks.
- Plan tasks and sub-agent calls run in a rolling window: the next starts
  as soon as one finishes; task start and end are reported as they happen.
- The task board cuts lines to the terminal width, so a long task name no
  longer makes every redraw add lines; it shows running and done counts.
- The welcome box fits narrow terminals.
- The /tests write guard applies to benchmark runs only; it refused
  ordinary commands that mention /tests in a pattern.
- Status lines say "model calls" instead of "turns".
- Providers report a refusal for rate or capacity reasons (HTTP 429,
  overloaded) as ProviderError::RateLimited, apart from other transient
  errors. It is retried with the same backoff.
- One Throttle per session: max_parallel is the ceiling; a rate limit
  halves the window (never below one); ten calls in a row that go through
  give a slot back. Plan tasks and sub-agent calls start new work only
  while the window has room; running work is never stopped.
- Counters provider_retries and rate_limit_retries; a guard event of kind
  rate_limited; a plan event window once a rate limit has narrowed it,
  which the task board shows ("slowed to 2 at a time after 3 rate limits").
- The score is shown as 93.0% ±0.8, the run-to-run standard error across
  the five runs, the measure the official leaderboard uses; the across-tasks
  interval stays, labelled as such.
…e repository

The dev/held-out split, the round history, the published scores, the
lesson store and the rerun logs stay on the benchmark machine. The
profiles, the public job links, the prices and the smoke fixture stay in
bench/, where the guard test and the reproduction steps use them.
One static binary that runs the same agent folders, hooks, schedules and
SDK code as the TypeScript gitagent, scored 93.03% ±0.8 on Terminal-Bench
2.1 with Claude Opus 5.5, and adds a terminal console, parallel sub-agents
with a live task board, schedules, and SDKs for Python, TypeScript and any
other language over a line protocol.

This branch has not been deployed

No deployments
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.

1 participant