Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -204,12 +204,12 @@ jobs:

trace-self-validate:
# Dogfood the tool's own trace format against its own source.
# `tool/trace/{sys,hlr,llr,tests}.toml` covers the full DO-178C
# `cert/trace/{sys,hlr,llr,tests}.toml` covers the full DO-178C
# §5.1 chain (SYS → HLR → LLR → Test); a validation failure here
# means either a link broke (UUID renamed without a corresponding
# edit) or the format can't express something new we tried to
# write — the latter is a format-change ticket recorded in
# `tool/trace/README.md`, not a bug in this job.
# `cert/trace/README.md`, not a bug in this job.
#
# `needs: check` intentionally NOT set — runs in parallel, does
# its own release build. Linux-only; trace validation is
Expand Down Expand Up @@ -241,7 +241,7 @@ jobs:
- name: Build release binary
run: cargo build --release -p cargo-evidence

- name: Validate tool/trace (enforcement flags on, discovery picks tool/trace)
- name: Validate cert/trace (enforcement flags on, discovery picks cert/trace)
run: |
# Trace-only validation — fast, no `cargo test` run.
# `check .` (below) is the agent-facing one-shot that also
Expand Down Expand Up @@ -327,9 +327,9 @@ jobs:
# without a UUID — the pre-commit workflow missed a step.
out=$(./target/release/cargo-evidence evidence trace \
--backfill-uuids \
--trace-roots tool/trace 2>&1)
--trace-roots cert/trace 2>&1)
if printf '%s' "$out" | grep -qE 'assigned [1-9]'; then
echo "::error::tool/trace/*.toml contains entries without UUIDs. Run \`cargo evidence trace --backfill-uuids --trace-roots tool/trace\` locally and commit."
echo "::error::cert/trace/*.toml contains entries without UUIDs. Run \`cargo evidence trace --backfill-uuids --trace-roots cert/trace\` locally and commit."
printf '%s\n' "$out"
exit 1
fi
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,9 @@ jobs:
run: |
for crate in evidence-core cargo-evidence evidence-mcp; do
cargo package --list -p "$crate" --allow-dirty > /tmp/pkg-"$crate".txt
if grep -qE '^(tool/trace|cert/baselines)/' /tmp/pkg-"$crate".txt; then
if grep -qE '^(cert/trace|cert/baselines)/' /tmp/pkg-"$crate".txt; then
echo "::error::Tarball for $crate contains workspace-root paths"
grep -E '^(tool/trace|cert/baselines)/' /tmp/pkg-"$crate".txt
grep -E '^(cert/trace|cert/baselines)/' /tmp/pkg-"$crate".txt
exit 1
fi
done
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ cargo evidence --format=jsonl check . # streaming per-requirement d

