Skip to content

Test code quality rubric with static datasets (Meta-Evals)#194

Merged
reidbaker merged 10 commits into
flutter:mainfrom
reidbaker:feature/test-code-quality-rubric
Jul 24, 2026
Merged

Test code quality rubric with static datasets (Meta-Evals)#194
reidbaker merged 10 commits into
flutter:mainfrom
reidbaker:feature/test-code-quality-rubric

Conversation

@reidbaker-agent

Copy link
Copy Markdown
Contributor

Adds a static dataset of good and bad code and a meta-eval dummy skill to test that the code quality rubric successfully catches anti-patterns and permits clean code.

Addresses PR #189 feedback by moving to a static fixture approach instead of having the LLM generate bad code on the fly.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a comprehensive framework for evaluating AI agent skills, including a new run-evals skill, a test-rubric dummy skill for meta-evaluations, universal code quality rubrics, and a test suite to ensure structural consistency of evaluation files. Feedback focuses on making the newly added tests in skills_evals_test.dart more robust by dynamically resolving the package directory rather than relying directly on Directory.current, which can cause failures when tests are executed from the repository root.

Comment on lines +11 to +19
void main() {
group('Evals structure consistency', () {
// Ensures all evals.json files dynamically share the exact same JSON schema.
// Keys are not hardcoded to ensure enforcement remains schema-agnostic and flexible.
test('all evals.json files across skills share consistent structure and keys', () {
final List<File> evalsFiles = [
..._findEvalsFiles(Directory(p.join(Directory.current.path, 'skills'))),
..._findEvalsFiles(Directory(p.join(Directory.current.path, '.agents', 'skills'))),
]..sort((a, b) => a.path.compareTo(b.path));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

Using Directory.current directly can make tests fragile and fail when executed from the repository root (e.g., during CI/CD or monorepo tasks) rather than the package root (tool/dart_skills_lint).

We can resolve the package directory dynamically by checking if Directory.current points to the package root, and if not, appending the relative path.

Suggested change
void main() {
group('Evals structure consistency', () {
// Ensures all evals.json files dynamically share the exact same JSON schema.
// Keys are not hardcoded to ensure enforcement remains schema-agnostic and flexible.
test('all evals.json files across skills share consistent structure and keys', () {
final List<File> evalsFiles = [
..._findEvalsFiles(Directory(p.join(Directory.current.path, 'skills'))),
..._findEvalsFiles(Directory(p.join(Directory.current.path, '.agents', 'skills'))),
]..sort((a, b) => a.path.compareTo(b.path));
void main() {
final packageDir = Directory.current.path.endsWith('tool/dart_skills_lint')
? Directory.current
: Directory(p.join(Directory.current.path, 'tool', 'dart_skills_lint'));
group('Evals structure consistency', () {
// Ensures all evals.json files dynamically share the exact same JSON schema.
// Keys are not hardcoded to ensure enforcement remains schema-agnostic and flexible.
test('all evals.json files across skills share consistent structure and keys', () {
final List<File> evalsFiles = [
..._findEvalsFiles(Directory(p.join(packageDir.path, 'skills'))),
..._findEvalsFiles(Directory(p.join(packageDir.path, '.agents', 'skills'))),
]..sort((a, b) => a.path.compareTo(b.path));

// Note: We intentionally only require an evals.json file for published skills.
// Contributor skills in .agents/skills/ are not currently required to have one.
test('all published skills have an evals.json file', () {
final skillsDir = Directory(p.join(Directory.current.path, 'skills'));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

Use the dynamically resolved packageDir instead of Directory.current to ensure the test runs correctly from any working directory.

Suggested change
final skillsDir = Directory(p.join(Directory.current.path, 'skills'));
final skillsDir = Directory(p.join(packageDir.path, 'skills'));

});

test('all rubric JSON files in evals/ share consistent structure and keys', () {
final rubricsDir = Directory(p.join(Directory.current.path, 'evals'));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

Use the dynamically resolved packageDir instead of Directory.current to ensure the test runs correctly from any working directory.

Suggested change
final rubricsDir = Directory(p.join(Directory.current.path, 'evals'));
final rubricsDir = Directory(p.join(packageDir.path, 'evals'));

@reidbaker
reidbaker force-pushed the feature/test-code-quality-rubric branch from 352023e to 3104642 Compare July 23, 2026 19:01
Comment thread tool/dart_skills_lint/dart_skills_lint.yaml
@reidbaker-agent

Copy link
Copy Markdown
Contributor Author

Meta-Eval Run Results

I've successfully run the test-rubric evaluation against our static fixtures to prove the rubric works! The agent successfully graded both the positive and negative test cases.

🔴 Eval 1: Negative Test Case (bad_script.dart)

Input: A script intentionally violating our hygiene and idiom rules.
Agent Output: The agent correctly flagged the failures according to the rubric criteria:

  • effective_dart_and_idioms: Flagged the use of raw string concatenation (r'Hello ' + user) instead of string interpolation ('Hello $user').
  • cross_platform_compatibility: Flagged the hardcoded Windows path (C:\my\path\data.txt).
  • directory_and_placement_hygiene: Flagged that the script was improperly located in a scratch tmp/ directory instead of the standard bin/ directory.

The agent then successfully fixed the script, moved it to bin/, and ensured it passed dart analyze and tests.

🟢 Eval 2: Positive Test Case (good_script.dart)

Input: A completely clean, idiomatic Dart script in a compliant directory.
Agent Output: The agent correctly analyzed the file and reported that it fully conforms to the rubric criteria with 0 violations found.

The code_quality_rubric.json is robust and agents can successfully parse and apply its criteria!

@reidbaker-agent

Copy link
Copy Markdown
Contributor Author

Updated Meta-Eval Run Results

After updating the run-evals prompts to ensure agents do not fix static test fixtures during grading tasks, I ran the meta-evaluations against the test data again. The agents correctly graded the code without modifying the files!

🔴 Eval 1: Negative Test Case (bad_script.dart)

Input: A script intentionally violating our hygiene and idiom rules.
Agent Output: The agent correctly flagged the failures according to the rubric criteria without touching the code:

  • effective_dart_and_idioms: Fail - Flagged the use of raw strings alongside string concatenation.
  • cross_platform_compatibility: Fail - Flagged the hardcoded Windows path ('C:\my\path\data.txt').
  • directory_and_placement_hygiene: Fail - Flagged that the script was improperly located in tmp/ instead of a standard directory.
    (The agent correctly returned an empty git diff!)

🟢 Eval 2: Positive Test Case (good_script.dart)

Input: A clean, idiomatic Dart script.
Agent Output: The agent correctly evaluated the file without making modifications:

  • effective_dart_and_idioms: Pass
  • cross_platform_compatibility: Pass
  • directory_and_placement_hygiene: Pass
    (It did note a compilation failure strictly due to the test fixture missing a pubspec.yaml for the path dependency, but otherwise gave it a clean bill of health).

Both evaluations passed successfully according to the updated prompt instructions!

@reidbaker
reidbaker marked this pull request as ready for review July 23, 2026 22:21
@reidbaker
reidbaker self-requested a review July 23, 2026 22:21
@reidbaker

Copy link
Copy Markdown
Contributor

/gemini-review

@@ -0,0 +1,15 @@
// ignore_for_file: unused_local_variable, prefer_final_locals, avoid_print, use_raw_strings

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This file needs a copyright statement.

@@ -0,0 +1,15 @@
import 'package:path/path.dart' as p;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This file needs a copyright statement.

@reidbaker
reidbaker merged commit c5cb871 into flutter:main Jul 24, 2026
13 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.

2 participants