Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,21 @@ The server communicates over JSON-RPC stdio. All tools return structured JSON wi
| `boruna_capability_list` | List the frozen 1.0 capability set with `capability_set_hash` |
| `boruna_policy_validate` | Validate a `Policy` JSON document; returns typed `error_kind` on rejection |

## Agent-native CLI surfaces

Beyond the MCP server, the `boruna` binary exposes read-only inspection
commands designed for agents. Every one accepts `--json`:

| Command | Use |
|---------|-----|
| `boruna skills list` / `boruna skills get <name>` | Self-describing docs — learn `.ax` and the toolchain from the binary alone |
| `boruna lang codes` | Resolve any `E0NN` diagnostic code seen in `lang check --json` output |
| `boruna doctor` | Verify the environment before relying on the toolchain |
| `boruna workflow graph <dir>` | Read a workflow's DAG (nodes, edges, topo order) before editing it |
| `boruna size <file.ax>` | Check the bytecode artifact cost of a program |

A fresh agent should start with `boruna skills get cli`.

## Usage patterns

**Compile and check for errors:**
Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ Versioning follows [Semantic Versioning](https://semver.org/).

## [Unreleased]

### Added

- **Agent-native CLI surfaces** — five read-only, `--json`-capable commands so AI agents can inspect Boruna projects without reading source. Motivated by a competitive review of `vercel-labs/zero`.
- `boruna lang codes [--json]` — emit the registry of stable diagnostic codes (`E001`–`E009`) with name, summary, and category. Backed by `tooling/src/diagnostics/registry.rs`; a drift test keeps the registry 1:1 with the `E0NN` constants the compiler emits.
- `boruna doctor [--json]` — environment and toolchain health: binary version, compiled features, Rust toolchain, data-directory writability, and project-layout detection. Exits 1 if any check fails.
- `boruna workflow graph <dir> [--json]` — emit DAG facts for a workflow: nodes (kind, capabilities, dependencies), edges, topological order, roots, and leaves. Exits 1 on a non-DAG.
- `boruna size <file.ax> [--json]` — bytecode artifact cost: per-function opcode counts, module-wide totals, and serialized `.axbc` byte size.
- `boruna skills list` / `boruna skills get <name> [--json]` — embedded, agent-curated documentation (`ax-language`, `cli`, `workflows`, `diagnostics`) compiled into the binary, usable with no repository checkout.
- **`docs/reference/diagnostic-codes.md`** — human reference for the diagnostic-code registry.

## [1.3.0] — 2026-04-30

### Stable
Expand Down
122 changes: 122 additions & 0 deletions claudedocs/research_zerolang_vs_boruna_2026-05-17.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# Research: ZeroLang (vercel-labs/zero) vs Boruna — сравнение

**Дата:** 2026-05-17
**Изследван обект:** https://zerolang.ai/ · https://github.com/vercel-labs/zero
**Сравнен с:** Boruna (ai-lang) — този проект
**Дълбочина:** standard · **Увереност:** висока (първични източници: official site + repo README + GitHub API)

---

## Executive Summary

ZeroLang и Boruna **споделят една и съща философия, но са различни продукти**.

- **Обща ДНК:** и двата са „agent-native" езици — експлицитни capabilities в сигнатурите, JSON структурни диагностики с repair-метаданни, една малка toolchain.
- **Различна същност:** Zero е **системен език за компилиране на малки native бинарни инструменти** (без GC, без runtime). Boruna е **платформа за детерминистично, одитируемо изпълнение на enterprise AI workflows** (bytecode + VM + evidence bundles).
- **Не сме конкуренти на едно поле.** Zero конкурира Rust/Zig/C за писане на CLI инструменти. Boruna конкурира workflow/orchestration платформи за compliance.
- **Има 6–7 идеи, които си струва да заемем** — без да губим нашия диференциатор (determinism + replay + hash-chained evidence).

⚠️ **Стратегически сигнал:** Zero е създаден от **Vercel Labs**, на **2026-05-15** (преди 2 дни), и вече има **1166 звезди**. Категорията „agent-native език с експлицитни capabilities + JSON диагностики" вече е валидирана от голям играч. Това е едновременно потвърждение, че сме на права посока, и сигнал, че трябва ясно да защитим това, което Zero **не** прави.

---

## Какво е ZeroLang

| | |
|---|---|
| Тип | Системен programming език (general-purpose, за малки native tools) |
| Автор | Vercel Labs |
| Създаден | 2026-05-15 · 1166 ⭐ за 2 дни · Apache-2.0 |
| Език на компилатора | C (`native/zero-c/`) + self-hosted (`compiler-zero/`) |
| Файлово разширение | `.0` |
| Статус | Experimental, нестабилен |

**Таглайн:** „The programming language for agents — humans and AI agents can read, repair, inspect, and ship small native programs together."

**Ключови технически свойства:**
- **Native артефакти** — статичен dispatch, **без задължителен GC**, без event loop, без скрит runtime. `zero size --json` показва цената на артефакта.
- **Capability-based I/O** — функциите декларират какво докосват; компилаторът отхвърля недостъпни capabilities **по време на компилация**.
- **Експлицитни effects & memory** — сигнатурите излагат fallibility (`raises`) и capabilities; алокацията е видима.
- **Agent-first tooling** — `zero check --json` връща структурни диагностики със стабилни кодове (`NAM003`) и `repair` метаданни.
- **Cross-target проверки** — компилаторът проверява target-neutral код за няколко target-а; emit на `linux-musl-x64` и др.
- **C ABI boundary** — експорт на C ABI символи за low-level interop.
- **Една toolchain:** `check`, `build`, `test`, `format`, `graph`, `size`, `routes`, `skills`, `doctor`, `document`.

---

## Сравнителна таблица

| Измерение | ZeroLang | Boruna |
|---|---|---|
| **Категория** | Системен език за native tools | Платформа за изпълнение на AI workflows |
| **Цел на компилация** | Native бинарни файлове (exe, C ABI) | Bytecode за custom VM |
| **Runtime модел** | Без runtime, без GC, без event loop | VM с capability gateway, actor система |
| **Главен диференциатор** | Малки артефакти, native, размерна прозрачност | Determinism + replay + hash-chained evidence bundles |
| **Capabilities** | ✅ Експлицитни, проверка при компилация | ✅ Експлицитни (`!{net.fetch}`), enforce-ват се в VM |
| **JSON диагностики + repair** | ✅ `check --json`, стабилни кодове | ✅ `lang check --json`, `lang repair`, suggested patches |
| **Agent интеграция** | `zero skills get`, machine-readable docs | `boruna-mcp` MCP сървър (10 tools) |
| **Compliance / audit** | ❌ Не е фокус | ✅ Ядро — EvidenceBundle, AuditLog, verify |
| **Workflow / DAG** | ❌ Няма | ✅ Ядро — WorkflowDef, validator, runner |
| **Framework модел** | ❌ Няма | ✅ Elm-архитектура (init/update/view) |
| **Целеви потребител** | Разработчици/агенти, пишещи CLI tools | Enterprise, изпълняващ одитируеми AI процеси |
| **Зрялост** | 2 дни, experimental, голям hype | По-зрял (557+ теста, 9 крейта, roadmap до 1.0) |

---

## Прилики (реално конвергентни решения)

1. **Capability-based effects** — почти идентична концепция. Zero: „compiler rejects unavailable capabilities". Boruna: `!{net.fetch}` анотации, VM gateway. И двата правят side effects видими в сигнатурата.
2. **JSON диагностики с repair-метаданни** — Zero: `"repair": {"id": "declare-missing-symbol"}`. Boruna: diagnostics със suggested patches + `boruna lang repair`. Една и съща идея: „хората четат текста, агентите четат JSON-а".
3. **Local reasoning** — сигнатурите излагат fallibility + capabilities за двата езика.
4. **Една малка toolchain** — обединен CLI за check/build/test/format/inspect.
5. **Agent-native позициониране** — и двата изрично се продават като езици, проектирани да бъдат поддържани от AI агенти.

**Извод:** Не сме копирали един друг — независимо стигнахме до едни и същи принципи. Това валидира дизайна на Boruna.

---

## Ключови разлики (нашият защитен ров)

Zero **не прави** нищо от следното, а то е сърцето на Boruna:
- Детерминистично изпълнение с гаранция „same input → same output".
- Запис/replay на изпълнения (`EventLog`, `ReplayEngine`).
- Hash-chained, tamper-evident evidence bundles за compliance/audit.
- DAG workflow оркестрация с policy gates и human approval.
- Enterprise compliance шаблони (SOC 2, HIPAA, финанси).

Обратно — Zero има неща, които Boruna няма (native компилация, без GC, C ABI, размерни отчети), но те **не са релевантни** за нашата ниша (изпълнение на workflows, не доставка на native бинарни файлове).

---

## Идеи за заемане (приоритизирани)

| # | Идея от Zero | Приложимост за Boruna | Усилие |
|---|---|---|---|
| 1 | **Стабилни кодове за диагностики** (`NAM003`) | Ако още нямаме стабилни, документирани error codes — да въведем. Критично за agent-repair надеждност. | Малко |
| 2 | **`size --json` / отчети за цена на артефакт** | `boruna` може да докладва размер на bytecode модул, брой стъпки, budget цена преди изпълнение. | Средно |
| 3 | **`graph --json`** — graph facts от CLI | Boruna има workflow DAG-ове — изложи `workflow graph --json` за визуализация/инспекция от агенти. | Малко |
| 4 | **`doctor --json`** — диагностика на toolchain/среда | Команда, която проверява среда, features, policy конфигурация и връща JSON. | Малко |
| 5 | **`skills get`** — machine-readable docs пакети за агенти | Boruna има MCP; добави skill/docs пакет, който агентите дърпат за самообучение по `.ax`. | Средно |
| 6 | **Cross-target / pre-flight проверки** | Boruna може да докладва изисквани capabilities/policy **преди** изпълнение („този workflow ще иска net.fetch + db.query"). | Средно |
| 7 | **Позициониране/маркетинг** — `curl \| bash` инсталатор, ясен „за агенти" таглайн, docs site | Подобри лендинга на Boruna с конкретен agent-native наратив. | Малко |

**Какво да НЕ заемаме:** native компилация, премахване на VM, C ABI, без GC — те противоречат на detmerinism/replay модела ни.

---

## Препоръка

1. **Запази стратегията.** Boruna и Zero не са конкуренти — различни слоеве. Не пренасочвай Boruna към native компилация.
2. **Засили диференциатора.** В маркетинга и docs изрично подчертай: determinism + replay + evidence bundles — точно това, което Zero (и Vercel) не предлагат.
3. **Бързи победи:** въведи стабилни диагностични кодове (#1), `doctor --json` (#4), `workflow graph --json` (#3) — евтини, директно повишават agent-надеждността.
4. **Следи Zero.** Голям играч в съседна ниша; ако Zero добави workflow/audit слой, става директен конкурент. Преглеждай repo-то им периодично.

---

## Източници

- https://zerolang.ai/ — официален сайт (fetched 2026-05-17)
- https://github.com/vercel-labs/zero — README + GitHub API метаданни (fetched 2026-05-17)
- Boruna `architecture` Serena memory + project CLAUDE.md

*Това е изследователски доклад. Без имплементация — следващата стъпка е решение на потребителя.*
182 changes: 182 additions & 0 deletions crates/llmvm-cli/src/doctor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
//! `boruna doctor` — environment and toolchain health checks.
//!
//! Read-only. Reports the binary version, which optional features were
//! compiled in, whether a Rust toolchain is reachable, the persistent data
//! directory's writability, and whether the current directory looks like a
//! Boruna project root. `--json` emits the report for agent consumption.

use std::path::Path;
use std::process::Command;

use serde::Serialize;

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum Status {
Ok,
Warn,
Error,
}

#[derive(Debug, Serialize)]
pub struct Check {
pub name: String,
pub status: Status,
pub detail: String,
}

#[derive(Debug, Serialize)]
pub struct Report {
pub ok: bool,
pub boruna_version: String,
pub checks: Vec<Check>,
}

fn check(name: &str, status: Status, detail: impl Into<String>) -> Check {
Check {
name: name.to_string(),
status,
detail: detail.into(),
}
}

/// A space-separated list of optional features compiled into this binary.
fn compiled_features() -> String {
let mut features = Vec::new();
if cfg!(feature = "persist-sqlite") {
features.push("persist-sqlite");
}
if cfg!(feature = "serve") {
features.push("serve");
}
if cfg!(feature = "http") {
features.push("http");
}
if cfg!(feature = "telemetry") {
features.push("telemetry");
}
if features.is_empty() {
"none".to_string()
} else {
features.join(" ")
}
}

fn check_rust_toolchain() -> Check {
match Command::new("rustc").arg("--version").output() {
Ok(out) if out.status.success() => {
let version = String::from_utf8_lossy(&out.stdout).trim().to_string();
check("rust_toolchain", Status::Ok, version)
}
_ => check(
"rust_toolchain",
Status::Warn,
"rustc not found — only needed to build Boruna from source",
),
}
}

fn check_data_dir(data_dir: &Path) -> Check {
if !data_dir.exists() {
return check(
"data_dir",
Status::Ok,
format!(
"{} does not exist yet — created on first persistent run",
data_dir.display()
),
);
}
if !data_dir.is_dir() {
return check(
"data_dir",
Status::Error,
format!("{} exists but is not a directory", data_dir.display()),
);
}
let probe = data_dir.join(".boruna-doctor-probe");
match std::fs::write(&probe, b"probe") {
Ok(()) => {
let _ = std::fs::remove_file(&probe);
check(
"data_dir",
Status::Ok,
format!("{} exists and is writable", data_dir.display()),
)
}
Err(e) => check(
"data_dir",
Status::Error,
format!("{} is not writable: {e}", data_dir.display()),
),
}
}

fn check_project_layout() -> Check {
let expected = ["templates", "libs", "examples"];
let missing: Vec<&str> = expected
.iter()
.filter(|d| !Path::new(d).is_dir())
.copied()
.collect();
if missing.is_empty() {
check(
"project_layout",
Status::Ok,
"templates/, libs/, examples/ present — looks like a Boruna repo root",
)
} else {
check(
"project_layout",
Status::Warn,
format!(
"missing {} — current directory may not be a Boruna repo root",
missing.join(", ")
),
)
}
}

/// Run the doctor checks. Returns `true` if no check reported `Error`.
pub fn run(data_dir: &Path, json: bool) -> bool {
let version = env!("CARGO_PKG_VERSION").to_string();
let checks = vec![
check("boruna_version", Status::Ok, version.clone()),
check("compiled_features", Status::Ok, compiled_features()),
check_rust_toolchain(),
check_data_dir(data_dir),
check_project_layout(),
];
let ok = !checks.iter().any(|c| c.status == Status::Error);
let report = Report {
ok,
boruna_version: version,
checks,
};

if json {
match serde_json::to_string_pretty(&report) {
Ok(s) => println!("{s}"),
Err(e) => eprintln!("failed to serialize doctor report: {e}"),
}
} else {
println!("boruna doctor — version {}", report.boruna_version);
for c in &report.checks {
let mark = match c.status {
Status::Ok => "ok",
Status::Warn => "warn",
Status::Error => "ERROR",
};
println!(" [{mark}] {}: {}", c.name, c.detail);
}
println!(
"{}",
if report.ok {
"status: healthy"
} else {
"status: problems found"
}
);
}
ok
}
Loading
Loading