rust-toolchain.toml, a C/C++
compiler for Tree-sitter, and Git for integration tests.
Code of conduct
Assume good intent, give specific feedback, and keep discussions about the work. Be patient with reviews. Harassment and personal attacks are not welcome in issues, pull requests, or discussions.Get started
fixtures/parity preserve legacy behavior, while corrective fixtures and Rust
regression cases cover intentional fixes.
Make a change
- Pick or open an issue to explain the problem and expected behavior.
- Branch from
main, for examplegit switch -c codex/fix-method-labels. - Add the behavior and an appropriate regression case. Keep parser-specific rules in the adapter rather than the shared matcher.
- Run focused tests, then the workspace checks below.
- Open a pull request with the behavior change, its reason, and validation.
cargo fmt --all to apply formatting. cargo xtask check runs the main
format/lint/test/documentation checks. cargo xtask coverage uses a separately
installed cargo-llvm-cov and requires at least 95% line and 90% function coverage.
Read the actual coverage report for the measured result.
Commit style
Use readable past-tense subjects that explain what changed:Added Python extractor for async functionsFixed root insertion when the old tree is emptyReplaced recursive tree walks with arena traversal
Project structure
crates/differens-core/src/lib.rs for matching,
crates/differens-tiers/src/router.rs for routing, or
crates/differens-engine/src/report.rs for reports. Shared dependencies and lints
live in the root Cargo.toml; Cargo.lock belongs to the workspace.
Adding a language extractor
- Pin the upstream grammar, licenses, and checksums in the grammar manifests.
- Add its archive/build wiring in
crates/differens-tiers/grammarsandbuild.rs. The separately packaged Swift grammar shows how a large grammar can be split. - Register the dialect in
src/code/grammar.rsand its extensions insrc/code/mod.rs; add path classification insrc/router.rsif needed. - Map CST kinds in
src/code/concepts.rsand declaration labels insrc/code/labels.rs. Use internal identity hints only where the language needs them, such as receiver-scoped Go methods. - Add grammar smoke inputs and tests for valid, malformed, Unicode, rename, move, and identity cases. Keep TypeScript and TSX as distinct dialects.
- Run grammar, label, adapter, engine, and packaged-artifact checks for the change.
crates/differens-tiers. Code
classification alone is not grammar support. The installed CLI does not load a
JavaScript extractor or discover arbitrary grammars from disk.
Adding a tier adapter
- Add the parser or sequence adapter under
crates/differens-tiers/src. - Build a validated immutable tree with
TreeBuilder, or use the shared sequence helpers where the format is line/word based. - Add routing in
src/router.rsand classification rules if the extension needs them. Reuse an existing tier when it fits the abstraction. - Preserve original bytes, explicit file presence, scalar types, and useful source coordinates. Retain nesting and non-label attributes.
- Return parser failures or budget errors so the router can compare raw lines.
- Add parser, malformed-input, Unicode, fallback, and report examples. Seed randomized cases and compare sequence alignment with a small independent reference where appropriate.
BinaryDiffPlugin may be enough. The
tiers reference shows the Rust
contract. Avoid putting a second tree matcher inside a format adapter.
Documentation and packaging
The documentation is deployed on Mintlify. Keepapps/docs/docs.json and its
navigation in sync with the pages. Edit CommonMark under apps/docs/content, then
run cargo xtask docs and commit the generated MDX pages under apps/docs with
your changes. The same command builds an optional static preview in target/site.
The generator checks page coverage; CI checks that generated files match their
sources.
Compare documentation changes with the previous version before removing a
walkthrough or example. Replace an obsolete example with a working equivalent
and preserve the explanation it teaches. Run CLI examples against the native
binary, compile complete Rust examples, and capture actual output rather than
writing a plausible report by hand.
Run mint validate and mint broken-links from apps/docs with the Mintlify CLI
installed. Use mint dev for a local Mintlify preview. Keep page slugs, static
preview navigation/routes, and crate API examples consistent with the source.
cargo xtask package --dry-run validates application packaging; publishing crates
or releases is a separate action.
Release process
Build and inspect before publishing:target/packages, including
licenses and the README. Neither command publishes crates or deploys the docs.
Publish native crates only through a deliberate release, in dependency order:
core and the grammar package before tiers, libraries before the engine, and the
CLI after its dependencies. Verify registry ownership, source packages, target
runtime smoke tests, and rollback artifacts before advertising release support.
The removed Bun/npm release script is not part of the native workflow.
Where to ask questions
Use GitHub issues for bugs, feature requests, and behavior questions, or discuss code in the relevant pull request. Include a small reproducer, the command, version, platform, and observed output.DEVELOPMENT_GUIDE.md in the repository has additional invariants and audit
commands.