> For the complete documentation index, see [llms.txt](https://kerno.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kerno.gitbook.io/docs/core-concepts/scenarios-and-baselines.md).

# Baselines tests

A baseline test reflects how your app currently behaves. Kerno captures your endpoint's current behavior as a test, then assesses every future code change against it. If a change alters how your endpoint behaves, the baseline catches it.

### Test scenarios

Scenarios are the test cases Kerno generates for your endpoints. Each one describes what state to set up, what request to send, what response to expect, and how to verify side effects. They live under `.kerno/scenarios/endpoints/` in your repository as TypeScript files, and are meant to be committed alongside your code.

{% hint style="info" %}
Kerno always writes scenarios in TypeScript, whatever language your application is written in. They reach your app over HTTP, so the language of your service does not matter.
{% endhint %}

A test scenario runs in four phases.

* **Arrange.** Set up any state the test needs, such as seeding a user, obtaining a token, or inserting a row.
* **Act.** Make the request to the endpoint under test.
* **Assert.** Check the response and any observable side effects.
* **Clean up.** Tear down test data and close connections.

### What baseline test record

A baseline records what a correct response looks like. It captures the status code, every field in the response body, and any state the endpoint stored.

Kerno builds the baseline from your endpoint's own data contract, the response types defined in your code. So it checks that every field holds the type and value your handler produces, deciding each expected value from its source:

* A value your handler always produces the same way, like a fixed status code, a constant string, or a field copied straight from the request, is recorded exactly. Any change to it shows up as a diff.
* A value generated fresh on every run, like an id, a token, or a timestamp, is recorded by its format. A new id on each run never counts as a diff.

The baseline also fixes the exact set of fields a response returns. A field the endpoint did not return before shows up as a diff, which is how an accidentally exposed field, like an internal flag or a leaked password hash, gets caught.

### What Kerno tests

Kerno generates two kinds of tests. **Validation tests** check that your endpoint behaves correctly, and **security tests** check that it resists the vulnerabilities that apply to it. When you generate the baseline for an endpoint.

{% hint style="info" %}
Kerno asks which you want, validation, security, or both, unless you have already set that preference in your rules.
{% endhint %}

#### **Validation  tests**

For each endpoint, Kerno generates validation scenarios across several categories of behavior, including:

<table><thead><tr><th width="197.994873046875">Category</th><th width="581.7186279296875">Description</th></tr></thead><tbody><tr><td><strong>Functional API Workflows</strong></td><td>Covers endpoint behaviour, multi step request sequences, coordinated service interactions, and integration patterns across services.</td></tr><tr><td><strong>Contract &#x26; Schema Validation</strong></td><td>Checks request and response structures, data types, required fields, serialization rules, and version compatibility for the API.</td></tr><tr><td><strong>Error Handling &#x26; Resilience</strong></td><td>Validates status codes, error body formats, retry behaviour, backoff procedures, timeout handling, and controlled fallback behaviour.</td></tr><tr><td><strong>Authorization &#x26; Authentication</strong></td><td>Reviews token validation, role based access rules, permission scopes, session handling, and all credential related flows.</td></tr><tr><td><strong>Boundary &#x26; Edge Cases</strong></td><td>Examines payload size limits, pagination behaviour, null or empty values, malformed inputs, and constraint based validation.</td></tr><tr><td><strong>Data Integrity &#x26; Persistence</strong></td><td><p>Confirms data consistency, transaction behaviour, idempotent operations,</p><p>state handling, and enforcement of database rules.</p></td></tr></tbody></table>

### **Security tests**

Security tests baseline your endpoints' security posture. Kerno captures how the endpoint stands up to a specific class of attack today, so if a later change opens that vulnerability, the test starts failing and the regression is caught.

Kerno assesses which **OWASP API and Web Top 10 categories** plausibly apply to the endpoint, given its inputs, its auth model, and what the surrounding code does, then writes tests only for the categories that fit. Common ones include **broken object-level and function-level authorization**, **injection**, **excessive data exposure**, **mass assignment**, and **server-side request forgery**.

### Effort levels

When Kerno creates baseline tests, the effort level sets how hard it tries to prove each one is solid, trading speed for rigor. It defaults to high, so you only lower it when you want a faster, lighter run.

* **Low.** Each test is written and run once. The fastest, cheapest signal.
* **Medium.** Each test runs twice in a row and both runs must pass. This proves the test is genuinely repeatable and exercises a second sample of randomized data.
* **High.** Everything medium does, plus an adversarial review that critiques each finished test and sends it back for repair until it holds up.

The second run is meaningful in itself. If a test passes once and fails the next, that is a real finding, either the test is not isolated or fresh random data hit an edge case worth knowing about.

### How Kerno ensures test quality

Tests run in Kerno's own sandbox against your live application, and every verdict comes from what the checks actually did there. Because the run is independent of your coding agent, the result reflects your application's real behavior.

Two mechanisms guard the tests themselves:

* **Every test is proven repeatable.** Each one runs twice in a row, so a test that only passed because of leftover state gets caught.
* **Every test is reviewed adversarially.** At the high effort mode, each finished test goes through a review that checks it against what it was meant to test and sends it back for repair until it holds up. The review rejects checks weakened or rigged to pass no matter what, errors swallowed silently, tests that verify less than they were meant to, matching loose enough to pass on the wrong value, setup that claims state it never created, hardcoded identifiers where each run needs a fresh one, and teardown that claims to delete something without confirming it did.

### Reading test results

Each scenario reports one of four verdicts.

* **Passed** — the scenario ran and the endpoint behaved as expected.
* **Failed** — the endpoint did something the scenario did not expect.
* **Blocked** — the scenario could not run, usually because a dependency it needs is not configured. Blocked is neither a pass nor a fail; nothing was tested.
* **Not implemented** — Kerno could not produce a working scenario for this case. This is reported honestly rather than counted as a pass.

A passing scenario may also carry a **potential bug**, where Kerno found the endpoint doing something unexpected, confirmed it against your source, and documented the real behaviour. See [Security testing](broken://pages/O6yzFP71JRsEJbcJIs0s) for how to review and dismiss these.

#### Potential bugs

A baseline test can carry a **potential bug tag**. Kerno noticed the endpoint doing something unexpected, confirmed it against your source code, and wrote the test to document that real behavior. The flag names what deviated, its root cause with a specific code location, and what a future change would signify.

A potential bug flags behavior worth your attention on a test that otherwise passes. If you review it and decide the behavior is known or intended, tell your agent to ignore it:

> "The `role` field Kerno flagged on `GET /users/:id` is intentional, we keep returning it for backwards compatibility. Have Kerno ignore that potential bug."

An ignore decision is recorded in Kerno's memory for that endpoint, alongside the code revision you made it against. Because that record is git-tracked, you can reverse the decision by removing it from Kerno's memory. See [Memory and learning](/docs/core-concepts/memory-and-learning.md).
