25e452aaf7
Iteration-2 §C of the construction service (#157), the CLI shell over the iteration-1 engine core (ea1ca32+27ac4dc): a declarative, replayable JSON op-list document drives the engine's per-op-fallible construction surface. - graph_construct.rs (new, aura-cli): an `OpDoc` serde DTO (`#[serde(tag="op", rename_all="lowercase")]` + field renames type/as) deserializes the document and maps 1:1 into the serde-free engine `Op` — the wire format is a CLI concern, the engine owns no second representation. Bind values use the typed Scalar form (`{"I64":2}`), kinds the capitalized #155 form (`"F64"`). - `aura graph build`: read the op-list from stdin, replay through std_vocabulary, emit the #155 blueprint JSON on success; on the first failing op print `op N (kind): cause` to stderr (the op-kind recovered from the retained parsed list) / `finalize: cause` for a holistic fault, and exit non-zero. A CLI-side format_op_error phrases each OpError (the engine error types stay Display-free). - `aura graph introspect`: `--vocabulary` (std_vocabulary_types), `--node <T>` (a type's ports/kinds + param paths off the pre-build schema), `--unwired` (a partial document's open slots via GraphSession::unwired) — all build-free. - Two new argv arms over the flat match; the bare `["graph"]` HTML-render arm (sample_blueprint, #159's concern) is left intact. #157 acceptance now demonstrated through the CLI (E2E in tests/graph_construct.rs, 8 tests): a document builds to the #155 blueprint that compiles identical to its Rust-built twin (C1); an invalid op is rejected at the op, named; introspection answers vocabulary / ports+kinds / unwired slots without a build. Full suite green (51 suites); clippy --all-targets -D warnings clean. The JSON op-list reuses #155's Scalar/ScalarKind serde shapes; full harnesses (SimBroker/Recorder construction-arg builders) await #156. Wire-format forks derived + recorded on #157. refs #157