feat(project): the project-as-crate load boundary (cycle 0102)
A research project is now a loadable external cdylib crate. Inside a directory whose ancestry holds an Aura.toml, aura discovers the project root cargo-style, locates the compiled dylib via cargo metadata (debug default, --release opt-in), loads it load-and-hold, and refuses mismatches before trusting anything: the AURA_PROJECT descriptor (aura-core::project, #[repr(C)]) carries a C-ABI stamp prefix (rustc + aura-core version, baked per consuming build by the new aura-core build.rs) validated before any Rust-ABI field is read. The vocabulary charter gates the merged resolution: project type ids are ::-namespaced (std stays bare), duplicates refuse, and the enumerable type-id list must agree with the resolver, so introspection can never silently omit a project type. All blueprint verbs resolve through the merged project + std vocabulary via a per-invocation Env threaded through the dispatch chains; registry, trace-store, and data paths anchor at the project runs root (Aura.toml [paths], paths-only by design — instrument geometry stays the recorded sidecar, C15). RunManifest gains the Tier-1 project provenance field (namespace + dylib sha256 + best-effort commit), stamped beside topology_hash on the blueprint-run paths; pre-0102 registry lines load unchanged. Default node names strip the namespace, so :: never reaches the param-path address space. Proven by the demo-project fixture (built by the e2e via cargo, path-dep on this workspace): run twice bit-identical, provenance recorded, introspection lists demo::* beside std, registry anchors at the discovered root from a subdirectory; the badcharter fixture proves the charter refusal through the real libloading path; a never-built project refuses with a cargo-build hint. Outside a project every path collapses to the previous literals — goldens and manifest pins byte-identical. Verification: cargo build --workspace clean; cargo test --workspace 862 passed / 0 failed (incl. 7 project_load e2e); clippy -D warnings clean (one precedent-matching allow(too_many_arguments) on run_oos_blueprint, whose arity the Env threading raised to 8); doc build unchanged. Docs/ledger aligned: Aura.toml field lists are paths-only in project-layout.md, glossary, C16/C17; new C13 realization note records the per-invocation-reload reading and the load-and-hold one-shot scope boundary. New deps, per-case review (aura-cli leaf binary only, never the frozen artifact): libloading, toml. refs #180
This commit is contained in:
+27
-9
@@ -1053,6 +1053,24 @@ toolchain plugins.
|
||||
**Why.** Hot-reload makes the research loop fast; a live artifact must be frozen
|
||||
and reproducible (audit trail: this bot = this commit). A sweep pays no
|
||||
hot-reload tax — params are runtime data (C12), so the cdylib loads once.
|
||||
**Realization (cycle 0102 — the load boundary; per-invocation reload).** The
|
||||
authoring-loop half is realized: a project is an external cdylib crate loaded
|
||||
per invocation through a two-tier `#[repr(C)]` descriptor (`AURA_PROJECT`,
|
||||
`aura-core::project`) — a C-ABI stamp prefix (rustc version + aura-core
|
||||
version, baked per consuming build) validated **before** any Rust-ABI field is
|
||||
touched, then the vocabulary resolver + enumerable type-id list behind the
|
||||
stamp gate. "Hot-reload" reads, in v1, as **per-invocation load of the
|
||||
freshest build**: the author (Claude) runs `cargo build`, the next `aura`
|
||||
invocation locates the artifact via `cargo metadata` (debug default,
|
||||
`--release` opt-in) and loads it **load-and-hold** (leaked, never unloaded).
|
||||
Scope boundary: load-and-hold is trivially sound only because the CLI is a
|
||||
one-shot process — a future long-running host (the open local-server thread,
|
||||
C22) must re-solve reload (host restart or subprocess isolation), never
|
||||
in-process unload. Mismatch of either stamp refuses (exit 1) naming both
|
||||
sides; the project vocabulary is charter-checked at load (`::`-namespaced ids,
|
||||
no duplicates against std, list↔resolver cross-check) — the invariant-9
|
||||
data-plane discipline of the C24 enforcement-shift note, now enforced at the
|
||||
one seam.
|
||||
|
||||
### C14 — Headless core, two faces
|
||||
**Guarantee.** The engine is a UI-agnostic library. Two faces sit on it: a
|
||||
@@ -1145,8 +1163,8 @@ their own repos, pulled as cargo git deps) / **project-local `nodes/`**
|
||||
(experimental, project-specific). A reusable node is an `rlib` dependency; the
|
||||
hot-reload unit stays the project-side `cdylib` that composes it (consistent
|
||||
with C13). Concretely a project is a **Rust crate** — a cdylib library of node /
|
||||
strategy / experiment blueprints — plus a static `Aura.toml` (project context:
|
||||
data paths, instrument/pip metadata, default broker & window, runs dir). During
|
||||
strategy / experiment blueprints — plus a static `Aura.toml` (project context,
|
||||
paths only: data archive root, runs dir — cycle 0102). During
|
||||
research the `aura` host loads and runs it (C13 hot-reload); for deploy the
|
||||
chosen strategy + broker freeze into a standalone binary. **A project is
|
||||
therefore always a Rust program built on the engine.** Beyond the node-reuse
|
||||
@@ -1207,7 +1225,7 @@ into a reusable domain-agnostic substrate — until then `RunReport` / `RunManif
|
||||
is authored in native Rust through **Claude Code + the skills pipeline**: the
|
||||
human describes, Claude writes the Rust, builds it, runs it via the `aura` CLI,
|
||||
and reports metrics. Declarative config (`Aura.toml`) carries only **static
|
||||
project context** (data paths, instrument/pip metadata, defaults, runs dir),
|
||||
project context** (paths only: data archive root, runs dir — cycle 0102),
|
||||
never logic. aura ships **no embedded coding-LLM**. IONOS LLMs are used only as a
|
||||
*runtime data source* (news-agent bias, C11), gated by per-session consent,
|
||||
never in the code path.
|
||||
@@ -2055,12 +2073,12 @@ artifact, and any run is deterministic once instantiated" (C1).
|
||||
atop the atomic sim unit (C12), not yet designed. Search over *params* sits atop the
|
||||
atomic unit; search over *structure* (graph mutation / crossover — NEAT-style)
|
||||
additionally needs topology-as-data (C24).
|
||||
- **`aura new` scaffolder, the experiment-builder API, and `Aura.toml`'s
|
||||
static-context schema** — `aura new` scaffolds a Rust project *crate* (node /
|
||||
strategy / experiment blueprints) against the engine (C16/C20); the
|
||||
experiment-builder API surface (harness wiring, structural axes, sweep
|
||||
combinators) and `Aura.toml`'s schema (data paths, instrument/pip metadata,
|
||||
default broker & window, runs dir) are not yet designed.
|
||||
- **`aura new` scaffolder and the experiment-builder API** — `aura new`
|
||||
scaffolds a Rust project *crate* (node / strategy blueprints) against the
|
||||
engine (C16/C20); the experiment-builder API surface (harness wiring,
|
||||
structural axes, sweep combinators) is not yet designed. `Aura.toml`'s
|
||||
schema was settled paths-only in cycle 0102 (data archive root, runs dir —
|
||||
see the C13 realization note); the load boundary itself shipped there.
|
||||
- **The analysis meta-level — composable orchestration + project-as-crate authoring
|
||||
(tracked: #109).** aura's differentiator (C21) has two unbuilt halves: (1) the
|
||||
orchestration axes (sweep / Monte-Carlo / walk-forward) becoming *composable tools*
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ The primitive `(frozen topology + param-set + data-window + RNG-seed) → determ
|
||||
|
||||
### Aura.toml
|
||||
**Avoid:** —
|
||||
The per-project declarative config holding only static context (data paths, instrument/pip metadata, default broker & window, runs dir), never logic. Its presence marks the project root, the way `Cargo.toml` marks a cargo crate.
|
||||
The per-project declarative config holding only static context — paths only: the data archive root and the runs dir — never logic, and never instrument geometry (that is the recorded sidecar, C15). Its presence marks the project root, the way `Cargo.toml` marks a cargo crate.
|
||||
|
||||
### backtest
|
||||
**Avoid:** —
|
||||
|
||||
@@ -30,8 +30,9 @@ A project is always a Rust program built on the engine.
|
||||
|
||||
```
|
||||
ger40-lab/ # your research project — a separate Rust crate (cdylib)
|
||||
├── Aura.toml # STATIC context only: data paths, instrument/pip
|
||||
│ # metadata, default broker & window, runs dir (no logic)
|
||||
├── Aura.toml # STATIC context only, paths only: data archive root,
|
||||
│ # runs dir (no logic; instrument geometry is the
|
||||
│ # recorded sidecar, C15 — never authored here)
|
||||
├── Cargo.toml # cdylib; depends on aura-core/aura-std (+ shared node crates);
|
||||
│ # carries an empty [workspace] table (see note below)
|
||||
├── CLAUDE.md # the project's own skills wiring (authoring discipline)
|
||||
|
||||
Reference in New Issue
Block a user