# TENET — Full Documentation > This file contains the complete TENET documentation for LLM consumption. > Source: https://docs.10et.ai --- # Getting Started ## What is TENET? URL: https://docs.10et.ai/introduction TENET is the context and learning layer for AI agents. It sits between your agents and your project, capturing every decision, accumulating training data, and improving the policy — automatically. ## The Problem Every AI agent starts from zero. Every session. The agent has no memory of what worked yesterday, no model of the domain it operates in, no learned preferences from the human it serves. Session ends, context gone. ## What TENET Does TENET provides the closed loop that connects **memory**, **training**, **policy**, and **eval** into a system that compounds: - **Memory** — every decision, pattern, and learned knowledge persists across sessions via a searchable knowledge graph with embeddings - **Training** — every agent action produces a (state, action, outcome) tuple that feeds the learning loop - **Policy** — an RL-trained action selector that biases agents toward what historically worked for YOUR project - **Eval** — continuous A/B testing that measures real improvement and catches regression ## How It Compounds You and your agents work normally using any tool. TENET captures decisions, code change outcomes, and patterns. Journals accumulate. Memory indexes. TENET knows your naming patterns, architecture preferences, which approaches work in your codebase. Agents get better suggestions from memory search. The policy head has enough data. RL agents try improvements while you sleep — eval against your metrics, keep what works, revert what doesn't. You wake up to PRs. The world model deeply understands your project. New team members' agents inherit the full context. The system understands not just what the code does but how and why. ## Works With Any Harness TENET provides context via MCP. Use it with: - **TENET harness** (built-in TUI with extensions, skills, RPC mode) - **Claude Code** (Anthropic's CLI agent) - **Cursor** (IDE-native agent) - **Custom scripts** (anything that can call MCP tools) ## For Solo Developers and Teams One TENET workspace. Your agents learn your patterns, preferences, and codebase. Overnight agents improve your metrics. ```bash tenet init ``` Parent TENET workspace scopes child workspaces per service. Each service has its own context and agents. New hire's agents inherit full context from day one. ```bash tenet init --parent ./platform ``` ## Quickstart URL: https://docs.10et.ai/quickstart ## Install ```bash npm install -g @10et/cli # package name during migration ``` Install the CLI with `npm i -g @10et/cli`. Both `tenet` and `jfl` commands work during migration. ## Initialize **New project:** ```bash tenet start my-project ``` This runs `init → setup → launch` in one command. Creates the workspace, configures agents for your stack, deploys CI workflows, and opens your editor. **Existing project:** ```bash cd your-project tenet init tenet setup ``` `init` creates the context layer. `setup` analyzes your codebase and creates personalized RL agents. ## What gets created ``` your-project/ ├── .tenet/ │ ├── config.json # Project config │ ├── journal/ # Session journals (JSONL) │ └── agents/ # Agent configs (TOML) ├── eval/ # Eval scripts for your stack ├── knowledge/ # VISION, THESIS, NARRATIVE ├── CLAUDE.md # Agent instructions └── AGENTS.md # Pi agent instructions ``` ## Run your first agent ```bash tenet peter agent list ``` ``` test-coverage Metric: coverage_percent (maximize) code-quality Metric: quality_score (maximize) ``` Run one round: ```bash tenet peter agent test-coverage --rounds 1 ``` ``` Baseline: 0.1276 Round 1 +0.0031 KEPT 48 tests added Coverage: 12.7% → 13.1% ``` ## Check health ```bash tenet doctor ``` ``` [ok] Context Hub (port 4360) [ok] Memory: 349 entries, 349 embedded [ok] Agents: 5 configured All checks passed. ``` ## What's next The RL learning loop, eval system, and agent architecture. TOML config reference — metrics, scope, eval scripts. How TENET remembers and learns from history. The nightly orchestrator that runs your agents. ## Capabilities URL: https://docs.10et.ai/capabilities # Capabilities TENET is a CLI that gives AI agents persistent memory, a learning loop, and coordination. Here's what you can do with it. ## Context Hub A daemon that runs alongside your agent sessions. Every agent connects to it via MCP. It serves journals, memory, knowledge docs, and events. ```bash tenet context-hub ensure # start the hub tenet ask "why is the timeout 30s?" # query your project's history tenet search "authentication flow" # semantic search across all memory ``` What it enables: - Agents start sessions with full context from every previous session - Semantic search across decisions, code patterns, and experiments - MCP server — works with Claude Code, Pi, Cursor, any MCP-compatible agent ## Peter Parker (Agent Orchestrator) The meta-orchestrator that decides which agents to run, in what order, and with what context. Named after Andrej Karpathy's autoresearch pattern. ```bash tenet setup # auto-detect metrics, create agents tenet peter agent test-coverage -r 5 # run test-coverage agent for 5 rounds tenet peter daily # run all agents with gradient tenet peter status # see what's running, what improved ``` Each round: 1. **Eval before** — measure the metric (coverage, quality, speed) 2. **Agent changes code** — in an isolated worktree 3. **Eval after** — did the metric improve? 4. **Keep or revert** — `git reset --hard` if it regressed 5. **Record tuple** — (state, action, reward) → training buffer ```bash # What a nightly run looks like $ tenet peter daily test-coverage (maximize) Round 1 +0.31% kept 48 tests added Round 2 -0.02% reverted types broke Round 3 +0.35% kept config loader code-quality (maximize) Round 1 +0.45% kept 12 console.logs → logger 4 improvements shipped. Tomorrow's agents are smarter. ``` ## RL Learning Loop Every agent action produces training data. The policy head learns what works in YOUR codebase. ```bash tenet eval status # current scores and trends tenet eval compare -2 -1 # compare last two snapshots tenet train transform # prepare tuples for training tenet train policy-head # train the policy head tenet policy-head score --type fix --description "add error handling" --scope small ``` The loop: - **Training buffer** — append-only JSONL of (state, action, reward) tuples - **Policy head** — neural network that predicts which actions improve metrics - **Build evals** — write a spec, the eval checks if it's built. Agents iterate from 0% to 100%. ```bash # Score candidate actions before committing $ tenet policy-head rank '[ {"type":"fix","description":"add retry logic","scope":"small"}, {"type":"refactor","description":"extract auth module","scope":"medium"} ]' 1. fix: add retry logic → predicted +0.04 2. refactor: extract auth → predicted +0.02 ``` ## Memory System Persistent memory with semantic search, graph edges, and knowledge lifecycle. ```bash tenet memory status # embedding health, total entries tenet memory search "auth flow" # search past decisions tenet organize # audit docs for staleness → PENDING.md ``` What's stored: - **Journals** — structured entries (decisions, features, fixes, discoveries) from every session - **Knowledge docs** — VISION.md, THESIS.md, ARCHITECTURE.md — living documents - **Code headers** — `@purpose` annotations indexed from source files - **Graph edges** — structured relationships (updates, contradicts, related_to) - **Embeddings** — semantic vectors for similarity search ## Event Bus (MAP) The nervous system. Events flow between agents, flows, and the hub. ```bash tenet events recent # see what's happening tenet events publish eval:scored # emit a custom event ``` Events trigger flows automatically: | Event | What happens | |-------|-------------| | `eval:scored` with `improved=true` | Auto-merge PR, close linked issue | | `scope:impact` | Cascade evals to downstream services | | `cron:nightly` | Peter Parker runs all agents with gradient | | `session:ended` | Journal synced, memory indexed | ## Flows (YAML Automation) Declarative event-driven workflows. Cron triggers, event patterns, agent spawns, approval gates. ```yaml # .tenet/flows/self-driving.yaml flows: - name: auto-merge-on-improvement trigger: pattern: "eval:scored" condition: 'data.improved == "true"' actions: - type: command command: "gh pr merge {{data.pr_number}} --auto" - type: journal entry_type: milestone title: "Auto-merged PR #{{data.pr_number}}" ``` ```bash tenet flows list # see all flows tenet flows enable # activate a flow ``` ## Services (Multi-Repo Coordination) Register services, declare what they produce and consume. Cross-repo impact detection. ```bash tenet services register ./api # register a service tenet scope list # see all produces/consumes tenet scope impact --service api # what breaks if API changes? tenet onboard ./new-service # full onboarding wizard ``` Scopes enable cascade: ``` api produces: api:schema-change web consumes: api:schema-change → API change triggers web evals automatically ``` ## IDE (Terminal Workspace) Multi-pane tmux workspace with smart surface detection. ```bash tenet ide # auto-detect and launch tenet ide add browser # add browser pane tenet ide add eval # add eval dashboard tenet ide open api # open child service tenet ide available # list all surface types ``` ## Browser (Agent Eyes) Terminal browser (Carbonyl) with CDP bridge. Agents get DOM, humans see pages. ```bash tenet-browser.sh https://10et.ai # launch browser # Then from agent session: subway_call("browser.relay", "navigate", '{"url":"https://..."}') subway_call("browser.relay", "read", '{}') # structured DOM subway_call("browser.relay", "click", '{"selector":"#btn"}') ``` Human interactions broadcast on `browser.events` — agents can respond to what you're looking at. ## Subway Mesh (Agent Coordination) P2P network for agent-to-agent communication across machines and sessions. ```bash subway_send("datboi.relay", "deploy is failing") subway_call("browser.relay", "navigate", '{"url":"..."}') subway_broadcast("status", "deploy complete") subway_subscribe("browser.events") ``` ## Migration Moving from JFL? One command: ```bash npm i -g @10et/cli tenet migrate # .tenet/ → .tenet/, updates all configs tenet migrate --rollback # undo ``` Both `jfl` command and `.tenet/` directory keep working — no rush. ## How It Works URL: https://docs.10et.ai/how-it-works TENET's core innovation is a reinforcement learning loop for code. Agents don't just make changes — they measure whether changes improved the codebase, keep what works, and learn from the results. ## The RL Loop **State** (world model) → **Action** (agent makes change) → **Eval** (measure result) → Keep or Revert → **Training Buffer** → **Policy Head** (learn what works) → back to State ### 1. State (World Model) Before each round, TENET captures the current system state: - Composite eval score - Test pass rate and coverage - Build health - Code quality metrics - Agent's trajectory (what it tried before) ### 2. Action (Agent) The agent makes a focused code change. The policy head helps select what type of change to try based on what worked in the past. ### 3. Eval (Measure) An eval script runs against the agent's changes — not the main branch. The `AGENT_WORKTREE` mechanism ensures the eval tests the actual changes in an isolated git worktree. ### 4. Reward (Keep or Revert) - **Score improved** → change is kept, merged to the session branch - **Score stayed same or regressed** → `git reset --hard HEAD~1`, change reverted ### 5. Training Buffer Every round — kept or reverted — writes a training tuple: ```json { "agent": "test-coverage", "state": { "composite_score": 0.1276, ... }, "action": { "type": "add_tests", "description": "...", "files_affected": [...] }, "reward": { "composite_delta": 0.0031, "improved": true } } ``` ### 6. Policy Head A 14M-parameter transformer trained on the training buffer. Predicts which actions will produce positive reward given the current state. Retrained nightly when 50+ new tuples accumulate. ## The Nightly Loop Every night at 2 AM (configurable): ``` tenet peter daily +-- Mine training tuples from journals +-- Synthesize product context +-- Strategic reasoning (which agents to run?) +-- Run stale agents (5 rounds each) +-- Retrain policy head (if 50+ new tuples) +-- Pick up backlog issues → create PRs ``` ## Self-Driving Pipeline Issues flow through a kanban pipeline automatically: ``` Issue filed (Linear/GitHub) → tenet/backlog label → PP picks up (every 30 min) → Agent creates PR → CI runs eval → Score improves → auto-merge → close issue → Score regresses → request changes ``` ## Key Insight The eval script is the reward function. **If the eval measures the right thing, agents improve. If it doesn't, they waste compute.** We learned this the hard way — 750 rounds with 2.5% keep rate because eval scripts were at ceiling (test pass rate was already 100%). The fix: eval scripts that measure metrics with real gradient (actual coverage percentage, not just pass/fail). ## Architecture URL: https://docs.10et.ai/architecture TENET is a collection of components that work together to create a learning system for AI agents. ## System Overview **Your Project** → **Context Hub** → **Agents** → **Eval** → **Training** → **Policy Head** → better agents tomorrow | Layer | Components | |-------|-----------| | **CLI** | init, setup, peter, train, eval, ide, deploy | | **Context Hub** | Memory DB, Event Bus, Indexer (port 4360) | | **Agent Harness** | Peter Parker, RL agents, worktree isolation | | **Learning** | Training buffer, policy head (14M params), build evals | | **Platform** | Dashboard, auth, cloud agents, team features | | **Mesh** | Subway P2P for agent coordination | ## Components ### CLI The entry point. All commands go through `tenet`: | Command | Purpose | |---------|---------| | `tenet` | Launch Pi with TENET extensions | | `tenet init` | Scaffold a new project | | `tenet setup` | Auto-detect metrics, create agents | | `tenet peter` | Agent orchestrator | | `tenet train` | Train policy head | | `tenet eval` | Run evals, check scores | | `tenet ide` | Terminal workspace | | `tenet deploy` | Deploy to platform | ### Context Hub The central coordination daemon. Runs locally on port 4360. - **Memory database** — SQLite with indexed memories, semantic embeddings, graph edges - **Event bus** — MAP (Multiplayer Agent Protocol) events for agent coordination - **Periodic indexer** — Indexes journal entries every 60s, code headers every 5 min - **API server** — REST endpoints for memory, events, context, eval ### Agent Harness Autonomous improvement agents that run in isolated git worktrees. **The loop:** Measure the baseline metric (coverage, quality, speed) In an isolated worktree — main branch is never touched Measure again. Did the metric improve? Score improved → advance branch, create PR. Regressed → `git reset --hard` (state, action, reward) → training buffer. Policy head learns. ### Storage Layer Everything is files in your repo: | Component | Format | Location | |-----------|--------|----------| | Journals | JSONL | `.tenet/journal/*.jsonl` | | Training buffer | JSONL | `.tenet/training-buffer.jsonl` | | Agent configs | TOML | `.tenet/agents/*.toml` | | Memory | SQLite | `.tenet/memory.db` | | Eval results | JSONL | `.tenet/eval.jsonl` | | Policy weights | JSON | `.tenet/checkpoints/` | | Flows | YAML | `.tenet/flows/*.yaml` | | Config | JSON | `.tenet/config.json` | ### Platform (Cloud) Optional hosted services for dashboard, auth, cloud agents, and team features. | API | Purpose | |-----|---------| | `/api/tenet/memory/*` | Cloud memory sync | | `/api/tenet/train` | Remote training | | `/api/tenet/policy` | Policy inference | | `/api/tenet/tuples` | Tuple upload | | `/api/agents/*` | Cloud agent management | | `/api/sessions/*` | Session tracking | ### Subway Mesh P2P agent coordination. Agents discover each other, send messages, broadcast events across machines. | Agent | Role | |-------|------| | Your Pi session | Coding agent with TENET tools | | `browser.relay` | Terminal browser with DOM access | | Other sessions | Parallel agents on same or different machines | ## Data Flow Agent sessions write journal entries and training tuples Context Hub indexes journals, code headers, embeddings Training buffer feeds the policy head — learns what works Picks best next experiment based on policy predictions Run in worktrees, eval-gated, auto-PR on improvement --- # Agent Harness ## Agent Overview URL: https://docs.10et.ai/agents/overview TENET agents are autonomous workers that make focused code changes, measure the results, and learn from the outcomes. They run on a reinforcement learning loop — keep what improves, revert what doesn't. ## How Agents Work Each agent has: - **A metric** — what it's trying to improve (test coverage, startup speed, code quality) - **An eval script** — how to measure the metric (bash or TypeScript) - **A scope** — which files it can modify - **A time budget** — how long each round gets ``` Agent starts → Measure baseline (run eval) → Make a focused change (via Claude/Sonnet) → Measure again (run eval) → Score improved? → KEEP (advance branch) → Score same/worse? → REVERT (git reset) → Write training tuple → policy head learns → Repeat for N rounds ``` ## Built-in Agents TENET ships with 5 focused agents out of the box: | Agent | Metric | Direction | What it does | |-------|--------|-----------|-------------| | `test-coverage` | coverage_percent | maximize | Adds tests for uncovered files. Uses `jest --coverage`. | | `code-quality` | quality_score | maximize | Reduces console.logs, `any` types, TODOs. Adds `@purpose` headers. | | `cli-speed` | p90_ms | minimize | Optimizes CLI startup latency. Lazy-loads, caches, reduces imports. | | `telemetry-rl` | product_health | maximize | Improves real user experience: startup speed, session reliability. | | `onboarding-success` | success_rate | maximize | Fixes onboarding edge cases in `tenet init`. | ## Running an Agent ```bash # List configured agents tenet peter agent list # Run a specific agent for 3 rounds tenet peter agent test-coverage --rounds 3 # Run all agents (swarm mode) tenet peter agent swarm --rounds 10 ``` ## Agent Output ``` Running Scoped Agent: test-coverage (3 rounds) Metric: coverage_percent (maximize) Time budget: 600s per round Baseline: 0.1276 ── Round 1/3 ────────────────────────────── Task: Add tests for uncovered files... ✓ Result: 0.1307 (+0.0031) KEPT ── Round 2/3 ────────────────────────────── Task: Add tests for auth module... ✗ Result: 0.1305 (-0.0002) REVERTED ── Round 3/3 ────────────────────────────── Task: Add tests for config loader... ✓ Result: 0.1342 (+0.0035) KEPT Session Complete Improved: 2 Total delta: +0.0066 ``` ## The Key Insight **The eval script is everything.** If the eval measures the right thing, agents improve. If it measures the wrong thing, they waste compute. We learned this the hard way — 750 rounds with 2.5% keep rate because eval scripts were at ceiling (test pass rate was already 100%). The fix: eval scripts that measure metrics with real gradient. Good eval = real gradient (12.8% coverage → 87% room to improve). Bad eval = ceiling (100% test pass rate → nowhere to go). ## What's Next TOML config reference — metrics, scope, time budgets. Write eval scripts that produce real gradient. The meta-orchestrator that runs the nightly loop. Build custom agents for your own metrics. ## Agent Configuration URL: https://docs.10et.ai/agents/configuration Agents are configured with TOML files in `.tenet/agents/`. Each file defines one agent with its metric, eval script, scope, and constraints. ## Basic Example ```toml .tenet/agents/test-coverage.toml [agent] name = "test-coverage" scope = "tests" metric = "coverage_percent" direction = "maximize" time_budget_seconds = 600 rounds = 10 target_repo = "../my-service" description = "Add tests for uncovered files. Focus on src/ files with 0% coverage first." [eval] script = "eval/test-coverage.sh" data = "eval/fixtures/test-coverage-baseline.jsonl" [constraints] scope_files = ["src/**/*.ts", "src/**/__tests__/*.test.ts"] max_file_changes = 5 ``` ## Reference ### `[agent]` Section | Field | Type | Required | Description | |-------|------|----------|-------------| | `name` | string | ✅ | Unique agent identifier | | `scope` | string | ✅ | Category (tests, quality, performance, product) | | `metric` | string | ✅ | Primary metric name (must match eval script output) | | `direction` | string | ✅ | `"maximize"` or `"minimize"` | | `time_budget_seconds` | number | ✅ | Max time per round | | `rounds` | number | | Default rounds per session (overridable via CLI) | | `target_repo` | string | | Relative path to target repo (for cross-repo agents) | | `description` | string | | Instructions for the agent — what to do, what to avoid | ### `[eval]` Section | Field | Type | Required | Description | |-------|------|----------|-------------| | `script` | string | ✅ | Path to eval script (relative to project root) | | `data` | string | ✅ | Path to eval fixtures/baseline data | ### `[constraints]` Section | Field | Type | Description | |-------|------|-------------| | `scope_files` | string[] | Glob patterns for files the agent can modify | | `files_in_scope` | string[] | Additional file patterns (broader scope) | | `files_readonly` | string[] | Files the agent must NOT modify | | `max_file_changes` | number | Maximum files changed per round | ### `[policy]` Section (Advanced) | Field | Type | Default | Description | |-------|------|---------|-------------| | `embedding_model` | string | auto | Model for state embeddings | | `exploration_rate` | number | 0.2 | Initial exploration rate (ε-greedy) | | `decay_per_round` | number | 0.004 | Exploration decay per round | | `min_exploration` | number | 0.05 | Minimum exploration rate | ### `[context_scope]` Section | Field | Type | Description | |-------|------|-------------| | `produces` | string[] | Events this agent emits (e.g., `"perf:cli-improved"`) | | `consumes` | string[] | Events this agent reacts to (e.g., `"telemetry:metric-alert"`) | ## Full Example (CLI Speed Agent) ```toml .tenet/agents/tenet-cli-speed.toml [agent] name = "tenet-cli-speed" scope = "performance" metric = "p90_ms" direction = "minimize" time_budget_seconds = 180 rounds = 50 target_repo = "../tenet-cli" [eval] script = "eval/cli-speed.sh" data = "eval/fixtures/cli-speed-baseline.jsonl" [constraints] scope_files = [ "src/index.ts", "src/commands/status.ts", "src/commands/doctor.ts", "src/lib/service-detector.ts", "src/utils/cache.ts", ] files_in_scope = ["src/commands/**/*.ts", "src/lib/**/*.ts"] files_readonly = ["eval/**", "node_modules/**", "dist/**"] max_file_changes = 3 [policy] exploration_rate = 0.2 decay_per_round = 0.004 min_exploration = 0.05 [context_scope] produces = ["perf:cli-improved", "perf:latency-reduced"] consumes = ["telemetry:metric-alert", "code:refactored"] ``` ## Creating an Agent Interactively ```bash tenet peter agent create ``` This walks you through setting up name, metric, eval script, and scope. ## Listing Agents ```bash tenet peter agent list ``` ``` Configured Agents test-coverage Scope: tests Metric: coverage_percent (maximize) Time budget: 600s Files: src/**/*.ts, src/**/__tests__/*.test.ts cli-speed Scope: performance Metric: p90_ms (minimize) Time budget: 180s Files: src/index.ts, src/commands/status.ts, ... ``` ## Archiving Agents Move dead agents to `.tenet/agents/_archived/`: ```bash mv .tenet/agents/old-agent.toml .tenet/agents/_archived/ ``` Archived agents are ignored by the nightly loop and `agent list`. ## Eval Scripts URL: https://docs.10et.ai/agents/eval-scripts Eval scripts are the reward function for your agents. They measure a metric before and after an agent makes changes. The delta determines whether the change is kept or reverted. ## Anatomy of an Eval Script An eval script is a bash or TypeScript file that: 1. Runs tests, measurements, or analysis 2. Outputs a JSON object with a primary metric 3. Exits with code 0 (even if the metric is bad) ```bash eval/test-coverage.sh #!/usr/bin/env bash set -euo pipefail # Use AGENT_WORKTREE when running in agent context, # fall back to main repo for manual runs CLI_DIR="${AGENT_WORKTREE:-$HOME/CascadeProjects/my-project}" # Run jest with coverage cd "$CLI_DIR" npx jest --coverage --coverageReporters=json-summary --silent # Parse coverage report COVERAGE_FILE="coverage/coverage-summary.json" LINE_PCT=$(python3 -c "import json; print(json.load(open('$COVERAGE_FILE'))['total']['lines']['pct'])") # Output JSON with primary metric SCORE=$(python3 -c "print(round($LINE_PCT / 100.0, 4))") echo "{\"coverage_percent\": $SCORE, \"line_pct\": $LINE_PCT}" ``` ## The AGENT_WORKTREE Pattern **Critical:** Agents work in isolated git worktrees at `/tmp/tenet-agent-*`. Your eval script must test the agent's changes, not the main branch. Always use `AGENT_WORKTREE` when referencing the target repo: ```bash CLI_DIR="${AGENT_WORKTREE:-$HOME/CascadeProjects/my-project}" ``` This uses the worktree when running in agent context, and falls back to the main repo for manual testing. ## Good vs Bad Eval Scripts ### ❌ Bad: Metric at ceiling ```bash # Tests pass rate — already 100%, no gradient PASSED=$(npx jest --json | jq '.numPassedTests') TOTAL=$(npx jest --json | jq '.numTotalTests') echo "{\"pass_rate\": $(echo "$PASSED / $TOTAL" | bc -l)}" # Always outputs 1.0 — agent can't improve this ``` ### ✅ Good: Metric with real gradient ```bash # Coverage percentage — 12.8% baseline, 87% room to improve npx jest --coverage --coverageReporters=json-summary LINE_PCT=$(jq '.total.lines.pct' coverage/coverage-summary.json) echo "{\"coverage_percent\": $(echo "$LINE_PCT / 100" | bc -l)}" # Outputs 0.128 — every test file moves this number ``` ### ❌ Bad: Binary pass/fail ```bash # Does the build succeed? Yes/no if npm run build; then echo '{"build": 1.0}'; else echo '{"build": 0.0}'; fi # No gradient — agent gets 1.0 or 0.0, nothing in between ``` ### ✅ Good: Continuous signal ```bash # Console.log count — 4461 instances, every cleanup moves the number COUNT=$(grep -r "console\.\(log\|error\|warn\)" src/ | wc -l) SCORE=$(python3 -c "print(round(1.0 - min($COUNT, 5000) / 5000, 4))") echo "{\"quality_score\": $SCORE, \"console_count\": $COUNT}" ``` ## Eval Script Requirements 1. **Output JSON** — Must output a single JSON object on stdout 2. **Primary metric** — The JSON must include the metric field matching your agent config 3. **Exit 0** — Even if the metric is bad. Non-zero exit = eval failure, not bad score 4. **Deterministic** — Same code should produce the same score 5. **Fast** — Under 30 seconds is ideal. Maximum is the agent's `time_budget_seconds` 6. **Stderr for logs** — Write debug output to stderr, not stdout ```bash echo "Running coverage..." >&2 # Goes to stderr (logs) echo '{"coverage_percent": 0.128}' # Goes to stdout (result) ``` ## Composite Metrics For multi-dimensional quality, create a weighted composite: ```bash eval/code-quality.sh #!/usr/bin/env bash CLI_DIR="${AGENT_WORKTREE:-$HOME/CascadeProjects/my-project}" # Multiple signals TODOS=$(grep -r "TODO\|FIXME" "$CLI_DIR/src" | wc -l) CONSOLE_LOGS=$(grep -r "console\.log" "$CLI_DIR/src" | wc -l) ANY_USAGE=$(grep -r ": any" "$CLI_DIR/src" | wc -l) # Individual scores (0-1) TODO_SCORE=$(python3 -c "print(round(1.0 - min($TODOS, 50) / 100, 4))") CONSOLE_SCORE=$(python3 -c "print(round(1.0 - min($CONSOLE_LOGS, 5000) / 5000, 4))") ANY_SCORE=$(python3 -c "print(round(1.0 - min($ANY_USAGE, 1000) / 1000, 4))") # Weighted composite QUALITY=$(python3 -c "print(round($TODO_SCORE * 0.3 + $CONSOLE_SCORE * 0.4 + $ANY_SCORE * 0.3, 4))") echo "{\"quality_score\": $QUALITY, \"todos\": $TODOS, \"console_logs\": $CONSOLE_LOGS, \"any_usage\": $ANY_USAGE}" ``` ## Testing Your Eval Run it manually first: ```bash # From your project root bash eval/test-coverage.sh # {"coverage_percent": 0.128, "line_pct": 12.8} # With agent worktree simulation AGENT_WORKTREE=/tmp/test-worktree bash eval/test-coverage.sh ``` Make sure the output is valid JSON and the primary metric has room to improve. ## Peter Parker URL: https://docs.10et.ai/agents/peter-parker Peter Parker (PP) is the meta-orchestrator. It decides which agents to run, in what order, and coordinates the entire nightly improvement cycle. ## What PP Does ``` tenet peter daily | +-- 1. Mine training tuples from journals +-- 2. Synthesize product context +-- 3. Layer 3: Strategic reasoning (which agents to run?) +-- 4. Hub health check +-- 5. Run stale agents (5 rounds each, capped at 1 hour) +-- 6. Pick up kanban backlog issues → create PRs +-- 7. Post summary event ``` ## Strategic Reasoning (Layer 3) PP uses Stratus to decide which agents deserve compute tonight: ``` Strategic reasoning: Run: ["test-coverage", "code-quality"] Skip: ["cli-speed"] — already optimized, diminishing returns Reasoning: test-coverage has 87% headroom, highest ROI ``` This prevents wasting tokens on agents that have plateaued. ## Running PP ### Daily Loop (Nightly Cron) ```bash tenet peter daily ``` Full orchestration cycle. Typically run at 2 AM via OpenClaw cron: ```json { "schedule": { "kind": "cron", "expr": "0 2 * * *" }, "payload": { "kind": "agentTurn", "message": "Run the TENET nightly loop..." } } ``` ### Single Agent Run ```bash tenet peter agent test-coverage --rounds 5 ``` ### Agent Swarm ```bash tenet peter agent swarm --rounds 10 ``` Runs all agents with the meta-orchestrator scheduling who goes next based on EMA reward. ### PR Mode ```bash tenet peter pr --task "Fix the auth token refresh bug" ``` Creates a branch, makes changes, opens a PR. Used by the kanban pickup flow. ## The Kanban Pipeline PP integrates with GitHub Issues for autonomous task execution: ``` Issue filed (tenet/backlog label) ↓ (every 30 min, flow: pick-up-linear-tasks) PP picks up highest-priority issue ↓ Moves label: tenet/backlog → tenet/in-progress ↓ Spawns: tenet peter pr --task "GitHub #N: " ↓ Agent makes changes, creates PR ↓ CI runs eval ↓ Score improves → auto-merge → close issue → tenet/done Score regresses → request changes on PR ``` ### Issue Labels | Label | Meaning | |-------|---------| | `tenet/backlog` | Available for PP pickup | | `tenet/in-progress` | PP is working on it | | `tenet/eval` | PR created, waiting for eval | | `tenet/done` | Merged and closed | | `scope:tenet-cli` | Target repo hint | ## Training Data Capture Every PP action generates training tuples: ```json { "agent": "test-coverage", "state": { "composite_score": 0.1276 }, "action": { "type": "add_tests", "description": "..." }, "reward": { "composite_delta": 0.0031, "improved": true } } ``` These feed the policy head for better action selection in future runs. ## PP Commands ```bash tenet peter daily # Full nightly loop tenet peter agent list # List configured agents tenet peter agent <name> --rounds N # Run specific agent tenet peter agent swarm --rounds N # Run all agents tenet peter pr --task "<task>" # Branch + change + PR tenet peter status # Show status + recent events tenet peter telemetry # Run telemetry agent tenet peter synthesize # Regenerate product context ``` ## Nightly Loop URL: https://docs.10et.ai/agents/nightly-loop The nightly loop is TENET's autonomous improvement engine. It runs while you sleep, making focused code changes, measuring results, and keeping only what improves. ## How It Works Every night at 2 AM (configurable): 1. **Mine tuples** — Extract training data from today's journal entries 2. **Synthesize context** — Generate product context summary for agents 3. **Strategic reasoning** — Stratus decides which agents to run based on ROI 4. **Run agents** — 5 rounds per agent, ~1 hour total 5. **Retrain policy head** — If 50+ new tuples since last training 6. **Pick up backlog** — Grab GitHub/Linear issues for autonomous PRs ## Setup ### OpenClaw Cron (Recommended) If you have OpenClaw running, add a cron job: ```json { "name": "nightly-loop", "schedule": { "kind": "cron", "expr": "0 2 * * *", "tz": "America/Denver" }, "payload": { "kind": "agentTurn", "message": "cd ~/CascadeProjects/my-project && tenet peter daily >> .tenet/nightly.log 2>&1", "timeoutSeconds": 3600 } } ``` ### System Cron ```bash # crontab -e 0 2 * * * cd /path/to/project && tenet peter daily >> .tenet/nightly.log 2>&1 ``` ### Manual Run ```bash tenet peter daily ``` ## What to Expect First run output: ``` Peter Parker - Daily RL Agent Loop Found 5 RL agent(s): • test-coverage (coverage_percent, maximize) • code-quality (quality_score, maximize) • cli-speed (p90_ms, minimize) • telemetry-rl (product_health, maximize) • onboarding-success (success_rate, maximize) Pre-flight: Mining tuples from journals... Mined 12 tuples, 8 new → buffer total: 2772 Pre-flight: Synthesizing product context... ✓ Product context updated Layer 3: Strategic reasoning... Run: ["test-coverage", "code-quality"] Skip: ["cli-speed"] — near optimal Reasoning: test-coverage has highest gradient (87% headroom) Hub health: ✓ (12ms) ── test-coverage ────────────────────────────── Baseline: 0.1276 Round 1: +0.0031 KEPT Round 2: -0.0002 REVERTED Round 3: +0.0018 KEPT Round 4: +0.0012 KEPT Round 5: -0.0001 REVERTED ── code-quality ─────────────────────────────── Baseline: 0.6836 Round 1: +0.0045 KEPT ... Daily loop complete. ``` ## Monitoring ### Check Last Night's Results ```bash # View the log tail -100 .tenet/nightly.log # Run the scorecard bash eval/nightly-scorecard.sh ``` ### Scorecard Output **TENET Nightly Scorecard** | Agent | Runs | Kept | Signal? | |-------|------|------|---------| | test-coverage | 15 | 8 | ✓ | | code-quality | 10 | 4 | ✓ | | cli-speed | 174 | 16 | ✓ | Keep rate: 28/199 (14.1%) ## Tuning ### Rounds Per Agent Default is 5. Increase for agents with high gradient: ```toml # .tenet/agents/test-coverage.toml rounds = 20 # More rounds = more improvement per night ``` ### Strategic Reasoning PP uses recent agent performance to decide who runs. If an agent has plateaued (0 improvements in last 10 runs), it gets skipped automatically. ### Cost Control Each round costs ~$0.50-1.00 in API tokens (depends on model). 5 agents × 5 rounds = ~$15/night. Use `--budget` to cap costs: ```bash tenet peter daily --budget 10 # Stop at $10 ``` ## Creating Agents URL: https://docs.10et.ai/agents/creating-agents Create agents tailored to your project's specific improvement goals. ## Interactive Setup ```bash tenet peter agent create ``` Walks you through: name, metric, eval script, scope files, time budget. ## Manual Setup 1. **Write an eval script** in `eval/`: ```bash #!/usr/bin/env bash CLI_DIR="${AGENT_WORKTREE:-$HOME/your-project}" # ... measure your metric ... echo '{"my_metric": 0.42}' ``` 2. **Create agent config** in `.tenet/agents/my-agent.toml`: ```toml [agent] name = "my-agent" scope = "quality" metric = "my_metric" direction = "maximize" time_budget_seconds = 300 description = "What this agent should do to improve my_metric" [eval] script = "eval/my-eval.sh" data = "eval/fixtures/my-agent-baseline.jsonl" [constraints] scope_files = ["src/**/*.ts"] max_file_changes = 3 ``` 3. **Test the eval** manually: ```bash bash eval/my-eval.sh # {"my_metric": 0.42} ``` 4. **Run the agent**: ```bash tenet peter agent my-agent --rounds 1 ``` ## Tips - **Start with one metric** — focused agents beat general-purpose ones - **Verify gradient** — run the eval, confirm the metric isn't at ceiling - **Narrow scope** — fewer `scope_files` = more focused changes - **Short rounds** — 3-5 minutes per round is ideal for iteration speed ## Build Agents URL: https://docs.10et.ai/agents/build-agents Build agents extend the RL improvement loop to greenfield building. Instead of optimizing an existing metric, they build new modules from specs and iterate until every assertion passes. ## The Pattern ``` spec → eval assertions → agent TOML → `tenet peter agent {name}` → Karpathy loop → PR ``` **"Granularity of feedback determines speed of convergence."** A monolithic eval with 16 checks stalled at 7%. The same eval decomposed into 6 page-level evals — each hit 100% in one round. Same agent, same code, different gradient. ## Writing a Build Eval ```typescript // eval/build/storage-adapter.ts export async function evaluate(): Promise<number> { const checks = [ { name: "interface-exists", pass: existsSync(resolve("src/lib/storage/interface.ts")) }, { name: "has-read-method", pass: fileContains("src/lib/storage/interface.ts", "read(") }, { name: "local-impl", pass: existsSync(resolve("src/lib/storage/local.ts")) }, { name: "compiles", pass: tscPasses() }, ] return checks.filter(c => c.pass).length / checks.length } ``` The eval checks `AGENT_WORKTREE` env var so it tests the agent's worktree, not the main repo. ## Agent TOML Config ```toml [agent] name = "build-storage-adapter" scope = "build" # triggers build-specific behavior metric = "spec_compliance" direction = "maximize" time_budget_seconds = 600 [eval] script = "eval/build/storage-adapter.ts" data = "eval/fixtures/build-baseline.jsonl" [task] description = """ Create the TenetStorage adapter with interface, LocalStorage, and CloudStorage implementations. Exact file paths: src/lib/storage/interface.ts, etc. """ ``` ## Build vs RL Agents | | RL Agent | Build Agent | |---|---|---| | Goal | Improve existing metric | Build from spec | | Baseline | Current score | Zero | | Rounds | 5-50, small changes | 3-10, creates files | | Worktree | From origin/main | From HEAD (inherits merged work) | | Turns | 15 per round | 40 per round | | Early stop | No | Yes (stops at 1.0) | ## Build Supervisor Between rounds, `checkRound()` detects patterns: - **Stalled**: 3+ rounds at same score → injects hint - **Filename mismatch**: files created but eval can't find them → alerts - **Repeated reverts**: same checks failing → suggests different approach The supervisor logs learnings to `.tenet/build-learnings.jsonl` for future sessions. ## Eval Decomposition Break complex builds into sub-evals. Instead of one frontend eval with 16 checks, create 6 page-level evals with 2-3 checks each. Each scores independently, giving the agent gradient from round 1. --- # Learning System ## RL Loop URL: https://docs.10et.ai/learning/rl-loop TENET implements a simplified reinforcement learning loop for code improvement. It's not traditional RL with neural network policies playing Atari — it's the Karpathy autoresearch pattern applied to codebases. ## The Three Components ### 1. State (World Model) Before each round, TENET captures the system state: ```typescript interface WorldState { systemState: { activeAgents: string[] hubConnections: number buildStatus: Record<string, string> pendingEvals: number } contextState: { recentCommits: number openPRs: number failingTests: number codeChurn: number } agentState: { lastEvalScore: number rewardEMA: number actionHistory: string[] consecutiveFailures: number } } ``` This gets converted to an `RLState` for the policy head: ```typescript interface RLState { composite_score: number dimension_scores: Record<string, number> tests_passing: number tests_total: number trajectory_length: number recent_deltas: number[] agent: string } ``` ### 2. Action (Policy Head Selects) The policy head is a 14M-parameter transformer that predicts reward for candidate actions: ```typescript interface RLAction { type: "fix" | "refactor" | "feature" | "test" | "config" | "experiment" description: string files_affected: string[] scope: "small" | "medium" | "large" } ``` The agent generates task descriptions informed by: - Experiment history (what worked, what didn't) - Policy head predictions (which action type is most promising) - Product context (what the team is focused on) ### 3. Reward (Eval Delta) After the agent makes changes: ``` reward = eval_score_after - eval_score_before ``` - Positive delta → **KEPT** (change merged to session branch) - Zero or negative delta → **REVERTED** (`git reset --hard HEAD~1`) ## Training Tuple Every round produces a training tuple, regardless of outcome: ```json { "agent": "test-coverage", "state": { "composite_score": 0.1276, "dimension_scores": { "test_pass_rate": 1.0, "build_health": 1.0 }, "trajectory_length": 3, "recent_deltas": [0.0031, -0.0002] }, "action": { "type": "test", "description": "Add tests for claude-md-generator.ts", "files_affected": ["src/utils/__tests__/claude-md-generator.test.ts"], "scope": "medium" }, "reward": { "composite_delta": 0.0031, "improved": true } } ``` ## Why This Works Traditional RL needs millions of episodes. TENET works with hundreds because: 1. **The action space is constrained** — agents modify specific files in a focused scope 2. **The eval is deterministic** — same code produces the same score 3. **The environment resets cleanly** — `git reset` provides perfect rollback 4. **History informs action** — agents see what worked/failed in past rounds ## The Karpathy Connection This is the [autoresearch](https://karpathy.ai/) pattern: - **Propose** an experiment (agent generates a code change) - **Run** the experiment (eval script measures the result) - **Evaluate** the outcome (delta > 0?) - **Learn** from the result (training tuple → policy head) - **Repeat** with better-informed proposals The key insight: you don't need massive compute. You need a good reward signal (eval script) and focused actions (scope files). ## Common Pitfalls **Bad reward signal = wasted compute.** If your eval is at ceiling (100% test pass rate), agents can't improve it. If your eval measures the wrong thing (code hygiene when the agent changes functionality), agents will be reverted every time. Always verify your eval has room to improve before running agents. | Pitfall | Symptom | Fix | |---------|---------|-----| | Eval at ceiling | 0% keep rate, delta always 0 | Measure something with gradient | | Wrong metric | Agent makes good changes, still reverted | Align eval with what agent actually changes | | Eval tests wrong code | Agent's worktree not evaluated | Use `AGENT_WORKTREE` env var | | Scope too broad | Agent changes unrelated files | Narrow `scope_files` in agent config | | Too many rounds | Diminishing returns | Cap at 5-10 rounds per session | ## Eval System URL: https://docs.10et.ai/learning/eval-system The eval system is the reward function for the RL loop. It runs before and after an agent makes changes, and the delta determines whether the change is kept. ## Eval Flow ``` Baseline eval (before changes) → Agent makes code change → Post-change eval (same script) → delta = post - baseline → delta > 0 → KEPT → delta ≤ 0 → REVERTED ``` ## Eval Store All eval results are stored in `.tenet/eval.jsonl`: ```json { "v": 1, "ts": "2026-03-22T21:30:00Z", "agent": "test-coverage", "run_id": "test-coverage-4bc3ff95", "metrics": { "coverage_percent": 0.1307, "line_pct": 13.37, "branch_pct": 12.27 }, "composite": 0.1307, "delta": 0.0031, "improved": true } ``` ## Viewing Eval History ```bash # Current eval status tenet eval status # Compare two snapshots tenet eval compare # View trajectory for an agent tenet eval trajectory --agent test-coverage ``` ## Eval Snapshots When an agent starts, TENET freezes the eval script into a snapshot (SHA-based). This ensures the eval doesn't change mid-run — the same script measures baseline and post-change. Snapshots are cached at `~/.cache/tenet/eval-snapshots/<hash>/`. ## Writing Good Evals See [Eval Scripts](/agents/eval-scripts) for the complete guide on writing eval scripts that produce real gradient. Key principles: 1. Output JSON with a primary metric 2. Use `AGENT_WORKTREE` for cross-repo agents 3. Ensure the metric has room to improve (not at ceiling) 4. Keep evals fast (under 30s) and deterministic ## Training Buffer URL: https://docs.10et.ai/learning/training-buffer The training buffer (`.tenet/training-buffer.jsonl`) captures every agent action and its outcome. This data trains the policy head and provides experiment history for future runs. ## Format Each line is a training tuple: ```json { "id": "tb_eyJjb21wb3Np", "v": "1", "ts": "2026-03-22T21:30:00Z", "agent": "test-coverage", "state": { "composite_score": 0.1276, "dimension_scores": { "test_pass_rate": 1.0, "build_health": 1.0 }, "tests_passing": 1414, "tests_total": 1414, "trajectory_length": 3, "recent_deltas": [0.0031, -0.0002], "agent": "test-coverage" }, "action": { "type": "test", "description": "Add tests for claude-md-generator.ts", "files_affected": ["src/utils/__tests__/claude-md-generator.test.ts"], "scope": "medium", "branch": "session/test-coverage-4bc3ff95-2026-03-22" }, "reward": { "composite_delta": 0.0031, "dimension_deltas": {}, "tests_added": 48, "quality_score": 0.0, "improved": true } } ``` ## Data Sources Tuples come from three sources: | Source | When | What | |--------|------|------| | **Agent runs** | Each round | State, action, reward from eval delta | | **Tuple miner** | Nightly pre-flight | Extracts tuples from journal entries | | **Manual** | `tenet_training_buffer` tool | Record observations during sessions | ## Querying the Buffer ```bash # Total tuples wc -l .tenet/training-buffer.jsonl # Tuples by agent jq -r '.agent' .tenet/training-buffer.jsonl | sort | uniq -c | sort -rn # Recent improvements jq 'select(.reward.improved == true)' .tenet/training-buffer.jsonl | tail -5 ``` ## Mining Tuples The tuple miner extracts learning data from journals: ```bash # Mine from all sources tenet eval mine --all # Mine from specific source tenet eval mine --source journals tenet eval mine --source evals tenet eval mine --source sessions ``` ## Buffer Health Check the nightly scorecard for buffer stats: ```bash bash eval/nightly-scorecard.sh ``` ``` Training Buffer ─────────────── Total tuples: 2764 Last 24h: 62 new tuples Reward distribution: test-coverage +8 / -2 / =0 (80% positive) code-quality +4 / -3 / =1 (50% positive) ``` ## When Policy Head Retrains The policy head retrains when the buffer has 50+ new tuples since last training. This happens automatically in the nightly loop, or manually: ```bash tenet train transform && tenet train policy-head --force ``` ## Policy Head URL: https://docs.10et.ai/learning/policy-head The policy head is a neural network trained on your project's training buffer. It predicts which actions will produce positive reward given the current system state. ## Architecture ``` Input: RLState (composite score, dimensions, trajectory) ↓ 4-layer transformer (512 hidden, 8 heads) ↓ Output: predicted reward for each candidate action ``` **Specs:** - 14M parameters - Trained on MPS (Apple Silicon) or CPU - Checkpoint: `.tenet/checkpoints/policy-head-v2.json` - Weights: `.tenet/checkpoints/best_policy_head.pt` ## How It's Used During agent runs, the policy head scores candidate actions: ```bash # Score a single action tenet policy score --type fix --description "Add error handling to auth module" --scope small # Rank multiple actions tenet policy rank '[ {"type": "test", "description": "Add tests for config loader", "scope": "small"}, {"type": "refactor", "description": "Extract auth middleware", "scope": "medium"}, {"type": "fix", "description": "Fix memory leak in hub", "scope": "large"} ]' ``` ``` Ranked Actions (predicted reward): 1. [+0.0042] test: Add tests for config loader (small) 2. [+0.0018] fix: Fix memory leak in hub (large) 3. [-0.0003] refactor: Extract auth middleware (medium) ``` ## Training ### When It Trains The nightly loop retrains automatically when 50+ new tuples have accumulated since last training: ```bash # In peter daily: BUFFER_SIZE=$(wc -l < .tenet/training-buffer.jsonl) LAST_TRAINED=$(jq '.trained_on' .tenet/checkpoints/policy-head-v2.json) NEW_TUPLES=$((BUFFER_SIZE - LAST_TRAINED)) if [ "$NEW_TUPLES" -ge 50 ]; then tenet train transform && tenet train policy-head --force fi ``` ### Manual Training ```bash # Transform raw tuples into training format tenet train transform # Train policy head tenet train policy-head --force ``` ### Training Data The training buffer (`.tenet/training-buffer.jsonl`) contains tuples from: - Agent autoresearch rounds (kept and reverted) - Manual journal entries (mined by tuple miner) - Cross-service events Current stats: **2764 tuples**, **91.6% validation accuracy**. ## Checkpoint ```json { "version": 2, "architecture": "transformer-4layer-512h", "embedding_dim": 768, "hidden_dim": 512, "num_layers": 4, "num_heads": 8, "trained_on": 1565, "val_accuracy": 0.9164, "parameters": 14191628, "tool_to_index": { "fix_bug": 0, "refactor_code": 1, "add_feature": 2, "add_tests": 3, "update_config": 4, "run_experiment": 5 } } ``` ## When to Use GPUs The policy head is small (14M params). Training on Apple Silicon MPS takes ~2 minutes. You don't need cloud GPUs unless: - You're training on 10K+ tuples - You want to experiment with larger architectures - You're running parallel training across multiple projects For most users, MPS or CPU is sufficient. ## World Model URL: https://docs.10et.ai/learning/world-model The world model captures a complete snapshot of the system at a point in time. It gives agents and the policy head context about the environment they're operating in. ## WorldState ```typescript interface WorldState { timestamp: number agentId: string systemState: { activeAgents: string[] // Which agents are running worktreeAllocation: {} // Git worktree usage hubConnections: number // Context Hub connections buildStatus: Record<string, string> // Build health per service fileLocks: string[] // Currently locked files pendingEvals: number // Queued eval runs } contextState: { recentCommits: number // Commits in last 24h openPRs: number // Open pull requests failingTests: number // Currently failing tests codeChurn: number // Lines changed recently humanActivity: boolean // Is a human currently working? } agentState: { lastEvalScore: number // Most recent eval composite rewardEMA: number // Exponential moving average of rewards actionHistory: string[] // Recent action types taken consecutiveFailures: number // Reverts in a row } } ``` ## RLState (Policy Head Input) The world state is converted to a compact format for the policy head: ```typescript interface RLState { composite_score: number // Current eval score dimension_scores: { test_pass_rate: number // Test health build_health: number // Build status code_quality: number // Code quality metrics hub_health: number // Hub connectivity } tests_passing: number tests_total: number trajectory_length: number // Rounds completed recent_deltas: number[] // Last 5 reward deltas agent: string // Agent name } ``` ## How It's Used 1. **Before each round** — World state captured as the "before" snapshot 2. **Policy head scoring** — RLState fed to transformer for action ranking 3. **Strategic reasoning** — Peter Parker uses state to decide which agents to run 4. **Training** — State included in training tuples for policy head learning ## State Transitions Each agent round creates a state transition: ``` Prior state (before) → Action (agent change) → Posterior state (after) ``` Transitions are tracked in `.tenet/telemetry/resource-transitions.jsonl` for analysis. ## Build Evals URL: https://docs.10et.ai/learning/build-evals Build evals extend the RL improvement loop to **greenfield building**. Instead of optimizing an existing metric, agents build new modules from specs and iterate until every assertion passes. ## The Pattern ``` spec → eval assertions → agent TOML → `tenet peter agent {name}` → Karpathy loop → PR ``` 1. Write a spec describing what to build 2. Write an eval script with assertions (file exists? method exists? compiles?) 3. Create an agent TOML config with the spec as the task 4. Run Peter Parker — the agent iterates from 0% → 100% 5. PR created automatically when score hits 1.0 ## Writing a Build Eval A build eval is a TypeScript file that checks spec compliance: ```typescript // eval/build/storage-adapter.ts export async function evaluate(): Promise<number> { const checks = [ { name: "interface-exists", pass: existsSync("src/lib/storage/interface.ts") }, { name: "has-read-method", pass: fileContains("src/lib/storage/interface.ts", "read(") }, { name: "has-write-method", pass: fileContains("src/lib/storage/interface.ts", "write(") }, { name: "local-impl", pass: existsSync("src/lib/storage/local.ts") }, { name: "cloud-impl", pass: existsSync("src/lib/storage/cloud.ts") }, { name: "compiles", pass: tscPasses() }, ] return checks.filter(c => c.pass).length / checks.length } ``` ## Agent TOML Config ```toml [agent] name = "build-storage-adapter" scope = "build" metric = "spec_compliance" direction = "maximize" time_budget_seconds = 600 [eval] script = "eval/build/storage-adapter.ts" data = "eval/fixtures/build-baseline.jsonl" [task] description = """ Create the TenetStorage adapter with interface, LocalStorage, and CloudStorage implementations. """ ``` ## Key Insight **"Granularity of feedback determines speed of convergence."** A monolithic eval with 16 checks stalled at 7% for hours. The same eval decomposed into 6 page-level evals — each hit 100% in one round. Same agent, same code, different gradient. ## Build vs RL Agents | | RL Agent | Build Agent | |---|---|---| | **Goal** | Improve existing metric | Build new code from spec | | **Baseline** | Current score (e.g., 0.43) | Zero (nothing exists) | | **Rounds** | 5-50, small changes | 3-10, creates files | | **Worktree** | From origin/main | From HEAD (inherits merged work) | | **Turns** | 15 per round | 40 per round | | **Early stop** | No (keep improving) | Yes (stops at 1.0) | ## Storage Adapter URL: https://docs.10et.ai/learning/storage-adapter TENET's storage adapter pattern lets all modules work against different backends without changing their code. Locally, everything writes to `.tenet/` files and SQLite. In production, the same operations go to Postgres with workspace isolation. ## Interface ```typescript interface TenetStorage { read(key: string): Promise<any> write(key: string, value: any): Promise<void> append(key: string, value: any): Promise<void> list(prefix?: string): Promise<string[]> query(query: Record<string, any>): Promise<any[]> execute(operation: string, params?: any): Promise<any> vectorSearch(vector: number[], options?: { limit?: number }): Promise<any[]> } ``` ## Implementations ### LocalStorage (default) File-based storage in `.tenet/` directory. Uses SQLite for queries and cosine similarity for vector search. This is what runs when you use `tenet` on your machine. ### CloudStorage Postgres-backed storage for multi-user deployments. All operations scoped by `workspaceId`. Uses pgvector for similarity search. ```typescript const storage = new CloudStorage(workspaceId, connectionString) ``` ## Factory ```typescript // Local (default) const local = createStorage() // Cloud const cloud = createStorage({ cloud: { workspaceId: 'ws_123', connectionString: process.env.DATABASE_URL } }) ``` ## How Modules Use It Memory, training buffer, and policy head all accept an optional storage parameter. When not provided, they use LocalStorage (backward compatible): ```typescript // Existing behavior — unchanged const memory = new MemoryDB(projectRoot) // Cloud behavior — same API, different backend const memory = new MemoryDB(projectRoot, { storage: cloudStorage }) ``` ## Domain Engine URL: https://docs.10et.ai/learning/domain-engine The domain engine provides the product-facing API for building agent applications. It wraps TENET's internal infrastructure (memory, training, policy, eval) into a clean interface that any app can use. ## Core Types ### TenetEntity Generic entity that any domain maps to: ```typescript interface TenetEntity { id: string source: string // which platform/connector sourceId: string // platform-specific ID name: string metadata: Record<string, any> funnelStage: string // from template FUNNEL.md temperature: 'hot' | 'warm' | 'cooling' | 'cold' createdAt: Date } ``` - **Dating**: Entity = Match - **Sales**: Entity = Lead - **Recruiting**: Entity = Candidate ### TenetConnector Typed interface to external platforms: ```typescript interface TenetConnector { authenticate(credentials: ConnectorCredentials): Promise<void> syncEntities(since?: Date): Promise syncInteractions(entityId: string): Promise send(entityId: string, content: string): Promise<{ platformMsgId: string }> getProfile(entityId: string): Promise> } ``` ### TenetRewardFunction Domain-specific reward definitions: ```typescript interface TenetRewardFunction { signals: RewardSignal[] calculate(context: RewardContext): number } ``` ## The World Class The `World` (or `DomainEngine`) wraps everything: ```typescript const world = await World.create({ template: 'dating', storage: cloudStorage(userId), connectors: [tinder(token), bumble(token)], }) await world.sync() // pull from platforms const draft = await world.generateDraft(matchId) // memory + policy await world.recordOutcome(draftId, 'send') // training signal await world.train() // nightly: policy improves ``` ## Templates URL: https://docs.10et.ai/learning/templates Templates encode domain expertise so agents don't start from a blank canvas. Each template provides funnel stages, reward functions, psychology frameworks, and anti-patterns specific to a domain. ## Using Templates ```bash # Scaffold a dating agent world tenet init --template dating # Default GTM template (existing behavior) tenet init ``` ## What a Template Contains ``` templates/dating/ ├── FUNNEL.md # matched → messaging → deep → meet ├── SIGNALS.md # reply_rate, response_time, sentiment ├── REWARDS.md # reply +1, meet +10, skip -0.5 ├── PSYCHOLOGY.md # push-pull, vulnerability, timing ├── ANTI_PATTERNS.md # triple-text, interrogation, generic openers ├── MODES.md # bold, playful, chill, intellectual └── connectors/ # platform integration stubs ``` ## Template Loader ```typescript const config = loadTemplate('dating', projectRoot) // Returns structured config from the markdown files: // { funnel: [...stages], rewards: [...signals], antiPatterns: [...], modes: [...] } ``` ## Creating Custom Templates Create a `templates/your-domain/` directory with the standard files. The DomainEngine reads and parses the markdown into structured configuration. ### FUNNEL.md Define your pipeline stages: ```markdown ## Dating-Specific Stages - **matched** — initial match on platform - **opened** — first message sent - **messaging** — active conversation - **deep** — meaningful connection - **meet_proposed** — date suggested - **met** — in-person meeting ``` ### REWARDS.md Define your reward function: ```markdown ## Signal Rewards - reply: +1 - fast_reply: +0.5 (within 1 hour) - meet_proposed: +3 - meet_confirmed: +10 - user_sent_as_is: +0.5 - user_edited: -0.1 - user_skipped: -0.5 ``` --- # Memory ## Memory System URL: https://docs.10et.ai/memory/overview TENET's memory system ensures nothing is forgotten between sessions. Every journal entry, code change, and decision is indexed, embedded, and searchable. ## What Gets Remembered | Source | What's Indexed | How Often | |--------|---------------|-----------| | **Journal entries** | Features, fixes, decisions, discoveries, pivots | Every 60 seconds | | **Code headers** | `@purpose` annotations from source files | Every 5 minutes | | **Manual memories** | Insights, notes, decisions via `tenet_memory_add` | On demand | ## How Search Works TENET uses hybrid search — combining lexical and semantic approaches for best results: ``` Query: "CLI startup optimization" | +----+----+ | | BM25+ Embedding (lexical) (semantic) | | +----+----+ | Reciprocal Rank Fusion (RRF) | Ranked Results ``` ### BM25+ (Always Available) Term-frequency scoring with: - Stopword removal and phrase detection - Adaptive document length normalization - Query term weighting based on IDF - Positive IDF floor (BM25+ variant) — common terms still contribute ### Semantic Search (When Embeddings Available) Cosine similarity on `text-embedding-3-small` vectors: - 1536 dimensions - OpenAI or OpenRouter fallback - Auto-backfill: if key was missing when indexed, embeddings are added later ### Reciprocal Rank Fusion Merges BM25 and embedding results by rank position, not raw scores. More robust than linear interpolation because it doesn't require score normalization. ## Current Stats ```bash tenet memory status ``` ``` total_memories: 349 by_type: {feature: 96, milestone: 96, decision: 55, fix: 40, ...} embeddings: {available: true, count: 349, model: "openrouter/text-embedding-3-small"} ``` **349/349 memories embedded** — zero gaps. ## Graph Edges Memories aren't isolated. They connect to each other: | Edge Type | Meaning | Example | |-----------|---------|---------| | `updates` | New info supersedes old | "CLI speed now 98ms" updates "CLI speed was 6.7s" | | `contradicts` | New finding invalidates old | "Connection pooling helps" contradicts "Keep connections short" | | `related_to` | Topically connected | Memory about eval system → related to agent config | | `caused_by` | Causal relationship | "Test failures" caused_by "Dependency upgrade" | | `part_of` | Hierarchical grouping | Session memories → part_of project milestone | ```bash # Add a link via API curl -X POST http://localhost:4360/api/memory/link \ -H "Content-Type: application/json" \ -d '{"from": 42, "to": 17, "type": "updates"}' ``` ## Code Header Indexing Files with `@purpose` annotations are automatically indexed: ```typescript /** * Memory Indexer Module * * @purpose Automatic indexing of journal entries and code headers */ ``` This creates a searchable memory entry: - Source: `file` - Type: `code-header` - Content: `src/lib/memory-indexer.ts: Automatic indexing of journal entries and code headers` Scans: `src/`, `packages/`, `scripts/`, `eval/` Updates if `@purpose` changes. Deduped by file path. ## Knowledge Doc Lifecycle Knowledge docs (VISION.md, THESIS.md, etc.) are audited for staleness: ```bash tenet organize ``` ``` Doc Health ✓ VISION 0d old drift: 20% mentions: 221 ✓ THESIS 0d old drift: 20% mentions: 223 ✓ NARRATIVE 0d old drift: 20% mentions: 206 0 of 5 docs need attention ``` When docs drift from journal evidence, `tenet organize` generates a `PENDING.md` with proposed updates and open questions for human review. BM25+ hybrid search internals and query optimization. Structured relationships between memories. Auto-backfill, model selection, and fallback behavior. Indexing @purpose annotations from source files. ## Memory Search URL: https://docs.10et.ai/memory/search TENET's memory search combines lexical (BM25+) and semantic (embedding cosine similarity) scoring, merged via Reciprocal Rank Fusion. ## Search Methods | Method | When Used | Requires API Key | |--------|-----------|-----------------| | `bm25` | Keyword-focused queries | No | | `embedding` | Semantic/conceptual queries | Yes | | `hybrid` | Best of both (default) | Partial — falls back to BM25 | ## BM25+ Improvements - **Stopword removal** — cleaner term matching - **Phrase detection** — multi-word terms kept together - **Adaptive b parameter** — adjusts to corpus length variance - **Positive IDF floor** — common terms still contribute (BM25+ variant) - **Query term weighting** — rare terms get more weight ## Boosts | Boost | Factor | Condition | |-------|--------|-----------| | Recency | 1.3x | Within 7 days | | Decision | 1.4x | Type = decision | | Feature | 1.2x | Type = feature | ## API ```bash curl -X POST http://localhost:4360/api/memory/search \ -H "Authorization: Bearer $TOKEN" \ -d '{"query": "startup optimization", "limit": 5, "type": "decision"}' ``` ## Graph Edges URL: https://docs.10et.ai/memory/graph-edges Memories connect to each other via typed edges, creating a knowledge graph. ## Edge Types | Type | Meaning | Example | |------|---------|---------| | `updates` | Supersedes previous knowledge | New benchmark → updates old benchmark | | `contradicts` | Invalidates previous belief | "Pooling helps" contradicts "Keep connections short" | | `related_to` | Topically connected | Eval system → related to agent config | | `caused_by` | Causal chain | Test failures caused by dependency upgrade | | `part_of` | Hierarchical grouping | Session entries → part of milestone | ## Creating Edges ```bash curl -X POST http://localhost:4360/api/memory/link \ -H "Authorization: Bearer $TOKEN" \ -d '{"from": 42, "to": 17, "type": "updates"}' ``` ## Querying Edges ```typescript // Get what a memory updates const links = await getLinksFrom(memoryId) // Get what updates a memory const links = await getLinksTo(memoryId) ``` ## Future: Contradiction Detection When a new memory contradicts existing knowledge, the system will automatically flag it and create an `updates` or `contradicts` edge. ## Embeddings URL: https://docs.10et.ai/memory/embeddings TENET uses `text-embedding-3-small` (1536 dimensions) for semantic search. Embeddings are computed at index time and auto-backfilled if keys were missing. ## Provider Fallback ``` 1. Try OPENAI_API_KEY → text-embedding-3-small 2. If fails → try OPENROUTER_API_KEY → openai/text-embedding-3-small 3. If both fail → memory stored without embedding (BM25 only) 4. Auto-backfill runs periodically to catch up ``` ## Auto-Backfill The periodic indexer automatically backfills missing embeddings: - Runs on first tick after hub startup - Runs whenever new entries are added - Truncates content >28K chars (model limit ~8K tokens) - Uses consecutive-null counter (3 strikes before stopping) ## Manual Backfill ```bash curl -X POST http://localhost:4360/api/memory/index \ -H "Authorization: Bearer $TOKEN" \ -d '{"backfill": true}' ``` ## Stats ```bash tenet memory status # embeddings: {available: true, count: 349, model: "openrouter/text-embedding-3-small"} ``` ## Code Headers URL: https://docs.10et.ai/memory/code-headers Files with `@purpose` annotations are automatically indexed into the memory system, making your codebase searchable alongside journal entries. ## How It Works ```typescript /** * Memory Indexer Module * * @purpose Automatic indexing of journal entries and code headers */ ``` Becomes a memory entry: - **Source:** `file` - **Type:** `code-header` - **Title:** `src/lib/memory-indexer.ts` - **Content:** `src/lib/memory-indexer.ts: Automatic indexing of journal entries and code headers` ## Scanned Directories `src/`, `packages/`, `scripts/`, `eval/`, `app/`, `lib/`, `components/` ## File Types `.ts`, `.tsx`, `.js`, `.jsx`, `.mjs`, `.rs`, `.py`, `.go`, `.sh` ## Update Behavior - Scans every 5 minutes (every 5th periodic indexer tick) - Deduped by file path - If `@purpose` changes, memory is updated and embedding cleared for re-computation - Capped at 200 files per project ## Searching Code Headers ```bash tenet ask "What does the memory indexer do?" # Returns the @purpose annotation alongside journal entries ``` ## Knowledge Docs URL: https://docs.10et.ai/memory/knowledge-docs Knowledge docs (VISION.md, THESIS.md, etc.) are living documents that should evolve with your project. `tenet organize` audits them for staleness. ## The Problem Knowledge docs drift. You write VISION.md on day 1, then 30 days of journals accumulate with decisions, pivots, and discoveries that the doc doesn't reflect. ## The Solution ```bash tenet organize ``` Scans docs against journal evidence, computes drift scores, generates `PENDING.md` with proposed updates and open questions. See [tenet organize](/cli/organize) for the full command reference. ## Recommended Structure ``` knowledge/ ├── VISION.md # What we're building (update quarterly) ├── THESIS.md # Why we win (update with competitive changes) ├── NARRATIVE.md # How we tell the story (update with product changes) ├── PHILOSOPHY.md # Core principles (rarely changes) ├── BRAND_DECISIONS.md # Visual identity, naming (update with rebrand) └── archive/ # Old docs organized by era ├── specs/ ├── research/ └── strategy/ ``` ## Lifecycle Manual or via `tenet init` `tenet organize` flags docs with no journal references Proposed updates + open questions for human review Answers questions, approves changes `tenet organize --apply` commits changes If no activity for 60 days → `knowledge/archive/` --- # Context Hub ## Context Hub URL: https://docs.10et.ai/hub/overview The Context Hub is a local HTTP daemon that coordinates all TENET subsystems. It runs on your machine, manages the memory database, serves context to agents, and coordinates events. ## Starting the Hub ```bash # Start (or ensure running) tenet context-hub ensure # Check health curl http://localhost:4360/health # {"status":"ok","port":4360} ``` The hub starts automatically when you run any TENET command. It persists across sessions. ## What It Does | Feature | Description | |---------|-------------| | **Memory DB** | SQLite database with indexed memories, embeddings, graph edges | | **Periodic Indexer** | Indexes journal entries (60s), code headers (5min), backfills embeddings | | **Event Bus** | MAP events for agent coordination and flow triggers | | **Context API** | Serves project context to agents (journals, knowledge, code) | | **Session Tracking** | Manages active sessions and branches | ## API Endpoints | Endpoint | Method | Description | |----------|--------|-------------| | `/health` | GET | Health check | | `/api/context` | POST | Query project context | | `/api/memory/search` | POST | Search memories | | `/api/memory/add` | POST | Add a memory | | `/api/memory/status` | GET | Memory system stats | | `/api/memory/index` | POST | Trigger reindex + backfill | | `/api/memory/link` | POST | Add graph edge between memories | | `/api/events` | GET/POST | Query or publish MAP events | ## Configuration The hub reads from `.tenet/config.json`: ```json { "contextHub": { "port": 4360 } } ``` Port and auth token are written to: - `.tenet/context-hub.port` - `.tenet/context-hub.token` ## Logs ```bash tail -f .tenet/logs/context-hub.log ``` ## Doctor Check ```bash tenet doctor ``` Reports hub health, memory DB size, journal count, and agent registrations. ## Journal System URL: https://docs.10et.ai/hub/journal The journal is the source of truth for everything that happens in a TENET project. Every feature, fix, decision, and discovery is captured as a JSONL entry. ## Format Each journal file is JSONL (one JSON object per line): ```json { "v": 2, "ts": "2026-03-22T21:30:00.000Z", "session": "session-goose-20260322-2009-4dfeec", "type": "feature", "status": "complete", "title": "Memory system — auto-backfill embeddings", "summary": "Periodic indexer now auto-backfills missing embeddings on first tick", "detail": "Fixed root cause: one 35K-char memory was killing the entire backfill loop", "files": ["src/lib/memory-indexer.ts", "src/lib/memory-search.ts"], "learned": ["Truncate content >28K chars for embedding models"], "next": "Add graph edges to memory schema" } ``` ## Entry Types | Type | When to Use | |------|------------| | `feature` | New capability shipped | | `fix` | Bug fix | | `decision` | Architectural or strategic choice | | `discovery` | Something learned or found | | `milestone` | Significant achievement | | `pivot` | Context checkpoint (mid-session save) | | `session-end` | Session completed | ## File Location ``` .tenet/journal/ ├── main.jsonl # Main branch entries ├── session-goose-20260322-2009-4dfeec.jsonl # Session-specific └── flow-engine.jsonl # Automated flow entries ``` ## Reading Journals ```bash # Recent work summary tenet synopsis 24 # Search memory (journals are indexed into memory DB) tenet ask "What did we do about embeddings?" # Raw journal tail -5 .tenet/journal/main.jsonl | python3 -m json.tool ``` ## How Journals Feed the System ``` Journal entry written ↓ (every 60 seconds) Memory indexer reads it ↓ Extracts content (title + summary + detail + files + learned) ↓ Computes TF-IDF tokens ↓ Computes embedding (text-embedding-3-small) ↓ Stored in memory.db → searchable via tenet_memory_search ↓ Training tuples mined → feeds policy head ``` ## Writing Journal Entries Agents write journal entries automatically via the Pi extension. You can also write them manually: ```bash # Via the memory tool tenet_memory_add --title "My discovery" --content "Details..." --type discovery # Directly to JSONL echo '{"v":2,"ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","session":"main","type":"note","title":"My note","summary":"Details"}' >> .tenet/journal/main.jsonl ``` ## Event Bus URL: https://docs.10et.ai/hub/events The MAP (Multiplayer Agent Protocol) event bus enables loose coupling between agents, flows, and external systems. Events flow through the Context Hub. ## Publishing Events ```bash # Via CLI tenet context-hub emit "eval:scored" \ --data "agent=test-coverage,delta=0.0031,improved=true" # Via API curl -X POST http://localhost:4360/api/events \ -H "Authorization: Bearer $TOKEN" \ -d '{"type":"eval:scored","data":{"agent":"test-coverage","delta":0.0031}}' ``` ## Event Types | Pattern | When Fired | Used By | |---------|-----------|---------| | `eval:scored` | After agent eval completes | Auto-merge flow, training capture | | `kanban:pickup` | PP picks up a backlog issue | Training data capture | | `session:ended` | Session closes | Tuple mining flow | | `peter:daily-complete` | Nightly loop finishes | Summary reporting | | `telemetry:insight` | Telemetry agent finds something | PP experiment trigger | | `scope:impact` | Cross-service change detected | Cascade fix flow | | `friction:detected` | User friction event | Auto-create issue | | `review:scored` | AI review completes | Block merge on blockers | | `subway:task` | Task from Subway mesh peer | Create GitHub issue | ## Subscribing (Flows) Flows subscribe to events via pattern matching in `.tenet/flows/self-driving.yaml`: ```yaml flows: - name: auto-merge-on-improvement trigger: pattern: "eval:scored" condition: 'data.improved == "true"' actions: - type: command command: "gh pr merge {{data.pr_number}} --merge" ``` ## Querying Events ```bash # Recent events curl "http://localhost:4360/api/events?limit=20" \ -H "Authorization: Bearer $TOKEN" # Filter by type curl "http://localhost:4360/api/events?pattern=eval:*&limit=10" \ -H "Authorization: Bearer $TOKEN" ``` ## Event-Driven Architecture Events enable the self-driving pipeline without tight coupling: ``` Agent finishes eval → emits eval:scored → auto-merge flow catches it → merges PR if improved → emits kanban:done → training capture flow logs tuple ``` No component knows about the others. They communicate through events. ## Service Discovery URL: https://docs.10et.ai/hub/services TENET projects can manage multiple service repos from a central GTM workspace. Each service registers with the GTM and shares context through produces/consumes scopes. ## Registering a Service ```bash # From the GTM workspace tenet onboard /path/to/my-service --name my-service --type api ``` This creates: - `.tenet/config.json` in the service (with `gtm_parent` pointer) - `CLAUDE.md` and `AGENTS.md` in the service - Entry in GTM's `registered_services` list ## Service Config Each service has a `.tenet/config.json`: ```json { "name": "my-api", "type": "api", "working_branch": "main", "gtm_parent": "/Users/you/CascadeProjects/my-gtm", "context_scope": { "produces": ["api:endpoint-changed", "api:schema-updated"], "consumes": ["cli:command-change", "eval:*"] } } ``` ## Context Scopes Services declare what events they produce and consume: ```json { "context_scope": { "produces": ["docs:page-updated"], "consumes": ["cli:command-change", "cli:api-change"] } } ``` When `cli:command-change` fires in tenet-cli, the docs service knows it might need updating. ## Cross-Service Flows The GTM workspace has flows that detect cross-service impact: ```yaml # .tenet/flows/cross-service.yaml - name: detect-cross-service-impact trigger: pattern: "eval:scored" condition: 'data.improved == "true"' actions: - type: command command: "tenet scope impact --service {{data.service}}" ``` ## Managing Services ```bash # List registered services tenet services list # Check service health tenet services health # Sync service journals to GTM tenet services sync my-service ``` ## Registered Services Example ```json { "registered_services": [ { "name": "tenet-cli", "path": "/Users/you/CascadeProjects/tenet-cli", "type": "cli", "status": "active", "context_scope": { "produces": ["cli:command-executed", "cli:hook-fired"], "consumes": ["platform:api-response", "telemetry:insight"] } }, { "name": "tenet-docs", "path": "/Users/you/CascadeProjects/tenet-docs", "type": "docs", "status": "active", "context_scope": { "produces": ["docs:page-updated"], "consumes": ["cli:command-change", "cli:api-change"] } } ] } ``` --- # Integrations ## Pi Integration URL: https://docs.10et.ai/integrations/pi [Pi](https://github.com/badlogic/pi-mono) is a minimal terminal coding agent that TENET extends with tools, memory, journal, eval, and the startup briefing. ## How It Works TENET ships as a Pi package (`@10et-ai/pi`). When Pi starts in a TENET project, the extension: 1. **Replaces the header** with branded TENET identity (project name, branch, system indicators) 2. **Runs the SATOR boot animation** with live system probes 3. **Registers 21+ tools** (tenet_context, tenet_memory_search, tenet_eval_status, etc.) 4. **Fires the startup briefing** — steers the model to produce a concise project briefing 5. **Journals every significant action** automatically ## Tools Available in Pi | Tool | What it does | |------|-------------| | `tenet_context` | Get project context (journals, knowledge, code headers) | | `tenet_memory_search` | Search across all indexed memories | | `tenet_memory_add` | Add a memory manually | | `tenet_memory_status` | Check memory system health | | `tenet_hud` | Project dashboard | | `tenet_synopsis` | Work summary across sessions | | `tenet_pivot` | Checkpoint current work | | `tenet_eval_status` | Current eval scores and trends | | `tenet_policy_score` | Score a candidate action via policy head | | `tenet_crm` | CRM pipeline queries | | `tenet_service` | Query registered services | ## Session Lifecycle ``` Pi starts → TENET header renders → SATOR boot animation + system probes → Startup briefing steer fires (triggerTurn: true) → Model produces concise greeting → User works (tools available, journal auto-captures) → /end → session branch merged to main → synopsis shown ``` ## Configuration In `.tenet/config.json`: ```json { "pi": { "provider": "anthropic", "model": "claude-opus-4-6" } } ``` ## OpenClaw URL: https://docs.10et.ai/integrations/openclaw [OpenClaw](https://github.com/openclaw/openclaw) provides conversational agent interfaces. TENET integrates with OpenClaw for: - **Telegram bot** (Cash) — Conversational interface to your project - **Nightly cron** — OpenClaw's cron system triggers `tenet peter daily` - **Subway mesh** — OpenClaw agents communicate via the P2P relay ## Setup Install OpenClaw and configure channels in `~/.openclaw/openclaw.json`. The nightly loop cron job runs TENET's autonomous improvement cycle. ## Nightly Cron ```json { "name": "nightly-loop", "schedule": { "kind": "cron", "expr": "0 2 * * *" }, "payload": { "kind": "agentTurn", "message": "cd ~/project && tenet peter daily >> .tenet/nightly.log 2>&1" } } ``` ## Subway Mesh URL: https://docs.10et.ai/integrations/subway-mesh Subway is a P2P mesh network for agent-to-agent communication. Agents register as `name.relay` and can send messages, make RPC calls, and broadcast to topics. ## How It Works ``` Agent A (cash.relay) ←→ Subway Relay (wss://subway-relay.fly.dev/ws) ←→ Agent B (switch.relay) ``` ## Operations | Operation | Description | |-----------|-------------| | `subway_send` | Fire-and-forget message to a peer | | `subway_call` | RPC call with response (30s timeout) | | `subway_broadcast` | Publish to all topic subscribers | | `subway_subscribe` | Listen for broadcasts on a topic | | `subway_resolve` | Check if a peer is online | ## Use Cases - Agent teams coordinating on tasks - Broadcasting optimization discoveries - Cross-machine agent communication - Real-time status updates between Pi sessions ## Linear URL: https://docs.10et.ai/integrations/linear TENET integrates with Linear for bi-directional issue tracking. Issues created in Linear sync to GitHub as `tenet/backlog` issues, which PP picks up autonomously. ## Setup ```json // .tenet/config.json { "linear": { "apiKey": "lin_api_...", "teamId": "...", "projectId": "...", "syncEnabled": true } } ``` ## Flow ``` Linear issue created → Webhook syncs to GitHub issue (tenet/backlog label) → PP picks up every 30 min → Agent creates PR → Eval passes → auto-merge → issue closed → Linear issue updated via API ``` ## GitHub URL: https://docs.10et.ai/integrations/github TENET uses GitHub for the autonomous improvement pipeline — issues as a kanban board, PRs for agent changes, and CI for eval runs. ## Kanban Labels | Label | Column | Meaning | |-------|--------|---------| | `tenet/backlog` | Backlog | Available for PP pickup | | `tenet/in-progress` | In Progress | PP is working on it | | `tenet/eval` | Eval | PR created, waiting for eval | | `tenet/done` | Done | Merged and closed | ## Kanban Automation `.github/workflows/kanban.yml` automatically moves issues: - PR opened → linked issue moves to `tenet/eval` - PR merged → linked issue moves to `tenet/done` - Branch created matching `issue/**` → issue moves to `tenet/in-progress` ## Auto-Merge When an agent's eval improves, the self-driving flow auto-merges the PR: ```yaml - name: auto-merge-on-improvement trigger: pattern: "eval:scored" condition: 'data.improved == "true"' actions: - type: command command: "gh pr merge {{data.pr_number}} --merge --delete-branch" ``` ## CI Eval Add eval to your CI pipeline: ```yaml # .github/workflows/tenet-eval.yml - name: Run TENET eval run: | npm i -g @10et/cli tenet eval run --agent ${{ github.event.pull_request.head.ref }} ``` --- # Guides ## Zero to Intelligence URL: https://docs.10et.ai/guides/zero-to-intelligence # Zero to Intelligence Get TENET running on your project in under 2 minutes. By tomorrow morning, your codebase will have improved itself. ## Install ```bash npm install -g @10et/cli ``` ## Initialize ```bash cd your-project tenet init ``` This creates: - `.tenet/config.json` — project configuration - `.tenet/journal/` — session journals - `.mcp.json` — MCP server config for your agent - `CLAUDE.md` — agent instructions - `knowledge/` — living documents (VISION, THESIS, ARCHITECTURE) ## Setup agents ```bash tenet setup ``` TENET scans your codebase and auto-creates agents with gradient: ``` Detected: TypeScript, 1,414 tests, jest Created agent: test-coverage (baseline: 12.8%) Created agent: code-quality (baseline: 0.485) ✓ 2 agents with gradient — ready to improve ``` Each agent gets a TOML config and an eval script that measures a real metric. ## Run your first loop ```bash tenet peter agent test-coverage --rounds 3 ``` Watch it work: ``` Round 1 Baseline: 12.8% Agent: added 48 test cases for config loader After: 13.1% (+0.3%) KEPT ✓ Round 2 Baseline: 13.1% Agent: added tests but broke type checking After: 12.9% (-0.2%) REVERTED ✗ Round 3 Baseline: 13.1% Agent: added edge case tests for API client After: 13.5% (+0.4%) KEPT ✓ PR #1 created automatically. ``` ## Set up the nightly loop ```bash tenet peter daily ``` Or add to cron: ```bash # Run every night at 2 AM 0 2 * * * cd /path/to/project && tenet peter daily >> .tenet/logs/nightly.log 2>&1 ``` ## Check results tomorrow ```bash tenet status ``` ``` Coverage: 12.8% → 13.5% overnight Code quality: 0.485 → 0.51 +3 issues fixed Tests: 1,414 → 1,493 +79 new 2 PRs merged while you were asleep. ``` ## What happens over time | Week | What changes | |------|-------------| | **1** | Journals accumulate. Memory indexes patterns. | | **2** | Agents remember past decisions. "It recalled that architecture choice from last week." | | **Month 1** | Policy head trained. Agents try smarter experiments. | | **Month 3** | World model understands your project. New team members inherit full context. | ## Flows URL: https://docs.10et.ai/guides/flows # Flows Flows are YAML-defined automations that react to events. When something happens in your project, flows trigger actions automatically. ## Where they live ``` .tenet/flows/ ├── self-driving.yaml # autonomous improvement loop ├── cross-service.yaml # multi-repo cascade └── scripts/ # bash scripts for complex actions ``` ## Structure ```yaml flows: - name: auto-merge-on-improvement description: "Auto-merge PRs when eval score improves" enabled: true trigger: pattern: "eval:scored" condition: 'data.improved == "true"' gate: requires_approval: false cooldown_hours: 4 actions: - type: log message: "Eval passed: {{data.agent}} delta={{data.delta}}" - type: command command: "gh pr merge {{data.pr_number}} --auto" - type: journal entry_type: milestone title: "Auto-merged PR #{{data.pr_number}}" ``` ## Triggers | Pattern | When it fires | |---------|--------------| | `eval:scored` | After any eval completes | | `scope:impact` | Cross-service impact detected | | `session:ended` | Agent or human session ends | | `cron:nightly` | Nightly schedule | | `cron:every-30-minutes` | Every 30 min | | `custom:*` | Your own events via `tenet events publish` | ## Gates Control when flows actually execute: ```yaml gate: requires_approval: true # human must approve cooldown_hours: 4 # don't re-trigger within 4h max_iterations: 1 # only run once per trigger ``` ## Actions | Type | What it does | |------|-------------| | `command` | Run a shell command | | `journal` | Write a journal entry | | `log` | Log a message | | `spawn` | Spawn an agent in a worktree | ## The Self-Driving Loop The default `self-driving.yaml` closes the autonomous improvement loop: ``` Issue filed (tenet/backlog label) → PP picks up issue → Agent creates PR in worktree → Eval runs on PR → Score improves → auto-merge → close issue → tenet/done → Score regresses → revert → log → try different approach tomorrow ``` ## Commands ```bash tenet flows list # see all flows and their status tenet flows enable <name> # activate a flow tenet flows disable <name> # deactivate tenet flows run <name> # trigger manually tenet events recent # see recent events tenet events publish custom:my-event # emit your own ``` ## Cross-Service Cascade When services declare `produces` and `consumes` scopes, flows detect impact: ```yaml - name: cascade-cross-service trigger: pattern: "scope:impact" actions: - type: spawn target: worktree command: tenet peter agent {{data.affected_agent}} -r 3 ``` API changes automatically trigger evals in downstream consumers. ## IDE Workspace URL: https://docs.10et.ai/guides/ide # IDE Workspace TENET IDE creates tmux-based workspaces with auto-detected surfaces for your project. ## Launch ```bash tenet ide # auto-detect and launch ``` Creates a layout based on your project: | Row | Pane | Size | |-----|------|------| | Top (70%) | Agent Session (Claude/Pi) | 50% | | Top (70%) | Browser (Carbonyl) | 50% | | Bottom (30%) | Shell | 100% | ## Surfaces Add or remove surfaces dynamically: ```bash tenet ide add browser # terminal browser with agent eyes tenet ide add eval # eval scores and trends tenet ide add agents # agent overview dashboard tenet ide add events # context hub event stream tenet ide add training # training buffer status tenet ide add topology # service dependency graph tenet ide available # list all surface types ``` ## Multi-Level Navigation Navigate between projects in a portfolio: ```bash tenet ide open api # open child service in workspace tenet ide up # navigate to parent GTM ``` ## Custom Layouts Define layouts in `.tenet/ide.yml`: ```yaml rows: - size: 70% panes: - title: "agent" type: claude - title: "browser" type: browser - size: 30% panes: - title: "shell" type: shell - title: "events" type: events ``` ## Commands ```bash tenet ide # launch tenet ide status # show current layout tenet ide add <surface> # add a surface tenet ide remove <surface> # remove a surface tenet ide stop # stop workspace tenet ide restart # restart tenet ide reset # reset to default tenet ide config # view/set config ``` ## Browser (Agent Eyes) URL: https://docs.10et.ai/guides/browser # Browser — Agent Eyes A terminal browser powered by Carbonyl that gives agents direct DOM access while rendering visually for humans. No screenshots needed. ## Why this exists | Tool | Agent sees | Human sees | Bidirectional? | |------|-----------|-----------|----------------| | Cursor | Screenshots | Nothing | ❌ | | Claude Code | Screenshots | Nothing | ❌ | | **TENET Browser** | **Live DOM** | **Terminal rendering** | **✅** | ## Start In a separate terminal: ```bash ./tools/browser/tenet-browser.sh https://10et.ai ``` The human sees the page rendered in their terminal. The agent gets structured DOM via CDP. ## Agent commands (via Subway) ```bash # Navigate subway_call("browser.relay", "navigate", '{"url":"https://example.com"}') # Read page structure (headings, forms, links, tables, errors) subway_call("browser.relay", "read", '{}') # Click an element subway_call("browser.relay", "click", '{"selector":"#deploy-btn"}') # Type into a field subway_call("browser.relay", "type", '{"selector":"#search", "text":"error logs"}') # Scroll subway_call("browser.relay", "scroll", '{"direction":"down"}') # Wait for element to appear subway_call("browser.relay", "wait", '{"selector":".results", "timeout":5000}') ``` ## What agents get back Not screenshots. Structured DOM: ```json { "url": "https://app.example.com/dashboard", "title": "Dashboard", "dom_summary": { "headings": ["Dashboard", "System Health"], "forms": [{"id": "search", "fields": ["query"]}], "links": [{"text": "Settings", "href": "/settings"}], "tables": [{"id": "health-table", "rows": 5}], "interactive": [{"type": "button", "text": "Deploy"}], "errors": [], "text_content": "3 services healthy, 1 degraded." } } ``` ## Human → Agent flow When you click or type in the browser, events broadcast on the Subway mesh: ```json { "type": "human_click", "element": { "tag": "div", "class": "error-banner", "text": "API timeout on /api/v2/health", "selector": "#dashboard > .error-banner" } } ``` Your agent receives this and can respond: *"I see you're looking at the monitoring page — the 502s started 20 minutes ago..."* ## Authentication No special auth system. The human is literally using the browser: 1. Agent navigates to login page 2. Human sees the form, types credentials in terminal 3. Agent detects auth state change 4. Agent proceeds with authenticated session ## HTTP fallback If Subway isn't running, use the local API: ```bash curl -X POST http://127.0.0.1:9223/navigate -d '{"url":"https://example.com"}' curl -X POST http://127.0.0.1:9223/read curl -X POST http://127.0.0.1:9223/click -d '{"selector":"button.submit"}' ``` --- # CLI Reference ## tenet init URL: https://docs.10et.ai/cli/init Create a new TENET project with context hub, eval system, agents, and knowledge docs. ## Usage ```bash cd your-project tenet init ``` ## What It Creates ``` your-project/ ├── .tenet/ │ ├── config.json # Project configuration │ ├── journal/main.jsonl # Initial journal entries │ └── agents/ # Default agent configs ├── eval/ # Eval scripts ├── knowledge/ # VISION, THESIS, NARRATIVE ├── CLAUDE.md # Agent instructions └── AGENTS.md # Pi agent instructions ``` ## Options ```bash tenet init # Interactive wizard tenet init --name my-project # Skip name prompt tenet init --type gtm # GTM workspace tenet init --type service # Service repo ``` ## Onboarding a Service To onboard an existing service repo into a GTM workspace: ```bash # From the GTM workspace tenet onboard /path/to/service --name my-service --type api ``` ## tenet status URL: https://docs.10et.ai/cli/status Display current project health, session info, and system status. ## Usage ```bash tenet status ``` ## Output ``` TENET Status Project: my-project Branch: main Hub: ✓ (port 4360) Memory: 349 entries (349 embedded) Journal: 65 sessions, 331 entries Agents: 5 configured Training: 2764 tuples Recent (24h): [feature] Memory system overhaul [fix] Agent eval root cause [decision] Archive 6 dead agents ``` ## tenet peter URL: https://docs.10et.ai/cli/peter Peter Parker is the agent orchestrator. It manages the nightly improvement loop, runs individual agents, creates PRs, and handles strategic reasoning. ## Commands ### Daily Loop ```bash tenet peter daily ``` Full nightly orchestration: mine tuples → synthesize context → strategic reasoning → run agents → pick up issues. Typically run via cron at 2 AM. ### Agent Management ```bash # List all configured agents tenet peter agent list # Run a specific agent tenet peter agent <name> --rounds <N> # Run all agents (swarm mode) tenet peter agent swarm --rounds <N> # Create a new agent interactively tenet peter agent create ``` ### PR Mode ```bash # Create a branch, make changes, open a PR tenet peter pr --task "Fix the auth token refresh bug" ``` ### Other Commands ```bash tenet peter status # Show status + recent events tenet peter dashboard # Live event stream tenet peter telemetry # Run telemetry agent tenet peter synthesize # Regenerate product context tenet peter sentinel # Run sentinel nightly review tenet peter metrics # Show current platform metrics ``` ## Options | Flag | Description | |------|-------------| | `--cost` | Cost-optimized model routing (haiku-heavy) | | `--balanced` | Balanced model routing (default) | | `--quality` | Quality-first model routing (opus-heavy) | | `--budget <amount>` | Cost budget in USD (auto-downgrades when exceeded) | | `--pi` | Force Pi runtime | | `--rounds <N>` | Number of rounds (for agent/autoresearch) | ## Examples ```bash # Run test-coverage for 10 rounds with cost optimization tenet peter agent test-coverage --rounds 10 --cost # Run the full nightly loop with $20 budget cap tenet peter daily --budget 20 # Create a PR to fix a specific issue tenet peter pr --task "GitHub #42: Fix login redirect loop" # Run all agents in quality mode tenet peter agent swarm --rounds 5 --quality ``` ## tenet organize URL: https://docs.10et.ai/cli/organize Audit knowledge docs for staleness, detect drift from journal evidence, and generate proposed updates for human review. ## Usage ```bash # Audit — show what's stale tenet organize # Generate PENDING.md with proposed updates tenet organize --fix # Apply reviewed changes from PENDING.md tenet organize --apply # Move archive candidates to knowledge/archive/ tenet organize --archive # Custom lookback period tenet organize --days 60 ``` ## How It Works 1. Scans `knowledge/*.md` for all active docs 2. Reads last N days of journal entries 3. Extracts topics from both docs and journals 4. Computes **drift score** per doc: - Age penalty (>7 days starts drifting) - Journal activity penalty (lots of activity + stale doc = drift) - Stale topic penalty (topics in doc not mentioned in journals) 5. Generates `knowledge/PENDING.md` with: - TLDR of what needs attention - Uncovered topics (journals mention, no doc covers) - Per-doc proposed updates with evidence - Open questions for human review ## Output ``` Knowledge Organizer Scanning 243 journal entries from last 30 days Doc Health ✓ VISION 0d old drift: 20% mentions: 221 ✓ THESIS 0d old drift: 20% mentions: 223 ✓ NARRATIVE 0d old drift: 20% mentions: 206 ✗ ROADMAP 14d old drift: 65% mentions: 89 1 of 4 docs need attention Generated: knowledge/PENDING.md Review it, answer questions, then run: tenet organize --apply ``` ## The PENDING.md Workflow PENDING.md acts as a PR for your knowledge base: ``` tenet organize → generates PENDING.md ↓ You review PENDING.md → answer questions, mark keep/update/archive ↓ tenet organize --apply → applies changes, clears PENDING.md ``` ### Example PENDING.md ```markdown # Knowledge Update — PENDING > Review this file, answer questions, then run `tenet organize --apply` ## TLDR 1 of 4 docs need attention: - ⚠️ **ROADMAP** — drifted (14d old, drift: 65%) ## Uncovered Topics Recent journal activity mentions these topics but no knowledge doc covers them: - **docker testing** — "Set up Docker-based onboarding eval" - **memory graph edges** — "Added graph edge functions to memory-db" ## Open Questions - [ ] VISION.md references old naming but recent journals use current naming. Update? - [ ] New RL learning loop — should this be in THESIS or a separate doc? **Action:** <!-- ANSWER: keep / update / archive --> ``` ## Options | Flag | Description | |------|-------------| | `--fix` | Generate PENDING.md (same as default) | | `--apply` | Apply reviewed changes, clear PENDING.md | | `--archive` | Move archive-candidate docs to `knowledge/archive/` | | `--days <N>` | Journal lookback period (default: 30) | ## tenet synopsis URL: https://docs.10et.ai/cli/synopsis Show a summary of recent work — journal entries, git commits, file changes, and time breakdown. ## Usage ```bash tenet synopsis # Last 24 hours tenet synopsis 48 # Last 48 hours tenet synopsis 24 goose # Filter by author ``` ## Output Shows: - Journal entries (features, fixes, decisions, discoveries) - Git commits across all branches - Files modified count - Code headers changed Used automatically at session end to show what was accomplished. ## tenet doctor URL: https://docs.10et.ai/cli/doctor Run diagnostics on your TENET project and optionally auto-fix issues. ## Usage ```bash tenet doctor # Check health tenet doctor --fix # Auto-repair issues tenet doctor --json # Machine-readable output ``` ## Checks | Check | What it verifies | |-------|-----------------| | `.tenet` directory | Exists with required files | | `config.json` | Valid JSON with required fields | | Context Hub | Running and responsive | | Memory database | Exists, has entries, embeddings available | | Journal | Has session files | | Agents | Valid TOML configs with eval scripts | | Git branch | On expected branch | | Hooks | HTTP hooks configured | ## tenet eval URL: https://docs.10et.ai/cli/eval Manage the eval system — run evals, view scores, mine training data. ## Commands ```bash # View current eval status tenet eval status # Compare two eval snapshots tenet eval compare # Mine training tuples from history tenet eval mine --all tenet eval mine --source journals tenet eval mine --source evals # View eval trajectory for an agent tenet eval trajectory --agent test-coverage ``` ## Eval Status Output ``` Eval Status (last 5) 2026-03-22 test-coverage 0.1307 +0.0031 ✓ 2026-03-22 test-coverage 0.1276 0.0000 · 2026-03-22 code-quality 0.6881 +0.0045 ✓ 2026-03-21 cli-speed 98ms -2ms ✓ ``` --- # API Reference ## Context API URL: https://docs.10et.ai/api/context ## POST /api/context Query project context — journals, knowledge docs, code headers. ```bash curl -X POST http://localhost:4360/api/context \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"query": "CLI startup", "maxItems": 10}' ``` ### Request Body | Field | Type | Description | |-------|------|-------------| | `query` | string | Optional search query | | `maxItems` | number | Maximum results (default: 30) | | `taskType` | string | Prioritization: code, spec, content, strategy, general | ### Response ```json { "items": [ { "source": "journal", "type": "feature", "title": "CLI startup optimization", "content": "Reduced p90 from 6.7s to 98ms...", "path": ".tenet/journal/main.jsonl" } ] } ``` ## Memory API URL: https://docs.10et.ai/api/memory ## POST /api/memory/search Search indexed memories with hybrid BM25 + semantic search. ```bash curl -X POST http://localhost:4360/api/memory/search \ -H "Authorization: Bearer $TOKEN" \ -d '{"query": "eval scripts", "limit": 5}' ``` ## POST /api/memory/add Add a memory manually. ```bash curl -X POST http://localhost:4360/api/memory/add \ -H "Authorization: Bearer $TOKEN" \ -d '{"title": "My insight", "content": "Details...", "type": "discovery"}' ``` ## GET /api/memory/status Memory system health and stats. ```bash curl http://localhost:4360/api/memory/status \ -H "Authorization: Bearer $TOKEN" ``` ## POST /api/memory/index Trigger reindex and embedding backfill. ```bash curl -X POST http://localhost:4360/api/memory/index \ -H "Authorization: Bearer $TOKEN" \ -d '{"backfill": true}' ``` ## POST /api/memory/link Add a graph edge between two memories. ```bash curl -X POST http://localhost:4360/api/memory/link \ -H "Authorization: Bearer $TOKEN" \ -d '{"from": 42, "to": 17, "type": "updates"}' ``` ### Link Types `updates` | `contradicts` | `related_to` | `caused_by` | `part_of` ## Events API URL: https://docs.10et.ai/api/events ## GET /api/events Query recent events. ```bash curl "http://localhost:4360/api/events?limit=20&pattern=eval:*" \ -H "Authorization: Bearer $TOKEN" ``` ### Query Parameters | Param | Description | |-------|-------------| | `limit` | Max events to return (default: 20) | | `pattern` | Filter by event type prefix (e.g., `eval:`, `kanban:`) | ## POST /api/events Publish an event. ```bash curl -X POST http://localhost:4360/api/events \ -H "Authorization: Bearer $TOKEN" \ -d '{"type": "custom:my-event", "data": {"key": "value"}}' ``` ## Eval API URL: https://docs.10et.ai/api/eval ## GET /api/eval/trajectory Get eval score history for an agent. ```bash curl "http://localhost:4360/api/eval/trajectory?agent=test-coverage&metric=composite" \ -H "Authorization: Bearer $TOKEN" ``` ### Query Parameters | Param | Description | |-------|-------------| | `agent` | Agent name (required) | | `metric` | Metric name (default: composite) | ### Response ```json { "agent": "test-coverage", "metric": "composite", "trajectory": [ {"ts": "2026-03-22T21:30:00Z", "value": 0.1276}, {"ts": "2026-03-22T21:35:00Z", "value": 0.1307}, {"ts": "2026-03-22T21:40:00Z", "value": 0.1342} ] } ```