docs(aura-engine): document to_json JSON schema + integer-token rendering

Resolves the two doc-level findings from the cycle-0009 fieldtest
(docs/specs/fieldtest-0009-run-metrics.md), both the same doc pass on
RunReport::to_json's rustdoc:

  - spec_gap: the JSON key names and {manifest,metrics} nesting were not on the
    public surface — a consumer parsing the JSON (the C18 registry, the deferred
    aura run printer) could not author against it from rustdoc alone. Now stated:
    keys mirror the struct field names in fixed order, window is a 2-element
    [from,to] array, params is an insertion-order object, with a worked sample
    object. Ratifies field-name-mirroring as the contract for the C14 face.
  - friction: a whole-valued f64 renders without a fractional part (12.0 -> 12),
    so one f64 field may appear as an integer or decimal token across runs. Now
    documented, with the consumer guidance to parse as a number, never key off
    token shape.

Doc-only change; no behaviour change. The sample is a `text` fence (not a
doctest). Verified: RUSTDOCFLAGS="-D warnings" cargo doc -p aura-engine clean;
clippy -p aura-engine --all-targets -D warnings clean; doctests 0.

refs #6
This commit is contained in:
2026-06-04 19:06:59 +02:00
parent a982b96ecc
commit 7a8d2097e7
+19 -3
View File
@@ -58,9 +58,25 @@ pub struct RunReport {
impl RunReport {
/// Render canonical, machine-readable JSON (C14). Hand-rolled — the schema
/// is tiny, closed, and flat, so the deliberately zero-dependency workspace
/// stays so. Field order is fixed; `f64` uses the round-trippable `{}`
/// shortest form (finite values only — pip equity and exposure are finite
/// by construction); `params` renders as a JSON object in insertion order.
/// stays so.
///
/// # Shape
///
/// The JSON keys mirror the struct field names, in fixed order, nested as
/// `{"manifest": {…}, "metrics": {…}}`. `window` is a 2-element
/// `[from, to]` array of epoch-ns integers; `params` is a JSON object of
/// `name: value` pairs in insertion order. A run renders as, e.g.:
///
/// ```text
/// {"manifest":{"commit":"abc123","params":{"sma_fast":2,"sma_slow":4},"window":[1,6],"seed":0,"broker":"sim-optimal(pip_size=0.0001)"},"metrics":{"total_pips":12,"max_drawdown":1,"exposure_sign_flips":1}}
/// ```
///
/// `f64` fields use the round-trippable `{}` shortest form (finite values
/// only — pip equity and exposure are finite by construction), so a
/// whole-valued float renders **without** a fractional part (`12.0` → `12`):
/// one `f64` field may appear as an integer token in one run and a decimal
/// token in another. Consumers must parse the value as a number, never key
/// off the token shape.
pub fn to_json(&self) -> String {
let m = &self.manifest;
let mut params = String::from("{");