# Launchplane

> Use for Launchplane-managed product/runtime state, secrets, config, deployments, rollout direction, product ownership boundaries, merge-train flow, and audited operator mutations. Use with github-plan when Launchplane work needs to stay aligned with a durable plan, issue graph, blockers, or rollout sequence. If authority is unknown or discovering private infrastructure access, use docs-lookup first.

- Skill: `cbusillo/launchplane` (Agent Skill, multi-file: 27 files)
- Install (CLI): `npx skillmds@latest add cbusillo/launchplane`
- Raw SKILL.md: https://api.skillmd.com/api/skills/cbusillo/launchplane/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: cbusillo (https://skillmd.com/u/cbusillo)
- Updated: 2026-09-21
- Page: https://skillmd.com/skills/cbusillo/launchplane

---


# Launchplane Expert

Use this skill to inspect product/runtime state and perform safe,
authenticated mutations via the Launchplane service API.

Use `docs-lookup` first when a task is discovering the source of truth or access
path for external/private infrastructure and it is not already clear that
Launchplane manages that resource.

## Runtime Authority Boundary

Checked-in files are not runtime authority for Launchplane-managed state. Code
may own schemas, validators, generic behavior, helper routing, fake examples,
and fail-closed defaults. Launchplane service records or explicit scoped
operator input own real product, tenant, repository, branch, domain, lane,
provider-target, runtime-environment, authz, operator, route, health-check, and
other mutable runtime values.

This applies even when values are not secrets. Non-secret topology can still
steer production behavior. Treat repo metadata, workflow variables, checked-in
examples, and archived workstation files as hints for which Launchplane helper,
service record, or operator surface to use; never use them as evidence of the
current live value. If the needed live value is only visible in checked-in or
workstation files, stop and obtain Launchplane context or explicit operator
input instead of inferring it.

When a repo has `.github/github.json`, inspect its `launchplane` block before
looking in sibling repos, archived workstation files, or workflow variables. The
repo block is public-safe routing metadata only: it may name helper paths,
environment variable names for service URLs, local config examples,
merge-train labels, and GitHub Actions workflow entrypoints. It must not
contain tokens, secret values, cookies, concrete Launchplane service URLs,
private credential paths, provider payloads, product/runtime endpoints, or
plaintext runtime configuration. Treat Launchplane-managed product, app,
preview, deploy, provider, lane, tenant, and health-check coordinates as service
records, not checked-in repo metadata; if repo metadata and Launchplane service
state disagree, service/operator state wins and the metadata is stale routing
context to fix deliberately.

## Agent/Operator Contract

Use `references/agent-operator-contract.json` as the checked-in public contract
for agent/helper operation routing, protected workflow bindings, and semantic
invariants. Run `uv run scripts/check-agent-operator-contract.py` after changing
Launchplane helper routes, workflow guidance, lifecycle guidance, governance
boundaries, or the vendored artifact.

The conformance gate is offline and non-authoritative. It proves that the local
artifact, helper bindings, protected workflows, and durable invariants agree;
it does not contact Launchplane and does not prove that the artifact is current
upstream. Use `check-agent-operator-contract-freshness.py compare` or the
scheduled `Launchplane Contract Freshness` workflow for separate advisory
evidence. Treat matching semantic digests as `current`, a valid mismatch as
`known-stale`, and unavailable or insufficient evidence as `unknown`. Ignore
provenance-only source SHA movement when the semantic digest is unchanged.

`unknown` never grants runtime authority and never opens a drift issue. A
scheduled `known-stale` result opens or updates one maintenance issue through
the maintained GitHub helpers; repeated mismatches reuse the same open issue.
Manual dispatch is compare-only unless issue reporting is explicitly selected.

Keep durable fail-closed rules local: Owner acceptance is authoritative,
engineering review is advisory, GitHub projection is routing/status only,
authorization/admission/landing are independent, protected workflow dispatch
and watching stay delegated to `github_workflow_babysit.py`, and raw protected
workflow dispatch is not allowed. Source projected HTTP paths from the vendored
operation map rather than adding duplicate literals.

