deploy: bind Agent Runtime updates to recorded resource identity
- Dominant language
- Python
- Stars
- 5.9k
- Forks
- 660
- PR merge metrics
- No merged PRs in 30d
Description
## Summary
Agent Runtime updates are selected by `display_name` on the v1.3.1 source baseline. A display name is not a unique resource identity, so an update can target an arbitrary same-name Reasoning Engine.
Baseline: `5a306f8956cb1eeae69f9709de0e4d61b44e11e7` (v1.3.1).
## Reproduction
1. Deploy an `agent_runtime` project and keep its generated `deployment_metadata.json`.
2. Create a second Reasoning Engine in the same project/location with the same display name.
3. Run `agents-cli deploy` again.
4. Separately, remove the metadata file and repeat with 0, 1, and 2 same-name resources.
## Actual behavior
The baseline lists by display name and uses the first match. With duplicate names, selection depends on list order and a mutation may be sent to the wrong resource.
## Expected behavior
1. If `deployment_metadata.json.remote_agent_runtime_id` exists, fetch exactly that resource by ID.
2. Before mutation, validate its project number, location, deployment target, resource name, and actual display name.
3. Reject stale or inconsistent metadata.
4. Only without usable metadata: create for 0 matches, update for exactly 1 match, and reject 2+ matches before any create/update API call.
5. Revalidate after acquiring the local deployment-operation claim so a concurrently changed target cannot be mutated.
## Minimal fix
Resolve the target in one shared selector that prefers the recorded resource ID and fails closed on every mismatch. Treat display-name lookup only as the metadata-free fallback and require it to be unambiguous. Atomically update metadata only after a successful mutation.
Reference implementation and regressions: [fork Batch 4 branch](https://github.com/benagentai93-dot/agents-cli/tree/codex/batch-4-runtime-identity-sdk-contract).
## Verification evidence
- Targeted identity/lifecycle suite: 35 tests passed under a fresh reviewer; full local suite: 92 passed.
- Multiple same-name case asserted zero calls to create/update/identity-create.
- Disposable isolated GCP project acceptance:
- create returned one recorded resource ID;
- update retained the same resource ID;
- after temporarily removing metadata and creating a second same-name resource, the CLI rejected before mutation;
- cleanup found 0 Reasoning Engines and 0 unfinished operations;
- project lifecycle was confirmed as `DELETE_REQUESTED`.
- `ruff check src tests`, `ty check src`, build, and Python 3.11/3.13 installed-wheel smoke tests passed.
Contributor guide
Assessment
This issue has not been assessed yet.