Skip to content

feat(goose): add experimental Goose (Block) harness#1933

Closed
sergio-sisternes-epam wants to merge 4 commits into
mainfrom
pr-1833-goose
Closed

feat(goose): add experimental Goose (Block) harness#1933
sergio-sisternes-epam wants to merge 4 commits into
mainfrom
pr-1833-goose

Conversation

@sergio-sisternes-epam

Copy link
Copy Markdown
Collaborator

Description

Adds experimental support for Goose (Block's open-source AI agent) as a new APM target. Goose has no project-level config file so its integration surface is distinct from prior YAML-config targets:

  • skills -> cross-tool .agents/skills/ standard (shared with other targets)
  • agents -> Goose recipes at .goose/recipes/<name>.yaml, runnable via goose run --recipe
  • MCP servers -> written to ~/.config/goose/config.yaml (user-scope only; honours $XDG_CONFIG_HOME)
  • instructions -> a thin .goosehints stub at the project root that imports the compiled AGENTS.md via Goose's @./AGENTS.md preprocessor

The entire feature is gated behind apm experimental enable goose -- the target appears in EXPERIMENTAL_TARGETS, carries requires_flag="goose" in its TargetProfile, and _goose_runtime_opted_in() calls is_enabled("goose") before any writes. Users without the flag enabled see no behaviour change.

The PR also extracts a YamlMcpClientAdapter base class shared by both the Goose and Hermes adapters, reducing duplication.

Fixes: #1833

Type of change

  • New feature

Testing

  • Tested locally
  • All existing tests pass
  • Added tests for new functionality (if applicable)

Spec conformance (OpenAPM v0.1)

Two new normative requirements were added to cover the generalised YAML-config MCP and agent native-format compilation surfaces introduced by Goose and Hermes:

  • Spec edit: docs/src/content/docs/specs/openapm-v0.1.md updated -- added req-tg-005 (YAML-config MCP key/schema contract) and req-tg-006 (agent native-format deploy contract) with anchors, prose, and Appendix C rows; updated section 1.3 count (95 -> 97) and revision history (0.1.8).
  • Manifest edit: docs/public/specs/manifests/openapm-v0.1.requirements.yml updated with both new entries.
  • Test edit: @pytest.mark.req("req-tg-005") and @pytest.mark.req("req-tg-006") tests added to tests/spec_conformance/test_manifest_reqs.py.
  • CONFORMANCE.{md,json} regenerated and committed.

Dorn- and others added 4 commits June 26, 2026 17:20
Hermes was the only MCP client adapter writing a YAML config document
(a single top-level servers mapping) rather than the JSON mcpServers
schema. Lift its YAML round-trip / sibling preservation / atomic 0o600
write / malformed-file refusal / configure_mcp_server flow into a new
YamlMcpClientAdapter base so a second YAML-backed adapter can reuse it
without duplicating those blocks (the R0801 duplication guard would
otherwise reject the copy).

HermesClientAdapter now only declares its config path, mcp_servers_key,
display name, and the per-server schema transform; behaviour and the
_to_hermes_format static surface are unchanged.
Adds Goose (https://goose-docs.ai) as a first-class, experimental APM
target gated behind the `goose` flag (`apm experimental enable goose`).
Like the other frontier targets it is hidden from auto-detection and
excluded from `--target all`.

Goose differs structurally from every existing target, so the mapping
follows its native surfaces:

- MCP servers: GooseClientAdapter writes the YAML `extensions:` block of
  ~/.config/goose/config.yaml (honouring $XDG_CONFIG_HOME) in Goose's
  own per-server schema (type: stdio / cmd / args / envs / enabled /
  timeout; remotes -> streamable_http / uri). Reuses the shared
  YamlMcpClientAdapter base. User-scope only (Goose has no project
  config), with the new `extensions` key wired into the conflict
  detector's generic path.
- agents -> recipes: each .apm/agents/<name>.md compiles to
  .goose/recipes/<name>.yaml, the native packaged-agent unit Goose runs
  via `goose run --recipe` (title/description/instructions, plus
  settings.goose_model when the agent pins a model). A shared
  _parse_agent_frontmatter helper is factored out of the Codex writer to
  avoid duplicating the frontmatter preamble. MCP extensions are not
  embedded per recipe -- an APM agent declares no MCP servers; those stay
  in config.yaml, which Goose reads globally at run time.
- skills -> the cross-tool .agents/skills/ standard Goose reads natively
  (.agents/skills/ project, ~/.agents/skills/ with --global).
- instructions: compile_family="agents" emits AGENTS.md and a thin
  .goosehints stub that imports it via Goose's `@./AGENTS.md`
  preprocessor (GeminiFormatter is parameterised by overridable stub
  attributes so GooseFormatter reuses it; _compile_gemini_md is
  generalised into a shared _compile_import_stub).

Includes path-fidelity acceptance tests, registry/dispatch invariant
updates, the integration docs page, and the experimental-flag reference.
…mat (closes Mode B gate for #1833)

Add two normative requirements to spec section 8.5 (Deploy directory
contract):

- req-tg-005: A consumer writing MCP config for a YAML-based target
  MUST use the target's registered config key and per-server schema,
  preserving sibling keys not managed by APM; JSON-format mcpServers
  MUST NOT be written to YAML-config target files.
- req-tg-006: A consumer supporting the agents primitive for a target
  MUST compile each agent to the target's registered native format and
  deploy under the target's registered root; a different target's
  format MUST NOT be emitted.

Both requirements generalize the Goose and Hermes YAML-config pattern
and the recipe/agent compilation surface. Spec count: 95 -> 97
(92 MUST, 5 SHOULD). Manifest + Appendix C + conformance tests updated.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…rements)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 26, 2026 16:50
@sergio-sisternes-epam sergio-sisternes-epam deleted the pr-1833-goose branch June 26, 2026 16:50
@sergio-sisternes-epam

Copy link
Copy Markdown
Collaborator Author

Closing this PR. Just adding fixes to the existing PR from the contributor.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Goose (Block) as a new experimental APM target, including a Goose-specific instructions stub (.goosehints), agent-to-recipe compilation, and YAML-backed MCP config support, plus the associated OpenAPM spec and conformance updates.

Changes:

  • Introduces GooseClientAdapter and a shared YamlMcpClientAdapter base for YAML-config MCP runtimes (Goose + Hermes).
  • Adds Goose target wiring (target registry, detection, experimental flag) and compilers/formatters for .goosehints + recipe output.
  • Updates OpenAPM v0.1 with two new normative requirements (req-tg-005/006) and regenerates conformance artifacts + tests.

Reviewed changes

Copilot reviewed 28 out of 28 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/unit/integration/test_targets_registry_completeness.py Registers Goose adapter and extensions as a known MCP key for completeness tests.
tests/unit/integration/test_goose_target.py New acceptance tests covering Goose target behavior, paths, transforms, and flag gating.
tests/unit/integration/test_data_driven_dispatch.py Adds agents_goose bucket to dispatch parity expectations.
tests/unit/core/test_target_detection.py Updates experimental target membership test to include Goose.
tests/unit/core/test_scope.py Adds goose to the expected KNOWN_TARGETS set.
tests/spec_conformance/test_manifest_reqs.py Adds conformance tests for new spec requirements req-tg-005 and req-tg-006.
src/apm_cli/utils/yaml_io.py Adds multiline_block YAML serialization option for readable block scalars.
src/apm_cli/integration/targets.py Adds Goose TargetProfile (agents -> recipes, skills -> .agents/skills, experimental).
src/apm_cli/integration/mcp_integrator_install.py Adds Goose runtime opt-in detection and runtime discovery integration.
src/apm_cli/integration/agent_integrator.py Adds Goose recipe writer and shared frontmatter parsing for agent transforms.
src/apm_cli/factory.py Registers Goose MCP client adapter in the factory registry.
src/apm_cli/core/target_detection.py Adds Goose to detection/config echo and .goosehints compile routing; expands target validation.
src/apm_cli/core/experimental.py Introduces the goose experimental flag metadata and hint.
src/apm_cli/compilation/goose_formatter.py New formatter emitting .goosehints as an AGENTS.md import stub.
src/apm_cli/compilation/gemini_formatter.py Generalizes Gemini stub generation via overridable class attributes for reuse.
src/apm_cli/compilation/agents_compiler.py Adds Goose compile target and generalizes stub compilation logic for Gemini/Goose.
src/apm_cli/commands/install.py Extends --target help text to mention Goose experimental enablement.
src/apm_cli/adapters/client/hermes.py Refactors Hermes YAML MCP adapter to inherit from the shared YAML base.
src/apm_cli/adapters/client/goose.py New Goose YAML MCP adapter writing extensions: to Goose config.yaml.
src/apm_cli/adapters/client/_yaml_config.py New shared YAML-backed MCP adapter base (round-trip, atomic write, malformed refusal).
docs/src/content/docs/specs/openapm-v0.1.md Adds req-tg-005/006 and updates normative counts and revision history.
docs/src/content/docs/reference/experimental.md Documents the new goose experimental flag.
docs/src/content/docs/producer/compile.md Documents apm compile -t goose emitting .goosehints + AGENTS.md.
docs/src/content/docs/integrations/goose.md New Goose integration documentation page.
docs/public/specs/manifests/openapm-v0.1.requirements.yml Adds req-tg-005/006 to the machine-readable requirements manifest.
CONFORMANCE.md Updates conformance table to include the two new consumer requirements.
CONFORMANCE.json Updates conformance JSON for new requirements and totals.
CHANGELOG.md Adds an Unreleased entry describing the new experimental Goose target.

Comment on lines +1050 to +1056
def _compile_import_stub(
self,
config: CompilationConfig,
primitives: PrimitiveCollection,
formatter,
label: str,
stat_key: str,
Comment on lines +137 to +139
- `The 'goose' target requires an experimental flag`: run `apm experimental enable goose`.
- MCP servers not written: confirm the flag is enabled and that you passed `--global` (Goose MCP config is user-scope only).
- `config.yaml is malformed YAML; refusing to overwrite`: fix or remove the file manually, then retry -- APM never discards a config it cannot parse.
Comment on lines 936 to +941
"--target",
"-t",
"target",
type=TargetParamType(),
default=None,
help="Target harness(es) to deploy to. Comma-separated for multiple: --target claude,cursor. Repeating the flag (e.g. '-t a -t b') is NOT supported -- only the last value wins; use commas. Highest-priority entry in the resolution chain (--target > apm.yml targets: > apm config target > auto-detect). Values: copilot, claude, cursor, opencode, codex, gemini, antigravity, windsurf, kiro, agent-skills, all. 'agent-skills' deploys to .agents/skills/ (cross-client). 'antigravity' (alias 'agy') deploys to .agents/ (AGENTS.md + rules + skills + hooks.json + mcp_config.json) and is explicit-only -- not part of 'all' or auto-detection. 'all' = copilot+claude+cursor+opencode+codex+gemini+windsurf+kiro (excludes agent-skills and antigravity); combine with 'agent-skills' or 'antigravity' to add them. 'copilot-cowork' is also accepted when the copilot-cowork experimental flag is enabled (run 'apm experimental enable copilot-cowork'). 'copilot-app' is also accepted when the copilot-app experimental flag is enabled (run 'apm experimental enable copilot-app'). Note: '--target all' on 'apm compile' is deprecated; use 'apm compile --all' instead.",
help="Target harness(es) to deploy to. Comma-separated for multiple: --target claude,cursor. Repeating the flag (e.g. '-t a -t b') is NOT supported -- only the last value wins; use commas. Highest-priority entry in the resolution chain (--target > apm.yml targets: > apm config target > auto-detect). Values: copilot, claude, cursor, opencode, codex, gemini, antigravity, windsurf, kiro, agent-skills, all. 'agent-skills' deploys to .agents/skills/ (cross-client). 'antigravity' (alias 'agy') deploys to .agents/ (AGENTS.md + rules + skills + hooks.json + mcp_config.json) and is explicit-only -- not part of 'all' or auto-detection. 'all' = copilot+claude+cursor+opencode+codex+gemini+windsurf+kiro (excludes agent-skills and antigravity); combine with 'agent-skills' or 'antigravity' to add them. 'copilot-cowork' is also accepted when the copilot-cowork experimental flag is enabled (run 'apm experimental enable copilot-cowork'). 'copilot-app' is also accepted when the copilot-app experimental flag is enabled (run 'apm experimental enable copilot-app'). 'goose' is also accepted when the goose experimental flag is enabled (run 'apm experimental enable goose'); use '--target goose --global' to write MCP servers as Goose extensions in ~/.config/goose/config.yaml (a .goosehints stub importing AGENTS.md is generated at the project root). Note: '--target all' on 'apm compile' is deprecated; use 'apm compile --all' instead.",
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants