Add a wiring-only project tier: Aura.toml without a crate is the smallest project #241
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
aura new
A quick data-only experiment — a throwaway project running std-vocabulary blueprints through the dissolved verbs — is impossible today; both entry routes are closed:
aura sweep … --real GER40in a bare directory exits 1 with "sweep needs a project" and leaves no store (#218's refuse-don't-litter gate;validate_and_register_axes,crates/aura-cli/src/main.rs:2976; pinned bysweep_outside_project_refuses_and_leaves_no_store,crates/aura-cli/tests/cli_run.rs:57).Aura.tomlwithout a crate dies at the metadata probe —aura: cargo metadata failed: error: could not find 'Cargo.toml' in …, exit 1 (crates/aura-cli/src/project.rs:228-240) — and with a crate but no built artifact it refuses with the ArtifactMissing message (project.rs:447).The smallest runnable project is therefore a full Rust crate plus a
cargo build— role 2 (extension dev) ceremony imposed on a user who only takes roles 5-7 (methodology / strategy / campaign design over the std vocabulary). #188's ratified diagnosis already named this ("the scaffold makes every project look like an extension project") and derived the fix: a wiring-only project tier (Aura.toml+blueprints/+runs/, no crate ceremony; the crate joins when the first native node arrives).Decision (user, 2026-07-12)
The wiring-only (data-only) tier is the intended first step of every new project — small steps that deepen as the project grows, the same rationale that produced the dissolved-verb sugar. The full Rust environment joins only when project-specific native nodes are needed; at that moment the trader decides whether to author the native components or to outsource that role. Genuinely new standard nodes are engine work (
aura-std), not project work. This deliberately amends invariant 9's "a project is always a Rust crate" reading (already re-opened by #188).Sketch (direction, not a spec)
Aura.tomlwhose directory holds no cargo crate resolves to a data-onlyEnv— std vocabulary only, project-localruns/(paths.runs),paths.datahonored; run-manifest provenance carries the project commit, no dylib fields.aura newscaffolds the wiring-only tier by default (Aura.toml, a std-only starter blueprint,CLAUDE.md,.gitignore, git init); the current crate scaffold becomes the native tier, reached by an explicit, visible upgrade act. The current starter blueprint binds the project-namespacedScalenode (crates/aura-cli/src/scaffold.rs:185) and needs a std-only sibling.Open forks (for the design pass, not settled here): the shape of the upgrade act (
aura new --nativeon scaffold vs a dedicated upgrade verb on an existing project); whether a data-only project carries a namespace at all; what the data-only manifest provenance looks like.Fork package: the role-switch act (design settled)
User decisions (2026-07-12), settling the forks left open in the issue body's sketch:
aura new. The act addresses a different role — the extension developer (role 2 in the nine-role model, #188) — than the trader running the research project (roles 5-7). A dedicated verb makes the switch the visible act the role model requires, and it creates that role's own artifact home instead of mutating the trader's project.aura-core(crates/aura-cli/src/scaffold.rs:87-101); nodes are pure stream transformers over read-only input windows; the only couplings are (a) the<ns>::TypeIdstrings blueprints reference by name and (b) the engine-ABI stamp checked at load (crates/aura-cli/src/project.rs:308-347). Native development is therefore its own project beside the research project — the natural outsourcing boundary, and cross-project reuse (invariant 9's shared node crates) falls out for free.Aura.toml(a[nodes]path — a research-time path pointer, like the engine path dependency).Derived (orchestrator, 2026-07-12):
Aura.tomlformat carries a list of node-crate pointers; the first ship binds exactly one. The vocabulary-merge and collision machinery already exists (charter check: project-first resolution, no std collision), but a single-crate load keeps the boundary change minimal; the list form avoids a format break when multi-crate support lands.Status: design settled — ready for spec production.
Spec auto-signed (grounding-check PASS, no human in the loop)
The spec for this issue (working file
docs/specs/wiring-only-project-tier.md, git-ignored) was signed autonomously on 2026-07-12: an independent fresh-context grounding check extracted its 13 load-bearing assumptions about current codebase behaviour (load boundary, discovery, crate pipeline, provenance stamping, scaffold shape, the outside-project refusal gate, std vocabulary) and ratified every one against a named, currently-green test. No assumption was unratified; the new behaviours themselves (tier selection, pointer errors, Option-widened provenance serde, std-only starter blueprint) are the spec's own commitments and enter as tests during implementation.Scope signed: data-only tier at the load boundary ([nodes] pointer list in Aura.toml, one entry honored), data-only default scaffold for
aura new(flags--engine-path/--namespacemove to the new verb),aura nodes new(sibling node-crate scaffold + attach, load-phase bypass), ProjectProvenance fields widened to optional (additive serde), three-way unresolved-namespace hint, docs/ledger/invariant-9 amendments per the fork package recorded in this thread on 2026-07-12.Status: spec signed — ready for planning.
Implementation decisions (derived, 2026-07-12) — plan corrected to engine reality
Three of the signed spec/plan's literal claims about current behaviour turned out wrong during implementation; each was verified live and the plan corrected (the shipped code follows reality, not the stale plan bytes):
aura runexits 2, not 1 (usage class, C14 partition) — verified by running a data-only project with anosuch::Nodeblueprint. The new data-only hint test asserts exit 2.aura runpersists nothing. The report (incl. the manifest) goes to stdout; only dissolved verbs/campaigns write theruns/store. The scaffold-run headline test asserts the commit-only provenance out of stdout and thatruns/does NOT exist after a plain run; the sweep headline owns the store assertion.aura runrequires a CLOSED blueprint (refuses free params) whileaura sweeprequires OPEN knobs ("this blueprint is fully bound; nothing to sweep"). Decision:aura newscaffolds a closed/open starter pair —blueprints/signal.json(run target) andblueprints/signal_open.json(fast.lengthfree) — and the scaffoldedCLAUDE.mdadvertisesaura sweep blueprints/signal_open.json --axis <name>_signal_open.fast.length=2,4,8, which is pinned by an e2e test driving exactly the advertised line. This makes the closed/open distinction (run vs sweep) visible in the very first project a user touches.Status: load-boundary tier selection, provenance widening, the tiered namespace hint, and the data-only
aura neware implemented and green; the attach verb and docs remain open.User reservation (2026-07-12): the closed/open starter-blueprint pair
The two-starter-blueprint decision recorded earlier in this thread (closed
signal.jsonforrun, opensignal_open.jsonforsweep) is flagged for a future design conversation — the user finds the pair somewhat inelegant (2026-07-12): it reads as a workaround for the run-requires-closed / sweep-requires-open split rather than a designed surface.Candidate directions for that conversation (unevaluated, for the record):
runcan execute open blueprints — one open starter serves both verbs;No work is scheduled; the shipped pair stands until that conversation happens.
Shipped (local commits, 2026-07-12) — with fieldtest and follow-ups
The two-tier project model is implemented and green across the full pipeline, in 14 local commits (43a427b..0ad8fc6; the closes fire on push):
[nodes], no root crate → std-vocabulary project; rootCargo.toml→ pre-#241 native project, unchanged;[nodes]pointer → load that crate). Provenance widened additively (commit-only for data-only runs).aura newscaffolds the data-only tier — Aura.toml, a closed run-target blueprint plus an open sweep-target sibling (runrequires closed,sweeprequires open knobs; the pair decision and the user's elegance reservation are recorded earlier in this thread), CLAUDE.md quickstart with verified command lines, git init + initial commit.aura nodes newscaffolds a sibling node crate and attaches it via the[nodes]pointer; refusals for outside-project / already-attached / existing destination; the full role-2 loop (scaffold → cargo build → namespace resolves) is pinned e2e.Full gates green: workspace suite, clippy -D warnings, doc build. Status: implementation complete — awaiting push (closes for this issue and #242-#245 fire then).
signal_open reservation — resolved
The starter-pair reservation recorded on this issue (closed
signal.jsonforrun+ opensignal_open.jsonforsweep, flagged as inelegant) is resolved by a user decision of 2026-07-12: sweep axes may override bound params — a bound value is the param's default — so the open sibling leaves theaura newscaffold. Decision record and implementation: #246.