Releases: anortham/julie-extractors
Release list
julie-extract v2.13.0
v2.13.0
This feature release adds certified Blazor and Razor extraction support backed
by a repaired tree-sitter-razor grammar fork, semantic fixtures, capability
evidence, and live-corpus verification.
Razor and Blazor support
- Razor attribute expressions, directive modifiers, render fragments,
constrained@typeparam, and render modes parse cleanly and retain C#
semantic rows. - Razor component files emit synthetic component classes and embedded C#
properties, while_Imports.razorremains an infrastructure input without a
synthetic component identity. razor.route_reference.v1covers literal Blazor navigation calls and local
Razorhreftargets.blazor.component_reference.v1records component tags, containing component,
namespace context, and staticT+uppercase attribute candidates for downstream
resolution. These are naming-convention syntax evidence, not proven generic semantics.- Razor
@codeand@functionsblocks emit existing
http.client_request.v1facts for attestedHttpClientcalls. - C#, VB.NET, and Razor now classify supported xUnit, NUnit, and MSTest classes
astest_containerwhile lifecycle-role gaps remain explicit.
Certification
- Registered goldens cover attribute-expression shapes,
.razorand
.razor.cscode-behind identity inputs,_Imports.razor, scoped Razor/CSS
adjacency, constrained type parameters, render modes, and cascading
parameters. - Razor kind coverage now certifies
classandpropertyin addition to the
existing import, method, and variable kinds. - The structural-fact registry export and all metadata declarations remain
byte-synchronized. - A clean live scan of the Terraform corpus reports zero Razor diagnostics.
The remaining 283 SQL errors and one SQL missing node are tracked separately
in issue #10.
Contract versions
- Rust package versions change from
2.12.1to2.13.0across
julie-extract-artifact,julie-extract-cli, andjulie-extractors. - SQLite schema stays
4. extract_contract_versionstays3.- JSONL schema stays
3. - The
tree-sitter-razorrevision is
f82b737c77f5e3ef26bd655eda622b281479bbbc.
Publication
- Published
2026-07-12T16:40:54Zfrom commit
9dcb12f9fbe65f83c2114ce5d4abb3f0d2c72826. - Release workflow run
29200290333passed all four binary builds and the GitHub Release job. - All downloaded archive digests and embedded binary checksums passed.
- The downloaded Apple Silicon binary reported
julie-extract 2.13.0and
dogfooded the Terraform corpus with 388 files, 7,086 symbols, and a clean
no-change rescan.
julie-extract v2.12.1
v2.12.1
This maintenance release supersedes v2.12.0 to close its source-control CI
finding. The v2.12.0 release workflow and published assets were correct, but
the separate Linux push CI run failed when Rust 1.97 introduced stricter Clippy
diagnostics for seven existing Option control-flow patterns.
CI Closeout
- SQL structural-fact fallback now uses
Option::filterwhile preserving the
prior missing-name behavior. - C++, CSS, GDScript, Lua, and Razor early-return paths use the
?operator in
the forms required by Rust 1.97 Clippy. - The rewrites do not change extracted symbols, facts, contracts, parser pins,
or release-package contents. v2.12.0publication evidence, downloaded asset checks, and dogfood results
are recorded indocs/release-evidence/2026-07-10-v2-12-0-release.md.
Release Process Hardening
- New
scripts/check-release-state.shtripwire fails when the source tree
declares a version whose tag is not on origin, when localmainis ahead of
origin/main, or when a local tag is missing from origin. This release was
itself delayed by that exact gap: thev2.12.1prep commit sat unpushed and
untagged for a day afterv2.12.0shipped.docs/release.mdnow requires
the tripwire at session start and as the first closeout check.
Contract Versions
- Rust package versions change from
2.12.0to2.12.1across
julie-extract-artifact,julie-extract-cli, andjulie-extractors. - SQLite schema stays
4. extract_contract_versionstays3.- JSONL schema stays
3. - Test evidence stays
1. - Parser dependency pins are unchanged.
Release Preparation
The patch candidate is verified with:
cargo fmt --check
rustup run 1.97.0 cargo clippy --workspace --all-targets --all-features --no-deps -- -D warnings
cargo test -p xtask
cargo xtask test default
cargo xtask test contract
cargo deny --all-features check
node scripts/language-data-quality-report.mjs --strict
cargo xtask release preflight --version 2.12.1
git diff --checkjulie-extract v2.12.0
v2.12.0
This feature release adds versioned, golden-backed test-role evidence for
continuous-testing consumers while keeping execution and verdict logic outside
the extraction product.
Test Evidence Contract
kind_coverage.test_detectionis now published through the library snapshot,
julie-extract languages --json, SQLite capability rows, and JSONL exports.- The fixed role vocabulary is
test_case,test_container, and
test_lifecycle. Positive capability claims require an emitted role in a
registered golden fixture. - Consumers get explicit
supported, source-backednot_applicable, and owned
open_gapsclassifications. Absence remains unknown when capability evidence,
indexed-file status, or parse health is insufficient. - The versioned consumer contract is documented in
docs/contracts/test-evidence-v1.md. - Release packages include both the test-evidence contract and the
continuous-testing evidence-boundary decision.
Golden Closure
- All 28 code languages now have golden-backed evidence for at least one emitted
test role. - All 108 language-role cells are classified exactly once: 60 are supported, 6
are source-backednot_applicable, and 42 remain explicitopen_gapswith
closure ownership. - The strict language-quality gate now includes test detection for code
languages and still reportssilent_cells: 0andquality_bar_debts: 0. - CSS and regex provide the source-backed negative cases. HTML, JSON, Markdown,
SQL, TOML, and YAML retain explicit gaps because test meaning comes from an
external host, framework, or schema rather than the standalone language.
Extraction Fixes
- Razor now detects embedded C# test attributes such as
[Fact]without
misclassifying ordinary declarations. - Vue
<script>and<script setup>sections now publish JavaScript and
TypeScript call-style test roles with host-SFC spans, body spans, stable IDs,
and parent relationships. - Ordinary declarations and qualified member calls remain negative controls for
call-style test detection.
Continuous-Testing Boundary
julie-extractors owns emitted test roles plus capability and diagnostic
evidence. Miller owns deterministic graph candidates over extracted facts. Eros
owns runner inventory, scheduling, results, freshness, and verdicts. This release
does not add a watcher, runner inventory, scheduler, result store, or impact
verdict engine.
The boundary decision is recorded in
docs/architecture/continuous-testing-evidence-boundary.md.
Contract Versions
- Rust package versions change from
2.11.0to2.12.0across
julie-extract-artifact,julie-extract-cli, andjulie-extractors. - SQLite schema stays
4. extract_contract_versionstays3.- JSONL schema stays
3. test_detectionis additive within the existing versioned capability object.- Parser dependency pins are unchanged.
Release Preparation
The local release candidate is verified with:
cargo fmt --check
cargo test -p xtask
cargo xtask test default
cargo xtask test contract
cargo deny --all-features check
node scripts/language-data-quality-report.mjs --strict
cargo xtask release preflight --version 2.12.0
cargo xtask release package-list
git diff --checkPublished Release
Published 2026-07-10T15:30:13Z as
https://github.com/anortham/julie-extractors/releases/tag/v2.12.0.
- Release commit:
3f00c928d056919cc86dcce79b0751eedc9a3767 - Release workflow:
https://github.com/anortham/julie-extractors/actions/runs/29103308762 - Release evidence:
docs/release-evidence/2026-07-10-v2-12-0-release.md
| Target | Archive SHA-256 |
|---|---|
aarch64-apple-darwin |
249ed102deece8841c2965d7ad370ef08e63a82d093315a21f374a4457e57812 |
x86_64-apple-darwin |
29ce60fbfc96d636eb1500df3d563c8739dd7bf1ef8097f00bda531c6ca467b5 |
x86_64-pc-windows-msvc |
b4c428bc25638381e9ad46603cc3f30cd5ebb0065f0df83134afdda43b6df9ef |
x86_64-unknown-linux-gnu |
578946c36965e80407a26f774ea730c0bce9bd536b20ce7e46e96098ed3006a2 |
The release workflow and all downloaded assets passed. The separate
push-triggered CI run exposed seven Linux Rust 1.97 Clippy findings after the
release was already live; v2.12.1 is prepared as a behavior-preserving source
and CI-hygiene superseding patch.
julie-extract v2.11.0
v2.11.0
This maintenance release supersedes v2.10.0 to close the release-audit findings
found after publication. It does not change the extraction data model or the
variable_ref emission contract.
Release-Audit Fixes
- Dependency policy is green again.
deny.tomlnow allows the actual pinned
Razor parser source (https://github.com/anortham/tree-sitter-razor), matching
the fork introduced inv2.10.0. - Security advisory closed.
Cargo.lockupdatescrossbeam-epoch
0.9.18->0.9.20, resolvingRUSTSEC-2026-0204. - Release packages include the current SQLite schema contract. The package
manifest now shipsdocs/contracts/sqlite-schema-v4.mdalongside the older
schema docs, so downloaded archives include the contract for schema-4 artifacts. - Release evidence surfaces are corrected.
README.md,
docs/release-notes/v2.10.0.md, and
docs/release-evidence/2026-07-07-v2-10-0-release.mdnow reflect the live
v2.10.0release facts, asset digests, downloaded-binary smoke, and final
variable_refcounts.
Guardrails Added
xtaskrelease-package contract tests now fail if the current SQLite schema
contract is omitted from the package manifest.- A new dependency-policy contract test checks that every pinned git parser
source incrates/julie-extractors/Cargo.tomlappears indeny.toml's
allow-gitlist.
Contract Versions
- Rust package versions change from
2.10.0to2.11.0across all three crates
(julie-extract-artifact,julie-extract-cli,julie-extractors). - SQLite schema stays
4. extract_contract_versionstays3.- JSONL schema stays
3. - Parser dependency pins are unchanged from the corrected
v2.10.0release; this
release only fixes the policy allow-list for the Razor fork.
Verification
Release-prep verification is recorded in
docs/release-evidence/2026-07-07-v2-11-0-release.md.
Published Release
Published 2026-07-07T23:51:58Z as
https://github.com/anortham/julie-extractors/releases/tag/v2.11.0.
- Release commit:
29fb2774b1ea675dd59452701610f79a2525f822 - Release workflow:
https://github.com/anortham/julie-extractors/actions/runs/28906523124
| Target | Archive SHA-256 |
|---|---|
aarch64-apple-darwin |
c50e78f24e5e80efe259f5f06c32974b77af9922187612dd8de6e41cebea4c68 |
x86_64-apple-darwin |
a8f2e4aeb738785aaf3201a2050c31878a78eebacf80894f0c80170f456f6542 |
x86_64-pc-windows-msvc |
e9b39696ad91148640bee09bf58cbd43560cc671bdb40ff49ef010295199075b |
x86_64-unknown-linux-gnu |
5dcb9b8313c903c6608c63c3d61c03ef06ac4aaab290ec63706cc234620ed3ae |
julie-extract v2.10.0
v2.10.0
This minor release adds variable_ref identifier emission on top of v2.9.0.
It is an additive data change — new rows of an already-defined identifier kind
land in the existing identifiers table. It does not change the extraction
contract, the IdentifierKind enum, the identifiers schema, or any schema
version. SQLite schema stays 4, extract_contract_version stays 3, JSONL
schema stays 3.
New Capability: variable_ref Identifier Emission
Every general-purpose language extractor now emits a variable_ref identifier for
a bare name read — a symbol referenced by a plain value/receiver read that no
other identifier arm captured. Before this release, a symbol used only as a bare
read (return VisibilityUnknown;) or as the object/receiver of a static access
(GraphTraversal in GraphTraversal.Reach()) produced no identifier row, so a
downstream name-liveness consumer falsely flagged live symbols as dead. variable_ref
closes that gap by name.
The emission contract (6 rules, locked by the C# reference implementation)
Emit IdentifierKind::VariableRef (serialized variable_ref) for a name node N
when ALL hold:
- Read in value or receiver position — N is a reference used as an expression,
operand, argument, initializer, return value, collection element, OR the
object/receiver of a member access (XinX.Y/X.Y()/X::Y), OR a
member-reference LHS in an initializer/named-argument context (object-initializer
members, attribute named arguments, and equivalent per-language constructs). - Not already emitted by another arm — N is not a call callee (
Call), the
accessed.nameof a member access, or a type usage (TypeUsage).variable_ref
is the complement of the arms already in that extractor. - Not a declaration name — not the defining identifier of a
type/method/property/field/enum-member/parameter/local, a label, or an
import/using-alias LHS. - Not a write-only target — not the LHS of a plain assignment (
x = 5). A
compound assignment (x += 1,x ||= y) IS a read and emits.out/ref-style
argument slots may emit as reads (the safe direction — bare write-slot targets are
locals, which are never dead-code candidates). - Not a keyword/builtin — reuses each language's existing builtin/keyword filter;
never emitstrue,null,this,base, contextual keywords, or builtin type
names. containing_symbol_idis set via the existing byte-range containment helper,
exactly as the sibling arms do.
Non-resolvable by design. variable_ref is intentionally not wired into the
resolver tier chain (ReferenceKind::from_identifier_kind stays call / type_usage
/ member_access). The new rows are consumed downstream by name-match only, never
by the tier-1..4 resolution overlay. A resolvable ValueRef kind is a possible future
enhancement, explicitly out of scope here.
Per-Language Coverage
Measured on the real-repo dogfood extract (the julie-extractors workspace itself, one
full pass) — SELECT language, COUNT(*) FROM identifiers WHERE kind='variable_ref' GROUP BY language. Every general-purpose language emits variable_ref; no
general-purpose language is at 0.
| Language | variable_ref rows |
Notes |
|---|---|---|
| rust | 169,741 | dominates the corpus (large Rust workspace) |
| qml | 431 | pre-existing arm, unchanged |
| javascript | 340 | |
| r | 84 | pre-existing arm, unchanged |
| python | 74 | |
| php | 58 | |
| go | 53 | |
| csharp | 49 | reference implementation |
| jsx | 37 | |
| typescript | 34 | |
| tsx | 34 | |
| elixir | 29 | |
| java | 31 | |
| zig | 25 | |
| lua | 22 | |
| scala | 22 | |
| kotlin | 20 | |
| ruby | 16 | |
| gdscript | 15 | |
| razor | 16 | |
| vue | 14 | |
| cpp | 13 | |
| dart | 12 | |
| vbnet | 12 | |
| powershell | 11 | |
| swift | 11 | |
| c | 10 | |
| bash | 8 | $var / ${var} expansion reads (added) |
| css | 3 | var(--x) custom-property reads (added) |
| yaml | 3 | alias references (*name), pre-existing arm |
not_applicable (no variable_ref construct in the code-symbol sense; capabilities.json
records the determination): html, json, markdown, regex, sql, toml. SQL
variable/column reads already surface name-visibly as member_access (covered via
member_access — not re-emitted as variable_ref); json/toml/markdown emit no
identifiers at all.
Open-Gaps Ledger
Genuine grammar/scope limitations recorded during the rollout (honest under-report,
never guessed rows). These are precision-first misses; the feature's contract is
high-precision candidates, so under-reporting is the correct failure direction.
- kotlin — tree-sitter-kotlin-ng lexes a simple
$nameinterpolation as
string_content, so those reads are structurally unrepresentable and do not emit.
${name}interpolation does emit. - javascript (plain JS) — plain-JS JSX component names have no JSX arm in the JS
extractor (the TSXCallarm owns them); component-name reads emit fortsx/jsx,
not plain.js. - yaml — the alias
variable_refbinds a target at extraction (inline anchor
resolution, a pre-existing behavior). This predates the non-resolvable contract; it
is correct for file-local YAML anchors and was left unchanged rather than normalized. - rust — macro callees have no identifier row (Call-arm scope); bare-name constants
in match patterns are excluded (would need scope analysis; no guessed rows). - zig — bare return types are not covered by the zig
TypeUsagearm
(kind-honesty exclusion).
Pre-existing defects surfaced during the rollout (follow-up issues, not fixed here)
These were observed while adding the arms and are documented for follow-up. None were
introduced by this release.
- powershell — the vendored tree-sitter-powershell grammar emits
invokation_expression(typo), so the PSCallarm never fires ($obj.Method()
emits noCallidentifier today). - gdscript — a vestigial subscript
MemberAccessarm reads anindexfield the
6.1.0 grammar no longer produces. - elixir — the dot arm and the standalone alias arm double-emit a module receiver
astype_usage(two identical-span rows perModule.fun()); present in the base
goldens, not avariable_refregression. - sql / bash — SQL
DECLARE/SETvariables and bashfor-loop bindings are not
extracted as symbols, so there is no declared symbol for liveness to test against
(symbol-side gap, not an identifier-side gap).
Bundled Fix: v2.9.0 Scan-Performance Regression (437f91c)
v2.9.0's in-transaction resolution pass wrapped ~125k per-row overlay upsert/update
statements in a single SQLite SAVEPOINT. Each statement then walked a
memjrnlTruncate over the growing savepoint journal (99.9% of profiler samples),
turning the resolution write into a quadratic. On this repo the full scan regressed
from ~6.5 s (v2.8.0) to 425.9 s. The fix collects the overlay writes and
flushes them in batches, preserving the non-fatal rollback contract and adding a
perf regression test through the resolution-hook seam (the harness blind spot that
let the regression ship). Post-fix full scan: ~10.2 s in the fix-branch e2e check.
Honest scan-duration line item (restored — the v2.9.0 release evidence omitted the
overall scan wall-clock):
| Version | Full scan wall-clock (this-class repo / Miller repo) |
|---|---|
| v2.8.0 baseline | ≈ 6.5 s |
| v2.9.0 (regressed) | 425.9 s |
v2.9.0 (post-fix 437f91c) |
≈ 10.2 s (fix-branch e2e) |
| v2.10.0 (measured, Miller repo, 3 runs) | 7.617 s median (min 7.525 s, max 7.851 s) |
The v2.10.0 measurement is on the Miller repo (838 files) with the release binary; the
seconds-scale result confirms the savepoint quadratic is gone.
Performance & Growth Deltas (Miller repo, release binary, 3 runs)
The performance harness generates baselines/summaries with no enforced identifier-count
budget, so the growth deltas are recorded and judged explicitly here against the
escalation triggers (stop-and-report if identifier rows grow >5× or scan wall-clock
grows >2×).
| Metric | v2.9.0 baseline | v2.10.0 | Delta | Trigger |
|---|---|---|---|---|
| identifiers (total) | 94,721 | 187,003 | 1.97× | < 5× ✓ |
— call |
52,498 | 52,498 | 1.00× | unchanged |
— member_access |
26,271 | 26,271 | 1.00× | unchanged |
— type_usage |
15,952 | 15,952 | 1.00× | unchanged |
— variable_ref (new) |
0 | 92,282 | — | additive |
| scan wall-clock (median) | ≈ 6.5 s (v2.8.0) | 7.617 s | 1.17× | < 2× ✓ |
| artifact size | 237 MB | 348 MB | 1.47× | report-only |
The pre-existing kind counts are byte-identical to the v2.9.0 baseline — the only
growth is the additive variable_ref rows, which confirms the arm is a true complement
(no double-emit, no spurious rewrite of existing rows) across the whole Miller corpus.
Known recall cost (accepted, precision-first). Emitting all bare reads means any
candidate symbol that shares an exact name with any read binding anywhere in the
workspace is masked alive by name-match. Case-sensitive/BINARY matching limits
collisions in camelCase languages (C#); snake_case languages (rust, python, ruby) mask
more. Under-reporting is the correct failure direction for a high-precision candidate
feature.
Capability Honesty
fixtures/extraction/capabilities.jsonrecordsvariable_refin the
kind_coverage.identifiers.supportedlist for every emitting language, and in
kind_coverage.identifiers.not_applicableforhtml,json,markdown,regex,
sql, andtoml.- The strict data-quality gate
(node scripts/language-data-quality-report.mjs --strict) stays at
silent_cells: 0,quality_bar_debts: 0. - Every emitting language is fixture-backed: the language's golden
fixtures/extraction/<lang>/**/expected.jsoncarries the realvariable_refrow...
julie-extract v2.9.0
v2.9.0
This minor release adds workspace reference resolution on top of v2.8.1.
It is an additive artifact-schema feature (SQLite schema 3 → 4); it does not
change the extraction contract or any existing table or column.
New Capability: Workspace Reference Resolution
Extraction records where a reference is used (identifiers) and an unresolved
description of what it targets (pending_relationships). v2.9.0 adds a
deterministic, tiered pass that connects the two across the whole workspace:
- Fills
identifiers.target_symbol_idwith the resolved definition symbol. - Records resolved pending relationships in a new
pending_resolutionsoverlay
and every attempted identifier outcome in a newidentifier_resolutions
overlay. - Runs inside the same writer transaction as the scan on every mutating flow
(full scan → full pass; incremental update / delete → delta pass), so an
artifact is never observed with half-applied resolution. - Is a derived overlay, never an extraction fact: FK cascades invalidate
resolutions automatically when a target symbol dies, and a resolver error is
non-fatal — the scan still commits and the report recordsresolution_failed.
Resolution is honest by construction: it uses no best-guess selection. An
edge resolves only when exactly one same-language candidate survives the tier
filters; otherwise it stays ambiguous or missing. A wrong edge is worse than
a missing one — it would corrupt downstream trace/impact and hide a live
symbol behind a false dead-code verdict.
Resolution tiers
| Tier | Signal | Confidence | Method |
|---|---|---|---|
| 1 | Same-file scope | 0.95 |
tier1_local |
| 2 | Import-guided (TypeScript / JavaScript only today) | 0.85 |
tier2_import |
| 3 | Receiver-typed (bounded by type_facts emission) |
0.75 / 0.65 inferred |
tier3_receiver |
| 4 | Unique language-global (disabled for member_access / method calls) |
0.55 |
tier4_global |
Tiers 1 and 4 are universal (same-language, no per-language gating). Tier 2 is
enabled only where a fixture-tested import contract exists; tier 3 ships with its
measured type_facts-bounded coverage. Both gated tiers advertise their limits
as reference_resolution.tier2_import / .tier3_receiver capability-gap rows.
Tier 2 trusts an aliased import only when its relative module specifier
resolves to a concrete workspace file — an alias whose source module is missing
does not resolve, rather than matching an unrelated same-named symbol. Every full
or force scan also re-checks already-resolved overlays against the current
workspace and demotes any that are no longer a unique target, so a full pass
self-corrects stale rows even when the referencing file was unchanged.
Measured Resolution Rates
Measured on a real-repo dogfood scan (the julie-extractors workspace itself, one
full pass at revision 1). The headline: 38.7% of reference outcomes resolved
— 25,866 of 66,807. The 66,807 total is identifier_resolutions (62,189) +
pending_resolutions (4,618); the per-language rows below are the report's
by_language breakdown of that same total.
| Language | Resolved | Outcomes | Rate | Resolved by tier |
|---|---|---|---|---|
| rust | 25,573 | 64,932 | 39.4% | t1=8,479 t4=17,094 |
| qml | 74 | 796 | 9.3% | t1=72 t4=2 |
| javascript | 41 | 308 | 13.3% | t1=34 t2=2 t4=5 |
| r | 4 | 128 | 3.1% | t1=2 t4=2 |
| elixir | 26 | 88 | 29.5% | t1=19 t4=7 |
| typescript | 6 | 63 | 9.5% | t1=3 t4=3 |
| tsx | 7 | 46 | 15.2% | t1=3 t4=4 |
| python | 15 | 38 | 39.5% | t1=12 t4=3 |
| java | 9 | 32 | 28.1% | t1=9 |
| csharp | 6 | 30 | 20.0% | t1=3 t3=2 t4=1 |
| kotlin | 7 | 29 | 24.1% | t1=6 t4=1 |
| ruby | 1 | 29 | 3.4% | t1=1 |
| gdscript | 5 | 26 | 19.2% | t1=5 |
| jsx | 3 | 25 | 12.0% | t1=3 |
| php | 6 | 25 | 24.0% | t1=6 |
| dart | 7 | 23 | 30.4% | t1=4 t4=3 |
| go | 13 | 23 | 56.5% | t1=6 t4=7 |
| scala | 9 | 21 | 42.9% | t1=7 t4=2 |
| bash | 2 | 17 | 11.8% | t1=2 |
| swift | 7 | 16 | 43.8% | t1=6 t4=1 |
| sql | 0 | 14 | 0.0% | — |
| lua | 4 | 13 | 30.8% | t1=3 t4=1 |
| razor | 7 | 13 | 53.8% | t1=7 |
| zig | 9 | 12 | 75.0% | t1=7 t4=2 |
| css | 0 | 11 | 0.0% | — |
| vue | 6 | 9 | 66.7% | t1=6 |
| cpp | 7 | 8 | 87.5% | t1=7 |
| powershell | 3 | 7 | 42.9% | t1=2 t4=1 |
| regex | 0 | 6 | 0.0% | — |
| vbnet | 5 | 6 | 83.3% | t1=5 |
| c | 4 | 5 | 80.0% | t1=4 |
| html | 0 | 5 | 0.0% | — |
| yaml | 0 | 3 | 0.0% | — |
Rust dominates the corpus (a large Rust workspace), so its 39.4% rate anchors the
overall 38.7%. The by_language total is dominated by identifier outcomes;
tier 1 (same-file) and tier 4 (unique global) carry almost all resolutions today,
which is expected until tier 2 broadens beyond TS/JS (F4) and tier 3 broadens
with type_facts emission (F2). Data and markup languages (sql, css, regex,
html, yaml) resolve 0% because their reference outcomes are no_context — they
carry no call/receiver context to resolve against.
Performance
Measured on Apple Silicon against a synthetic ~92k-identifier artifact (release
build):
- Full resolution pass: ~1.2 s at ~92k identifiers — within the < 2 s
design budget (~1.6× headroom). - Single-file delta pass: ~82 ms — within the < 100 ms design budget. The
delta scopes its identifier-locator and covered-set loads to the files it
touches (every co-location join is same-file), so the cost tracks the size of
the change rather than the workspace.
The pass is set-based SQL over the writer transaction; two identical scans
produce byte-identical resolution tables. The by-names delta worklists chunk
their IN (...) binds, so a delta touching an arbitrarily large distinct-name
set resolves rather than hitting SQLite's bound-variable limit. Both budgets are
enforced by a measurement-derived regression gate (test-perf).
Known Limitations
- The full resolution pass is O(workspace) (~1.2 s at 92k identifiers): a
full or force scan rebuilds the whole-workspace candidate index and re-resolves
every reference. Incremental delta passes are scoped and far cheaper; the full
cost grows with workspace size but stays within the < 2 s budget at the measured
scale. - Tier coverage is deliberately conservative and per-language. Import-guided
(tier 2) resolution is enabled only for TypeScript/JavaScript; receiver-typed
(tier 3) resolution is bounded bytype_factsemission (broader coverage is
tracked as F2). Ambiguous or unproven references stay unresolved rather than
guessing. Per-language coverage is advertised incapabilities.jsonand
enforced by the contract fixtures.
Capability Honesty
fixtures/extraction/capabilities.jsongains a top-levelreference_resolution
block documenting the tier model, confidence values, outcome vocabulary,
metadata keys, and the per-language tier posture (which languages are proven by
fixture, which are universal, which are recorded gaps, and which are
not_applicable). It mirrors — and points to — the machine-enforced honesty
surfaces: the runtimelanguage_capability_gapsrows and the
resolution_contractfixtures.- Each scan emits
reference_resolution.tier2_importgap rows for every language
outside TypeScript/JavaScript andreference_resolution.tier3_receivergap rows
for every language, each with a concrete reason, required closure, and planned
closure task (F4 and F2 respectively). - The strict data-quality gate (
node scripts/language-data-quality-report.mjs --strict) now fails on either silent cells or quality-bar debts; the baseline
stays at0/0.
Contract Changes
- Rust package versions change from
2.8.1to2.9.0. - SQLite schema version changes
3→4(additive). New tables
pending_resolutionsandidentifier_resolutions; the resolver now populates
identifiers.target_symbol_id; three newreference_resolution_*metadata
keys; three new indexes. Every v3 table and column is unchanged. See
docs/contracts/sqlite-schema-v4.md. - Artifact integer
extract_contract_versionremains3— the extraction
contract is unchanged; only the derived resolution overlay is new. - JSONL schema version remains
3. The JSONLartifactrecord gains three
additivereference_resolution_*fields (mirroring the metadata keys,null
when resolution never ran) so JSONL consumers can apply the same status-gating
rule; theidentifierrecord'starget_symbol_idis now resolver-populated
on v4 artifacts. JSON report schema version remains3; mutating-command
reports gain an additivelanguages.reference_resolutionsection (documented
indocs/contracts/reports.md). - Consumers must gate on the
reference_resolution_statusmetadata key, never
on the schema version or table probing. A v4 artifact can carry resolution
statusabsent(not yet backfilled) orfailed(resolver error); schema
version only answers whether the binary can read the artifact. ANULL
target_symbol_idcontinues to mean "unknown". - A v3 artifact opened for reading under
--strict-schemais rejected
(schema_migration_required); resolution backfills on the write path (any
scan / update / delete triggers a full pass that creates the overlay tables and
populates them). - Parser dependency versions are unchanged.
Verification
Local prep gates (run before staging a release package):
cargo fmt --all -- --checkcargo test -p julie-extract-cli(includes the resolution unit, contract, and
operations suites)cargo test -p julie-extract-cli --test resolution_contract(per-language
tier + parity fixtures)cargo test -p julie-extract-cli --features test-perf --test resolution_perf
(full/delta budget gate)cargo test -p julie-extract-artifact(schema + storage contract)node scripts/language-data-quality-report.mjs --strict
(silent_cells: 0,quality_bar_debts: 0)- `cargo xtask dogfood repo --root . --out-dir target/dogfood/julie-...
julie-extract v2.8.1
v2.8.1
This patch release prepares the GLM review remediation on top of v2.8.0.
It is a correctness, contract-honesty, and writer-hardening release; it does
not add a new public fact family.
Correctness Fixes
- Route and HTTP-boundary scanners now keep the static-literal silence rule for
dynamic ASP.NET, Spring, Java HTTP client, and Ruby HTTP client arguments
while preserving static siblings. - Django
re_pathnamed groups normalize tonormalized_route_template. - Vue SFC script scanning masks comments and string literals for route and HTTP
client facts. - React and Vue route-object extraction ignores
pathandindexvalues under
redirectandmeta, including nested descendants. - JavaScript string-literal parsing handles common escapes and rejects malformed
literals that would otherwise produce false routes. - Frontend route precision is tightened for Next/Nuxt file routes, JSX nested
route metadata, Nuxt relative links, and CSS attribute selector commas. - Backend framework edge cases are fixed for Express router mounts, Spring
annotation adjacency and class prefixes, Rails nested/member/collection
routing, Actix direct routes, Govar muxreceivers, and Razor@page
normalized route templates. - SQL, YAML, JSON, TOML, Markdown, CSS, and related data-domain structural facts
have focused fixes for the GLM-reviewed edge cases.
Artifact Writer And JSONL Hardening
- Lower-level structural-fact writes are hardened against duplicate IDs under
the selected dedupe policy. - Successful writes checkpoint and truncate WAL state without losing committed
rows. - JSONL export ordering is deterministic for source regions, structural facts,
and complexity metrics. - Raw structural-fact metadata JSON is validated and compacted before JSONL
emission, so valid stored objects containing whitespace still produce one
valid JSONL record per line while preserving key order. - Writer and schema contract tests cover the new indexes, tier routing, and
writer performance tripwires.
Capability Honesty
fixtures/extraction/capabilities.json now records explicit open_gaps for
known deferred semantics instead of claiming complete coverage or marking real
missing implementation as not_applicable. The documented gaps include SQL
advanced structures, Markdown extended constructs, YAML scalar/tag/multidoc
semantics, JSON schema/reference semantics, TOML multiline strings, Regex
advanced constructs, CSS additional at-rules, HTML semantic/link/media details,
Vue style/slot shorthand, Django non-template regex normalization, and
signal-free Next.js pages-router files.
Contract Changes
- Rust package versions change from
2.8.0to2.8.1. - SQLite schema version remains
3. New indexes are non-breaking query and
export-order helpers. - Artifact integer
extract_contract_versionremains3. - JSONL schema version remains
3. - JSON report schema version remains
3. EXTRACTION_CONTRACT_VERSIONremains at thebackend-http-boundary-v2
marker. This patch fixes and documents shipped semantics without adding a new
top-level extraction family.- Parser dependency versions are unchanged.
Verification
Release workflow:
- https://github.com/anortham/julie-extractors/actions/runs/28715921413
- Trigger: tag push (
v2.8.1) - Result: success
- Published:
2026-07-04T18:48:23Z
Local prep gates run before publish:
cargo fmt --all -- --checkcargo test -p xtaskcargo xtask test defaultcargo xtask test contractcargo test -p julie-extractors route_definitioncargo test -p julie-extract-artifact --test jsonl_contractcargo xtask release preflight --version 2.8.1
Published-asset verification after release:
- Remote tag
v2.8.1points at
bca2b811bcd00b3d3a136dbdbc0e0aae8b7cba8d. - The GitHub release is not a draft and not a prerelease.
- Downloaded asset SHA-256 digests match GitHub release metadata.
- Package checksum files verify the staged
dist/<target>/julie-extract
binaries. - The downloaded Apple Silicon binary reports
julie-extract 2.8.1. - Downloaded-binary dogfood completed with SQLite schema version
3,
extraction contract version3, JSONL schema version3,1424files,
121258symbols, and710965JSONL records.
Published Assets
| Target | Asset | Size | GitHub asset digest |
|---|---|---|---|
| Linux x86_64 | julie-extract-v2.8.1-x86_64-unknown-linux-gnu.tar.gz |
10,792,146 bytes | sha256:b8217e019b3cd4d1f3f930bab0507a2d3d3f313ed773a8110bdf45212bc32e9d |
| macOS Apple Silicon | julie-extract-v2.8.1-aarch64-apple-darwin.tar.gz |
10,555,746 bytes | sha256:d147b62367153b38c08399ddc8d11873b0f21268222a2dc9523428c5e5a78fcb |
| macOS Intel | julie-extract-v2.8.1-x86_64-apple-darwin.tar.gz |
10,504,870 bytes | sha256:431a6b9205dc5c259cea710d60d48e7440276a8fb2434e39dc31458093fd1e09 |
| Windows x86_64 | julie-extract-v2.8.1-x86_64-pc-windows-msvc.zip |
9,779,606 bytes | sha256:e3e1afb80fa168d6437a3fc886a969bf8dcb39c230b9fb5762d6bd22f45953dc |
julie-extract v2.8.0
v2.8.0
This minor release finishes the backend HTTP boundary lane: server-side
route/mount fact families for six more mainstream backend stacks (NestJS,
Kotlin + Spring, Laravel, Phoenix, axum, actix), the http.client_request.v1
extension to four more languages (Kotlin, PHP, Elixir, Rust), and per-framework
prefix-registration ("mount") families — all joined on the same
normalized_route_template (:param flavor) key introduced in v2.7.0, so
Miller can bridge outbound client calls to handler definitions across these
stacks too.
The static-vs-dynamic silence decision for the four new languages is made by a
single shared AST whole-argument allowlist helper (static_arg.rs, ADR-0005),
not by extending the byte-level source mask — see Contract Changes.
New Structural-Fact Families
Handler-definition facts (all emit route_template plus the cross-family
normalized_route_template join key in :param flavor, with attested
verb/verb_source and prefix/effective keys where the framework has them):
- TypeScript/JavaScript (NestJS):
nestjs.route.v1—@Get/@Post/… (and
@All, verb omitted) method decorators, joined to the@Controllerclass
prefix. - Kotlin (Spring): reuses the existing
spring.request_mapping.v1id
(languagesextended to[java, kotlin]) —@GetMapping/@RequestMapping
with class-prefix join, bracket multi-path arrays, andmethod=[...]
multi-verb expansion. - PHP (Laravel):
laravel.route.v1,laravel.resource_route.v1,
laravel.route_prefix.v1—Route::get/match/any,Route::resource,
andRoute::prefix(...)->group(...)/Route::group(['prefix'=>...])prefix
joins. - Elixir (Phoenix):
phoenix.route.v1,phoenix.resource_route.v1,
phoenix.forward.v1— router macros with nestedscopeprefixes,
resources, andforward. - Rust (axum):
axum.route.v1,axum.nest.v1—Router::new().route(...)
with per-verb method-router expansion and.nest(...)mounts;
single-assignment receiver tracing (poison on non-literal). - Rust (actix):
actix.attribute_route.v1,actix.scope_route.v1,
actix.mount.v1—#[get(...)]/#[route(...)]attribute macros (verb
always),web::scope(...).route(...)same-file scope joins, and
web::scope(...).configure/.servicemounts. Mirrors the shipped ASP.NET
attribute-vs-call routing split.
Outbound-call facts: http.client_request.v1 now also covers Kotlin (Ktor
client receiver.verb(url)), PHP (Guzzle and the Laravel Http facade),
Elixir (Req), and Rust (reqwest reqwest::get / client.get), in addition to
the v2.7.0 coverage.
Cross-Family Doctrine (unchanged from v2.7.0)
normalized_route_templateremains the universal join key::paramflavor,
computed per family from the raw source template.- M2 static-literal silence: only static string literals emit route or client
facts. Interpolations, concatenations,format!/sprintf/macro forms,
heredocs/sigils with interpolation, and identifier/const arguments stay
silent; a non-literal prefix poisons the prefix chain rather than guessing. - Verbs are recorded only when source-attested; verbless registrations
(@All, actixweb::route(), axumany, method-less@RequestMapping)
omitverb. - Prefix-registration ("mount") facts emit at the prefix's own definition site
withmount_path/normalized_mount_path(andmount_targetwhere a
same-file target exists); same-file-resolvable prefixes also flow into
route_group_prefix/effective_route_templateon the route fact itself.
Static-Literal Detection (ADR-0005)
The four new languages make the static-vs-dynamic decision via
static_route_arg(node, content, lang) — an AST allowlist run on the whole
route/URL argument expression, returning the literal's text only for an
approved static string-literal node and None for every wrapper. The vendored
tree-sitter grammars differ from a naive "interpolation-child" reading, so each
arm carries a grammar-verified guard: Kotlin also rejects an unescaped $ in
string_content; Elixir also rejects #{ in quoted_content (the ~S
capital-sigil case) and requires sigil_name ∈ {s, S}; PHP runs its allowlist
on the heredoc_body/nowdoc_body child. The byte-level SourceMask in
scan.rs is deliberately not extended to these languages.
Contract Changes
- Rust package versions change from
2.7.0to2.8.0. EXTRACTION_CONTRACT_VERSIONgains the trailingbackend-http-boundary-v2
marker (new pattern ids and newhttp.client_request.v1languages change the
canonical extraction shape).docs/contracts/structural-fact-patterns.jsonadds the new NestJS/Laravel/
Phoenix/axum/actix route and mount specs and the Kotlin extension of
spring.request_mapping.v1; thehttp.client_request.v1spec gains
kotlin/php/elixir/rust.- SQLite schema version remains
3. Artifact integer
extract_contract_versionremains3. JSONL schema version remains3.
JSON report schema version remains3. - Parser dependency versions are unchanged.
Documented Exclusions
Per-language deferrals are recorded as open_gaps (reason + closure task) on
the capability rows, not silent gaps: Ktor server routing and
RouterFunction/coRouter (Kotlin); Symfony #[Route] attributes and
cross-file RouteServiceProvider prefixes (PHP); LiveView/socket/channel and
cross-file scope/forward prefixes (Elixir); actix cross-file
configure/service scopes, web::resource guard forms, axum 0.7 :id
recording, cross-file .nest joins, and deferred clients
(OkHttp/Retrofit/WebClient, Symfony HttpClient/curl, Tesla/HTTPoison/Finch,
hyper/ureq). nestjs.global_prefix is out by design (no safe Miller consumer).
Miller Consumer Follow-Up (cross-repo)
docs/plans/2026-07-03-miller-http-boundary-consumer-followup.md tracks the
Miller-side work. Verified against the current consumer: Kotlin Spring routes
(reused spring.request_mapping.v1) and all four new client languages (reused,
non-language-gated http.client_request.v1) join today with zero Miller
changes. The eight new server-route ids and four new mount families need
whitelist + route-family wiring on Miller's side to join; they are correct and
evidence-bearing regardless, and same-file prefixes degrade gracefully via
effective_route_template.
Verification
Local and release gates passed for commit
2dbdcad327f8025fe0f6c3aedba6ece73e8323a1:
cargo test --workspace --quietcargo clippy --workspace --all-targets --all-features --no-deps -- -D warningscargo fmt --all -- --checkgit diff --check HEADcargo test -p julie-extractors --features test-golden structural_fact_registrycargo test -p julie-extractors --features test-golden golden_fixtures_match_canonical_extractioncargo test -p julie-extractors --features test-capability-matrix capability_matrixnode scripts/language-data-quality-report.mjs --strict(silent_cells 0, quality_bar_debts 0)scripts/check-agent-doc-sync.sh(AGENTS.md/CLAUDE.md synced)cargo xtask release preflight --version 2.8.0(4 targets, 19 inputs)- GitHub CI run
28707779894:Fast Gates, passed - Release workflow run
28707784242: all four binary builds and the GitHub Release job passed - Downloaded published Apple Silicon binary dogfood passed:
julie-extract 2.8.0
Published Assets
| Target | Asset | Size | GitHub asset digest |
|---|---|---|---|
| Linux x86_64 | julie-extract-v2.8.0-x86_64-unknown-linux-gnu.tar.gz |
10,758,539 bytes | sha256:185bd0cdd2b0ea45ab588fbf01fbc0d83953453c4423115cf4febcadf034ac8f |
| macOS Apple Silicon | julie-extract-v2.8.0-aarch64-apple-darwin.tar.gz |
10,523,676 bytes | sha256:75424faf62b98afd02f5268919dd5269db6146b1e410ea250a20a10e9afae8af |
| macOS Intel | julie-extract-v2.8.0-x86_64-apple-darwin.tar.gz |
10,458,063 bytes | sha256:12c3e6271cb73226bad1dcee6a8e508c04a3e2d7b312866352cb6b19b9b1c6d2 |
| Windows x86_64 | julie-extract-v2.8.0-x86_64-pc-windows-msvc.zip |
9,759,538 bytes | sha256:fb2d2df16ddb92eea4d47bee384bdf225a63b7a054087cf56f462a73a3128e0b |
Release metadata verified that v2.8.0 is not a draft and not a prerelease.
Downloaded assets matched the GitHub asset digests, and each archive stores the
binary under dist/<target>/julie-extract or dist/<target>/julie-extract.exe
with the checksum file beside it.
julie-extract v2.7.0
v2.7.0
This minor release ships the backend HTTP boundary coverage lane: 16 new
server-side route/mount fact families across 10 languages, the
http.client_request.v1 extension to five backend languages, and the
cross-family normalized join key that lets Miller connect outbound client
calls to handler definitions. It also includes the full resolution of the
38-finding pre-release code review of this lane
(docs/reviews/2026-07-02-backend-http-boundary-review-findings.md).
New Structural-Fact Families
Handler-definition facts (all emit route_template plus the cross-family
normalized_route_template join key in :param flavor, with
dynamic_segments, attested verb/verb_source, and prefix/effective keys
where the framework has them):
- JavaScript/TypeScript/JSX/TSX:
express.route.v1,
express.router_mount.v1,fastify.route.v1 - Python:
fastapi.route.v1,fastapi.include_router.v1,flask.route.v1,
flask.blueprint_registration.v1,django.url_pattern.v1,
django.url_include.v1 - Java:
spring.request_mapping.v1 - Go:
go.net_http.route.v1,gin.route.v1,echo.route.v1 - Ruby:
rails.route.v1,rails.resource_route.v1,rails.mount.v1
Outbound-call facts: http.client_request.v1 now also covers Python
(requests/httpx module calls), C# (HttpClient methods and
HttpRequestMessage), Go (net/http package calls), Java (HttpRequest
builder chains), and Ruby (Net::HTTP with literal URI(...)/URI.parse(...)),
in addition to the existing fetch/axios coverage.
ASP.NET route families additionally emit normalized_route_template as the
same cross-family join key.
Cross-Family Doctrine
normalized_route_templateis the universal join key::paramflavor,
computed per family from the raw source template; trailing slashes are
preserved as written.- M2 static-literal silence: only static string literals emit route or client
facts. Template literals, interpolations, concatenations, and identifier
arguments stay silent; a non-literalmethod:/group prefix poisons that
fact (or its prefix chain) rather than degrading to a guess. - Verbs are recorded only when source-attested (
verb_source="attested");
verbless registrations (app.all, gin/echoAny, method-less
@RequestMapping, verbless Go patterns) omitverb. - Receiver attestation is in-file only: routes emit on receivers traceable to
a framework constructor or an import-gated plugin parameter in the same
file. Mount facts (express.router_mount.v1,fastapi.include_router.v1,
flask.blueprint_registration.v1,django.url_include.v1) are the
cross-file prefix-join inputs for consumers.
Behavior Details From the Review-Fix Lane
- Go
net/httppatterns follow the Go 1.22[METHOD ][HOST]/[PATH]grammar:
route_templatecarries the path part,verbthe method token, and a new
optionalhostkey the host part; normalization uses the path only, so
host-scoped and host-less routes share a join key. - gin/echo facts emit
api_style="call_routing";mux_routingis reserved
forgo.net_http.route.v1. NestedGroupcalls compose literal prefixes;
the echo import gate accepts any major version ofgithub.com/labstack/echo. - Spring templates come only from the positional value or
value =/path =
annotation elements —produces/consumes/params/headersliterals are
not routes. Method-level@GetMapping-style annotations emit
attribute_kind="http_method"; method-level@RequestMappingemits
attribute_kind="request_mapping". Each class declaration resets the
class-level prefix. - Express: multi-line
app.route(...).get(h).post(h)chains emit per-verb
facts without scanning handler bodies; single-string-argument verb calls
(app.get('port')settings getter) stay silent. - Fastify: a plugin parameter named
fastifyattests the framework by
itself; a genericappparameter requires an in-file fastify import. - Rails:
config/routes.rbDSL must sit inside aroutes.draw do ... end
block; split files underconfig/routes/allow top-level DSL; nested
non-scope blocks (member,collection,constraints) no longer pop
enclosingnamespace/scopeprefixes. - Python: Django single-argument
path("x")calls stay silent (previously a
panic path); triple-quoted strings (including docstrings with apostrophes)
are masked correctly across all Python scanning. - Java client facts anchor the enclosing statement for builder chains; the
contract docs state this explicitly.
Contract Changes
- Rust package versions change from
2.6.1to2.7.0. EXTRACTION_CONTRACT_VERSIONgains the trailing
backend-http-boundary-v1marker.docs/contracts/structural-fact-patterns.jsonadds the 16 route/mount
family specs and the client extension, including the optionalhostkey on
go.net_http.route.v1and the correctedapi_styledescriptions for
gin.route.v1/echo.route.v1.- SQLite schema version remains
3. Artifact integer
extract_contract_versionremains3. JSONL schema version remains3.
JSON report schema version remains3. - Parser dependency versions are unchanged.
Documented Exclusions
Per family, dynamic values stay silent by doctrine: non-literal route
templates, f-string/interpolated URLs, computed group prefixes (poisoned
chains emit route_template only), non-traceable receivers, session/
instance HTTP clients, and DSL outside the Rails draw block. Negative
coverage is pinned by unit tests and the
fixtures/extraction/javascript/backend_http_boundary_negatives golden.
Verification
Local prep gates run on July 2, 2026:
cargo test --workspace(2811 passed, 0 failed)cargo clippy --workspace --all-targets --all-features --no-deps -- -D warningscargo fmt --all -- --checkgit diff --checkcargo test -p julie-extractors --features test-golden golden_fixtures_match_canonical_extractioncargo test -p julie-extractors --features test-capability-matrix capability_matrixnode scripts/language-data-quality-report.mjs --strict(silent_cells 0, quality_bar_debts 0)cargo test -p xtaskcargo xtask test defaultcargo xtask test contractcargo xtask release preflight --version 2.7.0
Published-asset verification is recorded in
docs/release-evidence/2026-07-02-v2-7-0-release.md after the
Release Binaries workflow completes.
Miller Handoff
Companion-plan inputs for Miller's fetch↔handler bridge: client target_path
joins against normalized_route_template across all server families; the
four mount/include facts are the cross-file prefix-join inputs;
rails.resource_route.v1 is a join input that needs Rails-semantics
expansion on Miller's side if desired.
julie-extract v2.6.1
v2.6.1
This patch release fixes structural-fact containing_symbol_id bindings for
Miller bridge consumers. It supersedes v2.6.0.
Fixes
- Structural facts now bind to scope-bearing containers instead of local value
holders.variable,constant,enum_member, andimportsymbols are not
containment candidates. http.client_request.v1facts insideconst res = await fetch(...)bind to
the enclosing function, not the localresvariable.nextjs.route_handler.v1facts forexport const VERB = async (...) => ...
bind to the exported handler symbol instead ofNULL.- Same-line route-object facts no longer bind to child object-property symbols
such asid,index, orpath; module-level route objects with no
enclosing scope-bearing owner stayNULL. - SQL schema and Vue helper regex paths avoid panic-prone unwraps while keeping
well-formed sibling extraction rows.
Contract Changes
- Rust package versions change from
2.6.0to2.6.1. EXTRACTION_CONTRACT_VERSIONretains the
containing-symbol-binding-v2marker introduced for this local release-prep
line. The marker covers the finalized binding semantics in this patch.- SQLite schema version remains
3. - Artifact integer
extract_contract_versionremains3. - JSONL schema version remains
3. - JSON report schema version remains
3. - Parser dependency versions are unchanged.
Verification
Local prep gates run on July 2, 2026:
cargo test -p julie-extractors react_route_object_does_not_bind_child_property_symbol -- --nocapturecargo test -p julie-extractors containing_symbol::tests -- --nocapturecargo test -p julie-extractors nextjs_const_arrow_route_handler_binds_its_function_symbol -- --nocapturecargo test -p julie-extractors fetch_assigned_to_const_binds_enclosing_function_not_variable -- --nocapturecargo test -p julie-extractors fetch_bare_call_binds_enclosing_function -- --nocaptureUPDATE_GOLDEN=1 cargo test -p julie-extractors --features test-golden golden_fixtures_match_canonical_extraction -- --nocapturecargo fmt --all -- --checkgit diff --checknode scripts/language-data-quality-report.mjs --strictcargo test -p julie-extractors --features test-golden golden_fixtures_match_canonical_extraction -- --nocapturecargo test -p julie-extractorscargo clippy -p julie-extractors --all-targets -- -D warningscargo xtask release preflight --version 2.6.1cargo build --bin julie-extracttarget/debug/julie-extract --versioncargo xtask test defaultcargo xtask test contract
Published-asset verification:
Release Binariesworkflow run28595729308passed for commit
c9a1bd1db3c3068b982ad01bcbdcc1fc28ab2f9a.- GitHub CI run
28595716930passedFast Gatesfor the same commit. - GitHub release
v2.6.1is live, non-draft, and non-prerelease. - Remote tag
v2.6.1and remotemainboth point at
c9a1bd1db3c3068b982ad01bcbdcc1fc28ab2f9a. - Downloaded archive digests matched GitHub's SHA-256 asset digests for all
four platform assets. - Package checksum files validated for all four extracted archives.
- The downloaded Apple Silicon binary reported
julie-extract 2.6.1. - Downloaded-binary dogfood scan completed with SQLite schema version
3,
extraction contract version3, JSONL schema version3,1321scanned
files, and588355JSONL records.
Package Assets
Published assets:
julie-extract-v2.6.1-aarch64-apple-darwin.tar.gz- SHA-256:
f68a346397d8f016311867cbda60b14c8b8027e45aa89ba9273cbc6c0ff85421
- SHA-256:
julie-extract-v2.6.1-x86_64-apple-darwin.tar.gz- SHA-256:
e05ad64b30ef3b44bc47644913c753126cbd53c76d99d54b6cbd0bf581e9dc33
- SHA-256:
julie-extract-v2.6.1-x86_64-pc-windows-msvc.zip- SHA-256:
2be36d45730d58c3cb7f193f503abf773b15ab83397b82e9139223f17157832d
- SHA-256:
julie-extract-v2.6.1-x86_64-unknown-linux-gnu.tar.gz- SHA-256:
8e681eee03bf568c7846c2e8f9be5b89cc19f507db764bd010b9856d9a008d1a
- SHA-256: