Goose Capability Assessment for SolOS
Goose Capability Assessment for SolOS
Date: 2026-10-06 · Subject: aaif-goose/goose (formerly block/goose) v1.53.0 · For: Young, SolOS
Method: every capability claim below is traced to a URL actually fetched. Repo-star counts and issue text come from the GitHub API at time of writing. Anything not confirmed by a fetched page is marked UNVERIFIED.
Headline verdict
REJECT as a stack replacement. ADOPT-SELECTIVELY as one execution-lane tool, behind the existing orchestrator, on the Heart host only.
Goose is a single-agent runtime with good automation ergonomics. SolOS is a fleet with a control plane. Goose duplicates the execution layer and provides nothing for the plane Young actually built: no brain/heart separation, no A2A mesh, no state-machine task queue, no evidence gate, no content-level watchdog. Everything it does offer in the orchestration direction is strictly worse than what exists, and its security posture (default-autonomous shell, no sandbox, subagents that bypass the parent's approval mode and policy hooks) is a direct regression against SolOS's read-only allow-list discipline.
The one place it genuinely adds something is the MCP client surface + goose run --output-format json as a cheap, disposable worker for narrow, well-specified Heart-lane chores. That is an addition, not a migration.
1. Core capabilities: desktop, CLI, headless, and is there a real automation API?
All three surfaces exist and are first-class.[1][3]8
| Surface | Entry point | Documented? |
|---|---|---|
| Desktop app (macOS/Linux/Windows, Electron) | download .deb/.zip, brew install --cask block-goose | yes3 |
| CLI | curl -fsSL .../download_cli.sh | bash, brew install block-goose-cli | yes3 |
| Headless / non-interactive | goose run -t "...", goose run -i instructions.md, --no-session, --quiet | yes[9]10 |
| HTTP/WebSocket server | goose serve --host --port --tls (ACP endpoint at /acp) | yes[8][11]13 |
| stdio server | goose acp | yes8 |
| Provider-only SDK | goose-sdk crate / pip install goose-sdk / Kotlin io.github.aaif-goose:gdk | yes14 |
Yes — there is a stable programmatic surface, but it is ACP, not a bespoke REST API. goose serve speaks the Agent Client Protocol over HTTP+WebSocket with X-Secret-Key auth, 401 on bad secret, /status for liveness, TLS via --tls with GOOSED_CERT_FINGERPRINT pinning.[11]13 That is a real, authenticated, automation-grade server. For CI/batch, the intended surface is simpler still: goose run with --output-format json or --output-format stream-json for structured output, --provider/--model per-invocation overrides, --max-turns, and --max-tool-repetitions as a loop breaker.8
The official site advertises "Desktop app, CLI, and API"1, and the GDK docs describe two integration routes: ACP to the running agent, or the SDK as an in-process provider layer.12 What does not exist is a stable REST task-queue API. The only REST-ish surface is ACP, which is an editor-oriented session protocol (session/new, session/prompt, session/load), not a durable job API with state transitions. Grepping all 173 fetched doc pages for REST/OpenAPI/endpoint language produced no task API — UNVERIFIED that any exists.
Also worth knowing: goose can use external ACP agents (Claude Code, Codex) as providers, handing them its extensions as MCP servers — i.e. goose can be a client of the very tooling SolOS already runs.[37]34
Two caveats that matter for unattended use:
- Keyring blocks unattended runs. Docs warn the system keyring can hang forever with no user present; the fix is
GOOSE_DISABLE_KEYRING=1plus env-var credentials.8 SolOS would have to set this on every worker. - The SDK is explicitly alpha: "The SDK is in alpha. The surface may change between
0.xreleases. Pin an exact version."14 Do not build SolOS's brain on it.
2. Extensions (MCP): first-class, and the strongest part of goose
MCP is not a bolt-on; it is the extension substrate. The architecture doc states goose "utilizes MCP to connect to MCP systems/servers. In goose, these systems/servers are referred to as extensions."34
- Count: the docs ship 71 MCP extension pages (
documentation/docs/mcp/*.md), and both the official site and the README advertise "70+ MCP extensions."[2][1]5 - Install paths: interactive
goose configure→ Add Extension (built-in, stdio, streamable-HTTP); one-shotgoose mcp <name>; per-invocation--with-extension,--with-streamable-http-extension,--with-builtin; Desktop GUI; or a central extensions directory.[5]8 - Built-in
developerextension (enabled by default):shell,write,edit,tree,read_image— docs rateshell/write/editas ⚠️ High risk ("Can run any system command with your user privileges" / "Can modify any accessible file"),tree/read_imageas ✅ Low, read-only.29 - Other built-ins: Memory, Tutorial, Auto Visualiser, Computer Controller; plus toggleable platform extensions — Analyze, Apps, Chat Recall, Code Mode, Extension Manager, Skills, Summon, Todo, Top of-Mind.5 Analyze is a dedicated code-structure/call-graph tool38, and Summon is the
delegate/loadentry point that subagents ride on.15 - Governance lever:
GOOSE_ALLOWLISTpoints at a YAML file of permitted extension install commands; anything not listed is refused at install time.30 This is the one admin control SolOS would genuinely want that goose has.
Note for the record: goose's own AGENTS.md says the project is retiring its own MCP directory in favour of the official MCP Registry — i.e. the "70+ extensions" figure is a docs catalogue, not a supported, versioned artefact set. Any single extension breaking on a goose release is an expected, recurring maintenance cost.
3. Sessions and durable memory
Storage. Local-first, on disk, single file: ~/.local/share/goose/sessions/sessions.db, a SQLite DB.24 Docs note "Starting with version 1.10.0, goose uses a SQLite database (sessions.db) instead of individual .jsonl files," and legacy .jsonl files are left behind unmanaged.25 Linux footprint is ~/.local/share/goose/ (data), ~/.local/state/goose/ (logs), ~/.config/goose/ (config), system keyring for secrets.33
Same DB across surfaces: "Sessions created in goose Desktop can be resumed in the CLI and vice versa. All sessions are stored in the same database."25 Sessions are exportable as JSON/YAML/markdown and re-importable.8
Durable memory across sessions: yes, but it is an optional built-in extension, not the core. The Memory extension stores memories as files on disk: project-scoped at .goose/memory/, global at ~/.config/goose/memory/, with tools remember_memory, retrieve_memories, remove_memory_category, remove_specific_memory. Critically: "goose loads all saved memories at the start of a session and includes them in every prompt sent to the LLM."20 So memory is local, plain-text, user-editable, git-committable — genuinely local-first — but it is not selective retrieval; everything is shoved into every prompt. That is a token-cost and context-pollution liability for any persona with real state, and it is exactly the thing SolOS's memories/MEMORY.md already does better (curated, agent-specific).
Context management. Auto-compaction at 80% of token limit by default (GOOSE_AUTO_COMPACT_THRESHOLD), with summarize/truncate/clear/prompt strategies (GOOSE_CONTEXT_STRATEGY); headless goose run auto-summarizes.26 Compaction is lossy summarization — a risk if you are relying on conversation state as a system of record.
4. Recipes: versionable, shareable, and genuinely good
Recipes are the most reusable primitive goose has, and they are the closest thing to SolOS's agent personas.
- Format: YAML or JSON; CLI accepts only
.yaml/.json(Desktop also takes.yml).23 - Storage: global
~/.config/goose/recipes/; project-local<cwd>/.goose/recipes/; plus an optional GitHub repo (GOOSE_RECIPE_GITHUB_REPO: "owner/repo") that goose pulls from when a name isn't found locally.22 - Versioning: the schema has a required-ish
versionfield defaulting to1.0.0.21 - Sharing:
goose recipe deeplink <file>generates a shareable link; Desktop import via link or file; recipient gets their own private session with "No data is shared between users."22 - Richness:
parameterswith typed inputs (string/number/boolean/date/file/select),{{ var }}templating,extensionsblock pinning exactly which MCP servers a recipe may use (incl.available_toolsallow-list),settings.goose_provider/goose_model/temperature/max_turns, and aretryblock withchecks: [{type: shell, command: ...}]that must exit 0 for success, pluson_failurecleanup.21 - Validation:
goose recipe validate <file>,goose recipe list --format json,goose recipe open.8
The retry.checks shell-exit-code gate is the single most interesting thing here for SolOS: it is goose's one built-in "did the work actually succeed" assertion. It is far weaker than SolOS's gate (it proves a command exited 0, not that content is correct), but it is a real, declarative verification primitive.
5. Subagents / multi-agent: real, but shallow, and with open security holes
Yes, subagents exist and are first-class enough to have a dedicated tool (delegate/load, provided by the summon platform extension, enabled by default), custom-agent files, and a tutorial.[15]16
Documented limits:
- Sequential (default) or parallel; the model decides based on trigger keywords like "parallel" / "simultaneously".15
- Autonomous spawning — goose may spawn subagents without being asked — but only in autonomous permission mode. "Subagents are disabled in manual approval, smart approval, and chat-only modes."15
- Defaults: max 25 turns (
GOOSE_SUBAGENT_MAX_TURNS), 5-minute timeout, extensions inherited from parent.15 Confirmed in source:DEFAULT_SUBAGENT_MAX_TURNS: usize = 25.45 The child's system prompt states the role boundary in prose — "Bounded Operation: Operate within defined limits (turn count, timeout)" and "Security: Cannot spawn additional subagents" — so the recursion guard is partly prompt-level.46 - Failure semantics: "If a subagent fails or times out (5-minute default), you will receive no output from that subagent. For parallel execution, if any subagent fails, you get results only from the successful ones."15 That is silent partial failure — the exact failure mode SolOS's "an empty result is an error" discipline was built to kill.
- Hard restrictions on subagents: cannot spawn further subagents (no recursion), cannot modify extensions, cannot touch schedules.15
- No distributed multi-agent. There is no A2A, no peer mesh, no cross-host agent federation. Zero
a2a/agent2agentreferences in the repo tree; multi-agent roadmap items are closed issues (#7238 "CLI-via-Goosed unified agent architecture", #7757) — UNVERIFIED whether the closed work shipped. - External subagents can be wrapped by running another agent CLI as an MCP server (documented with Codex
mcp-serverconfig).15 - Roaming agents (p2p ACP over iroh/QUIC) are real but experimental and not in released binaries — "not included in released goose binaries. Every command in this guide requires a goose built from source with the
roamingfeature enabled."36 Reject for production use.
Three open issues make goose's subagent layer unsafe to trust as a control point today:
- #11778 (open): "A subagent created by the Summon extension does not preserve an approval-requiring mode from its parent session. The child runs in automatic mode… This lets subagent tool calls bypass the approval policy selected for the parent."51
- #12650 (open): "
PreToolUsehooks don't run for tool calls made by a subagent created through Summon (delegate)… A command the hook denies when the parent calls it runs unchanged when a subagent calls it. So aPreToolUsehook can't serve as a policy gate while Summon is enabled."52 - #11999 (open): default 25-turn subagent budget causes spurious subagent failure; the parent then "decided to kill them and give up."54
A fix for the approval-mode inheritance shipped in v1.53.0-adjacent work (#12654, fix: subagents meet the parent's approval mode and tool hooks) — UNVERIFIED whether it is released; the two issues above were still open when fetched.
6. Providers and models: excellent breadth, includes your exact provider
The providers page lists 45+ provider rows including Anthropic, OpenAI, Google/Gemini, Vertex, Bedrock, Azure OpenAI, Azure AI Foundry, OpenRouter, Ollama, Ollama Cloud, LM Studio, Ramalama, Docker Model Runner, Atomic Chat, Groq, Cerebras, Together, DeepSeek, Mistral, xAI, Perplexity, Scaleway, Databricks, Snowflake, VMware Tanzu, GitHub Copilot, ChatGPT Codex, Marama, Novita, and ~15 more.4 The repo ships 48 declarative provider JSON definitions.43
Local models: yes and first-class. Ollama, LM Studio, Ramalama, Docker Model Runner, Atomic Chat, plus a goose local-models subcommand that searches Hugging Face for GGUF/MLX models and downloads them (search/download/list/delete) — build-gated behind the local-inference Cargo feature.[8]42
BYO key: yes. Custom providers are declarative: OpenAI-, Anthropic-, or Ollama-compatible, with custom headers, and credentials from a refreshable command (for IdP-issued short-lived tokens) rather than a static key.4
Free/cheap tiers: documented but marginal. "Using goose for Free" section names Groq (kimi-k2-instruct, qwen3-32b, llama-3.3-70b, llama-3.1-8b-instant) and Gemini's free tier, with an explicit caveat: "you may need to upgrade your LLM for better performance."4
The directly relevant finding: goose ships opencode_go.json. A first-class provider definition for OpenCode Go — https://opencode.ai/zen/go/v1, OpenAI-compatible, OPENCODE_API_KEY, dynamic model catalog, thinking preserved, 13 listed models (kimi-k2.5/2.6, deepseek-v4-flash/pro, glm-5/5.1, minimax-m2.5/2.7, qwen3.5/3.6-plus, mimo-v2.x).44 SolOS's existing free-tier model source is therefore a native goose provider, not something requiring a bridge. opencode_zen.json also exists.43
Per-session / per-extension pinning: yes, at four levels.
--provider/--modelflags override per invocation.8GOOSE_PROVIDER/GOOSE_MODELenv vars do the same per process.7- Recipe
settings.goose_provider/goose_modelpin per recipe.21 - Custom-agent frontmatter
model:pins per agent.17
Subagents additionally read GOOSE_SUBAGENT_MODEL and GOOSE_SUBAGENT_PROVIDER, with recipe settings taking precedence over both.15
7. Permissions and safety: the weakest area, and a regression risk for SolOS
Four permission modes: Completely Autonomous, Manual Approval, Smart Approval, Chat Only (GOOSE_MODE = auto/approve/smart_approve/chat).27
Tool-level allow-lists: per-tool Always Allow / Ask Before / Never Allow, configurable via goose configure or Desktop settings, stored in permission.yaml + auto-managed permissions/tool_permissions.json.[28]6
The problems, from the vendor's own text:
- Default is full autonomy with no approval. "Autonomous Mode is applied by default."27 "By default, goose can run system commands with your user privileges and edit any accessible file without your approval."29
- Granularity is per-tool, not per-command.
shellis one tool. There is no regex allow-list — that is an open feature request (#11399), and its own description concedes: "Ask Beforeon the shell tool: prompts for every command, including trivially safe ones likegit status… nothing stops agit push, arm -rfvariant, or a destructivedockercommand that the classifier happens to consider read-only."55 This is structurally weaker than SolOS's per-agent permission allow-lists. - Read/write classification is LLM-judged. "Read/write approval makes best effort attempt at classifying read or write tools. This is interpreted by your LLM provider."27 Non-deterministic enforcement.
- No sandbox on the shell tool. Open security issue #12566: "The developer extension's
shelltool… passes the LLM-supplied command string verbatim to the host shell… with no allowlist, sandbox, or content validation. The permission gate's default modeGooseMode::AutoreturnsAllowunconditionally for every tool call."50 - Sandbox bypass under ACP. #12513: "Shell tool → always delegated to the client… The client (e.g. Zed) spawns that terminal as its own child, outside any sandbox the user may have placed around the goose process (bubblewrap, distrobox, manual
sandbox-exec)."53 - There is no
.gooseignore/filesystem deny-list. Issue #9118 "Filesystem read deny-list for sandbox (.gooseignore)" is closed — I could not verify whether it shipped or was dropped. UNVERIFIED. - What does exist:
GOOSE_ALLOWLISTfor extension installs30; optional prompt-injection detection (SECURITY_PROMPT_ENABLED, plus an ML classifier endpoint — disabled by default)6; pluginPreToolUse/Stophooks that can hard-deny a tool call, withon_failure: blockfail-closed semantics31.
The hooks system is the one genuinely promising safety primitive — a PreToolUse hook with matcher: "^shell$" and on_failure: block is a deterministic gate. But per #12650, that gate does not currently see subagent tool calls.52
Lockdown verdict: partially possible, not sufficient. Chat-only mode + Never Allow on shell/write/edit gives a genuine read-only mode equivalent to SolOS's diagnostics posture. But there is no per-command allow-list, no filesystem deny-list, and no sandbox, so a read-only goose still has whatever the filesystem user can read — including all SolOS config, secrets, and the queue DB. SolOS's allow-list discipline has no goose equivalent.
8. Project context: .goosehints / AGENTS.md — good, and it beats nothing you have
- Two files: global
~/.config/goose/.goosehints(all sessions) and local.goosehints(working directory and subdirectories). Precedence is explicit: "If the instructions in your local hints file conflict with your global preferences, goose will prioritize the local hints."18 AGENTS.mdis supported natively. "By default, goose looks for bothAGENTS.mdand.goosehintsat each level," and nested loading walks from cwd up to the repo root, then discovers more as it reads into subdirectories.18- Overridable:
CONTEXT_FILE_NAMEStakes a JSON array —["CLAUDE.md", ".goosehints", "project_rules.txt"]— with identical nested-loading semantics.18 - Loaded into the system prompt on every request (token cost scales with file size), and requires the Developer extension to be enabled.18
- Stronger sibling feature — persistent instructions.
GOOSE_MOIM_MESSAGE_TEXT/GOOSE_MOIM_MESSAGE_FILEare re-read and re-injected every single turn via MOIM (Model-Observed Internal Memory), so they cannot be forgotten as context grows, and changes apply without restarting the session. Capped at 64 KB. Docs pitch it squarely at guardrails: "Do not upload, share, or transmit internal code or data to any external service."19 This is a better enforcement mechanism than a static hints file, and is the feature most directly analogous to SolOS's persona/permission enforcement.
9. Install footprint and runtime deps
No Docker required, no Rust build required. Install is a prebuilt binary via download_cli.sh or Homebrew3; Desktop is a .deb/.zip/cask.
Footprint on a Linux host is large. From the v1.53.0 release assets: goose-x86_64-unknown-linux-gnu.tar.gz = 94.6 MB compressed, .tar.bz2 = 84.1 MB; musl static build 44.7–51.1 MB; the .deb = 170.3 MB installed; the desktop Goose.zip = 212.9 MB; Flatpak ~159 MB.49 Plus ~/.local/share/goose/, ~/.local/state/goose/, ~/.config/goose/, and a keyring entry.
Optional local inference is where it gets heavy: the local-inference Cargo feature pulls candle-core/candle-nn/candle-transformers/tokenizers, with cuda, vulkan, and mlx variants — that is why the release ships -cuda and -vulkan binaries.[42]49
Docker: supported but explicitly for isolation/consistency debugging — the Dockerfile is a starting point you must edit for credentials, and "the keyring settings do not work on Ubuntu in Docker."35 Also goose session --container <id> runs extensions inside an existing container.8 So Docker is an isolation option, not a dependency. Note the flip side: isolation is an opt-in you must configure, not a default — unlike a containerised SolOS Heart host.
Runtime coupling: one static Rust binary. No Node/Python runtime needed unless you enable MCP extensions that shell out to npx/uvx.
10. Maturity and activity
Very active, and that is a double-edged sword.
- 55.0k stars, 6.4k forks, 437 open issues, Apache-2.0, last push 2026-10-06.47 (The 43.4k figure in the block/goose README is a stale mirror; the site's "45k+" is also conservative.1)
- Release cadence: roughly weekly minor. v1.43.0 (2026-07-14) → v1.53.0 (2026-10-02), 11 minors in under 3 months.48
RELEASE.mdconfirms automation: "Minor version releases… are typically done once per week," with a Tuesday version-bump cron.41 - Main branch is extremely hot — commits on 2026-10-05 alone include "Foreground subagents in the state machine loop (#12632)" and "Resolve extensions into a per-inference lease (#12161)".47 Active rework of the agent loop and subagent execution is in flight right now.
- Production-ready? No — not for unattended multi-agent use. Six concrete reasons.
- Subagent approval-mode bypass (#11778) and hook bypass (#12650) are both open.[51]52
- The shell tool has no sandbox or allow-list, reported as security issue #12566.50
- ACP delegates shell to the client, escaping sandboxes (#12513).53
- Subagent failures are silent (#11999).54
- Recipe metadata drift can hard-fail session load — #10113 documents
loadSessionfailing on an invalid stored recipe ("Unnecessary parameter definitions: pr.")56 - The docs themselves acknowledge instability: "In rare cases, goose may enter a 'doom spiral' or become unresponsive during a long session. This is often resolved by ending the current session."33
- Breaking-change surface is real. Sessions moved
.jsonl→ SQLite at v1.10.0.25 Desktop installs still reference theblock-goosecask, and Windows data lives at%APPDATA%\Block\goose\.[3]33
The repo is also mid-rename fromblock/goosetoaaif-goose/goose, with the README still saying "Some links and references are still being updated — please bear with us during the transition."1 Two adjacent repos exist — theopencode_go.jsonprovider44 and the goose-recipes repo referenced asaaif-goose/goose-recipes6 — but their long-term governance is UNVERIFIED. - Docs-site stability:
block.github.io/docs/*now 404s ("Looking for goose? It's moved to goose-docs.ai"), and the AAIF migration blog URL in the README is dead (404). Live canonical docs aregoose-docs.ai; everything I cite is from the repo's owndocumentation/docs/markdown onmain, which is the source of truth the site builds from.[1]59
11. Licensing and governance
- License: Apache License 2.0, verbatim in the repo
LICENSE.40 GOVERNANCE.md: "All outbound code and specifications will be made available under the Project License"; "All documentation (excluding specifications) will be made available under the Creative Commons Attribution 4.0 International license."39 GitHub API reportsApache-2.0.47 - Governance: maintainer-based with a documented escalation path — Maintainers → Core Maintainers (target 3–7, odd number) → simple majority vote; "In the event of a decision deadlock… goose's creator, Bradley Axen, steps in as a tie breaker."39 Merit-based, no CLA, "no contributor or copyright holder will be required to assign copyrights."39
- Ownership: "Founded by Block and now stewarded by AAIF (Agentic AI Foundation), goose has been established as a Series of LF Projects, LLC. Policies applicable to goose and participants in the goose project, including guidelines on the usage of trademarks, are located at https://lfprojects.org/policies/."[39] AAIF's project list confirms goose as an AAIF project alongside MCP, AGENTS.md, agentgateway, and Agent2Agent.58
- Redistribution: Apache-2.0 permits it, with the standard NOTICE/attribution obligations. No trademark grant is present in the repo. Trademark usage is governed by LF Projects policy, and AAIF itself notes "The Linux Foundation has registered trademarks and uses trademarks" with terms on its policies page.58 Practical read: you may redistribute and self-host goose freely; you may not imply AAIF/Block endorsement, and rebrand "goose" in a wrapper without checking LF trademark policy. Given the duck in the logo and the "goose" name, this is worth a 5-minute check with Young before any SolOS-branded surface calls itself goose-derived. The specific LF trademark clause text is UNVERIFIED — I did not fetch lfprojects.org/policies.
TABLE 1 — Goose capability → does SolOS have it → real value or duplicate?
| # | Goose capability | SolOS equivalent | Verdict |
|---|---|---|---|
| 1 | Desktop GUI (Electron, 3 OSes)3 | None | Irrelevant — SolOS is headless-by-design |
| 2 | Interactive CLI session (goose session)8 | Heart agents via OpenCode v2 | Duplicate, and a downgrade (no OpenCode v2 primitives) |
| 3 | Headless goose run + --output-format json[8][9]10 | Heart A2A JSON-RPC over loopback | Thin real value — cheapest possible worker adapter |
| 4 | ACP HTTP/WS server (goose serve, secret auth, TLS pinning)[11]13 | A2A JSON-RPC + SSH tunnels | Duplicate, worse fit — editor-session protocol, not job API |
| 5 | Provider-only SDK (Rust/Python/Kotlin)14 | Hermes framework internals | Reject — alpha, and Hermes already provides this |
| 6 | 70+ MCP extensions, one-command install5 | Hermes/OpenCode MCP tools | Genuine value — biggest single breadth win |
| 7 | Built-in developer ext (shell/write/edit/tree/read_image)29 | OpenCode v2 agent tools | Duplicate — and weaker safety |
| 8 | Extension allow-list (GOOSE_ALLOWLIST)30 | Per-agent permission allow-lists (code-enforced) | Duplicate — yours is stronger (code vs config) |
| 9 | SQLite session store, cross-surface resume25 | sqlite task queue (state machine) | Duplicate, worse — no state machine, no gate |
| 10 | Memory extension, local files, all-injected20 | memories/MEMORY.md + USER.md | Duplicate — yours is curated & per-agent; goose injects everything |
| 11 | Auto-compaction / context strategies26 | Hermes context management | Duplicate |
| 12 | Recipes: YAML/JSON, versioned, GitHub-shareable, params, settings.model[21]22 | SOUL.md personas + prompt templates | Near-duplicate, but recipes are strictly more executable |
| 13 | retry.checks shell-exit-0 gate inside a recipe21 | gate service closing working→verified→completed | Thin real value — declarative local verification; much weaker than gate |
| 14 | Subagents (sequential/parallel, custom agents)[15]16 | Whole Heart plane + Brain/Heart boundary | Duplicate and dangerous — no separation, silent partial failure, approval bypass |
| 15 | Subagent defaults: 25 turns, 5 min timeout[15]45 | Per-agent turn/budget discipline | Duplicate, worse — #11999 shows the cap bites |
| 16 | External subagents (Codex-as-MCP-server)15 | OpenCode v2 Heart agents over A2A | Duplicate |
| 17 | Roaming p2p agents (experimental, not in releases)36 | SSH-tunneled loopback A2A | Reject — source-build only, experimental |
| 18 | ~45 providers + 48 declarative definitions[4]43 | opencode-go free tier | Real value — opencode_go.json ships natively44 |
| 19 | Local inference (Ollama/LM Studio/Ramalama/Docker Model Runner)[4]8 | Not currently used | Optional value — only if SolOS ever needs data residency |
| 20 | BYO key + declarative custom providers + refreshable creds4 | opencode-go key | Marginal value — nice, not needed |
| 21 | Per-session/per-recipe/per-agent model pinning[8][21]17 | Per-agent persona config | Duplicate — you already pin per agent |
| 22 | 4 permission modes + per-tool allow/ask/deny[27]28 | Persona/permission enforcement, read-only allow-lists | Duplicate and a regression — see §7 |
| 23 | Plugin PreToolUse/Stop hooks, fail-closed31 | External watchdog + gate | Thin real value — but bypassed by subagents (#12650) |
| 24 | Prompt-injection detection (opt-in)6 | Not present in SolOS | Genuine gap-filler, low priority |
| 25 | .goosehints + AGENTS.md, local-wins precedence18 | SOUL.md + USER.md | Duplicate |
| 26 | MOIM persistent instructions, re-injected every turn19 | Persona enforcement | Mild real value — strongest enforcement primitive goose has |
| 27 | goose schedule (cron → recipe)8 | State-machine queue + scheduler | Duplicate, worse — no states, no gate |
| 28 | goose review with .agents/checks/*.md8 | Not present | Marginal value |
| 29 | Weekly releases, 55k stars, 4.3k commits[47][48]41 | n/a | Value (well-maintained) and cost (weekly churn) |
| 30 | Apache-2.0 + LF stewardship[39][40]47 | n/a | Value — no licence or lock-in risk |
| 31 | 94 MB binary, 170 MB .deb, optional CUDA/Vulkan builds[49]42 | Host already carries OpenCode | Cost, no offsetting benefit |
TABLE 2 — SolOS capability → would Goose cover it? → integration/maintenance cost
| SolOS subsystem | Goose equivalent | Gap / cost to bridge |
|---|---|---|
| Brain plane (min/mira/sol, Hermes, SOUL.md+MEMORY.md+USER.md) | Provider-only SDK (alpha)14 | No coverage. Goose has no decision-agent concept. Bridging = reimplementing Hermes; do not. |
| Hard Brain-does-not-execute boundary (enforced in orchestrator code) | Nothing | No coverage, and goose actively fights it. Goose's whole model is "spawn subagents and let them execute"; subagents inherit the parent's extensions15 and today bypass its approval mode51. Adopting goose as a decision agent removes the guarantee that makes SolOS safe. |
| Heart plane (ace/alpha/atlas/nova/echo on OpenCode v2, separate host) | goose run headless[8]9 | Partial. Goose can be one more worker type behind the existing dispatcher. Cost: new agent adapter in the orchestrator, per-agent goose config dirs, GOOSE_DISABLE_KEYRING=1, provider pinning, and a JSON-output parser contract. ~1 adapter + a watchdog probe. |
| A2A JSON-RPC over loopback + SSH tunnels | ACP over HTTP/WS[11]13 | Poor fit. ACP has no SolOS-equivalent method for working→verified→completed, no evidence field, no idempotency key. Bridging = writing a translation layer that fabricates the state machine outside goose. High cost, no gain. |
| State-machine queue (submitted→working→verified→completed, holds/uncertain/failed, sqlite) | Session list + resume[8]25; goose schedule8 | No coverage. Goose has no task states and no holds. Bridging means SolOS keeps its queue and treats goose as a pure function call — which is the right answer anyway. |
gate service (closes working→verified→completed) | retry.checks shell exit-021 | Weak coverage. Exit-code ≠ content. Use goose's check only for "did the command run", never as the gate. Gate stays SolOS's. |
| Evidence-before-complete / "empty result is an error" | Silent partial subagent failure15; exit codes8 | No coverage — goose actively violates it. Any goose-involving path must have an independent SolOS-side evidence assertion. |
| External watchdog asserting CONTENT not status | goose info/diagnostics, hooks31 | No coverage. Goose gives health, not content assertions. Watchdog probes must target goose's JSON output, not goose. |
| Per-agent persona/permission enforcement (v1→v2 OpenCode schema migration) | 4 modes + per-tool perms[27]28 | Partial but weaker. No per-command allow-list — #11399 is still open.55 No sandbox (#12566).50 Read/write classification is LLM-judged.27 Bridging means wrapping goose in a container/jail, which goose does not do for you. |
| Free/open models only, cost discipline | opencode_go provider44; Groq/Gemini free tiers4; GOOSE_CLI_SHOW_COST6 | Full coverage + improvement. Same provider, and goose has an explicit cost-display switch. This is the cleanest fit in the whole assessment. |
| Vendor-neutrality / no lock-in | Apache-2.0, LF Projects, ACP[13][39]40 | Full coverage. Config, recipes, agents, sessions are all local files. No exit cost. |
VERDICT PER SUBSYSTEM
| Subsystem | Verdict | Reasoning |
|---|---|---|
| Brain plane (min/mira/sol) | REJECT | Goose has no decision/execution separation and one actively defeats it: subagents bypass the parent's approval mode51 and its policy hooks52. The Brain plane is the highest-value asset in SolOS; putting goose anywhere near it trades a guaranteed invariant for a nicer CLI. |
| Heart plane | ADOPT-SELECTIVELY (narrow) | goose run --output-format json with --provider/--model/--max-turns/--no-session is a genuinely cheap, well-documented, auth-able worker for narrow Heart chores. It is an additional worker type behind the existing dispatcher, never a replacement for OpenCode v2 agents. Cap it at one or two agent personas. |
| Task queue / state machine | REJECT (do not touch) | Zero goose coverage. Keep sqlite + the state machine. Goose sessions are conversation history, not job records. |
gate / evidence discipline | REJECT (do not touch) | goose's retry.checks proves a command exited 0, nothing more. Substituting it for the gate would be a straight downgrade of the fleet's core reliability property. |
| Watchdog / content assertions | REJECT (do not touch) | No goose equivalent. Any new worker needs a SolOS-side probe asserting content. |
| A2A transport | REJECT | ACP is an editor session protocol; bridging it to SolOS's job semantics means writing the state machine twice, in the wrong place. |
| Provider / model layer | ADOPT (if you take anything) | opencode_go.json ships in goose as a native provider44 — SolOS's free-tier model source is already a first-class goose provider. Zero marginal model-routing work, zero cost regression, and GOOSE_CLI_SHOW_COST gives Young a cost readout6. |
| MCP tool surface | ADOPT-SELECTIVELY | 70+ extensions5 is the one place goose is strictly broader than what I know of SolOS. But it must be pinned: goose is retiring its own directory for the MCP Registry, and GOOSE_ALLOWLIST30 should be set to a SolOS-controlled list rather than "anything on npm". |
| Permission / safety layer | REJECT | Default-autonomous shell with no sandbox[29]50 and no per-command allow-list55, vs SolOS's code-enforced read-only allow-lists. This is a security regression, not a wash. |
| Persona / project context | REJECT | SolOS's SOUL.md/MEMORY.md/USER.md is more curated and more per-agent than .goosehints18 or the all-injected Memory extension20. |
| Subagent / multi-agent orchestration | REJECT | SolOS's Heart plane is the multi-agent system, with the boundary that matters. Goose's version is shallower, silently drops failed subagents,15 and carries three open correctness/security bugs in that exact layer: approval bypass (#11778),51 hook bypass (#12650),52 and default-turn starvation (#11999).54 |
| Goose-as-a-whole replacement | REJECT | ~85% of goose's feature surface maps to something SolOS already has; the remaining ~15% is either an operational hazard (permissions, subagents) or already covered by your model provider. |
The 3 highest-value things goose could actually do
- A fifth-class worker type for narrow, bounded Heart chores —
goose run --with-builtin developer -t "..." --output-format json --max-turns 8 --no-session, pinned toopencode_go, behind the existing orchestrator, withGOOSE_MODE=approveorsmart_approve. Bounded, content-asserted by your existing watchdog, never trusted with a brain task. - A free MCP tool surface at zero model cost — the 70+ extensions5 run as ordinary tool servers. Bolting one (e.g. a docs/fetch/search extension) onto one sandboxed Heart agent gives Young capabilities the fleet lacks, without adding a model, a licence, or a vendor.
- Declarative verification and scheduling primitives for new work, not existing work —
recipe.retry.checks+goose schedule+goose reviewwith.agents/checks/*.md[21]8 are genuinely well-designed. They are a good fit for new, low-stakes recurring chores (a weekly dependency-drift report) precisely because they don't touch the queue or the gate. Zero risk to the invariants because the blast radius is one cron job.
The 3 things it would risk breaking
- The Brain-does-not-execute invariant. goose's model is "delegate and let the child act," with subagents inheriting extensions15 and currently escaping the parent's approval mode51 and policy hooks52. One goose agent in a decision path is one prompt-injected task away from Brain executing.
- Permission discipline and the read-only boundary.
- goose defaults to no approval at all for shell with user privileges.29
- its shell tool carries no sandbox and no command allow-list (#12566).50
smart_approve's read/write classification is LLM-judged.27- the ACP path delegates shell to the client outside your sandbox.53
SolOS's allow-lists are enforced in code; goose's are advisory config plus a model classifier. - Evidence-before-complete, via silent partial failure. "If a subagent fails or times out… you will receive no output from that subagent. For parallel execution, if any subagent fails, you get results only from the successful ones."15 A goose task that half-succeeds will look like a success to any status-based probe. That is precisely the "HTTP 200 but broken" class SolOS built content assertions to kill — and goose reintroduces it at the agent layer.
Privacy / data residency (explicitly asked, and it is fine — with caveats).
goose's own telemetry is opt-in: "On first use, goose asks for permission to collect anonymous usage data."32 The enumerated payload is OS/version/arch, goose version + install method, provider+model, extension/tool usage counts (names only), session duration/token counts, and error types — "Collected usage data doesn't include your conversations, code, tool arguments, error messages, or any personal data." It is off by default (GOOSE_TELEMETRY_ENABLED false) and settable per-session via env var.6
The real exposure is not goose, it is the LLM provider: "Depending on the LLMs you use with goose, your conversations, prompts, and information accessed by goose might be sent to the provider and subject to their data retention and privacy policies."32
Concretely for SolOS: using opencode_go sends prompts and tool context to opencode.ai.44 A local Ollama provider keeps everything on-host.4 Note that the session DB at ~/.local/share/goose/sessions/sessions.db25 contains full transcripts in plaintext on the execution host — treat that file with the same hygiene as the queue DB, because it holds the same commercial-sensitive material.
One operational trap: GOOSE_DISABLE_KEYRING=1 moves secrets into secrets.yaml,6 which is a worse posture than the system keyring. Prefer env-var credentials supplied by a systemd unit over disabling the keyring wholesale.
Pilot proposal
Hypothesis: goose is a cheaper-to-operate worker than OpenCode v2 for one narrow, low-risk Heart chore — read-only repository reconnaissance and summarisation — at zero incremental model cost.
Scope (smallest possible):
- On the Heart host only, install the prebuilt CLI binary (
goose-x86_64-unknown-linux-gnu.tar.gz, 94.6 MB)49. No Rust build, no Docker, no Desktop app. - One dedicated config dir per agent persona (
GOOSE_CONFIG_DIR-equivalent via a distinctHOME, so this pilot cannot touch any SolOS credential or config). - Pin the provider:
opencode_gowithOPENCODE_API_KEYfrom the existing free-tier credential44. SetGOOSE_TELEMETRY_ENABLED=false,GOOSE_MODE=smart_approve,GOOSE_MAX_TURNS=8,GOOSE_DISABLE_KEYRING=1with env-var credentials, andGOOSE_ALLOWLISTpointing at a SolOS-owned allow-list containing onlydeveloper.30 - Exactly one new worker persona behind the existing orchestrator:
nova-adjacent "recon summariser".goose run --with-builtin developer --no-session --quiet --output-format json --max-turns 8 -t "...". No subagents (leavesummondisabled so no delegation path exists). No writes outside a scratch dir. - Keep the existing
gateand watchdog in the loop: goose output isworking →SolOS gate→ verified, exactly as for OpenCode v2 workers. The gate asserts content, not exit status. - Run for 10 business days / ~30 dispatched jobs. No production data — use a sandbox copy of the repo with synthetic persona/market data.
Success criterion (all must hold):
- ≥90% of dispatched jobs reach
verifiedwith content-asserted evidence (non-empty, task-shaped output — not an exit code). - Zero writes outside the scratch dir: verified by diffing the working tree after every run, asserted by a SolOS-side probe, not by goose's own reporting.
- Zero privilege escalations, and zero attempts to touch SolOS config/secret/queue paths (probe for any path access outside the scratch dir).
- Median wall-clock per job ≤ the current OpenCode v2 worker for the same chore.
- Total model spend for the 30 jobs ≈ $0 (free tier only) — measured, not assumed.
- No goose-initiated outbound network egress beyond the LLM endpoint and the MCP endpoints you allow-listed.
Abort conditions (any one, immediately revert):
- Any goose process reads or writes outside the scratch dir and the explicitly allow-listed paths.
- Any subagent is observed spawning (
delegate/summonactive when it should be disabled). - A job reaches
verifiedon exit-code evidence without content — i.e. goose's silent-partial-failure mode15 surfaces. - Any A/B test shows goose is slower or more expensive than the existing OpenCode v2 worker over 30 jobs.
- A goose minor release within the pilot window breaks JSON output format, session handling, or permissions without a documented migration (weekly cadence makes this a live risk[41]48).
- Any prompt-injection test — a planted malicious instruction in a scanned file — results in goose taking an action your SolOS policy would have blocked. Given #11778/#12650/#12566[51][52]50, assume this is the most likely failure and instrument for it.
Kill-switch: delete the worker entry from the orchestrator's dispatch table. Because goose holds no SolOS state (its sessions are per-pilot, disposable), removal is a one-line config revert with no data migration.
UNVERIFIED items
- Whether fixes #12654 (
subagents meet the parent's approval mode and tool hooks) and #12563 are in a released binary — both were PRs/merged at fetch time, not confirmed shipped. - Whether closed issue #9118 (
.gooseignorefilesystem read deny-list) shipped or was dropped. - Whether closed multi-agent issues #7238 / #7757 produced shipped architecture.
- Exact LF Projects trademark clause text (did not fetch lfprojects.org/policies).
- Whether a goose REST task API exists anywhere (grep found none across 173 doc pages; absence in docs ≠ absence in code).
- Long-term governance of
opencode_go.jsonandaaif-goose/goose-recipesrelative to the goose project itself. Related open question: goose is mid-flight on adopting the vendor-neutral Agent Plugins standard (#11043), which would change its plugin/skill packaging format.57 - Community sentiment / third-party user complaints beyond what the maintainers' own docs and open issues admit. I did not scrape Reddit/HN/Discord — that would be a good complement, but it is sentiment, not fact, and it is not needed for the verdict.
Sources
1 https://github.com/block/goose — goose GitHub README (redirects to aaif-goose/goose) 2 https://block.github.io/goose — goose official site 3 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/getting-started/installation — installation 4 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/getting-started/providers — providers 5 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/getting-started/using-extensions — using extensions 6 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/guides/config-files — config files 7 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/guides/environment-variables — environment variables 8 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/guides/goose-cli-commands — CLI commands 9 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/tutorials/headless-goose — headless mode tutorial 10 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/guides/running-tasks — running tasks 11 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/guides/remote-goose-server — remote goose server (ACP over HTTP/WS) 12 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/gdk/index — GDK overview 13 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/gdk/acp/index — GDK ACP 14 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/gdk/sdk/index — GDK SDK 15 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/guides/context-engineering/subagents.mdx — subagents guide 16 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/tutorials/subagents — subagents tutorial 17 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/guides/context-engineering/custom-agents — custom agents 18 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/guides/context-engineering/using-goosehints — goosehints 19 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/guides/context-engineering/using-persistent-instructions — persistent instructions 20 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/mcp/memory-mcp — memory extension 21 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/guides/recipes/recipe-reference — recipe reference 22 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/guides/recipes/session-recipes — session recipes 23 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/guides/recipes/storing-recipes — storing recipes 24 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/guides/sessions/index — sessions index 25 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/guides/sessions/session-management — session management 26 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/guides/sessions/smart-context-management — smart context management 27 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/guides/managing-tools/goose-permissions — permission modes 28 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/guides/managing-tools/tool-permissions — tool permissions 29 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/mcp/developer-mcp — developer extension 30 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/guides/allowlist — extension allowlist 31 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/guides/context-engineering/hooks — hooks 32 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/guides/usage-data — usage data / telemetry 33 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/troubleshooting/known-issues — known issues 34 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/goose-architecture/goose-architecture — architecture 35 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/tutorials/goose-in-docker — docker tutorial 36 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/guides/roaming-agents — roaming agents 37 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/guides/acp-providers — acp providers 38 https://raw.githubusercontent.com/aaif-goose/goose/main/documentation/docs/guides/codebase-analysis — codebase analysis 39 https://raw.githubusercontent.com/aaif-goose/goose/main/GOVERNANCE.md — GOVERNANCE.md 40 https://raw.githubusercontent.com/aaif-goose/goose/main/LICENSE — LICENSE 41 https://raw.githubusercontent.com/aaif-goose/goose/main/RELEASE.md — RELEASE.md 42 https://raw.githubusercontent.com/aaif-goose/goose/main/crates/goose/Cargo.toml — crates/goose/Cargo.toml (features) 43 https://api.github.com/repos/aaif-goose/goose/contents/crates/goose-providers/src/declarative/definitions — provider definitions dir listing 44 https://raw.githubusercontent.com/aaif-goose/goose/main/crates/goose-providers/src/declarative/definitions/opencode_go.json — opencode_go.json provider definition 45 https://raw.githubusercontent.com/aaif-goose/goose/main/crates/goose/src/agents/subagent_task_config.rs — subagent_task_config.rs 46 https://raw.githubusercontent.com/aaif-goose/goose/main/crates/goose/src/prompts/subagent_system.md — subagent_system.md prompt 47 https://api.github.com/repos/aaif-goose/goose — repo metadata API (stars/issues/license) 48 https://api.github.com/repos/aaif-goose/goose/releases?per_page=12 — releases API 49 https://api.github.com/repos/aaif-goose/goose/releases/tags/v1.53.0 — release v1.53.0 50 https://api.github.com/repos/aaif-goose/goose/issues/12566 — issue 12566 (shell no sandbox) 51 https://api.github.com/repos/aaif-goose/goose/issues/11778 — issue 11778 (subagents bypass approval) 52 https://api.github.com/repos/aaif-goose/goose/issues/12650 — issue 12650 (PreToolUse hooks skipped for subagents) 53 https://api.github.com/repos/aaif-goose/goose/issues/12513 — issue 12513 (ACP shell delegated, bypasses sandbox) 54 https://api.github.com/repos/aaif-goose/goose/issues/11999 — issue 11999 (subagent max turns) 55 https://api.github.com/repos/aaif-goose/goose/issues/11399 — issue 11399 (fine-grained shell perms feature request) 56 https://api.github.com/repos/aaif-goose/goose/issues/10113 — issue 10113 (recipe metadata breaks session load) 57 https://api.github.com/repos/aaif-goose/goose/issues/11043 — issue 11043 (agent-plugins standard) 58 https://aaif.io/projects — AAIF projects page 59 https://goose-docs.ai — goose-docs.ai homepage
solos-memory — shared fleet memory service
Directive: Young, 2026-09-28 — "Next to build long-term and short-term memory plugin for Hermes via API / MCP for our agents to shared and use." Owners: Ace (build) · Atlas (verification + rollout) · Tam (spec + acceptance) Host: LAB lab@192.168.4.60 (where solos.db lives and the A2A mesh runs)
Scraping stack for the fleet — spike-tested comparison

