diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index dbd77ef..695c449 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,5 +1,14 @@ # All files are owned by the DX team. # At least one DX team member must approve every PR before it can be merged. -# DX team members are also configured as bypass actors in the branch ruleset -# and can merge their own PRs without a separate review. * @dfinity/dx + +# Interface specification — additional required reviewers for spec files and attachments. +# GitHub CODEOWNERS: last matching rule wins, so these override the wildcard above. +docs/references/ic-interface-spec/* @dfinity/interface-spec @dfinity/team-dsm @dfinity/consensus @dfinity/dx +docs/references/http-gateway-protocol-spec.md @dfinity/interface-spec @dfinity/team-dsm @dfinity/consensus @dfinity/dx +docs/references/management-canister.md @dfinity/interface-spec @dfinity/team-dsm @dfinity/consensus @dfinity/dx +docs/references/execution-errors.md @dfinity/team-dsm @dfinity/dx +public/references/ic.did @dfinity/interface-spec @dfinity/team-dsm @dfinity/consensus @dfinity/dx +public/references/certificates.cddl @dfinity/interface-spec @dfinity/team-dsm @dfinity/consensus @dfinity/dx +public/references/requests.cddl @dfinity/interface-spec @dfinity/team-dsm @dfinity/consensus @dfinity/dx +public/references/http-gateway.did @dfinity/interface-spec @dfinity/team-dsm @dfinity/consensus @dfinity/dx diff --git a/.github/workflows/interface-spec-slack.yml b/.github/workflows/interface-spec-slack.yml new file mode 100644 index 0000000..432040a --- /dev/null +++ b/.github/workflows/interface-spec-slack.yml @@ -0,0 +1,43 @@ +name: Interface Specification PR Slack Notification + +on: + pull_request: + types: [opened, ready_for_review] + paths: + - .github/workflows/interface-spec.yml + - .github/workflows/interface-spec-tag.yml + - .github/workflows/interface-spec-slack.yml + - docs/references/ic-interface-spec/** + - docs/references/http-gateway-protocol-spec.md + - public/references/certificates.cddl + - public/references/requests.cddl + - public/references/http-gateway.did + - public/references/ic.did + +jobs: + notify-slack: + name: Notify Slack + if: github.event.pull_request.draft == false + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + + - name: Sanitize PR title + id: sanitize + env: + RAW_TITLE: ${{ github.event.pull_request.title }} + run: | + ESCAPED_TITLE=$(echo "$RAW_TITLE" \ + | sed 's/&/\&/g' \ + | sed 's//\>/g') + echo "safe_title=$ESCAPED_TITLE" >> "$GITHUB_OUTPUT" + + - name: Post to Slack + uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a # v2.1.1 + with: + method: chat.postMessage + token: ${{ secrets.SLACK_API_TOKEN }} + payload: | + channel: interface-spec + text: ":github: `${{ github.repository }}` <${{ github.event.pull_request.html_url }}|${{ steps.sanitize.outputs.safe_title }}>" diff --git a/.github/workflows/interface-spec-tag.yml b/.github/workflows/interface-spec-tag.yml new file mode 100644 index 0000000..ec2c59d --- /dev/null +++ b/.github/workflows/interface-spec-tag.yml @@ -0,0 +1,40 @@ +name: Interface Specification Tag + +on: + pull_request_target: + paths: + - .github/workflows/interface-spec.yml + - .github/workflows/interface-spec-tag.yml + - .github/workflows/interface-spec-slack.yml + - docs/references/ic-interface-spec/** + - docs/references/http-gateway-protocol-spec.md + - public/references/certificates.cddl + - public/references/requests.cddl + - public/references/http-gateway.did + - public/references/ic.did + +jobs: + interface-spec-tag: + name: Tag PR with interface-spec + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - name: Create label if missing + run: | + gh label create interface-spec \ + --color 0075ca \ + --description "Changes to the IC interface specification" \ + --repo ${{ github.repository }} \ + --force + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Tag PR with interface-spec + run: | + gh pr edit ${{ github.event.pull_request.number }} \ + --add-label interface-spec \ + --repo ${{ github.repository }} + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/interface-spec.yml b/.github/workflows/interface-spec.yml new file mode 100644 index 0000000..5f2a42c --- /dev/null +++ b/.github/workflows/interface-spec.yml @@ -0,0 +1,38 @@ +name: Interface Specification + +on: + pull_request: + paths: + - .github/workflows/interface-spec.yml + - docs/references/ic-interface-spec/** + - docs/references/http-gateway-protocol-spec.md + - public/references/certificates.cddl + - public/references/requests.cddl + - public/references/http-gateway.did + - public/references/ic.did + push: + branches: + - main + +jobs: + cddl: + name: Check cddl files + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + - name: Check cddl files + run: | + docker run --rm -v $PWD/public/references:/workdir ghcr.io/anweiss/cddl-cli:0.9.1 compile-cddl --cddl /workdir/certificates.cddl + docker run --rm -v $PWD/public/references:/workdir ghcr.io/anweiss/cddl-cli:0.9.1 compile-cddl --cddl /workdir/requests.cddl + + candid: + name: Check candid files + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + - name: Check candid files + run: | + curl -L https://github.com/dfinity/candid/releases/download/2023-07-25/didc-linux64 -o didc + chmod +x didc + ./didc check public/references/http-gateway.did + ./didc check public/references/ic.did diff --git a/astro.config.mjs b/astro.config.mjs index 13324ca..3bd2c57 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -7,6 +7,7 @@ import remarkIcpCliVersion from "./plugins/remark-icp-cli-version.mjs"; import remarkSnippet from "./plugins/remark-snippet.mjs"; import remarkHeadingId from "./plugins/remark-heading-id.mjs"; import remarkPlantUML from "./plugins/remark-plantuml.mjs"; +import remarkIncludeFile from "./plugins/remark-include-file.mjs"; import agentDocs from "./plugins/astro-agent-docs.mjs"; import { sidebar } from "./sidebar.mjs"; import { TITLE, DESCRIPTION, PUBLISHER, OG_ALT } from "./src/branding.mjs"; @@ -18,7 +19,7 @@ export default defineConfig({ // Rehype plugins work with Starlight (remark plugins don't — Starlight overrides them). // See: https://github.com/dfinity/icp-cli/issues/423 rehypePlugins: [rehypeRewriteLinks, rehypeExternalLinks], - remarkPlugins: [remarkHeadingId, remarkSnippet, remarkIcpCliVersion, remarkPlantUML], + remarkPlugins: [remarkHeadingId, remarkSnippet, remarkIcpCliVersion, remarkPlantUML, remarkIncludeFile], }, integrations: [ starlight({ diff --git a/docs/guides/frontends/certification.md b/docs/guides/frontends/certification.md index 65ddeaf..4d2be16 100644 --- a/docs/guides/frontends/certification.md +++ b/docs/guides/frontends/certification.md @@ -318,6 +318,6 @@ For the full working example including a backend canister, see the [certified-co - [Asset canister](asset-canister.md): deploy and configure the standard asset canister with automatic certification - [Certified variables](../backends/certified-variables.md): certify Candid query responses from backend canisters - [Security concepts](../../concepts/security.md): why query integrity matters -- [HTTP Gateway specification](../../references/http-gateway-spec.md): how boundary nodes verify responses +- [HTTP Gateway specification](../../references/http-gateway-protocol-spec.md): how boundary nodes verify responses diff --git a/docs/references/http-gateway-spec.md b/docs/references/http-gateway-protocol-spec.md similarity index 99% rename from docs/references/http-gateway-spec.md rename to docs/references/http-gateway-protocol-spec.md index c67fe9f..d709b99 100644 --- a/docs/references/http-gateway-spec.md +++ b/docs/references/http-gateway-protocol-spec.md @@ -432,7 +432,7 @@ service : { } ``` -You can also [download the file](/references/_attachments/http-gateway.did). +You can also [download the file](/references/http-gateway.did). Not all of this interface is required. The following sections detail what can be optionally omitted depending on the requirements of the canister in question. diff --git a/docs/references/ic-interface-spec/certification.md b/docs/references/ic-interface-spec/certification.md index 53d108f..f389994 100644 --- a/docs/references/ic-interface-spec/certification.md +++ b/docs/references/ic-interface-spec/certification.md @@ -179,7 +179,7 @@ Delegations are *scoped*, i.e., they indicate which set of canister principals t ### Encoding of certificates {#certification-encoding} -The binary encoding of a certificate is a CBOR (see [CBOR](./index.md#cbor)) value according to the following CDDL (see [CDDL](./index.md#cddl)). You can also [download the file](/references/_attachments/certificates.cddl). +The binary encoding of a certificate is a CBOR (see [CBOR](./index.md#cbor)) value according to the following CDDL (see [CDDL](./index.md#cddl)). You can also [download the file](/references/certificates.cddl). The values in the [The system state tree](./index.md#state-tree) are encoded to blobs as follows: @@ -251,6 +251,6 @@ In the pruned tree, the `lookup_path` function behaves as follows: ## The HTTP Gateway protocol {#http-gateway} -The HTTP Gateway Protocol has been moved into its own [specification](../http-gateway-spec.md). +The HTTP Gateway Protocol has been moved into its own [specification](../http-gateway-protocol-spec.md). diff --git a/docs/references/ic-interface-spec/https-interface.md b/docs/references/ic-interface-spec/https-interface.md index 544a277..4af90bf 100644 --- a/docs/references/ic-interface-spec/https-interface.md +++ b/docs/references/ic-interface-spec/https-interface.md @@ -735,7 +735,7 @@ A typical request would be (written in [CBOR diagnostic notation](https://www.rf ### CDDL description of requests and responses {#api-cddl} -This section summarizes the format of the CBOR data passed to and from the entry points described above. You can also [download the file](/references/_attachments/requests.cddl) and see [CDDL](./index.md#cddl) for more information. +This section summarizes the format of the CBOR data passed to and from the entry points described above. You can also [download the file](/references/requests.cddl) and see [CDDL](./index.md#cddl) for more information. ### Ordering guarantees diff --git a/docs/references/ic-interface-spec/management-canister.md b/docs/references/ic-interface-spec/management-canister.md index a221dee..4794cfa 100644 --- a/docs/references/ic-interface-spec/management-canister.md +++ b/docs/references/ic-interface-spec/management-canister.md @@ -22,7 +22,10 @@ It is possible to use the management canister via external requests (a.k.a. ingr ### Interface overview {#ic-candid} -The [interface description](/reference/ic.did), in [Candid syntax](../candid-spec.md), describes the available functionality. +The interface description below, in [Candid syntax](../candid-spec.md), describes the available functionality. You can also [download the file](/references/ic.did). + +```candid file=/public/references/ic.did +``` The binary encoding of arguments and results are as per Candid specification. diff --git a/docs/references/index.md b/docs/references/index.md index 05c2b16..bd48a2c 100644 --- a/docs/references/index.md +++ b/docs/references/index.md @@ -33,7 +33,7 @@ Technical reference material for ICP development. These pages cover exact specif ## Specifications - **[IC Interface Specification](ic-interface-spec/index.md)**: System API, HTTPS interface, certified data, management canister, and formal specification of the Internet Computer. -- **[HTTP Gateway Specification](http-gateway-spec.md)**: How boundary nodes serve canister HTTP responses with certification verification. +- **[HTTP Gateway Specification](http-gateway-protocol-spec.md)**: How boundary nodes serve canister HTTP responses with certification verification. - **[Candid Specification](candid-spec.md)**: The Candid interface description language: type system, encoding, and subtyping rules. - **[Internet Identity Specification](internet-identity-spec.md)**: Delegation chains, passkey management, and canister signatures. diff --git a/docs/references/internet-identity-spec.md b/docs/references/internet-identity-spec.md index 0396f34..0a3bc2b 100644 --- a/docs/references/internet-identity-spec.md +++ b/docs/references/internet-identity-spec.md @@ -241,7 +241,7 @@ This feature is intended to allow more flexibility with respect to the origins o `https://.ic0.app` and `https://.raw.ic0.app` do _not_ issue the same principals by default . However, this feature can also be used to map `https://.raw.ic0.app` to `https://.ic0.app` principals or vice versa. ::: -In order for Internet Identity to accept the `derivationOrigin` the origin of the client application must be listed in the JSON object served on the URL `https://.icp0.io/.well-known/ii-alternative-origins` (i.e. the file must be hosted by an ICP canister that must implement the `http_request` query call as specified [here](./http-gateway-spec.md)). +In order for Internet Identity to accept the `derivationOrigin` the origin of the client application must be listed in the JSON object served on the URL `https://.icp0.io/.well-known/ii-alternative-origins` (i.e. the file must be hosted by an ICP canister that must implement the `http_request` query call as specified [here](./http-gateway-protocol-spec.md)). ### JSON Schema {#alternative-frontend-origins-schema} @@ -1411,7 +1411,7 @@ See [here](../guides/authentication/verifiable-credentials.md) for the specifica ### HTTP gateway protocol -The methods `http_request` and `http_request_update` serve the front-end assets to browesers. See [here](./http-gateway-spec.md) for additional details. +The methods `http_request` and `http_request_update` serve the front-end assets to browesers. See [here](./http-gateway-protocol-spec.md) for additional details. ### Internal APIs @@ -1475,7 +1475,7 @@ Link replacements from source (source used absolute/relative paths pointing outs - internetcomputer.org [/docs]/current/references/ic-interface-spec/#canister-signatures → ./ic-interface-spec/index.md#canister-signatures (×2) - internetcomputer.org [/docs]/current/references/ic-interface-spec#authentication → ./ic-interface-spec/https-interface.md#authentication - internetcomputer.org [/docs]/current/references/ic-interface-spec/#system-api-inspect-message → ./ic-interface-spec/canister-interface.md#system-api-inspect-message - - internetcomputer.org [/docs]/current/references/http-gateway-protocol-spec → ./http-gateway-spec.md + - internetcomputer.org [/docs]/current/references/http-gateway-protocol-spec → ./http-gateway-protocol-spec.md - internetcomputer.org [/docs]/current/developer-docs/web-apps/custom-domains/using-custom-domains → ../guides/frontends/custom-domains.md - vc-spec.md (relative, same dir in source repo) → ../guides/authentication/verifiable-credentials.md Other changes from source: diff --git a/docs/references/management-canister.md b/docs/references/management-canister.md index 09c9915..30f81e1 100644 --- a/docs/references/management-canister.md +++ b/docs/references/management-canister.md @@ -612,9 +612,9 @@ Methods that require explicit cycle attachment (`create_canister`, `sign_with_ec ## Candid interface -The complete Candid interface definition for the management canister is available at [`ic.did`](/reference/ic.did). This file defines all types and method signatures in machine-readable Candid format and can be used for binding generation and type checking. +The complete Candid interface definition for the management canister is available at [`ic.did`](/references/ic.did). This file defines all types and method signatures in machine-readable Candid format and can be used for binding generation and type checking. - + ## Next steps diff --git a/package-lock.json b/package-lock.json index 041dec0..0e01910 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2223,6 +2223,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2309,6 +2310,7 @@ "resolved": "https://registry.npmjs.org/astro/-/astro-6.1.8.tgz", "integrity": "sha512-6fT9M12U3fpi13DiPavNKDIoBflASTSxmKTEe+zXhWtlebQuOqfOnIrMWyRmlXp+mgDsojmw+fVFG9LUTzKSog==", "license": "MIT", + "peer": true, "dependencies": { "@astrojs/compiler": "^3.0.1", "@astrojs/internal-helpers": "0.8.0", @@ -5473,6 +5475,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -5925,6 +5928,7 @@ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", "license": "MIT", + "peer": true, "dependencies": { "@types/estree": "1.0.8" }, @@ -6669,6 +6673,7 @@ "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.2.tgz", "integrity": "sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==", "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", diff --git a/plugins/remark-include-file.mjs b/plugins/remark-include-file.mjs new file mode 100644 index 0000000..0c3f621 --- /dev/null +++ b/plugins/remark-include-file.mjs @@ -0,0 +1,43 @@ +/** + * Remark plugin that embeds file contents into code blocks using a file= attribute. + * + * Usage in markdown code fences: + * + * ```candid file=/public/references/ic.did + * ``` + * + * The plugin resolves to the project root and reads the file + * synchronously at build time, replacing the empty code block body with the + * file's contents. + * + * A missing file causes a build error. + */ +import { visit } from "unist-util-visit"; +import { readFileSync, existsSync } from "node:fs"; +import { resolve } from "node:path"; +import { dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; + +const ROOT = join(dirname(fileURLToPath(import.meta.url)), ".."); + +export default function remarkIncludeFile() { + return (tree, file) => { + visit(tree, "code", (node) => { + const fileMeta = (node.meta || "") + .split(" ") + .find((m) => m.startsWith("file=")); + if (!fileMeta) return; + + const rawPath = fileMeta.slice("file=".length).replace(/^/, ROOT); + const absPath = resolve(file.dirname || ROOT, rawPath); + + if (!existsSync(absPath)) { + throw new Error( + `remark-include-file: file not found: ${absPath} (from file=${fileMeta})`, + ); + } + + node.value = readFileSync(absPath, "utf-8").trimEnd(); + }); + }; +} diff --git a/public/references/_attachments/certificates.cddl b/public/references/certificates.cddl similarity index 100% rename from public/references/_attachments/certificates.cddl rename to public/references/certificates.cddl diff --git a/public/references/_attachments/http-gateway.did b/public/references/http-gateway.did similarity index 100% rename from public/references/_attachments/http-gateway.did rename to public/references/http-gateway.did diff --git a/public/reference/ic.did b/public/references/ic.did similarity index 100% rename from public/reference/ic.did rename to public/references/ic.did diff --git a/public/references/_attachments/requests.cddl b/public/references/requests.cddl similarity index 100% rename from public/references/_attachments/requests.cddl rename to public/references/requests.cddl diff --git a/sidebar.mjs b/sidebar.mjs index 4ef125b..538c563 100644 --- a/sidebar.mjs +++ b/sidebar.mjs @@ -129,7 +129,7 @@ export const sidebar = [ { slug: "references/cycles-costs" }, { slug: "references/subnet-types" }, { slug: "references/execution-errors" }, - { slug: "references/http-gateway-spec" }, + { slug: "references/http-gateway-protocol-spec" }, { slug: "references/candid-spec" }, { slug: "references/internet-identity-spec" }, {