Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.crewship.ai/llms.txt

Use this file to discover all available pages before exploring further.

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.
crewship hire   --crew <slug> --template <name> --reason <text> [flags]
crewship rehire <agent-slug-or-id>             --reason <text> [flags]

Per-autonomy-level response

Both commands route through the per-crew autonomy_level policy gate (PR-B F2). The crew’s setting determines what happens to the hire:
Crew autonomyHire responseRehire response
strictRejected (403) — ephemeral spawn is forbidden on compliance-grade crews.Rejected (403) — same reason.
guidedPending review (202) — agent row created with status='PENDING_REVIEW'. Chatbridge refuses to start the agent until an operator approves via inbox.Same — re-promotion of a ghost still requires operator approval.
trustedLive immediately (201) + non-blocking inbox notification.Same.
fullLive immediately (201) + journal-only logging.Same.
See Autonomy + self-learning for the matrix and where to set the autonomy level.

crewship hire

crewship hire \
  --crew on-call \
  --template incident-responder \
  --ttl 240 \
  --reason "P1 incident #4582 needs sustained eyes-on"

Flags

FlagRequiredDefaultDescription
--crewyesCrew slug or ID to hire into. The agent inherits this crew’s MCP config, network policy, container image, and autonomy_level.
--templateyesBuilt-in agent template that defines the role + system prompt skeleton + CLI adapter (e.g. incident-responder, code-reviewer, release-manager).
--reasonyesFree-form audit text. Appended to agents.hire_reason as a chronological history (rehires also append; the column reads as the agent’s lifecycle narrative).
--ttloptional60Time-to-live in minutes. Server-clamped to [30, 1440] (30 min minimum prevents trivial-hire abuse; 24 hr maximum enforces the “ephemeral” framing — longer work hires a permanent agent).
--modeloptionaltemplate defaultOverride the LLM model for this hire. Useful when the template defaults to Sonnet but the work needs Opus.
--parent-leadoptionalAgent ID of the LEAD that initiated this hire (LEAD-driven sub-agent spawning). Links the rows for journal queries.
--ws-id / --wsoptionalactiveWorkspace override; defaults to the workspace from the active CLI token.
--outputoptionaltabletable or json for the hire response.
--yesoptionalfalseSkip interactive confirmation prompts.

Response

{
  "id": "agt_…",
  "slug": "incident-responder-a3f8",
  "crew_id": "crw_…",
  "crew_slug": "on-call",
  "ephemeral": true,
  "status": "IDLE",
  "expires_at": "2026-05-22T05:42:00Z",
  "hire_reason": "2026-05-21T01:42:00Z: P1 incident #4582 needs sustained eyes-on",
  "decision": "auto_log_inbox",
  "policy": { "autonomy_level": "trusted", "behavior_mode": "warn" }
}
FieldNotes
statusIDLE for trusted/full crews; PENDING_REVIEW for guided crews (chatbridge refuses to start until approved via inbox).
decisionThe policy decision that landed this hire — auto_journal (full) / auto_log_inbox (trusted) / inbox_approve (guided) / rejected (strict).
expires_atRFC3339 UTC. Set to now() + ttl_minutes.
hire_reasonAccumulating history — each hire/rehire appends <timestamp>: <reason>.

Exit codes

CodeMeaning
0Hire succeeded (201 or 202).
2Validation failure — missing required flag, TTL out of range, unknown crew/template.
3Policy rejection (strict crew refused ephemeral_spawn — exit message names the autonomy_level).
4Quota exceeded (crews.max_ephemeral_agents reached — exit message names the live count + max).
5Network / server error (5xx).

--ttl clamping

$ crewship hire --crew ops --template debug --reason x --ttl 10
warning: --ttl 10 below minimum (30); using 30
The server-side clamp is authoritative (the CLI just warns). An out-of-range TTL still produces a successful hire at the clamped value; the warning lets the operator know their input was adjusted.

crewship rehire

crewship rehire incident-responder-a3f8 \
  --ttl 120 \
  --reason "incident #4582 stretched into a sustained-fire investigation"

Flags

FlagRequiredDefaultDescription
agent (positional)yesSlug or ID of the ephemeral agent. Can be a ghost (expired_at != NULL) — that’s the canonical rehire case — or a still-live ephemeral whose operator wants to extend before it ghosts.
--reasonyesAudit text appended to hire_reason.
--ttloptional60New TTL in minutes. Resets expires_at to now() + ttl. Same [30, 1440] clamp as hire.
--ws-id / --wsoptionalactiveWorkspace override.
--outputoptionaltabletable or json.

Effect on the agent row

ColumnBefore rehire (ghost)After rehire
expires_atpast timestampnow() + ttl
expired_atnon-NULLNULL (un-ghost)
hire_reasoninitial-hire historyhistory + new line with timestamp + reason
id / slug / crew_id / memory filesunchangedunchanged — full continuity

Quota interaction

  • Rehiring a ghost does NOT count against crews.max_ephemeral_agents — the ghost row already exists; rehire just toggles expired_at to 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 as hire (0 / 2 / 3 / 4 / 5). Rehire-specific:
  • Exit 2 when the agent isn’t ephemeral (you can’t rehire a permanent agent — the lifecycle doesn’t apply).
  • Exit 3 when the policy rejects rehire on a strict crew (matches the hire rejection — re-promoting a ghost still needs policy approval).

Listing ephemeral agents

crewship agent list shows ephemerals by default; filter to just the live ones:
crewship agent list --crew on-call --ephemeral live
FilterMeaning
--ephemeral allBoth live and ghost (default).
--ephemeral liveephemeral=1 AND expired_at IS NULL.
--ephemeral ghostephemeral=1 AND expired_at IS NOT NULL.
--ephemeral nonePermanent agents only (ephemeral=0).

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

A LEAD-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.