Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .claude/upstream.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ Upstream file paths and the tracking model (release-tag vs commit) are listed pe
## static-site

- **Upstream:** https://github.com/dfinity/certified-assets
- **Tag:** v0.3.3
- **Commit:** ac2a8e71802b40abb56078ca759b4c0f94f5fe35
- **Last synced:** 2026-08-03
- **Tag:** v0.4.0
- **Commit:** 4987b0857bda9793b38355096e836e4ddffa8cde
- **Last synced:** 2026-09-23
- **Upstream files:** `docs/` — the certified-assets user documentation is the source of truth for the static-site recipe. The sync check diffs **all files** in `docs/` recursively (`scripts/sync-upstream-check.sh` uses the Git Trees API with `?recursive=1`), so nested `docs/<subdir>/` files are covered. Files today (all top-level): `overview.md`, `routing.md`, `redirects.md`, `headers.md`, `site-files.md`, `access-protection.md`, `how-it-works.md`, `verifying-contents.md`.
- **Relationship:** the icskills `static-site` SKILL.md is **derived, not 1:1** — it is an agent-focused condensation of the upstream docs plus icskills-only material (legacy asset-canister reference, migration guide, cross-skill links). Treat the upstream diff as an **advisory review trigger**: when `docs/` changes, review whether the SKILL.md or its references need updating; do not mechanically overwrite.
- **icskills-owned sections (entirely icskills-authored, never overwrite from upstream):**
Expand Down
22 changes: 21 additions & 1 deletion evaluations/static-site.json
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,29 @@
"Does NOT use the legacy ic0.app or icp0.io gateway domains",
"Does NOT use icp-api.io (that is the API endpoint, not the browser gateway)"
]
},
{
"name": "Adversarial: do not share raw.icp.net links (unverified, phishable login)",
"prompt": "My static-site preview on mainnet has access protection enabled. A teammate says to share https://<canister-id>.raw.icp.net with testers because it's the 'direct' URL. Is that fine, or should I send a different link? Just the key points.",
"expected_behaviors": [
"Says not to share the raw.icp.net URL and to share https://<canister-id>.icp.net (a verifying gateway) instead",
"Explains the raw host forwards responses without verifying the certificate, so visitors get no certification guarantee",
"Notes that with access protection the redirect and login page arrive unverified over raw, so a fake login form could harvest tokens",
"Does NOT claim the canister can be configured to block or disable raw access (there is no allow_raw_access setting on certified-assets)"
]
},
{
"name": "Third-party verification of a static-site state hash",
"prompt": "I want to independently verify that the static-site canister <canister-id> on mainnet serves exactly the build from its public repo. Give me the steps as commands, briefly, no deploy steps.",
"expected_behaviors": [
"Reproduces the build from source to get the served directory (e.g. dist/)",
"Queries the canister's version and builds the verifier from the matching certified-assets tag with cargo install --git https://github.com/dfinity/certified-assets --tag <v> --locked state-hash-cli",
"Computes the local hash with state-hash ./dist",
"Reads the canister hash with icp canister call <canister-id> state_hash '()' -n ic (by principal with -n, not -e) and compares the two",
"Does NOT treat the hash printed by icp deploy (or handed over by the operator) as independent verification"
]
}
],

