A scalable Graph-of-Thoughts (GoT) agent service for web research using task decomposition and parallel reasoning to increase accuracy and reduce cost.
Euglena is an agent with web crawling and retrieval-augmented generation. Tasks decompose into parallel subproblems (search, visit, save, think) and merge into structured deliverables. Context persists in ChromaDB. Cost efficiency is maximized through dynamic beam-width and a token-efficient workflow that benefits cheaper models through structured reasoning.
Live: https://euglena.vercel.app/
Ops (2026-03): The Euglena product is winding down. Current production runs on the local backend (this host, via Docker Compose + Tailscale Funnel), not AWS — see Quick Start below. The ECS/ECR/CloudWatch deploy path remains in-repo and functional as a secondary/legacy option, not the documented default anymore.
Every request becomes a mandate, which is a free-form research question handed to a controller
(IdeaDagEngine) that owns a directed acyclic graph (DAG) of "thought" nodes and a ChromaDB
memory. It decomposes, acts, and merges until it has an answer:
flowchart TD
A[Mandate] --> B[Root Node]
B --> C{"Expand<br/>LLM proposes 2-5 candidates"}
C --> D1[search]
C --> D2[visit]
C --> D3[think]
C --> D4[save]
D1 --> E["Score + Select<br/>(best-first)"]
D2 --> E
D3 --> E
D4 --> E
E --> F[Execute leaf action]
F --> G{"Branch children<br/>all terminal?"}
G -- no --> C
G -- yes --> H["Merge upward<br/>(LLM synthesis)"]
H --> I{Root reached?}
I -- no --> C
I -- yes --> J[Final Synthesis LLM]
J --> K[Deliverable]
Everything expensive is an LLM call the graph disciplines: expand (plan candidates), evaluate (score them), merge (synthesize a branch), finalize (write the deliverable). Everything else — dependency edges, dedup, dynamic beam width, pruning, retries, checkpointing — is deterministic Python keeping those calls grounded. Full internals: Idea Engine Deep Dive.
- Euglena, the product: a hosted GoT web-research agent (frontend, gateway, quotas, auth), winding down and kept running on the local backend in low-maintenance mode.
- The research line, built on the same engine, now in its fourth generation: the
Euglena Ledger, an auditable evidence compiler for weak local models (see the section
below). It started with the compiled scaffold, the project's first big benchmark result,
then ported those lessons into the live DAG loop as opt-in adaptive mechanisms (DAG v2),
then narrowed to the Ledger on 2026-08-31. This is where development effort goes. The
current state of every claim, including what was retracted, is in
docs/STATE_OF_EVIDENCE_2026-09-07.md; the decided roadmap isdocs/handoffs/ROADMAP_2026-09-07.md. The Benchmark Results section documents the closed-out compiled-scaffold proof — not the product, and not the Ledger.
This repo's architecture comes in named generations, referenced throughout these docs and in the Timeline below:
| Name | Landed | What it is |
|---|---|---|
| DAG v1 | 2026-02 → 03 | The original Graph-of-Thought rewrite — live LLM calls at every expand/evaluate/merge step, with no offline-authored plan. |
| Compiled v1 | 2026-06 | An expensive model authors a full DAG plan once, offline; a cheap model executes that fixed plan on every request (see Benchmark Results below). |
| DAG v2 | 2026-07 → 08 | The native-DAG improvement series, built on DAG v1's base loop, porting Compiled v1's planning lessons back in as opt-in adaptive mechanisms (see Notes below). Closed by the Ledger pivot; its planned barrage relaunch was retired unrun. |
| v3 | parked | Was to move past one-shot mandates toward a continuable, chatbot-like interaction and fold in codebench. Not on any live line; kept as a future option only. |
| Euglena Ledger | 2026-08-31 → present | The live line. A scoped pivot out of DAG v2: an auditable, replayable evidence compiler that emits claims pinned to verbatim page spans, deterministic derivations with unit refusal, and an ANSWER/PARTIAL/ABSTAIN verdict derived in code. A component other agents call, not a general agentic framework. See docs/LEDGER.md. |
Why DAG v2 emphasized native over compiled (historical rationale): Compiled v1 authors a plan with one expensive LLM call and reuses it, using pre-computed structure as its mechanism. Compared to DAG v1/v2's native reasoning, compiled trades adaptability for a narrower, harder-to-validate gain — a fixed plan can't react to what a step actually reveals, and testing it well means testing every plan shape it can produce. Native DAG improvements generalize across more tasks, stay easier to test, and make the more interesting story to explain, in interviews and in these docs. DAG v2 treats a compiled layer as one adjustable option among several.
The library, not a hand-edited prompt: the concrete form that layer takes inside DAG v2 is a
small, general-purpose library of prompt and reasoning guidance
(agent/app/strategy_library/,
agent/app/plan_library/) — pitfalls to watch for, phrasing that
avoids known failure modes, the kind of thing that used to mean hand-editing a prompt every time a
benchmark run exposed a new weak spot. Formalizing that editing into a library lets it improve
over time and get reused across tasks instead of living only in one prompt's edit history. It
stays deliberately small: one general-purpose snippet applicable to many kinds of benchmark
question, not one written guide per question — strategy_library/'s promotion gate (held out on
≥2 tasks, ≥5% uplift) exists specifically to keep it that way.
The goal, restated: raise the reasoning and agentic performance of cheaper models on publicly available endpoints until they're competitive with more expensive models. There are many candidate mechanisms for this — structure, memory, voting, calibration, compiled or native planning, and more still being tried — and the constraint that keeps them honest is cost: whatever a mechanism costs to run must stay cheaper than just calling the more expensive model directly, or it hasn't earned its place.
Give the Ledger a question and a set of sources; it returns a ledger of atomic claims, each
pinned to a verbatim span on a fetched page, plus values derived from those claims by
deterministic arithmetic that refuses mismatched units, plus a verdict derived in code from what
was actually obtained. Every LLM call is addressable and every run replays at $0 from a frozen
corpus. Entry point: agent/app/ledger_api.py (run(question, sources) → LedgerResult);
CLI: scripts/ledger_run.py.
flowchart LR
Q[Question + sources] --> L["Evidence loop<br/>search · visit · derive · verify · finish"]
L --> R["Ledger rows<br/>value + verbatim quote + page offset"]
L --> G["Derivation graph<br/>SOURCE → DERIVED, unit-checked"]
R --> C["Certify chain<br/>(deterministic clauses)"]
G --> C
C --> V["ANSWER / PARTIAL / ABSTAIN<br/>+ per-claim recheck"]
Why the scope narrowed. Across 432 cells the native DAG and an off-the-shelf LangGraph agent were statistically indistinguishable on mean score, and closing that would need 61–111 paired tasks to win a contest whose prize is parity with a framework this project cannot out-resource. The defensible niche is what none of the general frameworks do: make a weak model's answer auditable, replayable, and honest about its own gaps. Mean score is a guard, never the target.
What it can claim today (qwen2.5:7b and smaller, seeded, frozen-corpus replay, $0):
| Claim | Evidence |
|---|---|
| Fabricated-arithmetic rate and replay fidelity went from unmeasurable to measured, on two hosts | host vs host+module 2×2 (docs/LEDGER_MODULE_EXPERIMENT.md) |
| The certify chain rejects wrong answers | mint02: 192 cells, 10.4% coverage at 6.7% risk vs a 63.5% base wrong-rate; mint01: 4/144 certified at 0% risk |
| Zero invalid derivations where arithmetic is checked | 195/197 derived nodes corpus-wide |
| Every campaign since 2026-09-01 is byte-reproducible | preregistered, seeded, corpus replay |
What it does not claim: any mean-score win (evidence_loop is −0.100 vs LangGraph at ~3× wall
clock and nothing clears Holm at n=22), monotone calibration as a standing fact, or any arm ranking
from ≤22 paired tasks. The full list, with retractions, is in
docs/STATE_OF_EVIDENCE_2026-09-07.md.
The open problem. The verifier is sound but starved: 120/144 cells mint zero derivations,
and weak models below 7b never call the derive tool. The next phase mints rows mechanically
from the per-page quantity index so auditability stops depending on the model choosing to be
audited. Roadmap: docs/handoffs/ROADMAP_2026-09-07.md.
The compiled scaffold thesis: instead of letting a cheap model improvise its own research plan step-by-step, let an expensive model author an execution plan (a DAG: which sub-facts to gather, in what order, what depends on what) once, offline. A cheap model executes that fixed plan live, on every request. The plan is the expensive part, paid for once and reused forever; the part that runs on every request is cheap.
flowchart LR
subgraph Offline["Offline — once, cached by mandate hash"]
X[Expensive model] -->|authors| P[DAG Plan]
end
subgraph Runtime["Runtime — every request"]
P --> W1["Cheap model<br/>executes leaf 1"]
P --> W2["Cheap model<br/>executes leaf 2"]
P --> W3["Cheap model<br/>executes leaf N"]
W1 --> AG[Aggregate]
W2 --> AG
W3 --> AG
AG --> ANS[Answer]
end
1,026 live runs (barrage24b, ≈$38 real OpenRouter spend) across 38 hand-designed discriminating
tasks x 3 models x 3 repeats, comparing the compiled scaffold (graph_compiled) against a native
graph-of-thoughts build-it-yourself baseline, a plain ReAct loop (sequential_react), and
tool-free baselines (naive_rag, parametric).
| Model | Strategy | Score | Cost/task |
|---|---|---|---|
| gpt-4.1-nano (cheapest) | compiled plan | 0.837 | $0.002 |
| gpt-5-mini (mid-tier) | compiled plan | 0.896 | $0.017 |
| gemini-3.1-pro (premium, the reference ceiling) | best baseline | 0.896 | $0.169 |
The mid-tier model, given the compiled plan, exactly matches the premium model's score at 10% of the cost. The cheapest model reaches 93% of premium quality at ~1/85th the cost. This holds up under real statistics, not just a favorable average: on the hardest task tier, the compiled scaffold beats the plain ReAct baseline with a 95% confidence-interval-disjoint significant margin (n=270 runs per arm).
The compiled scaffold spends its LLM calls filling in a fixed plan's leaves, not re-deciding what to do next at every step — which is why it's both cheaper AND more consistent than a from-scratch ReAct loop on the harder tasks.
Full package (9 charts, raw + aggregated CSVs, significance tables, honest caveats) lives in
linkedin_package_38tests_2026-07-08/.
Compiled v1 above proved what a good plan buys you: it authors that plan once, offline, using an expensive model, and executes it live with a cheap one. DAG v2 ports those lessons into the native, non-compiled engine so it reasons adaptively mid-run: plan → act → observe the step → decide the next move (re-expand, backtrack, or stop) — reacting to what a step actually reveals, which a fixed offline plan can't do. (Compiled v1 is available inside DAG v2 as an optional, small-scope layer — see Versioning above.)
flowchart LR
P["Plan / Expand"] --> Ac["Act: execute leaf"]
Ac --> Ob["Observe:<br/>confidence judge + follow-up detector"]
Ob -->|"low confidence, or<br/>new lead found"| Re["Re-expand or Backtrack"]
Re --> P
Ob -->|"confident & satisfied"| Mg["Merge / Finalize"]
Every mechanism ships opt-in and default-off, byte-identical to prior behavior when disabled:
confidence-gated re-expansion, a follow-up detector, backtrack on dead-end chains, reasoning-effort
discipline for reasoning models, and price-tier-aware token budgets. Architecture, flag inventory,
and lessons learned: agent/app/ADAPTIVE_ENGINE.md.
Status: closed. The planned paid barrage relaunch (baseline → good_adaptive → max_burn
on gpt-5-mini) was retired unrun when the project pivoted to the Ledger. What DAG v2 did
establish, on local models: fan-out width is parity-tied with sequential execution, but the graph
loses −0.461 (t=−7.73, n=23) on aggregation-shaped tasks with a named code-level cause
(root-ward-only branch context, lossy merge, no extraction step;
docs/AGGREGATION_SHAPE_FINDING_2026-08-30.md). The engine survives inside the Ledger in a
narrower role, as a dependency analyzer rather than a plan executor. Full mechanism inventory
and lessons: agent/app/ADAPTIVE_ENGINE.md.
- Graph-of-Thought reasoning: Tasks decompose into parallel subproblems (search, visit, think, save), then merge results upward through the DAG into structured deliverables
- Dual execution modes:
graph(parallel branching with best-first selection) andsequential(generate then pick, single path depth first) for A/B comparison - Bot-resistant web access: Primary
aiohttpconnector with automaticundetected-chromedriverfallback on 403/401 - Long-term memory (RAG): Crawled content is chunked and embedded into ChromaDB, queryable across tasks and reasoning steps
- Dynamic beam width: Branching factor adapts to score quality. Expands exploration when scores are low, narrows when confident
- Deduplication and pruning: Candidate thoughts are deduplicated by embedding similarity. Low-scoring nodes are pruned to save budget
- Elastic worker fleet: ECS autoscaling matches demand via CloudWatch queue-depth metrics, winds down when idle (legacy/secondary deploy path — see Quick Start; current production scales via
docker compose ... --scale agent=Non the local backend) - User-scoped quotas: Supabase enforces per-user daily usage limits with JWT authentication
- Comprehensive test suite: 208 priority-ordered task modules (
agent/app/idea_tests/) with programmatic validation, plus a 9,388-passed/19-skipped/0-failed offlinepytestsuite (agent/tests/); 38 of the tasks are the curated, live-verified discriminators used in the compiled-scaffold benchmark above, 24 ("adaptive-targeted",test_122–test_145) discriminate the adaptive engine, and 22 (test_210–test_231) form the Ledger's numeric suite (sum/difference, ratio, argmax, unit-refusal, missing-operand, fabrication-bait)
Structured telemetry at every layer without cluttering business logic.
| Layer | What Is Tracked | Where |
|---|---|---|
| Connectors | Every HTTP request, LLM call, search query, browser fetch. Timing, status, payload size | ConnectorBase._record_timing, _record_io |
| AgentIO | Unified interface telemetry. Visit/search/store/retrieve with fallback tracking | AgentIO methods |
| Engine | Step-by-step DAG traversal. Expansion, evaluation, selection, merge, pruning events | IdeaDagEngine logger |
| GoT Operations | Embedding, deduplication hits, dynamic beam decisions, prune events | GoTOperations |
| Memory | Chunk storage, retrieval counts, namespace isolation | MemoryManager |
| Test Runner | Per-test scores, pass/fail, cost, tokens, duration, graph structure metrics | idea_test_runner.py |
| Visualization | 4-page core dashboard, heatmaps, efficiency frontiers, difficulty rankings | testing/visualization_* |
Connector base classes handle I/O logging so action classes stay focused on logic (see OOP conventions).
idea_test_runner > JSON results > visualization_summary > terminal report
> visualization_core > 4-page PNG dashboard
> visualization_plots > detailed plot gallery
Results are written to agent/idea_test_results/ as timestamped JSON (gitignored, not a repo-root directory). The visualizer can filter by run ID (--latest, --run-id) and generates executive dashboards, heatmaps, efficiency frontiers, and per-test breakdowns.
Regenerating Visualizations:
# From services/ directory, run visualization in Docker
docker compose run --rm agent python -m app.testing.idea_test_visualize --latest --core-only
# Or generate all plots (including detailed gallery)
docker compose run --rm agent python -m app.testing.idea_test_visualize --latest
# List available test runs
docker compose run --rm agent python -m app.testing.idea_test_visualize --list-runs
# Generate and copy benchmark plots to docs/benchmark/ (from project root)
python scripts/generate_benchmark_plots.pyVisualization Improvements:
- Executive Summary: Score heatmap (test × system) replaces model leaderboard table for better visual insight
- Efficiency Dashboard: Violin plots with all datapoints replace cramped tables, showing full score distributions
- Larger fonts: All text increased for better readability (titles 32-48pt, labels 18-22pt)
- All datapoints visible: Individual test runs shown as scatter points overlaid on distributions
- Clear trends: Graph vs Sequential advantage highlighted with annotations and visual comparisons
The docker-based pipeline above works on any test run. The compiled-scaffold campaign (the Benchmark Results above) has its own dedicated, $0-to-regenerate gallery pipeline, run locally against the on-disk result JSONs — no docker, no live model calls:
PYTHONPATH=.:services:agent python3 scripts/render_gallery.pyReads every barrage24b_*.json under agent/idea_test_results/, writes 9 square 4K
(3840×3840) PNGs plus raw/aggregated CSVs to agent/idea_test_results/barrage24b_gallery/
(scripts/bench_common.py is the shared, run-id-scoped data loader; agent/app/testing/plot_style.py
is the shared Magma-family house style — titles/labels/marks are sized to stay readable when the
4K image is viewed small, e.g. embedded in a doc or a slide). The curated, packaged copy for
external sharing is linkedin_package_38tests_2026-07-08/.
Visualizations are automatically generated after test runs and saved to agent/idea_test_results/plots_<run_id>/.
| Layer | Technology |
|---|---|
| Frontend | React, Vite, Supabase Auth |
| Backend | FastAPI, RabbitMQ, Redis, ChromaDB, Supabase |
| Agent | Graph-of-Thought engine, OpenAI LLMs, web search (Serper/Brave), undetected-chromedriver |
| Infra | Local Docker Compose on-host (current production path, via Tailscale Funnel); AWS ECS, ECR, CloudWatch, Lambda autoscaling remain available as a secondary/legacy path |
This is the path production actually runs today. Same Supabase keys. Run the stack without nginx:
cd services
cp keys.env.example keys.env
docker compose -f docker-compose.yml -f docker-compose.local.yml up -d --build --scale agent=3Or: python scripts/deploy_local_stack.py up from the repo root.
Run tailscale funnel --bg --yes 18080, set VITE_GATEWAY_URL on Vercel to the printed HTTPS URL, redeploy.
Optional static UI on this host (nginx on port 80):
python scripts/deploy_local_stack.py build-frontend
python scripts/deploy_local_stack.py up-spaStart on boot (systemd): from services/ run ./install-webrag-service.sh once (sets WorkingDirectory and enables webrag.service). Build images before first boot: docker compose -f docker-compose.yml -f docker-compose.local.yml build.
The original production path. Deploy scripts (scripts/deploy.py, deploy_ecs.py,
deploy_autoscale.py, etc.) remain in-repo and functional, but ECS is no longer the documented
default — use it only if you specifically need managed autoscaling infra. If VITE_GATEWAY_URL
is unset, the app uses the default hosted API URL in frontend/src/api/config.ts.
cd services
cp keys.env.example keys.env
docker compose up -d- Frontend (Vite):
http://localhost:5173 - Gateway:
http://localhost:8080 - RabbitMQ UI:
http://localhost:15672(guest/guest) - ChromaDB:
http://localhost:8001
With the stack up, submit a mandate and poll for the result. Auth is a Supabase JWT in the
Authorization header — obtain one by signing in through the frontend (or your Supabase
project) and use it as $TOKEN. (GATEWAY_TEST_MODE=true in keys.env relaxes the daily
quota check for local dev.)
# 1. Submit a task -> returns a correlation_id and status "in_queue"
curl -s -X POST http://localhost:8080/tasks \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"mandate": "Who wrote the novel Beloved, and where did she earn her master'\''s degree?"}'
# 2. Poll until status is "completed".
# result.deliverables[0] is the answer; result.evidence carries the pages actually
# visited (sources), the grounding verdict, and the token/cost usage.
curl -s http://localhost:8080/tasks/<correlation_id> -H "Authorization: Bearer $TOKEN"Interactive, auto-generated API docs: http://localhost:8080/docs. A runnable end-to-end
client (submit + poll loop, prints the answer + evidence) is in
examples/quickstart.py.
Everything below runs from services/. No host virtualenv is required.
# Offline unit/regression suite (~9.4k tests, no API keys, no network, no spend)
docker compose --profile test run --rm agent-test
# ...or one module
docker compose --profile test run --rm agent-test pytest -q agent/tests/got_operations_test.py
# Live task runs against the benchmark suite (these DO use keys.env and spend money)
IDEA_TEST_IDS=019,025 docker compose --profile test run --rm visit-test
docker compose --profile test run --rm idea-test
IDEA_TEST_MODE=benchmark docker compose --profile test run --rm idea-testThe equivalent host invocation, for a checkout with a .venv, is
PYTHONPATH=.:services:agent ./.venv/bin/python -m pytest -q agent/tests. The container run
differs in one respect: consol publishes no wheel for the image's Python 3.10, so five
optional-dependency tests skip there.
# Compute-ladder A/B against the LOCAL Ollama models ($0). No arguments = dry-run cell plan.
docker compose --profile ladder-benchmark run --rm ladder-benchmark
docker compose --profile ladder-benchmark run --rm ladder-benchmark \
--run-id ladder_local --axis capspec_local --task-set smoke8 \
--arms baseline,good_adaptive --jobs 1
# Prompt-shape / calibration micro-eval (also local, also $0)
docker compose --profile promptbench run --rm promptbench --census
docker compose --profile promptbench run --rm promptbench-analyze \
--runs agent/idea_test_results/promptbench_runs.jsonlBoth benchmark services write results to agent/idea_test_results/ on the host. Set
LADDER_UID/LADDER_GID (or PROMPTBENCH_UID/PROMPTBENCH_GID) if your host account is not
uid 1000, so the result files stay writable by a later host-side run.
The full registry (required / optional / benchmark-only) is in
docs/CONFIGURATION.md; run python scripts/list_env_vars.py for the
authoritative, always-current list scanned from the code.
Key environment variables for testing:
IDEA_TEST_IDS: Comma-separated test IDs (e.g., "019,025,033")IDEA_TEST_MODE: "default" or "benchmark"IDEA_TEST_RUNS: Number of runs per test/model pairIDEA_TEST_CONCURRENCY: Max parallel executionsIDEA_TEST_MODELS: Comma-separated models (e.g., "gpt-5.2,gpt-5-mini")IDEA_TEST_EXECUTION_VARIANTS: "graph", "sequential", or both
services/
agent/ Agent service (GoT engine, connectors, tests)
gateway/ FastAPI gateway, task intake, Supabase sync
shared/ Connector configs, models, storage helpers
metrics/ CloudWatch queue-depth publisher
lambda_autoscaling/ ECS autoscaler
frontend/ React web UI
scripts/ Deployment, diagnostics, audits
docs/ Architecture, security, benchmark plots
- State of Evidence - What is claimed, what is not, the retraction ledger, the roadmap. Start here.
- Euglena Ledger - The current line: product shape, design commitments, KPIs, what months of experiments ruled out
- Ledger KPI spec - Frozen metric contract (risk-coverage, claim edges, fabricated arithmetic, replay fidelity)
- Dev cycle - The repeatable plan → review → test → benchmark → implement → analyze loop
- Configuration - Environment variable registry (required / optional / benchmark-only)
- System Architecture - Overall system design and message flow
- Agent Architecture - Graph-of-Thought engine internals
- Idea Engine Deep Dive - File-and-line-cited walkthrough of the DAG controller, policies, and mechanics
- Adaptive Engine - The interleaved plan-act-observe-decide loop, flag inventory, and lessons learned
- Research Library - Mechanism-by-mechanism map of what external research each part of the agent matches or diverges from
- Test Suite - Test structure and validation
- Deployment - Deployment guide
- Debugger - Debugging tools and techniques
- Scripts - Deployment and diagnostic scripts
- 2025-10 → 2026-01: Started as a single-shot LLM
Connector+ CLI; grew a FastAPI gateway, then reached MVP. - 2026-02 → 2026-03 — DAG v1: Rewritten around a Graph-of-Thought DAG engine — decompose into subproblems, execute
search/visit/think/saveleaves, merge upward (see How It Works above). Native throughout: no offline-authored plan, every expand/evaluate/merge step is a live LLM call. AWS ECS wound down in favor of the local backend (Ops note near the top). - 2026-05: Default LLM provider migrated to OpenRouter (note near the top).
- 2026-06 — Compiled v1: an expensive model authors a DAG plan once, offline; a cheap model executes it live, recovering premium-model accuracy at a fraction of cost (see Benchmark Results above). Alongside it: a duplicate
shared/module tree and a stale forked engine copy were deleted, and the 1,600+-line engine controller was broken into focused modules. - 2026-07 → present — DAG v2: Compiled v1's lessons (structured planning, reasoning-effort discipline) ported into the live, non-compiled DAG loop as opt-in, default-off mechanisms: confidence-gated re-expansion, backtrack, price-tier token budgets (see Notes above and
ADAPTIVE_ENGINE.md). Currently mid-relaunch of a live cost/accuracy A/B (the "ladder benchmark") testing whether the adaptive loop closes the gap between cheap and premium models. Plan for finishing this generation: a hugely expanded, harder benchmark set than DAG v1's, repeating some of DAG v1's own tasks to measure improvement directly, dropping the sequential-mode comparison arm, and adding a new arm that compares the same model run through an off-the-shelf, publicly available agent system in current use. Codebench and additional tool/capability work are deliberately deferred to v3. - 2026-08: Repo restructure + a repeatable dev-cycle methodology.
services/agent/moved to a top-levelagent/, legacy AWS deploy code archived underservices/_legacy-aws/, andbadmodel-lab/codebench/(the Docker coding-benchmark harness) folded into a top-levelcodebench/— both cross-cutting moves fixed real silent-failure bugs (bash root-anchor depth-counting, a Python default path that returned[]instead of erroring). Work now happens directly onmaster(the long-livedcompiled-scaffold-dagbranch was fast-forward-merged in and retired) under a repeatable Plan → Adversarial review → Test → Benchmark → Implement → Run → Analyze loop (docs/DEV_CYCLE.md, invoked via the/cycleskill) that replaced one-off per-session handoff docs. Two live cycles have run; a third pass root-caused and fixed two independent silent self-loop deadlocks in the adaptive engine's re-expansion/merge logic (found by a live confirmation smoke, not by the offline suite or adversarial review — seedocs/handoffs/HANDOFF.md). Late August: a ~525-cell capability-spectrum sweep found the off-the-shelf LangGraph agent cannot run 4 of 8 cheap models at all (no tool-calling endpoint), a blind shape classification found the graph's loss is concentrated on aggregation-shaped tasks (−0.461, n=23), and an external literature review found no published result supporting "planning helps an untuned ≤14B model" under this project's filters. - 2026-08-31 → present — Euglena Ledger: scope narrowed from general agentic capability to an
auditable evidence compiler (
docs/LEDGER.md). Shipped: a derivation layer with unit refusal, per-call audit log withcall_idpairing, frozen-corpus replay (SEARCH_PROVIDER=corpus) so every campaign runs at $0, preregistration gates, a 22-task numeric suite, a frozen KPI spec with a sealed holdout, theledger_apicomponent façade, quote capture and a deterministic certify chain. Five preregistered campaigns (ledgernum22, ladder03, mint01, mint02 and the module 2×2) established what the Ledger can and cannot claim; see the Ledger section above. Work happened ondagv2-evidence-ledger, merged intomasteron 2026-09-07 with a consolidated state-of-evidence document and roadmap. - parked — v3: The continuable, chatbot-like interaction and the codebench fold-in are not on any live line. Kept as a future option, not a plan.


