Young's Mind
Tech

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.

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

SurfaceEntry pointDocumented?
Desktop app (macOS/Linux/Windows, Electron)download .deb/.zip, brew install --cask block-gooseyes3
CLIcurl -fsSL .../download_cli.sh | bash, brew install block-goose-cliyes3
Headless / non-interactivegoose run -t "...", goose run -i instructions.md, --no-session, --quietyes[9]10
HTTP/WebSocket servergoose serve --host --port --tls (ACP endpoint at /acp)yes[8][11]13
stdio servergoose acpyes8
Provider-only SDKgoose-sdk crate / pip install goose-sdk / Kotlin io.github.aaif-goose:gdkyes14

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=1 plus 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.x releases. 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-shot goose mcp <name>; per-invocation --with-extension, --with-streamable-http-extension, --with-builtin; Desktop GUI; or a central extensions directory.[5]8
  • Built-in developer extension (enabled by default): shell, write, edit, tree, read_image — docs rate shell/write/edit as ⚠️ High risk ("Can run any system command with your user privileges" / "Can modify any accessible file"), tree/read_image as ✅ 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/load entry point that subagents ride on.15
  • Governance lever: GOOSE_ALLOWLIST points 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 version field defaulting to 1.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: parameters with typed inputs (string/number/boolean/date/file/select), {{ var }} templating, extensions block pinning exactly which MCP servers a recipe may use (incl. available_tools allow-list), settings.goose_provider/goose_model/temperature/max_turns, and a retry block with checks: [{type: shell, command: ...}] that must exit 0 for success, plus on_failure cleanup.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/agent2agent references 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-server config).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 roaming feature 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): "PreToolUse hooks 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 a PreToolUse hook 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 / --model flags override per invocation.8
  • GOOSE_PROVIDER / GOOSE_MODEL env vars do the same per process.7
  • Recipe settings.goose_provider / goose_model pin 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. shell is one tool. There is no regex allow-list — that is an open feature request (#11399), and its own description concedes: "Ask Before on the shell tool: prompts for every command, including trivially safe ones like git status… nothing stops a git push, a rm -rf variant, or a destructive docker command 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 shell tool… passes the LLM-supplied command string verbatim to the host shell… with no allowlist, sandbox, or content validation. The permission gate's default mode GooseMode::Auto returns Allow unconditionally 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_ALLOWLIST for extension installs30; optional prompt-injection detection (SECURITY_PROMPT_ENABLED, plus an ML classifier endpoint — disabled by default)6; plugin PreToolUse/Stop hooks that can hard-deny a tool call, with on_failure: block fail-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.md is supported natively. "By default, goose looks for both AGENTS.md and .goosehints at 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_NAMES takes 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_FILE are 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.md confirms 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.
    1. Subagent approval-mode bypass (#11778) and hook bypass (#12650) are both open.[51]52
    2. The shell tool has no sandbox or allow-list, reported as security issue #12566.50
    3. ACP delegates shell to the client, escaping sandboxes (#12513).53
    4. Subagent failures are silent (#11999).54
    5. Recipe metadata drift can hard-fail session load — #10113 documents loadSession failing on an invalid stored recipe ("Unnecessary parameter definitions: pr.")56
    6. 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 the block-goose cask, and Windows data lives at %APPDATA%\Block\goose\.[3]33
    The repo is also mid-rename from block/goose to aaif-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 — the opencode_go.json provider44 and the goose-recipes repo referenced as aaif-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 are goose-docs.ai; everything I cite is from the repo's own documentation/docs/ markdown on main, 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 reports Apache-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 capabilitySolOS equivalentVerdict
1Desktop GUI (Electron, 3 OSes)3NoneIrrelevant — SolOS is headless-by-design
2Interactive CLI session (goose session)8Heart agents via OpenCode v2Duplicate, and a downgrade (no OpenCode v2 primitives)
3Headless goose run + --output-format json[8][9]10Heart A2A JSON-RPC over loopbackThin real value — cheapest possible worker adapter
4ACP HTTP/WS server (goose serve, secret auth, TLS pinning)[11]13A2A JSON-RPC + SSH tunnelsDuplicate, worse fit — editor-session protocol, not job API
5Provider-only SDK (Rust/Python/Kotlin)14Hermes framework internalsReject — alpha, and Hermes already provides this
670+ MCP extensions, one-command install5Hermes/OpenCode MCP toolsGenuine value — biggest single breadth win
7Built-in developer ext (shell/write/edit/tree/read_image)29OpenCode v2 agent toolsDuplicate — and weaker safety
8Extension allow-list (GOOSE_ALLOWLIST)30Per-agent permission allow-lists (code-enforced)Duplicate — yours is stronger (code vs config)
9SQLite session store, cross-surface resume25sqlite task queue (state machine)Duplicate, worse — no state machine, no gate
10Memory extension, local files, all-injected20memories/MEMORY.md + USER.mdDuplicate — yours is curated & per-agent; goose injects everything
11Auto-compaction / context strategies26Hermes context managementDuplicate
12Recipes: YAML/JSON, versioned, GitHub-shareable, params, settings.model[21]22SOUL.md personas + prompt templatesNear-duplicate, but recipes are strictly more executable
13retry.checks shell-exit-0 gate inside a recipe21gate service closing working→verified→completedThin real value — declarative local verification; much weaker than gate
14Subagents (sequential/parallel, custom agents)[15]16Whole Heart plane + Brain/Heart boundaryDuplicate and dangerous — no separation, silent partial failure, approval bypass
15Subagent defaults: 25 turns, 5 min timeout[15]45Per-agent turn/budget disciplineDuplicate, worse — #11999 shows the cap bites
16External subagents (Codex-as-MCP-server)15OpenCode v2 Heart agents over A2ADuplicate
17Roaming p2p agents (experimental, not in releases)36SSH-tunneled loopback A2AReject — source-build only, experimental
18~45 providers + 48 declarative definitions[4]43opencode-go free tierReal value — opencode_go.json ships natively44
19Local inference (Ollama/LM Studio/Ramalama/Docker Model Runner)[4]8Not currently usedOptional value — only if SolOS ever needs data residency
20BYO key + declarative custom providers + refreshable creds4opencode-go keyMarginal value — nice, not needed
21Per-session/per-recipe/per-agent model pinning[8][21]17Per-agent persona configDuplicate — you already pin per agent
224 permission modes + per-tool allow/ask/deny[27]28Persona/permission enforcement, read-only allow-listsDuplicate and a regression — see §7
23Plugin PreToolUse/Stop hooks, fail-closed31External watchdog + gateThin real value — but bypassed by subagents (#12650)
24Prompt-injection detection (opt-in)6Not present in SolOSGenuine gap-filler, low priority
25.goosehints + AGENTS.md, local-wins precedence18SOUL.md + USER.mdDuplicate
26MOIM persistent instructions, re-injected every turn19Persona enforcementMild real value — strongest enforcement primitive goose has
27goose schedule (cron → recipe)8State-machine queue + schedulerDuplicate, worse — no states, no gate
28goose review with .agents/checks/*.md8Not presentMarginal value
29Weekly releases, 55k stars, 4.3k commits[47][48]41n/aValue (well-maintained) and cost (weekly churn)
30Apache-2.0 + LF stewardship[39][40]47n/aValue — no licence or lock-in risk
3194 MB binary, 170 MB .deb, optional CUDA/Vulkan builds[49]42Host already carries OpenCodeCost, no offsetting benefit

TABLE 2 — SolOS capability → would Goose cover it? → integration/maintenance cost

SolOS subsystemGoose equivalentGap / cost to bridge
Brain plane (min/mira/sol, Hermes, SOUL.md+MEMORY.md+USER.md)Provider-only SDK (alpha)14No coverage. Goose has no decision-agent concept. Bridging = reimplementing Hermes; do not.
Hard Brain-does-not-execute boundary (enforced in orchestrator code)NothingNo 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]9Partial. 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 tunnelsACP over HTTP/WS[11]13Poor 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 schedule8No 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-021Weak 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 codes8No coverage — goose actively violates it. Any goose-involving path must have an independent SolOS-side evidence assertion.
External watchdog asserting CONTENT not statusgoose info/diagnostics, hooks31No 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]28Partial 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 disciplineopencode_go provider44; Groq/Gemini free tiers4; GOOSE_CLI_SHOW_COST6Full 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-inApache-2.0, LF Projects, ACP[13][39]40Full coverage. Config, recipes, agents, sessions are all local files. No exit cost.

VERDICT PER SUBSYSTEM

SubsystemVerdictReasoning
Brain plane (min/mira/sol)REJECTGoose 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 planeADOPT-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 machineREJECT (do not touch)Zero goose coverage. Keep sqlite + the state machine. Goose sessions are conversation history, not job records.
gate / evidence disciplineREJECT (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 assertionsREJECT (do not touch)No goose equivalent. Any new worker needs a SolOS-side probe asserting content.
A2A transportREJECTACP is an editor session protocol; bridging it to SolOS's job semantics means writing the state machine twice, in the wrong place.
Provider / model layerADOPT (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 surfaceADOPT-SELECTIVELY70+ 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 layerREJECTDefault-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 contextREJECTSolOS'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 orchestrationREJECTSolOS'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 replacementREJECT~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

  1. 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 to opencode_go, behind the existing orchestrator, with GOOSE_MODE=approve or smart_approve. Bounded, content-asserted by your existing watchdog, never trusted with a brain task.
  2. 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.
  3. Declarative verification and scheduling primitives for new work, not existing work — recipe.retry.checks + goose schedule + goose review with .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

  1. 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.
  2. 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.
  3. 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):

  1. 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.
  2. One dedicated config dir per agent persona (GOOSE_CONFIG_DIR-equivalent via a distinct HOME, so this pilot cannot touch any SolOS credential or config).
  3. Pin the provider: opencode_go with OPENCODE_API_KEY from the existing free-tier credential44. Set GOOSE_TELEMETRY_ENABLED=false, GOOSE_MODE=smart_approve, GOOSE_MAX_TURNS=8, GOOSE_DISABLE_KEYRING=1 with env-var credentials, and GOOSE_ALLOWLIST pointing at a SolOS-owned allow-list containing only developer.30
  4. 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 (leave summon disabled so no delegation path exists). No writes outside a scratch dir.
  5. Keep the existing gate and watchdog in the loop: goose output is working → SolOS gate → verified, exactly as for OpenCode v2 workers. The gate asserts content, not exit status.
  6. 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 verified with 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/summon active when it should be disabled).
  • A job reaches verified on 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 (.gooseignore filesystem 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.json and aaif-goose/goose-recipes relative 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

Copyright © 2026