Milestone-scope fieldtest (the functional leg of the Walking-skeleton
milestone-close gate), from the public interface only. Three end-to-end
scenarios, all green:
- the newcomer CLI path: `aura run` -> single-line {manifest,metrics} JSON,
exit 0, byte-identical twice (C1), non-degenerate trace (C22), bad-args ->
exit 2;
- the real-data thread: real AAPL.US 2006-08 M1 bars -> load_m1_window ->
close_stream -> SMA-cross -> Exposure -> SimBroker -> summarize -> RunReport,
deterministic AND populated;
- epoch-ns coherence: C3 normalization holds ingest -> run -> sink.
Roll-up: the milestone DELIVERS its promise end to end (ingest -> one signal ->
exposure -> sim-optimal broker -> pip-equity metric -> structured RunReport,
deterministic, populated) on BOTH the synthetic and real-data paths. 0 bugs.
Headline concern (verified by the orchestrator): issue #19's premise is WRONG at
the shipped SMA(2)/SMA(4) demo config — 21 AAPL.US bars warm the cross and
produce a populated trace (total_pips=-1.5, max_drawdown=65.5, 6 sign flips),
not all-zero. The degeneracy #19 saw was deep-SMA/param-dependent, not intrinsic
to the symbol. #19 to be re-scoped. Other findings: `aura run <junk>` exit 0
(already #16), `aura --help` lands on the exit-2 error path (friction), SimBroker
two-f64-slot order unchecked at bootstrap (documented footgun) — both filed.
11 KiB
Fieldtest — milestone "Walking skeleton" — 2026-06-04
Status: Draft — awaiting orchestrator triage Author: fieldtester (dispatched by fieldtest skill, milestone-scope variant) Scope mode: MILESTONE (closing functional gate), not per-cycle.
Scope
The "Walking skeleton" milestone (Gitea Brummel/Aura issues #4–#8) promises a
runnable end-to-end thread (design ledger INDEX.md ~line 20): ingest → one
signal (SMA-cross) → exposure/intent stream → sim-optimal broker → synthetic
pip-equity signal-quality metric, foldable into a structured RunReport
(manifest + metrics, C18/C14), deterministic (C1), reachable via the aura run
CLI (#8), and — per C22 — populated enough that "a newcomer sees a populated
trace immediately."
This fieldtest derives three end-to-end scenarios top-down from that promise and
drives them from the public interface only (the aura binary's observable
behaviour, rustdoc, INDEX.md, public re-exports, data-server's public rustdoc).
No crates/*/src was read. The artefact under test was built from HEAD
(cargo build -p aura-cli; the consumer crate compiled against the current
path-dep'd engine crates).
Examples
fieldtests/milestone-walking-skeleton/ms_1_newcomer_cli.sh — the newcomer CLI path
- Invokes the real
target/debug/aurabinary (built from HEAD) as a downstream user with nothing but the rustdoc module blurb. Checks: single-line JSON RunReport with the documented{manifest, metrics}shape; exit 0; byte-identical across two runs (C1); a NON-degenerate trace (≥1 exposure sign flip, C22); and the bad-args / usage contract. - Fits the promise: this is the one-command surface the milestone says makes the whole thread runnable, and the C22 "populated trace" demonstrator.
- Outcome: built? yes. ran? yes. matched expected? yes — single-line
{manifest,metrics}, exit 0, byte-identical, metricstotal_pips=-0.13, max_drawdown=0.17, exposure_sign_flips=1(populated). Bad/empty subcommand → exit 2,aura: usage: aura runon stderr, empty stdout.
fieldtests/milestone-walking-skeleton/ms_2_real_data_thread.rs — the real-data thread
- A standalone consumer crate (own
[workspace], path-deps on aura-core/std/engine/ingest + git dep on data-server — the shape a C16 project takes) wires the WHOLE thread over real recorded M1 bars:load_m1_window(AAPL.US, 2006-08) → close_stream → SMA(2)/SMA(4) → Sub → Exposure(0.5) → SimBroker(1e-4) → 2×Recorder → f64_field → summarize → RunReport, then folds the report twice and asserts determinism. - Fits the promise: this is the literal ingest→…→metric thread over REAL bars, the substance #7 + the milestone claim.
- Outcome: built? yes, first try. ran? yes (21 M1 bars ingested). matched
expected? yes, and better than the carrier predicted — the run is
deterministic (cross-process byte-identical RunReport, C1) AND non-degenerate:
total_pips=-1.5, max_drawdown=65.5, exposure_sign_flips=6. Window timestamps are canonical epoch-ns. See finding [spec_gap] on the #19 premise.
fieldtests/milestone-walking-skeleton/ms_3_epoch_ns_coherence.rs — epoch-ns coherence
- Hand-builds 4
M1Parsedbars (data-server's public AoS record) with knowntime_ms, runstranspose_m1 → close_stream → SMA(2) → Recorder, and asserts the recorded sink-trace timestamps equalunix_ms_to_epoch_ns(time_ms)(= ms·1e6) — the C3 normalization carried intact from ingest through the run loop into the recorded metric stream. No external data needed. - Fits the promise: closes the loop on C3 ("normalize at the one boundary") — proves the metric stream a newcomer reads is in aura's canonical time unit.
- Outcome: built? yes. ran? yes. matched expected? yes — ingest stamps
[…400e9, …460e9, …520e9, …580e9]; sink trace is the warmed suffix in the same epoch-ns stamps.
Findings
[working] The full real-data thread is authorable from the public interface and is deterministic + populated
- Example: ms_2_real_data_thread.rs.
- What happened: the entire ingest→signal→exposure→broker→metrics→RunReport thread compiled on the first attempt from rustdoc signatures alone (Harness::bootstrap, Edge/Target/SourceSpec field layout, summarize/f64_field, the aura-std node ctors, load_m1_window/close_stream). Two in-process folds and two separate processes produced byte-identical RunReports.
- Why working: the milestone's headline promise — a real ingest→metric thread, deterministic (C1) — is delivered, and the public surface is self-sufficient for a downstream author to wire it. This is the milestone's central win.
- Recommended action: carry-on.
[working] aura run delivers the C22 populated-trace newcomer path
- Example: ms_1_newcomer_cli.sh.
- What happened: one command, single-line
{manifest,metrics}JSON, exit 0, byte-identical twice, non-degenerate (1 sign flip, real drawdown). Bad/missing subcommand → exit 2 + usage on stderr + empty stdout. - Why working: C22 ("a newcomer sees a populated trace immediately") and C14 (structured face from a binary) are both satisfied by the shipped binary.
- Recommended action: carry-on.
[working] C3 epoch-ns normalization is coherent end to end
- Example: ms_3_epoch_ns_coherence.rs.
- What happened:
close_streamtimestamps equalunix_ms_to_epoch_ns(time_ms), and the recorded sink trace carries exactly those epoch-ns stamps (warmed suffix). ms·1e6 holds. - Why working: C3's "one boundary normalizes, nowhere else" is observably true through ingest → run → sink; the metric stream is in canonical time.
- Recommended action: carry-on.
[spec_gap] The #19 "AAPL.US too sparse → degenerate metrics" premise does NOT hold for the SMA(2)/SMA(4) demo config
- Example: ms_2_real_data_thread.rs.
- What happened: the carrier (and issue #19, from the cycle-0011 per-cycle
fieldtest) asserts AAPL.US 2006 is too sparse (~21 M1 bars/month) to warm an
SMA-cross, so the real-data run yields all-zero degenerate metrics. Empirically
this is false for the SMA(2)/SMA(4) cross (the same fast/slow pair the shipped
aura runsample uses): 21 bars warm SMA(4) after 4 bars, the cross produces 6 exposure sign flips,total_pips=-1.5,max_drawdown=65.5— a populated, non-degenerate trace over REAL bars. The degeneracy #19 observed is window/param-dependent (a deeper SMA, e.g. the longer lengths a realistic daily cross would use, would not warm on 21 bars), not intrinsic to the symbol. - Why spec_gap: the milestone never pins the "real-data demo" SMA lengths or
window, so two equally-plausible readings diverge on whether the real-data path
is degenerate. I picked the shipped
aura runconfig (SMA 2/4); under it the real-data thread is populated, not degenerate. The honest milestone roll-up therefore differs from the carrier's pre-stated assumption: the real-data thread is also a populated-trace demonstrator at the shipped param config, not merely "correct but degenerate." #19's concern remains valid for deeper SMAs / the C22 "name a denser demo symbol" recommendation, but it is not a blocker and the milestone promise is met on real bars at the demo config. - Recommended action: ratify (record that the walking-skeleton real-data demo is pinned to SMA 2/4 over 2006-08 and is populated there) AND re-scope #19 to "denser demo data for deep/daily crosses" rather than "real path is degenerate" — the latter is no longer accurate.
[spec_gap] aura run <trailing junk> → exit 0, trailing args silently ignored
- Example: ms_1_newcomer_cli.sh (
aura run extra junk→ exit 0, full report). - What happened: the arg parser keys only on the first token being
runand ignores everything after.aura run garbageruns the sample harness and exits 0. - Why spec_gap: re-confirmation at the milestone gate of the cycle-0010 finding
(already filed). The milestone's CLI contract does not unambiguously cover
run <extra>; the binary chose the lenient reading. Not a regression — same behaviour as cycle-0010. - Recommended action: ratify-or-tighten (decide whether trailing args reject with exit 2 or are deliberately ignored). Low priority; carried from #?/cycle-0010.
[friction] aura --help lands on the error path (exit 2, bare usage line)
- Example: ms_1_newcomer_cli.sh (
aura --help→ exit 2,aura: usage: aura runon stderr, empty stdout). - What happened: a newcomer's reflex first command (
--help) is treated as an unknown subcommand: exit 2, no help text, just the one-line usage on stderr. - Why friction: the task (discover how to run) completes — the usage line does
name
aura run— but the conventional discovery affordance returns a nonzero error path rather than help on stdout. For a "newcomer sees a populated trace" milestone (C22), the first-contact ergonomics are slightly off. - Recommended action: plan (tidy) — make
--help/-hprint the usage to stdout with exit 0; keep unknown subcommands at exit 2. Trivial, optional.
[friction] SimBroker slot order is load-bearing, both f64, unchecked at bootstrap
- Example: ms_2_real_data_thread.rs (had to consult rustdoc to wire slot 0 = exposure, slot 1 = price correctly).
- What happened: SimBroker's two inputs are both
f64, so a swapped wiring is not caught at bootstrap (the rustdoc explicitly warns it "would silently produce a wrong equity curve"). The downstream author must read prose to get it right; there is no typed guard. - Why friction: the thread is wireable correctly only by reading the rustdoc carefully — a known, documented footgun, but a footgun. Not a bug (it is documented and the wiring API offers no kind to distinguish the two f64 slots).
- Recommended action: plan (consider a named-role or distinct-newtype wiring for broker inputs in a later cycle); or carry-on if deemed acceptable given the rustdoc warning. Documented, so low urgency.
Recommendation summary
| Finding | Class | Action |
|---|---|---|
| Real-data thread authorable, deterministic, populated | working | carry-on |
aura run C22 populated-trace newcomer path |
working | carry-on |
| C3 epoch-ns coherence ingest→run→sink | working | carry-on |
| #19 "real path degenerate" false at SMA 2/4 demo config | spec_gap | ratify + re-scope #19 |
aura run <junk> → exit 0 (lenient) |
spec_gap | ratify-or-tighten |
aura --help → exit 2, no help text |
friction | plan (tidy) |
| SimBroker slot order load-bearing, unchecked | friction | plan / carry-on |
Milestone roll-up
The "Walking skeleton" milestone DELIVERS its promise end to end. The full
thread — ingest → SMA-cross → exposure → sim-optimal broker → pip-equity
metric → structured RunReport — runs deterministically (C1, cross-process
byte-identical), in canonical epoch-ns time (C3), reachable via aura run
(#8/C14), and produces a populated trace (C22) on both the synthetic
sample harness AND the real AAPL.US 2006-08 bars at the shipped SMA(2)/SMA(4)
config. The carrier's pre-stated worry — that the real-data path is correct-but-
degenerate — did not reproduce at the demo configuration; #19's degeneracy is a
deep-SMA / dense-data concern, not a milestone failure. No bugs found. Two
spec_gaps and two friction items, none blocking.