Skip to content

fix(wire): align all sites to protocol 0.2.0 (--mcp-config-path, schema rename, fixture bump)#24

Merged
manojp99 merged 1 commit into
mainfrom
fix/wire-protocol-0.2.0-cleanup
Jun 1, 2026
Merged

fix(wire): align all sites to protocol 0.2.0 (--mcp-config-path, schema rename, fixture bump)#24
manojp99 merged 1 commit into
mainfrom
fix/wire-protocol-0.2.0-cleanup

Conversation

@manojp99

Copy link
Copy Markdown
Collaborator

What. Brings the entire amplifier-agent codebase into alignment with the canonical PROTOCOL_VERSION = "0.2.0" declared in src/amplifier_agent_lib/protocol/methods.py. The work covers eight categories of drift caught by a static wire-protocol consistency linter: the JSON schema for InitializeParams (renamed mcpServersmcpConfigPath), the regenerated TypeScript types, the regenerated spec.md, the Python wrapper's PROTOCOL_VERSION_REQUIRED_BY_WRAPPER constant, the Python wrapper's argv-builder + MCP-spill helper + session driver (rename mcp_servers_flagmcp_config_path, emit --mcp-config-path instead of --mcp-servers, always spill the dict to a 0600 tmpfile and write the {"mcpServers": <map>} shape the engine reads via AMPLIFIER_MCP_CONFIG), 21 stale "0.1.0" pins across 8 conformance fixtures (with one fixture renamed initialize-with-mcpservers.yamlinitialize-with-mcp-config-path.yaml and its wire payload converted from inline dict to path string), and roughly 30 "0.1.0" literals in Python + TypeScript test suites. Two pre-existing failing tests that pinned the old wire shape (test_initialize_params_has_mcp_servers_field, test_expected_fixture_set_is_complete) were updated to reflect the new shape.

Why. Protocol 0.2.0 changed MCP config delivery from an inline mcpServers dict on the command line to a path string (mcpConfigPath) pointing at a JSON file. The truth source was bumped in commit ea51d05 but several downstream sites were missed, leaving the JSON schema, the Python wrapper's argv-builder, eight fixtures, and ~30 test literals pinned to the 0.1.0 wire shape. The Python wrapper would emit --mcp-servers <json> against an engine that only accepts --mcp-config-path <path> — a functional break. The TypeScript wrapper was already correct, which makes this an asymmetry/risk in cross-wrapper conformance.

How verified. (1) python_check on every changed Python file: clean (0 errors, ruff-format + ruff-lint + pyright + stub-check). (2) uv run pytest -m "not integration": 433 passing / 7 failing / 1 skipped / 18 deselected — down from main's 21 failures (−14 net). All 7 remaining failures are pre-existing on main and unrelated to this PR (they exercise the engine CLI's legacy --mcp-servers flag in tests/cli/test_mode_a_v2_envelope.py, plus three unrelated CLI tests and a counter gate). (3) cd wrappers/typescript && pnpm test: 61/61 passing across 12 test files. (4) Static wire-protocol consistency linter post-fix: 0 FAIL / 0 WARN across all 8 categories of drift checked.

…ma rename, fixture bump)

Bring the entire amplifier-agent codebase into alignment with the canonical
PROTOCOL_VERSION = "0.2.0" declared in src/amplifier_agent_lib/protocol/methods.py.
Work covers schema rename (mcpServers → mcpConfigPath), Python wrapper version constant
and argv-builder (--mcp-servers → --mcp-config-path), always-spill pattern in mcp_spill.py
to match TS wrapper, conformance fixture renames and version bumps, and ~30 test literals
across Python + TypeScript test suites.

Two pre-existing failing tests (test_initialize_params_has_mcp_servers_field,
test_expected_fixture_set_is_complete) updated to reflect new wire shape.

Verified: 433 pass / 7 fail / 1 skip (down from main's 21 fail; all 7 remaining are
pre-existing unrelated failures in test_mode_a_v2_envelope.py and counter gate).
TypeScript: 61/61 passing. Wire-protocol-consistency linter: 0 FAIL / 0 WARN.

🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)

Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
@manojp99 manojp99 merged commit d1c9b33 into main Jun 1, 2026
1 of 3 checks passed
manojp99 pushed a commit that referenced this pull request Jun 2, 2026
…vitest bump)

Resolves 10 conflicts between this PR's hostCapabilities removal + host
config layer work and main's protocol-0.2.0 rename pass (#24).

Strategy: combine both changes — our hostCapabilities deletions are
preserved; main's mcpServers → mcpConfigPath renames are preserved.
The deleted initialize-with-host-capabilities.yaml fixture stays deleted
(modify/delete resolved in favor of our deletion).

Side effect: PR #24's protocol-0.2.0 fixes close most of the pre-existing
tech debt that this PR's description previously documented as out of scope.
manojp99 added a commit that referenced this pull request Jun 3, 2026
…g + env var) (#29)

* test(engine): add removal guardrail for --mcp-config-path argv flag

Pure intent-capture commit (RED): the assertions in this test file FAIL
against the current source. The matching implementation drops in the next
commit (chore(engine)!: drop --mcp-config-path argv flag).

Mirrors the Phase 1 cleanup pattern from tests/cli/test_drop_host_capabilities.py:
each guardrail asserts an absence at a specific seam — click --help output,
click usage rejection, _TurnSpec dataclass fields, make_turn_handler signature,
and _runtime.py source — so future refactors that re-introduce the flag fail
loudly at this layer instead of via downstream regressions.

🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)

Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>

* chore(engine)!: drop --mcp-config-path argv flag

Pure removal, no flag tolerance — click rejects with `Error: No such
option '--mcp-config-path'` (exit 2). Mirrors Phase 1's hostCapabilities
removal posture.

After PR #27 merged the host config layer (commit 70121c3) and PR #24
renamed `--mcp-servers` to `--mcp-config-path`, three equivalent paths
set AMPLIFIER_MCP_CONFIG for tool-mcp:
  (1) host_config["mcp"]["configPath"]   — host policy via config file
  (2) AMPLIFIER_MCP_CONFIG env var       — read natively by tool-mcp
  (3) --mcp-config-path argv flag        — redundant survivor

Per Mode A amendment §2.5 D9 + host config D10, per-invocation flags stay
argv and host policy moves to config. `mcpConfigPath` is host policy.
This commit removes path (3); paths (1) and (2) remain.

Engine changes (src/amplifier_agent_cli/modes/single_turn.py):
 - Drop @click.option("--mcp-config-path") declaration and the matching
   `mcp_config_path` parameter on run().
 - Drop the §(5b) validation block that gated the flag value as a real
   file (mcp_config_path_invalid).
 - Drop `mcp_config_path` from the _TurnSpec dataclass and from the
   make_turn_handler kwargs in _execute_turn.
 - Drop `mcp_config_path` parameter on _write_audit and the
   `mcpConfigPathDigest` audit field. The field was only populated by
   the argv flag; no remaining surface feeds it. The envDigest
   precedent of preserving stable digests with empty placeholders
   does not apply here — the field carried no information once the
   source was gone, so dropping it cleanly is preferable.

Engine changes (src/amplifier_agent_lib/_runtime.py):
 - Drop the `mcp_config_path` parameter on make_turn_handler.
 - Drop the CLI-flag → AMPLIFIER_MCP_CONFIG translation block.
 - The host_config["mcp"]["configPath"] → AMPLIFIER_MCP_CONFIG block
   (added by 70121c3) remains; the `not mcp_config_path` precedence
   guard is dropped because the CLI path is gone.
 - The wire-side `handle_initialize` path (`params["mcpConfigPath"]` →
   `_wire_mcp_config_path` → AMPLIFIER_MCP_CONFIG) is untouched; it is
   protocol-0.2.0 surface, not argv surface.

