Repository navigation
track(2.0): breaking-change roadmap for the 2.x major bump #505
Description
Summary
Tracking issue for the 2.x major bump. A major bump is the only SemVer
window in which the breaking changes below may land. This collects:
- the loose ends already documented in
STABILITY.mdunder "On the 2.0 horizon", and - additional candidates surfaced by a pre-2.0 project review (linked under
Review findings below).
2.0 is not scheduled; this is the staging ground so nothing is forgotten
when it is cut. All issues here are filed against the 2.0 milestone.
Known loose ends (from STABILITY.md)
- Mark the per-metric
Statsstructs#[non_exhaustive]so field
additions stop being a strict-SemVer shape break. - Remove the deprecated
metrics/metrics_with_optionsshims (in
favour ofanalyze). - Decide the fate of the remaining
#[doc(hidden)]extension traits
(ParserTrait, the per-metric compute traits,Parser<T>,Filter):
delete or formally expose. The hidden state is a holding pattern. - Land the clean metric-value re-baseline note in the
2.0
CHANGELOG entry, folding in every value drift accumulated across1.x
so consumers have one diff to reason about across the major boundary. -
FilesData/ConcurrentRunnerreshape into a terminal file-set
processor (refactor(cli): single anchored walk seam — library globsets are dead and files are double-stat'd after #489 #495 — already closed; confirm it is reflected at 2.0).
Review findings (filed separately)
Core library API:
- fix(tools): guess_language returns unbound-lifetime &'a str (latent unsoundness) #506 —
guess_languagereturns an unbound-lifetime&'a str(latent
unsoundness; tighten to&'static stror drop the tuple element) (bug) — ✅ landed onmain - refactor(api): normalize &LANG-by-value and drop Java-style get_ getter prefixes #507 — normalize
&LANG-by-value and drop Java-styleget_getter
prefixes acrossLANG/LanguageInfo/ParserTrait - feat(lang): implement Display/FromStr/Hash for the LANG enum #508 — implement
Display/FromStr/HashforLANG— ✅ landed onmain - refactor(lib): get_ops/metrics_from_tree still key identity off a lossy path #509 —
get_ops/metrics_from_treestill key identity off a lossy
path; add aSource-based seam and deprecate the path-positional form - refactor(vcs): decide vcs::Options exhaustiveness (non_exhaustive/builder) before 2.0 #584 — decide
vcs::Optionsconstruction contract
(#[non_exhaustive]/ builder) so future additive VCS fields are not
external breaks; migrate CLI / web / Python construction sites
Core architecture (2.0-gated):
- refactor(checker): reshape Checker trait (default predicates, is_primitive(&Node), narrow bounds) #520 — reshape the
Checkertrait: default bodies for trivial
predicates (kills per-language stub boilerplate),is_primitive(&Node)
instead ofis_primitive(u16), narrowcount_specific_ancestors's
bound fromParserTraittoChecker
Metrics & output:
- refactor(output): normalize metric JSON/YAML key naming across all Stats #510 — normalize metric JSON/YAML key naming across all
Stats
(sum/average/min/max scheme; misleadingnom.functions/
nargs.total_functions; npa/npmaverage-as-ratio; abc magnitude
asymmetry;serialize_structnames) - fix(halstead): n1/N1/n2/N2 keys are case-only-distinct (CSV/header collisions) #511 — Halstead
n1/N1/n2/N2case-only-distinct keys collide for
case-insensitive consumers (CSV/env) (bug) - refactor(metrics): unify average-divisor guarding and denominator convention #512 — unify average-divisor guarding and per-space-vs-per-function
denominator convention (re-baseline)
CLI:
- refactor(cli): unify output-format selection across subcommands #513 — unify output-format selection across subcommands (flag vs
positional,-Ovs--format, enum consolidation) - fix(cli): reconcile metric-name spelling between diff --metric and check --threshold #514 — reconcile metric-name spelling between
diff --metricand
check --threshold— ✅ landed onmain - feat(cli): give --ls/--le descriptive long names; reconsider global scope #518 — give
--ls/--ledescriptive long names; reconsiderglobal
Web (not strictly 2.0-gated — schema/HTTP, not library SemVer):
- feat(web): version REST routes (/v1) before 2.0; revisit Option-in-200 errors #517 — version REST routes (
/v1) before 2.0; revisit
Option-in-200-body error idiom
Filed without the 2.0 milestone (fix anytime — not breaking):
- ✅ fix(web): content-type guards reject 'application/json; charset=utf-8' (silent 404) #515 — web content-type guards reject
application/json; charset=utf-8
(silent 404) (bug) — closed, landed onmain - refactor(web): replace eprintln! error logging with tracing/log #516 — replace
eprintln!web error logging withtracing/log - fix(groovy): closure bodies don't count toward cognitive lambda nesting #519 — (bug) Groovy closure bodies don't count toward cognitive lambda
nesting (cross-language parity violation; metric fix, lands pre-2.0) - ✅ perf(node): has_sibling allocates a TreeCursor per call on the JS/TS hot path #521 — perf:
Node::has_siblingallocates aTreeCursorper call on the
JS/TS hot path — closed, landed onmain - ✅ perf(spaces): Elixir per-node source scan runs regardless of metric selection #522 — perf: Elixir per-node source scan runs regardless of metric
selection — closed, landed onmain - ✅ refactor(node): children() iterator desyncs length (child_count) from data (cursor) #523 —
Node::children()iterator desyncs length from data (latent
dup-yield) — closed, landed onmain - ✅ build(deps): exact-pin tree-sitter-kotlin-ng and CI-guard enums/ grammar-pin lockstep #524 — exact-pin
tree-sitter-kotlin-ng; CI-guardenums/grammar-pin
lockstep (dependencies) — closed, landed onmain - ✅ build(deps): drop num meta-crate; hoist csv/tempfile into [workspace.dependencies] #525 — drop the
nummeta-crate; hoistcsv/tempfileto workspace deps
(dependencies) — closed, landed onmain - ✅ docs: stale supported-languages lists (phantom C/Mozcpp; deb/rpm omit 5 langs) #526 — stale supported-languages lists (phantom
C/Mozcpp; deb/rpm omit
5 langs) (documentation) — closed, landed onmain
Second-pass review findings (2026-06-05)
A fresh pre-2.0 review across the public Rust API, serialized output schema,
CLI grammar, REST surface, Python bindings, and cross-language metrics surfaced
the following, none overlapping the items above. All filed against the 2.0
milestone except where noted additive.
Bug (fix before the 2.0 re-baseline so values fold in cleanly):
- fix(cognitive): PHP double-counts two-word
else ifform #529 — (bug) PHP cognitive double-counts the two-wordelse ifform
(5.0 vs the correct 3.0; isolated to cognitive)
Serialized output schema:
- refactor(output): serialize integer-valued metrics as integers, not f64 #530 — integer-valued metrics are typed
f64and serialize as floats
("sloc":5.0); four formats disagree; CBOR bloat - refactor(output): uniform non-finite & precision policy at the serialize boundary #531 — no uniform non-finite (
NaN/Inf→silent JSONnull) or precision
policy at the serialize boundary - feat(lib): implement Deserialize on the serialization-root types #532 — implement
Deserializeon the serialization-root types (the
library can't read its own output) - refactor(output): normalize AstNode dump key casing; name the Span tuple #535 — normalize
AstNodedump key casing (Type/TextValue/…); name
theSpan4-tuple - test(output): add round-trip coverage for TOML/YAML/CBOR formats #543 — add round-trip test coverage for TOML/YAML/CBOR (additive;
de-risks refactor(output): serialize integer-valued metrics as integers, not f64 #530/refactor(output): uniform non-finite & precision policy at the serialize boundary #531)
Core library API:
- refactor(lib): hide builder-type internal fields (Source/MetricsOptions/MetricsCfg) #533 — hide builder-type internal
pubfields
(Source/MetricsOptions/MetricsCfg) - refactor(lib): tidy internal-plumbing visibility (Cursor/Callback/LanguageInfo/Node) #534 — tidy internal-plumbing visibility (
Cursoris dead public surface;
Callback/LanguageInforequire a doc-hiddenParserTrait) - refactor(lib): 2.0 shape & error-type ergonomics cleanups #536 — 2.0 shape & error ergonomics: parse-error accessors, reserved
MetricsErrorvariants, exit/nexits triple-spelling,FunctionSpan
name: Option<String> - refactor(lib): CountCfg/FindCfg leak Arc<Mutex>/Arc<[String]> representation #537 —
CountCfg/FindCfgleakArc<Mutex<…>>/Arc<[String]>
(companion to the refactor(cli): single anchored walk seam — library globsets are dead and files are double-stat'd after #489 #495 reshape)
CLI:
- refactor(cli): cross-subcommand parity (only-filter naming, --output/--strip-prefix on diff family) #538 — cross-subcommand parity (only-filter naming;
--output/
--strip-prefixon the diff family) - docs(cli): unify/clarify list-merge semantics (--paths-from union vs manifest replace) #539 — clarify/unify list-merge semantics (
--paths-fromunion vs
manifest replace)
Web & Python (published surfaces, newly represented here):
- fix(web): /metrics language field emits non-lookup display names (c/c++, c#) #540 —
/metricslanguageemits non-lookup display names
(c/c++,c#) that disagree with the Python surface - refactor(web): consistent error schema, response envelope, and introspection endpoints #541 — consistent REST error schema, response envelope, and introspection
endpoints - docs(stability): bring Python bindings & REST schema under the 2.0 stability contract #542 — bring the Python bindings & REST schema under the written 2.0
stability contract (name-lock before first PyPI publish;analyze_batch
default polarity)
Third-pass review findings (2026-06-06)
A third pre-2.0 review (focused on the SemVer-frozen surfaces that cannot be
changed after the major bump) filed #551–#562.
Core library API (2.0-gated / breaking):
- refactor(api)!: mark remaining public enums #[non_exhaustive] (suppression + Severity + SpaceKind) #551 — mark remaining public enums
#[non_exhaustive](MetricKind,
Severity,SuppressionScope,SpaceKind; reason about the closed
ones) — generalizes theStatsnon_exhaustive item; breaking-to-add-later - feat(lib): impl Display + std::error::Error + #[non_exhaustive] on ConcurrentErrors #553 — impl
Display+std::error::Error+#[non_exhaustive]on
ConcurrentErrors(separate error type refactor(lib): 2.0 shape & error-type ergonomics cleanups #536 missed) - refactor(suppression)!: give MetricKind::FromStr a real error type (Err=()) #554 —
MetricKind::FromStrhasErr = (); give it a real error type - refactor(api)!: reconcile the two parallel metric enums (Metric vs MetricKind) #555 — reconcile the two parallel metric enums (
MetricvsMetricKind:
Nexits/Exit,NArgs/Nargs, missingTokens) - refactor(node)!: hide Node's tree_sitter::Node pub field behind an accessor #556 — hide
Node'spub tree_sitter::Nodefield behind an accessor
(welds the value-not-stable dep into a stable layout)
Core library API (additive, bundle into the 2.0 sweep):
- feat(lib): derive PartialEq/Hash/Ord on public value types (Stats, Severity, SpaceKind) #552 — derive
PartialEqon the computeStats/CodeMetrics/FuncSpace/
Metrics(wire mirrors already have it);Hash/Ordon
Severity/SpaceKind/Direction
Metrics (re-baseline):
- fix(abc): wire Fitzpatrick unary-condition walker for Kotlin, Ruby, Elixir #557 — (bug) ABC Fitzpatrick unary-condition walker missing for
Kotlin/Ruby/Elixir (cross-language parity; reproduced) — lands with the
2.0 re-baseline; also fixes a staleabc.rspolicy doc-comment
Output / stability contract:
- docs(stability): lock output-format contracts (CSV/SARIF/code-climate/AST) for 2.0 #559 — lock the output-format contracts (CSV header + integer-column
nullability, SARIF schema version + rule shape, code-climate field set +
fingerprint, AST JSON shape + one-way status,wire::CyclomaticModified) - fix(output): use underscore keys for dump purity_ratio/estimated_program_length #562 — use underscore keys for dump
purity_ratio/estimated_program_length
Web (2.0-gated schema):
- fix(web): /comment empty result returns 200 {code:null} on JSON but 204 on octet-stream #558 — (bug)
/commentempty result returns200 {code:null}on JSON
but204on octet-stream (content-type-dependent envelope)
Filed without the 2.0 milestone (additive, fix anytime):
- feat(web): bca-web --num-jobs should accept 'auto' and be cgroup-aware (CLI parity) #560 —
bca-web --num-jobsshould acceptauto+ be cgroup-aware (CLI parity) - docs(cli): document the workspace-wide exit-code convention #561 — document the workspace-wide exit-code convention
Grammars (2.0-gated default flip, tracked epic):
- track(lang): default C/C++ to upstream grammars, add C language, mozcpp opt-in #718 —
track(lang): default C/C++ to upstreamtree-sitter-cpp/tree-sitter-c,
add a realLANG::C, demote the vendored mozcpp fork to an opt-in feature
(children chore(grammar): measure mozcpp vs upstream cpp/c grammar divergence #719-feat(lang): add C language backed by tree-sitter-c #721, chore(grammar): re-evaluate mozcpp-era skips, workarounds, and docs post-flip #723; mirrors the refactor(api): normalize &LANG-by-value and drop Java-style get_ getter prefixes #507 JS/mozjs shape; (breaking):
.creported language changescpp->c,cppfeature contents change)
Release-prep follow-ups (no separate issue — handle at cut)
STABILITY.mdis internally inconsistent on version: the header frames the
crate as1.xwhile the body/horizon describe already-staged2.0breaks in
past tense. At cut, flip the header to2.0.0, move landed-break descriptions
out of the "1.x" framing, and prune the "On the 2.0 horizon" list of
implemented items.- CHANGELOG has no
## [2.0.0]section yet, though[Unreleased]carries the
(breaking)entries and several say "the release-prep commit moves this into
the 2.0.0 section." Stage the section and author the refactor(output): normalize metric JSON/YAML key naming across all Stats #510/fix(halstead): n1/N1/n2/N2 keys are case-only-distinct (CSV/header collisions) #511 key map that
STABILITY.md (:629) promises the 2.0.0 entry will carry.
Acceptance
- Every checkbox above resolved or explicitly deferred with rationale.
-
STABILITY.md"On the 2.0 horizon" section emptied/updated. - CHANGELOG
2.0.0section lists every(breaking)change and the
value re-baseline.
Activity
dekobon commentedon Jun 4, 2026
Filed the pre-2.0 review findings as individual issues against the 2.0
milestone and linked them in the body above.
Bugs worth attention regardless of the 2.0 timeline:
guess_language's unbound output lifetime (only sound today becauseevery arm happens to be
'static).n1/N1/n2/N2case-only keys silently collide incase-insensitive CSV/env consumers.
application/json; charset=utf-8with a bodyless 404(not 2.0-gated; can ship now).
The largest single win is #510 (output key-naming normalization): the
serialized JSON is the documented-stable surface, so the inconsistent
sum/average/min/maxspellings can only be unified at the major bump.Review scope covered the core library API, all per-metric
Stats+ outputserializers, and the CLI / web / Python crates. The Python bindings were in
good shape — no 2.0-blocking findings there.
dekobon commentedon Jun 4, 2026
Second review wave (core AST architecture, per-language metric mirroring,
docs/build hygiene) added the following:
2.0-gated: #520 (Checker trait reshape — the biggest "add-a-language"
ergonomics win).
Bugs / fixes that should land pre-2.0 (not breaking):
Java/Kotlin/JS/etc. all have the
lambda += 1arm Groovy lacks). This isa cross-language parity violation per lesson build(deps): update tree-sitter-python requirement from =0.23.6 to =0.25.0 in /enums #11.
tree-sitter-kotlin-ngis the only grammar not exact-pinned; adependabot minor bump can silently shift Kotlin metric values.
Perf (whole-repo hot path): #521 (
has_siblingcursor alloc, the same#217 pattern, missed), #522 (Elixir double source-scan per node).
Robustness/hygiene: #523 (
children()iterator length/data desync),#525 (drop
nummeta-crate), #526 (stale supported-languages lists).The per-language modules are otherwise unusually well-mirrored — a
dedicated cross-language parity suite already guards ternary/safe-nav/
boolean-sequence/receiver-exclusion handling. The only genuine divergence
found was the Groovy closure gap (#519).
dekobon commentedon Jun 4, 2026
Batch progress update — the following findings landed on
main(fast-forward merge offix/batch-2026-06-03, rebased atop the #510/#511 key-normalization; fmt + clippy--all-features+cargo test --workspace --all-featuresall green before merge) and are now closed:guess_language→&'static strfbdcec78LANGDisplay/FromStr/Hashe0ba5fe1498d92daad152f42has_siblingTreeCursor alloc0d8564a76c74dfd6children()cursor terminationf6823957830eae90num; hoistcsv/tempfilee48e79ab4bc19af0(#510 / #511 — the metric-key normalization — landed earlier in
1d0606e9and were already closed.)Still open: #507, #509, #512, #513, #516, #517, #518, #519, #520.
refactor(api): drop get_ getter prefixes, take LANG by value
refactor(metrics): unify average-divisor guard, cyclomatic per-function
dekobon commentedon Jun 5, 2026
Second-pass pre-2.0 review complete (2026-06-05). Fanned out across six
surfaces — public Rust API, serialized output schema, CLI grammar, REST API,
Python bindings, and cross-language metrics — explicitly excluding the
already-filed #506–#526 findings. Filed 15 new issues (#529–#543), all linked
in the body's Second-pass review findings section.
Headline items:
else ifform #529 (bug, verified by reproduction): PHP cognitive double-counts thetwo-word
else if. Should land before the 2.0 re-baseline.uniform non-finite/precision policy — the two biggest schema decisions to
settle alongside the refactor(output): normalize metric JSON/YAML key naming across all Stats #510/fix(halstead): n1/N1/n2/N2 keys are case-only-distinct (CSV/header collisions) #511 key normalization.
this roadmap; fix(web): /metrics language field emits non-lookup display names (c/c++, c#) #540–docs(stability): bring Python bindings & REST schema under the 2.0 stability contract #542 close that gap. Python distribution/import names must
be locked in STABILITY.md before the first stable PyPI publish.
Each issue carries file:line evidence; the public-API and integer-as-float
claims were spot-checked against
main, and #529 was reproduced withbca metrics. The Python surface and the web/v1routing came out otherwise clean(no bugs); their findings are mostly contract-documentation and one breaking
default.
dekobon commentedon Jun 7, 2026
Third-pass pre-2.0 review (2026-06-06). Ran a fresh review focused on the
SemVer-frozen surfaces that cannot be fixed after the major bump. Filed
#551–#562; body updated with a "Third-pass review findings" section.
Highest-leverage (breaking-to-add-later — must land at 2.0):
#[non_exhaustive]on the remaining public enums. This is the onechange that is genuinely free only before 2.0; the track(2.0): breaking-change roadmap for the 2.x major bump #505 horizon had it for
Statsbut missedMetricKind/Severity/SpaceKind/SuppressionScope.Node'spub tree_sitter::Nodefield welds the value-not-stabledependency into a stable struct's layout; a
tree-sitterminor bump silentlybreaks our API.
MetricKind::FromStrreturnsErr = ();MetricandMetricKindare two divergent vocabularies for the same domain.ConcurrentErrors(a public returned error) has noDisplay/Errorimpl and isn't#[non_exhaustive].Bugs found (reproduced):
Kotlin/Ruby/Elixir; verified via CLI (
if (a && b || c)scores 0 conditionsvs Java's 3). Internally inconsistent with the same languages' cyclomatic.
Lands with the planned 2.0 re-baseline.
/commentreturns a content-type-dependent envelope for the emptyresult (
200 {code:null}vs204).Plus a consolidated stability-contract issue (#559) covering the output formats
(CSV/SARIF/code-climate/AST) that are public + serialized but not in
STABILITY.md, and additive parity/doc items (#552, #560, #561, #562).Two release-prep follow-ups (no separate issue, noted in the body): the
STABILITY.md1.x-vs-2.0 tense inconsistency and the missing## [2.0.0]CHANGELOG section + the #510/#511 key map it promises.
Scope note: deliberately did not file marginal additive nice-to-haves
(
/v1/metricsendpoint,BCA_LOGenv var,analyze(language=)kwarg,MetricSetbitwise ops) or items the closed issues already settled (the Pythonstr-vs-StrEnumsurface is intentional per #542's recorded decision; the--formatvalue-vocabulary divergence is documented per #513).dekobon commentedon Jun 7, 2026
Progress check — 2026-06-06
All filed review-finding sub-issues are resolved. #506–#562 are
closed and landed on
main; #505 is now the only open issue in the2.0 milestone. Ticked every
- [ ] #NNNreview-finding checkboxin the body accordingly.
The 35
(breaking)entries each sit in CHANGELOG[Unreleased],flagged "deferred to 2.0", with the release-prep commit slated to
move them into the
2.0.0section.Deliberately left unticked — this is the at-cut release-prep
The implementation work is done, but #505's own acceptance criteria
require the release cut itself, which has not happened (2.0 is not
scheduled):
Stats/enum#[non_exhaustive](refactor(api)!: mark remaining public enums #[non_exhaustive] (suppression + Severity + SpaceKind) #551), builder-field narrowing (refactor(lib): hide builder-type internal fields (Source/MetricsOptions/MetricsCfg) #533), the#[doc(hidden)]trait fate (refactor(lib): tidy internal-plumbing visibility (Cursor/Callback/LanguageInfo/Node) #534), theFilesData/ConcurrentRunnerreshape (refactor(cli): single anchored walk seam — library globsets are dead and files are double-stat'd after #489 #495), and the re-baseline note are all decided and staged
in
[Unreleased], but the breaking edits physically land at 2.0.STABILITY.md"On the 2.0 horizon" is still fully populated andthe header still frames the crate as
1.x(1.1.0).## [2.0.0]CHANGELOG section exists yet, and the refactor(output): normalize metric JSON/YAML key naming across all Stats #510/fix(halstead): n1/N1/n2/N2 keys are case-only-distinct (CSV/header collisions) #511key map + value re-baseline note promised for that entry are not yet
authored.
Recommendation
Keep open. #505 is a release-gate checklist, not a work-tracker —
the remaining boxes are the cut (flip STABILITY.md to 2.0.0, stage
the 2.0.0 CHANGELOG section with the key map + re-baseline, move the
(breaking)entries across). Closing now would orphan the onechecklist that fires when 2.0 is actually cut. Close this as part of
the 2.0 release-prep commit.
dekobon commentedon Jun 7, 2026
Trait/shim checkboxes — scoped into an execution epic (#566)
The two open #505 loose ends — "Remove the deprecated shims" and "Decide
the fate of the remaining
#[doc(hidden)]extension traits" — turned outto be one coupled body of work, now planned in #566 and broken into
four landable waves:
Astseam (strip_comments/functions/dump); additivebca-clioff the path-positional shims; delete thembca-web's four handlers offaction/CallbackontoAstParserTrait/Callback/Getter/Checker/compute traits topub(crate)Resolution of "delete or formally expose": delete from the public
surface — the traits survive as private
AstInnermachinery andAstbecomes the single documented analysis seam. (
Filterin the originallist is a struct, not a trait — no action.) #256 already closed having
parked these as the doc-hidden holding pattern; #566 is the deliberate
exit from it. No metric re-baseline — output is byte-identical.
dekobon commentedon Jun 7, 2026
Update: the
Ast-seam unification epic #566 is complete and closed (all of #567–#572 landed onmain, verified green). That resolves the two open trait/shim loose ends tracked here (deprecated shims removed;#[doc(hidden)]extension traits resolved as demote topub(crate), withAstthe single public analysis seam).#505 still cannot close: the remaining work is the 2.0 release cut itself — flip
STABILITY.mdto 2.0.0, author the## [2.0.0]CHANGELOG section (moving the(breaking, deferred to 2.0)entries, now including #570's), bump the crate version, and the value re-baseline. None of this series is pushed yet either. These are the at-cut steps; #505 closes as part of that release-prep commit.dekobon commentedon Jun 7, 2026
Partial progress on the STABILITY.md release-prep item: the API-reference reconciliation is now done on
main(the deletedaction/Callback/parser-generic fns/path-positional shims and the demotedParserTrait/Parser/<Lang>*/compute traits are described in past-tense "removed / demoted topub(crate)at 2.0" throughout — commit4e03f135). What remains for the at-cut commit is narrower: flip the header1.x/1.1.0→2.0.0, bump the crate version, and the value re-baseline +## [2.0.0]CHANGELOG section.docs(stability): finish reconciling STABILITY.md with the retired sur…
dekobon commentedon Jun 9, 2026
Added #584 (decide
vcs::Optionsexhaustiveness / builder before 2.0) to the Core library API checklist. Surfaced during the #576 file-type-scoping review:Optionskeeps gaining public fields, and once the VCS surface ships under SemVer each additive field is a breaking change for external constructors. Not a defect today — forward-looking for the 2.x bump.27 remaining items
refactor(cli)!: make -I/-X single-value and repeatable
refactor(cli)!: unify --top semantics (0 = all)
dekobon commentedon Jun 11, 2026
Status: all milestone-2.0 issues implemented on local
feat/2.0(pending review/merge)The full milestone-2.0 issue set has been implemented in one batched effort
on a local
feat/2.0integration branch (offmain, not yet pushed),in seven dependency-ordered waves. Each wave was followed by a four-skill
quality pass (simplify / optimize / audit-tests / code-review) with findings
remediated before commit.
make py-stubtestgate)The branch passes the full local gate: the cargo trio,
cargo doc -D warnings, self-scan at both tiers, snapshot-anchors, man-page drift, themarkdown/TOML/Makefile lints, and the Python
pytest/mypy --strict/pyright/ stubtest /ruffstages. Thebig-code-analysis-outputsubmodule carries one matching local snapshot commit.
Remaining (release-cut, intentionally deferred)
Per the "release-prep follow-ups" in this issue, the following are left for
the deliberate 2.0 cut and are not done on this branch:
Cargo.toml1.x → 2.0.0 across the crates.## [Unreleased]→## [2.0.0]and author the refactor(output): normalize metric JSON/YAML key naming across all Stats #510/fix(halstead): n1/N1/n2/N2 keys are case-only-distinct (CSV/header collisions) #511key map + the cumulative value re-baseline note.
list.
Close this tracker (and the child issues) once
feat/2.0is reviewed,merged, and the release is cut.
refactor(lib)!: align Stats accessor names with wire vocabulary (#588)
refactor(output)!: align wire/dump/VCS shapes for 2.0 (#589 #590 #674 #…
refactor(cli)!: format/metric/diff CLI surface for 2.0 (part 1)
refactor(cli)!: scope flags to subcommands and accept positional paths (
refactor(cli)!: fail on explicit unknown-language files; unify --outp…
refactor(cli)!: tiered thresholds, manifest/flag name alignment, CI o…
refactor(web)!: align 2.0 REST schema, errors, and defaults (#631 #633 …
refactor(python)!: namespace VCS, single-source shapes, walker entry …
refactor(cli)!: 2.0 AST-report presentation overhaul (#677 #687 #685 #…
docs(2.0): rest.md, python docs, stubtest gate, umbrella doc cleanup (#…
dekobon commentedon Jun 12, 2026
Added a new 2.0-gated child: #718 — default C/C++ parsing to upstream
tree-sitter-cpp(=0.23.4, the exact base mozcpp already inherits) and anew upstream-
tree-sitter-c-backedLANG::C, with the vendored mozcppfork demoted to an opt-in feature — the same shape #507 gave
JavaScript/Mozjs. Children: #719 (empirical go/no-go measurement), #720
(Cpp flip + mozcpp opt-in), #721 (C language), #723 (post-flip cleanup).
Related but not 2.0-gated: #724 (ObjC
.m/.mmmisrouting).Unlike the zero-drift JS flip, this one expects metric drift and an
integration-submodule re-baseline (mozcpp's
primitive_type/class_specifieroverrides;.cre-routing) — #719 scopes it before anycode moves.