The merge-train policy import dry-run/apply commands and generic-web
deploy-recovery dry-run/apply commands are explicit bounded local extensions
because the upstream public operation projection does not contain their
routes. Do not describe them as contract-backed. If a later artifact adds those
routes, migrate them deliberately and remove the local-extension entries instead
of retaining parallel sources of truth.

### Private Ordinary-Agent Client

For an ordinary agent connection, session, finite job, or cancellation, read
[the private client contract](references/ordinary-agent-client.md) and use
`scripts/launchplane-ordinary-agent.py`. Keep credential claims inside that
adapter; its public output must never contain the claim response or receiver
proof. Present the service's review link for a pending administrator decision.
Resume saved requests after interruption, and reuse issued session and lease
handles without asking the user to locate or type them. A proposal does not
approve itself, and client installation does not activate a worker.

### Contract-Backed Lifecycle And Repair Routing

For lifecycle retirement, managed authorization reconciliation, and stable-lane
repair, resolve the requested operation from the vendored contract before
choosing a surface. Use the operation's modes, idempotency, reviewed-evidence
requirements, and supported surfaces as the boundary. When the selected surface
is `protected_workflow`, resolve exactly one protected-workflow binding whose
route matches the operation path, then delegate dispatch and watching to the
`github` skill and `github_workflow_babysit.py`. Never open-code workflow
authentication, dispatch, polling, retry, or reconciliation in this skill.

Fail closed when the contract does not contain one unambiguous operation and,
when required, one unambiguous workflow binding. Report the scenario as an
unsupported capability gap and track focused follow-up coverage; do not route it
through a nearby helper, workflow, or endpoint. Plan or dry-run first, and do not
apply without every contract-required reviewed-evidence field, explicit operator
approval, and an apply-eligible result. Detached application retirement must
preserve zero authority writes and is complete only when candidate absence is
proved.

## Core Goal

Provide situational awareness and safe runtime management. Always favor
service-backed audit trails over local ad-hoc fallbacks.

Do not treat archived workstation files under `~/.config/launchplane/` as the
authority for current Launchplane runtime or product state. Files such as
`service.env`, `dokploy.env`, and `runtime-environments.toml` can be useful
historical clues, but they are not live records. When a task asks about current
product state, use the deployed Launchplane service/API or operator UI first;
use direct database access only from an explicitly approved host-side context.

## Rollout Plan Alignment

For Launchplane rollout, runtime, product-boundary, merge-train, or operator
work, do not continue from the latest operational finding alone. Before the next
slice, state how it fits the active Launchplane plan, issue graph, rollout
sequence, or product ownership boundary.

If an operational finding changes the plan, update the owning GitHub plan issue
or PR before treating the new path as canonical. Prefer explicit blocker,
sub-issue, or related-issue edges over burying direction changes in chat.

When Launchplane work turns into GitHub issue, PR, Actions, review, comment,
commit, or push work, delegate that surface to `github` or `github-plan` before
running commands. Launchplane owns runtime/operator authority; the GitHub skills
own helper-backed GitHub identity, body handling, planning state, and PR
lifecycle behavior.

## Situational Awareness (Context)

Use the context helper to identify product mapping, deploy evidence, and
readiness.

- **Usage**: `uv run scripts/launchplane-context.py --repo OWNER/REPO`
- **Output**: See `references/context.available.example.json` for schema.
- **Reporting**: Report readiness, blockers, and next action based on context.
- **Contract**: See `references/context-helper-contract.md` for config,
  fallback, and redaction behavior.

## Stable Deploy Identity

Before preparing or repairing an application-target deployment, read
[stable deploy identity](references/deploy-identity.md). Publish both an
immutable digest and immutable SHA tag before deployment; never use a floating
tag. Resolve the target category from Launchplane context or the operator
surface. Repair missing references through the product repository's build/deploy
workflow and delegate protected workflow dispatch and watching to `github`.

## Runtime Management (Operator)

Mutate runtime environments, managed secrets, and product config.