Test updates:
 - tests/cli/test_drop_mcp_config_path_flag.py (added in the previous
   commit) now passes — all five guardrails green.
 - tests/cli/test_drop_host_capabilities.py: drop the obsolete
   mcp_config_path=None kwarg from the _write_audit call.
 - tests/cli/test_mode_a_audit_trail.py: rewrite to invoke `run`
   without the removed flag and assert mcpConfigPathDigest is absent
   from the audit (negative guardrail).
 - tests/test_runtime_config_merge.py: drop
   test_cli_mcp_config_path_takes_precedence_over_host (precedence
   semantics are gone with the CLI path). The host-config translation
   test stays.
 - tests/test_runtime_mcp_threading.py: drop the two make_turn_handler
   CLI-path tests; rename the surviving "no source" test to reflect
   host_config being the only engine-side translation site. The
   wire-side handle_initialize tests are untouched.

Cross-repo follow-up: amplifier-nc-provider's adapter currently passes
`--mcp-config-path` to the engine subprocess (this was set up by the
PR #24 rename). It will break against this engine. Same shape as
Phase 1's hostCapabilities NC issue — file a tracking issue in the
adapter repo to migrate the spilled path forwarding from the argv
flag to AMPLIFIER_MCP_CONFIG via the subprocess environment.

BREAKING CHANGE: The `--mcp-config-path` argv flag was removed from
`amplifier-agent run`. Callers must migrate to one of:
  (1) host config: `mcp.configPath: /path/to/mcp.json` in the file
      consumed by --config; the engine translates it to
      AMPLIFIER_MCP_CONFIG at make_turn_handler boot.
  (2) ambient env: set AMPLIFIER_MCP_CONFIG=/path in the engine's
      subprocess environment; tool-mcp reads it natively via its
      config-discovery priority chain.

🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)

Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>

* chore(wrapper-py)!: drop mcp_config_path from assemble_argv + spawn_agent

Lockstep with the engine drop (chore(engine)!: drop --mcp-config-path
argv flag). The Python wrapper still spills the supplied mcp_servers
dict to a 0600 tmpfile (CR-A); the forwarding path changes from argv
flag to subprocess env var.

argv_builder.py:
 - Drop `mcp_config_path` parameter from `assemble_argv` and the
   `--mcp-config-path` emission block. Note the new path in the
   docstring (AMPLIFIER_MCP_CONFIG injected into subprocess env by
   SessionHandle._make_iterable, or set by the host directly).

session.py:
 - Drop the `mcp_config_path=spill["config_path"]` kwarg from the
   `assemble_argv` call in `_make_iterable`.
 - Build a fresh subprocess env dict per submit; when the spill
   produced a path, inject `AMPLIFIER_MCP_CONFIG=<path>` into it
   and pass that to `asyncio.create_subprocess_exec`. The
   SessionHandle's stored `subprocess_env` is never mutated.
 - Update the step-numbered comment block to reflect the env-var
   forwarding mechanism.

mcp_spill.py:
 - Docstring updates only — replace references to "engine receives
   the plain file path via --mcp-config-path" with the new "caller
   injects the spilled path into the engine's subprocess environment
   as AMPLIFIER_MCP_CONFIG" description.

__init__.py:
 - Update the spawn_agent() docstring for `mcp_servers` to describe
   the env-var forwarding mechanism.

tests/test_argv_builder.py:
 - Rename case (iv) from "threaded as bare path when caller
   pre-spilled" to "flag is not emitted".
 - Add case (v): asserts `assemble_argv(..., mcp_config_path=...)`
   raises TypeError so callers that still pass the obsolete kwarg
   fail loudly instead of silently no-opping.

BREAKING CHANGE: assemble_argv() no longer accepts the
`mcp_config_path` keyword argument. Callers using the public spawn_agent
API are unaffected — the wrapper handles the env-var injection
internally. Callers depending on the lower-level argv_builder must
remove the kwarg and inject AMPLIFIER_MCP_CONFIG into their
subprocess environment themselves.

🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)

Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>

* chore(wrapper-ts)!: drop mcpConfigPath from AssembleArgvInput + argv emission

