# klieo-spec
Generic decompose / critique / refine traits and a quality loop runner.
Part of the [klieo](https://crates.io/crates/klieo) Rust agent framework.
## Features
- `Decomposer<I, O>`, `Critic<T>`, and `Refiner<T>` traits for iterative quality loops
- `QualityLoop`: bounded-iteration runner with convergence check and telemetry
- Domain-agnostic — plug any decomposer, critic, and refiner
## Usage
```toml
[dependencies]
klieo-spec = "3"
async-trait = "0.1"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
```
```rust
use async_trait::async_trait;
use klieo_spec::{Critic, Critique, QualityLoop, Refiner, SpecError};
struct LenCheck { min: usize }
#[async_trait]
impl Critic<String> for LenCheck {
async fn evaluate(&self, t: &String, _i: u8) -> Result<Critique, SpecError> {
Ok(if t.len() >= self.min { Critique::pass("ok") }
else { Critique::fail("too short") })
}
}
struct Pad;
#[async_trait]
impl Refiner<String> for Pad {
async fn refine(&self, t: String, _c: &Critique, _i: u8) -> Result<String, SpecError> {
Ok(format!("{t}-x"))
}
}
#[tokio::main]
async fn main() -> Result<(), SpecError> {
let (out, meta) = QualityLoop::new(LenCheck { min: 5 }, Pad)
.with_max_iterations(10)
.run("a".into())
.await?;
assert!(meta.passed && out.len() >= 5);
Ok(())
}
```
The full compile-checked version of this snippet lives as the crate-level
doctest in [`src/lib.rs`](./src/lib.rs).
## Status
`3.x` — stable.
See [`docs/SEMVER.md`](https://github.com/mohrimic/klieo/blob/main/docs/SEMVER.md).
## License
MIT — see [`LICENSE`](https://github.com/mohrimic/klieo/blob/main/LICENSE).