Repository navigation
v3.0.0-dev.1
Pre-releasePre-release [3.0.0-dev.1]
The per-change notes for this release run past GitHub's 125000-character
release-body limit, so the full detail stays in the CHANGELOG:
Breaking Changes
-
The module path is now
github.com/go-steer/core-agent/v3. Go's semantic import versioning makes the/vNsuffix what decides whether avNtag can be installed at all, so it moves before the first 3.0 tag. Without it,v3.0.0-dev.1would join v2.0.0–v2.7.0-dev.4 as a taggo installcan never resolve (#327). To upgrade, rewrite importsgithub.com/go-steer/core-agent/v2/...→github.com/go-steer/core-agent/v3/..., together with the ADK v2 move below, and install withgo install github.com/go-steer/core-agent/v3/cmd/core-agent@latest. Consumers pinned to a v2.x tag keep the/v2path and are unaffected. Container images and source builds never depended on the suffix. The in-source fallback version is nowv3.0.0-dev, andverify-version-fallbackreads the major fromgo.mod, so the path and the fallback can no longer disagree. (#1312) -
core-agent now builds on ADK v2:
google.golang.org/adk/v2v2.5.0, up fromgoogle.golang.org/adkv1.7.0. ADK types are part of core-agent's library API, so embedders move with it. Change everygoogle.golang.org/adk/...import togoogle.golang.org/adk/v2/.... ADK v2 foldsagent.ToolContext,agent.CallbackContextandtool.Contextinto oneagent.Context, so afunctiontoolhandler is nowfunc(adkagent.Context, Args) (Result, error).session.NewEventtakes acontext.Contextfirst, andsession.NewEventWithContextis gone. A test fake that hand-implements the old tool context will not compile against the larger interface; embedagent.StrictContextMock, which panics on any method the fake doesn't override. The attach wire changes shape too. ADK v2 put camelCasejson:tags withomitemptyonsession.Event,EventActionsandLLMResponse, and every SSEagentframe andGET …/agents/{name}/eventsrow embeds that struct. So"ID","Author","Content","Partial"become"id","author","content","partial", and zero values are dropped instead of spelled out. Go clients are unaffected, becauseencoding/jsonmatches keys case-insensitively; core-tui, switchboard, the attach client and mast-web (which reads both casings) all keep working. A script that reads the frames with jq, Python or grep must accept both casings. This repo's own drill, soak and approval-gate graders, the GKE-recipe e2e andextract-watchdog-corpusnow do, so archived runs still grade. The protocol version does not move, because the spec never defined that payload's keys. The REST shape moves torest-subagent-events-v2.json, and the frozen v1 fixture is now pinned to keep decoding. Existing session databases open unchanged: ADK's AutoMigrate adds nullable columns, and a SQLite database written by v2.10.0-dev.1 (ADK v1.2.0) and one written at ADK v1.7.0 both reopen with state, events and the eventlog overlay intact, and take new appends. Opening a v2-touched database with an older binary was not tested. The bump also moves MCP go-sdk 1.4.1 → 1.8.0, genai 1.57 → 1.71 and OpenTelemetry 1.45 → 1.46. Provider profiles (pkg/models/profiles) now reach core-models through itsadkv2shim instead ofadkv1; the API is the same. MCP 1.7+ turns on the SEP-2322 multi-round-trip middleware, which answers a server's input requests through the client's registered handlers. In core-agent that is the same elicitation handler as before (the interactive elicitor, or decline), no sampling handler, and an empty roots list, so a server gains nothing it could not already ask for. (#1291) -
The Anthropic defaults move to the Claude 5.5 line.
anthropic.DefaultModelchanges fromclaude-opus-5toclaude-opus-5-5,anthropic.DefaultSmallModelID(the--agentic-small-modeldefault) fromclaude-haiku-4-5toclaude-haiku-5-5, andtaskclass.ModelForTierfollows foranthropicandanthropic-vertex: frontierclaude-opus-5→claude-opus-5-5, midclaude-sonnet-5→claude-sonnet-5-5, smallclaude-haiku-4-5→claude-haiku-5-5. The weekly pricing regen had failed since 2026-09-28 because the three models were priced but neither promoted nor held. Rates fall or hold: Opus 5.5 is $4/$20 per MTok against $5/$25 (cache reads $0.20 against $0.50); Sonnet 5.5 matches Sonnet 5's $2/$10 with cache reads at $0.10 against $0.20; Haiku 5.5 is $0.10/$0.50 against $1/$5. Opus and Sonnet keep a 1M window. Haiku goes from 200K to 1M, so the small tier's 0.35 compaction trigger moves from about 70K tokens to about 350K. Haiku 5.5's list price steps with prompt length: $0.50/$2.50 above 100,000 prompt tokens.pricing.Ratesholds one flat rate per model, so cost reporting and themax_*_cost_usdceilings under-count a Haiku 5.5 call past 100K prompt tokens by up to 5×. With compaction now at about 350K, a long-running small-tier subtask or background agent spends most of its life above that step, so for those runs the under-count is the usual case.claude-haiku-5-5now classifies as small inmodeltier. None of the three has been run against a live session in this repo; this follows a maintainer call to promote, not a UAT. Pin the old behaviour with--model claude-opus-5,--agentic-small-model claude-haiku-4-5, ormodel.namein.agents/config.json; all the old ids stay priced, classified and selectable. The same regen dropsclaude-mythos-preview: LiteLLM now marks it deprecated as of 2026-06-09, and the generator skips deprecated entries, so a config pinned to that id is unpriced unless a runtime catalog refresh supplies the rate. Move it toclaude-fable-5(same rates). (#1280) -
A daemon whose agent has the
bashtool no longer starts a token-less loopback or Unix-socket attach listener. It exits 2 withrefusing to start the attach listener on … without authenticationand names the fix. Until now such a listener started with a log warning, and the agent's ownbashcouldcurl …/perms/respondto approve its own permission prompts, add standing allow rules, or reset guardrails, with no credential to steal: loopback and a 0600 socket stop other users, not the agent's. To keep running, give the listener a token (--attach-token-file=<path>, new, or--attach-token=<ENVVAR>), use mTLS or enforced multi-session auth, make it--attach-readonly(writes are refused before any handler runs, so the agent cannot answer a prompt through it), start withoutbash(--disable-tools=bash), or pass--attach-allow-unauthenticated-localto accept the risk, which turns the refusal back into a warning. The opt-out is a CLI flag only, so accepting the risk is visible on the command line that started the daemon. Put--attach-unix-socketin a directory the agent's user cannot write: a token does not protect a socket the agent can move aside and impersonate. Nothing changes for a daemon withoutbash, for library embedders ofpkg/attach, or for non-loopback binds, which #376 already refused. (#1201) -
Two background subagents that can both write to the filesystem no longer run at the same time by default. The second
spawn_agentis refused, by name, while the first is still running:background: another write-capable subagent is already running: "w1" holds the shared working directory…. This turns away a shape that mostly worked — three background agents each grantedbashto run a different test suite is the common one — so it is a behaviour change and not only a new guard, andsafety.parallel_subagent_writes: "allow"restores the old behaviour in one line ("warn"runs it and logs an operator notice instead). The guard fires on the granted capability, not on an observed collision, because by the time a collision is observable the tree is already wrong; a subagent grantedbashcounts as a writer even if all it ever runs isgo test. Read-only fan-out is untouched, a second writer after the first has terminated is untouched, and out-of-process subagents (spawn_remote_agent) are the sanctioned way to genuinely write in parallel, since those get a filesystem of their own rather than a policy about sharing one. (#653)
Commits since v2.9.0
[3.0.0-dev.1] — 2026-10-12
124 commits from 2 contributor(s).
Feature
- provider profiles via core-models (#1294)
- declared subagents can be standing workers, plus a subagent-wakes UAT (#1283) (#1288)
- show a sleeping subagent's wake on the running-tasks bar (#1283) (#1287)
- report a sleeping subagent's wake and live progress on the roster (#1283) (#1286)
- add the checked-in grader for v3.0 box A7 (#1213) (#1279)
- add the A7 rig deployment and the seed script (#1213) (#1277)
- add the minimal soak dispatcher for A7 (#1213) (#1272)
- add the self-development soak image, pinned to an upstream ref (#1213) (#1273)
- store bearer-table tokens as SHA-256 digests (#1213 P2) (#1269)
- named auto-mode eligibility presets, permissions.auto.eligible_bundles (#1252) (#1255)
- honour the operator's explicit permission; never allow a destructive call (#1251) (#1254)
- box A6's adversarial boundary tests — harness, grader, and a live 6/6 (#1105) (#1248)
- a provider retry shows up in the session transcript, not only in daemon stderr (#1206) (#1243)
- the daemon states its compaction threshold in tokens at boot, and the soak grader reads it (#1199) (#1237)
- a labelled eval for auto mode's approver, and its first real-model runs (#1175) (#1222)
- permission mode auto can be selected (experimental) (#1175) (#1211)
- count box A2's failure classes in the log and the transcripts (#1200) (#1207)
- show auto mode's escalation on every prompt surface, ahead of selection (#1175) (#1208)
- grade an overnight soak against box A1 after the fact (#1199) (#1205)
- the -p summary names the thinking tokens its cost includes (#1198)
- stamp the auto-mode approver's context on every turn (#1175) (#1197)
- configure and implement the approver model behind auto mode (#1175) (#1188)
- pass full call arguments to the gate (#1175 phase 2) (#1187)
- auto mode, where an approver model decides eligible prompts (#1175 phase 1) (#1186)
- deny a permission prompt with a reason in both TUI hosts (#1182)
- let the session owner change the permission mode over attach (#1168) (#1177)
- a deny can carry the operator's reason, and the model reads it (#1174)
- approval_notify_after announces a prompt an attached client leaves unanswered (#1173)
- view_file_outline — structural skeleton without bodies (#1162)
- default to the overlay permission modal and persist /permissions layout (#1161)
- the T2 self-development tier, attended, with a delivery-graded approval notification (#1116) (#1158)
- replay a self-dev tier from its pinned base (#1116) (#1155)
- the T1 self-development task and its pre-fix grading (#1116) (#1152)
- the self-development rig, and the recipe bug it found (#1116) (#1145)
- a committed recipe for core-agent doing development work on core-agent (#1116) (#1143)
- ask whether you may, do not find out by doing (#1124) (#1130)
- pin every harness config with -c, and gate it (#1116) (#1127)
- ship the persona, keep the equipment local (#656) (#1121)
- the signal with no evasion, and the corpus to size it (#655) (#1120)
- a case says what it assumes about the process (#1061) (#1119)
- refuse concurrent write-capable subagents (#653) (#1117)
- refuse to load a skill this runtime cannot run (#962) (#1115)
- scenario D, graded on a sheet of its own (#1105) (#1114)
- two overlays select the apply leg (#1105) (#1113)
Bug or Regression
- the persona case makes the agent ask to learn it can't write (#1314)
- recompute the post-compaction session view on every read (#1292)
- grade a no-access baseline that worked until the deadline (#1302)
- make spawn_agent's rejections name what would have worked (#1303)
- load a fixture's own .agents/ again despite the config pin (#1301)
- repair four rotted smoke scripts (#1293)
- subagent-wakes runs the TUIs in your terminal and reads settings from .env (#1289)
- build on Go 1.26.9 and x/net v0.60.0 for the 2026-10-08 advisories (#1285)
- give the dispatcher's copies release tag names (#1213) (#1278)
- keep the bearer table out of agent tools and warn a root ptrace daemon (#1201) (#1267)
- refuse token-less local attach listeners when the agent has bash; read attach tokens from files (#1201) (#1266)
- read top-level $'…' as ANSI-C quoting (#1241) (#1264)
- retry a bare 400 INVALID_ARGUMENT once after a served call (#1247) (#1263)
- LEG=readonly removes the gated-apply grant and proves the daemon cannot patch (#1249) (#1262)
- per-turn guardrail cuts and turn errors are durable, so replay and late attaches show them (#1258) (#1260)
- D4's audit witness reads GKE's serviceAccount: principal (#1042) (#1246)
- the gke-platform-agent content image builds again and carries gated-apply/ (#1042) (#1245)
- a2_count exits 0 on an overcount, matching A2's settled wording (#1042) (#1244)
- a comment's apostrophes no longer decide what the config-pin gate finds (#1209) (#1242)
- a compaction between two soak samples still counts (#1199) (#1231)
- in attach mode, @-inlined file content no longer counts as the operator's task (#1230) (#1233)
- tag the TUI-only perm-mode test !no_tui, and vet the slim build in CI (#1227) (#1232)
- an operator's compaction threshold applies to every recognised model (#1226) (#1229)
- the soak grader owes compaction only on a session's next turn, and trusts the count (#1199) (#1224)
- send no sampling parameters, which Claude Sonnet 5 rejects (#1212) (#1225)
- attach clients and the self-dev rig take the token out of reach (#1201) (#1210)
- subtask and digest calls no longer stand in for the conversation (#1191) (#1204)
- the agent cannot reach the daemon's attach token (#1157) (#1202)
- make core-agent-tui's permission prompts follow /switch, /new and /attach (#1185)
- only a daemon admin's "allow always" reaches beyond the session (#1184)
- keep runtime allow/deny patterns in their own session and make /perms/allow owner-only (#1176) (#1180)
- drop a tools-without-text note once the model has spoken (#1172)
- stop_agent says when the subagent had already finished (#1171)
- keep a subagent's banked return when the run then fails (#1002) (#1154)
- drive the real spawn path in the T1 oracle, and lift the per-turn cap (#1116) (#1153)
- the self-dev scorecard contradicted the recipe it grades (#1116) (#1147)
- every operator line names its session, in a fixed slot (#1137) (#1142)
- instruction text is not a template, and a cut turn promises nothing (#1139, #1140) (#1141)
- a cut line an operator can act on names its session (#1136) (#1138)
- prune the class of dot-directories, not a list of names (#964) (#1135)
- comments name attachadapter.WithPromptBroker, not the gone option (#1103) (#1134)
- a guardrail that cuts a turn says so in the log (#1131) (#1133)
- a pod is what the world says it is, and events render (#1128) (#1129)
- the shim answers from the world, or says it cannot (#1123) (#1126)
- a flag that eats its value, or the verb (#1122) (#1125)
Documentation
- record that new providers are built in go-steer/core-models (#1282)
- keep the seed list out of the worker's tree; mirror-only commit identity (#1213) (#1268)
- design the auto-mode self-development soak on GKE (#1213) (#1240)
- A2 rerun after #1258 — guardrail trips 6=6, turn errors 6=6 on server-side replays (#1042) (#1261)
- A2 fault batch fails on a real gap — per-turn cuts and turn errors are live-only (#1258) (#1259)
- A6 second seed — scenario D on D2 against paymentservice passes all six (#1042) (#1257)
- 2026-10-06 live runs — A3 and A6 evidence, A2 natural batch (#1042) (#1250)
- A1 soak run note 2026-10-03 — box A1 met, compaction exercised (#1042) (#1236)
- check the kube-agents demo scenarios against the go-steer stack (#1214)
- narrow the Stream contract before 3.0 freezes it (#1195)
- design external state stores for session failover (#1190)
- design for an auto permission mode with an approver model (#1175) (#1181)
- the mouse-capture bypass in VS Code is Shift, or Option on macOS, never Alt (#1156)
- name the .agents/ walk-up as a hazard, not just a lookup rule (#1116) (#1146)
- say which doc changes get a CHANGELOG bullet (#1116) (#1148)
- design for pointing core-agent at core-agent (#1116) (#1118)
Other
- split real-provider e2e into provider and model-eval jobs (#1315)
- move the module path to github.com/go-steer/core-agent/v3 (#1312)
- move to ADK v2 (google.golang.org/adk/v2 v2.5.0) (#1291)
- authenticate the real-provider e2e with keyless WIF (#1297)
- assert an expired repeat is not re-prompted by counting prompts, not timing (#1290)
- re-scan main for agent attribution after it lands (#1149) (#1151)
- reject agent attribution in PR commits, titles and bodies (#1149) (#1150)
Other (Cleanup)
- regenerate builtin.go from LiteLLM (2026-10-12) (#1316)
- regen for Claude 5.5 and promote the Anthropic tier defaults (#1280)
- bump the lookout watcher pin to v0.29.0 (#1256)
- bump core-tui v0.30.0 -> v0.30.1 (go-steer/core-tui#364) (#1238)
- migrate off ADK v1.7.0's tool.Context and session.NewEvent deprecations (#1193) (#1228)
- bump the lookout watcher pin to v0.27.0 (#1159)
- bump ADK to v1.7.0 and OpenTelemetry to v1.45 for two advisories (#1194) (#1196)
- bump core-tui v0.28.0 -> v0.28.1 (#1189)
- give the reviewer a budget that can finish a review, and fix the T2 task text (#1170)
- bump core-tui v0.27.0 -> v0.27.1 (#1163)
- bump the lookout watcher pin to v0.26.0 (#1144)
Uncategorized
- Gemini and Anthropic via core-models v0.6.0 (do not merge) (#1296)
[2.10.0-dev.1] — 2026-09-17
61 commits from 2 contributor(s).
Feature
- the apply-capable agent, as a second content root (#1105) (#1110)
- track the gated-apply RBAC as a component (#1105) (#1109)
- mount a server for the tools you want, not all of them (#1100) (#1102)
- believe the server when it says a tool only reads (#1098) (#1099)
- the read-fidelity note reaches every recipe that mounts the tool (#1095) (#1096)
- read fidelity is a property of the tool surface, not a persona (#1016) (#1084)
- the seventh signal reads the answer, not the question (#655) (#1062)
- a skill that re-derives the delegated subject (#966) (#1060)
- a gated prompt nobody is attached to must tell somebody (#647) (#1059)
- ask whether the agent found it, and refuse to answer when the harness did not observe (#652) (#1058)
- a gated call with nobody watching must eventually stop waiting (#647) (#1057)
- an overnight run that breaks the cluster and watches, for hours (#1042) (#1056)
- a guardrail halt is its own event, not a turn's error (#891) (#1047)
- a wake loop that only fails looks idle, so make it say so (#978) (#1044)
- retry a Vertex 429 once, and prove Anthropic already does (#1037)
- the evidence sheet reports what a delegation did (#1032)
- a delegation returns the calls the subagent made (#1031)
- measure delegation shape, and put a rate on #1014 (#1030)
- read a drill run as a trajectory, not just as a score (#1028)
Bug or Regression
- the drill scores the incident it caused, not the next one (#1093) (#1094)
- a no-op streak costs the turn, not the session (#1090) (#1091)
- a prompt cut down with its turn is gone, not unheard-of (#1088) (#1089)
- the gate's cut takes the repetition off the watchdog's books (#1086) (#1087)
- the gate ends a turn the operator already answered (#1081) (#1085)
- a refused call cannot re-open the same prompt for the rest of the turn (#1074) (#1080)
- a prompt too small to cache will not grow on retry (#1067) (#1073)
- a pump's start cursor belongs to the pump, not to the broadcaster (#1075) (#1076)
- a refusal has to say the answer will not change (#1068) (#1072)
- a retry tick is not a boot (#1066) (#1071)
- --token takes an env var NAME, so call it --token-env (#947) (#1064)
- one event, one transaction (#976) (#1063)
- a tool result can overflow the window before the turn ends (#975) (#1055)
- compaction must survive an uncatalogued model and a dead summarizer (#974) (#1054)
- a delegation that delivered nothing must be disclosed if the parent absorbs it (#1036) (#1052)
- a 429 burst needs a retry budget, and every retry needs an outcome (#1039) (#1051)
- a per-turn cost ceiling should bound a turn, not the session (#1049) (#1050)
- one interruption gets one continuation, across daemons (#977) (#1046)
- one damaged run should not take the archive with it (#1045)
- a halted session goes inert instead of waking to be refused (#1040) (#1043)
- stop the GA fold from dying on its own diff preview (#1027)
Documentation
- the RBAC boundary is confirmed, not inferred (#1105) (#1108)
- the RBAC subject question is answered — yes (#1105) (#1107)
- record the scope decisions and the partial RBAC probe (#1105) (#1106)
- design for letting the GKE agent apply the fix it found (#1042) (#1104)
- record run 17 — the gated daemon absorbs a denial and keeps working (#1090) (#1092)
- the approval-gate rig's own finding — the sentence was delivered and the loop continued (#1074) (#1079)
- the A1 soak run note — three of four questions, and the fourth was never asked (#1042) (#1070)
- give #1045's bullet its own body back (#1048)
- genai has no retry; anthropic-sdk-go does (#1038)
Other
- the approval-gate rig reports the model's calls, not just the operator's prompts (#1081) (#1082)
- wait for a failure to be recorded, not for an RPC to be sent (#1077) (#1078)
- a daemon that runs gated, on a cluster, graded by a receiver (#647) (#1069)
- the pre-turn pipeline is data, not statement order (#659) (#1065)
- 21 runs on the #935 fix, and the one that still died is our own cooldown (#1041)
- 20 more runs, and the #1014 rate was two findings in a trench coat (#1035)
- three signed sheets re-measuring #1014 against #1031 (#1033)
Other (Cleanup)
- regenerate builtin.go from LiteLLM (2026-09-17) (#1111)
- bump grpc to v1.83.1 to clear GO-2026-6348 (#1101)
- bump the lookout watcher pin to v0.25.0 (#1083)
- move the deployable recipes onto the 2.9.0 GA image (#1026)
- bump Version fallback to v2.10.0-dev (571bac3)
Contributors
- Gari Singh
- go-steer-bot[bot]
Install
Pre-built binary (this Release)
TAG=v3.0.0-dev.1
OS=$(uname -s | tr A-Z a-z) # linux | darwin
ARCH=$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/')
gh release download "$TAG" \
--repo go-steer/core-agent \
--pattern "core-agent_3.0.0-dev.1_${OS}_${ARCH}.tar.gz"
tar xzf "core-agent_3.0.0-dev.1_${OS}_${ARCH}.tar.gz"
./core-agent --versionThe same pattern works for core-agent-tui_3.0.0-dev.1_${OS}_${ARCH}.tar.gz.
go install
go install github.com/go-steer/core-agent/v3/cmd/core-agent@v3.0.0-dev.1Container images
docker pull ghcr.io/go-steer/core-agent:3.0.0-dev.1 # full build, in-process TUI included
docker pull ghcr.io/go-steer/core-agent-slim:3.0.0-dev.1 # headless variant, ~5MB smaller
docker pull ghcr.io/go-steer/core-agent-tui:3.0.0-dev.1 # remote TUI client onlyVerify (Sigstore keyless)
Binaries — the checksum file signs every archive transitively:
gh release download "v3.0.0-dev.1" --repo go-steer/core-agent \
--pattern checksums.txt --pattern 'checksums.txt.*'
cosign verify-blob \
--signature checksums.txt.sig --certificate checksums.txt.pem \
--certificate-identity-regexp '^https://github.com/go-steer/core-agent' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
checksums.txt
sha256sum -c checksums.txt --ignore-missingContainer images:
cosign verify ghcr.io/go-steer/core-agent:3.0.0-dev.1 \
--certificate-identity-regexp '^https://github.com/go-steer/core-agent' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com