Skip to content

feat: add deploy-to-cloud-engine skill#212

Merged
artkorotkikh-dfinity merged 6 commits into
mainfrom
skill/deploy-to-cloud-engine
Jun 12, 2026
Merged

feat: add deploy-to-cloud-engine skill#212
artkorotkikh-dfinity merged 6 commits into
mainfrom
skill/deploy-to-cloud-engine

Conversation

@artkorotkikh-dfinity

@artkorotkikh-dfinity artkorotkikh-dfinity commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

What

Adds deploy-to-cloud-engine (category Infrastructure): a skill that deploys an already-built ICP project to a user's own cloud engine (an OpenCloud / control-panel engine, administered from a web console). It:

  • verifies the icp CLI is installed,
  • checks existing CLI identities (icp identity list) and, when no engine identity exists, links the user's console identity with icp identity link web <name> --auth <console-origin> (the user completes the Internet Identity sign-in in the browser),
  • defaults the console origin to https://opencloud.org (stated to the user and overridable when they sign in to a different console) and obtains the engine's subnet id, asking the user rather than guessing,
  • deploys with icp deploy -e ic --subnet <subnet-id>,
  • tags the canisters with __META_PROJECT / __META_NAME / __META_MAIN_CANISTER environment variables (via settings.environment_variables) so the engine console shows a single named app with labelled backend/frontend canisters and an "Open" button, instead of bare principal rows, and verifies the canisters on the console.

Includes evaluations/deploy-to-cloud-engine.json (output + trigger evals) covering the documented pitfalls: wrong or omitted --auth origin, the non-interactive "Press Enter" stall, deploying as anonymous, guessing the subnet id, dfx misuse, the console-naming metadata flow (naming an app + the "no Open button" case), and a marketplace-packaging near-miss that must not trigger this skill.

Why

The icp-cli skill covers general builds and mainnet deploys, but nothing covers the cloud-engine-specific path: linking the CLI to the engine's console identity, targeting the engine's own subnet, and tagging the canisters so the engine console shows them as one named app. This is the skill a coding agent links to so it can ship straight to a user's cloud engine — the flow the cloud-engine console currently spells out by hand.