Lockstep with the engine drop (chore(engine)!: drop --mcp-config-path
argv flag) and the Python wrapper drop (chore(wrapper-py)!: drop
mcp_config_path from assemble_argv + spawn_agent). The TypeScript
wrapper still spills the supplied mcpServers map to a 0600 tmpfile
(CR-A); the forwarding path changes from argv flag to subprocess env
var.

src/argv-builder.ts:
 - Drop `mcpConfigPath` field from `AssembleArgvInput`.
 - Drop the `--mcp-config-path` emission block in `assembleArgv`.
 - Document the new forwarding mechanism (AMPLIFIER_MCP_CONFIG injected
   into subprocess env by SessionHandle.makeIterable, or set by the
   host directly).

src/session.ts:
 - Drop the `mcpConfigPath: spill.configPath ?? undefined` field from
   the `assembleArgv` call in `makeIterable`.
 - Build a fresh `subprocessEnv` per submit; when the spill produced a
   path, inject `AMPLIFIER_MCP_CONFIG=<path>` into it and pass that
   object to `childSpawn`. The SessionHandle's stored
   `params.subprocessEnv` is never mutated.
 - Update the step-numbered JSDoc to reflect the env-var forwarding
   mechanism and the dropped argv flag.
 - Update the `mcpServers` field's JSDoc on `SessionHandleParams`.

src/mcp-spill.ts:
 - Docstring updates only — replace references to "engine receives the
   plain file path via --mcp-config-path" with the new description.

src/index.ts:
 - Update the JSDoc on `SpawnAgentParams.mcpServers` to describe
   env-var forwarding.

test/argv-builder.test.ts:
 - Rename case (iv) from "threaded as plain path" to "is not emitted
   (removed surface)".
 - Add case (v): a compile-time guardrail using `@ts-expect-error` to
   assert `AssembleArgvInput` no longer accepts `mcpConfigPath`; if a
   future refactor re-adds the field, the directive becomes a build
   error.