In source mode, `check` runs `cargo test --workspace`, parses outcomes,
and emits one `REQ_PASS` / `REQ_GAP` / `REQ_SKIP` diagnostic per
requirement in the discovered trace (`tool/trace/` or `cert/trace/`).
requirement in the discovered trace (`cert/trace/` or `cert/trace/`).
`REQ_GAP` events carry a `FixHint` for mechanically-fixable cases
(missing UUID, empty `traces_to` under policy, dangling
`test_selector`), and derived GAPs at higher layers carry
Expand Down Expand Up @@ -491,9 +491,9 @@ diagnostic_codes = 10 # evidence_core::RULES.len() if you use it
Only the dimensions you list are enforced — missing ones are
skipped, not assumed-zero. Point at a custom path via
`cargo evidence floors --config path/to/floors.toml` if your layout
differs. Measurement helpers that need workspace subdirs (`tool/trace/`,
differs. Measurement helpers that need workspace subdirs (`cert/trace/`,
`crates/*/src/`) gracefully degrade to 0 when the dirs are absent,
so a single-crate project without a `tool/trace/` directory can
so a single-crate project without a `cert/trace/` directory can
still enforce `test_count` and `diagnostic_codes` without
configuring the other dimensions.

Expand All @@ -513,7 +513,7 @@ consumes; every code here is (a) backed by a
`DiagnosticCode::code()` impl or by the `TERMINAL_CODES` /
`HAND_EMITTED_CLI_CODES` sets, and (b)
claimed by at least one LLR's `emits` list in
`tool/trace/llr.toml`. Four bijection invariants in
`cert/trace/llr.toml`. Four bijection invariants in
`diagnostic_codes_locked` fail CI if those relationships ever drift
— adding a code without updating `RULES` or writing an owning LLR
is not possible silently.
Expand Down Expand Up @@ -725,7 +725,7 @@ crates/
evidence-mcp/ # MCP (Model Context Protocol) server binary
schemas/ # JSON schemas for bundle files
cert/ # Certification configuration (boundary, profiles, floors)
tool/trace/ # SYS / HLR / LLR / Test chain (this project's own trace)
cert/trace/ # SYS / HLR / LLR / Test chain (this project's own trace)
tools/ # Repo utilities (install-hooks.sh, regen-golden-fixtures.sh)
scripts/ # CI mirror (local-ci.sh)
```
Expand Down
14 changes: 7 additions & 7 deletions cert/boundary.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ version = "0.0.1"
[scope]
in_scope = ["evidence-core", "cargo-evidence", "evidence-mcp"]

# Trace root directories (relative to workspace root). This repo's
# self-trace lives at `tool/trace/`; auto-discovery in
# `default_trace_roots()` already prefers that location, but the
# boundary.toml value is the documented fallback auditors read first.
# Keep the two in sync so an auditor opening this file doesn't head
# to a non-existent directory.
trace_roots = ["tool/trace"]
# Trace root directories (relative to workspace root). The
# canonical layout puts traces under `cert/trace/` alongside this
# config; `default_trace_roots` discovers that location
# automatically. The explicit value here is documentary so an
# auditor opening this file knows exactly where the trace lives
# without having to read the discovery code.
trace_roots = ["cert/trace"]

# Workspace crates explicitly forbidden as dependencies
explicit_forbidden = []
Expand Down
10 changes: 5 additions & 5 deletions cert/floors.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,13 @@ diagnostic_codes = 151
# DOCTOR_OK / DOCTOR_FAIL).
terminal_codes = 13

# tool/trace/sys.toml — System Requirements.
# cert/trace/sys.toml — System Requirements.
trace_sys = 28
# tool/trace/hlr.toml — High-Level Requirements.
# cert/trace/hlr.toml — High-Level Requirements.
trace_hlr = 66
# tool/trace/llr.toml — Low-Level Requirements.
# cert/trace/llr.toml — Low-Level Requirements.
trace_llr = 73
# tool/trace/tests.toml — Test Cases.
# cert/trace/tests.toml — Test Cases.
trace_test = 78

# evidence_core::trace::surfaces::KNOWN_SURFACES length — hand-curated
Expand All @@ -78,7 +78,7 @@ known_surfaces = 21

[per_crate.evidence-core]
# `#[test]` attribute count inside crates/evidence-core/**/*.rs.
test_count = 355
test_count = 358

[per_crate.cargo-evidence]
test_count = 134
Expand Down
8 changes: 4 additions & 4 deletions tool/trace/README.md → cert/trace/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,12 @@ Observation: `cargo evidence trace --backfill-uuids` writes each file
back via `toml::to_string_pretty`, which does not preserve comments.
PR #44's hand-written top-of-file commentary and inter-entry group
headers were lost when the UID rotation ran. Minimal `#
tool/trace/<name>.toml — … (see ../README.md)` headers were
cert/trace/<name>.toml — … (see ../README.md)` headers were
reinstated by hand; the richer commentary is now in `README.md`
only.

Workaround: treat README.md as canonical documentation, use brief
`# tool/trace/<name>.toml — …` file headers that survive backfill
`# cert/trace/<name>.toml — …` file headers that survive backfill
because the stripper only rewrites `[[sections]]`. Accept the loss
of inter-entry group separators for now.

Expand Down Expand Up @@ -149,7 +149,7 @@ unaffected; the tool's own CI enables it.

#### [2026-04 · PR #44b · closed] UUIDs rotated, hand-crafting banned

The original `tool/trace/*.toml` files landed in PR #44 used
The original `cert/trace/*.toml` files landed in PR #44 used
hand-authored deterministic UUIDs (`11…000001` per-layer-prefix
scheme). Pre-ship is cheap to rotate — PR #44b replaced every UID
with a real machine-generated v4 from `trace --backfill-uuids` and
Expand Down Expand Up @@ -256,7 +256,7 @@ Independent enforcement signals on the SYS contract (as of PR #44b):
2. `TEST-021` (integration test) asserts the above path fires.
3. `TEST-022` (integration test) asserts `--check-test-selectors`
fires on a dangling selector.
4. `TEST-023` (integration test) asserts `tool/trace/` discovery
4. `TEST-023` (integration test) asserts `cert/trace/` discovery
works without `--trace-roots`.
5. `TEST-024` (`ci_self_check`) greps the committed `ci.yml` to
assert both enforcement flags are wired on `trace-self-validate`.
Expand Down
8 changes: 4 additions & 4 deletions tool/trace/hlr.toml → cert/trace/hlr.toml
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ owner = "tool"
scope = "component"
description = """
When --trace-roots is absent, `cargo evidence trace` discovers
./tool/trace/ first, then ./cert/trace/, using the first that exists.
./cert/trace/ first, then ./cert/trace/, using the first that exists.
Explicit --trace-roots always wins; discovery only fires on absence.
The chosen root is logged via tracing::info!.
"""
Expand Down Expand Up @@ -824,10 +824,10 @@ owner = "tool"
scope = "component"
description = '''
A Rust integration test walks `.rs` under `crates/**/{src,tests}/**`,
`.md` files (excluding `tool/trace/README.md`), and non-
`tool/trace/` `.toml` files. Every match of
`.md` files (excluding `cert/trace/README.md`), and non-
`cert/trace/` `.toml` files. Every match of
`\b(SYS|HLR|LLR|TEST|DERIVED)-\d+\b` must resolve to an entry
in the loaded `tool/trace/` set (parsed via
in the loaded `cert/trace/` set (parsed via
`read_all_trace_files`), partitioned by kind. Unresolved refs
fire the gate via `assert!` with the offending `file:line` +
the ghost identifier; no `Diagnostic` wire shape, no new `RULES`
Expand Down
12 changes: 6 additions & 6 deletions tool/trace/llr.toml → cert/trace/llr.toml
Original file line number Diff line number Diff line change
Expand Up @@ -499,14 +499,14 @@ verification_methods = ["test"]
[[requirements]]
uid = "6be1b61b-0aeb-4c05-b2ef-f82fc7c00e55"
id = "LLR-023"
title = "default_trace_roots picks tool/trace or cert/trace"
title = "default_trace_roots picks cert/trace or cert/trace"
owner = "tool"
traces_to = ["911fe168-04d7-49ee-99f4-d7a5a7a6fb1c"]
modules = ["cargo_evidence::cli::trace::default_trace_roots"]
derived = false
description = """
default_trace_roots returns Option<Vec<String>> by probing for
./tool/trace/ then ./cert/trace/. cmd_trace calls it only when
./cert/trace/ then ./cert/trace/. cmd_trace calls it only when
--trace-roots is absent; explicit flag always wins. Logs chosen root
via tracing::info!.
"""
Expand Down Expand Up @@ -678,7 +678,7 @@ derived = false
description = """
`LlrEntry` gains `emits: Vec<String>` with `#[serde(default,
skip_serializing_if = "Vec::is_empty")]`. A locked-codes invariant
loads `tool/trace/llr.toml` via `read_all_trace_files`, collects
loads `cert/trace/llr.toml` via `read_all_trace_files`, collects
the union of `emits` across all LLRs, and asserts that union
equals `RULES.code` minus an explicit `reserved_unclaimed` set. The
invariant also asserts every `emits` string is a real code in
Expand Down Expand Up @@ -721,7 +721,7 @@ Two integration tests under `crates/cargo-evidence/tests/` run
on a committed synthetic source tree, normalize known-
nondeterministic fields (timestamps; libtest `finished in`
durations), and byte-diff against committed fixture files. The
synthetic source tree is independent of `tool/trace/` so the
synthetic source tree is independent of `cert/trace/` so the
fixture doesn't drift when the tool's own self-trace grows.
"""
verification_methods = ["test"]
Expand Down Expand Up @@ -1039,8 +1039,8 @@ derived = false
description = '''
A Rust `#[test] fn` in
`crates/evidence-core/tests/trace_id_refs_locked.rs` walks `.rs` under
`crates/**/{src,tests}/**`, `.md` (excluding `tool/trace/README.md`),
and `.toml` outside `tool/trace/`. Greps
`crates/**/{src,tests}/**`, `.md` (excluding `cert/trace/README.md`),
and `.toml` outside `cert/trace/`. Greps
`\b(SYS|HLR|LLR|TEST|DERIVED)-\d+\b`, loads trace IDs via
`evidence_core::read_all_trace_files`, partitions grep'd refs by kind,
asserts each exists. Fails via `assert!` with sorted
Expand Down
6 changes: 3 additions & 3 deletions tool/trace/sys.toml → cert/trace/sys.toml
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ traces_to = []
[[requirements]]
uid = "b1ddaec0-7981-491e-910f-6d04e1888f63"
id = "SYS-014"
title = "Every narrative trace-ID reference (SYS/HLR/LLR/TEST/DERIVED-NNN) in source and docs shall resolve to a real entry in tool/trace/"
title = "Every narrative trace-ID reference (SYS/HLR/LLR/TEST/DERIVED-NNN) in source and docs shall resolve to a real entry in cert/trace/"
owner = "soi"
scope = "soi"
description = '''
Expand All @@ -267,7 +267,7 @@ breaks cross-file pointers silently. The existing PR #47
bijection covers `LLR.emits ⇔ RULES` — a narrower axis than
"comments and docs reference real trace items." The tool shall
mechanically assert that every `(SYS|HLR|LLR|TEST|DERIVED)-\d+`
reference in `.rs` / `.md` / non-`tool/trace` `.toml` sources
reference in `.rs` / `.md` / non-`cert/trace` `.toml` sources
resolves to an `id` field in the corresponding trace file,
failing CI with the offending `file:line` pairs when a reference
becomes stale.
Expand Down Expand Up @@ -514,7 +514,7 @@ title = "Trace validation shall resolve references to every configured requireme
owner = "soi"
scope = "soi"
description = """
`tool/trace/derived.toml` is one of the four requirement-kind
`cert/trace/derived.toml` is one of the four requirement-kind
files cargo-evidence templates via `cargo evidence init`. A
trace-validate run that silently drops derived requirements
leaves cross-file `traces_to` pointing at derived UIDs as
Expand Down
4 changes: 2 additions & 2 deletions tool/trace/tests.toml → cert/trace/tests.toml
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ test_selector = "trace_sys_layer::selector_check_flags_dangling_selector"
[[tests]]
uid = "f9278d5b-373f-4493-a607-0e105ac84a0a"
id = "TEST-023"
title = "Trace defaults to tool/trace when --trace-roots is absent"
title = "Trace defaults to cert/trace when --trace-roots is absent"
owner = "tool"
traces_to = ["6be1b61b-0aeb-4c05-b2ef-f82fc7c00e55"]
test_selector = "trace_discovery::trace_defaults_to_tool_trace_when_flag_absent"
Expand Down Expand Up @@ -473,7 +473,7 @@ owner = "tool"
traces_to = ["ec50f98b-9a1d-4f7b-bc33-df56c7faab2a"]
description = """
Integration tests in `crates/cargo-evidence/tests/doctor_cmd.rs`:
- Rigorous fixture (synthetic repo with tool/trace, cert/floors.toml,
- Rigorous fixture (synthetic repo with cert/trace, cert/floors.toml,
cert/boundary.toml, .github/workflows/ci.yml mentioning cargo
evidence, README with `Override-Deterministic-Baseline:`) exits 0
with `DOCTOR_OK` terminal and one `_OK` diagnostic per check.
Expand Down
2 changes: 1 addition & 1 deletion crates/cargo-evidence/src/cli/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ pub enum Commands {
/// When set, an HLR with empty `traces_to` fails Link-phase
/// validation. Off by default; projects without a SYS layer
/// keep validating cleanly. The tool's own CI enables this
/// flag on `tool/trace/` to keep the SYS layer load-bearing.
/// flag on `cert/trace/` to keep the SYS layer load-bearing.
#[arg(long)]
require_hlr_sys_trace: bool,

Expand Down
6 changes: 3 additions & 3 deletions crates/cargo-evidence/src/cli/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//! Dispatches on argument shape (auto mode) or explicit `--mode`:
//!
//! - **Source mode.** Runs `cargo test --workspace --no-fail-fast`,
//! parses stdout into a per-test outcome map, walks `tool/trace/`
//! parses stdout into a per-test outcome map, walks `cert/trace/`
//! (or `cert/trace/` via discovery), emits one
//! `REQ_PASS` / `REQ_GAP` / `REQ_SKIP` diagnostic per requirement.
//! Each `REQ_GAP` for a derived failure carries `root_cause_uid`;
Expand Down Expand Up @@ -226,12 +226,12 @@ fn cmd_check_source(workspace_root: &Path, format: OutputFormat, quiet: bool) ->
}
};

// Phase 3: load trace. Discovery picks tool/trace → cert/trace per
// Phase 3: load trace. Discovery picks cert/trace → cert/trace per
// LLR-023; fall back to cert/boundary.toml otherwise. Every path
// resolves against `workspace_root` — the argument to
// `check --mode=source <PATH>` — NOT the process CWD. An auditor
// invoking `check --mode=source /downstream` from a parent
// directory gets `/downstream/tool/trace/` discovered, not the
// directory gets `/downstream/cert/trace/` discovered, not the
// caller's own.
if show_progress {
eprintln!("check: validating trace…");
Expand Down
2 changes: 1 addition & 1 deletion crates/cargo-evidence/src/cli/doctor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//! The six MVP checks:
//!
//! - **trace validity** (`DOCTOR_TRACE_INVALID` on fail) — load
//! `tool/trace/` and run the SYS / surface / selector bijections
//! `cert/trace/` and run the SYS / surface / selector bijections
//! the tool's own CI enables on itself.
//! - **floors present + satisfied**
//! (`DOCTOR_FLOORS_MISSING` / `DOCTOR_FLOORS_VIOLATED`) — load
Expand Down
Loading
Loading