Files
Aura/fieldtests/cycle-0106-research-artifacts/FINDINGS.md
T
Brummel 78806108d3 fieldtest: cycle 0106 research-artifact surface — GREEN core, authoring on-ramp findings
Downstream-consumer run (roles 5/6b, public interface only) over the
document-authoring loop: canonicalization byte-exact and stable across
reformatting (F8), intrinsic validation thorough and path-addressed (F9),
referential tier correct across the project boundary with progressive
resolution (F10). Findings: one bug (F2: introspect --block advertises an
identity_id process ref the validator refuses), four frictions (F1 envelope
not derivable from introspection incl. the block-id/field-name mismatch and
the un-blocked seed; F3 content:-prefixed id vs bare-hash refs breaking
referential resolution silently; F4 --unwired only reports omitted refs,
which validate then fails; F5 strategy refs unresolvable from the public
surface — no blueprint register/file-content-id/param-space verbs), one
doc-gap (F6 no worked examples, metric vocabulary unlisted), and the
spec-gap F7: a valid, registered campaign has no run path — the
intent-persistence re-test the executor decision waited on.

refs #189, #188
2026-07-03 16:51:36 +02:00

6.6 KiB

Fieldtest — cycle 0106 — research-artifact document surface — 2026-07-03

Role: downstream consumer (methodology designer / campaign designer), public interface only (ledger C18/C20/C22/C25, glossary, CLI help + introspection, the fieldtests corpus shape). No crates/ source read. Binary built from HEAD; referential tier exercised after cargo build in the scaffolded demo_project/.

Fixtures (this directory)

  • c0106_1_attempt1..3.json, c0106_1_partial.json, c0106_1_reformatted.json — process doc: 3-round envelope discovery + canonicalization + empty-gate probe
  • c0106_2_strategy.json — SMA-cross op-script (content id 573262…)
  • c0106_2_campaign_attempt1..2.json, c0106_2_campaign_valid.json, c0106_2_campaign_partial.json, c0106_2_probe_{barestring,refnull,noref,prefixed}.json
  • c0106_4_{emptyaxis,floatinint,noinstr,backwardwin,badmetric,badcmp,process_identity}.json
  • demo_project/aura new scaffold + campaign/process docs + in-project store
  • runs/{processes,campaigns}/… — content-addressed store written by register

Findings

F2 [bug] introspect --block std::process_ref advertises identity_id, which the validator refuses

The slot line prints ref required, one of { content_id } | { identity_id } while validation refuses an identity_id process ref (process.ref: a process is referenced by content id in this version, exit 1); the block header itself says "(content id)". The 0106 audit fixed the parallel --unwired hint but not this --block describe. Repro: aura campaign introspect --block std::process_ref. → debug (RED-pin content-id-only).

F1 [friction] Document envelope not derivable from the introspection contract

Process doc took 3 blind rounds (stages → wrong-kind refusal that does not name the kind key → unknown field stages, expected one of … pipeline). Campaign worse: block ids std::data/std::strategy/std::process_ref/std::presentation map to fields data/strategies (plural)/process/presentation, and the required seed appears in NO block (missing field seed). Introspection describes block slots but never the envelope composing them. → plan (envelope/skeleton introspection; reconcile block ids with field names).

F3 [friction] content-id printed content:-prefixed, refs need the bare hash — silent referential break

process|campaign introspect --content-id print content:<hash>; graph introspect --content-id prints bare. Pasting the prefixed form into a ref PASSES intrinsic validation (different id!) then fails referential resolution without the error naming the prefix as the cause. → plan (one display form across verbs; accept/strip the prefix in refs).

F4 [friction] --unwired open-slot hints fire only when a ref is omitted, which validate fails

The ref open-slot hints appear only with the ref key removed (then validate says missing field ref); placeholders {} / null give cryptic serde errors (expected map with a single key; invalid type: null, expected string or map) and --unwired reports no open slots. One draft file cannot both validate-so-far and report its open slots. → plan (treat ref: {}/null as the reported open slot).

F5 [friction] A campaign's strategy ref cannot be driven to resolve from the public surface

No verb computes a blueprint FILE's content id (graph introspect --content-id is op-list-only), no verb registers a standalone blueprint into the store (only sweep/mc/walkforward populate it), no verb lists a strategy's param_space (axis names/kinds undiscoverable). The ref stays unresolved unless a sweep already ran — but the sweep is what the campaign describes (see F7). → planner (blueprint register + file content-id + param-space listing; scope with the executor).

F6 [doc-gap] No worked document example anywhere; metric_vocabulary unlisted by any verb

Zero process/campaign JSON examples in docs/ or the corpus at test time. Block hints say "metric name (see metric_vocabulary)" but no verb lists it, and unknown metric does not enumerate valid names. → tighten docs (worked example per type; metric enumeration via introspect or in the refusal).

F7 [spec_gap] No executor — a valid campaign has no run path (the pending executor decision)

After registering a campaign whose process declares sweep → gate → walk_forward over a strategy + 9-point axis, the expected aura campaign run <id> does not exist; aura run/sweep take no campaign. The campaign+process pair is a complete declarative spec of machinery the engine already runs (sweep_family / optimize_deflated / walkforward_family); what exists is persisted, content-addressed, legible intent that nothing consumes. The trail ends at runs/campaigns/<hash>.json. → this run IS the intent-persistence re-test the executor decision waited on; scope the executor.

F8 [working] Content-id canonicalization is exact and stable

Reordered keys + reflowed whitespace + 0 vs 0.0 yield the identical content id; stored form is compact, declared-key-order, no trailing newline, and re-derives its id. → carry-on.

F9 [working] Intrinsic validation is thorough, path-addressed, house-style

Empty gate, unknown metric/cmp, empty axis, float-in-I64, empty instruments, backwards window, invalid-doc content-id refusal — all precise prose, exit codes usage=2 / invalid=1 / ok=0. Minor: the kind-mismatch error omits the axis path its siblings carry. → carry-on.

F10 [working] Referential tier correct across the project boundary

Outside: skip line names the search root. Inside without dylib: actionable build hint. Inside built: per-store diagnostics, progressive resolution as documents get registered. → carry-on.

Verdict

The shipped surface delivers standalone value: methodology and experiment intent are nameable, diffable (byte-exact content id surviving reformatting), and auditable (content-addressed, referentially checkable, honest diagnostics) — with no compile and no run. The shortfall concentrates in the authoring on-ramp (envelope invisible to introspection, no worked example, the content:-vs-bare id trap) and the terminal wall: the campaign+process pair fully specifies a sweep→gate→walk-forward the engine already runs, yet nothing consumes it. The single most valuable next capability is an executor (aura campaign run <id> driving the existing family machinery) — the one addition that turns persisted intent into a result and retroactively gives every id, store, axis, and gate its reason to exist.

Counts: bug 1 (F2), friction 4 (F1/F3/F4/F5), doc-gap 1 (F6), spec-gap 1 (F7), working 3 (F8/F9/F10).