Skip to content

Add TaxonomyLinter to validate taxonomy TOML files against schema - #385

Merged
codeZe-us merged 1 commit into
Toolbox-Lab:mainfrom
webdevayo:feat/taxonomy-linter
Jul 29, 2026
Merged

Add TaxonomyLinter to validate taxonomy TOML files against schema#385
codeZe-us merged 1 commit into
Toolbox-Lab:mainfrom
webdevayo:feat/taxonomy-linter

Conversation

@webdevayo

@webdevayo webdevayo commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

What

Closes #380 — adds a TaxonomyLinter that validates every taxonomy TOML file
in crates/core/src/taxonomy/data/ against the TaxonomyEntry schema, and
wires it into CI so malformed entries are rejected automatically.

Changes

  • crates/core/src/taxonomy/linter.rs — new module that parses each TOML
    file via the existing TaxonomyParser and validates:
    • required fields (id, name, summary, detailed_explanation) are
      non-empty
    • no duplicate (category, code) pairs across the directory
    • severity is a recognized value
    • since_protocol / deprecated_protocol are well-formed and consistent
      with each other when both are present
    • documentation_url, when present, is a structurally valid URL (checked
      via the url crate — no live network calls, to keep CI deterministic)
    • related_errors references resolve to real entry ids across the full
      data set
  • crates/core/src/bin/taxonomy_linter.rs — small binary that runs the
    linter against a given directory (defaults to the real taxonomy data dir)
    and exits non-zero if any issues are found
  • scripts/lint_taxonomy.sh — shell wrapper that invokes the binary
  • .github/workflows/ci.yml — added a "Lint taxonomy TOML" step to the
    existing rust_checks job so this runs on every push/PR

Verification

  • cargo test -p grat-core — all existing taxonomy tests still pass, plus
    new unit tests for the linter (valid entry, missing field, duplicate code,
    bad URL, invalid severity)
  • cargo fmt --all -- --check and cargo clippy --workspace --all-targets --all-features — clean
  • Ran the linter against the real crates/core/src/taxonomy/data/ directory
    — no issues reported, confirming the existing data is schema-compliant

Notes

URL validation is structural only (via url::Url::parse), not a live
reachability check, to avoid flaky CI from network calls or third-party
downtime.

Summary by CodeRabbit

  • New Features

    • Added validation for taxonomy data, including required fields, severity values, protocol versions, documentation URLs, duplicate codes, and related-error references.
    • Added a command-line taxonomy validation tool with clear file and entry-specific error reporting.
  • Bug Fixes

    • Automated checks now detect invalid taxonomy entries during continuous integration.
  • Tests

    • Added coverage for successful validation and individual taxonomy failure scenarios.

@drips-wave

drips-wave Bot commented Jul 29, 2026

Copy link
Copy Markdown

@webdevayo Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

Taxonomy linting

Layer / File(s) Summary
Linter validation and issue model
Cargo.toml, crates/core/src/taxonomy/linter.rs, crates/core/src/taxonomy/mod.rs
Adds taxonomy parsing and validation for required fields, severity, protocol versions, documentation URLs, duplicate codes, and unresolved references, with unit tests.
Linter CLI packaging
crates/core/Cargo.toml, crates/core/src/bin/taxonomy_linter.rs
Adds the binary target and CLI behavior for selecting a directory, reporting issues, and returning status codes.
Script and CI integration
scripts/lint_taxonomy.sh, .github/workflows/ci.yml
Runs the taxonomy linter through a strict shell script before Rust tests in CI.

Estimated code review effort: 4 (Complex) | ~45 minutes

Suggested reviewers: codeze-us

Sequence Diagram(s)

