docs: propose a staged, additive rewrite of candid - #756
Draft
lwshang wants to merge 9 commits into
Draft
Conversation
Reserves three directories for a staged, additive rewrite of Candid's
specification, reference model, and Rust implementation, and writes down
the reasoning so it is citable rather than living in one person's head.
lean/ Lean 4 reference implementation + Verso spec sources.
Eventually replaces coq/ and spec/.
crates/ Redesigned Rust crates. Eventually replaces rust/.
conformance/ Machine-readable vectors + generator. Replaces test/.
No code. Every directory contains only a README describing its scope and
the conditions under which the artifact it replaces gets deleted.
The released candid 0.10.x crates are unaffected: nothing here is
published, nothing on master references these directories, and no
existing source file is modified.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
✅ No security or compliance issues detected. Reviewed everything up to 031317f. Security Overview
Detected Code Changes
|
Click to see raw report |
v1 is a new major version of the existing candid / candid_parser / candid_derive crates, not a new set of names. Those names are already ours, and Cargo links semver-incompatible versions side by side, so 0.10.x and 1.x coexist in a dependency graph without renaming anything. Replaces the previous claim that the derive macro needed a name other than candid_derive, which was reasoning from a coexistence constraint that does not exist. Records the caveat that does apply: coexistence works for linking, not for types, so a graph pulling both majors still breaks where candid_0_10::Nat meets candid_1::Nat. Promoted to an open question, since it is the hardest unsolved part of the migration. Also documents candid_derive's own global-state defect, now that the derive crate's future is discussed: candid_method / export_service communicate across proc-macro invocations through a lazy_static! Mutex that the code itself flags as unsound under incremental compilation (rust-lang/rust#44034), with a silently truncated .did file as the failure mode. Added to the crates/CLAUDE.md anti-pattern list. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
candid, candid_parser, candid_derive and ic_principal all use `_`; the new layer crates now match. crates.io normalises the two spellings for uniqueness, so publishing candid_types also reserves candid-types. Closes the naming open question. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
lwshang
marked this pull request as draft
July 28, 2026 01:49
…isting files Two changes, both about the document claiming less than it did. "Charter" is an authorizing document signed by a sponsor. Nothing here is authorized, so the word was inaccurate as well as presumptuous. The document now says it proposes, its status reads "proposal, not scheduled work", and section 5 is "Proposed working model" rather than "How we work". Dropped the changes to .github/CONTRIBUTING.md and README.md. Both were edits to existing, team- and user-facing files, which the proposal itself argues against: CONTRIBUTING.md told colleagues how to review merges that have not been agreed to yet, and README.md announced on the repository's front page that a rewrite was "under way" when three empty directories is all that exists. Those rules still belong in CONTRIBUTING.md eventually, but after the working model is agreed, not as part of proposing it. The directories carry their own "Status: reserved, empty" READMEs, which is enough for anyone who stumbles across them in the meantime. The pull request is now purely additive and modifies no existing file, which is the property section 5 asks for. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Four corrections, all removing claims the document could not support.
Dropped the opening paragraph attributing candid to the Languages team
and its move to Caffeine. It is org history, not evidence, and it framed
the problems as somebody's fault rather than as facts about the code.
It also claimed maintenance sits "with one person", which is wrong —
PRs here are reviewed by teammates. Section 1 now just states that there
are six problems and that each is cited.
The same paragraph said "Five specific problems" while section 1 has six
subsections.
Section 3 said "Nobody on SDK knows Lean today." That overstates the
risk in one direction while the bus-factor note ("committing to learn")
understated the starting point in the other. It now says Lean is not
used in the team's stack today and that this would be a first
application of it here, which is accurate without implying either
expertise or a standing start.
Replaced the remaining dfx references with icp-cli, which supersedes it.
The candid_ui note no longer names a tool, since the claim only needs to
be that developer tooling points users at that canister.
Removed section 8, "Feedback". Asking people to argue with three named
decisions belongs in a pull request description, where it is bounded by
review; persisted in the document it invites re-litigating settled
points indefinitely and leaves it ambiguous whether work should stop
while that happens. Section 7 now opens by drawing the line instead:
section 7 is what is open, sections 1-6 are decisions recorded with
their reasoning, and new evidence is the reason to revisit one.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Picks up the CI workflow overhaul (#757). candid-ui.yml was renamed to candid-ui-release.yml there; the reference in REWRITE.md is fixed in the next commit.
candid-ui.yml became candid-ui-release.yml under the naming convention adopted in #757. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The previous wording lumped tools/candiff and tools/didc together as things to move to another repo, which was wrong in both directions. candiff was already deprecated in #405 and the directory is a single README saying so; it just goes. didc is a general Candid CLI and belongs in this repo, with a narrower scope after the split — parse, check, encode, decode, subtype checks, but no per-language binding generation, which leaves with the bindgen crates. tools/ui moves to its own repository, as a deployed canister with its own release pipeline. tools/didc-js is left open, with the reasoning in section 7: it publishes the Rust implementation as @dfinity/didc for JavaScript, has been at 0.0.4 with no functional change since #602, and overlaps @dfinity/candid from agent-js, so two DFINITY Candid libraries for one language can disagree with nothing checking that they don't. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The entry claimed one resolution could be that @dfinity/candid is shown to conform and the wasm build is therefore redundant. That is not possible: @dfinity/candid is a codec over programmatically constructed IDL types and has no .did parser, so it cannot replace a parser no matter how conformant its codec is. Checked against @dfinity/candid 2.1.3 — its surface is the IDL constructors, encode/decode, the UI helpers, and hash/leb128/buffer utilities, with no lexer or grammar anywhere. The two packages overlap only at encode/decode, which is still worth noting because two independent implementations exist there with nothing checking they agree. But the open question is not "which one survives" — it is whether this repo publishes a JS binding at all, and if so whether it exposes more than the method-name list it exposes today. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a document proposing a staged, additive rewrite of Candid's specification, reference model, and Rust implementation, plus three directories reserved for it.
Purely additive: five new files, no existing file modified. No code, no dependency changes.
candid0.10.x is unaffected. What this asks for is agreement on a plan, not a review of an implementation.The artifact to read is REWRITE.md. This description deliberately does not restate it.
What's here
coq/andspec/rust/test/Why
optcoercion, sode.rsstring-matches serde's private module paths andptr::reads the visitor. Both bugs in 0.10.34 come from this. §1.3CandidType::ty()memoises into four thread-locals, so generated.didtype names depend on the order types were first derived. §1.4#[doc(hidden)], and ten decode functions that are a cartesian product of two options. Each fix is a semver break on its own. §1.5Scope, stated plainly
Nothing here is scheduled work, and merging it commits no one to anything. The directories would stay empty until there is agreement on the plan; each carries a
Status: reserved, emptyREADME in the meantime. §3 is explicit about what Lean would cost, including the bus factor, and §4 about the parts that are slow regardless of how fast the code goes.The proposed working model is in §5: everything additive, so nothing on
mastercan break and there are structurally zero merge conflicts, with a working branch merged tomasterat least fortnightly. The existingnextbranch — 1 commit ahead, 109 behind — is what happens without that last part.Reviewing this
Verify it does what it says, then argue with the reasoning while it is still cheap to change. The decisions where a different answer would change the most: the serde divorce (§1.3), Lean over "just write more tests" (§3), and one-repo-additive over a separate repository (§4).