Files
symclaw/IMPLEMENTATION_PLAN.md
T

694 lines
27 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SymClaw — Implementation Plan & Critical Analysis
## Project: Open-Source Symbolic Computing for the Agentic Age
**Codename:** SymClaw
**Stack:** Rust Symbolic Engine + OpenClaw Agentic Bridge
**Author:** Omar (HPC-AI Platform)
**Date:** 2026-02-12
**Status:** Architecture Review
---
## 1. Strategic Assessment
### 1.1 What Makes This a Paradigm Shift
The roadmap you've drafted is strong, but to truly be paradigm-shifting, there are dimensions the original plan underweights. Here's what elevates this from "another CAS" to a genuine platform shift:
**The Killer Insight: Deterministic Compute + Agentic Intelligence**
Every existing CAS is either (a) deterministic but dumb (Mathematica, SymPy — you type exact commands) or (b) intelligent but unreliable (ChatGPT doing math — hallucinates). SymClaw is the first system where:
- The **LLM handles intent** ("what's the derivative of this messy physics equation?")
- The **symbolic engine guarantees correctness** (deterministic Rust computation)
- The **e-graph finds the optimal form** (not just *an* answer, but the *best* answer)
- The **agentic layer delivers it anywhere** (WhatsApp, Telegram, Canvas, voice)
This is the "compiler + IDE" moment for scientific computing. No one else is building this.
### 1.2 Critical Gaps in the Original Roadmap
| Gap | Why It Matters | Resolution |
|-----|---------------|------------|
| **No numeric fallback strategy** | Many real-world problems can't be solved symbolically | Add hybrid symbolic-numeric pipeline (Phase 2.5) |
| **No error recovery / graceful degradation** | Users will hit unsolvable expressions constantly | Implement "best effort" mode with confidence scoring |
| **Parser underspecified** | Input parsing is 50% of the user experience | Dedicate Sprint 1 to parser with extensive edge-case handling |
| **No caching layer** | Same expressions re-evaluated across sessions | Add expression-level memoization with LRU cache |
| **Security model missing** | Arbitrary expression evaluation is a DoS vector | Expression complexity limits, timeout enforcement, sandboxing |
| **No migration path from existing tools** | Scientists won't switch without import capability | SymPy/LaTeX import in V0.5, Mathematica notebook import in V1.0 |
| **Collaboration undefined** | Research is collaborative | Multi-user Canvas sessions via OpenClaw multi-agent routing (V1.0) |
| **No offline mode** | Scientists work on planes, in labs without internet | WASM module works fully offline; LLM intent parsing degrades to direct command mode |
### 1.3 Build vs. Integrate Decisions
Before writing a single line, these decisions save months:
| Component | Build | Integrate | Recommendation |
|-----------|-------|-----------|----------------|
| Expression AST | ✅ | | Build — core IP, must be Arc-based for your cluster |
| Parser | ✅ | | Build with nom — need custom notation support |
| Simplifier | Hybrid | `egg` crate | Integrate egg, build rule sets on top |
| Differentiation | ✅ | | Build — well-defined algorithms, your rules |
| Integration | ✅ | | Build core; consider SymPy FFI for edge cases |
| Linear Algebra | | `nalgebra` | Integrate nalgebra for numeric, build symbolic layer |
| Plotting | | Plotly.js | Integrate in Canvas; don't build a plotting library |
| LaTeX rendering | | KaTeX | Integrate — battle-tested, fast, WASM-compatible |
| Arbitrary precision | | `num` crate | Integrate |
| WASM compilation | | `wasm-bindgen` | Integrate |
---
## 2. Architecture Deep Dive
### 2.1 Expression AST — The Foundation
This is the most critical design decision. Get it wrong and everything downstream suffers.
```rust
// Core expression type — every operation in the system flows through this
#[derive(Clone, Hash, Eq, PartialEq, Debug)]
pub enum Expr {
// Atoms
Num(Rational), // Exact: 3/7, -42, 0
Float(OrderedFloat<f64>), // IEEE 754 when exact isn't needed
Symbol(Symbol), // Interned string: x, y, theta
Complex(Arc<Expr>, Arc<Expr>), // a + bi
// N-ary operations (flattened, canonically sorted)
Add(Vec<Arc<Expr>>), // a + b + c (not nested)
Mul(Vec<Arc<Expr>>), // a * b * c (not nested)
// Binary operations
Pow(Arc<Expr>, Arc<Expr>), // base^exponent
// Functions
Func(FuncId, Vec<Arc<Expr>>), // sin(x), log(x, base), custom(a, b, c)
// Calculus
Derivative(Arc<Expr>, Symbol, u32), // d^n f / dx^n
Integral(Arc<Expr>, Symbol, Option<Bounds>), // ∫f dx or ∫_a^b f dx
Limit(Arc<Expr>, Symbol, Arc<Expr>, Direction),
Sum(Arc<Expr>, Symbol, Arc<Expr>, Arc<Expr>), // Σ
Product(Arc<Expr>, Symbol, Arc<Expr>, Arc<Expr>), // Π
// Structural
Eq(Arc<Expr>, Arc<Expr>), // equation
Matrix(MatrixData), // symbolic matrix
Piecewise(Vec<(Arc<Expr>, Condition)>),
// Meta
Undefined, // 0/0, etc.
Infinity(Sign),
}
```
**Critical Design Notes:**
1. **Arc, not Box** — You need Send + Sync for rayon parallelism across your Pi cluster nodes. The ~8 bytes overhead per Arc is negligible vs. the threading flexibility.
2. **Interned Symbols** — Use the `string_interner` crate. In a typical session, the same variable names (x, y, t, theta) appear thousands of times. Interning reduces memory and makes comparison O(1).
3. **Canonical Ordering**`Add(vec![x, 3])` and `Add(vec![3, x])` must be the same expression. Sort commutative operands by a canonical ordering (constants first, then symbols alphabetically, then complex expressions by depth). This is essential for e-graph efficiency.
4. **Flattened N-ary**`(a + b) + c` becomes `Add(vec![a, b, c])`. This eliminates association ambiguity and makes pattern matching simpler.
### 2.2 The Egg Integration — This Is Your Moat
The equality saturation engine via `egg` is what differentiates SymClaw from SymPy. Here's why and how:
**Why it matters:**
Traditional CAS simplifiers apply rules greedily: pick a rule, apply it, repeat. This gets stuck in local optima. Example:
```
Input: (x^2 - 1) / (x - 1)
Greedy: tries to simplify numerator and denominator separately → stuck
Egg: discovers x^2 - 1 = (x+1)(x-1), cancels → (x+1) ✓
```
Egg explores ALL possible rewrites simultaneously using e-graphs, then extracts the simplest result. This is provably optimal (given enough rules and iterations).
**Implementation strategy:**
```rust
use egg::{*, rewrite as rw};
define_language! {
pub enum MathLang {
Num(i64),
"+" = Add([Id; 2]),
"*" = Mul([Id; 2]),
"/" = Div([Id; 2]),
"^" = Pow([Id; 2]),
"neg" = Neg([Id; 1]),
"sin" = Sin([Id; 1]),
"cos" = Cos([Id; 1]),
"ln" = Ln([Id; 1]),
"exp" = Exp([Id; 1]),
"d" = Deriv([Id; 2]), // d(expr, var)
Symbol(Symbol),
}
}
fn math_rules() -> Vec<Rewrite<MathLang, ConstantFold>> {
vec![
// Arithmetic identities
rw!("add-0"; "(+ ?a 0)" => "?a"),
rw!("mul-1"; "(* ?a 1)" => "?a"),
rw!("mul-0"; "(* ?a 0)" => "0"),
rw!("pow-0"; "(^ ?a 0)" => "1"),
rw!("pow-1"; "(^ ?a 1)" => "?a"),
// Commutativity
rw!("add-comm"; "(+ ?a ?b)" => "(+ ?b ?a)"),
rw!("mul-comm"; "(* ?a ?b)" => "(* ?b ?a)"),
// Associativity
rw!("add-assoc"; "(+ ?a (+ ?b ?c))" => "(+ (+ ?a ?b) ?c)"),
rw!("mul-assoc"; "(* ?a (* ?b ?c))" => "(* (* ?a ?b) ?c)"),
// Distribution
rw!("distribute"; "(* ?a (+ ?b ?c))" => "(+ (* ?a ?b) (* ?a ?c))"),
rw!("factor"; "(+ (* ?a ?b) (* ?a ?c))" => "(* ?a (+ ?b ?c))"),
// Differentiation rules (the magic — egg discovers derivatives)
rw!("d-const"; "(d ?c ?x)" => "0" if is_const("?c", "?x")),
rw!("d-var"; "(d ?x ?x)" => "1"),
rw!("d-add"; "(d (+ ?a ?b) ?x)" => "(+ (d ?a ?x) (d ?b ?x))"),
rw!("d-mul"; "(d (* ?a ?b) ?x)" =>
"(+ (* (d ?a ?x) ?b) (* ?a (d ?b ?x)))"),
rw!("d-pow"; "(d (^ ?a ?n) ?x)" =>
"(* (* ?n (^ ?a (+ ?n -1))) (d ?a ?x))"
if is_const("?n", "?x")),
rw!("d-sin"; "(d (sin ?a) ?x)" => "(* (cos ?a) (d ?a ?x))"),
rw!("d-cos"; "(d (cos ?a) ?x)" => "(* (neg (sin ?a)) (d ?a ?x))"),
rw!("d-exp"; "(d (exp ?a) ?x)" => "(* (exp ?a) (d ?a ?x))"),
rw!("d-ln"; "(d (ln ?a) ?x)" => "(* (/ 1 ?a) (d ?a ?x))"),
// Trig identities
rw!("sin2+cos2"; "(+ (^ (sin ?a) 2) (^ (cos ?a) 2))" => "1"),
rw!("exp-ln"; "(exp (ln ?a))" => "?a"),
rw!("ln-exp"; "(ln (exp ?a))" => "?a"),
]
}
```
**Explain Mode — The "Show Your Work" Feature:**
```rust
// Using egg's explain API to show step-by-step derivation
let runner = Runner::default()
.with_explanations_enabled()
.with_expr(&start)
.run(&rules);
let explanation = runner.explain_equivalence(&start, &goal);
// Returns: [(rule_name, before_expr, after_expr), ...]
// User sees: "Applied product rule → Applied power rule → Simplified"
```
This is huge for education. No other CAS can show WHY it simplified an expression.
### 2.3 OpenClaw Skill Architecture
```
┌─────────────────────────────────────────┐
│ User's Phone/Desktop │
│ Telegram │ WhatsApp │ Canvas │ WebChat │
└─────────────┬───────────────────────────┘
│ message: "derive sin(x^2)"
┌─────────────────────────────────────────┐
│ OpenClaw Gateway (Node.js) │
│ ┌─────────────────────────────────┐ │
│ │ LLM (Claude/GPT) — Intent Parse │ │
│ │ "derive sin(x^2)" │ │
│ │ → tool: math_eval │ │
│ │ → expr: "d/dx(sin(x^2))" │ │
│ └──────────────┬──────────────────┘ │
│ │ │
│ ┌──────────────▼──────────────────┐ │
│ │ symclaw Skill (JS wrapper) │ │
│ │ ┌────────────────────────┐ │ │
│ │ │ Option A: WASM Module │ │ │
│ │ │ (in-process, fast) │ │ │
│ │ └────────────────────────┘ │ │
│ │ ┌────────────────────────┐ │ │
│ │ │ Option B: Subprocess │ │ │
│ │ │ (native, full perf) │ │ │
│ │ └────────────────────────┘ │ │
│ └──────────────┬──────────────────┘ │
│ │ result + LaTeX │
│ ┌──────────────▼──────────────────┐ │
│ │ Response Formatter │ │
│ │ Telegram: ASCII + LaTeX image │ │
│ │ Canvas: Interactive HTML │ │
│ │ WhatsApp: ASCII + rendered PNG │ │
│ └─────────────────────────────────┘ │
└─────────────────────────────────────────┘
```
### 2.4 Canvas Manipulate — Real-Time Math Exploration
This is the feature that makes scientists' eyes light up. Mathematica's `Manipulate[]` is one of its most beloved features. Here's how we replicate it:
```javascript
// A2UI JSONL payload pushed to Canvas
{"surfaceUpdate": {
"surfaceId": "manipulate-1",
"components": [
{"id": "title", "component": {"Text": {
"text": {"literalString": "f(x) = a·sin(b·x + c)"},
"usageHint": "h2"
}}},
{"id": "slider-a", "component": {"Slider": {
"min": 0.1, "max": 5.0, "step": 0.1, "value": 1.0,
"label": "a (amplitude)"
}}},
{"id": "slider-b", "component": {"Slider": {
"min": 0.1, "max": 10.0, "step": 0.1, "value": 1.0,
"label": "b (frequency)"
}}},
{"id": "slider-c", "component": {"Slider": {
"min": -3.14, "max": 3.14, "step": 0.01, "value": 0.0,
"label": "c (phase)"
}}},
{"id": "plot", "component": {"WebView": {
"html": "<canvas id='plot'></canvas><script>/* Plotly + WASM eval */</script>"
}}}
]
}}
```
The magic: slider changes trigger WASM evaluation directly in the Canvas JavaScript, no round-trip to the server needed. 30fps updates on a phone.
---
## 3. Testing Strategy — Correctness Is Non-Negotiable
### 3.1 The Testing Pyramid
```
╱╲
╲ Manual Testing
5% ╲ (demo to researchers, get feedback)
╱──────╲
╲ Stress/Load Tests
10% ╲ (Pi cluster, WASM limits, DoS)
╱────────────╲
╱ ╲ Integration Tests
15% ╲ (OpenClaw → Engine → Canvas pipeline)
╱──────────────────╲
╱ ╲ Property-Based Tests
25% ╲ (proptest: numerical invariants)
╱────────────────────────╲
╱ ╲ Unit Tests
45% ╲ (every rule, every function)
╱──────────────────────────────╲
```
### 3.2 Property-Based Testing (The Secret Weapon)
```rust
use proptest::prelude::*;
// Strategy: generate random mathematical expressions
fn arb_expr(depth: u32) -> impl Strategy<Value = Expr> {
let leaf = prop_oneof![
(1..100i64).prop_map(|n| Expr::Num(Rational::from(n))),
Just(Expr::Symbol("x".into())),
Just(Expr::Symbol("y".into())),
];
leaf.prop_recursive(depth, 256, 10, |inner| {
prop_oneof![
(inner.clone(), inner.clone()).prop_map(|(a, b)|
Expr::Add(vec![Arc::new(a), Arc::new(b)])),
(inner.clone(), inner.clone()).prop_map(|(a, b)|
Expr::Mul(vec![Arc::new(a), Arc::new(b)])),
inner.clone().prop_map(|a|
Expr::Func(FuncId::Sin, vec![Arc::new(a)])),
]
})
}
proptest! {
// INVARIANT 1: Simplification preserves numerical value
#[test]
fn simplify_preserves_value(
expr in arb_expr(4),
x in -10.0f64..10.0,
) {
let original = expr.eval(&[("x", x)]);
let simplified = simplify(&expr);
let result = simplified.eval(&[("x", x)]);
if original.is_finite() && result.is_finite() {
prop_assert!((original - result).abs() < 1e-10,
"Simplification changed value: {} → {}", original, result);
}
}
// INVARIANT 2: Simplification is idempotent
#[test]
fn simplify_idempotent(expr in arb_expr(3)) {
let once = simplify(&expr);
let twice = simplify(&once);
prop_assert_eq!(once, twice, "Not idempotent");
}
// INVARIANT 3: Parse round-trip
#[test]
fn parse_roundtrip(expr in arb_expr(3)) {
let printed = format!("{}", expr);
let reparsed = parse(&printed).unwrap();
prop_assert_eq!(expr, reparsed, "Round-trip failed");
}
// INVARIANT 4: Derivative + Integral approximate inverse
#[test]
fn derivative_integral_roundtrip(
expr in arb_polynomial(3), // restrict to polynomials for tractability
x in -5.0f64..5.0,
) {
let d = differentiate(&expr, "x");
let i = integrate(&d, "x");
let diff = (expr.eval(&[("x", x)]) - i.eval(&[("x", x)])).abs();
// Should differ by at most a constant
let diff2 = (expr.eval(&[("x", x + 0.1)]) - i.eval(&[("x", x + 0.1)])).abs();
prop_assert!((diff - diff2).abs() < 1e-8,
"Integral of derivative should differ by constant");
}
}
```
### 3.3 Integration Test: Full Pipeline
```typescript
// test/integration/telegram-to-canvas.test.ts
describe('Telegram → Engine → Canvas pipeline', () => {
it('should differentiate and render on Canvas', async () => {
// 1. Simulate Telegram message
const response = await gateway.handleMessage({
channel: 'telegram',
sender: '+15555551234',
text: 'What is the derivative of x^3 * sin(x)?'
});
// 2. Verify text response
expect(response.text).toContain('3x²·sin(x) + x³·cos(x)');
// 3. Verify LaTeX image was generated
expect(response.attachments).toHaveLength(1);
expect(response.attachments[0].mimeType).toBe('image/png');
// 4. Verify Canvas push (if mobile node connected)
const canvasPush = await gateway.getLastCanvasPush();
expect(canvasPush.surfaceId).toBe('math-result');
expect(canvasPush.components).toContainEqual(
expect.objectContaining({ id: 'latex-display' })
);
});
});
```
### 3.4 Stress Test: Pi Cluster
```bash
#!/bin/bash
# stress_test.sh — Run on Pi cluster control node
# Generate 1000 random expressions and fire them concurrently
for i in $(seq 1 1000); do
EXPR=$(symclaw-cli random-expr --depth 5 --seed $i)
curl -s -X POST http://gateway:18789/api/eval \
-H "Content-Type: application/json" \
-d "{\"expr\": \"$EXPR\"}" &
# Rate limit: 50 concurrent
[ $(jobs -r | wc -l) -ge 50 ] && wait -n
done
wait
echo "All 1000 evaluations complete"
# Verify: no crashes, no OOM, all returned valid results
```
---
## 4. Deployment Architecture
### 4.1 Single-Node (90% of users)
```yaml
# docker-compose.yml — one command: docker compose up
version: '3.8'
services:
symclaw:
image: ghcr.io/symclaw/symclaw:latest
ports:
- "18789:18789" # OpenClaw Gateway
- "3000:3000" # WebChat
volumes:
- ~/.openclaw:/root/.openclaw
- ~/.symclaw:/root/.symclaw
environment:
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
- SYMCLAW_ENGINE=wasm # or 'native' for full performance
restart: unless-stopped
deploy:
resources:
limits:
memory: 2G
```
### 4.2 Pi Cluster (Power Users)
```
┌──────────────────────────────────────────┐
│ Pi 5 (Control Node) │
│ OpenClaw Gateway + Tailscale │
│ Load Balancer (round-robin) │
│ ┌────────┐ ┌────────┐ ┌────────┐ │
│ │ Pi 4 #1│ │ Pi 4 #2│ │ Pi 4 #3│ │
│ │ Engine │ │ Engine │ │ Engine │ │
│ │ Worker │ │ Worker │ │ Worker │ │
│ └────────┘ └────────┘ └────────┘ │
│ ↕ Tailscale mesh ↕ │
│ ┌──────────────────────────────┐ │
│ │ x86 Workstation (optional) │ │
│ │ RTX 5090 — heavy compute │ │
│ └──────────────────────────────┘ │
└──────────────────────────────────────────┘
```
### 4.3 Nix Deployment
```nix
# flake.nix
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
rust-overlay.url = "github:oxalica/rust-overlay";
crane.url = "github:ipetkov/crane";
};
outputs = { self, nixpkgs, rust-overlay, crane, ... }:
let
systems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
in {
packages = builtins.listToAttrs (map (system: {
name = system;
value = {
symclaw-core = crane.lib.${system}.buildPackage {
src = ./core;
# Cross-compile for Pi from x86
};
symclaw-wasm = crane.lib.${system}.buildPackage {
src = ./wasm;
CARGO_BUILD_TARGET = "wasm32-unknown-unknown";
};
};
}) systems);
nixosModules.symclaw = { config, ... }: {
services.symclaw = {
enable = true;
port = 18789;
engineMode = "native"; # or "wasm"
anthropicApiKey = config.sops.secrets.anthropic.path;
};
};
};
}
```
---
## 5. Open Source & Community Strategy
### 5.1 Launch Sequence
| Week | Action | Channel |
|------|--------|---------|
| T-2 | Soft launch: share with 10 trusted alpha testers | Direct invite |
| T-1 | Blog post: "Why We Built an Open-Source Mathematica in Rust" | Personal blog + dev.to |
| T+0 | GitHub public + crates.io publish | GitHub |
| T+0 | Hacker News "Show HN" post | Hacker News |
| T+0 | r/rust, r/math, r/opensource posts | Reddit |
| T+1 | OpenClaw Discord announcement | OpenClaw community |
| T+2 | Video demo: "From Telegram to LaTeX in 2 Seconds" | YouTube + X |
| T+4 | Reach out to university math departments | Email + academic networks |
### 5.2 Good First Issues (Pre-Labeled)
- "Add hyperbolic trig functions (sinh, cosh, tanh)"
- "Implement pretty-print for matrix expressions"
- "Add LaTeX input parser (basic subset)"
- "Write property test for trig identities"
- "Add Fibonacci sequence to the series module"
- "Improve error messages for parse failures"
- "Add --json output flag to CLI"
### 5.3 Governance
- **License:** MIT + Apache 2.0 (dual license, standard Rust ecosystem)
- **Contributions:** All PRs require 1 review + CI green + property tests pass
- **Rule contributions:** New rewrite rules require (a) correctness proof sketch, (b) proptest coverage, (c) benchmark showing no performance regression
- **Breaking changes:** Semantic versioning, deprecation warnings in minor versions
---
## 6. What the Roadmap Was Missing — Additions
### 6.1 Caching Layer (Add to Phase 1)
```rust
use lru::LruCache;
use std::sync::Mutex;
// Expression-level memoization
lazy_static! {
static ref SIMPLIFY_CACHE: Mutex<LruCache<u64, Arc<Expr>>> =
Mutex::new(LruCache::new(NonZeroUsize::new(10_000).unwrap()));
}
pub fn simplify_cached(expr: &Expr) -> Arc<Expr> {
let hash = expr.stable_hash();
if let Some(cached) = SIMPLIFY_CACHE.lock().unwrap().get(&hash) {
return cached.clone();
}
let result = simplify(expr);
SIMPLIFY_CACHE.lock().unwrap().put(hash, result.clone());
result
}
```
### 6.2 Confidence Scoring (Add to Phase 2)
Not all simplifications are equally trustworthy. Add a confidence score:
```rust
pub struct EvalResult {
pub expr: Expr,
pub latex: String,
pub confidence: Confidence,
pub steps: Vec<Step>,
}
pub enum Confidence {
Exact, // Algebraic simplification, fully verified
HighConfidence, // Integration by standard method
Heuristic, // Pattern-matched, not formally verified
NumericOnly, // Could not solve symbolically, numeric result
Failed(String), // Could not compute, here's why
}
```
### 6.3 Offline Mode (Add to Phase 3)
When no LLM is available (no API key, no internet), SymClaw should still work:
```
User types: /math d/dx(x^2 * sin(x))
→ Direct command parsing (no LLM needed)
→ Engine computes result
→ Returns ASCII: 2x*sin(x) + x^2*cos(x)
User types: "what's the derivative of x squared times sine x"
→ No LLM available
→ Respond: "Natural language mode requires an AI model connection.
Use command syntax: /derive x^2 * sin(x)"
```
### 6.4 Benchmark Suite (Add to Phase 5)
Compare against SymPy on standardized problems:
```rust
// benchmarks/sympy_parity.rs
const BENCHMARK_PROBLEMS: &[(&str, &str)] = &[
("simplify", "(x^2 - 1)/(x - 1)", "x + 1"),
("derive", "d/dx(x^3 * sin(x))", "3*x^2*sin(x) + x^3*cos(x)"),
("integrate", "∫ x*exp(x) dx", "x*exp(x) - exp(x)"),
("solve", "x^2 - 5*x + 6 = 0", "{2, 3}"),
("taylor", "sin(x) about 0 order 5", "x - x^3/6 + x^5/120"),
("limit", "lim(x→0) sin(x)/x", "1"),
// ... 100+ problems from MIT OCW
];
```
### 6.5 Telemetry & Observability (Add to Phase 4)
```rust
// Prometheus metrics exposed at /metrics
pub struct EngineMetrics {
pub eval_latency: Histogram, // How long evaluations take
pub egraph_size: Gauge, // Current e-graph node count
pub cache_hit_rate: Counter, // Memoization effectiveness
pub parse_errors: Counter, // Input quality signal
pub timeout_count: Counter, // Expressions that hit limits
pub active_sessions: Gauge, // Connected OpenClaw sessions
}
```
Surface these in Omar's OpenClaw Mission Control Dashboard.
---
## 7. Timeline Summary
```
Week 1-2: Phase 0 — Foundation (CI/CD, Nix, project scaffolding)
Week 3-6: Phase 1 — Engine Core: Arithmetic, Algebra, Egg, CLI
Week 7-10: Phase 2 — Engine Core: Calculus, Solving, Series, WASM
Week 11-13: Phase 3 — OpenClaw Skill, Canvas, Manipulate
Week 14-15: Phase 4 — Docker, Nix, Pi Cluster, Tailscale
Week 16-18: Phase 5 — Testing, Docs, Community, V0.1 Alpha Release
─────────────────────────────────────────────────────────────────
Week 19-30: Phase 6 — V0.5 Beta (LinAlg, ODEs, Jupyter)
Week 31-44: Phase 7 — V1.0 Launch (GPU, Clawbernetes, Collaboration)
```
**Total to Alpha: ~18 weeks**
**Total to Production Launch: ~44 weeks**
---
## 8. Final Recommendation
This project is viable and genuinely differentiated. The combination of:
1. **Rust performance** (10-100x over Python CAS)
2. **Equality saturation** (provably optimal simplification)
3. **Agentic AI delivery** (message your math assistant on WhatsApp)
4. **Edge deployment** (Pi cluster, WASM, offline-capable)
5. **Open source** (MIT, community-driven)
...creates a product that doesn't exist today. The closest comparison is if Wolfram built Mathematica on top of ChatGPT and gave it away for free — except you own the infrastructure.
**Key risk to manage:** Scope. Mathematica has 6,600 functions built over 35 years. SymClaw needs to ship V0.1 with ~50 functions that cover 80% of undergraduate math, then let the community build the rest. The architecture (extensible rule sets, community ClawHub skills) makes this feasible.
**The paradigm shift isn't the math engine — it's the delivery model.** Scientists don't want another desktop app. They want to text their math assistant at 2am from bed and get a correct, beautifully rendered answer on their phone. That's what SymClaw delivers.