Skip to content

operations: mctl-agents-investigate drops agent_image/agent_version (release pin is dead) and needs loop-id params #372

Closed

Description

@mashkovd

Problem

StripUndeclared (internal/api/handlers_write.go:83) silently drops every operation parameter the registry does not declare. For mctl-agents-investigate, the registry (internal/operations/registry.go:649-661) declares only issue_url, work_item_id and execution_id.

  1. The investigator release pin is dead today. The DevLoop resolves the pinned issue-investigator release and sends agent_image and agent_version (mctl-agents orchestrator/temporal/workflows/dev_loop.py, investigate step). The CWFT declares both parameters, but mctl-api strips them, so every investigate run uses the CWFT's default image. Registry promotions and rollbacks of the investigator therefore have no effect on DevLoop runs.
  2. Loop-identity params for mctl-agents#461 and chore(main): release 4.61.0 #451. mctl-gitops is adding optional temporal_workflow_id, temporal_run_id and execution_request_id to the investigate CWFT. A dispatched loop is dev-loop-xr_*, not the issue-keyed id, so the investigator must learn the real loop id. They need the same declaration here, or they are dropped as well.
  3. human_input_responses (the DevLoop continuation) is dropped too. The CWFT does not declare it either, so that one is a gitops + mctl-api pair.

Fix

  • Declare agent_image and agent_version for mctl-agents-investigate, with patterns matching the image-ref and <agent>@<version> shapes used elsewhere in the registry. Check the other mctl-agents-* operations that the DevLoop pins the same way.
  • After the gitops CWFT change lands (gitops first, fail-closed), declare temporal_workflow_id, temporal_run_id and execution_request_id as optional, following work_item_id/execution_id.
  • Add a test that every parameter the DevLoop sends for each operation is declared, or equivalently that none of them hits dropped.

Refs mctlhq/mctl-agents#461, mctlhq/mctl-agents#451.

🤖 Generated with Claude Code

https://claude.ai/code/session_01TpRNAyt63CpPb9xpQPBy2G

Activity

  1. mashkovd commented on Sep 23, 2026

    @mashkovd
    MemberAuthor

    Part 1 merged in #378: the DevLoop release pins agent_image/agent_version on investigate, implement, shepherd and incidents, with OmitWhenEmpty so unpinned callers keep the CWFT default.

    Still open here:

    • Loop-id params (temporal_workflow_id, temporal_run_id, execution_request_id). The gitops half is merged (mctl-gitops#1345). Declare them here only after the mctl-agents release that teaches the investigator CLI those flags; otherwise the CLI exits on an unknown flag.
    • human_input_responses. It needs the investigate CWFT declaration first.

    P3 follow-ups from the #378 review:

    • Cross-field check: reject agent_version without agent_image, and when the image is a tag, require the version's semver to match it.
    • Add an invariant test !(OmitWhenEmpty && Default != "") over builtinOperations, and note on the field that Default is ignored.
    • mctl-agents incidents.py (~101-105) wrongly says mctl-api passes undeclared params through. Correct that comment.
  2. mashkovd commented on Sep 24, 2026

    @mashkovd
    MemberAuthor

    Update after mctlhq/mctl-agents#487 (#461 option A, merged b68291c): dispatched loops are now issue-keyed, so the rationale in point 2 ("a dispatched loop is dev-loop-xr_*") no longer holds.

    Consumers were checked before deciding what to retire, and the declaration should stay:

    • temporal_run_id is still what retires a same-id leftover (mctl-agents#451).
    • execution_request_id is still sealed into the snapshot correlation.
    • temporal_workflow_id is now derivable from issue_url, but the investigator still prefers the loop's own id over its derivation. Keeping it declared costs nothing, and dropping it would silently break the correlation for any loop whose id is not derivable.

    Points 1 (agent_image/agent_version) and 3 (human_input_responses) are unaffected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions