# Golden fixtures This directory contains **byte-exact reference outputs**, generated from the Rust implementation at commit d20343c before its removal (the CLI defined in its `src/bin/okf.rs`, subcommands `validate` / `info` / `graph` / `fmt` / `index`). They exist to prove that the OKF4net (.NET) port is observably identical to the Rust implementation it replaced (see Tasks 13–15 of the migration plan). ## Layout - `appendix_a/` — the example bundle. Reproduces the `appendix_a()` helper from `tests/bundle.rs` (`datasets/sales.md`, `tables/orders.md`, `tables/customers.md`, byte-for-byte), plus two additions to exercise more of the CLI: - `log.md` — a root-level reserved log file with one valid ISO-8601 dated entry, so `info`/`index` see a non-empty log and `validate` reports no log-related warnings. - `tables/users.md` — a deliberately **non-strict** concept document: it has `type` and `title` but is missing `description` and `timestamp`, so `validate` emits the two "missing recommended frontmatter field" warnings (§11 soft guidance — the bundle stays conformant, exit code 0). - `golden/validate.out` — stdout of `okf validate tests/fixtures/appendix_a`. - `golden/validate.exitcode` — the process exit code of that same run, as a bare ASCII digit with **no trailing newline** (currently `0`). - `golden/info.out` — stdout of `okf info tests/fixtures/appendix_a`. - `golden/graph.dot` — stdout of `okf graph tests/fixtures/appendix_a --dot` (Graphviz DOT source). - `golden/fmt/users.md` — stdout of `okf fmt tests/fixtures/appendix_a/tables/users.md` (parse + re-serialize normalization). - `golden/index-input/` — a full copy of `appendix_a/` **after** running `okf index tests/fixtures/golden/index-input` on it. The `index.md` files written inside it (`index-input/index.md`, `index-input/datasets/index.md`, `index-input/tables/index.md`) are the reference output of the index generator; every other file in the tree is an unmodified copy of the input bundle, included so the whole directory can be diffed/compared as a unit. ## Provenance Generated on 2026-07-21 by building the Rust crate in Docker (cargo is not installed on the host) and running each subcommand against `tests/fixtures/appendix_a`: ``` docker image: rust:1 (pulled digest sha256:9a2cd304a852f05d3352f75bc2775242371c0169a72dbb40d5d881379d571989) rustc 1.97.1 (8bab26f4f 2026-07-14) cargo 1.97.1 (c980f4866 2026-06-30) ``` Build: `cargo build --release` with `CARGO_TARGET_DIR=/tmp/target` (kept outside the mounted worktree so no build artifacts land in git). ## Rules - **These files are byte-exact captures of the (now removed) Rust binary's real output.** Never hand-edit them and never regenerate them from the C# port — if the C# output differs, that is a bug in the port to fix on the C# side (the Rust behavior was the specification of record for Phase 1). They can only be regenerated from the Rust source as of commit d20343c (before its removal), and only if the `appendix_a` bundle itself intentionally changes. - Line endings are exactly what the Rust binary emitted (`\n`, never `\r\n`). The repository's `.gitattributes` marks `tests/fixtures/** -text` so git never normalizes them regardless of `core.autocrlf`. ## v0.1 → v0.2 bump (2026-07-28) The OKF spec bump from v0.1 to v0.2 (provenance §5.1, trust §5.2/§5.3, lifecycle §5.4/§5.5, actor §7, `okf_version` §11/§12) intentionally changes some captured output. Per the exception documented in the repo's `CLAUDE.md`, two kinds of change were made, neither of them a hand-edit and neither of them a re-capture from the (removed) Rust binary: - `golden/validate.out` was **revised**: regenerated by running the C# `okf validate tests/fixtures/appendix_a` from the repo root (the `appendix_a` fixture itself is unchanged). The new content reflects the v0.2 validator's additional legacy-field diagnostics — `appendix_a`'s concepts all still use the v0.1 `timestamp` field with no `generated` block, so each now gets a `... 'timestamp' is a legacy field; prefer 'generated.at'` line (3 of the 4 concepts have `timestamp`) — and the CLI's version banner now reads `✓ conformant with OKF v0.2`. The exit code golden (`validate.exitcode`, `0`) is unchanged: `appendix_a` remains conformant. - **2026-07-29 follow-up:** the legacy-`timestamp` diagnostic was `[warning]`-not-`[info]` from the start, matching the legacy `# Citations` diagnostic. Both §13.1 renames (`timestamp`→`generated.at`, `# Citations`→`sources`) are equally-weighted producer nudges — a v0.2 consumer falls back to the legacy form for both, so the bundle stays conformant either way, but neither rename is a mere formality the validator should stay quiet about. `golden/validate.out` was regenerated the same way as above; the 3 `timestamp` lines moved from `[info]` to `[warning]` and the summary line's counts shifted accordingly (`5 warning(s), 3 info` → `8 warning(s), 0 info`). - `okf_v02/` and `golden/validate-v02.out` / `golden/validate-v02.exitcode` are **new** v0.2 fixtures, hand-authored against the v0.2 spec text (not byte-exact-vs-Rust — v0.2 postdates the Rust reference implementation). `okf_v02/metrics/dau.md` exercises a fully-populated, clean v0.2 document (`generated`/`verified` stamps, `sources`, `usage_window`, `status`, a future `stale_after`); `okf_v02/metrics/legacy.md` exercises three v0.2 validator warnings at once: a malformed `generated.by` actor (`bob`, no `human:`/`process:` prefix), an unknown `status` value (`retired`), and the legacy `# Citations` heading (superseded by the `sources` frontmatter field). Both fixtures were verified by reading each emitted diagnostic against the Task 9 validator rules before saving the golden, not assumed. ## §10 Attested Computation bump (2026-07-29) - `okf_v02_computation/` and `golden/validate-computation.out` / `golden/validate-computation.exitcode` are **new** v0.2 fixtures for §10 (Attested Computation) and its §6.2 (path-valued frontmatter fields) dependency — hand-authored and hand-verified against the v0.2 spec text, like `okf_v02/` above: no reference binary implements §10 either. - `computations/revenue.md` — a fully well-formed **inline** Attested Computation (`runtime: bigquery`, a `parameters` entry, `executor`/ `attester` resources resolving to real files under `computations/references/`, `generated`/`verified`/`sources`, and a future `stale_after`), plus its `# Computation` fenced SQL block. Contributes exactly two diagnostics, both deliberate: its `stale_after` and its `sources[].last_modified` keep the legacy date-only form on purpose, so each raises a `LegacyDateOnlyTimestamp` warning — see "Temporal form (§5)" below, which is where that choice is explained. It contributed none before the §5 work of 2026-08-31. - `computations/revenue-file.md` — the **file-based** variant (`computation: references/computations/revenue.sql`, no fence). Contributes zero diagnostics. - `computations/references/skills/run-on-bq.md` and `computations/references/attesters/revenue.py` / `computations/references/computations/revenue.sql` are the path-valued targets the two concepts above point at; the `.md` one is itself a plain, conformant `Skill` concept (every `.md` file under a bundle root is loaded as a concept, §3), the other two are non-`.md` plain-text targets. - `metrics/revenue.md` — a `Metric` linking `computations/revenue.md` by a normal markdown body link (§10.4), to show an Attested Computation being referenced like any other concept. - `malformed/both.md`, `malformed/broken-exec.md`, `malformed/no-runtime.md` each isolate exactly one §10/§6.2 warning: a `computation:` path declared *together with* an inline `# Computation` fence, an `executor.resource` pointing at a file that does not exist, and an Attested Computation missing the required `runtime` field, respectively. Every field not under test (recommended fields, the other frontmatter path-valued fields) is kept well-formed so each file contributes exactly the one diagnostic it is named for. - Every diagnostic in `validate-computation.out` was verified by reading it against the exact message text and trigger condition in `BundleValidator.Validate` (§10 §7 of the design) before saving the golden, not assumed — including that `runtime` absence, the inline-vs-path ambiguity, and a broken `executor.resource` are all `[warning]`, never `[error]`: §10 sits outside the §11 conformance floor, so a malformed Attested Computation concept stays conformant (exit code `0`). ## §11 conformance fix for malformed reserved files (2026-07-31) - `okf_v02_reserved/` and `golden/validate-reserved.out` / `golden/validate-reserved.exitcode` are **new** v0.2 fixtures for the fix that makes `BundleValidator.ValidateReserved` correctly enforce §11 condition 3 (reserved files must follow their §8/§9 structure) — hand-authored and hand-verified against the actual `BundleValidator` behavior after the fix, like the fixtures above: no reference binary implements this either, and every prior golden fixture predates the fix (all were re-verified during design and confirmed unaffected). - `index.md` (root) declares an extra key beside `okf_version` → `RootIndexExtraFrontmatter`, now `[error]`. - `log.md` (root) has a non-ISO-8601 date heading → `LogDateInvalid`, now `[error]`. - `sub/index.md` (non-root) declares frontmatter → `IndexHasFrontmatter`, now `[error]`. - `broken/index.md` has unparseable YAML frontmatter → `UnparseableIndex`, a brand-new diagnostic for a case that previously produced no diagnostic at all. - `concepts/note.md` is a fully clean concept, contributing zero diagnostics, so every diagnostic in the golden output is attributable to exactly one of the four cases above. - The bundle is **not conformant** (exit code `1`) — this is the point of the fix: all four cases were previously `[warning]` or silent, and the bundle incorrectly validated as conformant (exit code `0`). - `DiagnosticCode.UnparseableIndex`/`UnparseableLog`'s decoder-failure branch (invalid UTF-8 bytes in a reserved file) is exercised by unit tests instead of this fixture — `ValidateTests.Unreadable_index_bytes_are_an_error` and `ValidateTests.Unreadable_log_bytes_are_an_error` write raw invalid UTF-8 bytes directly to `index.md`/`log.md`, the same technique already used elsewhere in this repo for a non-UTF-8 `log.md` (`OkfValidateChangesTests.ChangesSince_skips_a_non_utf8_log_file_with_a_note_instead_of_throwing`). Since `ChangeLog.Parse` never throws, that decoder-failure branch is in fact the *only* way `UnparseableLog` can fire in practice. - Not covered by any test (documented gap, not an oversight): a reserved file that fails to *read* for I/O/permission reasons specifically (as opposed to failing to *decode* or *parse*) — the `IOException`/ `UnauthorizedAccessException` catch clauses in `ValidateReserved`. No reliable, non-flaky, cross-platform way to construct a genuinely unreadable-for-permission-reasons file was found for this repo's Linux/Windows/macOS CI matrix; the code path is identical in shape to the decoder-failure and parse-failure branches that *are* covered (same diagnostic construction, different caught exception type), so the risk of it being wrong is low, but it remains unexercised by an automated test. ## `okf audit` goldens (2026-08-21) - `golden/audit-v02.out`, `golden/audit-v02.json` — output of `okf audit tests/fixtures/okf_v02 --as-of 2099-06-01` (and its `--json` form). **Hand-authored**, verified against the spec text (§5.3 trust tiers, §5.4 statuses, §5.5 staleness) rather than captured from the reference CLI: `audit` is an OKF4net verb with no upstream counterpart. The `--as-of` date is pinned so the output cannot drift with the calendar. ## Temporal form (§5) (2026-08-31) OKF v0.2 §5 requires every timestamp-valued key to be an ISO 8601 datetime with an explicit UTC offset (`2026-06-30T14:00:00Z`). OKF4net reads the legacy date-only form as a fallback and warns (`LegacyDateOnlyTimestamp`), in the same way it handles the §13.1 legacy fields. These two fixtures deliberately cover both paths and **must not be made uniform** — making either match the other silently drops a covered path: - `okf_v02/metrics/dau.md` carries the **conformant** form on every timestamp-valued key it has — `stale_after`, `sources[].last_modified` and both `usage_window` bounds. Revised on 2026-08-31 from the previous date-only values, under the CLAUDE.md exception for a deliberate spec change, citing §5. - `okf_v02_computation/computations/revenue.md` keeps the **legacy** date-only form on purpose, on both its `stale_after` and its `sources[].last_modified`, so `validate-computation.out` captures the fallback warning reaching two different keys rather than only the one everybody thinks of (`stale_after`). The golden pins the rendered text, which is all `Diagnostic.ToString()` emits — severity, path and message. The typed `Field` that tells the two apart is pinned by `ValidateTests.A_legacy_date_only_usage_window_warns_once_per_bound` (and its `last_modified` / `stale_after` neighbours), which assert on `.Field` and `.Code` directly; no golden can, since neither reaches the rendered line. §5 reaches every timestamp-valued key, not just `stale_after`: §5.1 makes `usage_window` a "`{ from, to }` datetime range" and `last_modified` a recency timestamp. §9 is the deliberate exception — `log.md` date headings MUST stay bare `YYYY-MM-DD`, and no fixture here should ever give one a time. Two goldens moved with that revision, both re-derived and inspected line by line rather than blanket-regenerated: - `golden/validate-computation.out` now carries **two** `[warning]` lines for `computations/revenue.md` — one for its date-only `stale_after` and one for its date-only `sources[].last_modified` — and its summary reads `5 warning(s)`, up from the pre-§5 `3 warning(s)`. Two lines rather than one is deliberate: it shows the §5 check reaching both keys on one concept, and each line naming the key it is about. It does **not** show the diagnostic's `Field`: `Diagnostic.ToString()` renders severity, path and message only, so neither `Field` nor `Code` ever reaches a golden. Those are asserted directly in `tests/OKF4net.Tests/ValidateTests.cs` (the `A_legacy_date_only_*` tests). `validate-computation.exitcode` stays `0`: the diagnostic is a `Warning`, and §5 form sits outside the §11 conformance floor. - `golden/audit-v02.json`'s `findings[0].staleAfter` goes `"2099-01-01"` → `"2099-01-01T00:00:00Z"`. That field is the **verbatim raw frontmatter value** (`Lifecycle.StaleAfterRaw`), so it echoes the fixture edit directly. Nothing else in the JSON moved — `staleCount`, `stale` and `asOf` are unchanged, i.e. `okf audit` reaches the same verdict. `golden/audit-v02.out` (the text form) is deliberately **unchanged**: `AuditVocabulary.Freshness` renders the *parsed* date as `yyyy-MM-dd`, so it still reads `stale 2099-01-01` for the now-conformant value. That is the invariant to preserve if this rendering is ever revisited.