agentme 0.24.2 → 0.25.2
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.
- package/.filedist-package.yml +1 -1
- package/.xdrs/agentme/edrs/application/015-cli-tool-standards.md +27 -27
- package/.xdrs/agentme/edrs/application/019-ai-agents-development-standards.md +2 -2
- package/.xdrs/agentme/edrs/application/021-ai-workflow-development-standards.md +7 -7
- package/.xdrs/agentme/edrs/application/024-ml-dataset-structure.md +25 -10
- package/.xdrs/agentme/edrs/application/026-pragmatic-hexagonal-architecture.md +61 -8
- package/.xdrs/agentme/edrs/application/028-ai-eval-standards.md +99 -40
- package/.xdrs/agentme/edrs/application/030-ai-test-types-taxonomy.md +98 -0
- package/.xdrs/agentme/edrs/devops/005-monorepo-structure.md +2 -8
- package/.xdrs/agentme/edrs/devops/006-github-pipelines.md +3 -3
- package/.xdrs/agentme/edrs/devops/008-common-targets.md +26 -26
- package/.xdrs/agentme/edrs/devops/027-environment-variable-configuration.md +8 -8
- package/.xdrs/agentme/edrs/governance/013-contributing-guide-requirements.md +2 -2
- package/.xdrs/agentme/edrs/index.md +1 -0
- package/.xdrs/agentme/edrs/observability/011-service-health-check-endpoint.md +25 -3
- package/.xdrs/agentme/edrs/principles/002-coding-best-practices.md +6 -16
- package/.xdrs/agentme/edrs/principles/004-unit-test-requirements.md +6 -6
- package/.xdrs/agentme/edrs/principles/007-project-quality-standards.md +8 -7
- package/.xdrs/agentme/edrs/principles/009-error-handling.md +9 -19
- package/.xdrs/agentme/edrs/principles/012-continuous-xdr-enrichment.md +7 -7
- package/.xdrs/agentme/edrs/principles/016-cross-language-module-structure.md +7 -7
- package/.xdrs/agentme/edrs/principles/022-secrets-management.md +26 -8
- package/.xdrs/agentme/edrs/principles/023-coding-abstraction-practices.md +6 -8
- package/.xdrs/agentme/index.md +9 -0
- package/.xdrs/index.md +10 -2
- package/package.json +2 -2
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: agentme-edr-policy-030-ai-test-types-taxonomy
|
|
3
|
+
description: Names AI-application test types (safety, responsible-AI, quality-eval, prompt, code-level) with their group, objective, mocking constraint, and relevance, and defines the shared "golden dataset" entry envelope that agentme-edr-028's eval tooling filters by test_types. Use when deciding which AI test types to implement or when authoring a golden dataset entry.
|
|
4
|
+
apply-to: AI projects (LLM, Agent, or Workflow tier) implementing AI-specific test types beyond generic code-level unit/integration tests
|
|
5
|
+
valid-from: 2026-07-05
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# agentme-edr-policy-030: AI test types taxonomy
|
|
9
|
+
|
|
10
|
+
## Context and Problem Statement
|
|
11
|
+
|
|
12
|
+
AI components need test types beyond generic unit/integration tests (safety, fairness, groundedness, functional accuracy, etc.). Which test types should be named, and how should their datasets and eval tooling work?
|
|
13
|
+
|
|
14
|
+
## Decision Outcome
|
|
15
|
+
|
|
16
|
+
**Adopt a named taxonomy of AI test types plus a shared "golden dataset" entry envelope that agentme-edr-028's eval tooling filters by `test_types`.**
|
|
17
|
+
|
|
18
|
+
Each test type is named with its group, objective, mocking constraint, applicability, and relevance; every golden dataset entry is labeled with the test types it applies to.
|
|
19
|
+
|
|
20
|
+
### Details
|
|
21
|
+
|
|
22
|
+
#### 01-golden-dataset-concept
|
|
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/`.
|
|
25
|
+
|
|
26
|
+
#### 02-golden-dataset-entry-envelope
|
|
27
|
+
|
|
28
|
+
Every golden dataset entry (a JSON file in `golden_dataset/data/`) MUST have this shape, in addition to any project-specific fields:
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"$schema": "../dataset.schema.json",
|
|
33
|
+
"test_types": ["functional"],
|
|
34
|
+
"input": "...",
|
|
35
|
+
"expected_output": "...",
|
|
36
|
+
"mock_fixtures": {
|
|
37
|
+
"system_y": [{"123": {"name": "Flavio"}}, {"456": {"name": "Andrew"}}]
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
- `test_types` — array, values MUST come from rule `04`'s enum, MUST contain at least one value. An entry MAY carry more than one value additively (e.g. `["functional", "smoke", "human"]`) — no test type excludes another.
|
|
43
|
+
- `input` — for Prompt-tier components, a raw prompt string or the prompt template's input parameters object; for Agent/Workflow-tier components, the input attributes object passed to the component.
|
|
44
|
+
- `expected_output` — the fields used to score the entry under each of its automated `test_types`: output attributes for an LLM-as-judge rubric, a target for vector-similarity scoring, or exact attribute values for strict comparison. When `human` is one of the entry's `test_types`, `expected_output` MUST additionally include a `human_test` string field with manual-verification instructions (e.g. `"check for ethical issues, verify record change in system X"`) — this supplements, and never replaces, the entry's automated scoring fields.
|
|
45
|
+
- `mock_fixtures` — optional object; keys identify the adapter or external system to mock (SHOULD match the connector folder name under `adapters/connectors/<name>` for readability, though not enforced), values are any valid JSON interpreted by the mock implementation. When present, eval.py MUST configure each named mock adapter with its fixture data BEFORE invoking the component for that entry; each entry MUST use fresh mock instances to prevent state from bleeding across entries. `mock_fixtures` applies to all `test_types` including `human` — the component is still invoked for human entries to capture `actual_output`. `mock_fixtures` MUST NOT include keys for LLM adapters: all golden dataset test types are rated `mocks disallowed for LLM calls` (rule `03`), so the LLM call MUST always be real; LLM provider mocking belongs exclusively to unit tests via [agentme-edr-018](018-ai-llm-development-standards.md) rule `04`. See [agentme-edr-026](026-pragmatic-hexagonal-architecture.md) rule `10` for the `_mock` file naming and placement convention.
|
|
46
|
+
- The dataset's `dataset.schema.json` MUST require `test_types`, `input`, and `expected_output`, and SHOULD declare `mock_fixtures` as optional (`"type": "object", "additionalProperties": {}`), per [agentme-edr-024](024-ml-dataset-structure.md) rule `04`.
|
|
47
|
+
|
|
48
|
+
#### 03-mocks-allowed-values
|
|
49
|
+
|
|
50
|
+
The taxonomy in rule `05` rates each test type using one of three values:
|
|
51
|
+
|
|
52
|
+
| Value | Meaning |
|
|
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. |
|
|
57
|
+
|
|
58
|
+
#### 04-test-types-enum
|
|
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`.
|
|
61
|
+
|
|
62
|
+
#### 05-test-type-taxonomy
|
|
63
|
+
|
|
64
|
+
Test types MUST be selected from this taxonomy. Each test type is named with its group, objective, mocking constraint, applicability, and relevance:
|
|
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 |
|
|
81
|
+
|
|
82
|
+
#### 06-priority-and-relevance-are-descriptive-only
|
|
83
|
+
|
|
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
|
+
|
|
86
|
+
#### 07-smoke-is-distinct-from-test-smoke
|
|
87
|
+
|
|
88
|
+
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
|
+
## References
|
|
91
|
+
|
|
92
|
+
- [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
|
|
94
|
+
- [agentme-edr-026](026-pragmatic-hexagonal-architecture.md) — Rule `10`: `_mock` file naming and placement convention for mock adapters referenced by `mock_fixtures`
|
|
95
|
+
- [agentme-edr-007](../principles/007-project-quality-standards.md) — Rule `09` tier-level testing requirements (the only mandated AI testing baseline)
|
|
96
|
+
- [agentme-edr-008](../devops/008-common-targets.md) — Rule `03` `eval-<qualifier>` Makefile convention; rule `03`'s `test-smoke` (distinguished in rule `07`)
|
|
97
|
+
- [agentme-edr-018](018-ai-llm-development-standards.md) — LLM tier definition and mocking utilities referenced by the `mocks allowed` value
|
|
98
|
+
- [agentme-edr-004](../principles/004-unit-test-requirements.md) — Unit test requirements underlying the Code-level rows
|
|
@@ -57,8 +57,6 @@ Module folder responsibilities, artifact locations, and test-folder conventions
|
|
|
57
57
|
- **MUST** contain a `README.md` with: purpose, architecture overview, how to build, and how to run.
|
|
58
58
|
- **MAY** contain `examples/`, `tests_integration/`, and `tests_benchmark/` when those artifacts apply to multiple modules inside the application.
|
|
59
59
|
|
|
60
|
-
*Why:* Isolating applications prevents implicit coupling and makes the `shared/` boundary explicit and intentional.
|
|
61
|
-
|
|
62
60
|
#### 03-module-folders
|
|
63
61
|
|
|
64
62
|
- A module is a subfolder inside an application that is independently compilable and produces a build artifact.
|
|
@@ -87,8 +85,6 @@ Module Makefiles **SHOULD** also provide `lint-fix` and `install` when the under
|
|
|
87
85
|
The root `Makefile` **MUST** also define a `setup` target that guides a new contributor to prepare their machine.
|
|
88
86
|
The root `setup` target **MUST** run `mise install` and any small repository bootstrap required before routine targets work.
|
|
89
87
|
|
|
90
|
-
*Why:* Makefiles provide a universal, stack-agnostic entry point regardless of programming language.
|
|
91
|
-
|
|
92
88
|
#### 06-mise-for-tooling-management
|
|
93
89
|
|
|
94
90
|
- [Mise](https://mise.jdx.dev/) **MUST** be used to pin all tool versions (compilers, runtimes, CLI tools).
|
|
@@ -100,8 +96,6 @@ The root `setup` target **MUST** run `mise install` and any small repository boo
|
|
|
100
96
|
- If a required tool is missing, the first remediation step **MUST** be to update `.mise.toml` or run `mise install`, not to install ad-hoc global tools with language-specific installers such as `go install`, `npm install -g`, `pip install --user`, or `cargo install`.
|
|
101
97
|
- Root and module `Makefile` targets **MUST** work when invoked as plain `make <target>` after `make setup`.
|
|
102
98
|
|
|
103
|
-
*Why:* Eliminates "works on my machine" build failures by ensuring identical tool versions across all environments.
|
|
104
|
-
|
|
105
99
|
#### 07-root-readme
|
|
106
100
|
|
|
107
101
|
The root `README.md` **MUST** include: overview, machine setup, quickstart, and a repository map.
|
|
@@ -116,12 +110,12 @@ All releases **MUST** be tagged using the format `<module-name>/<semver>` (e.g.,
|
|
|
116
110
|
|
|
117
111
|
`<module-name>` is preferably the path-like identifier of the module being released. A custom name is allowed but the folder name is strongly preferred.
|
|
118
112
|
|
|
119
|
-
*Why:* Namespacing tags by module prevents collisions and makes it easy to filter release history when multiple modules release independently.
|
|
120
|
-
|
|
121
113
|
---
|
|
122
114
|
|
|
123
115
|
#### 11-summary-of-requirements
|
|
124
116
|
|
|
117
|
+
All requirements marked 'Yes' MUST be met. The table below summarizes the mandatory requirements:
|
|
118
|
+
|
|
125
119
|
| Requirement | Scope | Mandatory |
|
|
126
120
|
|---|---|---|
|
|
127
121
|
| Lowercase folder/file names | All | Yes |
|
|
@@ -37,7 +37,7 @@ All workflows run on `ubuntu-latest`. Tool versions MUST be managed by Mise via
|
|
|
37
37
|
|
|
38
38
|
File: `.github/workflows/ci.yml`
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
Projects MUST configure this workflow, triggered on every PR targeting `main` and every push to `main`. It runs the standard `build`, `lint`, and `test` targets from the root Makefile and fails the workflow if any step exits non-zero.
|
|
41
41
|
|
|
42
42
|
```yaml
|
|
43
43
|
name: ci
|
|
@@ -67,7 +67,7 @@ jobs:
|
|
|
67
67
|
|
|
68
68
|
File: `.github/workflows/release.yml`
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
Projects MUST use this manually dispatched (`workflow_dispatch`) workflow. It calculates the next semantic version tag using **monotag** and pushes that tag to the repository. Pushing the tag then automatically triggers the publish workflow.
|
|
71
71
|
|
|
72
72
|
The checkout step **must** use `fetch-depth: 0` so monotag can traverse the full commit history to determine the correct next version.
|
|
73
73
|
|
|
@@ -112,7 +112,7 @@ jobs:
|
|
|
112
112
|
|
|
113
113
|
File: `.github/workflows/publish.yml`
|
|
114
114
|
|
|
115
|
-
|
|
115
|
+
Projects MUST configure this workflow, triggered exclusively when a tag matching `v*.*.*` is pushed to the repository. This ensures only explicitly tagged commits produce published artifacts. Runs `make publish` against the tagged commit.
|
|
116
116
|
|
|
117
117
|
```yaml
|
|
118
118
|
name: publish
|
|
@@ -15,7 +15,7 @@ What standard set of Makefile target names and execution rules should projects a
|
|
|
15
15
|
|
|
16
16
|
## Decision Outcome
|
|
17
17
|
|
|
18
|
-
**Every project
|
|
18
|
+
**Every project MUST expose its development actions through a root `Makefile` using a defined set of standardized target names. Target implementation and tool-execution rules follow [agentme-edr-017](017-tool-execution-and-scripting.md), which requires `mise exec --` before routine tool commands.**
|
|
19
19
|
|
|
20
20
|
Standardizing both the target names and the execution chain removes per-project guesswork, makes CI pipelines reusable, and keeps tooling behavior visible in one place.
|
|
21
21
|
|
|
@@ -23,18 +23,18 @@ Standardizing both the target names and the execution chain removes per-project
|
|
|
23
23
|
|
|
24
24
|
#### 01-every-project-must-have-root-makefile
|
|
25
25
|
|
|
26
|
-
The project root
|
|
26
|
+
The project root **MUST** contain a single authoritative `Makefile` that exposes the standard target names defined in rule 3. Developers and CI pipelines **MUST** invoke routine actions through this `Makefile`, **NEVER** by calling underlying tools directly in documentation, CI, or daily workflow commands.
|
|
27
27
|
|
|
28
28
|
`make <target>` is the shared contract across projects and languages.
|
|
29
29
|
|
|
30
|
-
- The root `Makefile`
|
|
31
|
-
- The root `Makefile`
|
|
32
|
-
- Reverse-compatibility wrappers are allowed when an ecosystem expects them, but they
|
|
30
|
+
- The root `Makefile` **MUST** be the entry point for both developers and pipelines.
|
|
31
|
+
- The root `Makefile` **MUST** expose at minimum the common targets defined in this XDR.
|
|
32
|
+
- Reverse-compatibility wrappers are allowed when an ecosystem expects them, but they **MUST** stay trivial.
|
|
33
33
|
- Allowed: `package.json` script `"test": "make test"`
|
|
34
34
|
- Not allowed: `make test` -> `npm run test` -> tool command
|
|
35
|
-
- Project logic
|
|
35
|
+
- Project logic **MUST NOT** live in npm scripts, Mise tasks, shell wrappers, or other secondary runners when the same logic belongs in the `Makefile`.
|
|
36
36
|
|
|
37
|
-
*Why:* The project entry point
|
|
37
|
+
*Why:* The project entry point **MUST** stay language-agnostic and obvious. A developer **SHOULD** be able to inspect the `Makefile` and immediately see which real tool commands will run.
|
|
38
38
|
|
|
39
39
|
#### 02-makefile-recipes-must-use-mise
|
|
40
40
|
|
|
@@ -47,10 +47,10 @@ make <target>
|
|
|
47
47
|
-> explicit tool command
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
-
- The `setup` target
|
|
51
|
-
- Routine targets such as `build`, `lint`, `test`, `run`, and `publish`
|
|
52
|
-
- Each Makefile recipe
|
|
53
|
-
- Makefile recipes
|
|
50
|
+
- The `setup` target **MUST** run `mise install` and any small project-specific bootstrap needed before normal targets work.
|
|
51
|
+
- Routine targets such as `build`, `lint`, `test`, `run`, and `publish` **MUST** be invoked as `make <target>` by both contributors and CI.
|
|
52
|
+
- Each Makefile recipe **MUST** call the real underlying command through `mise exec --`, following [agentme-edr-017](017-tool-execution-and-scripting.md).
|
|
53
|
+
- Makefile recipes **MUST NOT** add extra script layers such as `npm run`, `pnpm run`, `yarn run`, `mise run`, `mise tasks`, or shell aliases when those layers only forward to another command.
|
|
54
54
|
- Calling the actual tool is allowed even when that tool itself launches another program as part of its normal interface.
|
|
55
55
|
- Allowed: `mise exec -- pnpm exec eslint ./src`
|
|
56
56
|
- Allowed: `mise exec -- go test -cover ./...`
|
|
@@ -66,17 +66,17 @@ make <target>
|
|
|
66
66
|
|
|
67
67
|
#### 03-standard-target-groups-and-names
|
|
68
68
|
|
|
69
|
-
Targets are organized into five lifecycle groups. Projects
|
|
69
|
+
Targets are organized into five lifecycle groups. Projects **MUST** use these names unchanged. Extensions are allowed (see rule 5) but the core names **MUST NOT** be repurposed.
|
|
70
70
|
|
|
71
71
|
##### Developer group
|
|
72
72
|
|
|
73
73
|
| Target | Purpose |
|
|
74
74
|
|--------|---------|
|
|
75
75
|
| `setup` | Run `mise install` and any small project bootstrap needed before normal targets work. This is the first command after checkout. |
|
|
76
|
-
| `all` | Alias that runs `build`, `lint`, and `test` in sequence.
|
|
76
|
+
| `all` | Alias that runs `build`, `lint`, and `test` in sequence. **MUST** be the default target (i.e., running `make` or the runner with no arguments invokes `all`). Used by developers as a fast pre-push check to verify the software meets minimum quality standards in one command. **MUST** only invoke targets that run **offline** — no external credentials, running servers, paid APIs, or environment-specific configuration outside the repository. |
|
|
77
77
|
| `clean` | Remove all temporary or generated files created during build, lint, or test (e.g., `node_modules`, virtual environments, compiled binaries, generated files). Used both locally and in CI for a clean slate. |
|
|
78
78
|
| `dev` | Run the software locally for development (e.g., start a Node.js API server, open a Jupyter notebook, launch a React dev server). May have debugging tools, verbose logging, or hot reloading features enabled. |
|
|
79
|
-
| `run` | Run the software in production mode (e.g., start a compiled binary, launch a production server).
|
|
79
|
+
| `run` | Run the software in production mode (e.g., start a compiled binary, launch a production server). Debugging or development-only features **SHOULD NOT** be enabled. |
|
|
80
80
|
| `update-lockfile` | Update the dependency lockfile to reflect the latest resolved versions of all dependencies. |
|
|
81
81
|
|
|
82
82
|
##### Build group
|
|
@@ -93,17 +93,17 @@ Targets are organized into five lifecycle groups. Projects must use these names
|
|
|
93
93
|
|
|
94
94
|
| Target | Purpose |
|
|
95
95
|
|--------|---------|
|
|
96
|
-
| `lint` | Run **all static quality checks** outside of tests. This MUST include: code formatting validation, code style enforcement, code smell detection, static analysis, dependency audits for known CVEs, security vulnerability scans (e.g., SAST), and project/configuration structure checks. All checks
|
|
96
|
+
| `lint` | Run **all static quality checks** outside of tests. This MUST include: code formatting validation, code style enforcement, code smell detection, static analysis, dependency audits for known CVEs, security vulnerability scans (e.g., SAST), and project/configuration structure checks. All checks **MUST** be non-destructive (read-only); fixes are handled by `lint-fix`. **MUST** only invoke subtargets that run **offline** (no external credentials or services). |
|
|
97
97
|
| `lint-fix` | Automatically fix linting and formatting issues where possible. || `lint-format` | *(Optional)* Check code formatting only (e.g., Prettier, gofmt, Black). |
|
|
98
98
|
##### Test group
|
|
99
99
|
|
|
100
100
|
| Target | Purpose |
|
|
101
101
|
|--------|---------|
|
|
102
|
-
| `test` | Run **all offline tests** required for the project. This MUST include unit tests (with coverage enforcement — the build MUST fail if coverage thresholds are not met) and any integration or end-to-end tests that run **offline** (no external servers, credentials, or paid APIs). Normally delegates to `test-unit` and, when offline, `test-integration` in sequence. Suffixed targets that require external dependencies
|
|
102
|
+
| `test` | Run **all offline tests** required for the project. This MUST include unit tests (with coverage enforcement — the build MUST fail if coverage thresholds are not met) and any integration or end-to-end tests that run **offline** (no external servers, credentials, or paid APIs). Normally delegates to `test-unit` and, when offline, `test-integration` in sequence. Suffixed targets that require external dependencies **MUST NOT** be invoked automatically — see rule 08. |
|
|
103
103
|
| `test-unit` | Run unit tests only, including coverage report generation and coverage threshold enforcement. |
|
|
104
|
-
| `test-integration` | *(Optional)* Run integration and end-to-end tests only. Projects without integration tests
|
|
104
|
+
| `test-integration` | *(Optional)* Run integration and end-to-end tests only. Projects without integration tests MAY omit this target. |
|
|
105
105
|
| `test-smoke` | *(Optional)* Run a fast, minimal subset of tests to verify the software is basically functional. Useful as a post-deploy health check. |
|
|
106
|
-
| `eval` | *(Optional)* Run **all evaluations** for the module. Used alongside `test` to measure the accuracy and performance of statistical systems such as ML models, AI agents, or noisy systems. Typically runs against a live or near-live system (similar to an integration test) and produces a performance analysis report (e.g., F1 score, Accuracy, Precision, Recall).
|
|
106
|
+
| `eval` | *(Optional)* Run **all evaluations** for the module. Used alongside `test` to measure the accuracy and performance of statistical systems such as ML models, AI agents, or noisy systems. Typically runs against a live or near-live system (similar to an integration test) and produces a performance analysis report (e.g., F1 score, Accuracy, Precision, Recall). **MUST NOT** be included in `test` or `all` — evals are opt-in because they require live dependencies and MAY be slow or costly to run. Individual evaluations **MUST** follow the prefix convention: `eval-<qualifier>` (e.g., `eval-simple`, `eval-complex`). |
|
|
107
107
|
|
|
108
108
|
##### Release group
|
|
109
109
|
|
|
@@ -119,18 +119,18 @@ Targets are organized into five lifecycle groups. Projects must use these names
|
|
|
119
119
|
|
|
120
120
|
#### 04-standard-environment-variables
|
|
121
121
|
|
|
122
|
-
Two environment variables have defined semantics and
|
|
122
|
+
Two environment variables have defined semantics and **MUST** be used consistently.
|
|
123
123
|
|
|
124
124
|
| Variable | Purpose |
|
|
125
125
|
|----------|---------|
|
|
126
|
-
| `STAGE` | Identifies the runtime environment. Format: `[prefix][-variant]`. Common prefixes: `dev`, `tst`, `acc`, `prd`. Examples: `dev`, `dev-pr123`, `tst`, `prd-blue`.
|
|
126
|
+
| `STAGE` | Identifies the runtime environment. Format: `[prefix][-variant]`. Common prefixes: `dev`, `tst`, `acc`, `prd`. Examples: `dev`, `dev-pr123`, `tst`, `prd-blue`. **MAY** be required by any target that is environment-aware (build, lint, deploy, etc.). |
|
|
127
127
|
| `VERSION` | Sets the explicit version used during packaging and deployment. Used when there is no automatic version-tagging utility, or to override it. |
|
|
128
128
|
|
|
129
129
|
---
|
|
130
130
|
|
|
131
131
|
#### 05-extending-targets-with-prefixes
|
|
132
132
|
|
|
133
|
-
Projects
|
|
133
|
+
Projects **MAY** add custom targets beyond the standard set. Custom targets **MUST** be named by prefixing a standard target name with a descriptive qualifier, keeping the naming intuitive and consistent with the group it belongs to.
|
|
134
134
|
|
|
135
135
|
**Examples:**
|
|
136
136
|
|
|
@@ -166,15 +166,15 @@ dev-mlflow:
|
|
|
166
166
|
|
|
167
167
|
#### 08-default-targets-must-only-include-offline-subtargets
|
|
168
168
|
|
|
169
|
-
`make all`, `make test`, and `make lint`
|
|
169
|
+
`make all`, `make test`, and `make lint` **MUST** include every subtarget that runs **offline** — meaning it requires no external credentials, no running servers, no paid APIs, and no environment-specific configuration outside the repository.
|
|
170
170
|
|
|
171
|
-
Subtargets that require external dependencies (e.g., `test-integration` against a live database, `test-e2e` against a staging environment, `lint-api` against a remote schema registry) **
|
|
171
|
+
Subtargets that require external dependencies (e.g., `test-integration` against a live database, `test-e2e` against a staging environment, `lint-api` against a remote schema registry) **MUST** exist as named targets so developers can invoke them explicitly, but **MUST NOT** be invoked from `all`, `test`, or `lint`.
|
|
172
172
|
|
|
173
173
|
---
|
|
174
174
|
|
|
175
175
|
#### 06-monorepo-usage
|
|
176
176
|
|
|
177
|
-
In a monorepo, each module has its own `Makefile` with its own `build`, `lint`, `test`, and `deploy` targets scoped to that module. Parent-level Makefiles (at the application or repo root) delegate to child Makefiles in sequence. The parent Makefile
|
|
177
|
+
In a monorepo, each module has its own `Makefile` with its own `build`, `lint`, `test`, and `deploy` targets scoped to that module. Parent-level Makefiles (at the application or repo root) delegate to child Makefiles in sequence. The parent Makefile **SHOULD** call `$(MAKE) -C <child> <target>` directly, while each child `Makefile` runs its actual tool commands through `mise exec --`.
|
|
178
178
|
|
|
179
179
|
```makefile
|
|
180
180
|
# root Makefile — delegates to all modules
|
|
@@ -187,7 +187,7 @@ test:
|
|
|
187
187
|
$(MAKE) -C module-b test
|
|
188
188
|
```
|
|
189
189
|
|
|
190
|
-
A developer can run `make test` at the repo root to test everything, or `cd module-a && make test` to test a single module. Both
|
|
190
|
+
A developer can run `make test` at the repo root to test everything, or `cd module-a && make test` to test a single module. Both **MUST** work.
|
|
191
191
|
|
|
192
192
|
**Reference:** See [agentme-edr-005](005-monorepo-structure.md) for the full monorepo layout convention.
|
|
193
193
|
|
|
@@ -195,7 +195,7 @@ A developer can run `make test` at the repo root to test everything, or `cd modu
|
|
|
195
195
|
|
|
196
196
|
#### 07-quick-reference
|
|
197
197
|
|
|
198
|
-
Any project following this EDR
|
|
198
|
+
Any project following this EDR MUST support the following actions through the root `Makefile`.
|
|
199
199
|
|
|
200
200
|
```sh
|
|
201
201
|
# install the pinned toolchain and project bootstrap
|
|
@@ -25,7 +25,7 @@ Secrets (API keys, passwords, tokens) must never be placed in `.env` files. Thos
|
|
|
25
25
|
|
|
26
26
|
#### 01-when-to-use-dotenv
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
A `.env` file MUST be used when either of the following is true:
|
|
29
29
|
|
|
30
30
|
1. **Spawned process needs env vars** — the project launches a process (a deployable service, background worker, or shell script) that reads configuration from OS environment variables such as port numbers or API endpoint URLs.
|
|
31
31
|
2. **Value must not be committed** — a configuration value used in a YAML config file (see rule 07) is environment-specific or sensitive enough to exclude from version control. In that case, store the value in `.env` and reference it from the YAML file using env var substitution (see rule 08).
|
|
@@ -43,13 +43,13 @@ FEATURE_FLAG_NEW_UI=false
|
|
|
43
43
|
|
|
44
44
|
#### 02-dotenv-not-committed
|
|
45
45
|
|
|
46
|
-
`.env`
|
|
46
|
+
`.env` MUST be listed in `.gitignore` and must never be committed to the repository. It is intended for local use in standalone projects and libraries that do not have a formal deployment pipeline.
|
|
47
47
|
|
|
48
48
|
---
|
|
49
49
|
|
|
50
50
|
#### 03-dotenv-example-committed
|
|
51
51
|
|
|
52
|
-
A `.env.example` file
|
|
52
|
+
A `.env.example` file MUST be committed alongside `.env`. It contains all the same variable names with placeholder or illustrative values — no real URLs, credentials, or server names. This file documents what configuration is expected without exposing real values.
|
|
53
53
|
|
|
54
54
|
Example `.env.example`:
|
|
55
55
|
```
|
|
@@ -62,7 +62,7 @@ FEATURE_FLAG_NEW_UI=false
|
|
|
62
62
|
|
|
63
63
|
#### 04-stage-specific-dotenv-committed
|
|
64
64
|
|
|
65
|
-
Stage-specific overrides
|
|
65
|
+
Stage-specific overrides MUST use the naming convention `.env.[stage]` (e.g., `.env.production`, `.env.staging`, `.env.test`). These files may be committed to the repository because they carry deployment-stage configuration rather than local developer configuration. They are used during deployment pipelines where the stage is known and explicit.
|
|
66
66
|
|
|
67
67
|
The generic `.env` must still not be committed. The distinction is: `.env` is for local, ad-hoc, standalone use; `.env.[stage]` is for deployment pipelines with a defined environment identity.
|
|
68
68
|
|
|
@@ -70,7 +70,7 @@ The generic `.env` must still not be committed. The distinction is: `.env` is fo
|
|
|
70
70
|
|
|
71
71
|
#### 05-load-in-makefile-before-processes
|
|
72
72
|
|
|
73
|
-
When `.env` defines variables consumed by shell scripts or spawned processes, the Makefile
|
|
73
|
+
When `.env` defines variables consumed by shell scripts or spawned processes, the Makefile MUST load and export them before invoking those processes. Use the following pattern at the top of the relevant Makefile or in a shared include:
|
|
74
74
|
|
|
75
75
|
```makefile
|
|
76
76
|
ifneq (,$(wildcard .env))
|
|
@@ -85,7 +85,7 @@ This ensures all variables in `.env` are available as environment variables to e
|
|
|
85
85
|
|
|
86
86
|
#### 06-no-application-level-dotenv-loading
|
|
87
87
|
|
|
88
|
-
Applications
|
|
88
|
+
Applications MUST NOT load `.env` files directly inside their own code using dotenv libraries or equivalent mechanisms. Configuration must enter the process exclusively as OS-level environment variables, set before the process is launched (by the Makefile, a shell script, CI, or a container runtime).
|
|
89
89
|
|
|
90
90
|
Prohibited patterns:
|
|
91
91
|
|
|
@@ -114,7 +114,7 @@ This rule prevents two parallel loading paths — OS env and file-based env —
|
|
|
114
114
|
|
|
115
115
|
#### 07-cli-adapters-use-yaml-config
|
|
116
116
|
|
|
117
|
-
CLI adapters with multiple configuration attributes
|
|
117
|
+
CLI adapters with multiple configuration attributes MUST use a YAML config file rather than env vars or flags for those attributes. This applies whenever configuration is nested, repetitive, or too verbose for flags alone.
|
|
118
118
|
|
|
119
119
|
The CLI layer is responsible for loading and parsing the YAML file and passing the resolved values to the application layer. The application layer must not read the config file directly.
|
|
120
120
|
|
|
@@ -131,7 +131,7 @@ max_retries: 3
|
|
|
131
131
|
|
|
132
132
|
#### 08-env-var-substitution-in-config-files
|
|
133
133
|
|
|
134
|
-
When a YAML config file contains a value that
|
|
134
|
+
When a YAML config file contains a value that MUST NOT be committed (such as a real endpoint URL, a username, or any other environment-specific value), that value must be expressed as an environment variable reference using `${VAR_NAME}` syntax, and the actual value must be defined in `.env`.
|
|
135
135
|
|
|
136
136
|
This keeps the YAML file committable while keeping the environment-specific value out of the repository.
|
|
137
137
|
|
|
@@ -15,9 +15,9 @@ What contributor workflow guidance must every project publish so contributors kn
|
|
|
15
15
|
|
|
16
16
|
## Decision Outcome
|
|
17
17
|
|
|
18
|
-
**Every project
|
|
18
|
+
**Every project MUST publish a root CONTRIBUTING.md with a small, explicit contribution workflow.**
|
|
19
19
|
|
|
20
|
-
Projects
|
|
20
|
+
Projects MUST keep a `CONTRIBUTING.md` file at the repository root. The file MUST explain where bugs, feature discussions, and code changes belong so contributors follow a predictable workflow before opening pull requests.
|
|
21
21
|
|
|
22
22
|
### Details
|
|
23
23
|
|
|
@@ -37,6 +37,7 @@ Language and framework-specific tooling and project structure.
|
|
|
37
37
|
- [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
38
|
- [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
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
|
|
40
41
|
- [agentme-edr-024](application/024-ml-dataset-structure.md) - **ML dataset structure** - Standard folder layout and file conventions for ML datasets
|
|
41
42
|
- [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)
|
|
42
43
|
- [agentme-edr-026](application/026-pragmatic-hexagonal-architecture.md) - **Pragmatic hexagonal architecture** - Organize application layers as External/Adapters/Application with practical coupling rules
|
|
@@ -17,7 +17,7 @@ How should services expose their health status and validate operational readines
|
|
|
17
17
|
|
|
18
18
|
**Standardized `/health` endpoint with dependency validation**
|
|
19
19
|
|
|
20
|
-
All services
|
|
20
|
+
All services **MUST** expose a `GET /health` endpoint that validates external dependencies using read-only operations and returns structured status with appropriate HTTP codes.
|
|
21
21
|
|
|
22
22
|
### Details
|
|
23
23
|
|
|
@@ -45,12 +45,12 @@ All services must expose a `GET /health` endpoint that validates external depend
|
|
|
45
45
|
|
|
46
46
|
- `health` (required): overall state — `OK`, `WARNING`, or `ERROR`
|
|
47
47
|
- `latencyMs` (required): total milliseconds to run all checks
|
|
48
|
-
- `message` (required): human-readable summary;
|
|
48
|
+
- `message` (required): human-readable summary; **MUST NEVER** expose credentials, internal IPs, or stack traces
|
|
49
49
|
|
|
50
50
|
**Dependency validation rules:**
|
|
51
51
|
|
|
52
52
|
- Check all external dependencies (databases, downstream APIs, queues, caches) using read-only operations (e.g., `SELECT 1`, lightweight GET, connection ping)
|
|
53
|
-
-
|
|
53
|
+
- **MUST NOT** execute write operations or create side effects
|
|
54
54
|
- `OK`: all dependencies healthy within expected thresholds
|
|
55
55
|
- `WARNING`: non-critical dependency degraded, or elevated but acceptable response times
|
|
56
56
|
- `ERROR`: critical dependency unavailable or service unable to process requests
|
|
@@ -70,6 +70,28 @@ All services must expose a `GET /health` endpoint that validates external depend
|
|
|
70
70
|
- Monitoring: periodic polling with alerts on `210` and `503` responses
|
|
71
71
|
- CI/CD: poll `/health` to confirm deployment success
|
|
72
72
|
|
|
73
|
+
**Unit testing and mocking strategy:** Each dependency checker MUST be injectable so unit tests can simulate `OK`, `WARNING`, and `ERROR` states independently without a real database or API. Integration tests MUST NOT mock dependency checkers — they MUST run against real dependencies to verify the wiring.
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
// Good — injectable checkers; unit test controls each state
|
|
77
|
+
function buildHealthHandler(checkers: DependencyChecker[]) {
|
|
78
|
+
return async () => {
|
|
79
|
+
const results = await Promise.all(checkers.map(c => c.check()));
|
|
80
|
+
const status = results.some(r => r.status === "ERROR") ? "ERROR"
|
|
81
|
+
: results.some(r => r.status === "WARNING") ? "WARNING" : "OK";
|
|
82
|
+
return { health: status };
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
it("returns ERROR when the database checker fails", async () => {
|
|
87
|
+
const handler = buildHealthHandler([
|
|
88
|
+
{ check: async () => ({ name: "db", status: "ERROR" }) },
|
|
89
|
+
]);
|
|
90
|
+
const response = await handler();
|
|
91
|
+
expect(response.health).toBe("ERROR");
|
|
92
|
+
});
|
|
93
|
+
```
|
|
94
|
+
|
|
73
95
|
## Considered Options
|
|
74
96
|
|
|
75
97
|
* (REJECTED) **No health checks** — detect failures through request errors
|
|
@@ -21,12 +21,10 @@ What coding practices should be followed across all languages and projects to ke
|
|
|
21
21
|
|
|
22
22
|
#### 01-keep-files-short
|
|
23
23
|
|
|
24
|
-
A file
|
|
24
|
+
A file MUST NOT exceed **400 lines**. When a file grows beyond this limit, split related functions or types into separate, focused modules.
|
|
25
25
|
|
|
26
26
|
One exception are test files, which normally are bigger than the tested resources.
|
|
27
27
|
|
|
28
|
-
*Why:* Large files make navigation slow, increase merge conflicts, and obscure the single-responsibility principle.
|
|
29
|
-
|
|
30
28
|
**Example (TypeScript):**
|
|
31
29
|
|
|
32
30
|
```
|
|
@@ -48,9 +46,7 @@ src/
|
|
|
48
46
|
|
|
49
47
|
#### 02-apply-template-method-pattern
|
|
50
48
|
|
|
51
|
-
When a function's main logic contains well-defined sections and **any individual section exceeds ~20 lines**,
|
|
52
|
-
|
|
53
|
-
*Why:* Named sub-functions serve as inline documentation, are independently testable, and reduce cognitive load.
|
|
49
|
+
When a function's main logic contains well-defined sections and **any individual section exceeds ~20 lines**, each section MUST be extracted into its own named function. The outer function becomes an orchestrator that calls the extracted helpers in sequence.
|
|
54
50
|
|
|
55
51
|
**Example (Python):**
|
|
56
52
|
|
|
@@ -85,9 +81,7 @@ def _persist_order(order, total): ...
|
|
|
85
81
|
|
|
86
82
|
#### 03-put-entry-point-function-first
|
|
87
83
|
|
|
88
|
-
Place the **entry-point function** (the outermost caller) at the **top** of the file. All helper or sub-functions it calls internally
|
|
89
|
-
|
|
90
|
-
*Why:* Readers can follow the overall logic top-down without jumping around the file. The most important function is immediately visible when the file is opened.
|
|
84
|
+
Place the **entry-point function** (the outermost caller) at the **top** of the file. All helper or sub-functions it calls internally MUST appear **below** it.
|
|
91
85
|
|
|
92
86
|
**Example (Python):**
|
|
93
87
|
|
|
@@ -106,27 +100,23 @@ def _persist_order(order, total): ...
|
|
|
106
100
|
|
|
107
101
|
#### 04-keep-readme-tests-and-examples-in-sync
|
|
108
102
|
|
|
109
|
-
Every change to a public interface, behavior, or configuration option
|
|
103
|
+
Every change to a public interface, behavior, or configuration option MUST be reflected in:
|
|
110
104
|
|
|
111
105
|
- `README.md` — update usage examples, option tables, and feature descriptions.
|
|
112
106
|
- Unit/integration tests — update or add tests that cover the changed behavior.
|
|
113
107
|
- `examples/` resources — update runnable examples so they continue to work.
|
|
114
108
|
|
|
115
|
-
*Why:* Stale documentation and broken examples erode trust and waste time for consumers of the code.
|
|
116
|
-
|
|
117
109
|
---
|
|
118
110
|
|
|
119
111
|
#### 05-declare-types-in-file-where-used
|
|
120
112
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
*Why:* Co-locating a type with its sole consumer removes the need to navigate to a separate types file and makes the type's purpose immediately obvious from context.
|
|
113
|
+
Types used in only **one** file MUST be declared in that same file. Move a type to a shared module only when it is referenced in two or more files.
|
|
124
114
|
|
|
125
115
|
---
|
|
126
116
|
|
|
127
117
|
#### 06-keep-test-files-next-to-source
|
|
128
118
|
|
|
129
|
-
Where the language ecosystem supports it (e.g. JavaScript/TypeScript, Go, Rust),
|
|
119
|
+
Where the language ecosystem supports it (e.g. JavaScript/TypeScript, Go, Rust), test files MUST be placed **beside** the source file they cover and use a consistent naming convention rather than mirroring the source tree in a separate `tests/` folder.
|
|
130
120
|
|
|
131
121
|
**Recommended naming conventions:**
|
|
132
122
|
|
|
@@ -21,7 +21,7 @@ What unit testing practices should be followed to ensure tests are meaningful, r
|
|
|
21
21
|
|
|
22
22
|
#### 01-must-have-at-least-one-assertion-per-test
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
Every test MUST have at least one assertion that validates the expected behavior.
|
|
25
25
|
// bad — no assertion; passes even when code is broken
|
|
26
26
|
it("processes the order", () => { processOrder(mockOrder); });
|
|
27
27
|
|
|
@@ -36,7 +36,7 @@ it("processes the order and returns a confirmation id", () => {
|
|
|
36
36
|
|
|
37
37
|
#### 02-must-run-offline
|
|
38
38
|
|
|
39
|
-
Unit tests
|
|
39
|
+
Unit tests MUST NOT depend on any external resources: no network calls, no running databases, no external APIs, no file system paths outside the repo. Tests must pass with only static code available.
|
|
40
40
|
|
|
41
41
|
```typescript
|
|
42
42
|
// bad — hits a real HTTP endpoint
|
|
@@ -64,13 +64,13 @@ export default defineConfig({
|
|
|
64
64
|
});
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
-
Builds that miss the threshold
|
|
67
|
+
Builds that miss the threshold MUST NOT be merged.
|
|
68
68
|
|
|
69
69
|
---
|
|
70
70
|
|
|
71
71
|
#### 04-must-place-test-files-alongside-source
|
|
72
72
|
|
|
73
|
-
Test files
|
|
73
|
+
Test files MUST live next to the source file they test, in the same directory, following the convention of the language/framework:
|
|
74
74
|
|
|
75
75
|
| Language | Pattern | Example |
|
|
76
76
|
|----------|---------|-------|
|
|
@@ -96,7 +96,7 @@ Do not flatten or reorganize paths when using a separate test folder.
|
|
|
96
96
|
|
|
97
97
|
#### 05-should-extract-shared-setup
|
|
98
98
|
|
|
99
|
-
When setup logic is repeated across two or more test files,
|
|
99
|
+
When setup logic is repeated across two or more test files, it SHOULD be centralized (`src/test-utils/`, `internal/testutil/`, `tests/conftest.py`).
|
|
100
100
|
|
|
101
101
|
```typescript
|
|
102
102
|
// src/test-utils/order-factory.ts
|
|
@@ -109,7 +109,7 @@ export function makeOrder(overrides: Partial<Order> = {}): Order {
|
|
|
109
109
|
|
|
110
110
|
#### 06-should-avoid-mocks
|
|
111
111
|
|
|
112
|
-
|
|
112
|
+
Tests SHOULD use the lowest-cost alternative that exercises real behavior:
|
|
113
113
|
|
|
114
114
|
1. **Real implementation** — always prefer this
|
|
115
115
|
2. **In-memory / lightweight fake** — e.g. in-memory DB, stub HTTP server
|