Skip to content

spawn: pkg/aws.Launch needs a ClientToken + classifiable errors to back cohort's Actuator #108

Description

@scttfrdmn

Context

queuezero's cohort core reconciles named, single-entity launches and depends on two provider-seam guarantees (q0 non-negotiables #4 and #5):

spawn's pkg/aws.Client.Launch(ctx, LaunchConfig) (*LaunchResult, error) already has the right shape (one named instance per call, rich tag-driven config), which is exactly why it's the natural candidate to back cohort's Actuator once cohort graduates into this monorepo (ARCHITECTURE §15). But two gaps block that today:

1. No ClientToken on RunInstances

pkg/aws/client.go (~line 352) issues RunInstances with MinCount=1, MaxCount=1 and no ClientToken. Without it, a retry after a network timeout can double-launch, and the caller can't distinguish "launch succeeded but the response was lost" from "launch never happened" — that's the Ambiguous fault class cohort is designed never to see.

2. Opaque errors

The launch path wraps failures as fmt.Errorf("failed to run instances: %w", err). The verbatim AWS error code (InsufficientInstanceCapacity, RequestLimitExceeded, Unsupported, spot MaxSpotInstanceCountExceeded, …) survives in the %w chain but there's no exported way to get it as a classifiable value — cohort needs to branch on capacity-vs-quota-vs-config to drive fast-fail vs fallback-rung vs lagotto-watch.

(For reference, pkg/orchestrator.scaleUp uses the MinCount==MaxCount==count count-based fleet pattern — that one is the count-based abstraction cohort retires wholesale and is not what this issue asks to fix; this is only about the single-entity Launch.)

Ask

So that spawn/pkg/aws.Launch can legitimately fill cohort's Actuator:

  1. Add a ClientToken string field to LaunchConfig (or accept it as an explicit arg) and pass it through to RunInstancesInput.ClientToken. Caller supplies the deterministic token; spawn just plumbs it.
  2. Either (a) return the underlying smithy.APIError unwrapped/typed so callers can classify on ErrorCode(), or (b) expose a small exported error type carrying the verbatim code. Do not paraphrase the code.

Neither change alters spawn's existing CLI behavior (token optional → today's behavior; error wrapping can stay, just stop hiding the code).

Acceptance

  • Launch accepts a caller-supplied ClientToken and forwards it to RunInstances.
  • A capacity/quota/config failure from Launch is recoverable as a Go value with the verbatim AWS error code intact.

Filed from queuezero's spawn/spored leverage review (post Phase 2m, the first spore.host dep — truffle — having landed). This is the launch-side half of the convergence; the readiness/sensor half is #333.


Migrated from spore-host/spore-host#335 — spawn issues belong on this repo.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:launchlaunch path: instance-type, AMI, user-data, runarea:queuezeroqueuezero/cohort convergence (provider seam)enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions