Decided (2026-06-05): AST keys → snake_case type/value/span/field_name/children; Span → flat {start_row,start_col,end_row,end_col} named struct (still Option). See the resolved-decisions comment.
Summary
The bca dump/AST JSON output uses PascalCase keys while every other
serialized type in the library is lowercase, and the AST span is an unnamed
4-tuple.
Evidence
AstNode hand-serializes Type / TextValue / Span / FieldName /
Children (src/ast.rs, the impl Serialize), and renames the value field
to TextValue. Compare SpaceKind's #[serde(rename_all = "lowercase")]
(src/spaces.rs) and the lowercase CodeMetrics keys.
pub type Span = Option<(usize, usize, usize, usize)> (src/ast.rs:26) — a
bare tuple alias as public API; the four positions (start_row, start_col,
end_row, end_col) have no names on the wire.
Why 2.0-worthy
The #510/#511 horizon normalizes metric output keys but does not cover the AST
dump keys, so without action the AST dump stays a permanent casing inconsistency.
Renaming serialized keys and changing Span to a named struct are both breaking
→ 2.0.
Proposed change
At 2.0: bring AstNode keys into the same lowercase scheme as the rest of the
output (type/value/span/field_name/children), and promote Span to a
named struct (Span { start_row, start_col, end_row, end_col }) so the AST dump
is self-documenting.
Acceptance
bca dump -O json keys match the rest of the serialized surface's casing.
Span serializes as a named object; 2.0 CHANGELOG records the shape change.
Part of the pre-2.0 review (#505).
Resolution
Implemented on branch fix/issue-535 (commit ab030f87).
- AST dump keys are now snake_case:
type / value / span /
field_name / children. TextValue → value; the hand-written
serialize_struct("Node", ...) impl was replaced with
#[derive(Serialize)] + #[serde(rename_all = "snake_case")].
Span is now a named struct Span { start_row, start_col, end_row, end_col }, still wrapped in Option. Field order maps 1:1 to the
former tuple (spos_row+1, spos_column+1, epos_row+1, epos_column+1);
values are unchanged (1-based tree-sitter rows/cols). Span derives
Deserialize for wire round-trip parity.
- Updated call sites:
src/alterator.rs::get_text_span, the web
/ast integration tests, the book AST-traversal example test, and
the book doc page.
- (breaking) — serialized AST shape; lands with the 2.0 schema
cluster. CHANGELOG entry is consolidated by the orchestrator.
Summary
The
bca dump/AST JSON output usesPascalCasekeys while every otherserialized type in the library is lowercase, and the AST span is an unnamed
4-tuple.
Evidence
AstNodehand-serializesType/TextValue/Span/FieldName/Children(src/ast.rs, theimpl Serialize), and renames thevaluefieldto
TextValue. CompareSpaceKind's#[serde(rename_all = "lowercase")](
src/spaces.rs) and the lowercaseCodeMetricskeys.pub type Span = Option<(usize, usize, usize, usize)>(src/ast.rs:26) — abare tuple alias as public API; the four positions (start_row, start_col,
end_row, end_col) have no names on the wire.
Why 2.0-worthy
The #510/#511 horizon normalizes metric output keys but does not cover the AST
dump keys, so without action the AST dump stays a permanent casing inconsistency.
Renaming serialized keys and changing
Spanto a named struct are both breaking→ 2.0.
Proposed change
At 2.0: bring
AstNodekeys into the same lowercase scheme as the rest of theoutput (
type/value/span/field_name/children), and promoteSpanto anamed struct (
Span { start_row, start_col, end_row, end_col }) so the AST dumpis self-documenting.
Acceptance
bca dump -O jsonkeys match the rest of the serialized surface's casing.Spanserializes as a named object; 2.0 CHANGELOG records the shape change.Part of the pre-2.0 review (#505).
Resolution
Implemented on branch
fix/issue-535(commitab030f87).type/value/span/field_name/children.TextValue→value; the hand-writtenserialize_struct("Node", ...)impl was replaced with#[derive(Serialize)]+#[serde(rename_all = "snake_case")].Spanis now a namedstruct Span { start_row, start_col, end_row, end_col }, still wrapped inOption. Field order maps 1:1 to theformer tuple
(spos_row+1, spos_column+1, epos_row+1, epos_column+1);values are unchanged (1-based tree-sitter rows/cols).
SpanderivesDeserializefor wire round-trip parity.src/alterator.rs::get_text_span, the web/astintegration tests, the book AST-traversal example test, andthe book doc page.
cluster. CHANGELOG entry is consolidated by the orchestrator.