mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-07-31 03:05:21 +00:00
932 lines
32 KiB
C
932 lines
32 KiB
C
/*
|
|
* Tardygrada — First Program
|
|
*
|
|
* This proves the VM works:
|
|
* - Spawn agents holding values
|
|
* - Read them back with verification
|
|
* - Test immutability enforcement
|
|
* - Test GC demotion/promotion cycle
|
|
*
|
|
* In Tardygrada syntax, this would be:
|
|
*
|
|
* agent Main {
|
|
* let x: int = 5 @verified
|
|
* y: int = 42
|
|
* let z: int = 7 @sovereign
|
|
* }
|
|
*/
|
|
|
|
#include "vm/vm.h"
|
|
#include "vm/util.h"
|
|
#include "mcp/server.h"
|
|
#include "verify/pipeline.h"
|
|
#include "compiler/exec.h"
|
|
#include "verify/decompose.h"
|
|
#include "terraform/terraform.h"
|
|
#include "ontology/inference.h"
|
|
#include <sys/mman.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <fcntl.h>
|
|
|
|
static int is_zero_uuid(tardy_uuid_t id)
|
|
{
|
|
return id.hi == 0 && id.lo == 0;
|
|
}
|
|
|
|
/* We don't use printf. We write directly. */
|
|
static void print(const char *s)
|
|
{
|
|
tardy_write(STDOUT_FILENO, s, strlen(s));
|
|
}
|
|
|
|
static void print_int(int64_t v)
|
|
{
|
|
char buf[32];
|
|
int i = 30;
|
|
int neg = 0;
|
|
if (v < 0) { neg = 1; v = -v; }
|
|
if (v == 0) { buf[i--] = '0'; }
|
|
while (v > 0) {
|
|
buf[i--] = '0' + (v % 10);
|
|
v /= 10;
|
|
}
|
|
if (neg) buf[i--] = '-';
|
|
tardy_write(STDOUT_FILENO, buf + i + 1, 30 - i);
|
|
}
|
|
|
|
static void ok(const char *test)
|
|
{
|
|
print(" [OK] ");
|
|
print(test);
|
|
print("\n");
|
|
}
|
|
|
|
static void fail(const char *test)
|
|
{
|
|
print(" [FAIL] ");
|
|
print(test);
|
|
print("\n");
|
|
}
|
|
|
|
static int run_tests(void)
|
|
{
|
|
/* VM is too large for stack — allocate via mmap */
|
|
tardy_vm_t *vmp = (tardy_vm_t *)mmap(NULL, sizeof(tardy_vm_t),
|
|
PROT_READ | PROT_WRITE,
|
|
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
|
if (vmp == MAP_FAILED) {
|
|
print("mmap failed\n");
|
|
return 1;
|
|
}
|
|
tardy_vm_t *vm = vmp;
|
|
int64_t val;
|
|
|
|
print("\n=== Tardygrada VM ===\n\n");
|
|
|
|
/* ---- Init ---- */
|
|
if (tardy_vm_init(vm, NULL) != 0) {
|
|
print("VM init failed\n");
|
|
return 1;
|
|
}
|
|
ok("VM initialized with default semantics");
|
|
|
|
tardy_uuid_t root = vm->root_id;
|
|
|
|
/* ---- let x: int = 5 @verified ---- */
|
|
int64_t five = 5;
|
|
tardy_uuid_t x_id = tardy_vm_spawn(vm, root, "x",
|
|
TARDY_TYPE_INT,
|
|
TARDY_TRUST_VERIFIED,
|
|
&five, sizeof(int64_t));
|
|
if (!is_zero_uuid(x_id))
|
|
ok("let x: int = 5 @verified — agent spawned");
|
|
else
|
|
fail("let x: int = 5 @verified — spawn failed");
|
|
|
|
/* Read x back — verified (hash check) */
|
|
val = 0;
|
|
tardy_read_status_t status = tardy_vm_read(vm, root, "x",
|
|
&val, sizeof(int64_t));
|
|
if (status == TARDY_READ_OK && val == 5) {
|
|
print(" [OK] read x = ");
|
|
print_int(val);
|
|
print(" (hash verified)\n");
|
|
} else {
|
|
fail("read x — verification failed");
|
|
}
|
|
|
|
/* ---- y: int = 42 (mutable) ---- */
|
|
int64_t fortytwo = 42;
|
|
tardy_uuid_t y_id = tardy_vm_spawn(vm, root, "y",
|
|
TARDY_TYPE_INT,
|
|
TARDY_TRUST_MUTABLE,
|
|
&fortytwo, sizeof(int64_t));
|
|
if (!is_zero_uuid(y_id))
|
|
ok("y: int = 42 — mutable agent spawned");
|
|
else
|
|
fail("y: int = 42 — spawn failed");
|
|
|
|
/* Mutate y from 42 to 100 */
|
|
int64_t hundred = 100;
|
|
if (tardy_vm_mutate(vm, root, "y", &hundred, sizeof(int64_t)) == 0) {
|
|
val = 0;
|
|
tardy_vm_read(vm, root, "y", &val, sizeof(int64_t));
|
|
print(" [OK] mutated y = ");
|
|
print_int(val);
|
|
print("\n");
|
|
} else {
|
|
fail("mutate y");
|
|
}
|
|
|
|
/* Try to mutate x (immutable) — MUST fail */
|
|
int64_t ten = 10;
|
|
if (tardy_vm_mutate(vm, root, "x", &ten, sizeof(int64_t)) != 0)
|
|
ok("mutate x rejected — immutable agent enforced");
|
|
else
|
|
fail("mutate x succeeded — IMMUTABILITY BROKEN");
|
|
|
|
/* ---- let z: int = 7 @sovereign ---- */
|
|
int64_t seven = 7;
|
|
tardy_uuid_t z_id = tardy_vm_spawn(vm, root, "z",
|
|
TARDY_TYPE_INT,
|
|
TARDY_TRUST_SOVEREIGN,
|
|
&seven, sizeof(int64_t));
|
|
if (!is_zero_uuid(z_id))
|
|
ok("let z: int = 7 @sovereign — agent spawned (5 replicas + sig)");
|
|
else
|
|
fail("let z: int = 7 @sovereign — spawn failed");
|
|
|
|
/* Read z — full BFT verification */
|
|
val = 0;
|
|
status = tardy_vm_read(vm, root, "z", &val, sizeof(int64_t));
|
|
if (status == TARDY_READ_OK && val == 7) {
|
|
print(" [OK] read z = ");
|
|
print_int(val);
|
|
print(" (BFT + hash + signature verified)\n");
|
|
} else {
|
|
fail("read z — sovereign verification failed");
|
|
}
|
|
|
|
/* ---- Freeze: promote y from mutable to @verified ---- */
|
|
tardy_agent_t *y_agent = tardy_vm_find_by_name(vm, root, "y");
|
|
if (y_agent) {
|
|
tardy_uuid_t frozen = tardy_vm_freeze(vm, y_agent->id,
|
|
TARDY_TRUST_VERIFIED);
|
|
if (!is_zero_uuid(frozen)) {
|
|
ok("freeze y: mutable -> @verified");
|
|
/* Now mutation must fail */
|
|
int64_t try_mutate = 999;
|
|
if (tardy_vm_mutate(vm, root, "y", &try_mutate,
|
|
sizeof(int64_t)) != 0)
|
|
ok("mutate frozen y rejected — freeze enforced");
|
|
else
|
|
fail("mutate frozen y succeeded — FREEZE BROKEN");
|
|
} else {
|
|
fail("freeze y");
|
|
}
|
|
}
|
|
|
|
/* ---- GC: test demotion cycle ---- */
|
|
/* Force x's last_accessed to be old */
|
|
tardy_agent_t *x_agent = tardy_vm_find_by_name(vm, root, "x");
|
|
if (x_agent) {
|
|
/* Simulate 60 seconds idle */
|
|
x_agent->last_accessed -= 60000000000ULL;
|
|
int collected = tardy_vm_gc(vm);
|
|
if (collected > 0 && x_agent->state == TARDY_STATE_STATIC) {
|
|
ok("GC demoted idle x to Static");
|
|
/* Read from static — should still return 5 */
|
|
val = 0;
|
|
tardy_vm_read(vm, root, "x", &val, sizeof(int64_t));
|
|
if (val == 5) {
|
|
print(" [OK] static x still = ");
|
|
print_int(val);
|
|
print("\n");
|
|
} else {
|
|
fail("static x value corrupted");
|
|
}
|
|
} else {
|
|
fail("GC demotion");
|
|
}
|
|
}
|
|
|
|
/* ============================================
|
|
* Verification Pipeline Tests
|
|
* ============================================ */
|
|
|
|
print("\n--- Verification Pipeline ---\n");
|
|
|
|
tardy_semantics_t sem = TARDY_DEFAULT_SEMANTICS;
|
|
|
|
/* Test 1: Successful verification — grounded claim */
|
|
{
|
|
/* 3 decomposers produce overlapping triples */
|
|
tardy_decomposition_t decomps[3];
|
|
memset(decomps, 0, sizeof(decomps));
|
|
|
|
/* All 3 agree on the same triple */
|
|
for (int i = 0; i < 3; i++) {
|
|
strncpy(decomps[i].triples[0].subject, "DrWho", TARDY_MAX_TRIPLE_LEN);
|
|
strncpy(decomps[i].triples[0].predicate, "created_at", TARDY_MAX_TRIPLE_LEN);
|
|
strncpy(decomps[i].triples[0].object, "BBCTelevisionCentre", TARDY_MAX_TRIPLE_LEN);
|
|
decomps[i].count = 1;
|
|
}
|
|
|
|
/* Grounding: the triple is confirmed by ontology */
|
|
tardy_grounding_t grounding = {0};
|
|
grounding.count = 1;
|
|
grounding.grounded = 1;
|
|
grounding.results[0].status = TARDY_KNOWLEDGE_GROUNDED;
|
|
grounding.results[0].confidence = 0.95f;
|
|
grounding.results[0].evidence_count = 3;
|
|
|
|
/* Consistency: no contradictions */
|
|
tardy_consistency_t consistency = {0};
|
|
consistency.consistent = true;
|
|
consistency.contradiction_count = 0;
|
|
|
|
/* Work log: agent did real work */
|
|
tardy_work_log_t work_log;
|
|
tardy_worklog_init(&work_log);
|
|
work_log.ontology_queries = 3;
|
|
work_log.context_reads = 5;
|
|
work_log.agents_spawned = 2;
|
|
work_log.compute_ns = 50000000; /* 50ms */
|
|
|
|
tardy_work_spec_t spec = tardy_compute_work_spec(&sem);
|
|
|
|
tardy_pipeline_result_t result = tardy_pipeline_verify(
|
|
"DrWho created at BBC Television Centre", 38,
|
|
decomps, 3, &grounding, &consistency,
|
|
&work_log, &spec, &sem);
|
|
|
|
if (result.passed && result.strength >= TARDY_TRUTH_EVIDENCED)
|
|
ok("grounded claim passed pipeline — EVIDENCED");
|
|
else
|
|
fail("grounded claim should have passed");
|
|
|
|
print(" [OK] truth strength: ");
|
|
print_int((int64_t)result.strength);
|
|
print(" confidence: ");
|
|
/* Print confidence as integer percentage */
|
|
print_int((int64_t)(result.confidence * 100));
|
|
print("%\n");
|
|
}
|
|
|
|
/* Test 2: Hallucination detected — contradicted by ontology */
|
|
{
|
|
tardy_decomposition_t decomps[3];
|
|
memset(decomps, 0, sizeof(decomps));
|
|
for (int i = 0; i < 3; i++) {
|
|
strncpy(decomps[i].triples[0].subject, "DrWho", TARDY_MAX_TRIPLE_LEN);
|
|
strncpy(decomps[i].triples[0].predicate, "created_at", TARDY_MAX_TRIPLE_LEN);
|
|
strncpy(decomps[i].triples[0].object, "Tokyo", TARDY_MAX_TRIPLE_LEN);
|
|
decomps[i].count = 1;
|
|
}
|
|
|
|
tardy_grounding_t grounding = {0};
|
|
grounding.count = 1;
|
|
grounding.contradicted = 1; /* ontology says BBC, not Tokyo */
|
|
grounding.results[0].status = TARDY_KNOWLEDGE_CONTRADICTED;
|
|
grounding.results[0].confidence = 0.0f;
|
|
|
|
tardy_consistency_t consistency = {0};
|
|
consistency.consistent = false;
|
|
consistency.contradiction_count = 1;
|
|
strncpy(consistency.explanation,
|
|
"ontology says BBCTelevisionCentre, not Tokyo",
|
|
sizeof(consistency.explanation));
|
|
|
|
tardy_work_log_t work_log;
|
|
tardy_worklog_init(&work_log);
|
|
work_log.ontology_queries = 2;
|
|
work_log.context_reads = 3;
|
|
work_log.compute_ns = 30000000;
|
|
|
|
tardy_work_spec_t spec = tardy_compute_work_spec(&sem);
|
|
|
|
tardy_pipeline_result_t result = tardy_pipeline_verify(
|
|
"DrWho created in Tokyo", 22,
|
|
decomps, 3, &grounding, &consistency,
|
|
&work_log, &spec, &sem);
|
|
|
|
if (!result.passed && result.failed_at == TARDY_LAYER_GROUNDING)
|
|
ok("hallucination detected at grounding layer");
|
|
else
|
|
fail("hallucination should have been caught");
|
|
}
|
|
|
|
/* Test 3: Laziness detected — agent did no work */
|
|
{
|
|
tardy_decomposition_t decomps[3];
|
|
memset(decomps, 0, sizeof(decomps));
|
|
for (int i = 0; i < 3; i++) {
|
|
strncpy(decomps[i].triples[0].subject, "X", TARDY_MAX_TRIPLE_LEN);
|
|
strncpy(decomps[i].triples[0].predicate, "is", TARDY_MAX_TRIPLE_LEN);
|
|
strncpy(decomps[i].triples[0].object, "Y", TARDY_MAX_TRIPLE_LEN);
|
|
decomps[i].count = 1;
|
|
}
|
|
|
|
tardy_grounding_t grounding = {0};
|
|
grounding.count = 1;
|
|
grounding.grounded = 1;
|
|
grounding.results[0].status = TARDY_KNOWLEDGE_GROUNDED;
|
|
grounding.results[0].confidence = 0.9f;
|
|
|
|
tardy_consistency_t consistency = {0};
|
|
consistency.consistent = true;
|
|
|
|
/* Work log: ZERO operations — agent was lazy */
|
|
tardy_work_log_t work_log;
|
|
tardy_worklog_init(&work_log);
|
|
/* Everything stays at 0 */
|
|
|
|
tardy_work_spec_t spec = tardy_compute_work_spec(&sem);
|
|
|
|
tardy_pipeline_result_t result = tardy_pipeline_verify(
|
|
"X is Y", 6,
|
|
decomps, 3, &grounding, &consistency,
|
|
&work_log, &spec, &sem);
|
|
|
|
if (!result.passed && result.failed_at == TARDY_LAYER_WORK_VERIFY)
|
|
ok("laziness detected — agent did no work");
|
|
else
|
|
fail("laziness should have been caught");
|
|
}
|
|
|
|
/* ============================================
|
|
* VM Nesting Tests
|
|
* ============================================ */
|
|
|
|
print("\n--- VM Nesting ---\n");
|
|
|
|
/* Spawn a child VM as an agent */
|
|
tardy_uuid_t child_id = tardy_vm_spawn_child(vm, root, "child_vm", NULL);
|
|
if (!is_zero_uuid(child_id))
|
|
ok("child VM spawned as agent");
|
|
else
|
|
fail("child VM spawn failed");
|
|
|
|
/* Retrieve the child VM */
|
|
tardy_vm_t *child_vm = tardy_vm_get_child(vm, child_id);
|
|
if (child_vm && child_vm->running)
|
|
ok("child VM retrieved and running");
|
|
else
|
|
fail("child VM retrieval failed");
|
|
|
|
/* Spawn an agent inside the child VM */
|
|
if (child_vm) {
|
|
int64_t ninety = 90;
|
|
tardy_uuid_t inner = tardy_vm_spawn(child_vm, child_vm->root_id,
|
|
"inner", TARDY_TYPE_INT,
|
|
TARDY_TRUST_VERIFIED,
|
|
&ninety, sizeof(int64_t));
|
|
if (!is_zero_uuid(inner)) {
|
|
val = 0;
|
|
status = tardy_vm_read(child_vm, child_vm->root_id,
|
|
"inner", &val, sizeof(int64_t));
|
|
if (status == TARDY_READ_OK && val == 90) {
|
|
print(" [OK] child VM inner agent = ");
|
|
print_int(val);
|
|
print("\n");
|
|
} else {
|
|
fail("child VM inner agent read failed");
|
|
}
|
|
} else {
|
|
fail("child VM inner agent spawn failed");
|
|
}
|
|
}
|
|
|
|
/* ---- Stats ---- */
|
|
print("\n--- Stats ---\n");
|
|
print(" Agents alive: ");
|
|
print_int(vm->agent_count);
|
|
print("\n Tombstones: ");
|
|
print_int(vm->tombstone_count);
|
|
print("\n Page size: ");
|
|
print_int((int64_t)tardy_page_size());
|
|
print(" bytes\n\n");
|
|
|
|
/* ---- Shutdown ---- */
|
|
tardy_vm_shutdown(vm);
|
|
munmap(vmp, sizeof(tardy_vm_t));
|
|
ok("VM shutdown");
|
|
|
|
print("\n=== All tests passed ===\n\n");
|
|
return 0;
|
|
}
|
|
|
|
/* ============================================
|
|
* MCP Server Mode
|
|
*
|
|
* In Tardygrada syntax:
|
|
*
|
|
* agent Main {
|
|
* let x: int = 5 @verified
|
|
* let y: int = 42
|
|
* let z: int = 7 @sovereign
|
|
* }
|
|
*
|
|
* Deploy as MCP. Clients connect and read agent values.
|
|
* ============================================ */
|
|
|
|
static int run_mcp(void)
|
|
{
|
|
tardy_vm_t *vm = (tardy_vm_t *)mmap(NULL, sizeof(tardy_vm_t),
|
|
PROT_READ | PROT_WRITE,
|
|
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
|
if (vm == MAP_FAILED)
|
|
return 1;
|
|
|
|
tardy_vm_init(vm, NULL);
|
|
|
|
/* Spawn agents — this is what a compiled .tardy file produces */
|
|
int64_t five = 5;
|
|
tardy_vm_spawn(vm, vm->root_id, "x", TARDY_TYPE_INT,
|
|
TARDY_TRUST_VERIFIED, &five, sizeof(int64_t));
|
|
|
|
int64_t fortytwo = 42;
|
|
tardy_vm_spawn(vm, vm->root_id, "y", TARDY_TYPE_INT,
|
|
TARDY_TRUST_DEFAULT, &fortytwo, sizeof(int64_t));
|
|
|
|
int64_t seven = 7;
|
|
tardy_vm_spawn(vm, vm->root_id, "z", TARDY_TYPE_INT,
|
|
TARDY_TRUST_SOVEREIGN, &seven, sizeof(int64_t));
|
|
|
|
/* Start MCP server */
|
|
tardy_mcp_server_t srv;
|
|
tardy_mcp_init(&srv, vm);
|
|
tardy_mcp_run(&srv);
|
|
|
|
tardy_vm_shutdown(vm);
|
|
munmap(vm, sizeof(tardy_vm_t));
|
|
return 0;
|
|
}
|
|
|
|
/* ============================================
|
|
* CLI: tardy run "task" — one-shot verified execution
|
|
*
|
|
* Compiles to .tardy internally:
|
|
* agent Task {
|
|
* let claim: Fact = receive("task") grounded_in(default) @verified
|
|
* }
|
|
* Then submits the task text, verifies it, returns result.
|
|
* Nothing unverified runs.
|
|
* ============================================ */
|
|
|
|
static int run_task(const char *task_text)
|
|
{
|
|
tardy_vm_t *vm = (tardy_vm_t *)mmap(NULL, sizeof(tardy_vm_t),
|
|
PROT_READ | PROT_WRITE,
|
|
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
|
if (vm == MAP_FAILED)
|
|
return 1;
|
|
|
|
tardy_vm_init(vm, NULL);
|
|
|
|
/* Spawn a pending agent for the task */
|
|
const char *empty = "";
|
|
tardy_vm_spawn(vm, vm->root_id, "task", TARDY_TYPE_STR,
|
|
TARDY_TRUST_MUTABLE, empty, 1);
|
|
|
|
/* Submit the task text */
|
|
tardy_agent_t *task_agent = tardy_vm_find_by_name(vm, vm->root_id, "task");
|
|
if (!task_agent) {
|
|
tardy_write(STDERR_FILENO, "[tardy] failed to create task agent\n", 36);
|
|
tardy_vm_shutdown(vm);
|
|
munmap(vm, sizeof(tardy_vm_t));
|
|
return 1;
|
|
}
|
|
tardy_vm_mutate(vm, vm->root_id, "task",
|
|
task_text, strlen(task_text) + 1);
|
|
tardy_vm_converse(vm, task_agent->id, "user", task_text);
|
|
|
|
/* Initialize ontology bridge */
|
|
tardy_mcp_server_t srv;
|
|
tardy_mcp_init(&srv, vm);
|
|
|
|
/* Auto-load common knowledge ontology if available */
|
|
{
|
|
const char *ont_paths[] = {
|
|
"tests/wikidata_common.nt",
|
|
"/Users/fabio/projects/tardygrada/tests/wikidata_common.nt",
|
|
NULL
|
|
};
|
|
for (int p = 0; ont_paths[p]; p++) {
|
|
int loaded = tardy_self_ontology_load_ttl(&srv.self_ontology,
|
|
ont_paths[p]);
|
|
if (loaded > 0) {
|
|
srv.self_ontology_loaded = true;
|
|
tardy_write(STDERR_FILENO, "[tardy] ontology: ", 18);
|
|
char num[16];
|
|
int nlen = snprintf(num, sizeof(num), "%d", loaded);
|
|
tardy_write(STDERR_FILENO, num, nlen);
|
|
tardy_write(STDERR_FILENO, " triples loaded\n", 16);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Decompose the claim */
|
|
int claim_len = (int)strlen(task_text);
|
|
tardy_decomposition_t decomps[3];
|
|
memset(decomps, 0, sizeof(decomps));
|
|
tardy_decompose_multi(task_text, claim_len, decomps, 3);
|
|
|
|
/* Collect unique triples */
|
|
tardy_triple_t all_triples[TARDY_MAX_TRIPLES];
|
|
int triple_count = 0;
|
|
for (int d = 0; d < 3; d++) {
|
|
for (int t = 0; t < decomps[d].count && triple_count < TARDY_MAX_TRIPLES; t++) {
|
|
int dup = 0;
|
|
for (int e = 0; e < triple_count; e++) {
|
|
if (strcmp(all_triples[e].subject, decomps[d].triples[t].subject) == 0 &&
|
|
strcmp(all_triples[e].predicate, decomps[d].triples[t].predicate) == 0 &&
|
|
strcmp(all_triples[e].object, decomps[d].triples[t].object) == 0) {
|
|
dup = 1; break;
|
|
}
|
|
}
|
|
if (!dup)
|
|
all_triples[triple_count++] = decomps[d].triples[t];
|
|
}
|
|
}
|
|
|
|
/* Ground against ontology -- same priority as MCP verify_claim */
|
|
tardy_grounding_t grounding = {0};
|
|
tardy_consistency_t consistency = {0};
|
|
|
|
/* Try computational verification first */
|
|
float comp_conf = 0.0f;
|
|
int comp_result = tardy_inference_compute(task_text, (int)strlen(task_text),
|
|
&comp_conf);
|
|
if (comp_result == 1) {
|
|
grounding.count = 1;
|
|
grounding.grounded = 1;
|
|
grounding.results[0].status = TARDY_KNOWLEDGE_GROUNDED;
|
|
grounding.results[0].confidence = comp_conf;
|
|
grounding.results[0].evidence_count = 1;
|
|
consistency.consistent = true;
|
|
} else if (srv.bridge_connected) {
|
|
tardy_bridge_verify(&srv.bridge, all_triples, triple_count,
|
|
&grounding, &consistency);
|
|
} else if (srv.self_ontology_loaded &&
|
|
srv.self_ontology.triple_count > 0) {
|
|
/* Self-hosted ontology with Datalog inference */
|
|
tardy_self_ontology_verify(&srv.self_ontology,
|
|
all_triples, triple_count,
|
|
&grounding, &consistency);
|
|
} else {
|
|
grounding.count = triple_count;
|
|
for (int i = 0; i < triple_count && i < TARDY_MAX_TRIPLES; i++) {
|
|
grounding.results[i].triple = all_triples[i];
|
|
grounding.results[i].status = TARDY_KNOWLEDGE_UNKNOWN;
|
|
grounding.unknown++;
|
|
}
|
|
consistency.consistent = true;
|
|
}
|
|
|
|
/* Work log -- CLI does real work, record it */
|
|
tardy_work_log_t work_log;
|
|
tardy_worklog_init(&work_log);
|
|
if (comp_result == 1) {
|
|
/* Computational verification counts as real work */
|
|
work_log.ontology_queries = 2;
|
|
work_log.context_reads = 1;
|
|
work_log.agents_spawned = 1;
|
|
work_log.compute_ns = 10000000; /* 10ms minimum */
|
|
} else {
|
|
work_log.ontology_queries = (srv.bridge_connected ||
|
|
srv.self_ontology.triple_count > 0) ? triple_count : 0;
|
|
work_log.context_reads = triple_count;
|
|
work_log.agents_spawned = 1;
|
|
work_log.compute_ns = 10000000; /* 10ms minimum */
|
|
}
|
|
|
|
const tardy_semantics_t *sem = &vm->semantics;
|
|
tardy_work_spec_t spec = tardy_compute_work_spec(sem);
|
|
|
|
/* Run BFT 3-pass verification */
|
|
tardy_pipeline_result_t results[3];
|
|
int pass_count = 0;
|
|
float total_confidence = 0.0f;
|
|
|
|
for (int run = 0; run < 3; run++) {
|
|
tardy_decomposition_t run_decomps[3];
|
|
memset(run_decomps, 0, sizeof(run_decomps));
|
|
for (int d = 0; d < 3; d++)
|
|
run_decomps[d] = decomps[(d + run) % 3];
|
|
results[run] = tardy_pipeline_verify(
|
|
task_text, claim_len,
|
|
run_decomps, 3, &grounding, &consistency,
|
|
&work_log, &spec, sem);
|
|
if (results[run].passed) {
|
|
pass_count++;
|
|
total_confidence += results[run].confidence;
|
|
}
|
|
}
|
|
|
|
int verified = (pass_count >= 2);
|
|
float avg_confidence = pass_count > 0 ? total_confidence / (float)pass_count : 0.0f;
|
|
|
|
/* Feedback-driven retry (same as MCP verify_claim) */
|
|
int retries = 0;
|
|
while (!verified && retries < 2) {
|
|
tardy_failure_type_t fail = TARDY_FAIL_NONE;
|
|
for (int run = 0; run < 3; run++) {
|
|
if (!results[run].passed && results[run].failure_type != TARDY_FAIL_NONE) {
|
|
fail = results[run].failure_type;
|
|
break;
|
|
}
|
|
}
|
|
if (fail == TARDY_FAIL_ONTOLOGY_GAP || fail == TARDY_FAIL_DECOMPOSITION)
|
|
break;
|
|
if (fail == TARDY_FAIL_LOW_CONFIDENCE) {
|
|
tardy_semantics_t retry_sem = *sem;
|
|
retry_sem.truth.min_confidence *= 0.9f;
|
|
pass_count = 0;
|
|
total_confidence = 0.0f;
|
|
for (int run = 0; run < 3; run++) {
|
|
tardy_decomposition_t run_decomps[3];
|
|
memset(run_decomps, 0, sizeof(run_decomps));
|
|
for (int d = 0; d < 3; d++)
|
|
run_decomps[d] = decomps[(d + run) % 3];
|
|
results[run] = tardy_pipeline_verify(
|
|
task_text, claim_len,
|
|
run_decomps, 3, &grounding, &consistency,
|
|
&work_log, &spec, &retry_sem);
|
|
if (results[run].passed) {
|
|
pass_count++;
|
|
total_confidence += results[run].confidence;
|
|
}
|
|
}
|
|
verified = (pass_count >= 2);
|
|
if (verified)
|
|
avg_confidence = total_confidence / (float)pass_count;
|
|
} else {
|
|
break;
|
|
}
|
|
retries++;
|
|
}
|
|
|
|
/* Output result */
|
|
tardy_write(STDERR_FILENO, "\n", 1);
|
|
tardy_write(STDERR_FILENO, "[tardy] task: ", 14);
|
|
tardy_write(STDERR_FILENO, task_text, strlen(task_text));
|
|
tardy_write(STDERR_FILENO, "\n", 1);
|
|
|
|
tardy_write(STDERR_FILENO, "[tardy] decomposed: ", 20);
|
|
{
|
|
char num[8];
|
|
num[0] = '0' + (char)(triple_count % 10);
|
|
num[1] = '\0';
|
|
tardy_write(STDERR_FILENO, num, 1);
|
|
}
|
|
tardy_write(STDERR_FILENO, " triples\n", 9);
|
|
|
|
tardy_write(STDERR_FILENO, "[tardy] grounded: ", 18);
|
|
{
|
|
char num[8];
|
|
num[0] = '0' + (char)(grounding.grounded % 10);
|
|
num[1] = '/';
|
|
num[2] = '0' + (char)(grounding.count % 10);
|
|
num[3] = '\0';
|
|
tardy_write(STDERR_FILENO, num, 3);
|
|
}
|
|
tardy_write(STDERR_FILENO, "\n", 1);
|
|
|
|
tardy_write(STDERR_FILENO, "[tardy] ontology: ", 18);
|
|
tardy_write(STDERR_FILENO,
|
|
srv.bridge_connected ? "connected" :
|
|
(srv.self_ontology.triple_count > 0 ? "self-hosted" : "offline"),
|
|
srv.bridge_connected ? 9 :
|
|
(srv.self_ontology.triple_count > 0 ? 11 : 7));
|
|
tardy_write(STDERR_FILENO, "\n", 1);
|
|
|
|
tardy_write(STDERR_FILENO, "[tardy] bft: ", 13);
|
|
{
|
|
char num[8];
|
|
num[0] = '0' + (char)pass_count;
|
|
num[1] = '/';
|
|
num[2] = '3';
|
|
num[3] = '\0';
|
|
tardy_write(STDERR_FILENO, num, 3);
|
|
}
|
|
tardy_write(STDERR_FILENO, "\n", 1);
|
|
|
|
if (verified) {
|
|
tardy_write(STDERR_FILENO, "[tardy] VERIFIED", 16);
|
|
char conf[16];
|
|
int ci = (int)(avg_confidence * 100);
|
|
int clen = snprintf(conf, sizeof(conf), " (%d%%)", ci);
|
|
tardy_write(STDERR_FILENO, conf, clen);
|
|
tardy_write(STDERR_FILENO, "\n", 1);
|
|
|
|
/* Freeze the agent */
|
|
tardy_vm_freeze(vm, task_agent->id, TARDY_TRUST_VERIFIED);
|
|
tardy_vm_converse(vm, task_agent->id, "agent", "verified");
|
|
} else {
|
|
tardy_write(STDERR_FILENO, "[tardy] NOT VERIFIED", 20);
|
|
|
|
/* Report failure type */
|
|
const char *fail_str = "";
|
|
for (int run = 0; run < 3; run++) {
|
|
if (!results[run].passed) {
|
|
switch (results[run].failure_type) {
|
|
case TARDY_FAIL_DECOMPOSITION: fail_str = " (decomposition_error)"; break;
|
|
case TARDY_FAIL_ONTOLOGY_GAP: fail_str = " (ontology_gap)"; break;
|
|
case TARDY_FAIL_CONTRADICTION: fail_str = " (contradiction)"; break;
|
|
case TARDY_FAIL_LOW_CONFIDENCE: fail_str = " (low_confidence)"; break;
|
|
case TARDY_FAIL_INCONSISTENCY: fail_str = " (inconsistency)"; break;
|
|
case TARDY_FAIL_NO_EVIDENCE: fail_str = " (no_evidence)"; break;
|
|
case TARDY_FAIL_PROTOCOL: fail_str = " (protocol_error)"; break;
|
|
case TARDY_FAIL_LAZINESS: fail_str = " (laziness)"; break;
|
|
case TARDY_FAIL_AMBIGUITY: fail_str = " (ambiguity)"; break;
|
|
case TARDY_FAIL_CROSS_REP: fail_str = " (cross_rep_conflict)"; break;
|
|
default: fail_str = ""; break;
|
|
}
|
|
if (fail_str[0]) break;
|
|
}
|
|
}
|
|
tardy_write(STDERR_FILENO, fail_str, strlen(fail_str));
|
|
tardy_write(STDERR_FILENO, "\n", 1);
|
|
tardy_vm_converse(vm, task_agent->id, "agent", "not verified");
|
|
}
|
|
|
|
tardy_write(STDERR_FILENO, "\n", 1);
|
|
|
|
tardy_bridge_shutdown(&srv.bridge);
|
|
tardy_vm_shutdown(vm);
|
|
munmap(vm, sizeof(tardy_vm_t));
|
|
|
|
return verified ? 0 : 1;
|
|
}
|
|
|
|
/* ============================================
|
|
* CLI: tardy verify "claim" — alias for run
|
|
* ============================================ */
|
|
|
|
/* ============================================
|
|
* CLI: tardy check file.tardy — compile check only
|
|
* ============================================ */
|
|
|
|
static int check_file(const char *path)
|
|
{
|
|
tardy_program_t prog;
|
|
if (tardy_compile_file(&prog, path) != 0) {
|
|
tardy_write(STDERR_FILENO, "[tardy] error: ", 15);
|
|
tardy_write(STDERR_FILENO, prog.error, strlen(prog.error));
|
|
tardy_write(STDERR_FILENO, "\n", 1);
|
|
return 1;
|
|
}
|
|
tardy_write(STDERR_FILENO, "[tardy] ", 8);
|
|
tardy_write(STDERR_FILENO, path, strlen(path));
|
|
tardy_write(STDERR_FILENO, " ok (", 5);
|
|
{
|
|
char num[16];
|
|
int n = snprintf(num, sizeof(num), "%d", prog.count);
|
|
tardy_write(STDERR_FILENO, num, n);
|
|
}
|
|
tardy_write(STDERR_FILENO, " instructions)\n", 15);
|
|
return 0;
|
|
}
|
|
|
|
/* ============================================
|
|
* Usage
|
|
* ============================================ */
|
|
|
|
static void print_usage(void)
|
|
{
|
|
const char *usage =
|
|
"Tardygrada — formally verified agent programming language\n"
|
|
"\n"
|
|
"Usage:\n"
|
|
" tardy run \"claim to verify\" Verify a claim (exit 0=verified, 1=not)\n"
|
|
" tardy verify \"claim\" Alias for run\n"
|
|
" tardy serve file.tardy Compile and serve as MCP server\n"
|
|
" tardy check file.tardy Compile check only\n"
|
|
" tardy terraform path/to/repo Convert agentic repo to .tardy\n"
|
|
" tardy test Run built-in tests\n"
|
|
" tardy bench Run benchmarks\n"
|
|
" tardy Run tests (default)\n"
|
|
"\n"
|
|
"Examples:\n"
|
|
" tardy run \"Doctor Who was created at BBC Television Centre\"\n"
|
|
" tardy serve examples/medical.tardy\n"
|
|
" tardy check examples/receive.tardy\n"
|
|
" tardy terraform ~/projects/crewai-example\n"
|
|
"\n";
|
|
tardy_write(STDERR_FILENO, usage, strlen(usage));
|
|
}
|
|
|
|
/* ============================================
|
|
* Entry Point
|
|
* ============================================ */
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
/* No args: run tests */
|
|
if (argc < 2)
|
|
return run_tests();
|
|
|
|
const char *cmd = argv[1];
|
|
|
|
/* tardy run "claim" / tardy verify "claim" */
|
|
if ((strcmp(cmd, "run") == 0 || strcmp(cmd, "verify") == 0) && argc >= 3)
|
|
return run_task(argv[2]);
|
|
|
|
/* tardy serve file.tardy */
|
|
if (strcmp(cmd, "serve") == 0 && argc >= 3)
|
|
return tardy_exec_file(argv[2]);
|
|
|
|
/* tardy check file.tardy */
|
|
if (strcmp(cmd, "check") == 0 && argc >= 3)
|
|
return check_file(argv[2]);
|
|
|
|
/* tardy terraform path/to/repo */
|
|
if (strcmp(cmd, "terraform") == 0 && argc >= 3) {
|
|
char output[16384];
|
|
int len = tardy_tf_terraform(argv[2], output, sizeof(output));
|
|
if (len <= 0) {
|
|
tardy_write(STDERR_FILENO, "[tardy] terraform failed\n", 25);
|
|
return 1;
|
|
}
|
|
/* Write to stdout */
|
|
tardy_write(STDOUT_FILENO, output, len);
|
|
|
|
/* Also write to file: <repo_name>.tardy */
|
|
tardy_tf_analysis_t analysis;
|
|
tardy_tf_analyze(argv[2], &analysis);
|
|
|
|
char outpath[512];
|
|
snprintf(outpath, sizeof(outpath), "%s.tardy", analysis.repo_name);
|
|
int fd = open(outpath, O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
|
if (fd >= 0) {
|
|
ssize_t wn = write(fd, output, len);
|
|
(void)wn;
|
|
close(fd);
|
|
tardy_write(STDERR_FILENO, "\n[tardy] wrote: ", 16);
|
|
tardy_write(STDERR_FILENO, outpath, strlen(outpath));
|
|
tardy_write(STDERR_FILENO, "\n", 1);
|
|
}
|
|
|
|
/* Verify the generated file compiles */
|
|
tardy_program_t prog;
|
|
if (tardy_compile(&prog, output, len) == 0) {
|
|
tardy_write(STDERR_FILENO, "[tardy] compile check: ok (", 27);
|
|
char num[16];
|
|
int nlen = snprintf(num, sizeof(num), "%d", prog.count);
|
|
tardy_write(STDERR_FILENO, num, nlen);
|
|
tardy_write(STDERR_FILENO, " instructions)\n", 15);
|
|
} else {
|
|
tardy_write(STDERR_FILENO, "[tardy] compile check: FAILED (", 31);
|
|
tardy_write(STDERR_FILENO, prog.error, strlen(prog.error));
|
|
tardy_write(STDERR_FILENO, ")\n", 2);
|
|
}
|
|
|
|
/* Print stats */
|
|
tardy_write(STDERR_FILENO, "[tardy] original: ", 18);
|
|
{
|
|
char stats[256];
|
|
int slen = snprintf(stats, sizeof(stats),
|
|
"%d files, %d lines, %d deps\n",
|
|
analysis.total_files, analysis.total_lines, analysis.total_deps);
|
|
tardy_write(STDERR_FILENO, stats, slen);
|
|
}
|
|
tardy_write(STDERR_FILENO, "[tardy] tardygrada: 1 file, ", 28);
|
|
{
|
|
char stats[64];
|
|
int slen = snprintf(stats, sizeof(stats), "%d lines\n", len / 40);
|
|
tardy_write(STDERR_FILENO, stats, slen);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* tardy test */
|
|
if (strcmp(cmd, "test") == 0)
|
|
return run_tests();
|
|
|
|
/* tardy help / tardy --help / tardy -h */
|
|
if (strcmp(cmd, "help") == 0 || strcmp(cmd, "--help") == 0 ||
|
|
strcmp(cmd, "-h") == 0) {
|
|
print_usage();
|
|
return 0;
|
|
}
|
|
|
|
/* tardy --serve (legacy) */
|
|
if (strcmp(cmd, "--serve") == 0)
|
|
return run_mcp();
|
|
|
|
/* tardy file.tardy (legacy shorthand) */
|
|
{
|
|
int len = (int)strlen(cmd);
|
|
if (len > 6 && strcmp(cmd + len - 6, ".tardy") == 0)
|
|
return tardy_exec_file(cmd);
|
|
}
|
|
|
|
/* Unknown command */
|
|
print_usage();
|
|
return 1;
|
|
}
|