Skip to content

Manifest extraction silently drops symbols and misreports domain capabilities #428

Description

@coderdan

The Doxygen → eql-manifest.json pipeline has a class of failure where a symbol is lost or misdescribed without the docs build failing. Four instances were found while pinning the docs site to EQL 3.0.3; all four are fixed in #427, but the underlying property — extraction failures are silent — is worth tracking separately, along with one gap left open.

What was wrong in 3.0.3

# Symptom Cause
1 eql_v3.grouped_value and eql_v3.lints() absent from the manifest entirely @example takes a filename in Doxygen; used as an inline snippet marker it pulls the block out of the member's documentation
2 grouped_value lost a second way; 60 min/max aggregates present but garbled (a parameter literally named public., return type CREATE AGGREGATE eql_v3) CREATE AGGREGATE's body is a second parenthesised group, which C++ has no form for, so Doxygen misreads the declaration
3 public.eql_v3_text_match described as storage-only; match capability absent from all 52 domains _capabilities_from_ops still tested the pre-3.0.1 @> / <@ spelling of fuzzy match, renamed to @@ in 3.0.1
4 public.eql_v3_json missing from the manifest dump_catalog filtered it out of stevec as scalar, while types iterates scalar_families(), which excludes the mixed json family wholesale — so it was in neither list

Two of these are worth dwelling on. #1 inverts the usual failure mode: it penalises the best-documented symbols, which is why grouped_value — the richest doc block of any aggregate in the codebase — was the one that vanished. #3 produced an actively contradictory record: a domain reporting capabilities: ["storage"] alongside supportedOperators: ["@@"] and termFunctions: ["eql_v3.match_term"].

The manifest is the machine-readable contract the documentation site and downstream agents build against. A missing symbol reads exactly like a symbol that does not exist, and a wrong capability reads exactly like a domain that cannot be searched — so these propagate into published docs as confident, wrong statements. #3 shipped that way for three releases, and it silently deleted a whole card from the docs site's generated text-function reference, because that generator keyed off the match capability.

Still open

SteVec domains report no operators. supportedOperators is hardcoded [] for the whole json family, so public.eql_v3_json_search claims no operators despite being the domain that supports @> / <@. This cannot be derived today: SteVecEntry carries no operator data, and terms is hardcoded in stevec_terms() because JSON_DOMAINS declare terms: &[] (the shape_and_terms_are_consistent invariant fails CI otherwise). Closing it means adding operator data to the Rust catalog's JSON domains, sourced from the hand-written src/v3/json/operators.sql. Deliberately left out of #427 rather than asserting an operator set that could not be verified from the catalog.

Worth considering

The four bugs share a shape: the pipeline treats "no memberdef", "empty description", and "no matching capability" as ordinary outcomes. A few cheap guards would have caught all of them at build time rather than three releases later:

  • Assert the manifest's symbol count against CREATE FUNCTION|AGGREGATE counts in the generated SQL, and fail on a drop. (61 CREATE AGGREGATE statements ship; 60 were listed.)
  • Fail when a domain's capabilities and supportedOperators disagree — a non-empty operator list reducing to ["storage"] is always a bug.
  • Fail, or at least warn, when a documented symbol yields an empty description.
  • Reject @example in --! blocks in the SQL doc lint, since it never means what it appears to mean here.

The stale test_xml_to_json.py fixture is a contributing factor too: it predated typname and the 3.0.1 renames and had been failing on main, so it could not catch #3. #427 brings it current.

Fixed by #427 (items 1–4).

Metadata

Metadata

Assignees

Labels

EQLbugSomething isn't workingdocumentationImprovements or additions to documentation

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions