Skip to content

fix: state each skill's real mo:core minimum instead of one repo-wide pin - #333

Open
raymondk wants to merge 1 commit into
mainfrom
fix/align-mo-core-pin
Open

fix: state each skill's real mo:core minimum instead of one repo-wide pin#333
raymondk wants to merge 1 commit into
mainfrom
fix/align-mo-core-pin

Conversation

@raymondk

@raymondk raymondk commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

The core mops pin diverged four ways. Rather than standardising on the highest, this gives each skill the minimum its own content actually needs — an example should document what it requires, not impose a repo-wide floor.

The mops constraint

mops has no range syntax. Both of these crash mops install, because it reads the string as a literal version directory (.../packages/core@>=2.0.0/mops.toml):

core = ">=2.0.0"   # ✗ crashes
core = "^2.0.0"    # ✗ crashes

So the mops.toml block carries the concrete floor and the prose states it as >=. The two always name the same version, so there's no dissonance for an agent reading both.

Per-skill floors

Skill Was Now Why
stable-memory 2.0.0 2.0.0 Hard floor — List/Map dot notation fails below it (M0072: field add does not exist)
canister-security 2.0.0 2.0.0
ckbtc 2.0.0 2.0.0
cycles-management 2.0.0 2.0.0
vetkd 2.0.0 2.0.0
https-outcalls prose "mo:core 2.0" 2.0.0 Prose replaced with a concrete, checkable floor
icrc-ledger 2.3.1 2.0.0 Nothing in it needs 2.3.x — verified
multi-canister 2.1.0 2.1.0 Runtime.envVar needs it, as #324 established

Verification

Every claimed floor was checked, not assumed: for each skill I extracted its Motoko examples, type-checked them with mops check at the claimed floor, and confirmed the error set matches the one at 2.5.0. All eight pass.

OK   stable-memory      floor 2.0.0: compiles same as 2.5.0
OK   canister-security  floor 2.0.0: compiles same as 2.5.0
OK   ckbtc              floor 2.0.0: compiles same as 2.5.0
OK   cycles-management  floor 2.0.0: compiles same as 2.5.0
OK   vetkd              floor 2.0.0: compiles same as 2.5.0
OK   https-outcalls     floor 2.0.0: compiles same as 2.5.0
OK   icrc-ledger        floor 2.0.0: compiles same as 2.5.0
OK   multi-canister     floor 2.1.0: compiles same as 2.5.0

