024e8652c0afc186b2718c0c0f5189a6874fa5d7
18 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
74281842b8 |
feat(aura-cli, aura-engine): use-aware unwired introspection; gang-rule prose; LinComb discovery
Harvest sweep, batch 5 of 6. - introspect --unwired resolves use refs through the registry store: the parse+resolve phase is extracted from graph build's path into the shared parse_and_resolve_ops, so a use-bearing document introspects identically to how it builds (fetch, C29 gate, label resolution) — retiring both the hard miss and the 'content id' mislabeling of by-name refs. The engine's subgraph closure contract is unchanged (store-freedom binds the engine, not the CLI caller). - ganging a spliced instance's member path refuses with the rule (OpError::GangOfSplicedInstance) instead of the typo-shaped no-such-param prose; the leaf-typo case keeps its UnknownParam shape under a new sibling pin. - the --node pending note names the follow-up moves on the current surface (build, then introspect --params / --unwired), and the authoring guide gains a worked LinComb op-script example (args-then-bind order, term[i]/weights[i], verified by building it). refs #339 refs #341 |
||
|
|
a851af993a |
feat(aura-engine, aura-cli): the blueprint name op — name_gate on every authored intake
An eleventh op-script op {"op":"name","name":"<n>"} sets the composite
render name (engine Op::Name + CLI OpDoc mirror); omitting it keeps the
default "graph" byte-identically. The default leaked everywhere one
research project has more than one strategy: every store entry named
graph, every default tap recording sharing traces/graph/, and two
use-splices of unnamed blueprints colliding on the default instance
identifier — the authored name dissolves all three through existing
mechanics (no downstream site edited).
Mechanics: at-most-once per script (doc-op precedent), position-free
(read only at finish). A shared deterministic name_gate (aura-engine:
non-empty, no path separators, not . or ..) guards every seam where a
name is born from authored data, because the name keys a trace
directory unsanitized: the op intake (GraphSession::set_name) and all
four CLI fresh-file envelope intakes (register, introspect
--content-id FILE, the bare graph FILE viewer, aura run FILE — the run
route reached begin_run(signal.name()) ungated, and introspect
--params FILE rode the same parse). Store read-back (reproduce, use
resolution, introspect/params by content id) stays deliberately
ungated — C29: registered artifacts are never retroactively
invalidated — pinned by a test that plants a bad-root-name blueprint
via the registry API and asserts introspect --params still answers.
Refusal prose is single-sourced (name_gate_fault_prose) so every seam
reads identically, op-indexed on the op route.
Identity semantics: the authored name hashes into the content id (a
named document is a different document) and never into the identity id
(names are stripped as debug symbols, C23) — pinned by a twin test.
The previously untested use-splice instance-name default
(construction.rs) got its ratifying pin before the collision claim
leans on it. The registry label (register --name) stays orthogonal.
Review rounds caught and fixed: the envelope gate initially fired on
store read-back (C29 violation at the introspect surface), and the
run/params fresh-file routes were unenumerated intake seams — closed
with the call-site classification now recorded in the wrapper docs.
Verification: cargo build/test/clippy -D warnings all green (99 test
targets, 0 failures, independently re-run); the new run-route test was
RED-verified by hand-removing the gate.
closes #331
refs #328, #311
Spec: blueprint-name-op (fork minutes on #331)
|
||
|
|
a8b1ba45c5 |
feat(aura-engine, aura-vocabulary, aura-cli): the args channel end to end
The data plane reaches non-scalar structural config (closes #271, the final Data-authorability-boundary item). Op::Add gains args (string pairs, applied via try_args after resolve and before the bind loop — no pending builder ever enters a graph; an arg-bearing type without args refuses as MissingArg). OpError::BadArg carries the precise ArgOpError; the CLI renders it as prose naming the arg, its kind, and the kind's closed hint (exit 1, #175 content-fault class). Serde: PrimitiveData.args (skip-if-empty — args-free documents stay byte-identical, golden-pinned, so every existing content id is stable per C18) with a data-driven format version: the writer emits 1 for args-free documents and 2 when any primitive recursively carries args; the loader accepts 1..=2. The old v2-refusal pin flips deliberately to v3 (named contract change). Identity JSON keeps args — they are structural, and the Rust configured() path and the args op-script bridge to the same identity id (pinned). Roster: Session / LinComb / CostSum enter (33 -> 36, both count pins; the LinComb-rejection assertion flips to the resolved side). introspect --node shows arg rows (name, kind, hint) plus the pending note; OP_REFERENCE's add row teaches the args form. Registry comment de-staled (LinComb is now roster-reachable). Sequencing note: this commit lands op seam and roster together so no intermediate tree state exposes a pending builder. |
||
|
|
4a30222fdc |
audit: #317 cycle close — residues homed, gang-refusal claim pinned
Architect (fable gate): drift_found, minor, no contract violation. What holds: invariant 9 / engine-store split (Op::Use resolves only through the injected closure; the label sidecar is the C24 §Enforcement-shift-permitted store-layer discovery, the splice inlines so the marketplace Forbids clause is untouched); the C1 twin oracle; the open-pattern split consistent on both cadences across C24, guide, module docs, and the flipped pin. Drift resolutions: - [medium] #317 minute 4621 over-claimed "gangable" -> correcting comment 4629 posted; all prose surfaces already state "sweepable, not gangable". - [medium] four accepted residues had no tracker home -> collective issue #339 (instance-param ganging, gang-knob binding at splice, open-run refusal rendering, --unwired on use-bearing documents) per the consolidation practice. - [low] the documented "gang refuses an instance member path" claim was unpinned -> pinned here: gang_of_a_spliced_instance_member_path_refuses (this commit's one code change). - [low] --unwired on use-bearing documents -> #339 item 4. Regression: aura-bench report-only, all five surfaces fingerprint OK — engine_throughput -0.2% bars_per_s, ingest +0.0%, campaign_sweep +0.1% cpu / +0.5% rss / -0.3% wall, campaign_heavy +1.2% cpu / -8.8% rss / -0.9% wall, cli_fixed_cost +1.2% help / -1.8% run. No baseline moved, nothing to ratify. Erratum (batch-2 report): the harvest-sweep fieldtest spec consumed this cycle; removed with the plan/spec sweep at this close. refs #317 |
||
|
|
9e26be60f3 |
feat(aura-engine): Op::Use splices a registered blueprint; open patterns build
The construction session gains the use op: Op::Use { ref_id, name, bind }
resolves through a second injected closure (subgraph: &dyn Fn(&str) ->
Option<Composite>, mirroring vocab's closed-lookup posture — the engine never
touches the store) and pushes the fetched composite as BlueprintNode::Composite,
renamed to the instance identifier (names are identity-blind debug symbols),
with path-qualified binds applied at splice time. Port resolution, kind checks,
the eager cycle gate, and the holistic finish gates all walk the existing
Composite arm — the session storage already carried it; the
"sessions only ever add primitives" unreachable! is retired by construction.
Open patterns (ratified mid-cycle, #317 comment 4627): finish() drops the
root-role gate; compile/bootstrap keep it. An op-script's explicit input roles
are a pattern's formal parameters — buildable, registerable, splicable; running
one standalone still refuses at bootstrap. The pinned finish-refusal test flips
to assert the new split (finish OK, compile refuses). No shipped fixture used
the input op; no corpus behaviour moves.
Gang integrity at the use seam (review finding): binding a ganged member's raw
path refused via the new BindOpError::AlreadyGanged { param, gang } (aura-core)
instead of silently de-fusing the gang — membership keyed on the same
(node, original_pos) coordinate collect_params/check_gangs use, per nesting
level. The gang's public knob stays unbindable at the seam (recorded residue).
Correctness oracle: use_op_splices_byte_identical_to_the_rust_built_twin pins
blueprint_to_json byte-equality against the GraphBuilder twin AND a
bit-identical recorded run (C1). Seven further use_op_* tests cover the fault
surfaces; open_input_pattern_finishes_registers_shaped_and_splices covers the
open-pattern round trip build -> serialize -> reload -> splice -> run.
No blueprint-format change: the serialized form already nests composites
recursively; the golden byte pin stays untouched.
refs #317
|
||
|
|
7126886b81 |
feat(engine, cli): op-script doc slot -- the vocabulary grows the C29 meaning line
Iteration 3 completion (tasks 5-6): the construction vocabulary gains the slot its own #125 scope-cut comment anticipated. Op::Doc { text } is the op-script twin of the builder's .doc(...) -- a closed, typed metadata construct (C25, no logic content); at most one per script, a second refuses via OpError::DuplicateDoc (the existing duplicate-fault family), rendered "a doc op may appear at most once". GraphSession threads the text through Composite::with_doc at finish, so op-built composites pass the C29 store gate like builder-built ones. The op-script register test runs on the described variant (SIGNAL_DOC_DESCRIBED) for both shapes; the doc-less script now pins the C29 refusal, and the E2E phase added the RestatesName op-script case. Full gates: cargo test --workspace green (98 suites, 0 failed); clippy -D warnings clean. refs #316 |
||
|
|
b39fd63396 |
refactor: split the aura-std roster into C28 layer crates
Phase 4 of the Stratification milestone. aura-std held four C28 ladder layers in one roster; this cuts them into layer-aligned, aura-core-only node crates so the import direction is enforced by the crate graph: - aura-std — engine nodes only (arithmetic/logic/rolling + sinks) - aura-market — session, resample - aura-strategy — bias, stops, sizer, cost-model machinery - aura-backtest — sim_broker, position_management - aura-vocabulary — the relocated closed std_vocabulary roster Node modules move verbatim (byte-identical renames); consumers are rewired by import path only. A new structural test (aura-vocabulary/tests/c28_layering.rs) asserts each node crate's [dependencies] stay within its C28-permitted inner set, catching the acyclic-but-outward violation the compiler misses. Behaviour byte-identical: full workspace suite green (1448 tests), no golden edited, clippy -D warnings clean. C28 Status block updated. closes #288 |
||
|
|
592750b122 |
audit: close #284/#285 cycle — GraphBuilder::tap twin restores C24 symmetry
Cycle-close tidy for the #284 (tap construction op) + #285 (docs) cycle. The architect drift review (cb6211c..HEAD) came back drift-clean on the ledger contracts the cycle touched — C27 machinery untouched, a faithful `expose` twin (C25 preserved), lockstep op<->OpDoc / OpError<->format_op_error arms paired, and the #285 docs verified accurate against aura-std/src/session.rs — save one drift item, fixed here. Drift item (fixed): the op-script gained `Op::Tap` but `GraphBuilder` had no `tap()` twin, softening C24 (replay-equals-builder = one construction semantics) and C17 (builder-primacy) — every other op verb has a builder twin. Unlike the op-script's `doc` gap (a ledger-recorded #125 scope cut), this asymmetry had no rationale; a tap is a first-class authoring act on both surfaces, so denying only the fluent builder was an accident of incremental delivery, not a design cut. Fix: `GraphBuilder::tap` (builder.rs), the exact output-side mirror of `expose` — a `taps: Vec<(String, OutPort)>` accumulator resolved at `build()` into `Tap { name, from: TapWire }` and threaded via `.with_taps`. Plus a construction.rs lockstep test `tap_replay_matches_builder` proving the op-script `Op::Tap` replay and the `GraphBuilder::tap` twin serialize to byte-identical blueprint JSON and compile to identical `FlatGraph.taps` — the tap op is the by-identifier face of the same construction semantics, not a second one. Carry-on (architect debt-low, no action): commit 43a1cc4's body phrase "op-built composites silently lost their taps" over-claims a prior drop (no tap op existed pre-cycle); the "latent" qualifier keeps it honest, so the wording is left as-is rather than rewriting an already-landed commit. Verification: full `cargo test --workspace` green; `cargo clippy --workspace --all-targets -- -D warnings` clean. The bench is report-only by project convention and was not run — this cycle adds a construction-time op + docs, no hot-path change. Fieldtest: the #284 `tap` surface is exercised from the public interface by two E2E consumer-path tests (op-script -> `aura graph build` -> `aura run` -> persisted trace) plus two worked authoring examples hand-verified through the built binary; #285 is documentation. The per-cycle fieldtest is satisfied. Spec + plan working files (docs/specs/tap-construction-op.md, docs/plans/tap-construction-op.md) discarded per audit Step 5 (git-ignored, never committed; their design intent lives in the commit bodies + the ledger). |
||
|
|
43a1cc44d3 |
feat(graph): name-addressed tap construction op — declared taps without raw indices
Declared taps (C27, #282) were authorable only by hand-patching the raw blueprint envelope's `taps` array, where `node` is a raw interior index — an index miscount was the expected mistake and the root friction behind the two `aura run` panics the measurement-milestone fieldtest found. Add a `tap` op to the construction op-script vocabulary — the exact output-side twin of `expose`. It names its source wire by the dotted `"node.field"` identifier the op surface uses everywhere (`split_port` + `resolve_output_field` + `node_index`), so `{"op":"tap","from":"fast.value","as":"fast_ma"}` replaces patching `{"node":14,"field":0}`. Engine (construction.rs): `Op::Tap`, its `tap()` handler (a verbatim twin of `expose` — same resolvers, same name-dedup, appending a `Tap` to a new `taps`/`tap_names` namespace), and `OpError::DuplicateTap` (the twin of `DuplicateOutput`, stricter than the raw envelope, which enforces no tap-name uniqueness). `finish()` now threads `.with_taps(self.taps)` into the built `Composite` — fixing a latent drop #282 left (it built `.with_gangs` but never `.with_taps`, so op-built composites silently lost their taps). CLI (graph_construct.rs): `OpDoc::Tap` (externally tagged, `"as"`-renamed like `expose`) + the `kind_label` / `From` / `format_op_error` arms (the last compiler-enumerated by the exhaustive match). No change to the `Tap` / `FlatTap` / `bind_tap` / `aura run` machinery — the op-declared tap flows through the existing #282 compile + record path unchanged. Verification: 7 new tests green (4 engine: resolve+append, bad-port / ghost-node refusal, duplicate-name refusal, finish-threads-into-FlatGraph; 1 CLI serde round-trip; 2 CLI E2E over the real `aura graph build` / `aura run` subprocess — one pinning the exact serialized `"taps":[{"name":"fast_ma","from":{"node":0,"field":0}}]`, one proving an op-authored tap round-trips through build -> run -> persisted trace). Full workspace suite green; clippy clean. The RED-before-GREEN step was verified by a temporary stash of the production edits (the `Tap` / `with_taps` machinery pre-existed from #282, so a fresh RED-only test could not be authored) — the new tests fail without the edits, pass with them. Docs (the authoring-guide `tap` row, the ledger op-list `tap` line, and a worked tap-authoring example) are deliberately out of this commit's scope — they land in #285, the docs follow-up in this same cycle. closes #284 |
||
|
|
f3daded514 |
feat(engine): compile resolves and hoists declared taps (#282)
The compile core. resolve_tap_wire resolves a blueprint Tap's interior
{node, field} through the lowering table exactly as OutField re-exports and
edges resolve — a leaf to its remapped index (output-arity checked), a nested
composite through its output remap. Taps are terminal (not re-exported through
the boundary): a flat_taps accumulator threads through the lowering recursion,
so an interior composite's taps hoist to the root FlatGraph.taps with remapped
wires — the case the CLI single-run wrapper relies on. validate_wiring gains a
tap leg (threaded at all three call sites incl. GraphSession::finish) and
CompileError::TapWireOutOfRange names a bad wire. Root-resolve, out-of-arity,
and nested-hoist are pinned green.
refs #282
|
||
|
|
89d703dd99 |
test: red executable-spec for #261 — SessionFrankfurt preset reachable from blueprints
A data-only op-script naming the roster id SessionFrankfurt must resolve to a Frankfurt-baked Session preset (09:00 Europe/Berlin baked, one period_minutes: I64 knob, bars_since_open: I64 out) and build to a finished Composite. Fails on std_vocabulary returning None — the preset is absent from the roster; fork decision on the issue. refs #261 |
||
|
|
43a427bfed |
audit: run-tail close — ledger and glossary reconciled to the shipped state
The tail audit over d1e01ef..62f6592 found no code drift against the contracts (C18 name-resolution read-only, C23 doc identity-blind and inline-dissolved, C1 fit deterministic) but four lagging records, fixed here: the #106 real-roller amendment gains the #239 fit-to-window note (fixed sizes are a ceiling on the sugar path); a #125 realization note records the composite doc as a C23 debug symbol with its serde/identity/ viewer treatment; the glossary identity-id and composite entries name the doc; GraphSession::finish states the deliberate absence of a doc-carrying op-script surface (refs #125) instead of leaving the authoring asymmetry silent. |
||
|
|
bc88e18247 |
feat(engine,cli): GraphBuilder gang cadence + render carrier (#61 tasks 5-6)
Builder: NodeHandle::param -> ParamRef, GraphBuilder::gang, build() resolves
the gang table (collect-then-reject, BuildError::{UnknownParam,AmbiguousParam,
BadGang}) and terminates in Composite::with_gangs — the same predicate the
op-script and serde boundaries use. C24 lockstep extended: an op-script gang
replay serializes byte-identically to the GraphBuilder twin (FlatGraph edges +
sources + canonical JSON).
Render: model_to_json emits a per-scope gangs fragment (name, kind, [node,pos,
"param"] members) for ganged scopes only — the gang-free model stays
byte-identical (model_golden untouched). graph-viewer.js annotates a ganged
open param with its public knob name; guarded by a viewer_gang_param.{mjs,rs}
pair RED-first per the established viewer_bound_param convention (a welcome
extra beyond the plan's file list).
Ratified deviation: the model's kind string uses the serde form ("I64") — the
plan's implementation snippet (kind_str -> "i64") contradicted its own test;
resolved toward the test + the blueprint_serde form. Two quality nits held as
principled plan-holds (inline resolution block; the unreachable unwrap_or
placeholder check_gangs refuses first).
Verified: aura-engine lib 264/0 (model_golden, lockstep, builder, carrier all
green), viewer_gang_param 1/0, workspace clippy -D warnings clean. Slice
resumed across a transient API failure via workflow resume (cached prefix).
refs #61
|
||
|
|
521cfc8b5b |
feat(engine,cli): gang serde + identity + the gang construction op (#61 tasks 3-4)
Serde: CompositeData carries an additive-optional gangs section (omitted when empty — every existing v1 document round-trips byte-identically, NO format-version bump per the #61 decision; BLUEPRINT_FORMAT_VERSION doc now records the pre-ship Tier-2 dormancy). project() emits gangs canonically (members by (node,pos), gangs by first member) so declaration order never reaches the content id; reconstruct() re-mints through Composite::with_gangs and a corrupted section refuses as the new typed LoadError::Gang. strip_debug_symbols blanks gang + member names, keeps (node,pos,kind) — the identity id stays gang-name-blind and gang-structure-sensitive. Construction: Op::Gang { as_name, into } with the feed-style two-phase eager arm (member resolution against the post-bind schemas, kind uniformity, single-gang membership; OpError::{GangKindMismatch,AlreadyGanged,GangArity}); finish() routes the assembled composite through with_gangs, and gang-name collisions surface via the existing injectivity gate on the projected space. CLI: OpDoc::Gang ({"op":"gang","as":…,"into":[…]}), kind_label/From/ format_op_error arms, and format_load_error phrases gang faults as prose (gang_fault_prose) instead of leaking Debug — a ratified improvement over the plan bytes. Held quality nit (principled plan-hold): gang()'s inline collect-then-reject param resolution is the module's established convention (bind/try_bind); a shared cross-crate helper is out of this task's scope. Verified: workspace build clean, aura-engine lib 258/0, aura-cli graph_construct 48/0 (incl. the new gang-op e2e), clippy -D warnings clean. refs #61 |
||
|
|
f1ab81d1b8 |
feat(0089): construction diagnostics read by-identifier (closes #162)
The cycle-0088 fieldtest found three presentation defects on the construction
op-script surface, all where the surface dropped out of its by-identifier register.
Presentation only — every fault still fires identically (same exit code, same
op/finalize attribution); only the rendered cause changes.
- Item 1 (finalize by-identifier). The holistic finalize fault leaked the raw
index Debug form (`UnconnectedPort { node: 2, slot: 1 }`). `GraphSession::finish()`
now translates the three reachable index-carrying CompileErrors into new
by-identifier OpError variants (UnconnectedPort{node,slot} / RoleKindMismatch{role}
/ UnboundRootRole{role}) using the session's `ids`/`schemas` and the composite's
`input_roles()` — the holistic gate calls (validate_wiring,
check_param_namespace_injective, check_root_roles_bound) stay byte-for-byte
unchanged (C24: no second validator; only the `.map_err` closures changed).
`aura graph build` now prints `finalize: slot sub.rhs is unconnected`.
- Item 2 (bind mismatch prose). `format_op_error`'s BadParam arm matches the
BindOpError variants instead of `{:?}`: `op 1 (add): param fast.length expects I64
but got F64`, matching the connect mismatch register.
- Item 3 (discoverable bind form). `introspect --node` shows the typed-Scalar bind
form: `param length:I64 (bind {"I64": <v>})`.
Item 1 spans both crates atomically (adding OpError variants forces the exhaustive
format_op_error match; the finish() translation flips behavioural test pins in both
crates). Five test touches: the two in-file unit tests, the two E2E twins plan-recon
found that the spec's testing strategy under-enumerated
(construction_e2e.rs, tests/graph_construct.rs), and a new unbound-root-role test;
the implementer added RoleKindMismatch / Ambiguous/UnknownParam coverage too. The
CLI finalize test was tightened (orchestrator) to pin `sub.rhs` and the absence of a
raw `node:` index.
Spec boss-signed on a grounding-check PASS (docs/specs+plans/0089). Verified: full
workspace suite + clippy green; the three messages reproduce exactly against the
built binary on the fieldtest fixtures.
|
||
|
|
16520429be |
fix(0088): reject dataflow cycles in construction build (closes #161)
The construction op-script service accepted a dataflow cycle and exited 0,
emitting a non-DAG blueprint — violating domain invariant 5 / C9 (the graph is a
DAG; the only feedback path is an explicit delay/state node). The cycle-0088
fieldtest surfaced it (fieldtests/cycle-0088-construction-op-script/FINDINGS.md).
The construction gate set had no acyclicity check: a cyclic interior-edge set
passed both the eager per-op gates and the holistic finish, so replay() returned
Ok. Fix: an eager reachability check at the connect op that closes the cycle —
GraphSession::closes_cycle(from, to) asks "does the `to` node already reach the
`from` node through the edges added so far?" and rejects with a new by-identifier
OpError::WouldCycle { from, to } ("connecting from -> to would close a cycle"),
threaded through the CLI's exhaustive format_op_error. The fault is attributed to
the offending connect op, consistent with the surface's eager per-op diagnostics.
Eager rather than a holistic topological check at finish: a cycle is closed by
one specific connect, and naming that connect is the sharpest by-identifier error.
RED-first: two tests pin the symptom (a 2-cycle a<->b and a self-loop), both red
before the fix and green after; the 19 existing construction tests, the full
workspace suite, and clippy stay green.
Scope is the cycle only. The validity-floor cases the fieldtest also noted (an
unfed declared source role, an output-less graph) are degenerate-but-well-formed,
not invariant violations, and are deferred (refs #161) pending the build->consume
edge (#28) that defines what a valid emitted blueprint must guarantee.
|
||
|
|
86841b0740 |
audit(0088): cycle close — drift fixes + C24 ledger refresh; close construction service
Architect drift review of cycle 0088 (#157, the introspectable fail-fast construction service: §A shared gate predicates, §B the GraphSession/Op/replay per-op surface + introspection, §C the aura graph build/introspect CLI). What holds (confirmed against the diff): no-second-validator (C24) — edge_kind_check is the single kind-check site called by both validate_wiring and GraphSession::connect, and validate_wiring / check_param_namespace_injective are reused verbatim in finish(); engine domain-free (invariant 9) — construction takes an injected Fn(&str)->Option<PrimitiveBuilder>, no registry, the closed match + std_vocabulary_types live in aura-std; topology-as-data / no DSL (C24/C17/inv 10) — the engine Op is serde-free, the OpDoc wire DTO is CLI-side, ops are static and non-Turing-complete; replay-equals-builder byte-identity (construction_e2e.rs) protects C9/C19/C23. Resolution: - fix (drift-med): the root-role-boundness gate was the one holistic check finish() re-implemented instead of sharing — extracted check_root_roles_bound (blueprint.rs) and called from BOTH compile_with_cells and finish(), so finish() now reuses ALL the holistic gates and the no-second-validator claim is literally true. Behaviour- preserving (same UnboundRootRole variant; unbound_root_role_is_rejected stays green). - fix (drift-med): removed the #![allow(dead_code)] on construction.rs — empirically unnecessary (the pub re-exported surface is reachable; clippy -D warnings green without it) — and its now-inaccurate comment (it claimed removal "when the consumer lands", but the consumer is a separate crate). Also tidied a stale graph_construct.rs module-doc line. - fix (ledger): C24 Status refreshed — #157 moved out of "Remaining" with a cycle-0088 realization note (the construction service: eager/holistic gate split, build-free introspection, emits the #155 blueprint); #159 reframed as paired with #157. - carry-on (debt-med, forward-noted): the std_vocabulary roster is now a third hand-kept copy (match + test list + std_vocabulary_types) and introspect --vocabulary escalates #160's gap to user-facing — noted on #160; still fails safe. - carry-on (scaling-low, forward-noted): the engine Op -> wire OpDoc direction is unguarded for future Op variants — noted on #156 (the format-extension track). No architect-sweep / regression script is declared in the project facts, so the suite is the gate: cargo test --workspace 51 suites green; clippy --all-targets -D warnings clean. Cycle drift-clean. Ephemeral cycle artifacts removed (lifecycle convention): docs/specs/0088-*, docs/plans/0088-*. closes #157 |
||
|
|
27ac4dc537 |
feat(0088): §B construction op-script surface — GraphSession/Op/replay + introspection
Iteration-1 §B of the construction service (#157), on the §A shared predicates
(
|