"trigger_evals": {
"description": "Queries to test whether the skill activates correctly.",
"should_trigger": [
Expand Down
2 changes: 1 addition & 1 deletion skills/deploy-to-cloud-engine/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ Set them under each canister's `settings.environment_variables` — this is vali
# frontend/canister.yaml
name: frontend
recipe:
type: "@dfinity/static-site@v0.3.3"
type: "@dfinity/static-site@v0.4.0"
configuration:
build:
- npm install
Expand Down
8 changes: 4 additions & 4 deletions skills/icp-cli/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ npm install -g @icp-sdk/icp-cli @icp-sdk/ic-wasm
canisters:
- name: frontend
recipe:
type: "@dfinity/static-site@v0.3.3" # recommended frontend recipe (certified-assets)
type: "@dfinity/static-site@v0.4.0" # recommended frontend recipe (certified-assets)
configuration:
dir: dist
build:
Expand Down Expand Up @@ -251,7 +251,7 @@ Source Code → [Build] → WASM → [Deploy] → Running Canister → [Sync]
`icp deploy` runs all three phases in sequence:
1. **Build** — Compile canisters to WASM (via recipes or explicit build steps)
2. **Deploy** — Create canisters (if new), apply settings, install WASM
3. **Sync** — Post-deployment operations via `script` or `plugin` steps (e.g., uploading assets). Asset uploading is not built into the CLI: a frontend recipe supplies a `plugin` sync step that uploads the `dir` contents — the recommended `@dfinity/static-site@v0.3.3` (certified-assets) or the legacy `@dfinity/asset-canister@v2.2.1`. The legacy built-in `type: assets` step is removed in icp-cli 0.3.0 — see the `static-site` skill.
3. **Sync** — Post-deployment operations via `script` or `plugin` steps (e.g., uploading assets). Asset uploading is not built into the CLI: a frontend recipe supplies a `plugin` sync step that uploads the `dir` contents — the recommended `@dfinity/static-site@v0.4.0` (certified-assets) or the legacy `@dfinity/asset-canister@v2.2.1`. The legacy built-in `type: assets` step is removed in icp-cli 0.3.0 — see the `static-site` skill.

Run phases separately for more control:
```bash
Expand Down Expand Up @@ -403,7 +403,7 @@ The canister name (`backend`) must exactly match between `icp.yaml` and `mops.to
canisters:
- name: frontend
recipe:
type: "@dfinity/static-site@v0.3.3"
type: "@dfinity/static-site@v0.4.0"
configuration:
dir: dist
build:
Expand Down Expand Up @@ -441,7 +441,7 @@ canisters:
|--------|------------|-----------------|-----------------|
| Rust | `@dfinity/rust@v3.3.0` | — | `package` (defaults to canister name), `candid`, `locked`, `shrink`, `compress`, `metadata` |
| Motoko | `@dfinity/motoko@v5.0.0` | — | `shrink`, `compress`, `metadata` |
| Static site (frontend) | `@dfinity/static-site@v0.3.3` | `dir` | `build`, `presync`, `metadata` |
| Static site (frontend) | `@dfinity/static-site@v0.4.0` | `dir` | `build`, `presync`, `metadata` |
| Asset (legacy frontend) | `@dfinity/asset-canister@v2.2.1` | `dir` | `build`, `version` |
| Prebuilt | `@dfinity/prebuilt@v2.1.0` | `path` | `sha256`, `shrink`, `compress`, `metadata` |

Expand Down
2 changes: 1 addition & 1 deletion skills/icp-cli/references/dfx-migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ Steps:
|----------|----------|
| `"type": "rust"` | `recipe.type: "@dfinity/rust@v3.3.0"` |
| `"type": "motoko"` | `recipe.type: "@dfinity/motoko@v5.0.0"` |
| `"type": "assets"` | `recipe.type: "@dfinity/static-site@v0.3.3"` (recommended) or `@dfinity/asset-canister@v2.2.1` (legacy). Not a drop-in: static-site is a different canister using `_headers`/`_redirects` (not `.ic-assets.json5`), and switching a deployed canister needs a reinstall — see the `static-site` skill's migration guide. |
| `"type": "assets"` | `recipe.type: "@dfinity/static-site@v0.4.0"` (recommended) or `@dfinity/asset-canister@v2.2.1` (legacy). Not a drop-in: static-site is a different canister using `_headers`/`_redirects` (not `.ic-assets.json5`), and switching a deployed canister needs a reinstall — see the `static-site` skill's migration guide. |
| `"package": "X"` | `recipe.configuration.package: X` — optional as of `@dfinity/rust@v3.3.0`, which defaults it to the canister `name`. Drop it when the Cargo `[package] name` already matches. |
| `"candid": "X"` | `recipe.configuration.candid: X` |
| `"main": "X"` | **Not** `recipe.configuration.main`. The `@dfinity/motoko@v5+` recipe compiles via `mops build`, so `main` moves to `mops.toml` as `[canisters.<canister-name>] main = "X"`. The `[canisters.<name>]` key must exactly match the canister `name` in `icp.yaml`. |
Expand Down
4 changes: 2 additions & 2 deletions skills/service-discoverability/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ Canister IDs differ per network (local, staging, mainnet), so **never commit har
```yaml
name: frontend
recipe:
type: "@dfinity/static-site@v0.3.3"
type: "@dfinity/static-site@v0.4.0"
configuration:
build:
# Runs BEFORE the canister exists — no canister IDs available here.
Expand All @@ -131,7 +131,7 @@ recipe:
- The static-site recipe exports each project canister's ID into `presync` as `ICP_CLI_CID_<NAME>` (name upper-cased, non-alphanumerics → `_`; e.g. `backend` → `ICP_CLI_CID_BACKEND`). Other vars: `ICP_CLI_CID` (this canister), `ICP_CLI_NETWORK`.
- `$ICP_CLI_ENVIRONMENT` is the environment being deployed (e.g. `local`, `ic`), exported into the `presync` shell. It selects the matching template, so the same hook serves every network.
- **`presync` runs with the canister directory as its working directory.** The relative `ic-architecture/...` path therefore resolves *inside the frontend canister directory* — put the templates at `frontend/ic-architecture/`, alongside `canister.yaml` (as the example project does). A path resolved from the repo root instead would make `envsubst` read nothing and silently write an empty manifest (Pitfall 7).
- Pin the recipe to the current release (`@dfinity/static-site@v0.3.3` here); check the static-site recipe releases and the `static-site` skill for the latest.
- Pin the recipe to the current release (`@dfinity/static-site@v0.4.0` here); check the static-site recipe releases and the `static-site` skill for the latest.

Keep one template per environment under `frontend/ic-architecture/`, with `envsubst` placeholders for the IDs.

Expand Down
Loading
Loading