feat(cli): add hinzu api-diff for cross-language public-surface conformance#34
Open
zmaril wants to merge 2 commits into
Open
feat(cli): add hinzu api-diff for cross-language public-surface conformance#34zmaril wants to merge 2 commits into
zmaril wants to merge 2 commits into
Conversation
zmaril
force-pushed
the
feat/hinzu-api-diff
branch
from
July 21, 2026 16:15
2827b5d to
818ca02
Compare
zmaril
pushed a commit
that referenced
this pull request
Jul 21, 2026
Rebasing #34 onto main (which now carries #40's `ranges` subcommand) pushed crates/hinzu-cli/src/main.rs to 1527 lines, over straitjacket's 1500-line file-size limit. Move the `hinzu api-diff` CLI flow — the ApiDiffArgs struct and the api_diff/load_api_report/api_diff_rules handlers — into a new crates/hinzu-cli/src/api_diff.rs module (mirroring api_ts.rs / api_fluessig.rs), and make write_json crate-visible. Pure code move; main.rs drops to 1452 lines. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P8vNpHV16JdfQGmZLpqRCk
…rmance `hinzu api-diff` takes two `hinzu api` reports (a source package's public API and a target port's) and emits a stable JSON conformance grade: per source public item, is there a matching target item (matched / signatureMismatch / missing), plus target-only extras. Advisory and evidence-carrying, mirroring port-diff's ethos. - Pure core `build_api_diff` in hinzu-core `apidiff.rs`: name + kind-class matching, structural shape comparison (param arity, field/variant sets), a per-kind breakdown and an overall conformance score. No I/O — passes the functional-core self-check. - Reuses port-diff's naming rules (exposed as pub(crate)) so convention renames (camelCase<->snake_case fns and fields, PascalCase/SCREAMING kept, kebab<->snake files) don't false-miss; a PascalCase *function* name snake-folds since keep-Pascal is a type rule. - CLI `api-diff` subcommand reads the two report JSONs and the port config (--config/--package) for the naming rules + crate mapping; all I/O in the CLI. - notes/api-diff.md documents the schema, matching, kind-equivalence table, composition with port-diff, and the pi->pidgin validation (conformance 0.32). - notes/port-pi-pidgin.toml: the pi->pidgin port config (atilla renamed). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P8vNpHV16JdfQGmZLpqRCk
Rebasing #34 onto main (which now carries #40's `ranges` subcommand) pushed crates/hinzu-cli/src/main.rs to 1527 lines, over straitjacket's 1500-line file-size limit. Move the `hinzu api-diff` CLI flow — the ApiDiffArgs struct and the api_diff/load_api_report/api_diff_rules handlers — into a new crates/hinzu-cli/src/api_diff.rs module (mirroring api_ts.rs / api_fluessig.rs), and make write_json crate-visible. Pure code move; main.rs drops to 1452 lines. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P8vNpHV16JdfQGmZLpqRCk
zmaril
force-pushed
the
feat/hinzu-api-diff
branch
from
July 21, 2026 21:29
6de5bc9 to
be78c2e
Compare
zmaril
marked this pull request as ready for review
July 21, 2026 23:11
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.
What
A new
hinzu api-diffsubcommand that takes twohinzu apireports — a SOURCE package's public API and a TARGET package's public API (typically different languages) — and emits a stable JSON conformance grade. Each source public item is classified matched / signatureMismatch / missing, plus target-only items surfaced as extra, with an overall conformance score and a per-kind breakdown. It is advisory and evidence-carrying (every pairing cites source and target id/file/line), the same ethos asport-diff.Why
It completes the original intent behind
hinzu api: knowing both the public API a port must match AND how far a target language's surface has gotten. It composes withport-diff— port-diff bands file progress by graph structure; api-diff grades the actual public-surface conformance. They're complementary, not redundant.How
A pure
hinzu_core::apidiff::build_api_diff(source, target, rules)(no I/O — passes the self-check pure-region policy) does name+kind matching and structural shape comparison; the CLI reads the two JSON reports and the port config.signatureMismatchis a signal, not a proof.Validated on the real pi→pidgin pair (the
aipackage)Source pi
ai(TypeScript) vs target pidginai(Rust). Grade: conformance 0.32 — matched 124, missing 206, signatureMismatch 58, extra 527 (388 source public items).Spot-checked examples verified against pidgin source:
calculateCost→calculate_cost;AssistantMessagefields align snake_case.completeSimpleTS 3 params → Rust 4, splitting outOption<&AbortSignal>.anthropicProviderfactory fns (pidgin uses registries);ANTHROPIC_MODELSconst (pidgin exposes via methods) — genuinely unported as that shape, grep-confirmed.During validation two convention false-misses were caught and fixed (field-name normalization; PascalCase function names now snake-fold).
Honest limitations
hinzu apicaptures only the first overload).missing.Docs
notes/api-diff.md— schema, matching + naming rules + kind-equivalence table, composition with port-diff, the pi→pidgin result.notes/api.md— links the follow-up.notes/port-pi-pidgin.toml— the atilla→pidgin-renamed port config.Gate (all green locally)
cargo fmt --all --checkcargo clippy --all-targets -- -D warningscargo test— 93 core (incl. 8 new apidiff) + lsp/dbsp/integration, 0 failedhinzu checkself-check pure-region policyIt's a DRAFT — not for merge without review.