# Yool Tuple Space Kernel

Reference Python kernel for Tuple-Space + Yool Architecture.

Core files:

- `kernel/aggregator.py` - oracle-driven behavior consensus for selecting a
  winning candidate from fan-out output.
- `kernel/arena.py` - adversarial implementer/reviewer pairs for pressure
  testing generated candidates before selection.
- `kernel/yool_tuple_kernel.py` — tuple-space, lazy `batch_spawn`, `LaneWorkerPool`,
  and the safe-speed guardrails (cache, backoff, circuit breaker).
- `kernel/providers.py` — dependency-free OpenAI-compatible LLM client
  (`LLMProvider`) with DeepSeek / MiMo / local presets, usage + cost accounting,
  and a `make_executor` adapter for `LaneWorkerPool`.
- `kernel/subagent_runtime.py` — `SubagentRuntime` that turns the virtual
  `batch_spawn` model into **real** subagents on a provider.

## Primitives

- `out_tuple`, `in_tuple`, `rd_tuple`
- `spawn_agent`
- `batch_spawn(depth, branching, compression_threshold)`
- `route_packet`
- `scan_index`
- `hookwall`
- `compress_token`
- `prune_idle`
- `ReceiptCache` for receipt/input-hash dedupe
- `ProviderCircuitBreaker` and jittered backoff for API/LLM calls
- `ContextCompressor` for large prompt/context payloads
- `LaneWorkerPool` for adaptive per-lane fan-out and small-task batching
- `record_token_usage` / `token_usage` snapshots for per-lane token and cost accounting

## Scale model

Use `batch_spawn(root, "codex_worker", depth=4, branching=32)` to represent
1,048,576 subagents without materializing a flat million-item Python list. The
kernel stores a lazy batch controller tuple plus compressed virtual-agent
accounting, then materializes only active work.

Inactive materialized agents can be compacted with `compress_token(agent_id)`.
`prune_idle(max_active)` automatically compresses the oldest active subagents.

## Real subagents

`kernel/subagent_runtime.py` materializes N subagent tuples on a lane and drains
them through `LaneWorkerPool`, where each tuple is executed by a real
`LLMProvider` (DeepSeek / MiMo / local). The fan-out inherits bounded per-lane
concurrency, the receipt/input cache (identical prompts hit cache once), jittered
backoff, and the provider circuit breaker.

```python
from kernel.providers import resolve_provider_config, LLMProvider
from kernel.subagent_runtime import SubagentRuntime

provider = LLMProvider(resolve_provider_config("deepseek"))
# CLI profiles resolve to an explicit API count; standard is 200.
report = SubagentRuntime(provider).run("audit this module", subagents=200)
print(report.format_summary())  # completed/failed, tokens, total cost in USD
```

Oracle-driven aggregation lets callers plug their own test runner and select
the candidate whose behavior is best supported by pass/fail evidence:

```python
def oracle_fn(code: str) -> dict[str, bool]:
    return {"unit": "expected_role" in code, "security": "admin" in code}

report = SubagentRuntime(provider).run(
    "fix the role guard",
    subagents=200,
    aggregator="behavior",
    oracle=oracle_fn,
)
print(report.selected_result.text)
print(report.aggregation["broken_tests"])
```

Adversarial arena mode is API-only and leaves the default fan-out path intact.
It runs M implementer attempts and M senior-reviewer critiques, then picks the
highest-scoring attempt with zero critic violations:

```python
critic = LLMProvider(resolve_provider_config("openrouter"))
report = SubagentRuntime(provider).run(
    "repair the router guard",
    mode="arena",
    M=100,
    critic_provider=critic,
)
print(report.winner_text)
```

```bash
# offline cost projection — no key, no network:
python kernel/subagent_runtime.py --provider deepseek \
  --task "..." --dry-run --report-dir reports/fanout
python kernel/subagent_runtime.py --provider deepseek --fanout-profile max \
  --task "..." --dry-run --report-dir reports/fanout
```

Batch JSONL mode reuses one provider/runtime boot for many tasks and emits one
line per result when `--json` is set:

```bash
python kernel/subagent_runtime.py --batch-file tasks.jsonl --fanout-profile max \
  --dry-run --json --report-dir reports/batch > out.ndjson
```