dist/*: regenerated by `npm run build` — these are committed artifacts
in this wrapper. Source-of-truth changes live in src/ and test/; the
dist/ delta is mechanical.

BREAKING CHANGE: `AssembleArgvInput` no longer exposes the
`mcpConfigPath` field. Callers using the public `spawnAgent` API are
unaffected — the wrapper handles env-var injection internally. Callers
depending on the lower-level `assembleArgv` must remove the field and
inject `AMPLIFIER_MCP_CONFIG` into their subprocess environment
themselves.

🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)

Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>

---------

Co-authored-by: Manoj Prabhakar Paidiparthy <mpaidiparthy@microsoft.com>
Co-authored-by: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
manojp99 added a commit that referenced this pull request Jun 3, 2026
…#27, #29, #31) (#32)

* fix(conformance): rename runner refs to initialize-with-mcp-config-path (post-#24)

PR #24 renamed the wire-shape fixture from
``initialize-with-mcpservers.yaml`` to
``initialize-with-mcp-config-path.yaml`` but left three hardcoded
references to the old name behind:

  * wrappers/conformance/test/runner-ts.test.ts (TS conformance suite)
  * wrappers/conformance/tests/test_runner_py.py (Py conformance suite)
  * tests/test_phase_2_1_exit_gate.py (engine-side fixture-set guard)

All three have been failing since PR #24. The conformance suites
showed up as "1 pre-existing failure each" in PRs #27, #29, and
#31, so wrapper/engine drift could land unseen during the entire
window in which we did most of the v0.3.0 argv cleanup -- the
exact class of bug the conformance suite is supposed to catch.

This commit restores the baseline to green by pointing each
reference at the surviving wire-protocol fixture name. No fixture
data changes, no engine logic changes.

Verification (this commit, host machine):
  * wrappers/conformance/ (TS): 5 passed (was 4 passed, 1 failed)
  * wrappers/conformance/ (Py): 5 passed (was 4 passed, 1 failed)
  * tests/test_phase_2_1_exit_gate.py: passes (was failing)

Out of scope (separate cleanup, noted for the PR body):
  * tests/cli/test_mode_a_v2_envelope.py still has 3 pre-existing
    failures referencing the removed ``--mcp-servers`` flag.
    Not touched here per the conformance-restore PR scope.

* chore(conformance): align version_skew remediation text with post-#27 host-config surface

PR #27 dropped the --allow-protocol-skew argv flag and moved protocol-skew opt-in into the host config file (allowProtocolSkew: true, surfaced through --config). The engine's real protocol_version_mismatch remediation string was updated in lockstep (src/amplifier_agent_lib/engine.py:160-163).

The version_skew wire-shape fixture's scripted server response still carried the old 'pass --allow-protocol-skew' remediation text, drifting it from current engine behavior even though no assertion in the fixture exercises the field directly. Update the scripted response to match the engine's current text so the fixture remains an honest exemplar of the wire-protocol surface post-#27/#29/#31.

Companion to PR #31 fixture sweep. No engine logic changes, no assertions changed, no test outcome changes.

* test(conformance): add baseline + protocol-skew-override wire-shape fixtures

Extend the conformance suite with two wire-protocol fixtures that lock in the post-cleanup surface and the previously-uncovered override branch of the version-skew contract:

* initialize-baseline.yaml -- canonical minimum init + turn/submit + result/final flow with only protocol-required params (no mcpConfigPath, no allowProtocolSkew, no hostCapabilities, no envAllowlist, no envExtra). Locks in the wire shape that survives PR #27 (host config + drop hostCapabilities), PR #29 (drop --mcp-config-path argv), and PR #31 (drop env-allowlist / env-extra / allow-protocol-skew from wrappers). Any future re-introduction of those legacy fields on the wire must be an intentional, reviewed addition rather than silent drift.

* initialize-with-protocol-skew-override.yaml -- the 'permits the handshake' branch of design §8 D6, companion to version_skew.yaml which covers only the strict-refuse branch. Client sends allowProtocolSkew=true (now sourced from the host config file, not from a --allow-protocol-skew argv flag) and a mismatched protocolVersion; server returns a successful sessionState instead of protocol_version_mismatch.

Both new fixtures are wired into the TS and Python conformance runners and acknowledged in the two fixture-set guard tests (tests/test_protocol_conformance_fixtures.py and tests/test_phase_2_1_exit_gate.py).

Scope note: the conformance runners use scripted JSON-RPC wire replay (ScriptedTransport) -- they do NOT spawn the engine subprocess. Argv-level 'loud failure' invariants for the dropped flags (--host-capabilities, --env-allowlist, --env-extra, --allow-protocol-skew, --mcp-config-path) are already locked in by the engine-side click-CliRunner tests at tests/cli/test_drop_host_capabilities.py and tests/cli/test_drop_mcp_config_path_flag.py. Extending the conformance runner to also exercise argv-level invariants would require subprocess invocation and changes to the loader at src/amplifier_agent_lib/protocol/conformance/loader.py (engine-internal, off limits per the PR scope) and is intentionally left for a future PR.

Verification (host machine):

* wrappers/conformance/ (TS): 7 passed (was 5 after rename commit)

* wrappers/conformance/ (Py): 7 passed (was 5 after rename commit)

* tests/test_protocol_conformance_fixtures.py: 17 passed (was 16; the new fixtures load and validate)

* tests/test_phase_2_1_exit_gate.py: passes (now acknowledges the new fixtures in the sorted-name guard)

* Engine suite (uv run pytest -q --ignore=wrappers): 519 passed, 3 pre-existing failures in tests/cli/test_mode_a_v2_envelope.py (unchanged from PR #31's pre-existing baseline -- they reference the long-removed --mcp-servers flag and are tracked for a separate cleanup).

* Wrappers/python: 48 passed; wrappers/typescript: 63 passed; manual smoke confirms --host-capabilities / --env-allowlist / --env-extra / --allow-protocol-skew / --mcp-config-path all reject with click UsageError ('no such option').

---------

Co-authored-by: Manoj Prabhakar Paidiparthy <mpaidiparthy@microsoft.com>
manojp99 pushed a commit that referenced this pull request Jun 3, 2026
Bump the wire protocol version to reflect accumulated backward-incompatible
changes shipped under the 0.4.0 release window:

  - metadata.hostCapabilities removed from response envelope (#27)
  - InitializeParams.host removed (#27)
  - InitializeParams.mcpServers renamed to mcpConfigPath (#24)
  - skills field added (host config skills: block, #30)

Old wrappers pinned to '0.2.0' should hard-fail handshake with a typed
protocol_version_mismatch error and exit 2 — verified manually:

    $ uv run amplifier-agent run --protocol-version 0.2.0 --session-id sm 'hi'
    {... "code": "protocol_version_mismatch" ...}
    EXIT=2

    $ uv run amplifier-agent run --protocol-version 0.3.0 --session-id sm 'hi'
    {... "reply": "..." ...}
    EXIT=0

Updated sites (audited via 'git grep "0.2.0" src/ tests/'):

  - src/amplifier_agent_lib/protocol/methods.py — PROTOCOL_VERSION constant
  - src/amplifier_agent_lib/protocol/spec.md — regenerated artifact
  - 9 conformance fixtures' protocolVersion: literals (setup + initialize params)
  - version_skew.yaml — serverVersion in expected error.data
  - 6 test files pinning protocolVersion in wrapper-side InitializeParams

Left as historical references (per release-issue guidance):

  - loader.py docstring example (illustrative fixture shape)
  - test_protocol_conformance_fixtures.py's self-contained _VALID_FIXTURE
    (loader smoke test, not engine-compat)
  - serverInfo.version: "0.2.0" in fixture script result blocks
    (not asserted by conformance harness — engine emits __version__ at
    runtime; fixture scripts are descriptive, only the explicit
    assertions: block is verified)

BREAKING CHANGE: Wire protocol 0.2.0 -> 0.3.0. Old wrappers pinned to 0.2.0
will hard-fail handshake with protocol_version_mismatch (exit 2). Reinstall
both engine and wrapper, or set allowProtocolSkew: true in host config.
manojp99 pushed a commit that referenced this pull request Jun 3, 2026
Closes the last 4 Python CI failures on this release branch.

(1) tests/cli/test_config_show.py::test_config_show_reports_default_when_env_absent

Click's CliRunner.invoke(env=...) MERGES the env dict with os.environ instead
of replacing it. GitHub Actions runners set XDG_CONFIG_HOME by default, which
leaked into the test and made source='env:XDG_CONFIG_HOME' instead of the
'default' the test was asserting. Now uses monkeypatch.delenv() to explicitly
remove XDG_CONFIG_HOME / XDG_CACHE_HOME / XDG_STATE_HOME before invoking.

(2) tests/cli/test_mode_a_v2_envelope.py

The three test_mcp_servers_* tests (inline_json_parsed, at_path_form,
malformed_json_yields_argv_envelope) target the --mcp-servers argv flag.
That flag was renamed to --mcp-config-path by PR #24 and then fully removed
by PR #29. The tests have been failing as 'pre-existing baseline' through
PRs #27, #29, #31, #32, and #33's earlier baselines. They test removed
surface and should never have been kept.

Replaced with an inline comment naming the removal context and pointing at
the removal guardrail at tests/cli/test_drop_mcp_config_path_flag.py.

Local: 532 passed, 3 skipped, 0 failed (full pytest tests/).
manojp99 added a commit that referenced this pull request Jun 3, 2026
…ce restored (#33)

* chore(protocol)!: bump wire PROTOCOL_VERSION 0.2.0 -> 0.3.0

Bump the wire protocol version to reflect accumulated backward-incompatible
changes shipped under the 0.4.0 release window:

  - metadata.hostCapabilities removed from response envelope (#27)
  - InitializeParams.host removed (#27)
  - InitializeParams.mcpServers renamed to mcpConfigPath (#24)
  - skills field added (host config skills: block, #30)

Old wrappers pinned to '0.2.0' should hard-fail handshake with a typed
protocol_version_mismatch error and exit 2 — verified manually:

    $ uv run amplifier-agent run --protocol-version 0.2.0 --session-id sm 'hi'
    {... "code": "protocol_version_mismatch" ...}
    EXIT=2

    $ uv run amplifier-agent run --protocol-version 0.3.0 --session-id sm 'hi'
    {... "reply": "..." ...}
    EXIT=0

Updated sites (audited via 'git grep "0.2.0" src/ tests/'):

  - src/amplifier_agent_lib/protocol/methods.py — PROTOCOL_VERSION constant
  - src/amplifier_agent_lib/protocol/spec.md — regenerated artifact
  - 9 conformance fixtures' protocolVersion: literals (setup + initialize params)
  - version_skew.yaml — serverVersion in expected error.data
  - 6 test files pinning protocolVersion in wrapper-side InitializeParams

Left as historical references (per release-issue guidance):

  - loader.py docstring example (illustrative fixture shape)
  - test_protocol_conformance_fixtures.py's self-contained _VALID_FIXTURE
    (loader smoke test, not engine-compat)
  - serverInfo.version: "0.2.0" in fixture script result blocks
    (not asserted by conformance harness — engine emits __version__ at
    runtime; fixture scripts are descriptive, only the explicit
    assertions: block is verified)

BREAKING CHANGE: Wire protocol 0.2.0 -> 0.3.0. Old wrappers pinned to 0.2.0
will hard-fail handshake with protocol_version_mismatch (exit 2). Reinstall
both engine and wrapper, or set allowProtocolSkew: true in host config.

* chore(engine)!: bump amplifier-agent version 0.3.0 -> 0.4.0

Engine version bump for the host-config-layer release window. Pairs with
the wire PROTOCOL_VERSION bump (0.2.0 -> 0.3.0) and consolidates argv/wire
surface removals shipped in PRs #27, #29, #30, #31.

Verified:
  $ uv run amplifier-agent --version
  amplifier-agent, version 0.4.0

BREAKING CHANGE: Engine version 0.3.0 -> 0.4.0. Wire protocol 0.2.0 -> 0.3.0
shipped in the same release. Old wrappers fail handshake. See CHANGELOG.md
for the full argv/wire/API removal list.

* chore(wrapper-py)!: bump Python wrapper version 0.3.0 -> 0.4.0

Python wrapper version bump to pair with the engine 0.4.0 release.
Same major.minor as engine — the two move together.

The wrapper's compiled PROTOCOL_VERSION (sourced from amplifier_agent_lib)
follows the engine bump 0.2.0 -> 0.3.0 transitively.

BREAKING CHANGE: SpawnAgentParams API removed envAllowlist, envExtra,
allowProtocolSkew, host, and mcpConfigPath fields across PRs #27, #29, #31.
Callers must migrate to host_config (JSON file passed via --config or
$AMPLIFIER_AGENT_CONFIG) or env var injection (AMPLIFIER_MCP_CONFIG).

* chore(wrapper-ts)!: bump amplifier-agent-ts version 0.4.0 -> 0.5.0

The TS wrapper jumps minor (0.4.0 -> 0.5.0) rather than tracking the
engine's major.minor (0.4.0) because of release-window history:

  - 0.4.0 was already published to npm (verified: 'npm view
    amplifier-agent-ts versions' lists 0.3.0, 0.3.1, 0.4.0)
  - 0.4.0 was published by PR #17 (path-based MCP config delivery,
    pre-#27/#29/#30/#31)
  - Since the 0.4.0 publish, PRs #27, #29, #30, #31 have all landed,
    removing breaking surface from the TS wrapper API:
      * SpawnAgentParams.host / HostCapabilities type (#27)
      * mcpConfigPath field + argv emission (#29)
      * envAllowlist / envExtra / allowProtocolSkew fields (#31)

We cannot republish 0.4.0 with different code, and the accumulated changes
are breaking (not a patch). Bumping to 0.5.0 puts the next npm release on
a fresh, unpublished version. If you have context I'm missing about a
prior decision to keep TS major.minor tied to engine major.minor, override
with a follow-up bump.

BREAKING CHANGE: TS wrapper API removed SpawnAgentParams.host,
HostCapabilities type, InitializeHostParams type (#27); mcpConfigPath field
+ argv emission (#29); envAllowlist, envExtra, allowProtocolSkew fields
(#31). Callers must migrate to AMPLIFIER_MCP_CONFIG env var and a
host_config JSON file passed via --config.

* docs(changelog): consolidate 0.4.0 release notes (PRs #27, #29, #30, #31, #32)

Replace the [Unreleased] section with a full [0.4.0] - 2026-06-03 entry
that consolidates the host-config-layer release window:

  PR #27 - Host config layer + drop hostCapabilities surface
  PR #29 - Drop --mcp-config-path argv (subsumed by host config + env var)
  PR #30 - host-config skills: block + tool-skills bundle composition
  PR #31 - Drop env-allowlist, env-extra, allow-protocol-skew from wrappers
  PR #32 - Restore conformance suite

Highlights:
  - 4 argv flags + 1 env var removed (subsumed by host config layer)
  - hostCapabilities fully removed from envelope, initialize, and wrapper API
  - 5th host-config block 'skills:' (D11/D12/D13)
  - Wire protocol 0.2.0 -> 0.3.0 (BREAKING)
  - Engine 0.3.0 -> 0.4.0, Python wrapper 0.3.0 -> 0.4.0, TS wrapper 0.4.0 -> 0.5.0

Also documents the cross-repo follow-ups that downstream consumers
(notably amplifier-module-provider-nc) must catch up on but are NOT
part of this release.

* fix(ci): commit uv.lock for deterministic dependency resolution

The CI workflow uses astral-sh/setup-uv@v3 with enable-cache: true, which
defaults to globbing **/uv.lock to compute the cache key. With uv.lock
gitignored, every CI run failed at the install step with:

  No matches found for glob **/uv.lock

Committing uv.lock fixes CI and aligns with Astral's recommended practice
for reproducible builds. Catches reproducibility drift between contributors
and CI/DTU. The lock is ~150KB.

This was a pre-existing CI break on main (every recent CI run failing) that
this version-bump release is unblocking as part of release-readiness.

* fix(ci): install Node + pnpm for conformance parity tests

tests/test_conformance_parity.py::test_ts_and_py_runners_agree[*] shells
out to 'pnpm exec tsx runner_ts.ts' to cross-validate the TS runner against
the Python runner. The Python CI job had no Node.js or pnpm installed, so
all 10 parametrized cases failed with:

  FileNotFoundError: [Errno 2] No such file or directory: 'pnpm'

Adds setup-node@v4, pnpm/action-setup@v3, and a pnpm-install step in
wrappers/conformance/ before pytest runs. Pre-existing CI gap that this
release branch is closing as part of release-readiness.

* fix(ci): make XDG test hermetic + delete obsolete --mcp-servers tests

Closes the last 4 Python CI failures on this release branch.

(1) tests/cli/test_config_show.py::test_config_show_reports_default_when_env_absent

Click's CliRunner.invoke(env=...) MERGES the env dict with os.environ instead
of replacing it. GitHub Actions runners set XDG_CONFIG_HOME by default, which
leaked into the test and made source='env:XDG_CONFIG_HOME' instead of the
'default' the test was asserting. Now uses monkeypatch.delenv() to explicitly
remove XDG_CONFIG_HOME / XDG_CACHE_HOME / XDG_STATE_HOME before invoking.

(2) tests/cli/test_mode_a_v2_envelope.py

The three test_mcp_servers_* tests (inline_json_parsed, at_path_form,
malformed_json_yields_argv_envelope) target the --mcp-servers argv flag.
That flag was renamed to --mcp-config-path by PR #24 and then fully removed
by PR #29. The tests have been failing as 'pre-existing baseline' through
PRs #27, #29, #31, #32, and #33's earlier baselines. They test removed
surface and should never have been kept.

Replaced with an inline comment naming the removal context and pointing at
the removal guardrail at tests/cli/test_drop_mcp_config_path_flag.py.

Local: 532 passed, 3 skipped, 0 failed (full pytest tests/).

---------

Co-authored-by: Manoj Prabhakar Paidiparthy <mpaidiparthy@microsoft.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant