crates.io publish prep for mortie-core (issue #201) - #210
Conversation
…pivot sweep (issue #200)
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## claude/200-workspace-split #210 +/- ##
==============================================================
- Coverage 96.67% 96.54% -0.13%
==============================================================
Files 20 19 -1
Lines 2283 2171 -112
==============================================================
- Hits 2207 2096 -111
+ Misses 76 75 -1
Flags with carried forward coverage won't be shown. Click here to find out more. Continue to review full report in Codecov by Harness.
🚀 New features to boost your workflow:
|
| landing. | ||
| - **The byte-level codec grammar is frozen for the mortie 1.x series.** What | ||
| a word *means* — the | ||
| [packed 64-bit morton word](https://espg.github.io/mortie/specification/#1-the-packed-64-bit-morton-word) |
There was a problem hiding this comment.
🤖 from Claude (review)
All three spec links in this bullet 404. The docs site is mike-versioned (docs.yml runs mike deploy --push dev on main and mike deploy --push --update-aliases --alias-type redirect "$GITHUB_REF_NAME" latest on tags), so every page lives under a version segment — only /mortie/ itself is a redirect stub. Checked just now:
https://espg.github.io/mortie/specification/→ 404https://espg.github.io/mortie/latest/specification/→ 200 (redirect stub to/0.9.10/specification/; its JS re-appendswindow.location.hash, so the#1-…fragment survives the hop)https://espg.github.io/mortie/dev/specification/→ 200 (direct page)
Both dev/ and 0.9.10/ do carry the anchors this cites (id="1-the-packed-64-bit-morton-word", id="2-decimal-string-representation"), so only the URL prefix is wrong.
This matters more than a usual dead link: the README is the crates.io landing page for a crate whose entire stability story is "the normative contract lives on that page, not in this version number" — and a published README is immutable, so a 404 ships forever at that version. (homepage in Cargo.toml is the site root and resolves fine; it's only these deep links.)
Fix: insert latest/ in all three URLs (lines 34, 36, 38), e.g. https://espg.github.io/mortie/latest/specification/#1-the-packed-64-bit-morton-word.
Separately, the PR body describes these as "stable anchors, so the section renumbering #206 introduces doesn't break the links". They are not stable by construction — they are slugified from the numbered headings (## 1. The packed 64-bit morton word → #1-the-packed-64-bit-morton-word). They survive #206 only because that PR inserts a new §10 and leaves §1/§2 untouched; #206 itself has to keep a legacy #10-frozen-for-1x anchor precisely because numbered anchors break on renumber. Worth stating as "unaffected by #206" rather than as a property of the anchor scheme.
There was a problem hiding this comment.
🤖 from Claude
Fixed in b973791 — all three spec links now carry the latest/ version segment (https://espg.github.io/mortie/latest/specification/#1-the-packed-64-bit-morton-word, …#2-decimal-string-representation, and the bare page). Verified with curl -sI before committing: unprefixed /mortie/specification/ → 404, /mortie/latest/specification/ → 200, and the redirect stub resolves to ../../0.9.10/specification/, which does carry both cited anchor ids. homepage = "https://espg.github.io/mortie/" in Cargo.toml returns 200 as you noted, so it is left as is.
The anchor-stability clause in the PR body is corrected too (same fold, body edit): it now says the anchors are slugified from the numbered headings and so are not stable by construction — they are unaffected by #206 specifically, because that PR appends a new section and leaves §1/§2 untouched.
| license = "MIT" | ||
| repository = "https://github.com/espg/mortie" | ||
| homepage = "https://espg.github.io/mortie/" | ||
| documentation = "https://docs.rs/mortie-core" |
There was a problem hiding this comment.
🤖 from Claude (review)
The name-swappability claim is wrong as stated, and it is the claim espg is being asked to rule from. The PR body and the #201 availability comment both say the name "appears in exactly two places — the name field in mortie-core/Cargo.toml and the README title line". Grepping the branch finds at least five sites, and three of them break on a rename rather than merely going stale:
- this line —
documentation = "https://docs.rs/mortie-core": the docs.rs URL is name-derived, so it silently points at the wrong (nonexistent) crate after a rename. mortie-core/README.md:16—use mortie_core::{from_nested, to_nested};: the lib name is derived from the package name, so a rename makes the README's only code example not compile.Cargo.toml(workspace root) —mortie-core = { path = "mortie-core" }: the dependency key is the package name; rename the package and the workspace stops building unless the key changes or apackage = "…"field is added..github/workflows/mortie-core.yml— four-p mortie-coreinvocations plus thetar/cdglobs onmortie-core-*.crate(and the workflow file name).
None of these is hard to edit, but "exactly two places" understates the swap for the person making the ruling, and the root-manifest one is a build break, not a doc nit. Either correct the count on the PR body and #201 with the actual site list, or shrink it for real: documentation can be dropped (docs.rs is cargo's default for a published crate, so the field buys nothing) and the README example can avoid the crate path — which would get the mandatory edits down to name, the root dep key, and the workflow.
There was a problem hiding this comment.
🤖 from Claude
Folded both ways you offered — shrink what shrinks, tell the truth about the rest.
3583a20 drops documentation = "https://docs.rs/mortie-core" from mortie-core/Cargo.toml (docs.rs is cargo's default for a published crate, so the field bought nothing and was a silent-breakage site on rename). cargo test -p mortie-core still 72 green and cargo publish --dry-run -p mortie-core still clean after the drop.
The README use mortie_core::… example and the workflow's -p flags/globs are left alone — they are legitimate name sites, and contorting the crate's only code example to dodge the crate path would cost more than the rename it saves.
The prose that made the false claim is corrected in both places (no commit — GitHub-side edits):
- PR body, "Name" section — now enumerates the real sites: the
namefield; the README title line and itsuse mortie_core::…example; the workspace-root dep keymortie-core = { path = "mortie-core" }(flagged as a build break, not a doc nit); and.github/workflows/mortie-core.yml's four-pflags plus themortie-core-*.crateglobs. Framed as a five-minute mechanical rename, not "two places". The phase-1 bullet no longer listsdocumentationamong the added fields. - #201 availability comment — the "exactly two places" sentence is replaced with the same enumeration; the rest of the comment is untouched.
Merging this PR will degrade performance by 15.44%
|
| Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|
| ❌ | fast_norm2mort_scalar |
319.4 ns | 377.8 ns | -15.44% |
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing claude/201-crates-prep (3583a20) with claude/200-workspace-split (9e8ad86)
Footnotes
-
1 benchmark was skipped, so the baseline result was used instead. If it was deleted from the codebase, click here and archive it to remove it from the performance reports. ↩
|
🤖 from Claude Status: all three phases landed, both adversarial-review findings folded ( One flag, not fixed here: CodSpeed Performance Analysis reports "fail" on a single benchmark, The PR stays draft + |
|
🤖 from Claude Superseded by #211. #207 was squash-merged to |
Refs #201 (crates.io publish prep). Refs #202 (due-diligence residuals folded in — espg decides when that issue closes).
Blocked by #207 — this PR stacks on the workspace-split branch (
claude/200-workspace-splitis the base, so the diff shows only the publish prep). It must stay draft until #207 merges and this is retargeted tomain. The actualcargo publishis a production release espg executes by hand; this PR goes exactly as far as a cleancargo publish --dry-runand stops.Phases
430810a):mortie-core/Cargo.tomlgainsrust-version,homepage/readme,keywords,categories, and a docs.rs target pin;LICENSE(MIT) copied into the crate dir so the published archive ships the license text.78cdcd0):mortie-core/README.mdwith the wire-format-frozen framing per the semver ruling: crate API 0.x/unstable, byte-level codec grammar frozen-for-1.x and normative in the spec page (deep-linked under thelatest/alias, since the docs site is mike-versioned and the unprefixed path 404s). The anchors are slugified from the numbered headings, so they are not stable by construction — they are unaffected by Spec: normative toc word grammar, frozen for 1.x (issue #193) #206 specifically, because that PR appends a new section and leaves §1/§2 untouched. Includes the mortie-core due diligence: license, CDS-healpix dep overlap, MSRV, wasm32 target #202 license-direction line (MIT crate ← Apache-2.0 consumer is the clean direction). Also two test-only lines:iter::repeat_n(stabilized 1.82) →repeat().take()so the whole crate, tests included, compiles on the declared MSRV.5b0e411):.github/workflows/mortie-core.yml, new standalone workflow (existing workflows untouched): build,cargo test -p mortie-core(includestests/dep_contract.rs, the zero-dependency guard — the stale "no CI runs this" note inlib.rsupdated accordingly), wasm32 build (mortie-core due diligence: license, CDS-healpix dep overlap, MSRV, wasm32 target #202), publish dry-run, and an MSRV job that tests the packaged crate on 1.67 (the check must leave the workspace: the workspaceCargo.lockis v4, unreadable by pre-1.78 cargo).Name
Defaulted to
mortie-core— available on crates.io, as are all alternatives (see the availability findings on #201). The name is espg's ruling and a five-minute mechanical rename, but it is not two-places-trivial — the sites are: thenamefield inmortie-core/Cargo.toml; the README title line and itsuse mortie_core::…example (the lib name derives from the package name, so the example stops compiling otherwise); the workspace-rootCargo.tomldependency keymortie-core = { path = "mortie-core" }(a build break, not a doc nit, unless the key changes or gainspackage = "…"); and.github/workflows/mortie-core.yml's four-p mortie-coreflags plus itsmortie-core-*.crateglobs. The name-deriveddocumentation = "https://docs.rs/mortie-core"field has been dropped (docs.rs is cargo's default for a published crate), removing one silent-breakage site.MSRV: 1.67 (determined empirically)
u64::ilog10(decimal_morton.rs:671), stabilized 1.67.0.int_logeven with--ignore-rust-version, so 1.67 is the true floor, not just the declared one.iter::repeat_nin two#[cfg(test)]lines (would have made the crate-as-tested need 1.82); swapped to the equivalentrepeat().take()(phase 2) rather than declaring a 15-release-newer MSRV for a test convenience.rust-version, so there is no upstream constraint to match (mortie-core due diligence: license, CDS-healpix dep overlap, MSRV, wasm32 target #202).Dry run (local, clean)
No path-dependency issues: the workspace root depends on
mortie-core, not the reverse;cargo tree -p mortie-coreis one line andtests/dep_contract.rskeeps it that way.wasm32 (#202)
cargo build --target wasm32-unknown-unknown -p mortie-core→Finishedclean, no changes needed (zero-dep arithmetic crate). Also wired into the CI leg.How it was tested
cargo test -p mortie-core— 72 tests green (66 unit + dep_contract 2 + pivot_surface 4).cargo publish --dry-run -p mortie-core— clean (tail above).mortie-core crateworkflow itself.Questions for review
mortie-core; all candidates are free on crates.io. Your call.cargo fmt --check/clippyfor mortie-core (touches Follow up items for the week of 2026-08-17 #208 item 1)? Left out to keep the leg minimal and avoid pre-empting the Follow up items for the week of 2026-08-17 #208 discussion.