Two floors that compiling code blocks alone would have got wrong, worth calling out:

  • multi-canister. Runtime.envVar appears only in prose (Prerequisites and Pitfall 1), never inside a ```motoko block. Measured from code alone its floor reads as 1.0.0 — the 2.1.0 requirement is real but invisible to the compiler. Verified separately: Runtime.envVar fails at core 1.0.0 with `M0072`, since `Runtime` there has only `trap` and `unreachable`.
  • internet-identity. Its 2.5.0 is a genuine transitive floor: identity-attributes@0.4.1 resolves core@2.5.0. Confirmed by installing it. Left untouched.

The residual mops check errors present at every version are harness artifacts, not skill bugs — deliberate teaching fragments that only fail compiled standalone (snippets opening mid-actor, the stable vs persistent contrast pair, ../shared/Types imports). Left as-is.

Left alone deliberately

  • motoko, migrating-motoko, migrating-motoko-enhanced, mops-cli — upstream-tracked; their pins are upstream content per .claude/upstream.md. Worth noting their core >= 2.5.0 is upstream's latest-at-sync value rather than a requirement: I type-checked the motoko skill's own examples (SKILL.md + references/examples.md) at 2.0.0 and 2.5.0 and the results are identical.
  • caffeine-app (2.5.0) — reflects what the Caffeine platform ships, not a minimum its examples need. Out of scope for this drift.
  • Historical statementscycles-management's "In mo:core 2.0, the module is renamed to Cycles" and stable-memory's "With mo:core 2.0, persistent actor makes stable storage trivial" are facts about the 2.0 release, not pins.

Evals

stable-memory #4 previously only checked that some core pin existed. It now requires a concrete version — which is the failure mode that actually breaks a build, given mops rejects ranges and wildcards outright, and is exactly what the baseline emits.

Eval results
━━━ stable-memory #4 — mops.toml must pin moc in [toolchain] (CHANGED) ━━━

  WITH skill: 3/3 passed
    ✅ Includes a [toolchain] section that pins moc to a specific version
    ✅ Includes a [dependencies] section pinning core to a concrete version
    ✅ Does NOT emit a mops.toml whose only sections are [package] and [dependencies]

  WITHOUT skill: 2/3 passed
    ❌ Includes a [toolchain] section that pins moc to a specific version
       → The [toolchain] section is present but empty, containing no moc version pin.
    ✅ Includes a [dependencies] section pinning core to a concrete version
    ✅ Does NOT emit a mops.toml whose only sections are [package] and [dependencies]

  Summary: WITH 3/3 | WITHOUT 2/3
  (An earlier run of this case caught the baseline emitting `core = "*"` — a wildcard
   mops cannot install — which is the behaviour this expectation now guards.)


━━━ multi-canister #4 — core pin must allow Runtime.envVar (regression check) ━━━
  Re-run because this PR changes the exact pin this case covers.

  WITH skill: 3/3 passed
    ✅ Pins core to 2.1.0 or higher in [dependencies]
    ✅ Does NOT pin core = "2.0.0"
    ✅ Reads the ID with Runtime.envVar<system>("PUBLIC_CANISTER_ID:<canister-name>")

  WITHOUT skill: 1/3 passed
    ❌ Pins core to 2.1.0 or higher in [dependencies]
       → The mops.toml only lists base = "0.13.4"; core is not included at all.
    ✅ Does NOT pin core = "2.0.0"
    ❌ Reads the ID with Runtime.envVar<system>("PUBLIC_CANISTER_ID:<canister-name>")
       → The output instead uses Principal.fromActor(Sibling), never calling Runtime.envVar.

  Summary: WITH 3/3 | WITHOUT 1/3 — no regression

npm run validate: 26 skills validated, all passed, 15 warnings (unchanged from baseline).

Closes #297

🤖 Generated with Claude Code

https://claude.ai/code/session_01NEm1Tbkypzi8SuXhrMfBek

@raymondk
raymondk requested review from a team and JoshDFN as code owners August 6, 2026 06:20
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

Skill Validation Report

Project Checks


✓ Project checks passed for 7 skills (0 warnings)

… pin

The core pin diverged four ways (2.0.0 / 2.1.0 / 2.3.1 / 2.5.0). Rather
than standardising on the highest, give each skill the minimum its own
content actually needs — an example should document what it requires, not
impose a repo-wide floor.

mops has no range syntax: `core = ">=2.0.0"` and `core = "^2.0.0"` both
crash `mops install`, which reads the string as a literal version
directory. So the toml carries the concrete floor and the prose states it
as `>=`.

Per-skill floors, each verified by type-checking that skill's Motoko
examples at the claimed version and confirming the error set matches the
one at 2.5.0:

- `core >= 2.0.0`: stable-memory (hard floor — `List`/`Map` dot notation
  fails below it), canister-security, ckbtc, cycles-management, vetkd,
  https-outcalls, icrc-ledger (was 2.3.1; nothing in it needs 2.3.x)
- `core >= 2.1.0`: multi-canister — `Runtime.envVar` needs it, as #324
  established. It appears only in prose, so compiling the code blocks
  alone would have under-reported this floor to 1.0.0.

Prose now reads `core >= X` and the mops.toml block pins exactly X, so
the two agree.

Left alone deliberately:
- `motoko`, `migrating-motoko`, `migrating-motoko-enhanced`, `mops-cli` —
  upstream-tracked, pins are upstream content (see .claude/upstream.md).
  Their `core >= 2.5.0` is upstream's latest-at-sync value, not a
  requirement: those skills' own examples compile unchanged on 2.0.0.
- `internet-identity` (2.5.0) — real transitive floor, verified:
  `identity-attributes@0.4.1` resolves `core@2.5.0`.
- `caffeine-app` (2.5.0) — reflects what the Caffeine platform ships, not
  a minimum its examples need; out of scope for this drift.
- Historical statements ("In mo:core 2.0, the module is renamed to
  `Cycles`") — facts about the 2.0 release, not pins.

Evals: stable-memory #4 previously only checked that some core pin
existed. It now requires a concrete version, since mops rejects ranges
and wildcards — which is what the baseline emits (WITH 3/3, WITHOUT 2/3).

Closes #297

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NEm1Tbkypzi8SuXhrMfBek
@raymondk
raymondk force-pushed the fix/align-mo-core-pin branch from a3b2af4 to 3c74c6b Compare August 6, 2026 09:41
@raymondk raymondk changed the title fix: align mo:core pin on 2.5.0 across all non-upstream skills fix: state each skill's real mo:core minimum instead of one repo-wide pin Aug 6, 2026
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.

Version drift: mo:core pinned at 2.0.0 / 2.3.1 / 2.5.0 across skills

1 participant