- **Safety**: Strictly follow the `references/operator-contract.md`.
- **Helper Contract**: Use `references/write-action-helper-contract.md` for
  bounded helper entrypoints, exit behavior, and redacted output shape.
- **Auth**: Prefer signed-in, scoped operator sessions in the Launchplane UI or
  service API. Source terminal/local operator credentials only through the
  operator contract; do not paste token values into chat, issues, PRs, docs, or
  logs.
- **Private Config**: For non-browser terminal execution, use the source order
  in the operator contract. Missing private config means the write-capable path
  is unavailable and must fail closed; do not use `.github/github.override.json`
  for Launchplane credentials.
- **Operator Diagnostics**: Before concluding operator access is unavailable,
  run `scripts/launchplane-write-action.py operator-config-diagnostic`. Treat
  `launchplane-context` availability and local operator readiness as separate
  checks: context can be unavailable while the write helper is usable, and the
  write helper can be blocked only by missing local operator config. If the
  diagnostic reports `missing_service_url`, token material was found but no
  write-capable Launchplane service URL source was found; configure
  `LAUNCHPLANE_OPERATOR_URL` in the private local operator env file or pass
  `--url` before the subcommand, then rerun the diagnostic. If the active shell
  has a service URL under `LAUNCHPLANE_PUBLIC_URL` but not
  `LAUNCHPLANE_OPERATOR_URL`, treat it as an ambiguous URL source: obtain the
  correct operator URL and pass it with `--url` before the subcommand, or copy
  the sanctioned value into private operator config. Do not use public URL
  variables as write authority.
- **Repo Metadata**: Use `.github/github.json` `launchplane` metadata to find
  helper paths, workflow entrypoints, labels, and service URL env var names, but
  keep concrete service URLs and credentials in private operator config,
  environment variables, GitHub Actions OIDC, or signed-in Launchplane UI
  sessions.
- **No Checked-In Product Authority**: Do not add or copy product-specific
  authz grants, provider target route batches, product target IDs, tenant
  domains, runtime seed/import payloads, or live product topology into
  Launchplane deploy scripts, workflow defaults, repo-local config files, or
  product repos. Committed examples must use fake placeholders or intentionally
  public, non-authoritative sample data. For shared/prod, use the deployed
  Launchplane service, operator UI, or the bounded write-action helper/API with
  the correct service URL and scoped credentials.
- **No Checked-In Topology Inference**: Do not infer real products, tenants,
  domains, lanes, provider targets, runtime environments, route batches, authz,
  repository bindings, branch bindings, or operator identity from checked-in
  config or workflow defaults. Those files may identify the Launchplane surface
  to query; they do not answer what live topology is now.
- **First Shot**: For product-config/runtime/secret sync, use the service API
  path from the operator contract first. Do not start by searching for a local
  `launchplane` binary or by poking provider config directly.
- **Denied Actions**: A local operator token can be present and still lack a
  specific action. Report that as authorization denial, not missing credential.
  Before choosing a next step, classify the denial. A scope denial means an
  existing Launchplane capability does not grant this identity the requested
  scope. A capability gap means no supported Launchplane surface owns the
  operation. Neither case is solved by selecting another credential or CI job.
  Block only the affected operation or work item, preserve the trace and source
  URL, and continue independent safe work when available. Stop the whole
  session only when no useful unblocked work remains or the failed operation may
  have produced an uncertain effect.
- **GitHub Is Not Authorization Authority**: A GitHub workflow, Actions secret,
  repository or environment variable, OIDC role, or CI job is never evidence
  that a denied Launchplane action is authorized. Do not author, edit, extend,
  retarget, or dispatch a workflow to carry a call Launchplane denied.
  Repository workflow content is routing metadata, just like
  `.github/github.json`; Launchplane DB/service records remain authority.
- **Unsupported Helper Coverage**: If the helper lacks a command for the needed
  runtime record operation, treat that as a capability gap. Stop the affected
  operation at the supported Launchplane service/UI path and use `github-plan`
  to open or update the owning authorization-architecture issue, record the
  denied operation and trace ID, and add a native `blocked-by` edge from the
  affected work. Re-rank or continue unrelated work instead of turning one gap
  into a session-wide stop. Do not synthesize record payloads from issue text,
  checked-in examples, workflow defaults, provider observations, or local
  files, and do not close the gap with a workflow.
- **Workflow**:
  1. Inspect Context to identify the target and change needed.
  2. Run operator config diagnostics before a write-capable helper call when
     target URL, token source, or authority is unclear.
  3. If diagnostics report `missing_service_url`, fix local operator routing
     first. This is a workstation setup problem, not PR readiness, merge-train
     admission, or scheduler state.
  4. Preflight product-config intent with `scripts/launchplane-write-action.py
product-config-preflight` when agent-side authorization or managed-secret
     binding evidence is useful.
  5. Use the signed-in/scoped operator path when a human-approved runtime or
     managed-secret mutation is required.
  6. Build a product-config request for `POST /v1/product-config/apply` only in
     an approved operator surface. The helper may submit dry-run/apply from a
     private local payload file, never from chat, CLI plaintext secret args, or
     committed examples.
  7. **Dry-run** and inspect redacted results.
  8. **Apply** with a concrete reason only after the dry-run succeeds and the
     operator intent is explicit.
  9. Inspect returned `next_actions` and complete required follow-up actions;
     product-config apply can update Launchplane records before the live target
     runtime has been synced.

Agents may guide the operator, prepare request shape, summarize redacted dry-run
evidence, and report trace IDs/status. Agents must not collect plaintext secret
values in chat, issues, PRs, docs, logs, or helper output, and must not bypass
Launchplane by editing provider configuration directly.

### Blocked Work Continuation

Until Launchplane exports a native deferred-operation lifecycle, represent an
authorization or capability gap through the owning GitHub plan relationship:

1. preserve the denied operation, bounded reason, trace ID, and source URL;
2. block only the affected work item on the owning architecture issue;
3. use `github-plan next` or the existing work source to select independent
   work;
4. notify the operator immediately only when every useful item is blocked, an
   effect is uncertain, or an active environment is unhealthy.

Do not tell the operator to provision a new credential or click through a
GitHub Actions workaround. A future Launchplane deferred-operation record may
replace this GitHub-plan handoff after it is present in the public contract.

### Sanctioned Reconciliation And Break-Glass

A Launchplane-owned reconciliation entrypoint may run under GitHub Actions OIDC.
That path executes authority Launchplane already granted; it never creates
authority merely because another identity was denied. Use it only when every
condition holds:

- the entrypoint already exists and is named in repository routing metadata,
  the operator contract, or explicit operator instruction;
- Launchplane owns it and already sanctions it for this exact record type;
- the operator initiated this run for the specific record;
- the workflow, inputs, permissions, target, and secrets are used unmodified;
- dry-run and reviewed evidence precede apply where supported.

Delegate dispatch and watching to the `github` skill. If any condition fails,
stop and escalate architecturally. Bootstrap and break-glass are
operator-initiated exceptions with an audit trail; they are never the routine
answer to `authorization_denied`.

## Merge Train (Controller)

Use Launchplane's controller route as the default merge-train workflow. Before
advancing or diagnosing a train, read [merge-train execution](references/merge-train.md)
for phase, stack, retry, and terminal evidence requirements. Label only the root
PR and never hand-collapse stacks.

- **Preferred Route**: `POST /v1/work-graph/merge-train/controller/run-once`.
- **Helper**: Use `scripts/launchplane-write-action.py
merge-train-controller-run-once` instead of open-coding the route. Mutating
  calls require an idempotency key.
- **Operator Action**: Put `ready-to-merge` only on the root PR that targets the
  protected base branch. Do not hand-collapse stacks in GitHub.
- **Mutation Gate**: Keep scheduled runners in dry-run mode until the operator
  explicitly selects a mutation pilot. Manual `mutate=true` controller runs are
  appropriate only after dry-run evidence shows the intended queue, candidate,
  and next action. Do not leave scheduled mutation enabled as a casual default.