sequenceDiagram
  participant CI as CI workflow
  participant Script as lint_taxonomy.sh
  participant CLI as taxonomy_linter
  participant Linter as lint_dir
  CI->>Script: run taxonomy lint step
  Script->>CLI: invoke cargo run with taxonomy directory
  CLI->>Linter: lint directory
  Linter-->>CLI: return lint issues
  CLI-->>Script: exit success or failure
  Script-->>CI: report lint status
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding a taxonomy linter for TOML schema validation.
Linked Issues check ✅ Passed The PR adds the linter, validation rules, and CI integration required to reject malformed taxonomy entries.
Out of Scope Changes check ✅ Passed The changes stay focused on taxonomy linting, its binary, script, dependencies, and CI wiring.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Fix failing CI checks
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
crates/core/src/taxonomy/linter.rs (1)

77-169: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Reduce repeated LintIssue construction with a small helper.

The same three-field struct literal is repeated ~10 times for each check. A tiny helper cuts boilerplate and makes it easier to add checks going forward.

♻️ Proposed refactor
+    let mut push_issue = |issues: &mut Vec<LintIssue>, file: &str, entry_id: &str, message: String| {
+        issues.push(LintIssue {
+            file: file.to_string(),
+            entry_id: Some(entry_id.to_string()),
+            message,
+        });
+    };
+
     for entry in schema.errors {
         let entry_id = entry.id.clone();

         // ── id must be non-empty ─────────────────────────────────
         if entry.id.trim().is_empty() {
-            issues.push(LintIssue {
-                file: file_name.clone(),
-                entry_id: Some(entry_id.clone()),
-                message: "id is empty".to_string(),
-            });
+            push_issue(&mut issues, &file_name, &entry_id, "id is empty".to_string());
         }

Separately, documentation_url is only checked for parseability, so non-http(s) absolute URLs (e.g. mailto:, ftp:) would pass as "valid" — worth a scheme allow-list if strict doc-link hygiene matters here.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/core/src/taxonomy/linter.rs` around lines 77 - 169, Introduce a small
local helper around the linter loop to construct and append a LintIssue from
file_name, entry_id, and message, then replace the repeated LintIssue literals
in each validation branch with that helper. Keep the existing validation
conditions and messages unchanged; do not expand the documentation_url URL
validation unless separately requested.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@crates/core/src/taxonomy/linter.rs`:
- Around line 77-169: Introduce a small local helper around the linter loop to
construct and append a LintIssue from file_name, entry_id, and message, then
replace the repeated LintIssue literals in each validation branch with that
helper. Keep the existing validation conditions and messages unchanged; do not
expand the documentation_url URL validation unless separately requested.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 931bd7a3-8e2c-4061-b3c1-2e14fb3b87e1

📥 Commits

Reviewing files that changed from the base of the PR and between 3fd2e42 and 8dc4051.

📒 Files selected for processing (7)
  • .github/workflows/ci.yml
  • Cargo.toml
  • crates/core/Cargo.toml
  • crates/core/src/bin/taxonomy_linter.rs
  • crates/core/src/taxonomy/linter.rs
  • crates/core/src/taxonomy/mod.rs
  • scripts/lint_taxonomy.sh

@webdevayo

Copy link
Copy Markdown
Contributor Author

@codeZe-us CI is failing on Rust Checks due to a pre-existing issue on main, unrelated
to this PR: crates/core/src/decode/context.rs currently contains TypeScript
content instead of Rust (export class AppError extends Error {...}), which
breaks cargo fmt --all -- --check. This file needs to be restored to valid
Rust independently of this PR.

Confirmed via git diff upstream/main origin/feat/taxonomy-linter -- crates/core/src/decode/context.rs that this branch doesn't introduce or
touch this file — the content is identical to what's already on main.

Node & Web Checks passes cleanly on this PR.

@codeZe-us
codeZe-us self-requested a review July 29, 2026 14:37
@codeZe-us
codeZe-us merged commit 4149ba8 into Toolbox-Lab:main Jul 29, 2026
2 of 3 checks passed
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.

TaxonomyLinter: validate TOML against schema

2 participants