Updates since opening

  • Verified end-to-end against a real engine (opencloud.org console) on 2026-06-10: a coding agent following the skill linked the console identity and deployed a two-canister app successfully.
  • Fixes harvested from that run: icp defaulticp identity default (the former does not exist in icp 0.3.0), and documentation of the "Press Enter to log in" prompt that stalls icp identity link web in non-interactive shells.
  • Console origin is now a stated default (https://opencloud.org) with an invited override, instead of an open-ended ask; the subnet id remains a hard ask.
  • Added from CLI verification on icp 0.3.0: identity pre-check via icp identity list (the CLI cannot reveal which console an identity was linked against), a warning that omitting --auth silently links against its built-in default https://id.ai, the frontend URL form https://<canister-id>.icp0.io, and a compatibility pin to icp-cli >= 0.3.0.
  • App metadata for the console (2026-06-11): added a step plus two pitfalls documenting the __META_PROJECT / __META_NAME / __META_MAIN_CANISTER environment variables that group CLI-deployed canisters into one named app (same __META_PROJECT across canisters), label each one, and mark the entry point (__META_MAIN_CANISTER: "true") for the "Open" button. Verified on the opencloud.org engine: icp-cli merges these with the auto-injected PUBLIC_CANISTER_ID:* variables, so the asset canister keeps serving. Added matching output evals (naming an app, "no Open button" adversarial) and two should_trigger queries.
  • Review fixes (2026-06-12, addressing the first review): non-interactive link now prescribes printf '\n' | icp identity link web … with an explicit do-not-use-/dev/null note (Step 1, Pitfall 1, and the stall eval); eval 2's prompt/behavior contradiction fixed ("the link command and what to expect"); the dfx pitfall anchors the full correct sequence; inline icp.yaml example added to Step 2 (array form per the v0.3.0 schema — canisters is a list of {name, recipe, settings}); the identity-name pitfall folded into Step 1; prerequisites defer installation to icp-cli.

⚠️ Draft — remaining before merge

  • npm run validateskill-validator was not available in my environment (no Go/Homebrew install). node scripts/check-project.js deploy-to-cloud-engine passes (metadata title/category present, eval file found, 0 warnings).
  • Re-run the evaluation suite (node scripts/evaluate-skills.js deploy-to-cloud-engine) after the review fixes and paste results below. (Reviewer's run on the pre-fix state: 40/43 WITH skill vs 8/43 WITHOUT; triggers 17/17.)
  • End-to-end verification of icp identity link web … and icp deploy -e ic --subnet … against a real engine — done 2026-06-10, see "Updates since opening".
  • End-to-end verification of the __META_* console-naming metadata against a real engine — done 2026-06-11 (canisters merged the vars and rendered as a named app).
Evaluation results

Not yet generated. evaluations/deploy-to-cloud-engine.json is included (10 output evals + trigger evals, covering the deploy flow, the documented pitfalls, and the console-naming metadata); results need to be produced with node scripts/evaluate-skills.js deploy-to-cloud-engine before merge.

Per CONTRIBUTING, all PRs require repo-admin approval before merge.

New Infrastructure skill that deploys an already-built ICP project to a user's
own cloud engine: verify the icp CLI, link the user's console identity with
`icp identity link web --auth <console-origin>`, obtain the console origin and
subnet id (asking when unknown), and run `icp deploy -e ic --subnet <subnet-id>`.
Includes evaluations/deploy-to-cloud-engine.json (output + trigger evals).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown

Skill Validation Report

Validating skill: /home/runner/work/icskills/icskills/skills/deploy-to-cloud-engine

Structure

  • Pass: SKILL.md found

Frontmatter

  • Pass: name: "deploy-to-cloud-engine" (valid)
  • Pass: description: (973 chars)
  • Pass: license: "Apache-2.0"
  • Pass: compatibility: (127 chars)
  • Pass: metadata: (2 entries)

Markdown

  • Pass: no unclosed code fences found

Tokens

File Tokens
SKILL.md body 2,701
Total 2,701

Content Analysis

Metric Value
Word count 1,872
Code block ratio 0.08
Imperative ratio 0.10
Information density 0.09
Instruction specificity 1.00
Sections 9
List items 40
Code blocks 8

Contamination Analysis

Metric Value
Contamination level low
Contamination score 0.01
Primary language category shell
Scope breadth 2
  • Warning: Language mismatch: config (1 category differ from primary)

Result: passed

Project Checks


✓ Project checks passed for 1 skills (0 warnings)

artkorotkikh-dfinity and others added 4 commits June 10, 2026 11:40
- Console origin now defaults to https://opencloud.org (the main OpenCloud
  console): the agent states the default and offers an override instead of
  asking open-endedly. Subnet id stays a hard ask — it cannot be guessed.
- Pitfall 2 gains a recovery path for an unauthorized deploy after linking
  against the default origin.
- Fix `icp default` -> `icp identity default` (the former does not exist
  in icp 0.3.0), in both the skill and the evals.
- Evals: case 1 expects default-with-override behavior; new override case
  for a non-default console origin.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…acts

- Step 1 starts with `icp identity list`: the CLI cannot reveal which
  console an identity was linked against, so route by what exists —
  no web-linked identity -> link; recognizable identity -> set active;
  unsure -> relink under a new name (cheap and safe). Verify with
  `icp identity default` / `icp identity principal`.
- Warn never to omit --auth: its built-in default is https://id.ai,
  not the console (verified against icp 0.3.0 --help).
- Document the 'Press Enter to log in' prompt that stalls the link
  command in non-interactive shells (hit in a real agent deploy).
- Step 3 names the frontend URL form https://<id>.icp0.io and the
  console's 'Open in browser' link.
- compatibility: icp-cli >= 0.3.0 (commands verified on 0.3.0).
- Evals: stalled-link case, deploy-as-anonymous case (pitfall 5 had no
  coverage), marketplace .icp packaging near-miss in should_not_trigger.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Add a step explaining how to tag canisters with __META_PROJECT /
__META_NAME / __META_MAIN_CANISTER via settings.environment_variables so
the cloud engine console groups them into one named application with
labelled canisters and an "Open" button, instead of bare principal rows.
icp-cli merges these with the auto-injected PUBLIC_CANISTER_ID:* vars
(verified against 0.3.0). Renumber deploy/verify steps, add two pitfalls,
and surface naming in the skill description.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add two output evals (naming a deployed app via __META_PROJECT /
__META_NAME / __META_MAIN_CANISTER in settings.environment_variables, and
an adversarial "no Open button" case checking the literal "true" value),
two should_trigger queries for console-naming requests, and mention the
metadata in the eval-file description.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@artkorotkikh-dfinity artkorotkikh-dfinity marked this pull request as ready for review June 11, 2026 16:03
@artkorotkikh-dfinity artkorotkikh-dfinity requested review from a team and JoshDFN as code owners June 11, 2026 16:03

@marc0olo marc0olo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skill and evals review — deploy-to-cloud-engine

Good skill. Covers genuinely new territory (nothing in icp-cli handles the --auth identity link, subnet targeting, or __META_* console metadata), end-to-end verified, and the without-skill baseline confirms the delta is real — baseline invents dfx deploy --network ic for every flow question. Validation passes; triggers are perfect 9/9 / 8/8.

I ran the full suite. Three failures in the WITH-skill results, analysed below.

Eval results — node scripts/evaluate-skills.js deploy-to-cloud-engine
Eval WITH skill WITHOUT skill
Deploy a built project to a cloud engine 6/6 ✅ 0/6
Just the link command 3/4 ⚠️ 1/4
Adversarial: wrong --auth origin 4/4 ✅ 1/4
Override: non-default console origin 4/4 ✅ 1/4
Adversarial: guessing the subnet id 3/3 ✅ 1/3
Agent pitfall: link command stalls non-interactively 4/4 ✅ 0/4
Adversarial: deploying as anonymous 4/4 ✅ 2/4
Adversarial: dfx to the engine 3/4 ⚠️ 0/4
Name the app in the engine console 6/6 ✅ 0/6
Adversarial: named app but no Open button 3/4 ⚠️ 1/4
Trigger evals 9/9 should-trigger 8/8 should-not-trigger

Total: 40/43 WITH | 8/43 WITHOUT


Required before merge

1. printf '\n' | — the "Press Enter" wording will cause silent failures

Step 1 says "supply the Enter keypress (pipe an empty line)". On icp-cli 0.3.2 (verified in PR #217 agent-web-identity), redirecting stdin from /dev/null produces a bare EOF that does not satisfy the prompt — the command sits on Press Enter to log in indefinitely, no browser opens, and the flow wastes the first sign-in attempt. Piping an actual newline is the only reliable fix:

printf '\n' | icp identity link web <your-identity-name> --auth <console-origin>

Update both the Step 1 prose and Pitfall 1 to use this form, and add an explicit note: do NOT redirect from /dev/null.

2. Eval 2 — prompt/expected_behavior mismatch (false failure)

Prompt: "Give me only the command … No deploy steps."
Expected behavior: "Mentions a browser tab opens and the user completes the Internet Identity sign-in there."

These contradict. Asking for only the command and then checking for surrounding context is a design bug — the failure here is in the eval, not the skill. Two options: (a) remove that expected_behavior, or (b) drop the "No deploy steps" scope restriction and reword to "Give me the link command and what to expect when I run it."

3. Pitfall 6 too thin — causing real eval 8 failure (3/4)

The failure in "Adversarial: dfx to the engine": when correcting dfx misuse, the agent produced icp identity link web without <name> and --auth <console-origin>. Pitfall 6 currently reads only "This ecosystem uses icp, never dfx." — not enough to anchor the full command signature under adversarial conditions. Strengthen it to show the complete correction:

6. **Using `dfx`.** This ecosystem uses `icp`, never `dfx`. The correct sequence is:
   `icp identity link web <name> --auth <console-origin>` (Step 1), then
   `icp deploy -e ic --subnet <subnet-id>` (Step 3).

Suggested improvements (not blocking)

Missing inline icp.yaml example in Step 2. The text says "For a single inline icp.yaml, put the same block under each canister entry instead" but shows no YAML. Since agents use code blocks directly, prose-only guidance is a gap for the common case of single-file projects. Add a snippet:

# icp.yaml
canisters:
  frontend:
    recipe: ...
    settings:
      environment_variables:
        __META_PROJECT: "My App"
        __META_NAME: "Frontend"
        __META_MAIN_CANISTER: "true"
  backend:
    recipe: ...
    settings:
      environment_variables:
        __META_PROJECT: "My App"
        __META_NAME: "Backend"

Eval 10 — name the command explicitly. The failure was the agent said "redeploy" without naming icp deploy. Change the expected_behavior to check that the agent says icp deploy specifically — it matters that the right command is named.

Pitfall 4 — weak, not a failure mode. "Assuming a fixed identity name" is a clarification about a placeholder value, not a failure path. The identity name is already explained in Step 1. Either drop this pitfall or fold the note into the Step 1 inline explanation.

Prerequisites — strip the install detail. The npm install -g @icp-sdk/icp-cli @icp-sdk/ic-wasm, Node.js >= 22, and demo-icp fallback instructions duplicate what lives in icp-cli. This skill already defers there for everything else — trim to: "icp on $PATH — see the icp-cli skill to install."

Future cross-reference. PR #217 agent-web-identity covers icp identity link web --app <domain> for acting as a user's app-specific principal (oisy.com, NNS, etc.) — a distinct use case from --auth here. Once that lands, add it to ## Related Skills.

@marc0olo

Copy link
Copy Markdown
Member

Skill and evals review — deploy-to-cloud-engine

Good skill. Covers genuinely new territory (nothing in icp-cli handles the --auth identity link, subnet targeting, or __META_* console metadata), end-to-end verified, and the without-skill baseline confirms the delta is real — baseline invents dfx deploy --network ic for every flow question. Validation passes; triggers are perfect 9/9 / 8/8.

I ran the full suite. Three failures in the WITH-skill results, analysed below.

Eval results — node scripts/evaluate-skills.js deploy-to-cloud-engine
Eval WITH skill WITHOUT skill
Deploy a built project to a cloud engine 6/6 ✅ 0/6
Just the link command 3/4 ⚠️ 1/4
Adversarial: wrong --auth origin 4/4 ✅ 1/4
Override: non-default console origin 4/4 ✅ 1/4
Adversarial: guessing the subnet id 3/3 ✅ 1/3
Agent pitfall: link command stalls non-interactively 4/4 ✅ 0/4
Adversarial: deploying as anonymous 4/4 ✅ 2/4
Adversarial: dfx to the engine 3/4 ⚠️ 0/4
Name the app in the engine console 6/6 ✅ 0/6
Adversarial: named app but no Open button 3/4 ⚠️ 1/4
Trigger evals 9/9 should-trigger 8/8 should-not-trigger

Total: 40/43 WITH | 8/43 WITHOUT


Required before merge

1. printf '\n' | — the "Press Enter" wording will cause silent failures

Step 1 says "supply the Enter keypress (pipe an empty line)". On icp-cli 0.3.2 (verified in PR #217 agent-web-identity), redirecting stdin from /dev/null produces a bare EOF that does not satisfy the prompt — the command sits on Press Enter to log in indefinitely, no browser opens, and the flow wastes the first sign-in attempt. Piping an actual newline is the only reliable fix:

printf '\n' | icp identity link web <your-identity-name> --auth <console-origin>

Update both the Step 1 prose and Pitfall 1 to use this form, and add an explicit note: do NOT redirect from /dev/null.

2. Eval 2 — prompt/expected_behavior mismatch (false failure)

Prompt: "Give me only the command … No deploy steps."
Expected behavior: "Mentions a browser tab opens and the user completes the Internet Identity sign-in there."

These contradict. Asking for only the command and then checking for surrounding context is a design bug — the failure here is in the eval, not the skill. Two options: (a) remove that expected_behavior, or (b) drop the "No deploy steps" scope restriction and reword to "Give me the link command and what to expect when I run it."

3. Pitfall 6 too thin — causing real eval 8 failure (3/4)

The failure in "Adversarial: dfx to the engine": when correcting dfx misuse, the agent produced icp identity link web without <name> and --auth <console-origin>. Pitfall 6 currently reads only "This ecosystem uses icp, never dfx." — not enough to anchor the full command signature under adversarial conditions. Strengthen it to show the complete correction:

6. **Using `dfx`.** This ecosystem uses `icp`, never `dfx`. The correct sequence is:
   `icp identity link web <name> --auth <console-origin>` (Step 1), then
   `icp deploy -e ic --subnet <subnet-id>` (Step 3).

Suggested improvements (not blocking)

Missing inline icp.yaml example in Step 2. The text says "For a single inline icp.yaml, put the same block under each canister entry instead" but shows no YAML. Since agents use code blocks directly, prose-only guidance is a gap for the common case of single-file projects. Add a snippet:

# icp.yaml
canisters:
  frontend:
    recipe: ...
    settings:
      environment_variables:
        __META_PROJECT: "My App"
        __META_NAME: "Frontend"
        __META_MAIN_CANISTER: "true"
  backend:
    recipe: ...
    settings:
      environment_variables:
        __META_PROJECT: "My App"
        __META_NAME: "Backend"

Eval 10 — name the command explicitly. The failure was the agent said "redeploy" without naming icp deploy. Change the expected_behavior to check that the agent says icp deploy specifically — it matters that the right command is named.

Pitfall 4 — weak, not a failure mode. "Assuming a fixed identity name" is a clarification about a placeholder value, not a failure path. The identity name is already explained in Step 1. Either drop this pitfall or fold the note into the Step 1 inline explanation.

Prerequisites — strip the install detail. The npm install -g @icp-sdk/icp-cli @icp-sdk/ic-wasm, Node.js >= 22, and demo-icp fallback instructions duplicate what lives in icp-cli. This skill already defers there for everything else — trim to: "icp on $PATH — see the icp-cli skill to install."

Future cross-reference. PR #217 agent-web-identity covers icp identity link web --app <domain> for acting as a user's app-specific principal (oisy.com, NNS, etc.) — a distinct use case from --auth here. Once that lands, add it to ## Related Skills.

…dfx pitfall

Required items from the review:
- Step 1, Pitfall 1, and the stall eval now prescribe
  `printf '\n' | icp identity link web ...` and explicitly forbid
  `< /dev/null` (bare EOF never satisfies the 'Press Enter' prompt).
- Eval 2: prompt reworded to 'the link command and what to expect' so
  the browser-tab expected_behavior no longer contradicts the prompt.
- dfx pitfall now anchors the full correct sequence (link with
  --auth, then icp deploy -e ic --subnet).

Suggested items:
- Step 2 gains the inline icp.yaml example. Corrected from the review
  snippet: per the v0.3.0 schema, `canisters` is an ARRAY of
  {name, recipe, settings} items, not a map keyed by canister name.
- Eval 10 requires naming `icp deploy` explicitly, not 'redeploy'.
- 'Assuming a fixed identity name' pitfall folded into Step 1 prose.
- Prerequisites defer installation to the icp-cli skill.
- PR #217 cross-reference deferred until it lands.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@artkorotkikh-dfinity

Copy link
Copy Markdown
Contributor Author

Thanks for the thorough review and for running the suite — all items addressed in 73d87d4.

Required

  1. printf newline — Step 1 now shows printf '\n' | icp identity link web <name> --auth <console-origin> with an explicit "do not redirect stdin from /dev/null" note (bare EOF never satisfies the prompt). Pitfall 1 and the stall eval use the same form.
  2. Eval 2 — took option (b): the prompt is now "Give me the command to link my icp CLI to my cloud engine console at https://opencloud.org, and what to expect when I run it. No deploy steps." (case renamed to "Link command and what to expect").
  3. dfx pitfall — now anchors the full correction: icp identity link web <name> --auth <console-origin> (Step 1), then icp deploy -e ic --subnet <subnet-id> (Step 3 — deploy moved to Step 3 when the __META_* step landed as Step 2).

Suggestions

  • Inline icp.yaml example — added, with one correction to the snippet from the review: per the v0.3.0 icp-yaml-schema.json, canisters is an array of {name, recipe, settings} items, not a map keyed by canister name. The map form would fail validation.
  • Eval 10 — the expected behavior now requires naming icp deploy explicitly rather than accepting a bare "redeploy".
  • Pitfall 4 — dropped; the placeholder explanation is folded into the Step 1 link instruction where the name is introduced.
  • Prerequisites — trimmed to defer installation to the icp-cli skill, keeping only the icp --version check and the 0.3.0 verification note.
  • PR Add agent-web-identity skill #217 cross-reference — agreed; will add agent-web-identity to Related Skills once it lands.

The three WITH-skill failures from your run map to required items 2–3 plus the eval-10 wording, so the suite should be re-run on the new state — checklist updated accordingly.

@marc0olo marc0olo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All three required fixes and all suggested improvements addressed. Re-ran the four affected evals — every previous failure is now resolved:

Eval Before After
2 — Link command and what to expect 3/4 ⚠️ 4/4 ✅
6 — Link command stalls non-interactively 4/4 (old criterion) 4/4 ✅ (stricter /dev/null criterion)
8 — Adversarial: dfx to the engine 3/4 ⚠️ 4/4 ✅
10 — Adversarial: named app but no Open button 3/4 ⚠️ 4/4 ✅

Effective score is now 43/43 across the output suite. Good to merge.

@artkorotkikh-dfinity artkorotkikh-dfinity merged commit 27713aa into main Jun 12, 2026
6 checks passed
@artkorotkikh-dfinity artkorotkikh-dfinity deleted the skill/deploy-to-cloud-engine branch June 12, 2026 08:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants