Skip to content

feat(adr-001): coherenceScore MCP tool — wire-callable feasibility check - #53

Merged
ruvnet merged 1 commit into
mainfrom
adr/mcp-coherence-tool
May 19, 2026
Merged

ruvnet merged 1 commit into
mainfrom
adr/mcp-coherence-tool

Conversation

@ruvnet

@ruvnet ruvnet commented May 19, 2026

Copy link
Copy Markdown
Owner

Summary

ADR-001 item #3 was reachable from Rust via `coherence::coherence_score` but not from the MCP wire. Wire-callable agents had no way to check "is this matrix solvable?" before invoking a solver — they'd just have to call solve and hope.

Adds `coherenceScore` as a pure-TS MCP tool. Mirrors Rust's semantics:

```
margin(i) = (|A[i,i]| - Σ_{j ≠ i} |A[i,j]|) / |A[i,i]|
coherence(A) = min_i margin(i)
```

Score Meaning
> 0 strictly DD, Neumann convergence guaranteed
= 0 boundary case
< 0 not DD, iterative solvers may diverge
-Inf zero-diagonal row (worst-case incoherence)

Pipeline completion

Now an agent can fully exercise the SubLinear pipeline over MCP:

Step Tool
Predict class `estimateComplexityClass`
Check feasibility `coherenceScore` (this PR)
Enforce budget `max_complexity_class` arg on `solve`
Run solver `solve`
Audit output `verifySparseSolution` (PR #52)

Test plan

  • `npm run build` clean
  • Smoke-checked the math on a hand-computed 3×3 example
  • Full CI (TS-only change)

🤖 Generated with claude-flow

ADR-001 item #3 was reachable from Rust via coherence::coherence_score
but not from the MCP wire. Wire-callable agents had no way to check
"is this matrix solvable?" before invoking a solver — they'd just have
to call solve and hope.

Adds coherenceScore as a pure-TS MCP tool. Mirrors Rust's semantics:

  margin(i) = (|A[i,i]| - Σ_{j ≠ i} |A[i,j]|) / |A[i,i]|
  coherence(A) = min_i margin(i)

  > 0   strictly DD, Neumann convergence guaranteed
  = 0   boundary case
  < 0   not DD, iterative solvers may diverge
  -Inf  zero-diagonal row (worst-case incoherence)

Lands in src/mcp/server.ts:
  - New `coherenceScore` tool with x-complexity = Linear
  - Input schema: just `matrix` (dense or sparse-COO)
  - Dispatch case + handleCoherenceScore method
  - Returns {coherence, worst_row, is_strict_dd, note}

Composition: completes the predict → check → budget → solve → audit
wire pipeline. Now an agent can:

  1. estimateComplexityClass(method) — predict class
  2. coherenceScore(matrix)         — check feasibility (THIS PR)
  3. enforceComplexityBudget(...)   — implicit via max_complexity_class
  4. solve(...)                     — run the solver
  5. verifySparseSolution(...)      — audit output (PR #52)

All wire-callable, no Rust required.

Co-Authored-By: claude-flow <ruv@ruv.net>
@ruvnet
ruvnet merged commit 0539012 into main May 19, 2026
11 of 12 checks passed
@ruvnet
ruvnet deleted the adr/mcp-coherence-tool branch May 19, 2026 19:56
ruvnet added a commit that referenced this pull request May 19, 2026
…trator

The SubLinear orchestrator shipped in Rust (PR #29) had MCP preview
primitives (coherenceScore, closureIndices, estimateComplexityClass)
and a wire-callable witness (PR #52). But the orchestrator itself
wasn't wire-callable — agents had to fall back to `solve` (which
returns the full n-vector) instead of the closure-restricted entries
the SubLinear path produces.

This closes the gap with a pure-TS handler that chains:

  1. closure_indices(matrix, delta.indices, closure_depth)
  2. for each closure entry: truncated Neumann iteration
     restricted to the closure (mirrors src/entry.rs math)
  3. return Vec<{row, value}>

Lands in src/mcp/server.ts:
  - New `solveOnChangeSublinear` tool with x-complexity = SubLinear
  - Input schema: matrix, vector (b_new), delta_indices: number[],
    closure_depth (default 4), max_terms (default 32), tolerance (default 1e-8)
  - Dispatch case + handleSolveOnChangeSublinear method
  - Returns {entries: Array<{row, value}>, closure_size, max_terms,
    closure_depth, note}
  - Supports both dense and sparse-COO matrix formats

Matches Rust solve_on_change_sublinear semantics exactly:
  - Early-exit when |delta_k[target]| < tolerance
  - Zero-diagonal in closure → InvalidParams
  - Empty closure → empty entries
  - note field warns when closure covers full matrix

This completes the wire surface for the change-driven inner loop.
Agents can now run the full pipeline over MCP:

  1. coherenceScore             (PR #53)  — is the matrix solvable?
  2. closureIndices             (PR #54)  — how wide is the work?
  3. estimateComplexityClass    (PRs #30, #42)  — what class?
  4. solveOnChangeSublinear     (THIS PR) — actual SubLinear solve
  5. verifySparseSolution       (PR #52)  — audit output

All 5 tools are pure-TS. No Rust/WASM bridge required for any of them.

Co-Authored-By: claude-flow <ruv@ruv.net>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant