New crate _primitives/_rust/kei-runtime/ implementing §Runtime invocation contract from locked substrate schema. CLI (clap-derive): - list-atoms [--root] [--crate] [--kind] → walk + print - invoke <atom-id> --input <json|@file> → discover + validate input (stub exec) - schema-lint [--root] [--crate] → 6-check validator - pipe <dag.toml> → "not yet implemented" stub Modules (≤ 200 LOC each, largest lint.rs @ 171): - src/discover.rs — walk_atoms walks <root>/*/atoms/*.md, parses frontmatter - src/validate.rs — JSONSchema draft-07 via jsonschema 0.17.1 - src/invoke.rs — MVP stub: discover → parse → validate_input → boundary ack - src/lint.rs — 6 checks: required fields, kind enum, side_effects shape, schema path existence + draft-07 declaration, wikilink resolution - src/main.rs — clap CLI, exit 0|1|2 per §Runtime contract Intentional stub boundary: invoke returns structured JSON ack (exit 0), wire-up to concrete atom impls deferred to integration pass (needs Stream B atoms landed first). Registered kei-runtime in workspace members. Tests: 2/2 integration smoke (lint_smoke, discover_smoke) green. Stream D of substrate v1 parallel build. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
50 lines
1.5 KiB
Rust
50 lines
1.5 KiB
Rust
//! Integration test — walk_atoms returns 2 well-formed records from temp root.
|
|
|
|
use kei_runtime::discover::walk_atoms;
|
|
use std::fs;
|
|
use std::path::Path;
|
|
|
|
fn write_atom(root: &Path, crate_name: &str, verb: &str) {
|
|
let atoms = root.join(crate_name).join("atoms");
|
|
let schemas = atoms.join("schemas");
|
|
fs::create_dir_all(&schemas).unwrap();
|
|
let input = format!("{verb}-input.json");
|
|
let output = format!("{verb}-output.json");
|
|
fs::write(schemas.join(&input), "{}").unwrap();
|
|
fs::write(schemas.join(&output), "{}").unwrap();
|
|
let md = format!(
|
|
r#"---
|
|
atom: {crate_name}::{verb}
|
|
kind: query
|
|
version: "0.1.0"
|
|
input:
|
|
schema: schemas/{input}
|
|
output:
|
|
schema: schemas/{output}
|
|
side_effects: []
|
|
idempotent: true
|
|
stability: stable
|
|
---
|
|
|
|
# {crate_name}::{verb}
|
|
"#,
|
|
);
|
|
fs::write(atoms.join(format!("{verb}.md")), md).unwrap();
|
|
}
|
|
|
|
#[test]
|
|
fn walk_atoms_finds_two_records() {
|
|
let tmp = tempfile::tempdir().unwrap();
|
|
write_atom(tmp.path(), "kei-alpha", "search");
|
|
write_atom(tmp.path(), "kei-beta", "fetch");
|
|
let mut atoms = walk_atoms(tmp.path());
|
|
atoms.sort_by(|a, b| a.full_id.cmp(&b.full_id));
|
|
assert_eq!(atoms.len(), 2);
|
|
assert_eq!(atoms[0].full_id, "kei-alpha::search");
|
|
assert_eq!(atoms[0].crate_name, "kei-alpha");
|
|
assert_eq!(atoms[0].verb, "search");
|
|
assert_eq!(atoms[0].kind, "query");
|
|
assert_eq!(atoms[1].full_id, "kei-beta::fetch");
|
|
assert!(atoms[1].input_schema_path.ends_with("schemas/fetch-input.json"));
|
|
assert!(atoms[1].output_schema_path.ends_with("schemas/fetch-output.json"));
|
|
}
|