- **Post-Merge Checkout Handoff**: After the controller confirms a final landing
  commit, delegate post-merge default-branch freshness to `github` with the exact
  final landing SHA from that terminal controller result and an explicit source
  worktree belonging to the landed repository. Never substitute a PR head,
  candidate, admission, observation, landing-plan, queued, or other intermediate
  SHA, and never use an unrelated controller working directory as the source
  worktree. That handoff uses the landed repo-local reconciler for a runtime-bound
  checkout and safely fast-forwards a unique clean non-runtime default checkout,
  or reports the stale-checkout hint when local state is unsafe. Preserve
  Launchplane landing success independently when local reconciliation is blocked
  or fails, and block only claims that installed runtime behavior or the local
  default checkout is current.
- **Boundaries**: Merge-train behavior is DB/policy-backed. Do not hardcode
  repositories, labels, tokens, protected branches, or local file config.

## Intentionality & Safety

This skill combines inspection and mutation. You must explicitly announce when
you are transitioning from **Inspecting Context** to **Executing Operator
Actions**. Never apply a mutation without a preceding dry-run and situational
verification.

## Tools

- `scripts/launchplane-context.py`: Structural state helper.
- `scripts/launchplane-write-action.py`: Public-safe write-action wrapper for
  product-config intent preflight, private local product-config dry-run/apply,
  change-impact policy dry-run/apply/read-back, guarded merge-train policy
  import, repository inventory read/dry-run/apply, and merge-train controller
  calls.
- `scripts/check-agent-operator-contract.py`: Hermetic schema, digest,
  public-safety, operation, workflow, invariant, and local-consumer conformance
  gate. A green result is not upstream freshness evidence.
- `operator-config-diagnostic`: Redacted source-presence diagnostic for local
  operator URL and token configuration. Global options such as `--url` must come
  before the subcommand.
- `POST /v1/agent/write-intents/evaluate`: Product-config preflight surface for
  authorization and managed-secret binding evidence; never carries plaintext.
- `POST /v1/product-config/apply`: Primary product-config operator path for
  signed-in/scoped operators; dry-run before apply.
- `POST /v1/change-impact/policies/apply`: Change-impact policy dry-run/apply
  path for explicit private operator input; apply must pin the dry-run policy
  digest and be followed by bounded read-back.
- `GET /v1/change-impact/policy`: Bounded active policy read-back for exact
  revision and digest verification.
- `POST /v1/merge-train/policies/import`: Bounded local-extension path for
  private merge-train policy dry-run/apply. Require active-policy digest
  preflight, exact saved dry-run evidence, reviewed acknowledgement,
  idempotency, and post-apply read-back. The helper-side digest check is not
  server-enforced compare-and-swap.
- `GET /v1/work-graph/merge-train/policy-targets`: Internal bounded preflight
  read used immediately before policy import to verify the expected active
  policy digest. It is not an independently exposed helper command.
- `GET /v1/repository-inventory`: Bounded current repository inventory read for
  exact immutable GitHub repository identity.
- `POST /v1/repository-inventory/apply`: Repository inventory dry-run/apply
  route. Use private payload files; apply requires reviewed helper evidence,
  inventory digest binding, and a stable idempotency key.
- `POST /v1/admin/generic-web/deploy-recovery/dry-run`: Generic-web
  deploy-recovery dry-run path; always run before apply and capture the
  `recovery_digest` from the redacted result.
- `POST /v1/admin/generic-web/deploy-recovery/apply`: Generic-web
  deploy-recovery apply path; requires the original deploy idempotency key,
  the dry-run digest, and reviewed acknowledgement.
- `POST /v1/work-graph/merge-train/controller/run-once`: Preferred merge-train
  controller path; call repeatedly to advance one safe phase at a time.
- `POST /v1/previews/pr-feedback/remediation`: Contract-backed bounded preview
  feedback remediation path; dry-run before apply.
- Launchplane host-only CLI helpers: Use only when you are explicitly on the
  Launchplane host via SSH or the repo provides a concrete command. Do not
  assume a global `launchplane` binary exists on ordinary workstations.

