Skip to content

launch-task: derive worker report address from the launcher's identity#230

Open
gnguralnick wants to merge 3 commits into
mainfrom
mngr/fix-lead-agent-resolution
Open

launch-task: derive worker report address from the launcher's identity#230
gnguralnick wants to merge 3 commits into
mainfrom
mngr/fix-lead-agent-resolution

Conversation

@gnguralnick

@gnguralnick gnguralnick commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Problem

A worker reports back by mngr rsync-ing its report to the lead_agent named in its task file's frontmatter. That value was author-supplied, so it could be wrong: a task file authored with the Write tool (instead of a cat <<EOF heredoc) carries a literal, unexpanded lead_agent: $MNGR_AGENT_NAME; a value can also be stale or omitted. In any of those cases the worker has no valid address — it finishes successfully but the report never lands at the lead's finish_report_path, and the lead's await poll waits until timeout. The failure is silent.

This was hit in practice: an update-pr-review harden worker completed all gates but could not deliver its report.

Fix

Stop trusting the task file for this at all. The agent running create_worker.launch is the lead that polls for the report, so its own MNGR_AGENT_NAME is the authoritative lead_agent. launch now stamps it into the task file before provisioning, overwriting whatever the file holds (and inserting it if absent). Authors no longer need to set the field.

Fallback for non-agent contexts: when MNGR_AGENT_NAME is unset (e.g. launch run manually or in a test), the file's existing value is used; an unresolved value (missing, blank, or an unexpanded $…) in that case is fatal (exit 2) rather than launching an unaddressable worker.

This assumes the launcher is always the report recipient, which holds throughout this codebase (the launcher is the poller). A future cross-agent dispatch would add an explicit recipient argument rather than reviving the trust-the-file behavior.

Tests

create_worker_test.py:

  • literal $MNGR_AGENT_NAME is replaced from the env
  • a resolved file value is overridden by the env (launcher identity wins)
  • an absent field is injected from the env (siblings preserved)
  • no env + unresolved value aborts before provisioning (exit 2, no mngr create)
  • no env + resolved value is accepted as a fallback
  • _set_frontmatter_field replace / insert / no-frontmatter behavior

uv run pytest .agents/skills/launch-task/scripts/create_worker_test.py → 53 passed.

Note: the branch has two commits — the initial conservative fix and this follow-up making the env authoritative — kept separate per the repo's no-rebase rule.

🤖 Generated with Claude Code

runtime-backup and others added 2 commits June 30, 2026 16:29
A task file authored with the Write tool (rather than the documented
heredoc) can carry a literal `lead_agent: $MNGR_AGENT_NAME` because no
shell expansion runs. The worker then has no valid address to rsync its
report to, so it silently never reports back and the lead's poll waits
until timeout.

create_worker.launch now resolves lead_agent before provisioning: if the
value is unresolved (missing, empty, or contains an unexpanded `$...`),
it is rewritten to the launching agent's MNGR_AGENT_NAME (the agent that
will poll for the report). If the value is unresolved and MNGR_AGENT_NAME
is unset, launch fails fast (exit 2) instead of creating an
unaddressable worker. Already-resolved author-set names are left
untouched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Don't trust the task file's lead_agent at all when the launcher knows its
own identity. The agent running `launch` IS the lead that polls for the
report, so its MNGR_AGENT_NAME is authoritative: stamp it into the task
file, overwriting whatever the file holds (a literal $MNGR_AGENT_NAME, a
stale name, or nothing). Authors no longer need to set the field.

The file value is used only as a fallback when MNGR_AGENT_NAME is unset
(launch run outside an mngr agent, e.g. manually or in tests); an
unresolved value in that case is still fatal (exit 2).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gnguralnick gnguralnick changed the title launch-task: resolve unexpanded lead_agent at worker launch launch-task: derive worker report address from the launcher's identity Jun 30, 2026
The worker launcher now stamps lead_agent from its own MNGR_AGENT_NAME,
so task-file authors no longer set it. Remove the lead_agent line from
every task-file frontmatter template and drop it from the prose that
listed the reporting fields, across launch-task, crystallize-artifact,
update-artifact, heal-artifact, update-system-interface, and
use-ai-integration. finish_report_path stays author-supplied.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Comment on lines +271 to +272
except yaml.YAMLError:
return None # malformed YAML surfaces later via _read_source_artifacts_dir

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.

sure, but why not let it blow up right away?

@joshalbrecht

Copy link
Copy Markdown
Contributor

lgtm except for my one minor comment

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.

2 participants