agentme 0.26.0 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -218,4 +218,6 @@ Return a JSON object with:
218
218
  - [agentme-edr-004](../principles/004-unit-test-requirements.md) — Unit test requirements including external API mocking guidance
219
219
  - [agentme-edr-014](014-python-project-tooling.md) — Python project tooling and structure
220
220
  - [agentme-edr-007](../principles/007-project-quality-standards.md) — Project quality standards including AI-tier testing requirements (rule `09-ai-project-testing-requirements`)
221
- - [agentme-edr-028](028-ai-eval-standards.md) — AI eval standards: folder structure, script requirements, and MLflow tracking
221
+ - [agentme-edr-028](028-ai-eval-core-standards.md) — AI eval core standards: eval folder structure (rule `01`) and LLM-as-judge binary scoring contract (rule `02`)
222
+ - [agentme-edr-031](031-ai-eval-script.md) — AI eval script: entry-first loop, `--type` filtering, `mock_fixtures`, and MLflow conventions
223
+ - [agentme-edr-032](032-ai-eval-report-format.md) — AI eval report format: `report-<type>.md` template, Wilson CI, and convergence analysis
@@ -179,4 +179,6 @@ def test_workflow_calls_subagent(mocker):
179
179
  - [agentme-edr-018](018-ai-llm-development-standards.md) — LLM development standards (LangChain configuration, mocking patterns)
180
180
  - [agentme-edr-026](026-pragmatic-hexagonal-architecture.md) — Hexagonal architecture (tool placement in adapters/connectors)
181
181
  - [agentme-edr-007](../principles/007-project-quality-standards.md) — Project quality standards including AI-tier testing requirements (rule `09-ai-project-testing-requirements`)
182
- - [agentme-edr-028](028-ai-eval-standards.md) — AI eval standards: folder structure, script requirements, and MLflow tracking
182
+ - [agentme-edr-028](028-ai-eval-core-standards.md) — AI eval core standards: eval folder structure (rule `01`) and LLM-as-judge binary scoring contract (rule `02`)
183
+ - [agentme-edr-031](031-ai-eval-script.md) — AI eval script: entry-first loop, `--type` filtering, `mock_fixtures`, and MLflow conventions
184
+ - [agentme-edr-032](032-ai-eval-report-format.md) — AI eval report format: `report-<type>.md` template, Wilson CI, and convergence analysis
@@ -37,7 +37,7 @@ Use **MLflow** for all workflow observability and evaluation:
37
37
 
38
38
  #### 04-dataset-driven-accuracy-measurement
39
39
 
40
- Projects MUST follow the eval dataset and implementation requirements defined in [agentme-edr-028](028-ai-eval-standards.md). Testing requirements (when evals are required, release gates) are defined in [agentme-edr-007](../principles/007-project-quality-standards.md) rule `09-ai-project-testing-requirements`.
40
+ Projects MUST follow the eval dataset and implementation requirements defined in [agentme-edr-028](028-ai-eval-core-standards.md) and [agentme-edr-031](031-ai-eval-script.md). Testing requirements (when evals are required, release gates) are defined in [agentme-edr-007](../principles/007-project-quality-standards.md) rule `09-ai-project-testing-requirements`.
41
41
 
42
42
  #### 05-flow-documentation
43
43
 
@@ -101,7 +101,7 @@ lib/src/<package_name>/
101
101
 
102
102
  #### 08-workflow-evals
103
103
 
104
- Projects MUST follow the eval folder structure and script requirements defined in [agentme-edr-028](028-ai-eval-standards.md).
104
+ Projects MUST follow the eval folder structure defined in [agentme-edr-028](028-ai-eval-core-standards.md) rule `01` and the eval script requirements defined in [agentme-edr-031](031-ai-eval-script.md). For LLM-as-judge scoring used in workflow verification nodes and evals, see [agentme-edr-028](028-ai-eval-core-standards.md) rule `02`.
105
105
 
106
106
  #### 09-node-naming-conventions
107
107
 
