SkyPilot Workflows
SkillProductivityUse when running or debugging how the engine renders and submits SkyPilot from an npa.workflow spec: invocation, SkyPilot limits, JobGroups, multi-node tasks, runner scripts, and cleanup. For authoring, use author-npa-workflow.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the SkyPilot Workflows skill
What this skill tells your AI
The instructions your AI receives, as published by nebius/nebius-physical-ai in skills/tools/skypilot-workflows/SKILL.md and read by ahel’s review.
For teardown after project/config removal, use the existing immutable teardown
receipt (npa skypilot cleanup-controller --receipt <id> --context <context> --yes). A terminal receipt or exact provider-verified missing cluster is a no-op
without bootstrapping SkyPilot. Otherwise cleanup stays bound to the exact
recorded project/context and preserves local controller state until remote
absence is independently verified. Never fall back to the current kube context
or an unrelated SkyPilot profile.
SkyPilot is the workflow execution engine in this repo. Argo is deprecated; do not add or revive Argo workflows.
SkyPilot is not the repository authoring surface. Pipelines are
npa.workflow/v0.0.1 specs, and the engine plans those specs and renders
SkyPilot tasks. Use skills/workflows/author-npa-workflow/SKILL.md to author a
pipeline. The retired raw-task catalog must not return; raw SkyPilot input is
still accepted for customer-provided tasks and guarded tool-specific examples.
Invocation
SkyPilot lives in an isolated virtualenv outside NPA's main Python environment. Invoke it through NPA_SKYPILOT_BIN; never rely on sky from PATH.
Use npa skypilot bootstrap to create or reuse the pinned SkyPilot 0.12.2
venv, then set NPA_SKYPILOT_BIN="$(npa skypilot status --bin-path)".
The Kubernetes controller is the default path (W9-skypilot-k8s-controller). The VM controller exists only as a fallback.
For workflows that write S3 state or artifacts, supply config.bucket and a
run-scoped config.prefix, even when their declared output URIs are absolute.
NPA_CONFIG_DIR selects NPA configuration; set KUBECONFIG separately to the
verified file containing the selected cluster context. An isolated configuration
must also resolve the authorized S3 endpoint and credentials through supported
private sources or the child process environment. Keep credential values out of
arguments and logs. A successful structural render or --plan-only does not
prove these live submission prerequisites.
Preserve a failed submission intent and inspect the exact run state before
recovering from a preflight failure; do not delete the intent or assume a failed
CLI exit means no launch occurred.
Known SkyPilot 0.12.2 Limits
- Raw SkyPilot
envsdoes not support self-referencing variable interpolation. Repository specs use resolvedconfigtokens instead. sky jobs launchhas no dry-run flag. For a spec, useworkflow submit --plan-onlyto inspect the rendered plan without launching.- Mixed serial/parallel task groups are expressed in the spec. The runtime
driver emits a SkyPilot JobGroup for each
parallel:wave and submits the following state as its barrier. - Managed-job Python API
Dagsupport is effectively single-task for this repo's burst path. Usenpa burst submit-yamlonly for rendered single-task SkyPilot YAMLs; usenpa workbench workflow submitfor multi-stage workbench YAMLs. - Direct Nebius burst jobs pull
resources.image_idbefore YAMLsetupruns. Official public GHCR development and release tags need no registry secret. Operator-controlled private registries require explicit exact-host SkyPilot Docker credentials; NPA forwards them but never mints a provider token. - The standard Kubernetes template derives the provider namespace from the
selected kubeconfig context. In 0.12.2, native pod creation overwrites
pod_config.metadata.namespacewith that provider namespace. Before using existing PVCs or Secrets, configure a workload-specific context with their namespace and verify the resulting pod namespace after submission.
What the Renderer Emits
npa/src/npa/orchestration/npa_workflow/skypilot_render.py turns a planned spec
into SkyPilot documents:
- A
parallel:wave becomes a SkyPilot JobGroup;maxConcurrencysplits a larger group into batches. num_nodesis emitted at the SkyPilot task level. SkyPilot gang-schedules the pods and exportsSKYPILOT_NODE_RANKandSKYPILOT_NODE_IPStoruncommands. Do not assume rank is available duringsetup.- Package extras, third-party requirements, source staging, and vendor interpreters are selected from the toolRef.
- A self-hosted service that must survive into the task command belongs in the
run preamble, not in
setup. - Isaac-routed stages carry
ACCEPT_EULA=Yby default. An explicit--no-accept-eularenders and forwards an empty value, including through Kubernetes Sim2Real paths, and fails before download. Generic BYOF routes are gated only whenconfig.base_profileorconfig.base_imageselects Isaac; GR00T routes are gated only for Isaac simulation.
Live Debugging Traps
Native Ray development
Do not infer SkyPilot compatibility from image pullability or local Docker
success. The non-root LanceDB image lacks the sudo needed by SkyPilot's SSH
bootstrap. The guarded CLIP development example therefore reuses an immutable
public PyTorch image and prepares a separately pinned Ray application environment.
The target policy must permit that image's root user inside an unprivileged pod;
this does not grant host-root or privileged-container access.
Record the image digest and prepared dependency freeze separately: the digest
does not attest later pip installations. Its Python 3.12 has pip but no ensurepip;
use the tested venv --system-site-packages --without-pip preparation. This
qualifies the canonical Workbench CLIP UDF and LanceDB library, not the published
LanceDB service image or HTTP backfill API.
The tool-specific development cluster is
npa/workflows/workbench/ray-clip-development/cluster.yaml; the complete customer
journey is Run and edit a GPU Ray application.
This is a customer development task, not a second workflow catalog. SkyPilot
owns the named cluster and its application service task. Ray Jobs owns application
submission, logs, status and cancellation, using its public CLI/SDK. Ray
runtime_env.working_dir transfers ordinary application Python and the exact
Workbench UDF; no NPA source overlay or custom submit/finalize protocol is used.
Persist and verify application outputs before cancelling the exact service task
and removing the named development cluster with SkyPilot. Shared SkyPilot API
services and the underlying configured Kubernetes cluster remain operator-owned.
The guide includes a separately owned upstream API Compose contract for hosts
without a suitable API: it mounts explicit backend credentials read-only, keeps
its own state volume and fixed namespace, and verifies a completed dry run.
Do not copy another API's state, patch its backend or stop its processes to make
a development submit work. Remove an owned API only after all its development
clusters are gone; preserve a platform supplied by another operator.
Keep application Ray in its own environment with explicit addresses and separate
ports. Never connect through ambient management-Ray discovery or use ray stop.
Jobs/Dashboard binds to loopback behind an authenticated SSH tunnel. The startup
script runs ray start --block; SkyPilot owns that task's process lifetime.
SkyPilot 0.12.2 uses management Ray 2.9.3 with a head worker range of
11002–65535. Keep application service and worker ports below 11002, avoid fixed
management ports, and verify the OS ephemeral range starts above the application's
highest port. The example worker range is 10010–10999. Keep Jobs drivers on the
head when application checkpoints and aggregation outputs use its local disk.
Verify Jobs readiness and the expected GPU/node resources before submission.
New Ray source submissions create new actors and reload model weights; this is source redeployment, not hot reload. Python edits within the prepared dependency boundary require no image rebuild. Native/ABI changes require a compatible image. Report cold environment preparation and model loading separately from source iteration. For distributed checks match the GPU actor count to available GPUs and report actual node/GPU placement; several GPUs on one node are not multi-node validation. Review imported source hashes, persisted vectors and retrieval results after each source edit.
Existing NPA runtime
- A vendor image may put a stale npa tree on
PYTHONPATH; the renderer stages the selected source first and runs the recorded interpreter. - Operator wrappers must set
NPA_LIVE_WTto an existing, durable worktree and fail before submission when it is missing. Never fall back to an ambient checkout: a vanished/tmpworktree once made the harness test another contributor's tree and report a misleading skip. - The
NPA_SRC_S3_URIoverlay has no embedded provenance. Re-stage it after a source change before diagnosing a renamed flag in a live pod. - An unresolved placeholder in rendered setup is rejected before submission.
- With a remote SkyPilot API server, inspect its effective kubeconfig and selected context namespace. A correct client-side context or rendered pod metadata does not establish the server's namespace. Keep API health, namespace selection and actual pod placement as separate checks; see the upstream API server configuration guide.
Reference Pattern
- Canonical spec:
workflows/testing/bdd100k-pipeline.yaml. - Runner script pattern:
npa/scripts/run_bdd100k_pipeline.py, a thin wrapper aroundnpa.orchestration.skypilot.submit_workflow. - Isaac Lab runners follow the same shape through
npa/scripts/run_isaac_lab_rl.py.
Commit And Cleanup
Acquire /tmp/npa-commit-lock/workflows-skypilot before committing workflow files in parallel-run contexts.
Cleanup is best-effort and must not raise. also_teardown_controller=False is
the safe default; only opt into controller teardown when no other run can be
using it. Explicit controller teardown requires a single NPA project and its
exact saved Kubernetes context, cross-checks stable provider identity, performs
remote deletion against a clone of SkyPilot state, independently proves remote
absence, checkpoints that evidence, and only then converges the matching local
metadata. Authentication/RBAC/connectivity/identity uncertainty preserves local
state; never fall back to an ambient context or unrelated SkyPilot profile.
Runtime-orchestrated workflows persist one immutable managed-job identity per wave and attempt. Status and cancellation use that identity for only the wave's encoded stage members; retries remain historical records and the final attempt is selected deterministically. A discovered/root job ID must never be broadcast across runtime stages. Conflicting or missing history is reported as ambiguous or unknown. Root-ID fan-out is compatible only with the legacy single-managed- job manifest contract.
SkyPilot 0.12.2 job names are not idempotency keys. NPA wraps the non-idempotent
launch POST in an owner-only logical-identity lock. Production submit uses the
asynchronous API surface, then performs structured exact-name/ID queue
reconciliation before returning control to the runtime supervisor. The durable wave records readiness samples, launch sequence,
failure category, reconciliation/adoption, recovery decision, and cancellation
verification. UP and STOPPED controllers are usable; controller absence is a
distinct state that requires stable Kubernetes API readiness before creation.
Unknown/ambiguous queue evidence blocks both relaunch and fuzzy cancellation.
The standard runtime's lightweight supervisor stays outside payload pods and
persists content-addressed attempt decisions in S3. It classifies actionable
configuration, transient infrastructure, payload, and unknown evidence. Only a
typed transient with matching immutable workflow/source/image identity, verified
declared-output state, passing launch preflights, and exact cancellation may
advance to a new attempt. The expected identities are recomputed independently
from current runtime inputs. --max-infrastructure-recoveries is finite and
separate from payload --retries; exhaustion is durable and terminal.
Cancellation is polled by exact provider ID until terminal under a finite
verification policy; a merely requested cancellation blocks relaunch.
Completed-wave reuse validates declared S3 outputs;
mid-stage resume additionally requires a real compatible tool checkpoint loader.
The shared supervisor is also active in Genesis' existing production Serverless
Jobs command. This does not route individual npa.workflow/v0.0.1 stages to
Serverless; runtime workflow waves remain SkyPilot/Kubernetes.
Signals
- GitHub stars
- 28
- Forks
- 15
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
skypilot-workflows- Source
- github.com/nebius/nebius-physical-ai