Skip to content

Commit 9d81761

Browse files
authored
docs: sync content against the ten upstream releases the watcher surfaced (#370)
Closes #360, #361, #362, #363, #364, #365, #366, #367, #368, #369. The first batch from the upstream watcher added in #358, plus one fix to the watcher itself that running the batch exposed. **23 files, 18 of them docs pages.** Two of the ten issues needed real content changes; the other eight were version strings or pin bumps. Every claim below was checked against the upstream at the new ref. Where a replacement is named, it is upstream's own wording, not an inference. ## What a reviewer should scrutinise 1. **The 20 Motoko call-site replacements** are the only changes that alter code a reader copies. Each one is named in upstream's `@deprecated` marker, quoted below. 2. **`icp canister status <name> -i`** replacing `icp canister id <name>`. This is a real command substitution, verified against the installed CLI, not a rename. 3. **The examples path filter** decides whether a whole class of issue fires. Its two-way verification is in the table below. Everything else is a version string or a pin. ## motoko-core v2.4.0 → v2.6.1: 20 deprecated call sites (#362) v2.6.0 deprecated every `Module.fromX` conversion that has a `toX` counterpart. Our examples used five of them, so left alone each one emits a compiler warning for anyone who copies the code. The replacements are read from `src/*.mo` at v2.6.1: | Deprecated | Upstream's `@deprecated` text | Sites | |---|---|---| | `Nat64.fromNat` | Use `Nat.toNat64` instead. | 7 | | `Nat8.fromNat` | Use `Nat.toNat8` instead. | 5 | | `Blob.fromArray` | Use `Array.toBlob` instead. | 5 | | `Float.fromInt` | Use `Int.toFloat` instead. | 2 | | `Text.fromChar` | Use `Char.toText` instead. | 1 | **Import policy: four added, zero removed.** A replacement can need a module the block did not import (`Nat`, `Char`), so those are added. Nothing is removed, deliberately: an unused import is harmless, a missing one does not compile, and pre-existing imports are not this change's business. A first attempt did prune them and got it wrong three ways, dropping `Text` where `hex.chars()` still needs it in scope for contextual dot, plus `Cycles` and `Principal`, which are unrelated. That pass was reverted. Two cases handled by hand: one `Nat64.fromNat` appears in prose rather than a fence (`ledgers.mdx`), and one fence is a fragment with no import block of its own, so it gets the call change without an import. ## icp-cli v1.1.0 → v1.3.0: nothing lost, two commands that never existed (#361) The decisive check is that **`docs/reference/cli.md` lost 0 lines** between the two refs (14 added, all for the new `icp canister link`). No documented command or flag disappeared, so the bump itself is safe. Verifying every `icp` invocation in `docs/` against that reference then surfaced two commands that do not exist. Both confirmed against the installed v1.3.0, not just the reference: | In the docs | Actual | Sites | |---|---|---| | `icp canister id <name>` | `icp canister status <name> -i` (`-i` is documented as "Only print the canister ids") | 4 | | `icp identity whoami` | `icp identity principal` | 1 | These predate the bump. They are exactly what the verification pass deferred in #354 was for. ## The remaining eight - **Four recipes** (#366, #367, #368, #369) each shipped **one identical additive change**, an optional `visibility` field on metadata entries, so the `icp.yaml` examples stay valid and only the 20 version strings move: `asset-canister` v2.2.1→v2.3.0 (10 places), `rust` v3.3.0→v3.4.0 (6), `motoko` v5.0.0→v5.1.0 (3), `prebuilt` v2.0.0→v2.1.0 (1). - **icp-js-core v5.4.0 → v6.1.0** (#364) is a major bump, and still pin-only for us. It changes `Agent.readState`, delegation permissions, effective subnet ID and URL path handling. Our examples import `agent`, `agent/canister-env`, `principal`, `identity` and `candid` only, never construct a `Delegation`, and never call `readState`. - **cdk-rs 0.20.2** (#363) only makes entry points lenient about an empty input vector. Pin-only. - **icp-js-canisters 3.6.0** (#365) adds NNS converter fields and snapshot visibility; the stated `>= 3.5.0` minimum still holds. Pin-only. - **examples** (#360) bumped to `42c474d`, with all six `snippet=` regions verified to resolve. ## Watcher fix: report an examples bump only when it touches a quoted file Running the batch showed #360 was noise, and the first attempt at fixing that was wrong in an instructive way. I dropped the check entirely, reasoning that the build already fails when a `snippet=` path or `#region` marker stops resolving. It does, but that only covers **breakage**. It cannot see an example being **corrected upstream while still resolving**, which leaves the docs quoting old code with a green build. That is the more valuable signal, and dropping the check would have lost it. So the check stays and gets precise. The entry carries `pathFilter: "snippets"`, and the check intersects the files changed between the pinned gitlink and the branch head with every file a `snippet=` quotes, opening an issue only when they overlap, naming the files. Verified both ways against real history: | Pin | Range | Result | |---|---|---| | `01edb5d8`, before a fix to the two `send_http_*` examples | 5 commits, 80 files | **reports**, naming `motoko/send_http_get/backend/main.mo` and `motoko/send_http_post/backend/main.mo` | | `b4fe175`, the pin this PR bumps from | 4 commits, 78 files, none quoted | **silent** | The second row is the point: #360 fired for a range touching nothing the docs quote, and would not fire now. Two implementation details worth a look. The snippet path is `<lang-dir>/<attribute>`, where the directory comes from the **fence language**, so `LANG_TO_DIR` is mirrored from `plugins/remark-snippet.mjs` rather than imported, because that plugin pulls in remark dependencies and the workflow installs none. The two must be kept in step, and an unmapped language throws rather than silently matching fewer files. Separately, when the comparison cannot be trusted, the API failing or truncating at its 300-file cap, the check reports instead of assuming nothing moved. The per-recipe split from #358 is unchanged. A batch release produces one issue per recipe, four here for a single upstream change. That is the cost of tracking them independently, and it is what made four stale version strings visible. ## Verification ``` npm run check:upstream # every entry current, exits 0 npm run build # passes npm run validate # 7 errors, unchanged from main ``` The 7 are all in `docs/references/internet-identity-spec.md`, which is generated. They clear when Internet Identity cuts its next dated release containing [dfinity/internet-identity#4284](dfinity/internet-identity#4284); our pin is already on the newest existing release tag, so there is nothing to sync until then. Tracked in #356. ## Known limits - The two CLI command fixes are verified against `icp 1.3.0` locally and against the published reference, but not executed end to end against a live project. - `snippet=` coverage depends on `LANG_TO_DIR` staying in step with the plugin. The two now match key for key, verified by parsing both maps rather than reading them, and an unmapped language fails loudly, which is the safe direction. It is still a duplicated constant: the plugin cannot be imported here because it pulls in remark dependencies the workflow does not install.
1 parent 4174594 commit 9d81761

23 files changed

Lines changed: 202 additions & 91 deletions

.agents/upstream-tracking.md

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,19 @@ Upstream repos fall into three groups, and the group decides the procedure.
77
| | Vendored (submodule) | Watched | Reference |
88
|---|---|---|---|
99
| Which | `motoko`, `internetidentity`, `examples` | the `watched` array in `.sources/upstream.json` | the `reference` array |
10-
| Why | the build opens their files | a release can silently invalidate a lot of published content | drawn on too lightly for a weekly issue |
10+
| Why | the build opens their files | a release can silently invalidate a lot of published content | drawn on too lightly, or another check already catches the drift |
1111
| Pin | the gitlink | `pinned` in `upstream.json` | none; verify against the latest release |
12-
| Notified | yes | yes | no |
12+
| Release issue | only `examples`, and only when a quoted file moved | yes | no |
1313

1414
Deciding between the last two is a judgment about blast radius, and the `why`
1515
field on each `reference` entry records the footprint that decided it. Promote an
1616
entry to `watched` if its footprint grows.
1717

1818
`motoko` and `internetidentity` have their own weekly sync workflows that open
19-
the bump PR directly. `examples` and the `watched` repos are covered by the
20-
weekly **Upstream release check**, which opens an issue. `reference` repos are
21-
not checked at all.
19+
the bump PR directly. The `watched` repos are covered by the weekly **Upstream
20+
release check**, which opens an issue whenever one moves. That same check covers
21+
`examples`, but opens an issue only when the range touched a file a `snippet=`
22+
quotes. `reference` repos are not checked at all.
2223

2324
## Why only three are vendored
2425

@@ -167,10 +168,14 @@ When `icp-cli` moves to a new minor:
167168

168169
Only the project maintainer bumps submodule refs.
169170

170-
`examples` tracks a branch and is checked by the same **Upstream release check**
171-
workflow, which opens an issue when the gitlink falls behind that branch. Its pin
172-
lives in git, so `upstream.json` records only the branch to compare against and
173-
what a bump affects.
171+
`examples` is checked, but only for the case the build cannot see. A `snippet=`
172+
path or `#region` marker that stops resolving already fails the build. What the
173+
build cannot notice is an example being corrected upstream while still
174+
resolving, which leaves the docs quoting old code with everything green. So its
175+
entry carries `pathFilter: "snippets"`: the check intersects the files changed
176+
between the pinned gitlink and the branch head with every file a `snippet=`
177+
quotes, and opens an issue only when they overlap, naming the files. Any other
178+
commit on that repo stays silent.
174179

175180
`motoko` and `internetidentity` are not in `upstream.json`: `sync-motoko.yml` and
176181
`sync-ii-spec.yml` already check for a new release, run the sync, and open the

.sources/examples

Submodule examples updated 78 files

.sources/upstream.json

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,60 +2,69 @@
22
"$comment": [
33
"Every upstream this repo tracks, in three groups.",
44
"",
5-
"`vendored` are submodules whose pin has no sync workflow of its own. Their pin",
6-
"is the gitlink in git, not a field here, so it has one source of truth; the entry",
7-
"records which branch to compare against and what a bump affects. `motoko` and",
8-
"`internetidentity` are absent on purpose: sync-motoko.yml and sync-ii-spec.yml",
9-
"already check for a new release and open the bump PR themselves.",
10-
"",
115
"`watched` are repos where a release can silently invalidate a lot of published",
126
"content, so they get a pinned ref and a weekly issue when they move. Verify",
137
"claims against the pinned ref, not against main, so a review is reproducible.",
148
"",
9+
"`vendored` are submodules whose pin has no sync workflow of its own. Their pin",
10+
"is the gitlink, so git stays the single source of truth. `motoko` and",
11+
"`internetidentity` are absent on purpose: sync-motoko.yml and sync-ii-spec.yml",
12+
"already release-check and open the bump PR themselves.",
13+
"",
1514
"`reference` are repos the docs draw on too lightly to be worth a weekly issue:",
1615
"each `why` records the footprint that decided it. They carry no pin. Verify",
17-
"against the latest release on demand; the surface is small enough that the next",
18-
"edit to those pages catches any drift. Promote one to `watched` if its footprint",
19-
"grows.",
16+
"against the latest release on demand. Promote one if that changes.",
2017
"",
21-
"scripts/check-upstream-releases.mjs checks `vendored` and `watched` only, and",
18+
"scripts/check-upstream-releases.mjs checks `watched` and `vendored`, and",
2219
".github/workflows/upstream-releases.yml opens an issue per repo that moved.",
2320
"See AGENTS.md 'Source material' and .agents/upstream-tracking.md.",
2421
"",
2522
"Fields (watched):",
2623
" repo owner/name on GitHub",
24+
" name optional, when one repo releases several things independently",
2725
" pinned the ref docs are currently verified against",
2826
" track where releases appear: 'release' (git tags matching tagPattern),",
2927
" 'crate' (crates.io, needs `crate`), 'npm' (npm registry, needs",
30-
" `package`), or 'commit' (no releases; the default branch head).",
31-
" Entries in `vendored` use 'branch' and name the branch instead.",
28+
" `package`), or 'commit' (no releases; the default branch head)",
3229
" tagPattern anchored JS regex selecting the tags that count as a release",
3330
" verify file whose diff between the two refs is the review payload",
3431
" affects what to re-check in docs/ when this moves",
35-
" reference authoritative published docs for the topic"
32+
" reference authoritative published docs for the topic, deliberately the",
33+
" living version rather than a pinned one: an issue exists because a",
34+
" NEW release shipped, so a maintainer opening it wants the docs for",
35+
" that release, not for the version being replaced. This is why the",
36+
" icp-cli entry uses the bare root while AGENTS.md requires a",
37+
" versioned slug in docs/ pages, and why every other entry here",
38+
" points at docs.rs/latest, mops.one, js.icp.build or a branch.",
39+
"",
40+
"Fields (vendored): path, repo, track 'branch', branch, affects, and an optional",
41+
"pathFilter. 'snippets' reports only when the range touched a file quoted by a",
42+
"`snippet=` in docs/, so an unrelated commit on an active repo stays silent."
3643
],
3744
"vendored": [
3845
{
3946
"path": ".sources/examples",
4047
"repo": "dfinity/examples",
4148
"track": "branch",
4249
"branch": "master",
43-
"affects": "Every `snippet=` path and `#region` marker resolved at build time by plugins/remark-snippet.mjs. A renamed region is a build error, so verify each one after bumping."
50+
"pathFilter": "snippets",
51+
"affects": "Bump the submodule and re-read the affected pages: the example moved on, so the code the docs quote is behind. The build already fails if a `snippet=` path or `#region` marker stops resolving, so this reports the case the build cannot see, an example that changed while still resolving.",
52+
"reference": "https://github.com/dfinity/examples"
4453
}
4554
],
4655
"watched": [
4756
{
4857
"repo": "dfinity/icp-cli",
49-
"pinned": "v1.1.0",
58+
"pinned": "v1.3.0",
5059
"track": "release",
5160
"tagPattern": "^v\\d+\\.\\d+\\.\\d+$",
5261
"verify": "docs/reference/cli.md",
53-
"affects": "Every `icp` command and flag in docs/. A new minor also moves the cli.internetcomputer.org link slug (AGENTS.md 'Linking rules'). NOTE: the doc links were moved to the 1.3 slug in #354, but the commands themselves were last verified against v1.1.0, so the first bump of this pin carries that verification pass.",
62+
"affects": "Every `icp` command and flag in docs/. A new minor also moves the cli.internetcomputer.org link slug (AGENTS.md 'Linking rules'), so check the slug procedure in .agents/upstream-tracking.md when the minor changes.",
5463
"reference": "https://cli.internetcomputer.org/"
5564
},
5665
{
5766
"repo": "dfinity/motoko-core",
58-
"pinned": "v2.4.0",
67+
"pinned": "v2.6.1",
5968
"track": "release",
6069
"tagPattern": "^v\\d+\\.\\d+\\.\\d+$",
6170
"affects": "Every `mo:core` import and API signature in Motoko code blocks.",
@@ -64,15 +73,15 @@
6473
},
6574
{
6675
"repo": "dfinity/cdk-rs",
67-
"pinned": "0.20.1",
76+
"pinned": "0.20.2",
6877
"track": "crate",
6978
"crate": "ic-cdk",
7079
"affects": "`ic-cdk` APIs in Rust code blocks. The repo stopped tagging releases (its newest bare-semver tag is two minors behind the published crate), so the crate version on crates.io is the release identity. Read the sections newer than the pin in https://github.com/dfinity/cdk-rs/blob/master/ic-cdk/CHANGELOG.md, then grep docs/ for the symbols they name. `ic-cdk-timers` and `ic-cdk-executor` version separately; check whether they moved too.",
7180
"reference": "https://docs.rs/ic-cdk/latest/ic_cdk/"
7281
},
7382
{
7483
"repo": "dfinity/icp-js-core",
75-
"pinned": "v5.4.0",
84+
"pinned": "v6.1.0",
7685
"track": "release",
7786
"tagPattern": "^v\\d+\\.\\d+\\.\\d+$",
7887
"verify": "CHANGELOG.md",
@@ -81,7 +90,7 @@
8190
},
8291
{
8392
"repo": "dfinity/icp-js-canisters",
84-
"pinned": "3.5.0",
93+
"pinned": "3.6.0",
8594
"track": "npm",
8695
"package": "@icp-sdk/canisters",
8796
"affects": "`@icp-sdk/canisters` APIs, notably `AssetManager` in references/application-canisters.md and guides/frontends/asset-canister.md, which states a minimum of 3.5.0. This repo's semver tags lag its published versions, so npm is the release signal. Changelog: https://github.com/dfinity/icp-js-canisters/blob/main/CHANGELOG.md",
@@ -90,7 +99,7 @@
9099
{
91100
"repo": "dfinity/icp-cli-recipes",
92101
"name": "asset-canister",
93-
"pinned": "asset-canister-v2.2.1",
102+
"pinned": "asset-canister-v2.3.0",
94103
"track": "release",
95104
"tagPattern": "^asset-canister-v\\d+\\.\\d+\\.\\d+$",
96105
"affects": "Cited in 10 places across docs/, including references/application-canisters.md and guides/frontends/asset-canister.md. The legacy frontend recipe; static-site supersedes it. Each recipe in this repo tags and releases on its own prefix, so it gets its own entry: a single pattern across prefixes would compare `rust-` against `static-site-` textually and only ever surface one of them.",
@@ -108,7 +117,7 @@
108117
{
109118
"repo": "dfinity/icp-cli-recipes",
110119
"name": "rust",
111-
"pinned": "rust-v3.3.0",
120+
"pinned": "rust-v3.4.0",
112121
"track": "release",
113122
"tagPattern": "^rust-v\\d+\\.\\d+\\.\\d+$",
114123
"affects": "Cited in 6 places as the Rust canister recipe in icp.yaml examples. Each recipe in this repo tags and releases on its own prefix, so it gets its own entry: a single pattern across prefixes would compare `rust-` against `static-site-` textually and only ever surface one of them.",
@@ -117,7 +126,7 @@
117126
{
118127
"repo": "dfinity/icp-cli-recipes",
119128
"name": "motoko",
120-
"pinned": "motoko-v5.0.0",
129+
"pinned": "motoko-v5.1.0",
121130
"track": "release",
122131
"tagPattern": "^motoko-v\\d+\\.\\d+\\.\\d+$",
123132
"affects": "Cited in 3 places as the Motoko canister recipe in icp.yaml examples. Each recipe in this repo tags and releases on its own prefix, so it gets its own entry: a single pattern across prefixes would compare `rust-` against `static-site-` textually and only ever surface one of them.",
@@ -126,7 +135,7 @@
126135
{
127136
"repo": "dfinity/icp-cli-recipes",
128137
"name": "prebuilt",
129-
"pinned": "prebuilt-v2.0.0",
138+
"pinned": "prebuilt-v2.1.0",
130139
"track": "release",
131140
"tagPattern": "^prebuilt-v\\d+\\.\\d+\\.\\d+$",
132141
"affects": "Cited once, in guides/canister-management/reproducible-builds.md. Each recipe in this repo tags and releases on its own prefix, so it gets its own entry: a single pattern across prefixes would compare `rust-` against `static-site-` textually and only ever surface one of them.",

AGENTS.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -229,9 +229,10 @@ git submodule update --init --depth 1 # do NOT use --recursive
229229
| Code examples (`snippet=`, `<CodeExample>`) | `.sources/examples/` |
230230

231231
Pinned versions: [`.sources/VERSIONS`](.sources/VERSIONS). `motoko` and
232-
`internetidentity` are release-checked and synced by their own workflows;
233-
`examples` tracks a branch and is checked by the weekly **Upstream release
234-
check**. Canister IDs and code patterns are in the skills (see "Skills").
232+
`internetidentity` are release-checked and synced by their own workflows.
233+
`examples` is checked weekly, but reports only when a commit touches a file a
234+
`snippet=` quotes; the build already fails if such a path or `#region` marker
235+
stops resolving. Canister IDs and code patterns are in the skills (see "Skills").
235236

236237
**Watched** are the repos where a release can silently invalidate a lot of what
237238
is published, so [`.sources/upstream.json`](.sources/upstream.json) records the

docs/getting-started/project-structure.mdx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ The Motoko backend uses the `@dfinity/motoko` recipe, which compiles via `mops b
8787
```yaml
8888
name: backend
8989
recipe:
90-
type: "@dfinity/motoko@v5.0.0"
90+
type: "@dfinity/motoko@v5.1.0"
9191
```
9292

9393
The recipe takes no source or Candid configuration. Instead, the source file (and optionally the Candid file and compiler flags) are declared in a `mops.toml` at the project root. The `[canisters]` key must match the canister `name`:
@@ -106,7 +106,7 @@ The Rust backend uses the `@dfinity/rust` recipe:
106106
```yaml
107107
name: backend
108108
recipe:
109-
type: "@dfinity/rust@v3.3.0"
109+
type: "@dfinity/rust@v3.4.0"
110110
configuration:
111111
shrink: true
112112
candid: backend.did
@@ -123,7 +123,7 @@ The frontend uses the `@dfinity/asset-canister` recipe, which builds the fronten
123123
```yaml
124124
name: frontend
125125
recipe:
126-
type: "@dfinity/asset-canister@v2.2.1"
126+
type: "@dfinity/asset-canister@v2.3.0"
127127
configuration:
128128
build:
129129
- npm install

docs/guides/canister-calls/candid.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ You can also provide a hand-written `.did` file by setting the `candid` field fo
110110
canisters:
111111
- name: backend
112112
recipe:
113-
type: "@dfinity/motoko@v5.0.0"
113+
type: "@dfinity/motoko@v5.1.0"
114114
```
115115
116116
Declare the source and Candid file under the canister's entry in `mops.toml`:
@@ -166,7 +166,7 @@ Reference the generated `.did` file in your `icp.yaml`:
166166
canisters:
167167
- name: my_canister
168168
recipe:
169-
type: "@dfinity/rust@v3.3.0"
169+
type: "@dfinity/rust@v3.4.0"
170170
configuration:
171171
candid: src/my_canister/my_canister.did
172172
```

docs/guides/canister-calls/inter-canister-calls.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ Deployment order does not matter: `icp deploy` creates all canisters first, then
201201
**Init arguments.** Accept the target `Principal` as an `#[init]` argument and store it. This avoids the environment variable lookup at call time but requires passing the ID at every deploy and upgrade:
202202

203203
```bash
204-
TARGET_ID=$(icp canister id counter)
204+
TARGET_ID=$(icp canister status counter -i)
205205
icp deploy my_canister --argument "(principal \"$TARGET_ID\")"
206206
```
207207

docs/guides/canister-management/large-wasm.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ The Rust and prebuilt recipes expose a `compress` flag that gzip-compresses the
3434
canisters:
3535
- name: backend
3636
recipe:
37-
type: "@dfinity/rust@v3.3.0"
37+
type: "@dfinity/rust@v3.4.0"
3838
configuration:
3939
shrink: true
4040
compress: true

docs/guides/canister-management/logs.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ You can configure log visibility per canister in `icp.yaml` so it is applied on
155155
canisters:
156156
- name: backend
157157
recipe:
158-
type: "@dfinity/rust@v3.3.0"
158+
type: "@dfinity/rust@v3.4.0"
159159
settings:
160160
log_visibility: controllers # "controllers" | "public" | allowed_viewers object
161161
```

docs/guides/canister-management/optimization.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ This guide covers the main tools and techniques available:
2626
canisters:
2727
- name: backend
2828
recipe:
29-
type: "@dfinity/rust@v3.3.0"
29+
type: "@dfinity/rust@v3.4.0"
3030
configuration:
3131
shrink: true
3232
```

0 commit comments

Comments
 (0)