crewship hire / crewship rehire
hire provisions a short-lived agent from a template into an existing crew, gives it a TTL, and writes a hire_reason audit row. The agent runs like any permanent crew member until its TTL elapses, at which point a background sweeper ghosts it (sets expired_at, keeps the row + memory files for audit + rehire).
rehire resets the TTL on a ghost (or a still-live ephemeral whose operator wants to extend before it ghosts). Same row, same id, same memory files — the agent picks up exactly where it left off, with full continuity.
For the lifecycle walkthrough and operator workflows see Ephemeral agents. This page is the canonical CLI reference: flags, error codes, exit semantics.
Per-autonomy-level response
Both commands route through the per-crewautonomy_level policy gate (PR-B F2). The crew’s setting determines what happens to the hire:
See Autonomy + self-learning for the matrix and where to set the autonomy level.
crewship hire
Flags
Response
hireResponse in internal/api/agents_hire.go. inbox_item_id is added only when a guided hire creates a blocking inbox waitpoint.)
Auto-assigned credentials
On a successful hire, Crewship automatically assigns the available workspace Anthropic credential (typeAPI_KEY or AI_CLI_TOKEN, ordered by creation
date) to the new ephemeral agent, so it can authenticate on first run. This is
best-effort and never blocks the hire:
- No Anthropic credential in the workspace → the hire still succeeds and the
agent journals
credential.auto_assign_empty; the agent will fail to chat until you add one and rehire (or assign manually). - You can always override afterwards with
crewship credential assign <agent> <credential>.
Exit codes
The CLI exits0 on success (a 201 live hire or a 202 pending-review hire) and 1 on any failure — the error text printed to stderr names the cause. Common failure causes and the message they carry:
Waiting for a guided approval (--wait)
guided-autonomy crew the hire lands as 202 PENDING_REVIEW and
needs an operator to run crewship hire approve <agent> before the agent
can chat. --wait polls GET /api/v1/agents/{id} (the same route
crewship agent get uses) every --wait-interval until the status flips
away from PENDING_REVIEW (approved) or the hire ghosts — its TTL elapses
before anyone approves it, which the CLI also treats as a resolved (failing)
outcome so --wait doesn’t hang forever on an abandoned approval. There is
no explicit “denied” state today; a rejected hire is left to expire.
--ttl clamping
The clamp is entirely server-side and silent — the CLI forwards ttl_minutes as-is and does not pre-validate or warn. An out-of-range value (e.g. --ttl 10) still produces a successful hire; the server clamps it into [30, 1440] and the effective value comes back in expires_at (now() + clamped_ttl). Read expires_at on the response to confirm the TTL that actually landed.
crewship rehire
Flags
Effect on the agent row
Quota interaction
- Rehiring a ghost does NOT count against
crews.max_ephemeral_agents— the ghost row already exists; rehire just togglesexpired_atto NULL. - Rehiring a still-live ephemeral is also free for the same reason (same row).
- Hiring a fresh ephemeral when the quota is full returns 429 — at that point the operator either raises the quota or rehires a ghost instead of hiring fresh.
Exit codes
Same ashire: 0 on success, 1 on any failure with the cause in the stderr message. Rehire-specific failures:
- The agent isn’t ephemeral (you can’t rehire a permanent agent — the lifecycle doesn’t apply).
- The policy rejects rehire on a
strictcrew (matches the hire rejection — re-promoting a ghost still needs policy approval).
crewship hire approve
Approve a guided-autonomy hire that is parked in PENDING_REVIEW, flipping it to IDLE so it can serve work. This is the terminal counterpart to the UI inbox “Approve” button.
crewship hire and shown in crewship agent list) as its single positional argument, and calls POST /api/v1/agents/{id}/approve-hire. A 409 comes back if the agent isn’t in PENDING_REVIEW (already approved, or hired under a non-guided autonomy level).
Listing ephemeral agents
crewship agent list shows every agent in the workspace, ephemerals included. Scope to one crew with --crew:
expired_at / expires_at fields. Use --format json and jq if you want to filter to just the live or ghost rows:
TTL mid-mission grace
The sweeper that ghosts expired ephemerals (internal/ephemeral/expiry.go, 5-minute ticker) skips agents with status='RUNNING'. A mission in flight finishes even if its TTL elapsed mid-call; the agent ghosts on the next sweep after it idles back to IDLE. This avoids the worst-case “agent was mid-tool-call when ghost flag fired” scenario.
The trade-off is that a long-running ephemeral can outlive its TTL by up to one sweep interval (5 min). For stricter timing, provision a permanent agent and crewship agent delete <id> explicitly.
LEAD-driven hire from inside a container
ALEAD-mode agent in active orchestration can hire a sub-agent via the sidecar /spawn endpoint without an operator running crewship hire. The sidecar proxies the request to POST /api/v1/internal/agents/hire and injects MANAGER role into the request context; the policy gate still fires (a strict crew rejects LEAD-driven hires too — autonomy_level is the security boundary, not RBAC).
See Ephemeral agents — LEAD-driven hire for the full pattern, including the AgentBrief primitive for handing curated context to the sub-agent.
Related
- Ephemeral agents — operator playbook with workflow scenarios
- Autonomy + self-learning — the policy matrix that gates hire decisions
- AgentBrief — sub-agent briefing primitive used by LEAD-driven hires
crewship policy— set the crew’s autonomy_level before hiring against itcrewship inbox— approve / dismiss the pending-review hire entries for guided crews