@@ -207,5 +207,8 @@ All workflow elements MUST maintain naming coherence as defined in [agentme-edr-
207
207
  - [agentme-edr-026](026-pragmatic-hexagonal-architecture.md) — Adapter/application layer separation that defines the project layout
208
208
  - [agentme-edr-014](014-python-project-tooling.md) — Python project tooling and structure
209
209
  - [agentme-edr-024](024-ml-dataset-structure.md) — ML dataset structure for eval datasets
210
- - [agentme-edr-028](028-ai-eval-standards.md) — AI eval standards: folder structure, script requirements, and MLflow tracking
210
+ - [agentme-edr-028](028-ai-eval-core-standards.md) — AI eval core standards: eval folder structure (rule `01`) and LLM-as-judge binary scoring contract for all tiers (rule `02`)
211
+ - [agentme-edr-031](031-ai-eval-script.md) — AI eval script: entry-first loop, `--type` filtering, `mock_fixtures`, and MLflow conventions
212
+ - [agentme-edr-032](032-ai-eval-report-format.md) — AI eval report format: `report-<type>.md` template, Wilson CI, and convergence analysis
213
+ - [agentme-edr-033](033-ai-eval-repeatability.md) — AI eval repeatability: REPEAT_COUNT loop, scoring methods, and release cadence
211
214
  - [agentme-edr-007](../principles/007-project-quality-standards.md) — Project quality standards including AI-tier testing requirements (rule `09-ai-project-testing-requirements`)
@@ -0,0 +1,120 @@
1
+ ---
2
+ name: agentme-edr-policy-028-ai-eval-core-standards
3
+ description: Defines the eval folder structure and Makefile interface for AI projects, and the LLM-as-judge binary scoring contract applicable to all AI tiers and test types. Use when scaffolding evals or implementing an LLM judge. For eval script requirements see agentme-edr-031. For report format see agentme-edr-032. For repeatability see agentme-edr-033. For when evals are required see agentme-edr-007 rule 09-ai-project-testing-requirements. For the test type taxonomy see agentme-edr-030.
4
+ apply-to: Python AI projects (LLM, Agent, or Workflow tier) that implement eval testing
5
+ valid-from: 2026-06-05
6
+ ---
7
+
8
+ # agentme-edr-policy-028: AI eval core standards
9
+
10
+ ## Context and Problem Statement
11
+
12
+ Eval tests measure AI component accuracy against expected outputs using real LLM providers. Without a shared folder layout and a common LLM judge contract, eval setups diverge across LLM, Agent, and Workflow projects, making them hard to scaffold, run, and compare.
13
+
14
+ How should eval tests be structured, and how must LLM judges produce scores across all AI tiers?
15
+
16
+ ## Decision Outcome
17
+
18
+ **Use a per-component folder structure under `evals/` with a standardized Makefile interface, and require all LLM judges to produce binary (`0`/`1`) output compatible with classification metrics.**
19
+
20
+ For when evals are required per AI tier, see [agentme-edr-007](../principles/007-project-quality-standards.md) rule `09-ai-project-testing-requirements`.
21
+
22
+ ### Details
23
+
24
+ #### 01-eval-folder-structure
25
+
26
+ Evals are grouped first by the component being evaluated, then by the specific evaluation scenario. Create one directory per component under `evals/`, and one directory per eval scenario inside it. Place `evals/` at the same level as `lib/` and `examples/`:
27
+
28
+ ```text
29
+ evals/
30
+ <component>/ # the component being evaluated (e.g., workflow-x, agent-y, model-z)
31
+ eval-<name>/
32
+ golden_dataset/ # EDR-024 + EDR-030 compliant golden dataset (README.md, dataset.schema.json, data/)
33
+ eval.py # evaluation script
34
+ report-<type>.md # generated report, one per evaluated test type (overwritten on each run — see agentme-edr-032 rule 01)
35
+ Makefile # lint, eval, run, and eval-<type> targets
36
+ eval-<name2>/
37
+ ...
38
+ <component2>/
39
+ ...
40
+ ```
41
+
42
+ `<component>` MUST match the name of the component under evaluation and use lowercase hyphen-separated words (e.g., `workflow-document-review`, `agent-support`, `model-classifier`).
43
+
44
+ `<name>` identifies the specific evaluation scenario using lowercase hyphen-separated words (e.g., `eval-basic`, `eval-complex`, `eval-edge-cases`). A scenario's `golden_dataset` MAY mix multiple test types across its entries: label each entry with its applicable `test_types` ([agentme-edr-030](030-ai-test-types-taxonomy.md) rule `04`) and use the `eval-<type>` targets below to run one type at a time.
45
+
46
+ The `golden_dataset/` subfolder MUST be a valid [agentme-edr-024](024-ml-dataset-structure.md) dataset (`README.md`, `dataset.schema.json`, one JSON file per entry under `data/` per rule `04-complex-structured-datasets-must-use-per-entry-json-files`, lint-validated per rule `06`) whose entries follow the golden dataset envelope defined in [agentme-edr-030](030-ai-test-types-taxonomy.md) rule `02`.
47
+
48
+ Each `evals/<component>/eval-<name>/Makefile` MUST declare a `TEST_TYPES` variable listing the `test_types` values present in its golden dataset, and define:
49
+
50
+ | Target | Behaviour |
51
+ |---|---|
52
+ | `lint` | Validates every `golden_dataset/data/*.json` file against `golden_dataset/dataset.schema.json` per [agentme-edr-024](024-ml-dataset-structure.md) rule `06` |
53
+ | `eval` | Depends on `lint`; runs `eval.py --type=all` with threshold enforcement; exits non-zero on failure (CI-safe) |
54
+ | `run` | Depends on `lint`; runs `eval.py --type=all` with threshold enforcement; same as `eval` but intended for local exploration |
55
+ | `eval-<type>` | Depends on `lint`; runs `eval.py --type=<type>` for one declared test type, following [agentme-edr-008](../devops/008-common-targets.md) rule `03`'s `eval-<qualifier>` convention |
56
+
57
+ ```makefile
58
+ TEST_TYPES := smoke functional safety
59
+
60
+ lint:
61
+ mise exec -- uv run --project . python lint_dataset.py golden_dataset/
62
+
63
+ eval: lint
64
+ mise exec -- uv run --project . python eval.py --type=all
65
+
66
+ run: lint
67
+ mise exec -- uv run --project . python eval.py --type=all
68
+
69
+ eval-%: lint
70
+ mise exec -- uv run --project . python eval.py --type=$*
71
+ ```
72
+
73
+ The module root Makefile MUST expose `make eval` and `make lint` targets that delegate to `eval` and `lint` respectively in every `evals/<component>/eval-<name>/Makefile`:
74
+
75
+ ```makefile
76
+ eval:
77
+ $(MAKE) -C evals/workflow-document-review/eval-basic eval
78
+ $(MAKE) -C evals/workflow-document-review/eval-complex eval
79
+
80
+ lint:
81
+ $(MAKE) -C evals/workflow-document-review/eval-basic lint
82
+ $(MAKE) -C evals/workflow-document-review/eval-complex lint
83
+ ```
84
+
85
+ #### 02-llm-as-judge-binary-output
86
+
87
+ LLM judges scoring component outputs MUST produce binary output: `0` (fail) or `1` (success). This rule applies to all AI tiers (LLM, Agent, Workflow) and to all eval test types that use an LLM judge (functional, quality, safety, repeatability, or any other).
88
+
89
+ **Requirements:**
90
+
91
+ - Judge prompts MUST instruct the model to output exactly `0` or `1`
92
+ - Scoring logic MUST parse the response and map to binary. Ambiguous/invalid responses: score as `0` or raise error
93
+ - Reports using LLM judges MUST use classification metrics (Accuracy, F1, Precision, Recall), not regression metrics (RMSE, R2, MAE)
94
+ - Multi-class classification not supported. For multiple quality levels, use multiple binary judges (e.g., one for "factually correct", another for "tone appropriate")
95
+
96
+ **Rationale:** Binary output makes LLM judges compatible with classification metrics infrastructure (Accuracy, F1, Wilson CI, convergence analysis) defined in [agentme-edr-032](032-ai-eval-report-format.md) rule `01`.
97
+
98
+ **Example LLM judge prompt:**
99
+
100
+ ```
101
+ Evaluate whether the document review decision is correct.
102
+
103
+ Input: {input_summary}
104
+ Expected: {expected_decision}
105
+ Actual: {actual_decision}
106
+
107
+ Output exactly "1" if the actual decision matches the expected decision and reasoning, or "0" if it does not.
108
+
109
+ Output:
110
+ ```
111
+
112
+ ## References
113
+
114
+ - [agentme-edr-031](031-ai-eval-script.md) — AI eval script: entry-first eval loop, `--type` filtering, `mock_fixtures`, and MLflow conventions
115
+ - [agentme-edr-032](032-ai-eval-report-format.md) — AI eval report format: `report-<type>.md` template, Wilson CI, and convergence analysis
116
+ - [agentme-edr-033](033-ai-eval-repeatability.md) — AI eval repeatability: loop exception, scoring methods (including LLM-as-judge per rule `02`), and cadence
117
+ - [agentme-edr-007](../principles/007-project-quality-standards.md) — Project quality standards: when evals are required per AI tier (rule `09`) and statistical model eval targets (rule `07`)
118
+ - [agentme-edr-030](030-ai-test-types-taxonomy.md) — AI test types taxonomy: `test_types` enum and golden dataset entry envelope
119
+ - [agentme-edr-024](024-ml-dataset-structure.md) — ML dataset structure, per-entry JSON format, and schema-lint validation for golden datasets
120
+ - [agentme-edr-008](../devops/008-common-targets.md) — `eval-<qualifier>` Makefile convention (rule `03`)
@@ -21,7 +21,7 @@ Each test type is named with its group, objective, mocking constraint, applicabi
21
21
 
22
22
  #### 01-golden-dataset-concept
23
23
 
24
- Projects MUST use a golden dataset to test AI components. A **golden dataset** comprises all eval case entries used to test an AI component (LLM, Agent, or Workflow tier); each entry is labeled with the `test_types` (rule `04`) it applies to. It is the dataset consumed by [agentme-edr-028](028-ai-eval-standards.md) evals and stored as one JSON file per entry per [agentme-edr-024](024-ml-dataset-structure.md) rule `04`, at `evals/<component>/eval-<name>/golden_dataset/`.
24
+ Projects MUST use a golden dataset to test AI components. A **golden dataset** comprises all eval case entries used to test an AI component (LLM, Agent, or Workflow tier); each entry is labeled with the `test_types` (rule `04`) it applies to. It is the dataset consumed by [agentme-edr-031](031-ai-eval-script.md) evals and stored as one JSON file per entry per [agentme-edr-024](024-ml-dataset-structure.md) rule `04`, at `evals/<component>/eval-<name>/golden_dataset/`.
25
25
 
26
26
  #### 02-golden-dataset-entry-envelope
27
27
 
@@ -47,52 +47,70 @@ Every golden dataset entry (a JSON file in `golden_dataset/data/`) MUST have thi
47
47
 
48
48
  #### 03-mocks-allowed-values
49
49
 
50
- The taxonomy in rule `05` rates each test type using one of three values:
50
+ The taxonomy in rule `05` rates each test type using one of three values under the `Mock Constraint` column:
51
51
 
52
52
  | Value | Meaning |
53
53
  |---|---|
54
- | `mocks allowed` | Fully offline; fakes may replace every dependency (e.g. `FakeListChatModel` per [agentme-edr-018](018-ai-llm-development-standards.md) rule `04`). |
55
- | `mocks disallowed` | No mocking of any dependency — real external systems required. |
56
- | `mocks disallowed for LLM calls` | Tools and other external/dependency calls MAY be mocked; only the LLM call itself MUST be real for the test to be meaningful. |
54
+ | `mocks allowed` | Fully offline; fakes may replace every dependency including the LLM (e.g. `FakeListChatModel` per [agentme-edr-018](018-ai-llm-development-standards.md) rule `04`). Used only for code-level unit tests. |
55
+ | `mocks disallowed` | No mocking of any dependency — all real external systems required. Used for integration tests. |
56
+ | `mocks disallowed for LLM calls` | **The LLM call MUST be real; all other external dependencies (databases, APIs, external services) MAY and SHOULD be mocked via `mock_fixtures`.** `mock_fixtures` keys MUST NOT reference LLM adapters. This is the standard constraint for every golden-dataset eval test type. See rule `08` for rationale. |
57
57
 
58
58
  #### 04-test-types-enum
59
59
 
60
- A golden dataset entry's `test_types` array MUST only use these values: `safety`, `adversarial`, `fairness`, `bias`, `robustness`, `explainability`, `groundedness`, `functional`, `prompt`, `smoke`, `human`. These correspond to the dataset-driven rows of rule `05`. **Unit test** and **Integration test** (the two Code-level rows) are NOT part of this enum — they have no golden dataset entries and remain governed entirely by [agentme-edr-004](../principles/004-unit-test-requirements.md) and [agentme-edr-007](../principles/007-project-quality-standards.md) rule `08`.
60
+ A golden dataset entry's `test_types` array MUST only use these values: `safety`, `adversarial`, `fairness`, `bias`, `robustness`, `explainability`, `groundedness`, `functional`, `prompt`, `smoke`, `human`, `repeatability`. These correspond to the dataset-driven rows of rule `05`. **Unit test** and **Integration test** (the two Code-level rows) are NOT part of this enum — they have no golden dataset entries and remain governed entirely by [agentme-edr-004](../principles/004-unit-test-requirements.md) and [agentme-edr-007](../principles/007-project-quality-standards.md) rule `08`.
61
61
 
62
62
  #### 05-test-type-taxonomy
63
63
 
64
64
  Test types MUST be selected from this taxonomy. Each test type is named with its group, objective, mocking constraint, applicability, and relevance:
65
65
 
66
- | Test Type Name | Group | Test Objective | Mocks Allowed | When to Apply | Relevance – Business | Relevance – Development Team | Priority (1-5) |
67
- |---|---|---|---|---|---|---|---|
68
- | Safety/content eval | Safety & adversarial | Detect harmful, biased, or policy-violating output | mocks disallowed for LLM calls | Any user-facing release | Avoids reputational harm; acceptable-use compliance | Automated content gate before merge/release | 5 |
69
- | Adversarial/red-team test | Safety & adversarial | Probe for prompt injection, jailbreaks, unsafe tool use | mocks disallowed for LLM calls | System exposes tool-invocation or agent loops | Reduces security-incident/breach liability | Finds exploitable tool-loop paths before attackers do | 5 |
70
- | Fairness test | Responsible AI | Verify equitable outcomes across user groups | mocks disallowed for LLM calls | Output affects decisions about individuals/groups | Regulatory requirement; protects equitable access | Surfaces uneven outcomes before release | 4 |
71
- | Bias test | Responsible AI | Detect skewed or stereotyped associations | mocks disallowed for LLM calls | User-facing content generation | Lowers legal/reputational exposure | Catches bias introduced by data/prompts/fine-tuning | 3 |
72
- | Robustness test | Responsible AI | Verify stable behavior under noisy/out-of-distribution input | mocks disallowed for LLM calls | Inputs come from untrusted/variable sources | Protects reliability/SLAs | Confirms graceful degradation, guides input validation | 3 |
73
- | Explainability test | Responsible AI | Verify output is justifiable with a faithful rationale | mocks disallowed for LLM calls | Output must be justified to users/auditors/regulators | Required for auditability; builds user trust | Gives rationale trace for debugging wrong answers | 2 |
74
- | Groundedness (RAG) eval | Quality eval | Verify the answer is supported by retrieved context | mocks disallowed for LLM calls | System uses retrieval-augmented generation | Avoids confidently-wrong answers reaching customers | Pinpoints retrieval/prompt bugs | 4 |
75
- | Human evaluation | Quality eval | Manually verify aspects automated scoring can't (ethics, side effects, external state) | mocks disallowed for LLM calls | Before major releases; periodic spot-check | Defensible, human-reviewed sign-off | Catches what automated metrics miss | 3 |
76
- | Functional eval (golden-dataset accuracy / LLM-as-judge) | Quality eval | Measure output correctness against the golden dataset | mocks disallowed for LLM calls | Required before every Workflow release ([agentme-edr-007](../principles/007-project-quality-standards.md) rule `09`); advised elsewhere | Auditable evidence of business correctness before release | Detects regressions from model/provider/prompt changes | 5 |
77
- | Smoke test | Quality eval | Fast pass/fail check on a small, critical subset before running fuller suites | mocks disallowed for LLM calls | Every commit/PR, before functional/responsible-AI evals run | Cheap early warning before slower evals run | Fast, cheap feedback loop | 4 |
78
- | Prompt regression test | Prompt/LLM | Detect behavior change when a prompt or model version changes | mocks disallowed for LLM calls | Whenever a prompt template or model version changes | Prevents shipping a worse experience via a "small" tweak | Fast check on every prompt edit | 3 |
79
- | Integration test | Code-level | Verify real interaction with external systems | mocks disallowed | Component depends on external systems | Reduces production outages from integration mismatches | Catches wiring bugs unit tests can't see | 2 |
80
- | Unit test (offline, mocked) | Code-level | Verify deterministic logic in isolation, offline | mocks allowed | Required for Workflow tier every commit ([agentme-edr-007](../principles/007-project-quality-standards.md) rule `09`) | Lowest-cost point to catch defects | Fastest, fully offline feedback on every commit | 5 |
66
+ | Test Type Name | `test_types` value | Group | Test Objective | Mock Constraint | When to Apply | Relevance – Business | Relevance – Development Team | Priority (1-5) |
67
+ |---|---|---|---|---|---|---|---|---|
68
+ | Safety/content eval | `safety` | Safety & adversarial | Detect harmful, biased, or policy-violating output | mocks disallowed for LLM calls | Any user-facing release | Avoids reputational harm; acceptable-use compliance | Automated content gate before merge/release | 5 |
69
+ | Adversarial/red-team test | `adversarial` | Safety & adversarial | Probe for prompt injection, jailbreaks, unsafe tool use | mocks disallowed for LLM calls | System exposes tool-invocation or agent loops | Reduces security-incident/breach liability | Finds exploitable tool-loop paths before attackers do | 5 |
70
+ | Fairness test | `fairness` | Responsible AI | Verify equitable outcomes across user groups | mocks disallowed for LLM calls | Output affects decisions about individuals/groups | Regulatory requirement; protects equitable access | Surfaces uneven outcomes before release | 4 |
71
+ | Bias test | `bias` | Responsible AI | Detect skewed or stereotyped associations | mocks disallowed for LLM calls | User-facing content generation | Lowers legal/reputational exposure | Catches bias introduced by data/prompts/fine-tuning | 3 |
72
+ | Robustness test | `robustness` | Responsible AI | Verify stable behavior under noisy/out-of-distribution input | mocks disallowed for LLM calls | Inputs come from untrusted/variable sources | Protects reliability/SLAs | Confirms graceful degradation, guides input validation | 3 |
73
+ | Explainability test | `explainability` | Responsible AI | Verify output is justifiable with a faithful rationale | mocks disallowed for LLM calls | Output must be justified to users/auditors/regulators | Required for auditability; builds user trust | Gives rationale trace for debugging wrong answers | 2 |
74
+ | Groundedness (RAG) eval | `groundedness` | Quality eval | Verify the answer is supported by retrieved context | mocks disallowed for LLM calls | System uses retrieval-augmented generation | Avoids confidently-wrong answers reaching customers | Pinpoints retrieval/prompt bugs | 4 |
75
+ | Repeatability test | `repeatability` | Quality eval | Verify output stability/variance across N repeated invocations of the same input under fixed configuration | mocks disallowed for LLM calls | Non-deterministic components (temperature > 0, agentic tool-selection loops, sampling-based decoding) used in decision-critical or user-facing flows | Protects against silently flaky behavior reaching production; supports consistency SLAs | Detects prompt/agent designs too sensitive to sampling noise; informs temperature/seed tuning | 3 |
76
+ | Human evaluation | `human` | Quality eval | Manually verify aspects automated scoring can't (ethics, side effects, external state) | mocks disallowed for LLM calls | Before major releases; periodic spot-check | Defensible, human-reviewed sign-off | Catches what automated metrics miss | 3 |
77
+ | Functional eval (golden-dataset accuracy / LLM-as-judge) | `functional` | Quality eval | Measure output correctness against the golden dataset | mocks disallowed for LLM calls | Required before every Workflow release ([agentme-edr-007](../principles/007-project-quality-standards.md) rule `09`); advised elsewhere | Auditable evidence of business correctness before release | Detects regressions from model/provider/prompt changes | 5 |
78
+ | Smoke test | `smoke` | Quality eval | Fast pass/fail check on a small, critical subset before running fuller suites | mocks disallowed for LLM calls | Every commit/PR, before functional/responsible-AI evals run | Cheap early warning before slower evals run | Fast, cheap feedback loop | 4 |
79
+ | Prompt regression test | `prompt` | Prompt/LLM | Detect behavior change when a prompt or model version changes | mocks disallowed for LLM calls | Whenever a prompt template or model version changes | Prevents shipping a worse experience via a "small" tweak | Fast check on every prompt edit | 3 |
80
+ | Integration test | n/a — code-level only (see rule `04`) | Code-level | Verify real interaction with external systems | mocks disallowed | Component depends on external systems | Reduces production outages from integration mismatches | Catches wiring bugs unit tests can't see | 2 |
81
+ | Unit test (offline, mocked) | n/a — code-level only (see rule `04`) | Code-level | Verify deterministic logic in isolation, offline | mocks allowed | Required for Workflow tier every commit ([agentme-edr-007](../principles/007-project-quality-standards.md) rule `09`) | Lowest-cost point to catch defects | Fastest, fully offline feedback on every commit | 5 |
81
82
 
82
83
  #### 06-priority-and-relevance-are-descriptive-only
83
84
 
84
- Priority, Relevance, and When to Apply in rule `05` are guidance for prioritization conversations — they MUST NOT be treated as mandating which test types a project must implement, nor their thresholds. [agentme-edr-007](../principles/007-project-quality-standards.md) rule `09` remains the only tier-level testing requirement in force (Workflow unit tests + functional evals). Once a project chooses to implement and threshold a test type, [agentme-edr-028](028-ai-eval-standards.md) rule `02`'s failing-threshold behavior applies uniformly, regardless of this table's priority rating — a project may enforce fairness at 70% and functional at 90%, or skip fairness entirely; that choice is a project/business decision, not one this Policy makes.
85
+ Priority, Relevance, and When to Apply in rule `05` are guidance for prioritization conversations — they MUST NOT be treated as mandating which test types a project must implement, nor their thresholds. [agentme-edr-007](../principles/007-project-quality-standards.md) rule `09` remains the only tier-level testing requirement in force (Workflow unit tests + functional evals). Once a project chooses to implement and threshold a test type, [agentme-edr-031](031-ai-eval-script.md) rule `01`'s failing-threshold behavior applies uniformly, regardless of this table's priority rating — a project may enforce fairness at 70% and functional at 90%, or skip fairness entirely; that choice is a project/business decision, not one this Policy makes.
85
86
 
86
87
  #### 07-smoke-is-distinct-from-test-smoke
87
88
 
88
89
  The `smoke` test type (surfaced as the `eval-smoke` Makefile target, a fast subset of the golden-dataset functional eval) is a different concept from [agentme-edr-008](../devops/008-common-targets.md)'s existing `test-smoke` target (a fast subset of code-level tests). Both MAY exist in the same project; teams MUST NOT conflate them.
89
90
 
91
+ #### 08-eval-mocking-constraint
92
+
93
+ For every golden-dataset eval test type: **the LLM call MUST be real; all other external dependencies MUST be mocked via `mock_fixtures`.** This applies equally to `human` entries — the component is invoked to capture `actual_output` and external dependencies must be deterministic. `mock_fixtures` keys MUST NOT reference LLM adapters. Code-level unit tests are the correct place for fully offline, LLM-mocked testing (see [agentme-edr-018](018-ai-llm-development-standards.md) rule `04`).
94
+
95
+ #### 09-repeatability-vs-reproducibility
96
+
97
+ | Property | Definition | What varies | Measured by |
98
+ |---|---|---|---|
99
+ | **Repeatability** | Output stability across N invocations at non-zero temperature | Model sampling variance | `repeatability` test type per [agentme-edr-033](033-ai-eval-repeatability.md) |
100
+ | **Reproducibility** | Deterministic output at temperature = 0 with fixed seed | Nothing — any variance is a config bug | Not a golden-dataset type; verified via config, documented in [agentme-edr-027](../devops/027-environment-variable-configuration.md) |
101
+
102
+ A component may satisfy reproducibility (temperature = 0) yet still need repeatability tests for its production configuration (temperature > 0). The `repeatability` test type MUST NOT be applied to components with intentionally diverse output (brainstorming, creative generation) — variance is correct behavior there.
103
+
90
104
  ## References
91
105
 
92
106
  - [agentme-edr-024](024-ml-dataset-structure.md) — Golden dataset file layout, per-entry JSON format, `$schema` pointer, and schema-lint validation
93
- - [agentme-edr-028](028-ai-eval-standards.md) — Eval folder structure, `--type` filtering, per-type Makefile targets, and per-type reports that consume this taxonomy
107
+ - [agentme-edr-028](028-ai-eval-core-standards.md) — AI eval core standards: eval folder structure and Makefile targets (rule `01`); LLM-as-judge binary scoring contract (rule `02`)
108
+ - [agentme-edr-031](031-ai-eval-script.md) — AI eval script: `--type` filtering, entry-first loop, `mock_fixtures`, threshold enforcement, and MLflow conventions
109
+ - [agentme-edr-032](032-ai-eval-report-format.md) — AI eval report format: per-type `report-<type>.md` that consumes this taxonomy's test types
110
+ - [agentme-edr-033](033-ai-eval-repeatability.md) — AI eval repeatability: `REPEAT_COUNT` loop exception, scoring constants (`EVAL_MIN_ACCURACY_REPEATABILITY`, `REPEAT_SEMANTIC_SIMILARITY_SCORE`), scoring methods, `repeatability_accuracy` MLflow metric, report shape, and run cadence
94
111
  - [agentme-edr-026](026-pragmatic-hexagonal-architecture.md) — Rule `10`: `_mock` file naming and placement convention for mock adapters referenced by `mock_fixtures`
95
112
  - [agentme-edr-007](../principles/007-project-quality-standards.md) — Rule `09` tier-level testing requirements (the only mandated AI testing baseline)
96
113
  - [agentme-edr-008](../devops/008-common-targets.md) — Rule `03` `eval-<qualifier>` Makefile convention; rule `03`'s `test-smoke` (distinguished in rule `07`)
114
+ - [agentme-edr-027](../devops/027-environment-variable-configuration.md) — Environment-configuration conventions referenced in rule `09`'s reproducibility disambiguation
97
115
  - [agentme-edr-018](018-ai-llm-development-standards.md) — LLM tier definition and mocking utilities referenced by the `mocks allowed` value
98
116
  - [agentme-edr-004](../principles/004-unit-test-requirements.md) — Unit test requirements underlying the Code-level rows
@@ -0,0 +1,136 @@
1
+ ---
2
+ name: agentme-edr-policy-031-ai-eval-script
3
+ description: Defines eval.py script requirements for AI projects — entry-first eval loop, --type test-type filtering, mock_fixtures wiring, human entries, threshold enforcement, and MLflow experiment naming and port assignment. Use when implementing eval scripts. For eval folder structure see agentme-edr-028 rule 01. For the test type taxonomy and mock_fixtures envelope see agentme-edr-030. For mock file naming see agentme-edr-026 rule 10. For report format see agentme-edr-032. For repeatability loop exception see agentme-edr-033.
4
+ apply-to: Python AI projects (LLM, Agent, or Workflow tier) that implement eval testing
5
+ valid-from: 2026-07-07
6
+ ---
7
+
8
+ # agentme-edr-policy-031: AI eval script
9
+
10
+ ## Context and Problem Statement
11
+
12
+ Eval scripts execute entries from a golden dataset against a real AI component and measure output quality. Without a shared script contract, eval implementations diverge: some invoke components multiple times per entry (wasting LLM cost), some skip mock isolation, and some omit threshold enforcement — making results inconsistent and hard to trust across projects.
13
+
14
+ How should eval scripts load datasets, iterate entries, handle mocking, and produce metrics?
15
+
16
+ ## Decision Outcome
17
+
18
+ **Use an entry-first eval loop with `--type` filtering, fresh mock isolation per entry, real LLM providers, and MLflow-backed metrics with explicit per-type thresholds.**
19
+
20
+ For when evals are required per AI tier, see [agentme-edr-007](../principles/007-project-quality-standards.md) rule `09-ai-project-testing-requirements`.
21
+
22
+ ### Details
23
+
24
+ #### 01-eval-script-requirements
25
+
26
+ Each `eval.py` script MUST:
27
+
28
+ - Load the golden dataset from `golden_dataset/` in the same eval folder, following [agentme-edr-024](024-ml-dataset-structure.md) and the entry envelope in [agentme-edr-030](030-ai-test-types-taxonomy.md) rule `02` (one JSON file per entry, `test_types` array, `input`, `expected_output`, optional `mock_fixtures`).
29
+ - Accept a required `--type=<test_type>|all` CLI argument and filter entries whose `test_types` array contains the requested value; `--type=all` includes every entry.
30
+ - Iterate **entry-first**: for each entry in the filtered set, invoke the real component exactly once; then score that single `actual_output` for every `test_types` value the entry carries that falls within the current `--type` scope — MUST NOT invoke the component more than once per entry per run.
31
+ - When an entry contains `mock_fixtures` ([agentme-edr-030](030-ai-test-types-taxonomy.md) rule `02`), configure each named mock adapter with its fixture data BEFORE invoking the component for that entry. Each entry MUST use fresh mock instances so fixture state does not bleed across entries. `mock_fixtures` applies to all test types including `human`. `mock_fixtures` MUST NOT configure LLM adapters — the LLM call MUST be real (see [agentme-edr-030](030-ai-test-types-taxonomy.md) rule `03`). How mock adapters are discovered and instantiated is left to the project; see [agentme-edr-026](026-pragmatic-hexagonal-architecture.md) rule `10` for the `_mock` file naming and placement convention.
32
+ - Run every component invocation against **real LLM providers** (not mocked responses), to capture model drift.
33
+ - For `human` entries: invoke the component to capture `actual_output`, export each entry's `input`, `expected_output.human_test` instructions, and `actual_output` into a manual-review checklist (`report-human.md`). MUST NOT invoke an automated scorer and MUST NOT enforce a pass/fail threshold for it. Other `test_types` on the same entry (e.g. `functional`) are still scored automatically.
34
+ - After all entries are processed, compute aggregate metrics per test type, log them to a local MLflow experiment (see rule `02`), write one `report-<type>.md` per evaluated test type ([agentme-edr-032](032-ai-eval-report-format.md) rule `01`), and exit with a non-zero status when any metric falls below its defined threshold per [agentme-edr-007](../principles/007-project-quality-standards.md) rule `07-statistical-models-must-have-eval-targets`. The `human` type has no threshold and does not trigger a non-zero exit.
35
+ - Compare outputs to expected values using project-defined quality thresholds per test type. Thresholds and all other scoring parameters MUST be declared as constants in `eval.py` — they are design decisions about what constitutes acceptable quality for the component under test, not runtime configuration, and MUST NOT be passed via Makefile variables or CLI flags. Use one of two naming conventions, chosen consistently within an `eval.py`: (a) **per-type constants** — `EVAL_MIN_<METRIC>_<TYPE>` for each test type (e.g. `EVAL_MIN_ACCURACY_FUNCTIONAL = 0.85`, `EVAL_MIN_ACCURACY_REPEATABILITY = 0.8`); or (b) **dict constant** — `EVAL_MIN_<METRIC> = {<type>: <value>}` (e.g. `EVAL_MIN_ACCURACY = {"functional": 0.85, "smoke": 0.85}`). Per-type constants are preferred when each test type has a dedicated `eval.py`; the dict form is preferred when a single `eval.py` handles multiple types. In either convention, `EVAL_MIN_ACCURACY` (as a scalar) MAY be declared as a project-wide default and MUST be used as fallback when no per-type override is defined for the current test type. This Policy does not mandate which test types a project must threshold or what value to use (see [agentme-edr-030](030-ai-test-types-taxonomy.md) rule `06`).
36
+
37
+ **Example:**
38
+
39
+ ```python
40
+ import argparse
41
+ from collections import defaultdict
42
+ import mlflow
43
+ from my_package.app.workflows.document_review_workflow.graph import graph
44
+
45
+ # Per-type constants; fall back to EVAL_MIN_ACCURACY default when no override is defined
46
+ EVAL_MIN_ACCURACY = 0.85 # project-wide default
47
+ EVAL_MIN_ACCURACY_FUNCTIONAL = 0.85
48
+ EVAL_MIN_ACCURACY_SMOKE = 0.90
49
+ EVAL_MIN_ACCURACY_PER_TYPE = {"functional": EVAL_MIN_ACCURACY_FUNCTIONAL, "smoke": EVAL_MIN_ACCURACY_SMOKE}
50
+
51
+ def get_min_accuracy(test_type: str) -> float:
52
+ return EVAL_MIN_ACCURACY_PER_TYPE.get(test_type, EVAL_MIN_ACCURACY)
53
+
54
+ parser = argparse.ArgumentParser()
55
+ parser.add_argument("--type", required=True)
56
+ args = parser.parse_args()
57
+
58
+ entries = load_golden_dataset("golden_dataset/", test_type=args.type) # "all" loads every entry
59
+ resolved_types = resolve_types(args.type, entries)
60
+
61
+ mlflow.set_experiment("document-review/eval-basic")
62
+
63
+ with mlflow.start_run():
64
+ mlflow.set_tag("test_types", ",".join(sorted(resolved_types)))
65
+
66
+ results = defaultdict(list)
67
+ cumulative_metrics = defaultdict(lambda: {"accuracy": [], "f1": []}) # Track cumulative metrics
68
+
69
+ # Entry-first loop: invoke each entry exactly once
70
+ for idx, entry in enumerate(entries, start=1):
71
+ # Configure mock adapters from mock_fixtures before invocation
72
+ # (implementation left to the project — see agentme-edr-026 rule 10)
73
+ if entry.get("mock_fixtures"):
74
+ configure_mocks(entry["mock_fixtures"]) # project-defined helper
75
+
76
+ actual_output = invoke_component(entry, graph)
77
+
78
+ for test_type in [t for t in entry["test_types"] if t in resolved_types]:
79
+ if test_type == "human":
80
+ export_human_review(entry, actual_output)
81
+ continue
82
+
83
+ score_val = score(test_type, actual_output, entry["expected_output"])
84
+ results[test_type].append(score_val)
85
+
86
+ # Track cumulative metrics for convergence analysis
87
+ cumulative_accuracy = sum(results[test_type]) / len(results[test_type])
88
+ cumulative_f1 = compute_f1(results[test_type]) # project-defined
89
+ cumulative_metrics[test_type]["accuracy"].append(cumulative_accuracy)
90
+ cumulative_metrics[test_type]["f1"].append(cumulative_f1)
91
+
92
+ # Aggregate, report, and enforce thresholds per test type
93
+ for test_type in resolved_types:
94
+ if test_type == "human":
95
+ continue
96
+
97
+ accuracy = sum(results[test_type]) / len(results[test_type])
98
+ mlflow.log_metric(f"{test_type}_accuracy", accuracy)
99
+
100
+ # Generate convergence analysis
101
+ stability_window = min(10, len(results[test_type]))
102
+ acc_change = abs(cumulative_metrics[test_type]["accuracy"][-1] -
103
+ cumulative_metrics[test_type]["accuracy"][-stability_window])
104
+ f1_change = abs(cumulative_metrics[test_type]["f1"][-1] -
105
+ cumulative_metrics[test_type]["f1"][-stability_window])
106
+
107
+ write_eval_report(
108
+ test_type,
109
+ results[test_type],
110
+ cumulative_metrics=cumulative_metrics[test_type],
111
+ stability_window=stability_window,
112
+ thresholds={"accuracy": get_min_accuracy(test_type)}
113
+ )
114
+
115
+ if accuracy < get_min_accuracy(test_type):
116
+ raise SystemExit(f"Eval failed: {test_type} accuracy {accuracy:.2f} < {get_min_accuracy(test_type)}")
117
+ ```
118
+
119
+ #### 02-eval-mlflow-unique-port
120
+
121
+ Each `evals/<component>/eval-<name>/Makefile` MUST start its MLflow tracking server on a **unique port** to prevent conflicts when multiple eval Makefiles are run concurrently or in parallel (e.g., in CI or across multiple terminal sessions).
122
+
123
+ Ports MUST be statically assigned per eval scenario (not per test type) and MUST NOT reuse the default `5000` port (reserved for `dev-mlflow` per [agentme-edr-008](../devops/008-common-targets.md) rule `09-ai-project-dev-targets`). Assign ports starting at `5100` and incrementing by 1 for each additional eval scenario across the entire project.
124
+
125
+ The MLflow **experiment** is scoped to the eval scenario: `<component>/<eval-name>` (e.g. `document-review/eval-basic`). Each `mlflow.start_run()` call MUST set a `test_types` tag listing the test types evaluated in that invocation (comma-separated, e.g. `"functional,smoke"` for `--type=all`, `"smoke"` for `--type=smoke`). A remote MLflow server MUST NOT be required — all tracking is local.
126
+
127
+ ## References
128
+
129
+ - [agentme-edr-028](028-ai-eval-core-standards.md) — AI eval core standards: eval folder structure (rule `01`) and LLM-as-judge binary scoring contract (rule `02`)
130
+ - [agentme-edr-032](032-ai-eval-report-format.md) — AI eval report format: `report-<type>.md` template, Wilson CI, and convergence analysis
131
+ - [agentme-edr-033](033-ai-eval-repeatability.md) — AI eval repeatability: loop exception to rule `01`'s entry-first constraint, scoring methods, and cadence
132
+ - [agentme-edr-030](030-ai-test-types-taxonomy.md) — AI test types taxonomy: `test_types` enum, golden dataset entry envelope (including `mock_fixtures`), and mocking constraints per type
133
+ - [agentme-edr-026](026-pragmatic-hexagonal-architecture.md) — Rule `10`: `_mock` file naming and placement convention for mock adapters used in `mock_fixtures`
134
+ - [agentme-edr-024](024-ml-dataset-structure.md) — ML dataset structure, per-entry JSON format, and schema-lint validation for golden datasets
135
+ - [agentme-edr-007](../principles/007-project-quality-standards.md) — Project quality standards: when evals are required per AI tier (rule `09`) and statistical model eval targets (rule `07`)
136
+ - [agentme-edr-008](../devops/008-common-targets.md) — `eval-<qualifier>` Makefile convention (rule `03`) and reserved MLflow port `5000` (rule `09`)
@@ -0,0 +1,171 @@
1
+ ---
2
+ name: agentme-edr-policy-032-ai-eval-report-format
3
+ description: Defines the eval report format for AI projects — report-<type>.md template, Wilson score confidence interval, convergence analysis, and the human-type checklist artifact. Use when generating eval reports from eval scripts. For the eval script that produces these reports see agentme-edr-031. For repeatability report shape see agentme-edr-033 rule 02.
4
+ apply-to: Python AI projects (LLM, Agent, or Workflow tier) that implement eval testing
5
+ valid-from: 2026-07-07
6
+ ---
7
+
8
+ # agentme-edr-policy-032: AI eval report format
9
+
10
+ ## Context and Problem Statement
11
+
12
+ Eval scripts produce output reports, but without a shared format these vary across projects: some omit confidence intervals, some skip convergence analysis, and some allow LLMs to write sections — making reports unreliable and non-comparable.
13
+
14
+ What format should eval reports follow, and what constraints apply to how they are generated?
15
+
16
+ ## Decision Outcome
17
+
18
+ **Use a standardized `report-<type>.md` template with a Wilson score confidence interval, a Mermaid convergence chart, and a strict no-LLM generation constraint for all metric values.**
19
+
20
+ ### Details
21
+
22
+ #### 01-eval-report-file
23
+
24
+ Each eval script MUST produce one `report-<type>.md` per evaluated test type in the same `evals/<component>/eval-<name>/` folder and overwrite each on every run — only the types included in the current `--type` invocation are (re)written; report files for other types are left untouched. The `human` type does not produce a metrics report (see below).
25
+
26
+ **Generation constraint:** The report MUST be produced programmatically, reading raw metric values directly from MLflow. No LLM or generative model may write, summarize, or paraphrase any section of the report, to prevent hallucinated metric values. This constraint applies to all report sections including Overall Results, Convergence Analysis, and Per-item Results — all metric values and convergence chart data points MUST be computed from actual evaluation results.
27
+
28
+ The report MUST follow this template:
29
+
30
+ ```markdown
31
+ # Eval Report: <name> — <type>
32
+
33
+ **Date:** <ISO date>
34
+ **Dataset:** golden_dataset/
35
+ **Script:** eval.py --type=<type>
36
+ **Thresholds:** accuracy ≥ <value>, F1 ≥ <value>
37
+
38
+ ## Overall Results
39
+
40
+ | Metric | Value | 95% CI | Threshold | Status |
41
+ |-----------|--------|----------------|-----------|---------|
42
+ | Accuracy | <val> | [<low>, <high>]| ≥ <thr> | ✓/✗ PASS/FAIL |
43
+ | F1 Score | <val> | — | ≥ <thr> | ✓/✗ PASS/FAIL |
44
+ | Precision | <val> | — | — | — |
45
+ | Recall | <val> | — | — | — |
46
+ | Samples | <n> | — | — | — |
47
+
48
+ **Overall: PASS / FAIL**
49
+
50
+ ## Convergence Analysis
51
+
52
+ ```mermaid
53
+ xychart-beta
54
+ title "Metric Evolution vs Sample Count"
55
+ x-axis "Samples" [<sample_points>]
56
+ y-axis "Score" 0.0 --> 1.0
57
+ line "Accuracy" [<accuracy_values>]
58
+ line "F1 Score" [<f1_values>]
59
+ ```
60
+
61
+ **Stability Analysis:**
62
+ - Accuracy change over last <window> samples: <change> percentage points
63
+ - F1 change over last <window> samples: <change> percentage points
64
+
65
+ **Recommendation:** <"Dataset appears sufficient for confident evaluation" | "Add more samples — metrics have not yet stabilized">
66
+
67
+ ## Per-item Results
68
+
69
+ | ID | Input Summary | Expected | Actual | Correct |
70
+ |-----|---------------|----------|--------|---------|
71
+ | 001 | <summary> | <label> | <label>| ✓ |
72
+ | 002 | <summary> | <label> | <label>| ✗ |
73
+
74
+ ## Notes
75
+
76
+ - <observations, failure patterns, MLflow run link>
77
+ ```
78
+
79
+ **Confidence interval:** The 95% CI for accuracy MUST be computed using the **Wilson score interval** (preferred over the normal approximation for small $n$). A wide interval signals that the dataset is too small to support confident conclusions and the sample count should be increased.
80
+
81
+ The Wilson score bounds at 95% confidence ($z = 1.96$) are:
82
+
83
+ $$\frac{\hat{p} + \frac{z^2}{2n} \pm z\sqrt{\frac{\hat{p}(1-\hat{p})}{n} + \frac{z^2}{4n^2}}}{1 + \frac{z^2}{n}}$$
84
+
85
+ Where $\hat{p}$ is observed accuracy and $n$ is sample count. Accuracy and F1 are required; precision and recall are recommended.
86
+
87
+ **Convergence analysis:** The Convergence Analysis section shows whether adding more samples would likely change measured metrics. The section MUST include:
88
+
89
+ 1. **Mermaid xychart-beta** showing cumulative Accuracy and F1 evolution:
90
+ - X-axis: absolute cumulative sample count; Y-axis: metric value (0.0 to 1.0)
91
+ - Two lines: Accuracy and F1
92
+ - For datasets > 50 samples: sample at `floor(dataset_size / 10)` intervals (minimum 5), always include first and last points
93
+ - For datasets ≤ 50 samples: show all points
94
+
95
+ 2. **Stability analysis**: compute absolute change (percentage points) for both Accuracy and F1 over last `min(10, dataset_size)` samples. Example: Accuracy from 0.85 to 0.87 = 0.02 = 2 percentage points.
96
+
97
+ 3. **Recommendation**:
98
+ - Default threshold: both Accuracy AND F1 change ≤ 2 percentage points
99
+ - If both meet threshold: "Dataset appears sufficient for confident evaluation"
100
+ - If either exceeds: "Add more samples — metrics have not yet stabilized"
101
+ - Projects MAY customize threshold (document in Makefile/README)
102
+
103
+ Exclude from `report-human.md` (no automated metrics).
104
+
105
+ **Filled-in example** (`evals/workflow-document-review/eval-basic/report-functional.md` for a document review workflow):
106
+
107
+ ```markdown
108
+ # Eval Report: eval-basic — functional
109
+
110
+ **Date:** 2026-06-12
111
+ **Dataset:** golden_dataset/
112
+ **Script:** eval.py --type=functional
113
+ **Thresholds:** accuracy ≥ 0.85, F1 ≥ 0.80
114
+
115
+ ## Overall Results
116
+
117
+ | Metric | Value | 95% CI | Threshold | Status |
118
+ |-----------|-------|--------------|-----------|-------------|
119
+ | Accuracy | 0.88 | [0.69, 0.97] | ≥ 0.85 | ✓ PASS |
120
+ | F1 Score | 0.86 | — | ≥ 0.80 | ✓ PASS |
121
+ | Precision | 0.89 | — | — | — |
122
+ | Recall | 0.84 | — | — | — |
123
+ | Samples | 25 | — | — | — |
124
+
125
+ **Overall: PASS**
126
+
127
+ > Note: CI [0.69, 0.97] is wide — 25 samples may be insufficient for high confidence. Consider expanding the dataset.
128
+
129
+ ## Convergence Analysis
130
+
131
+ ```mermaid
132
+ xychart-beta
133
+ title "Metric Evolution vs Sample Count"
134
+ x-axis "Samples" [1, 5, 10, 15, 20, 25]
135
+ y-axis "Score" 0.0 --> 1.0
136
+ line "Accuracy" [0.60, 0.80, 0.85, 0.87, 0.88, 0.88]
137
+ line "F1 Score" [0.55, 0.78, 0.83, 0.85, 0.86, 0.86]
138
+ ```
139
+
140
+ **Stability Analysis:**
141
+ - Accuracy change over last 10 samples: 0.01 percentage points
142
+ - F1 change over last 10 samples: 0.01 percentage points
143
+
144
+ **Recommendation:** Dataset appears sufficient for confident evaluation
145
+
146
+ > Metrics stabilized after ~15 samples. Changes over last 10 samples are well below the 2 percentage point threshold.
147
+
148
+ ## Per-item Results
149
+
150
+ | ID | Input Summary | Expected | Actual | Correct |
151
+ |-----|--------------------------------------|----------|----------|---------|
152
+ | 001 | Contract renewal, 3 pages, standard | approve | approve | ✓ |
153
+ | 002 | NDA with unusual liability clause | escalate | escalate | ✓ |
154
+ | 003 | Vendor invoice, missing PO number | reject | reject | ✓ |
155
+ | 004 | Employment agreement, standard terms| approve | approve | ✓ |
156
+ | 005 | Amendment with redlined IP clause | escalate | approve | ✗ |
157
+
158
+ ## Notes
159
+
160
+ - Sample 005 misclassified: redlined IP clause not flagged as escalation trigger. Possible model drift.
161
+ - MLflow run: experiment `workflow-document-review/eval-basic`, tag `test_types=functional` — view with `mlflow ui`
162
+ ```
163
+ ```
164
+
165
+ **`human` type artifact:** instead of `report-human.md` with metrics, `--type=human` produces a checklist artifact (still named `report-human.md`) listing, per entry, its `input`, `expected_output.human_test` instructions, and the captured `actual_output` — with no Overall Results table, threshold, or PASS/FAIL section, since this type MUST NOT be auto-scored.
166
+
167
+ ## References
168
+
169
+ - [agentme-edr-031](031-ai-eval-script.md) — AI eval script: the script that produces these reports (rule `01`)
170
+ - [agentme-edr-033](033-ai-eval-repeatability.md) — AI eval repeatability: rule `02` defines the adapted report shape for `report-repeatability.md`
171
+ - [agentme-edr-028](028-ai-eval-core-standards.md) — AI eval core standards: folder structure (rule `01`) and LLM-as-judge binary scoring (rule `02`)
@@ -0,0 +1,75 @@
1
+ ---
2
+ name: agentme-edr-policy-033-ai-eval-repeatability
3
+ description: Defines the repeatability test type for AI evals — REPEAT_COUNT loop exception to the entry-first constraint, semantic-similarity and LLM-as-judge scoring methods, repeatability_accuracy metric, and the repeatability report format and run cadence. Use when implementing repeatability evals. For the entry-first constraint see agentme-edr-031 rule 01. For LLM-as-judge binary output see agentme-edr-028 rule 02. For the base report template see agentme-edr-032 rule 01. For the repeatability test type definition see agentme-edr-030.
4
+ apply-to: Python AI projects (LLM, Agent, or Workflow tier) that implement repeatability eval testing
5
+ valid-from: 2026-07-07
6
+ ---
7
+
8
+ # agentme-edr-policy-033: AI eval repeatability
9
+
10
+ ## Context and Problem Statement
11
+
12
+ Some AI components must be tested for output consistency across multiple invocations with the same input — a property the standard entry-first eval loop cannot capture because it invokes each entry only once. Without a shared repeatability protocol, teams either skip this test or implement ad-hoc variations that produce incomparable results.
13
+
14
+ How should repeatability be measured in evals, and how should its results be reported?
15
+
16
+ ## Decision Outcome
17
+
18
+ **Exempt `repeatability` entries from the entry-first constraint, invoking each `REPEAT_COUNT` times and scoring via semantic-similarity or LLM-as-judge; schedule at release cadence rather than per-commit.**
19
+
20
+ For the `repeatability` test type definition and its disambiguation from `reproducibility`, see [agentme-edr-030](030-ai-test-types-taxonomy.md) rule `09`.
21
+
22
+ ### Details
23
+
24
+ #### 01-repeatability-eval-loop-exception
25
+
26
+ Entries whose `test_types` includes `repeatability` are exempt from [agentme-edr-031](031-ai-eval-script.md) rule `01`'s "invoke exactly once per entry" constraint. The following constants MUST be declared in `eval.py` and MUST NOT be exposed as Makefile variables, CLI flags, or stored as per-entry dataset fields:
27
+
28
+ - `REPEAT_COUNT` — number of times each repeatability entry is invoked. SHOULD default to 3-5 for routine CI runs and 10-20 for focused passes on decision-critical or previously-flagged components. Projects SHOULD calibrate the value once per component by plotting cumulative pass rate against repeat count for a few representative entries and picking the point where it plateaus, rather than guessing.
29
+ - `EVAL_MIN_ACCURACY_REPEATABILITY` — minimum fraction of repeatability entries that must PASS for the eval to exit 0.
30
+ - `REPEAT_SEMANTIC_SIMILARITY_SCORE` — minimum average pairwise cosine similarity for a single entry to PASS; declared only when using semantic-similarity scoring.
31
+
32
+ `eval.py` MUST invoke the component `REPEAT_COUNT` times for every repeatability entry and score the resulting outputs by comparing them to each other. `expected_output` is unused for repeatability entries and SHOULD be omitted or set to `null` in the dataset.
33
+
34
+ **Choosing the scoring method:** Two approaches are supported, declared as a constant in `eval.py`:
35
+
36
+ - **Semantic-similarity:** Embed all `REPEAT_COUNT` outputs for an entry into vectors and compute the average pairwise cosine similarity. The entry passes (score = 1) if the average similarity ≥ `REPEAT_SEMANTIC_SIMILARITY_SCORE`; otherwise it fails (score = 0). Use for classification or short structured outputs.
37
+ - **LLM-as-judge:** Provide all `REPEAT_COUNT` outputs for an entry to an LLM judge (kept at low/zero temperature) that returns 0 (fail) or 1 (pass) directly, based on whether the outputs are sufficiently consistent. No `REPEAT_SEMANTIC_SIMILARITY_SCORE` constant is needed. Use for free-text or complex structured outputs where vector distance is an unreliable proxy for agreement. The judge MUST follow [agentme-edr-028](028-ai-eval-core-standards.md) rule `02`'s binary output contract.
38
+
39
+ **`repeatability_accuracy`:** the fraction of repeatability entries that received PASS (score = 1), logged to MLflow as `repeatability_accuracy`. The eval exits non-zero if `repeatability_accuracy` < `EVAL_MIN_ACCURACY_REPEATABILITY`. Both `repeatability_accuracy` and `repeat_count` MUST be logged to MLflow and included in `report-repeatability.md` (rule `02`).
40
+
41
+ ```python
42
+ REPEAT_COUNT = 5
43
+ EVAL_MIN_ACCURACY_REPEATABILITY = 0.8
44
+ REPEAT_SEMANTIC_SIMILARITY_SCORE = 0.9 # only when using semantic-similarity scoring
45
+
46
+ for entry in repeatability_entries:
47
+ outputs = [invoke_component(entry, graph) for _ in range(REPEAT_COUNT)]
48
+ entry_pass = score_agreement(outputs) # returns 0 or 1; expected_output is not used
49
+ results["repeatability"].append(entry_pass) # 1 = PASS, 0 = FAIL
50
+
51
+ repeatability_accuracy = sum(results["repeatability"]) / len(results["repeatability"])
52
+ mlflow.log_metric("repeatability_accuracy", repeatability_accuracy)
53
+ mlflow.log_metric("repeat_count", REPEAT_COUNT)
54
+
55
+ if repeatability_accuracy < EVAL_MIN_ACCURACY_REPEATABILITY:
56
+ raise SystemExit(f"Eval failed: repeatability_accuracy {repeatability_accuracy:.2f} < {EVAL_MIN_ACCURACY_REPEATABILITY}")
57
+ ```
58
+
59
+ `mock_fixtures` configuration per [agentme-edr-031](031-ai-eval-script.md) rule `01` applies to each of the `REPEAT_COUNT` invocations. Any prompt or response caching (provider-side or gateway-side) MUST be bypassed for these invocations — a cache hit would return an identical cached response and falsely report perfect stability instead of measuring the model's actual variance.
60
+
61
+ **Scoping:** this test type MUST NOT be applied to components whose intended behavior is diverse or creative output (e.g. brainstorming, creative writing) — low agreement there is correct behavior, not a defect.
62
+
63
+ #### 02-repeatability-report-and-cadence
64
+
65
+ `--type=repeatability` MUST produce `report-repeatability.md` with a shape adapted from [agentme-edr-032](032-ai-eval-report-format.md) rule `01`'s template: the header MUST include a **Repeat count:** line stating the `REPEAT_COUNT` value used for the run, alongside the usual Date/Dataset/Script/Thresholds lines. The body MUST have an aggregate row reporting `repeatability_accuracy` (the fraction of entries that PASS — see rule `01`) with a Wilson score interval computed over the number of `repeatability` entries, plus a per-item table listing each entry's individual pass/fail result and, when using semantic-similarity, its computed average pairwise cosine similarity — instead of the `Expected | Actual | Correct` columns used by other types.
66
+
67
+ Because `repeatability` entries multiply real LLM-provider calls by `REPEAT_COUNT`, projects SHOULD schedule `make eval-repeatability` at release cadence rather than on every commit, aligned with the Workflow eval cadence in [agentme-edr-007](../principles/007-project-quality-standards.md) rule `09`, rather than treating it as a mandatory per-commit gate.
68
+
69
+ ## References
70
+
71
+ - [agentme-edr-031](031-ai-eval-script.md) — AI eval script: rule `01` defines the entry-first constraint this policy exempts for repeatability entries
72
+ - [agentme-edr-028](028-ai-eval-core-standards.md) — AI eval core standards: rule `02` defines the LLM-as-judge binary output contract used by the LLM-as-judge scoring method in rule `01`
73
+ - [agentme-edr-032](032-ai-eval-report-format.md) — AI eval report format: rule `01` defines the base report template that `report-repeatability.md` adapts
74
+ - [agentme-edr-030](030-ai-test-types-taxonomy.md) — AI test types taxonomy: `repeatability` test type definition and disambiguation from `reproducibility` (rule `09`)
75
+ - [agentme-edr-007](../principles/007-project-quality-standards.md) — Project quality standards: Workflow eval cadence (rule `09`) that repeatability runs align with
@@ -27,21 +27,36 @@ Synthetic views combining agentme XDRs and skills around a specific topic.
27
27
 
28
28
  Language and framework-specific tooling and project structure.
29
29
 
30
+ ### Language and framework tooling
31
+
30
32
  - [agentme-edr-003](application/003-javascript-project-tooling.md) - **JavaScript project tooling and structure** - Scaffold JavaScript libraries with the standard toolchain *(includes skill: [001-create-javascript-project](application/skills/001-create-javascript-project/SKILL.md))*
31
33
  - [agentme-edr-010](application/010-golang-project-tooling.md) - **Go project tooling and structure** - Scaffold Go CLIs and libraries with the standard layout *(includes skill: [003-create-golang-project](application/skills/003-create-golang-project/SKILL.md))*
32
34
  - [agentme-edr-014](application/014-python-project-tooling.md) - **Python project tooling and structure** - Scaffold Python packages and CLIs with the standard layout *(includes skill: [005-create-python-project](application/skills/005-create-python-project/SKILL.md))*
33
35
  - [agentme-edr-015](application/015-cli-tool-standards.md) - **CLI tool standards** - Define command UX and behavior for CLI tools
36
+ - [agentme-edr-026](application/026-pragmatic-hexagonal-architecture.md) - **Pragmatic hexagonal architecture** - Organize application layers as External/Adapters/Application with practical coupling rules
37
+ - [004-select-relevant-xdrs](application/skills/004-select-relevant-xdrs/SKILL.md) - **Select relevant XDRs**
38
+
39
+ ### AI development
40
+
41
+ Standards for building LLM, Agent, and Workflow components.
42
+
34
43
  - [agentme-edr-018](application/018-ai-llm-development-standards.md) - **AI LLM development standards** - Standard framework (LangChain) and patterns for simple LLM calls with explicit configuration (no environment variables)
35
44
  - [agentme-edr-019](application/019-ai-agents-development-standards.md) - **AI agents development standards** - Structural patterns for agents: framework selection, sandbox setup, naming conventions, composition, and system prompt structure
36
45
  - [agentme-edr-020](application/020-ai-agents-quality-standards.md) - **AI agents implementation quality standards** - Tool definition patterns, error handling, observability, and unit testing for agents
37
46
  - [agentme-edr-021](application/021-ai-workflow-development-standards.md) - **AI workflow development standards** - Standard toolchain (LangGraph), evaluation, and testing patterns for workflow projects
38
47
  - [agentme-edr-029](application/029-ai-workflow-naming-conventions.md) - **AI workflow naming conventions** - Node suffix/prefix roles, state type and attribute naming, judge output schema, workflow class names, and cross-element coherence rules
39
- - [agentme-edr-028](application/028-ai-eval-standards.md) - **AI eval standards** - Folder structure, script requirements, and MLflow tracking for eval tests across LLM, Agent, and Workflow tiers
40
- - [agentme-edr-030](application/030-ai-test-types-taxonomy.md) - **AI test types taxonomy** - Names AI test types (safety, responsible-AI, quality-eval, prompt, code-level) with group, objective, mocking constraint, and relevance, and defines the shared golden dataset entry envelope
41
- - [agentme-edr-024](application/024-ml-dataset-structure.md) - **ML dataset structure** - Standard folder layout and file conventions for ML datasets
42
48
  - [agentme-edr-025](application/025-ai-agent-xdrs-knowledge-layer.md) - **AI agent XDRS knowledge layer** - How to integrate XDRS as the runtime source of truth for policies and skills in AI agents (apply only when the project explicitly uses XDRS)
43
- - [agentme-edr-026](application/026-pragmatic-hexagonal-architecture.md) - **Pragmatic hexagonal architecture** - Organize application layers as External/Adapters/Application with practical coupling rules
44
- - [004-select-relevant-xdrs](application/skills/004-select-relevant-xdrs/SKILL.md) - **Select relevant XDRs**
49
+
50
+ ### AI evaluation and testing
51
+
52
+ Standards for eval datasets, scripts, reports, and test type taxonomy.
53
+
54
+ - [agentme-edr-030](application/030-ai-test-types-taxonomy.md) - **AI test types taxonomy** - Names AI test types (`functional`, `safety`, `smoke`, `repeatability`, `adversarial`, `fairness`, and 6 others) with group, objective, mocking constraint, and relevance, and defines the shared golden dataset entry envelope
55
+ - [agentme-edr-028](application/028-ai-eval-core-standards.md) - **AI eval core standards** - Eval folder structure and Makefile interface; LLM-as-judge binary scoring contract applicable to all AI tiers and test types
56
+ - [agentme-edr-031](application/031-ai-eval-script.md) - **AI eval script** - eval.py requirements: entry-first loop, --type filtering, mock_fixtures wiring, human entries, threshold enforcement, and MLflow experiment conventions
57
+ - [agentme-edr-032](application/032-ai-eval-report-format.md) - **AI eval report format** - report-<type>.md template, Wilson score confidence interval, convergence analysis, and human-type checklist artifact
58
+ - [agentme-edr-033](application/033-ai-eval-repeatability.md) - **AI eval repeatability** - Repeatability test type: REPEAT_COUNT loop exception, semantic-similarity and LLM-as-judge scoring, repeatability_accuracy metric, report shape, and run cadence
59
+ - [agentme-edr-024](application/024-ml-dataset-structure.md) - **ML dataset structure** - Standard folder layout and file conventions for ML datasets
45
60
 
46
61
  ## Devops
47
62
 
@@ -175,23 +175,28 @@ Projects that contain statistical models (e.g., ML models, LLM-based evaluators,
175
175
  **Requirements:**
176
176
  - A `make eval` target MUST exist and execute all performance evaluations
177
177
  - Each evaluation MUST have a **documented minimum performance threshold** (e.g., accuracy ≥ 0.85, F1 ≥ 0.80, BLEU ≥ 0.70)
178
- - Thresholds MUST be declared explicitly in the project (e.g., in a config file, `Makefile` variable, or documented in `README.md`)
178
+ - Thresholds and all scoring parameters MUST be declared as constants in `eval.py` — they are design decisions about acceptable quality for the component under test, not runtime configuration, and MUST NOT be passed as Makefile variables or CLI flags. See [agentme-edr-031](../application/031-ai-eval-script.md) rule `01`.
179
179
  - `make eval` MUST **exit with a non-zero status** (fail) if:
180
180
  - The evaluation cannot be executed (missing data, environment errors, model load failures)
181
181
  - Any metric falls below its defined minimum threshold
182
182
  - CI/CD MUST invoke `make eval` before releasing any version that changes model weights, prompts, or evaluation logic
183
183
 
184
- **Threshold declaration example (Makefile):**
184
+ **Threshold declaration example (eval.py):**
185
185
 
186
- ```makefile
187
- EVAL_MIN_ACCURACY := 0.85
188
- EVAL_MIN_F1 := 0.80
186
+ ```python
187
+ EVAL_MIN_ACCURACY = {"functional": 0.85, "smoke": 0.90}
188
+ EVAL_MIN_F1 = {"functional": 0.80}
189
+
190
+ # Thresholds are declared here and enforced by the script:
191
+ if accuracy < EVAL_MIN_ACCURACY.get(test_type, 0):
192
+ raise SystemExit(f"Eval failed: {test_type} accuracy {accuracy:.2f} < {EVAL_MIN_ACCURACY[test_type]}")
193
+ ```
189
194
 
195
+ **Makefile target (delegates to eval.py — no threshold variables here):**
196
+
197
+ ```makefile
190
198
  eval:
191
- python eval.py \
192
- --min-accuracy $(EVAL_MIN_ACCURACY) \
193
- --min-f1 $(EVAL_MIN_F1) \
194
- || (echo "Evaluation failed: metrics below threshold"; exit 1)
199
+ mise exec -- uv run --project . python eval.py --type=all
195
200
  ```
196
201
 
197
202
  ---
@@ -261,5 +266,5 @@ AI projects are classified into three tiers — LLM, Agent, and Workflow — def
261
266
  - Evals MUST be executed before every release.
262
267
  - Accuracy below project-defined thresholds MUST block the release. Thresholds MUST be documented in the eval Makefile or README.
263
268
  - Evals MUST run against real LLM providers (not mocks) to capture model drift.
264
- - For eval folder structure and script requirements, see [agentme-edr-028](../application/028-ai-eval-standards.md).
269
+ - For eval folder structure and LLM-as-judge scoring, see [agentme-edr-028](../application/028-ai-eval-core-standards.md). For eval script requirements, see [agentme-edr-031](../application/031-ai-eval-script.md).
265
270
  - For the taxonomy of AI test types (safety, responsible-AI, quality-eval, prompt, code-level) and the golden dataset entry format, see [agentme-edr-030](../application/030-ai-test-types-taxonomy.md).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentme",
3
- "version": "0.26.0",
3
+ "version": "0.27.0",
4
4
  "description": "",
5
5
  "dependencies": {
6
6
  "filedist": "^0.39.0"
@@ -1,257 +0,0 @@
1
- ---
2
- name: agentme-edr-policy-028-ai-eval-standards
3
- description: Defines how to structure, write, and run eval tests for AI projects — folder layout, golden dataset, --type test-type filtering, mock_fixtures wiring, entry-first eval loop, per-type Makefile targets and reports, and MLflow tracking. Use when implementing evals for LLM, Agent, or Workflow projects. For when evals are required see agentme-edr-007 rule 09-ai-project-testing-requirements. For the test type taxonomy and mock_fixtures envelope see agentme-edr-030. For mock file naming see agentme-edr-026 rule 10.
4
- apply-to: Python AI projects (LLM, Agent, or Workflow tier) that implement eval testing
5
- valid-from: 2026-06-05
6
- ---
7
-
8
- # agentme-edr-policy-028: AI eval standards
9
-
10
- ## Context and Problem Statement
11
-
12
- Eval tests measure AI component accuracy against expected outputs using real LLM providers. Without a shared folder layout and script convention, eval setups diverge across LLM, Agent, and Workflow projects, making them hard to run, compare, and integrate into CI/CD pipelines.
13
-
14
- How should eval tests be structured and run across all AI tiers?
15
-
16
- ## Decision Outcome
17
-
18
- **Use a per-component folder structure under `evals/` with a standardized Makefile interface and MLflow-backed scripts, applicable to LLM, Agent, and Workflow components.**
19
-
20
- For when evals are required per AI tier, see [agentme-edr-007](../principles/007-project-quality-standards.md) rule `09-ai-project-testing-requirements`.
21
-
22
- ### Details
23
-
24
- #### 01-eval-folder-structure
25
-
26
- Evals are grouped first by the component being evaluated, then by the specific evaluation scenario. Create one directory per component under `evals/`, and one directory per eval scenario inside it. Place `evals/` at the same level as `lib/` and `examples/`:
27
-
28
- ```text
29
- evals/
30
- <component>/ # the component being evaluated (e.g., workflow-x, agent-y, model-z)
31
- eval-<name>/
32
- golden_dataset/ # EDR-024 + EDR-030 compliant golden dataset (README.md, dataset.schema.json, data/)
33
- eval.py # evaluation script
34
- report-<type>.md # generated report, one per evaluated test type (overwritten on each run — see rule 03)
35
- Makefile # lint, eval, run, and eval-<type> targets
36
- eval-<name2>/
37
- ...
38
- <component2>/
39
- ...
40
- ```
41
-
42
- `<component>` MUST match the name of the component under evaluation and use lowercase hyphen-separated words (e.g., `workflow-document-review`, `agent-support`, `model-classifier`).
43
-
44
- `<name>` identifies the specific evaluation scenario using lowercase hyphen-separated words (e.g., `eval-basic`, `eval-complex`, `eval-edge-cases`). A scenario's `golden_dataset` MAY mix multiple test types across its entries: label each entry with its applicable `test_types` ([agentme-edr-030](030-ai-test-types-taxonomy.md) rule `04`) and use the `eval-<type>` targets below to run one type at a time.
45
-
46
- The `golden_dataset/` subfolder MUST be a valid [agentme-edr-024](024-ml-dataset-structure.md) dataset (`README.md`, `dataset.schema.json`, one JSON file per entry under `data/` per rule `04-complex-structured-datasets-must-use-per-entry-json-files`, lint-validated per rule `06`) whose entries follow the golden dataset envelope defined in [agentme-edr-030](030-ai-test-types-taxonomy.md) rule `02`.
47
-
48
- Each `evals/<component>/eval-<name>/Makefile` MUST declare a `TEST_TYPES` variable listing the `test_types` values present in its golden dataset, and define:
49
-
50
- | Target | Behaviour |
51
- |---|---|
52
- | `lint` | Validates every `golden_dataset/data/*.json` file against `golden_dataset/dataset.schema.json` per [agentme-edr-024](024-ml-dataset-structure.md) rule `06` |
53
- | `eval` | Depends on `lint`; runs `eval.py --type=all` with threshold enforcement; exits non-zero on failure (CI-safe) |
54
- | `run` | Depends on `lint`; runs `eval.py --type=all` without threshold enforcement (exploration / debugging) |
55
- | `eval-<type>` | Depends on `lint`; runs `eval.py --type=<type>` for one declared test type, following [agentme-edr-008](../devops/008-common-targets.md) rule `03`'s `eval-<qualifier>` convention |
56
-
57
- ```makefile
58
- TEST_TYPES := smoke functional safety
59
-
60
- lint:
61
- mise exec -- uv run --project . python lint_dataset.py golden_dataset/
62
-
63
- eval: lint
64
- mise exec -- uv run --project . python eval.py --type=all
65
-
66
- run: lint
67
- mise exec -- uv run --project . python eval.py --type=all --no-threshold
68
-
69
- eval-%: lint
70
- mise exec -- uv run --project . python eval.py --type=$*
71
- ```
72
-
73
- The module root Makefile MUST expose `make eval` and `make lint` targets that delegate to `eval` and `lint` respectively in every `evals/<component>/eval-<name>/Makefile`:
74
-
75
- ```makefile
76
- eval:
77
- $(MAKE) -C evals/workflow-document-review/eval-basic eval
78
- $(MAKE) -C evals/workflow-document-review/eval-complex eval
79
-
80
- lint:
81
- $(MAKE) -C evals/workflow-document-review/eval-basic lint
82
- $(MAKE) -C evals/workflow-document-review/eval-complex lint
83
- ```
84
-
85
- #### 02-eval-script-requirements
86
-
87
- Each `eval.py` script MUST:
88
-
89
- - Load the golden dataset from `golden_dataset/` in the same eval folder, following [agentme-edr-024](024-ml-dataset-structure.md) and the entry envelope in [agentme-edr-030](030-ai-test-types-taxonomy.md) rule `02` (one JSON file per entry, `test_types` array, `input`, `expected_output`, optional `mock_fixtures`).
90
- - Accept a required `--type=<test_type>|all` CLI argument and filter entries whose `test_types` array contains the requested value; `--type=all` includes every entry.
91
- - Iterate **entry-first**: for each entry in the filtered set, invoke the real component exactly once; then score that single `actual_output` for every `test_types` value the entry carries that falls within the current `--type` scope — MUST NOT invoke the component more than once per entry per run.
92
- - When an entry contains `mock_fixtures` ([agentme-edr-030](030-ai-test-types-taxonomy.md) rule `02`), configure each named mock adapter with its fixture data BEFORE invoking the component for that entry. Each entry MUST use fresh mock instances so fixture state does not bleed across entries. `mock_fixtures` applies to all test types including `human`. `mock_fixtures` MUST NOT configure LLM adapters — the LLM call MUST be real (see [agentme-edr-030](030-ai-test-types-taxonomy.md) rule `03`). How mock adapters are discovered and instantiated is left to the project; see [agentme-edr-026](026-pragmatic-hexagonal-architecture.md) rule `10` for the `_mock` file naming and placement convention.
93
- - Run every component invocation against **real LLM providers** (not mocked responses), to capture model drift.
94
- - For `human` entries: invoke the component to capture `actual_output`, export each entry's `input`, `expected_output.human_test` instructions, and `actual_output` into a manual-review checklist (`report-human.md`). MUST NOT invoke an automated scorer and MUST NOT enforce a pass/fail threshold for it. Other `test_types` on the same entry (e.g. `functional`) are still scored automatically.
95
- - After all entries are processed, compute aggregate metrics per test type, log them to a local MLflow experiment (see rule `04`), write one `report-<type>.md` per evaluated test type (rule `03`), and exit with a non-zero status when any metric falls below its defined threshold per [agentme-edr-007](../principles/007-project-quality-standards.md) rule `07-statistical-models-must-have-eval-targets`. The `human` type has no threshold and does not trigger a non-zero exit.
96
- - Compare outputs to expected values using project-defined quality thresholds per test type. Thresholds MUST be declared explicitly (e.g., in a Makefile variable or README) — this Policy does not mandate which test types a project must threshold or what value to use (see [agentme-edr-030](030-ai-test-types-taxonomy.md) rule `06`).
97
-
98
- **Example:**
99
-
100
- ```python
101
- import argparse
102
- from collections import defaultdict
103
- import mlflow
104
- from my_package.app.workflows.document_review_workflow.graph import graph
105
-
106
- EVAL_MIN_ACCURACY = {"functional": 0.85, "smoke": 0.85}
107
-
108
- parser = argparse.ArgumentParser()
109
- parser.add_argument("--type", required=True)
110
- args = parser.parse_args()
111
-
112
- entries = load_golden_dataset("golden_dataset/", test_type=args.type) # "all" loads every entry
113
- resolved_types = resolve_types(args.type, entries)
114
-
115
- mlflow.set_experiment("document-review/eval-basic")
116
-
117
- with mlflow.start_run():
118
- mlflow.set_tag("test_types", ",".join(sorted(resolved_types)))
119
-
120
- results = defaultdict(list)
121
-
122
- # Entry-first loop: invoke each entry exactly once
123
- for entry in entries:
124
- # Configure mock adapters from mock_fixtures before invocation
125
- # (implementation left to the project — see agentme-edr-026 rule 10)
126
- if entry.get("mock_fixtures"):
127
- configure_mocks(entry["mock_fixtures"]) # project-defined helper
128
-
129
- actual_output = invoke_component(entry, graph)
130
-
131
- for test_type in [t for t in entry["test_types"] if t in resolved_types]:
132
- if test_type == "human":
133
- export_human_review(entry, actual_output)
134
- continue
135
- results[test_type].append(score(test_type, actual_output, entry["expected_output"]))
136
-
137
- # Aggregate, report, and enforce thresholds per test type
138
- for test_type in resolved_types:
139
- if test_type == "human":
140
- continue
141
-
142
- accuracy = sum(results[test_type]) / len(results[test_type])
143
- mlflow.log_metric(f"{test_type}_accuracy", accuracy)
144
- write_eval_report(test_type, results[test_type], thresholds={"accuracy": EVAL_MIN_ACCURACY[test_type]})
145
-
146
- if accuracy < EVAL_MIN_ACCURACY[test_type]:
147
- raise SystemExit(f"Eval failed: {test_type} accuracy {accuracy:.2f} < {EVAL_MIN_ACCURACY[test_type]}")
148
- ```
149
-
150
- #### 03-eval-report-file
151
-
152
- Each eval script MUST produce one `report-<type>.md` per evaluated test type in the same `evals/<component>/eval-<name>/` folder and overwrite each on every run — only the types included in the current `--type` invocation are (re)written; report files for other types are left untouched. The `human` type does not produce a metrics report (see below).
153
-
154
- **Generation constraint:** The report MUST be produced programmatically, reading raw metric values directly from MLflow. No LLM or generative model may write, summarize, or paraphrase any section of the report, to prevent hallucinated metric values.
155
-
156
- The report MUST follow this template:
157
-
158
- ```markdown
159
- # Eval Report: <name> — <type>
160
-
161
- **Date:** <ISO date>
162
- **Dataset:** golden_dataset/
163
- **Script:** eval.py --type=<type>
164
- **Thresholds:** accuracy ≥ <value>, F1 ≥ <value>
165
-
166
- ## Overall Results
167
-
168
- | Metric | Value | 95% CI | Threshold | Status |
169
- |-----------|--------|----------------|-----------|---------|
170
- | Accuracy | <val> | [<low>, <high>]| ≥ <thr> | ✓/✗ PASS/FAIL |
171
- | F1 Score | <val> | — | ≥ <thr> | ✓/✗ PASS/FAIL |
172
- | Precision | <val> | — | — | — |
173
- | Recall | <val> | — | — | — |
174
- | Samples | <n> | — | — | — |
175
-
176
- **Overall: PASS / FAIL**
177
-
178
- ## Per-item Results
179
-
180
- | ID | Input Summary | Expected | Actual | Correct |
181
- |-----|---------------|----------|--------|---------|
182
- | 001 | <summary> | <label> | <label>| ✓ |
183
- | 002 | <summary> | <label> | <label>| ✗ |
184
-
185
- ## Notes
186
-
187
- - <observations, failure patterns, MLflow run link>
188
- ```
189
-
190
- **Confidence interval:** The 95% CI for accuracy MUST be computed using the **Wilson score interval** (preferred over the normal approximation for small $n$). A wide interval signals that the dataset is too small to support confident conclusions and the sample count should be increased.
191
-
192
- The Wilson score bounds at 95% confidence ($z = 1.96$) are:
193
-
194
- $$\frac{\hat{p} + \frac{z^2}{2n} \pm z\sqrt{\frac{\hat{p}(1-\hat{p})}{n} + \frac{z^2}{4n^2}}}{1 + \frac{z^2}{n}}$$
195
-
196
- Where $\hat{p}$ is observed accuracy and $n$ is sample count. Accuracy and F1 are required; precision and recall are recommended.
197
-
198
- **Filled-in example** (`evals/workflow-document-review/eval-basic/report-functional.md` for a document review workflow):
199
-
200
- ```markdown
201
- # Eval Report: eval-basic — functional
202
-
203
- **Date:** 2026-06-12
204
- **Dataset:** golden_dataset/
205
- **Script:** eval.py --type=functional
206
- **Thresholds:** accuracy ≥ 0.85, F1 ≥ 0.80
207
-
208
- ## Overall Results
209
-
210
- | Metric | Value | 95% CI | Threshold | Status |
211
- |-----------|-------|--------------|-----------|-------------|
212
- | Accuracy | 0.88 | [0.69, 0.97] | ≥ 0.85 | ✓ PASS |
213
- | F1 Score | 0.86 | — | ≥ 0.80 | ✓ PASS |
214
- | Precision | 0.89 | — | — | — |
215
- | Recall | 0.84 | — | — | — |
216
- | Samples | 25 | — | — | — |
217
-
218
- **Overall: PASS**
219
-
220
- > Note: CI [0.69, 0.97] is wide — 25 samples may be insufficient for high confidence. Consider expanding the dataset.
221
-
222
- ## Per-item Results
223
-
224
- | ID | Input Summary | Expected | Actual | Correct |
225
- |-----|--------------------------------------|----------|----------|---------|
226
- | 001 | Contract renewal, 3 pages, standard | approve | approve | ✓ |
227
- | 002 | NDA with unusual liability clause | escalate | escalate | ✓ |
228
- | 003 | Vendor invoice, missing PO number | reject | reject | ✓ |
229
- | 004 | Employment agreement, standard terms| approve | approve | ✓ |
230
- | 005 | Amendment with redlined IP clause | escalate | approve | ✗ |
231
-
232
- ## Notes
233
-
234
- - Sample 005 misclassified: redlined IP clause not flagged as escalation trigger. Possible model drift.
235
- - MLflow run: experiment `workflow-document-review/eval-basic`, tag `test_types=functional` — view with `mlflow ui`
236
- ```
237
-
238
- **`human` type artifact:** instead of `report-human.md` with metrics, `--type=human` produces a checklist artifact (still named `report-human.md`) listing, per entry, its `input`, `expected_output.human_test` instructions, and the captured `actual_output` — with no Overall Results table, threshold, or PASS/FAIL section, since this type MUST NOT be auto-scored.
239
-
240
- #### 04-eval-mlflow-unique-port
241
-
242
- Each `evals/<component>/eval-<name>/Makefile` MUST start its MLflow tracking server on a **unique port** to prevent conflicts when multiple eval Makefiles are run concurrently or in parallel (e.g., in CI or across multiple terminal sessions).
243
-
244
- Ports MUST be statically assigned per eval scenario (not per test type) and MUST NOT reuse the default `5000` port (reserved for `dev-mlflow` per [agentme-edr-008](../devops/008-common-targets.md) rule `09-ai-project-dev-targets`). Assign ports starting at `5100` and incrementing by 1 for each additional eval scenario across the entire project.
245
-
246
- The MLflow **experiment** is scoped to the eval scenario: `<component>/<eval-name>` (e.g. `document-review/eval-basic`). Each `mlflow.start_run()` call MUST set a `test_types` tag listing the test types evaluated in that invocation (comma-separated, e.g. `"functional,smoke"` for `--type=all`, `"smoke"` for `--type=smoke`). A remote MLflow server MUST NOT be required — all tracking is local.
247
-
248
- ## References
249
-
250
- - [agentme-edr-007](../principles/007-project-quality-standards.md) — Project quality standards: when evals are required per AI tier (rule `09-ai-project-testing-requirements`) and statistical model eval targets (rule `07-statistical-models-must-have-eval-targets`)
251
- - [agentme-edr-030](030-ai-test-types-taxonomy.md) — AI test types taxonomy: `test_types` enum, golden dataset entry envelope (including `mock_fixtures`), and mocking constraints per type
252
- - [agentme-edr-026](026-pragmatic-hexagonal-architecture.md) — Rule `10`: `_mock` file naming and placement convention for mock adapters used in `mock_fixtures`
253
- - [agentme-edr-018](018-ai-llm-development-standards.md) — LLM development standards: LangChain framework and observability
254
- - [agentme-edr-019](019-ai-agents-development-standards.md) — Agent development standards
255
- - [agentme-edr-021](021-ai-workflow-development-standards.md) — Workflow development standards
256
- - [agentme-edr-024](024-ml-dataset-structure.md) — ML dataset structure, per-entry JSON format, and schema-lint validation for golden datasets
257
- - [agentme-edr-008](../devops/008-common-targets.md) — `eval-<qualifier>` Makefile convention (rule `03`) and Mise tool-execution flow (rule `02`)