Skip to content

feat(ingest): add the pure AI span classifier and registry loader - #432

Closed
JeremyFunk wants to merge 1 commit into
ai/01-registry-artifactfrom
ai/03-rust-classifier-core
Closed

feat(ingest): add the pure AI span classifier and registry loader#432
JeremyFunk wants to merge 1 commit into
ai/01-registry-artifactfrom
ai/03-rust-classifier-core

Conversation

@JeremyFunk

@JeremyFunk JeremyFunk commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

What this layer contains

Three self-contained Rust modules in apps/ingest, plus their tests and benchmark:

  • ai_registry.rs — loads and validates registry.json (via include_str!) at first use.
  • ai_classifier.rs — per-span vendor and session-key resolution over the registry's four-operator algebra, with the resource/scope context hoisted once per batch.
  • cityhash102.rs — the CityHash64 v1.0.2 variant ClickHouse's cityHash64 implements.
  • ai_classifier_corpus_test.rs, a criterion group, and serde_yaml as a dev-dependency.

The only edit outside new files is widening telemetry::any_value_string to pub(crate).

Why it is shaped this way

Nothing calls any of this yet. It is pure CPU with no pipeline wiring, no I/O and no schema change, which is exactly what makes a 3,000-line classifier reviewable — its behaviour is fully determined by the registry plus its inputs. The registry is validated at load rather than at classification so a bad resync fails the process start, not the first AI span. The pub(crate) widening is the one deliberate coupling: the classifier must canonicalize attribute values through the same function the row writer uses, or the Rust and SQL evaluators cannot be proven equivalent later.

The corpus replay is an on-demand local gate driven by TRACE_CAPTURE_DIR and skips when the variable is unset, because the ~60 OTLP capture directories are deliberately not vendored.

Gates run at this level

  • cargo test --locked — 125 lib tests, 69 bin tests, 0 failures.
  • cargo test --locked with TRACE_CAPTURE_DIR — corpus replay green: 41/41 goldens over 41 captures, 1,514 spans.
  • cargo clippy --all-targets — no new warnings; every remaining warning traces to a file this PR does not add (main.rs, telemetry.rs, autumn.rs, otel.rs, usage_metrics.rs).

Dependencies

Requires #430ai_registry.rs include_str!s packages/domain/src/ai-registry/registry.json.

Partition note: the criterion bench's accept_traces call stays at main's signature here. Its extra &AiClassificationSettings::disabled() argument depends on a telemetry.rs type that does not exist until the write-path PR, so that one hunk of the bench file lands there instead. The new ai_classifier bench group is complete in this PR.

🤖 Generated with Claude Code


Stack created with GitHub Stacks CLIGive Feedback 💬


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Adds three self-contained Rust modules: `ai_registry` (loads and validates
the vendored `registry.json` at first use, rejecting a bad artifact at load
rather than at classification), `ai_classifier` (per-span vendor and
session-key resolution over the registry's four-op algebra, with a
resource/scope context hoisted per batch), and `cityhash102` (the
CityHash64 v1.0.2 variant ClickHouse's `cityHash64` implements, so Rust and
SQL hash identically).

Nothing calls this yet — it is pure CPU with no pipeline wiring, which is
what makes it reviewable on its own. The only edit outside the new files
is widening `telemetry::any_value_string` to `pub(crate)` so the classifier
canonicalizes attribute values through the exact function the row writer
uses. The corpus replay test (`ai_classifier_corpus_test.rs`) is an
on-demand local gate driven by `TRACE_CAPTURE_DIR`; it needs `serde_yaml`
as a dev-dependency to read trace-capture's seed goldens, and is skipped
when the variable is unset. The criterion group measures classification in
isolation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@JeremyFunk
JeremyFunk changed the base branch from ai/02-org-session-salt to ai/01-registry-artifact August 12, 2026 21:04
@JeremyFunk
JeremyFunk force-pushed the ai/03-rust-classifier-core branch from 3a22d60 to a8baf21 Compare August 12, 2026 21:05
@JeremyFunk

Copy link
Copy Markdown
Collaborator Author

Superseded by the v2 stack: #451#452#453. The registry-artifact + SQL-equivalence design this stack implemented was dropped in the write-side plan's v2 revision; vendor rules are now plain Rust with the vendored classification fixture as the CI gate.

@github-actions

Copy link
Copy Markdown

🍁 Maple PR preview

Note

Preview resources were removed when this pull request closed.

Final commit a8baf21 · View workflow run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant