Skip to content

Add MseeP.ai badge - #1

Closed
lwsinclair wants to merge 1 commit into
ruvnet:mainfrom
lwsinclair:add-mseep-badge
Closed

lwsinclair wants to merge 1 commit into
ruvnet:mainfrom
lwsinclair:add-mseep-badge

Conversation

@lwsinclair

Copy link
Copy Markdown

Hi there,

This pull request shares a security update on sublinear-time-solver.

We also have an entry for sublinear-time-solver in our directory, MseeP.ai, where we provide regular security and trust updates on your app.

We invite you to add our badge for your MCP server to your README to help your users learn from a third party that provides ongoing validation of sublinear-time-solver.

You can easily take control over your listing for free: visit it at https://mseep.ai/app/ruvnet-sublinear-time-solver.

Yours Sincerely,

Lawrence W. Sinclair
CEO/SkyDeck AI
Founder of MseeP.ai
MCP servers you can trust


MseeP.ai Security Assessment Badge

Here are our latest evaluation results of sublinear-time-solver

Security Scan Results

Security Score: 90/100

Risk Level: low

Scan Date: 2025-09-20

Score starts at 100, deducts points for security issues, and adds points for security best practices

Detected Vulnerabilities

Medium Severity

  • axios

    • [{'source': 1097679, 'name': 'axios', 'dependency': 'axios', 'title': 'Axios Cross-Site Request Forgery Vulnerability', 'url': 'https://github.com/advisories/GHSA-wf5p-g6vw-rhxx', 'severity': 'moderate', 'cwe': ['CWE-352'], 'cvss': {'score': 6.5, 'vectorString': 'CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:N'}, 'range': '>=0.8.1 <0.28.0'}, {'source': 1103617, 'name': 'axios', 'dependency': 'axios', 'title': 'axios Requests Vulnerable To Possible SSRF and Credential Leakage via Absolute URL', 'url': 'https://github.com/advisories/GHSA-jr5f-v2jv-69x6', 'severity': 'high', 'cwe': ['CWE-918'], 'cvss': {'score': 0, 'vectorString': None}, 'range': '<0.30.0'}, {'source': 1107599, 'name': 'axios', 'dependency': 'axios', 'title': 'Axios is vulnerable to DoS attack through lack of data size check', 'url': 'https://github.com/advisories/GHSA-4hjh-wcwx-xvwj', 'severity': 'high', 'cwe': ['CWE-770'], 'cvss': {'score': 7.5, 'vectorString': 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H'}, 'range': '<1.12.0'}]
    • Fixed in version: unknown
  • binary-install

    • ['axios']
    • Fixed in version: unknown
  • wasm-pack

    • ['binary-install']
    • Fixed in version: unknown

This security assessment was conducted by MseeP.ai, an independent security validation service for MCP servers. Visit our website to learn more about our security reviews.

@ruvnet ruvnet closed this Sep 20, 2025
ruvnet pushed a commit that referenced this pull request May 19, 2026
Refuses polynomial-time solves on near-singular systems whose
diagonal-dominance margin falls below a configurable threshold —
the architectural defence against the Pi-Zero / Cognitum failure
mode where the solver burns a J/decision budget producing an
ε-quality answer the agent then discards.

New module `src/coherence.rs`:

  - `coherence_score(&dyn Matrix) -> f64` — one-pass diagonal-
    dominance margin in [-∞, 1]:
      * 1.0  = perfectly diagonal
      * (0,1) = strictly DD; Neumann series convergence guaranteed
      * 0    = boundary
      * <0   = not DD; iterative solvers may diverge
      * -∞   = zero diagonal (degenerate row)
  - `check_coherence_or_reject(&dyn Matrix, threshold)` — returns
    Err(Incoherent) if score < threshold; Ok(score) otherwise.
    Threshold = 0 disables the gate entirely (the default).

Wired into the public API:

  - `SolverError::Incoherent { coherence, threshold }` — new
    variant, `is_recoverable() = true`, severity = Low (it's a
    budget refusal, not corruption), formatted error message
    points the caller at ADR-001 and the opt-out.
  - `SolverOptions::coherence_threshold: Precision` — defaults to
    `0.0` (gate disabled) so every existing caller is wire-
    compatible. Setting to `0.05` enables the recommended floor.
  - lib.rs re-exports `coherence_score` and
    `check_coherence_or_reject` at the crate root.

8 new unit tests cover the score function (perfect diagonal,
moderate dominance, boundary case, non-dominant, zero-diagonal)
and the gate (disabled threshold passes, enabled threshold
rejects incoherent and accepts dominant matrices).

Test count: 137 → 145 lib pass. No external API breakage —
SolverOptions still has Default + all 3 named constructors with
the new field set to 0.0.

ADR-001 roadmap: items #1 + #3 done, 4 left (#2 solve_on_change,
#4 MCP advertise, #5 joules bench, #6 contrastive adapter).
ruvnet pushed a commit that referenced this pull request May 19, 2026
The central architectural payoff of ADR-001: when a downstream system
(Cognitum reflex loop, RuView change detection, Ruflo agentic inner
loop, ruvector graph repair) delivers a *sparse* update to the RHS,
the solver pays sub-linear work proportional to ||delta|| rather than
cold-starting against the full b. Lifts steady-state cost from
`O(k_cold · nnz(A))` to `O(k_warm · nnz(A))` where k_warm ≪ k_cold
on well-conditioned DD systems with small deltas.

New module `src/incremental.rs`:

  - `SparseDelta { indices, values }` — additive sparse update to a
    RHS vector. `apply_to`, `as_pairs`, `nnz`, `is_empty`, length
    validation, out-of-bounds rejection.

  - `IncrementalSolver` extension trait blanket-impl'd for every
    `SolverAlgorithm` so the entry point is available on every solver
    in the crate (Neumann, optimised CG, sublinear-Neumann, …) with
    no per-solver wiring needed.

  - `solve_on_change(matrix, prev, delta, opts)` uses the
    **residual-correction pattern**:
        r   = delta            (= b_new − A·prev for converged prev)
        dx  = A⁻¹ · r          (inner cold solve on a small sparse RHS)
        x   = prev + dx

    This sidesteps the trap of feeding `initial_guess = prev` to
    iterative solvers that don't honour it correctly (Neumann's
    `compute_next_term` double-counts the k=0 series term, same class
    of bug as the iter-2 v1.6.0 fix). Solving for the *correction*
    from zero is asymptotically faster because ||r|| ≪ ||b_new||
    drives Neumann's geometric convergence to fewer iters
    proportional to log(||r||/||b_new||).

  - `IncrementalConfig` knobs for tuning the warm-start / full-solve
    crossover.

  - `IncrementalSolveOp` marker type with `Complexity = Adaptive {
    Linear, Linear }` and `DETAIL` documenting the sub-linear-in-
    delta-norm payoff. Stable target for the future MCP `x-complexity`
    schema (ADR-001 item #4).

6 unit tests pin the contract:

  - SparseDelta validation: length match, out-of-bounds detection.
  - Identity case: empty delta + prev_solution → same solution as
    full solve.
  - Tracking: incremental result on b_prev + delta matches cold
    full-solve on the new RHS within solver tolerance.
  - **Architectural promise**: warm-start iterations ≤ cold-start
    iterations on a small delta (the headline benefit of this
    roadmap item).

Test count: 145 → 151 lib pass (+6). No external API breakage —
purely additive. Existing callers keep working unchanged; the new
entry point is opt-in.

ADR-001 roadmap status: items #1 #2 #3 done. Remaining:
  #4 MCP x-complexity + max_complexity_class budget arg
  #5 joules_per_decision bench
  #6 find_anomalous_rows contrastive adapter
ruvnet pushed a commit that referenced this pull request May 19, 2026
Cuts the minor that captures the first three roadmap items of
ADR-001 (Complexity as Architecture):

  - item #1: ComplexityClass enum + Complexity trait
  - item #2: solve_on_change residual-correction
  - item #3: coherence gate

Public API is additive — no breaking changes. SolverOptions gains
one new field with default 0.0 (gate disabled), so every existing
caller stays wire-compatible.

Bumps:
  - npm  sublinear-time-solver  1.6.0 → 1.7.0
  - rust sublinear (crate)      0.2.0 → 0.3.0

CHANGELOG.md gets a fresh 1.7.0 section above the existing 1.6.0
entry, structured to match Keep-a-Changelog conventions.

Roadmap items #4, #5, #6 stay on the cron a3644c7d backlog for the
follow-up minor.
ruvnet pushed a commit that referenced this pull request May 19, 2026
ADR-001 roadmap item #6: the boundary-crossing primitive RuView /
Cognitum / Ruflo's inner loops actually call. Two functions in a
new module `src/contrastive.rs`:

  - `find_anomalous_rows(baseline, current, k) -> Vec<AnomalyRow>`
    Top-k rows by |current[i] - baseline[i]|, sorted desc with row
    index as the tie-break. `O(n log k)` via a `k`-sized min-heap
    (BinaryHeap with inverted Ord). Phase-1 implementation: full
    scan over the dense vectors. Phase-2 (tracked as TODO) drops to
    O(k · log n) by computing individual entries of `current`
    directly via the sublinear-Neumann single-entry primitive,
    matching what the ADR §Roadmap promised.

  - `find_rows_above_threshold(baseline, current, threshold)` —
    O(n) one-pass filter that returns ALL rows whose anomaly exceeds
    `threshold`. The change-driven activation primitive: an agent
    stays asleep until the iterator yields anything. RuView's
    "activate only on boundary crossing" maps directly to this.

  - `AnomalyRow { row, baseline, current, anomaly }` — the report
    shape. Comparable by row + anomaly for deterministic ordering.

  - `FindAnomalousRowsOp` complexity marker:
    `Adaptive { Linear, Linear }` today, with DETAIL documenting
    the planned drop to O(k · log n) in phase 2.

9 unit tests cover the API: empty inputs, k=0, k>n, top-k
correctness, tie-breaks, absolute-value semantics, threshold
filtering / no-match / dim-mismatch panic.

Also fixes the CI failure on the previous push:

  src/incremental.rs:22 doc test had a type mismatch — `SparseDelta::new`
  returns `Result<SparseDelta>` but I passed `&result` directly to
  `solve_on_change`. Added `?` to unwrap the Result and `as &dyn Matrix`
  to make the cast explicit. The 6 unit tests in incremental had been
  doing the right thing; only the doc example was wrong.

Test count: 151 → 160 lib pass + 11 doc tests (was 1 failing).

ADR-001 roadmap: items #1 #2 #3 #6 done. Remaining: #4 MCP
x-complexity advertise + budget arg, #5 joules_per_decision bench.
ruvnet pushed a commit that referenced this pull request May 19, 2026
The metric that converts "this is edge-deployable" from vibes to a
falsifiable number. ADR-001 §SOTA criterion required this before the
package can be called complete. New file
`examples/joules_per_decision.rs`:

  - `PowerCounter` trait with two impls:
      * RaplCounter:    /sys/class/powercap/intel-rapl:0/energy_uj
                        — works on Intel and AMD Zen 2+ via the
                        compatible interface, microjoule resolution.
      * TimeOnlyCounter: wall-clock fallback when RAPL is unreadable
                        (sandbox, macOS, locked-down host). Reports
                        energy as `(not measured)`, prints timing
                        only.

  - `pick_counter()` tries the impls in order and never panics.

  - Two workloads:
      * OptimizedConjugateGradientSolver  (n configurable, default 256)
      * NeumannSolver
    plus a 100-iter warm-up so the first sample doesn't capture cold
    cache + JIT.

  - Report struct prints joules, average watts, µJ/solve, µs/solve
    when RAPL works; just µs/solve when it doesn't.

Local run on the dev host (RAPL not granted to user; fell back to
time-only):

  OptimizedConjugateGradientSolver, n=256:  0.77 µs / solve
  NeumannSolver, n=256:                     47.98 µs / solve

That's a 62× CG-over-Neumann ratio, consistent with the BENCHMARK.md
baselines from the v1.6.0 release. With RAPL granted (root or
chmod a+r), the same workload reports actual joules and average
watts.

Run with:
  cargo run --release --example joules_per_decision
  cargo run --release --example joules_per_decision -- --n 1024 --iters 5000

Phase-2 plan (in the source as a comment):
  - Integrate into the CI bench-smoke job once a stable per-job
    power counter exists (currently GitHub Actions doesn't expose
    one).
  - Add hwmon backend for the Pi Zero 2W path.

ADR-001 roadmap: items #1 #2 #3 #5 #6 done. Only #4 (MCP
x-complexity schema + max_complexity_class budget) remains.
ruvnet pushed a commit that referenced this pull request May 19, 2026
…hase-2)

Promotes the MCP max_complexity_class arg from informational to a
server-side reject. The "bounded-planning kernel" promise from ADR-001
item #4: a caller with a J/decision budget can refuse over-budget
solver invocations at dispatch time, not after the call burns the
budget.

New SublinearSolverMCPServer static tables:

  - COMPLEXITY_RANK: 12-tier rank map mirroring the Rust
    `ComplexityClass::rank()` in src/complexity.rs. Lower = cheaper.
    Logarithmic=100, PolyLogarithmic=200, …, DoubleExponential=1200.

  - METHOD_WORST_CASE: per-solver class lookup. For Adaptive solvers
    (e.g. sublinear-neumann which is `Adaptive { Logarithmic, Linear }`)
    we use the **worst-case** bound so callers always see safe behaviour
    — a caller with a SubLinear budget won't accidentally invoke a
    solver that can degrade to Linear on hard inputs.

New private method `enforceComplexityBudget(method, budget)`:

  - No-op when `budget` is undefined (default — wire compatible).
  - InvalidParams when budget is not a recognised class label.
  - InvalidRequest when method's worst-case rank > budget rank, with
    a structured error message pointing the caller at
    `estimateComplexityClass` for alternatives.

Wired into both solve handlers BEFORE any work is done:

  - handleSolve(params): looks up params.method (default 'neumann')
    and enforces against params.max_complexity_class.
  - handleSolveTrueSublinear(params): always enforces against the
    'sublinear-neumann' method's worst-case class.

Functional smoke (via dist/mcp/server.js):

  enforceComplexityBudget('neumann', 'SubLinear')      → throws ✓
  enforceComplexityBudget('forward-push', 'Linear')    → ok    ✓
  enforceComplexityBudget('neumann', undefined)        → no-op ✓

dist/ rebuilt — TS compiles clean.

ADR-001 status: items #1 through #6 all done + phase-2 enforcement
for #4 now live. Only remaining SOTA polish: CI bench-smoke
integration of J/solve (blocked on GH Actions exposing per-job
power counters; tracked as ADR-001 phase-2 #5).
ruvnet pushed a commit that referenced this pull request Jul 5, 2026
Turns the lineage from an audit trail into a verifiable knowledge base
(design items #1/#3/#4/#5). From the immutable gen-0 root, run-cohort.mjs
autonomously generates a cohort of machine-mutated candidates (real
DeterministicMutator, one per seed), gates each against the frozen anchor
suite with the real ADR-076 gate, and derives two analytics:

- mutation-effectiveness: per mutation surface {attempts, promotions, meanDelta},
  sorted by payoff — the evidence a future optimizer uses to bias mutation
  toward high-payoff classes.
- regression-ancestry: each rejected candidate -> the gate clause it failed ->
  its ancestor (why a direction was abandoned).

verify-cohort.mjs re-runs every node's gate from sealed inputs and RECOMPUTES
both analytics from the node receipts, asserting they match — the knowledge
base is itself verifiable, not a trusted summary. 8-node cohort, deterministic,
all checks pass. Outcomes remain synthetic and are keyed by mutation surface so
payoff differs by class (efficiency surfaces promote; planner regresses and is
abandoned); the real/synthetic boundary is unchanged and documented.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011cHoWPXP5UHwVaNYwjhvjn
ruvnet pushed a commit that referenced this pull request Jul 5, 2026
Running `ruflo guidance` auto-wrote a signed retrieval config champion to
.claude/proven-config.json — this is part #1 of the ruflo 3.24.0 gist ("a
signed retrieval config champion that auto applies on upgrade when authenticity
and compatibility pass"). The exact adopted artifact is captured verbatim under
integrations/ruflo-flywheel/proven-config/ as committed evidence; I did not
author its numbers — ruflo produced them.

The champion carries the full gate receipt the gist describes: heldOutDelta
0.0738, redblue PASS, drift 0, canary rollbackRate 0 / costPerTask 0,
receiptCoverage 1.

The live .claude/ copies are ruflo's runtime state, left in place for it and
gitignored so they don't pollute the tracked .claude/ agent tree.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011cHoWPXP5UHwVaNYwjhvjn
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.

2 participants