Skip to content

fix(spawn): bind every real positional arg of a spawned callable (calque#191) - #193

Merged
scttfrdmn merged 1 commit into
mainfrom
fix/calque-191-spawn-multiarg-binding
Aug 15, 2026
Merged

fix(spawn): bind every real positional arg of a spawned callable (calque#191)#193
scttfrdmn merged 1 commit into
mainfrom
fix/calque-191-spawn-multiarg-binding

Conversation

@scttfrdmn

Copy link
Copy Markdown
Contributor

Summary

Verification

Went beyond manifest-field inspection: TestSpawnDictDispatchMultiArgBindingEndToEnd drives the real fixture's bundle(job_id, config) through the actual warm.Supervisor + runner.py subprocess and asserts the actual returned values for both args — mirroring TestStarmapEndToEndDryRun's own proof strength (real execution, real result, not just "didn't crash" or "field is set"). Also extended spawn_dict_dispatch.py's fixture to return both args so this assertion is possible.

Files touched

  • internal/exec/spawnshard.goSpawnCallable.MethodArgs, nonSelfCls, updated ResolveSpawnCallables/ResolveOneSpawnCallable.
  • internal/exec/spawnshard_test.go — new unit tests for MethodArgs population (plain function + class method, self-stripping).
  • cmd/calque/spawnrun.go — new spawnManifestBody pure function, wired into runSpawnShard.
  • cmd/calque/spawnrun_test.go (new) — unit tests for spawnManifestBody's splat-routing decision.
  • cmd/calque/spawn_dict_dispatch_e2e_test.go — new real-execution end-to-end test.
  • testdata/scripts/spawn_dict_dispatch.py — fixture extended to return both args.
  • CHANGELOG.md.

Test plan

  • go build ./... && go vet ./... && gofmt -l . && go test -count=1 ./... — all pass
  • golangci-lint run ./... — 0 issues
  • ruff check . — all checks passed
  • TestSpawnDictDispatchMultiArgBindingEndToEnd — real subprocess execution, confirms both job_id and config bind to their real supplied values

… just the first (calque#191)

SpawnCallable.MethodArg only ever carried the FIRST non-self/cls
parameter name -- a callable like AI-Almanac's forecasts_app.py's
run_forecast_inference(job_id, model_id, config) would (once calque#189's
target-resolution fix landed) build a real shard but silently leave
model_id/config undefined inside the worker on real hardware. The same
class of arity gap calque#187 fixed for run/real/fleetrun, but
spawn-run's own separate driver (internal/exec/spawnshard.go) had no
equivalent.

New SpawnCallable.MethodArgs carries the full non-self/cls arg list
(ResolveSpawnCallables/ResolveOneSpawnCallable populate it via a new
nonSelfCls helper). spawnManifestBody (cmd/calque/spawnrun.go) routes a
2+-arg callable through the SAME Starmap/MethodArgs splat mechanism
.starmap() already uses in runner.py -- spawnArgsPayload was already
building the right list payload, nothing downstream consumed it as a
splat until now. A single-arg callable is byte-for-byte unchanged.

Verified with a real subprocess execution test
(TestSpawnDictDispatchMultiArgBindingEndToEnd) asserting both args'
actual bound values through the real warm.Supervisor + runner.py, not
just manifest-field inspection -- mirroring TestStarmapEndToEndDryRun's
own proof strength.
@scttfrdmn
scttfrdmn merged commit 774f8b9 into main Aug 15, 2026
7 checks passed
@scttfrdmn
scttfrdmn deleted the fix/calque-191-spawn-multiarg-binding branch August 15, 2026 22:21
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