Each input line is `{ "task_id": "...", "prompt": "...", "system": "..." }`.
Malformed lines and per-task failures emit `status: "error"` and do not stop the
remaining tasks.

## Safe speed model

The reference kernel increases throughput without provider-ban risk by avoiding
repeat work and by slowing down safely when providers fail:

- `TupleSpace.execute_tuple(...)` checks registered local yools first, compresses
  large LLM context, hits `ReceiptCache`, then calls the provider with jittered
  backoff and a provider-level circuit breaker.
- `LaneWorkerPool.concurrency_for(lane)` adapts from lane queue depth, latency,
  failures, and env ceilings instead of using one fixed worker count forever.
- `LaneWorkerPool.run_lane_batched(...)` groups small lane tasks into bounded
  batches.
- `speculative_executor` is only used when the tuple data explicitly sets
  `idempotent=True`.
- `TupleSpace.record_token_usage(...)` records prompt/completion tokens and
  cost by lane, and `LaneWorkerPool.snapshot()` exposes lane success/failure
  metrics for orchestration dashboards.

## Runtime policy

Environment aliases:

- `YOOL_TUPLE_LANE_CONCURRENCY` / `YOOL_LANE_CONCURRENCY`, default `32`
- `YOOL_TUPLE_MAX_LANE_CONCURRENCY` / `YOOL_MAX_LANE_CONCURRENCY`, default `64`
- `YOOL_TUPLE_CPU_QUOTA_PCT` / `YOOL_CPU_QUOTA_PCT`, default `95`
- `YOOL_TUPLE_QUEUE_MAXSIZE` / `YOOL_QUEUE_MAXSIZE`, default `8192`
- `YOOL_TUPLE_COMPRESSION_THRESHOLD` / `YOOL_COMPRESSION_THRESHOLD`, default `1024`
- `YOOL_TUPLE_CACHE_MAX_ENTRIES` / `YOOL_CACHE_MAX_ENTRIES`, default `16384`
- `YOOL_TUPLE_CACHE_TTL_S` / `YOOL_CACHE_TTL_S`, default `3600`
- `YOOL_TUPLE_API_MAX_RETRIES` / `YOOL_API_MAX_RETRIES`, default `3`
- `YOOL_TUPLE_API_BACKOFF_BASE_MS` / `YOOL_API_BACKOFF_BASE_MS`, default `100`
- `YOOL_TUPLE_API_BACKOFF_MAX_MS` / `YOOL_API_BACKOFF_MAX_MS`, default `5000`
- `YOOL_TUPLE_CIRCUIT_FAILURE_THRESHOLD` / `YOOL_CIRCUIT_FAILURE_THRESHOLD`, default `5`
- `YOOL_TUPLE_CIRCUIT_COOLDOWN_S` / `YOOL_CIRCUIT_COOLDOWN_S`, default `30`
- `YOOL_TUPLE_BATCH_SMALL_TASK_SIZE` / `YOOL_BATCH_SMALL_TASK_SIZE`, default `32`
- `YOOL_TUPLE_CONTEXT_COMPRESSION_CHARS` / `YOOL_CONTEXT_COMPRESSION_CHARS`, default `6000`

## Usage

```python
from kernel.yool_tuple_kernel import build_default_space

space, root = build_default_space()
receipt = space.batch_spawn(root, "codex_worker", depth=4, branching=32)
space.record_token_usage("analysis", prompt_tokens=120, completion_tokens=40, cost_usd=0.01)
print(receipt.virtual_agents)  # 1048576
print(space.snapshot())
```

## Consumer adapter

`examples/python/prompt_fanout.py` provides a small `PromptFanout` adapter for
`simplicio-sprint` and `simplicio-dev-cli` consumers that do not want to manage
root tuples directly:

```python
from examples.python.prompt_fanout import PromptFanout

fanout = PromptFanout(repo="checkout-api", authority="simplicio-sprint")
root, receipt = fanout.spawn_task(
    "verify checkout edge cases",
    mapper_context={"target": "src/checkout.ts"},
    depth=2,
    branching=8,
)
print(receipt.virtual_agents)
print(fanout.snapshot()["token_usage"])
```

Run:

```bash
python kernel/yool_tuple_kernel.py
python -m unittest discover -s tests -p "test_*.py"
```
