# Example fixture

A small project that exercises acceptance examples 1–5, 7, and 8 from [SPEC.md](../SPEC.md) so an implementation can be validated against a known target. Example 6 (missing manifest) is exercised by running the tool against a directory with no `traceable-reqs.toml`, so it doesn't fit a static fixture — see "What this fixture does NOT cover" at the bottom.

Run the tool from this directory:

```text
cd example
traceable-reqs check --json > actual.json
```

Then compare `actual.json` against `expected.json` per the rules in [What counts as a match](#what-counts-as-a-match-against-expectedjson). Array ordering is implementor-defined, so a raw `diff` will report spurious differences — normalize both files first (e.g. `jq -S` plus `sort_by` on `requirements[]`, `findings[]`, and each `stages.*.evidence[]`).

## Layout

- `traceable-reqs.toml` — manifest with three declared requirements, a custom `qc` stage, and a `[[signoffs]]` entry pointing at a fake GitHub issue comment URL. The `[policy]` block restates the spec default so REQ-LOGOUT-001's inheritance is visible alongside REQ-LOGIN-001's broader override and REQ-AUDIT-001's narrower override.
- `src/`, `docs/`, `tests/` — scanned roots.
- `expected.json` — the JSON document the tool should emit.

## What each requirement exercises

| ID | `required_stages` | What it covers |
|----|-------------------|----------------|
| `REQ-LOGIN-001` | `doc, impl, unit, int, qc` | Complete trace across all four built-in stages (acceptance example 1). Its `impl` evidence shares a multi-tag line with `REQ-AUDIT-001` (acceptance example 5). The `qc` stage is satisfied entirely by a manifest-declared `[[signoffs]]` URL (acceptance example 8). |
| `REQ-LOGOUT-001` | inherits policy `doc, impl, unit` | Missing `impl` evidence; emits `missing_stage` (acceptance example 2). |
| `REQ-AUDIT-001` | `doc, impl, qc` (narrows the policy, adds custom stage) | Per-requirement override: `unit` and `int` are not required, so `complete: false` on those stages does not emit a finding. Its `impl` stage has block-comment evidence in `src/audit.cpp` to exercise C/C++ block-comment scanning. The `qc` stage is satisfied by a `[qc->REQ-AUDIT-001]` tag in `docs/audit.md` (acceptance example 7). |

## Findings the tool should emit

| Code | Where | Why |
|------|-------|-----|
| `missing_stage` | `REQ-LOGOUT-001` / `impl` | No `[impl->REQ-LOGOUT-001]` tag exists. |
| `undeclared_id` | `src/typos.py:3` | `[impl->REQ-LOGNI-001]` is a typo of `REQ-LOGIN-001` (acceptance example 3). |
| `parse_error` | `src/audit.cpp:3` | `[test->REQ-LOGIN-001]` uses an unknown stage (acceptance example 4). |

## What counts as a match against `expected.json`

The stable contract is the **set** of findings and the per-requirement stage status, not array ordering or message prose.

When comparing:

- Treat `requirements[]` and `findings[]` as sets — sort consistently before diffing. The tool's own output order is implementor-defined.
- Treat `message` text as illustrative; only `code`, `requirementId`, `stage`, `path`, and `line` are stable per the spec.

## Review needles

This fixture deliberately contains one **planted misplaced tag** so the `review` command's agent prompt has something concrete to find when it runs against the fixture. The trace tool itself does not flag it (the tag is structurally valid); only an agent inspecting the surrounding code can spot the placement bug.

| Location | Tag | Why it is wrong |
|----------|-----|-----------------|
| `tests/auth_test.py:11` | `[unit->REQ-AUDIT-001]` | The function `test_rejects_invalid_credentials` exercises sign-in credential rejection, not audit logging. The correct requirement is `REQ-LOGIN-001`. Suggested action: `move` (or `rewrite-code` to actually test audit behaviour). |

When you run `traceable-reqs review` against this fixture and hand the prompt to an agent, the expected output is a `tag-placement` finding pointing at this row. Use it as a quick smoke test of the review pipeline.

## What this fixture does NOT cover

- `manifest_error` — the manifest here is valid by construction. Exercise this code by running the tool with no `traceable-reqs.toml` or with a malformed one.
- `scan_error` — every scanned file is readable. Exercise this code by making a scanned file unreadable at runtime (e.g., revoking read permissions, or a broken symlink if the implementation follows links).

These two codes are operational rather than file-shaped, so they belong in the implementation's own test harness, not in this fixture.
