Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
41 changes: 38 additions & 3 deletions .claude/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,50 @@
"PowerShell(dotnet *)",
"Bash(git *)",
"PowerShell(git *)",
"Bash(python Scripts/*)",
"PowerShell(python Scripts/*)",
"Bash(python *)",
"Bash(python3 *)",
"PowerShell(python *)",
"Bash(./update-code-headers.cmd*)",
"Bash(./cleanup.cmd*)",
"Bash(./Sources/Benchmark/run.cmd*)",
"PowerShell(.\\update-code-headers.cmd*)",
"PowerShell(.\\cleanup.cmd*)",
"PowerShell(.\\Sources\\Benchmark\\run.cmd*)",
"PowerShell(taskkill /F /IM dotnet.exe)"
"PowerShell(taskkill /F /IM dotnet.exe)",
"PowerShell(Select-String *)",
"PowerShell(Select-Object *)",
"PowerShell(Sort-Object *)",
"PowerShell(Where-Object *)",
"PowerShell(ForEach-Object *)",
"PowerShell(Measure-Object *)",
"PowerShell(Get-Command *)",
"PowerShell(Test-Path *)",
"Write(D:\\Overfit\\.claude\\run.py)",
"Edit(D:\\Overfit\\.claude\\run.py)",
"Write(.claude/run.py)",
"Edit(.claude/run.py)",
"Bash(python D:/Overfit/.claude/run.py)",
"Bash(python3 D:/Overfit/.claude/run.py)",
"PowerShell(python D:/Overfit/.claude/run.py)",
"Bash(python D:\\Overfit\\.claude\\run.py)",
"Bash(python .claude/run.py)",
"PowerShell(python D:\\Overfit\\.claude\\run.py)",
"Write(D:\\Overfit\\.claude\\run.ps1)",
"Edit(D:\\Overfit\\.claude\\run.ps1)",
"Write(.claude/run.ps1)",
"Edit(.claude/run.ps1)",
"PowerShell(pwsh -File D:\\Overfit\\.claude\\run.ps1)",
"PowerShell(pwsh -File .claude/run.ps1)",
"PowerShell(pwsh -File *)",
"PowerShell(cmake *)",
"Bash(cmake *)",
"PowerShell($cm = *)",
"PowerShell(& $cm *)",
"PowerShell(& $b *)",
"PowerShell(Set-Location *)",
"PowerShell(cd *)",
"PowerShell(Get-ChildItem *)",
"PowerShell(Get-Content *)"
],
"deny": [
"Bash(git commit *)",
Expand Down
48 changes: 36 additions & 12 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ dotnet_diagnostic.OVERFIT007.severity = suggestion
# PROMOTED TO ERROR (criteria: zero existing sites + unconditional rule + trivial fix/pragma + high miss-cost):
# OVERFIT008 — a suppress leak silently breaks data-parallel training (measured 1.8x); like RS0030.
# OVERFIT015 — CpuFeatures gating is a hard convention; the fix is a one-token change.
dotnet_diagnostic.OVERFIT008.severity = error
dotnet_diagnostic.OVERFIT015.severity = error
# (moved to the [Sources/Main/**.cs] section at the end of this file)
# (moved to the [Sources/Main/**.cs] section at the end of this file)
dotnet_diagnostic.OVERFIT009.severity = suggestion
# Tier A, added 2026-06-13 — start on the bottom rung (suggestion everywhere). Escalate a directory
# once it is swept, exactly like 001-009. 010 (growable collections) and 014 (ToLower compare) are
Expand All @@ -84,24 +84,27 @@ dotnet_diagnostic.OVERFIT010.severity = suggestion
# or a switch expression. Introduced 2026-07-18 against 321 existing occurrences in 124 files, so a
# blanket `error` was not an option — it would have forced one mechanical rewrite across the whole
# library including hot inference paths, which is precisely the unmeasured behaviour-preserving
# refactor this repo forbids. So: SUGGESTION everywhere (IDE-visible, non-blocking), ERROR in directories
# that are already at zero. Sweep a directory -> add it below. Never remove a directory from the list.
# refactor this repo forbids. The sweep is now COMPLETE (322 -> 0 in Sources/Main, and every other project
# except Tests), so the rule is ERROR repo-wide. Tests are exempted at the END of this file: test code is
# throwaway and local, and the argument for the ban (shipped library, read by strangers, hot paths) does not
# apply there. Sources/Benchmark/ElseRefactorBenchmark.cs keeps its `else` behind a #pragma — those forms are
# the measurement subject that justifies the rule.
# Backlog at introduction: LanguageModels 163, Audio 35, Ops 34, Data 13, Onnx 14, DeepLearning 12.
dotnet_diagnostic.OVERFIT021.severity = suggestion
dotnet_diagnostic.OVERFIT021.severity = error

# OVERFIT022 (direct recursion) — NASA Power of 10 rule 1. ERROR EVERYWHERE, deliberately: a .NET
# StackOverflowException cannot be caught, so unbounded recursion is an uncatchable kill of the HOST
# application, and Overfit's whole premise is running inside someone else's process. Every recursive site
# in Sources/Main therefore carries an explicit `#pragma warning disable OVERFIT022` whose comment states
# the BOUND that makes it safe (a checked depth cap, or a structural log2(n) argument). If you cannot write
# that sentence, the recursion is not safe and needs an explicit stack/worklist instead.
dotnet_diagnostic.OVERFIT022.severity = error
# (moved to the [Sources/Main/**.cs] section at the end of this file)

# OVERFIT023 (loop with no exit condition in its header) — NASA Power of 10 rule 2. ERROR EVERYWHERE, same
# contract as OVERFIT022: an unbounded loop hangs the HOST process with no exception, no stack trace and no
# log line, which is the hardest failure of all to diagnose. Every `while (true)` in Sources/Main carries a
# `#pragma warning disable OVERFIT023` whose comment starts with "BOUND:" and names what terminates it.
dotnet_diagnostic.OVERFIT023.severity = error
# (moved to the [Sources/Main/**.cs] section at the end of this file)


dotnet_diagnostic.OVERFIT011.severity = suggestion
Expand All @@ -125,7 +128,7 @@ dotnet_diagnostic.OVERFIT020.severity = suggestion
# fires inside a member or type marked [DevOnBike.Overfit.Diagnostics.OverfitHotPath] is reported as
# this hard error INSTEAD of its directory-configured severity — the per-member ratchet. Always error;
# never loosen it (that would defeat the marker). Suppress a justified site with #pragma + a reason.
dotnet_diagnostic.OVERFIT900.severity = error
# (moved to the [Sources/Main/**.cs] section at the end of this file)

[Sources/Main/Kernels/**.cs]
# Allocation rules are ERRORS in pure kernels — per-call allocation is never right here;
Expand Down Expand Up @@ -228,8 +231,10 @@ dotnet_diagnostic.OVERFIT001.severity = suggestion
[**/obj/**]
dotnet_diagnostic.RS0030.severity = none

# OVERFIT021 (else) — directories already at zero occurrences, locked in as errors. Sweep a directory ->
# add it here. Never remove one.
# OVERFIT021 (else) — Sources/Main is FULLY swept (322 -> 0), so the whole tree is the error scope.
# This replaced a hand-maintained directory list: ten already-clean directories (Diagnostics, Extensions,
# Licensing, Maths, Properties, Redaction, Runtime, Tokenization, Training, Trees) had been swept but never
# added to that list, so the ratchet silently did not hold for them. A whole-tree glob cannot drift.
#
# THREE gotchas, each of which silently produced a rule that looked configured but did nothing (all three
# were hit while wiring this up on 2026-07-18):
Expand All @@ -240,11 +245,30 @@ dotnet_diagnostic.RS0030.severity = none
# 3. The rule ID must NOT appear in <WarningsNotAsErrors> in Directory.Build.props. That maps to
# -warnaserror-:ID, which reverts the diagnostic to warning EVEN WHERE .editorconfig sets error —
# defeating this whole section. (This is why OVERFIT008/015 are absent from that list.)
[Sources/Main/{Anomalies,Core,Exceptions,Inference,Parameters,Randomization,Serving,Statistical,Tensors}/**.cs]
dotnet_diagnostic.OVERFIT021.severity = error

# OVERFIT022 (recursion) — ERROR on the paths that parse untrusted, externally-authored input, where an
# uncatchable stack overflow would kill the embedding host. Existing bounded sites carry a #pragma naming
# their depth cap; this stops NEW unbounded recursion from entering these directories.
[Sources/Main/LanguageModels/{Loading,Constraints}/**.cs]
dotnet_diagnostic.OVERFIT022.severity = error

# OVERFIT021 (else) — Tests are the one exemption: test code is local and disposable, so the ban's rationale
# (shipped library, read by strangers, hot paths) does not apply. Kept at suggestion so it still shows in the
# IDE. MUST stay at the END of this file — a [section] header scopes every setting below it.
[Tests/**.cs]
dotnet_diagnostic.OVERFIT021.severity = suggestion

# ── Library-only OVERFIT rules ─────────────────────────────────────────────────────────────
# These were designed for the SHIPPED library: zero-alloc hot paths (OVERFIT008/900), the CpuFeatures
# convention (015), and the NASA bounded-execution pair (022/023, whose rationale is "Overfit runs inside
# someone else's process"). Once the analyzer was wired into every project they also started firing in
# benchmarks and demos, where they are wrong by construction — Sources/Benchmark deliberately calls raw
# Parallel.For to A/B it against OverfitParallel, and OverfitParallelLegacy is a kept-for-comparison copy.
# So they are scoped to the library; OVERFIT021 (else) stays repo-wide because readability is not scoped.
[Sources/Main/**.cs]
dotnet_diagnostic.OVERFIT008.severity = error
dotnet_diagnostic.OVERFIT015.severity = error
dotnet_diagnostic.OVERFIT024.severity = warning
dotnet_diagnostic.OVERFIT022.severity = error
dotnet_diagnostic.OVERFIT023.severity = error
dotnet_diagnostic.OVERFIT900.severity = error
15 changes: 13 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,13 +234,24 @@ Every perf change is a **hypothesis until measured**. Benchmark before/after wit
**negative results** honestly — they are the most valuable output: in this codebase
register-blocking (direct-conv), K-blocking + A-packing (im2col GEMM), Winograd F(2,3) for 3x3 stride-1
convs (parity-correct cos 1.0 but +79% slower on deepcnn, 119.7→214.4 ms — sequential scalar transforms +
16 small GEMMs + 16x U/V/M blow-up beat the 2.25x FLOP cut), the AVX-512 decode port, and
`OverfitPool<T>` all **regressed or tied and were reverted**; the wins were the *opposite* of the
16 small GEMMs + 16x U/V/M blow-up beat the 2.25x FLOP cut), the AVX-512 decode port, bias support in
the Q4_K tiled prefill GEMM (`GemmTiled` — a path census showed `bias.IsEmpty` barred 88% of prefill
dispatches, i.e. all attention Q/K/V, from the tiled kernel; lifting it measured **0.999x, an exact
tie**, because `ProjectBatchedWeightStationary` already amortises weight decode across the row tile —
the same thing the tiling does; the "~3x" in the kernel docs is against re-decode-per-row, not against
weight-stationary), and `OverfitPool<T>` all **regressed or tied and were reverted**; the wins were the *opposite* of the
"obvious" move (`TensorPrimitives` bulk-SIMD beat a hand micro-kernel; the simple register-blocked
GEMM beat the cache-blocked one — structure of the data around the technique decides, not the
technique). Mind the **measurement environment**: a thermally-throttled or loaded box invalidates
A/B (detect it with a *canary* — re-measure an unchanged code path; if it shifted, the box did, not
your change). The decode spin-pool assumes dedicated cores, so it is sensitive to background load.
Two corollaries this repo has paid for. **Cross-process before/after does not work here**: a prefill
change read as +5% while the untouched decode path in the same run moved +32% — interleave the
configurations run-by-run in ONE process (ABAB…, not all-A-then-all-B) and time a canary path in
every sample. **Verify the flag you are A/B-ing is actually live**: `OVERFIT_TILED_PREFILL` is a dead
flag whenever a `*.gguf.repack` sidecar sits next to the model, because `IsPrepacked` short-circuits
it — both arms ran an identical mix and the "measurement" was noise. Count the paths taken (a
temporary counter in the dispatcher) before believing any kernel A/B.
Never ship, claim, or commit a perf "win" you have not measured on a stable box — and prefer
measuring over reasoning even when the reasoning feels airtight.

Expand Down
3 changes: 2 additions & 1 deletion Demo/AgentDemo/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// DevonBike Overfit is licensed under the GNU AGPLv3.
// For commercial licensing options, contact: devonbike@gmail.com

using DevOnBike.Overfit.Runtime;
using System.Text.Json;
using DevOnBike.Overfit.LanguageModels.Chat;
using DevOnBike.Overfit.LanguageModels.Constraints;
Expand All @@ -28,7 +29,7 @@ internal static class Program
{
private static int Main()
{
var dir = Environment.GetEnvironmentVariable("OVERFIT_MODEL_DIR") ?? @"C:\qwen3b";
var dir = Environment.GetEnvironmentVariable(OverfitEnvironment.ModelDir) ?? @"C:\qwen3b";
var ggufPath = ResolveGguf(dir);
if (ggufPath is null)
{
Expand Down
3 changes: 2 additions & 1 deletion Demo/AgentFrameworkDemo/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
//
// Verified against Microsoft.Agents.AI 1.13.0 + DevOnBike.Overfit 10.0.x on a Qwen2.5-0.5B Q4_K_M.

using DevOnBike.Overfit.Runtime;
using DevOnBike.Overfit.Extensions.AI;
using DevOnBike.Overfit.LanguageModels;
using Microsoft.Agents.AI;
Expand All @@ -26,7 +27,7 @@ public static async Task<int> Main(string[] args)
{
var modelPath = args.Length > 0
? args[0]
: Environment.GetEnvironmentVariable("OVERFIT_MODEL_PATH");
: Environment.GetEnvironmentVariable(OverfitEnvironment.ModelPath);

if (string.IsNullOrWhiteSpace(modelPath) || !File.Exists(modelPath))
{
Expand Down
17 changes: 12 additions & 5 deletions Demo/AnomalyConsoleDemo/Program.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// Copyright (c) 2026 DevOnBike.
// Copyright (c) 2026 DevOnBike.
// This file is part of DevonBike Overfit.
// DevonBike Overfit is licensed under the GNU AGPLv3.
// For commercial licensing options, contact: devonbike@gmail.com

using DevOnBike.Overfit.Runtime;
using DevOnBike.Overfit.Anomalies.Adaptive;
using DevOnBike.Overfit.Anomalies.Baseline;
using DevOnBike.Overfit.Anomalies.Gpt;
Expand Down Expand Up @@ -54,7 +55,8 @@ private static async Task<int> Main(string[] args)
{
RunMultiPodAdaptiveScenario(model);
}
else

if (!(HasFlag(args, "--multipod")))
{
RunScenario(model, config);
}
Expand All @@ -73,7 +75,11 @@ private static async Task<int> Main(string[] args)
private static async Task<(GPT1Model model, GptTrainingConfig config)> GetModelAsync(
string? csv, string checkpoint, GptTrainingConfig config)
{
if (!File.Exists(checkpoint))
// Capture BEFORE training: RunAsync WRITES the checkpoint, so a second File.Exists test would
// see the file it just produced and announce "Loading checkpoint" right after training one.
var hadCheckpoint = File.Exists(checkpoint);

if (!hadCheckpoint)
{
if (csv is null || !File.Exists(csv))
{
Expand All @@ -95,7 +101,8 @@ private static async Task<int> Main(string[] args)
Console.WriteLine($"Trained: {result.SnapshotsLoaded:N0} snapshots, " +
$"val loss {result.InitialLoss:F2} → {result.FinalValLoss:F2}, {result.TrainingTime:mm\\:ss}.");
}
else

if (hadCheckpoint)
{
Console.WriteLine($"Loading {config.DModel}d/{config.NLayers}L checkpoint {checkpoint} ...");
}
Expand Down Expand Up @@ -463,7 +470,7 @@ private static bool HasFlag(string[] args, string name)
return explicitPath;
}

var dir = Environment.GetEnvironmentVariable("OVERFIT_MODEL_DIR");
var dir = Environment.GetEnvironmentVariable(OverfitEnvironment.ModelDir);
var candidates = new[]
{
dir is null ? null : Path.Combine(dir, "k8s_metrics.csv"),
Expand Down
3 changes: 2 additions & 1 deletion Demo/EvaluationDemo/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
// judgments; the evaluator prompts are tuned against GPT-4o-class models, so treat small local
// judges (<7B) as a demo of the PLUMBING, not a calibrated quality gate.

using DevOnBike.Overfit.Runtime;
using DevOnBike.Overfit.Demo.Evaluation;
using DevOnBike.Overfit.Extensions.AI;
using DevOnBike.Overfit.LanguageModels;
Expand All @@ -22,7 +23,7 @@

var modelPath = args.Length > 0
? args[0]
: Environment.GetEnvironmentVariable("OVERFIT_JUDGE") ?? @"C:\qwen3b\qwen.q4km.gguf";
: Environment.GetEnvironmentVariable(OverfitEnvironment.Judge) ?? @"C:\qwen3b\qwen.q4km.gguf";

if (!File.Exists(modelPath))
{
Expand Down
3 changes: 2 additions & 1 deletion Demo/Gpt2ConsoleDemo/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// DevonBike Overfit is licensed under the GNU AGPLv3.
// For commercial licensing options, contact: devonbike@gmail.com

using DevOnBike.Overfit.Runtime;
using System.Diagnostics;
using DevOnBike.Overfit.DeepLearning;
using DevOnBike.Overfit.LanguageModels;
Expand Down Expand Up @@ -178,7 +179,7 @@ private static string ResolvePath(string? cliValue, string fileName)
}

// 2. $OVERFIT_MODEL_DIR/<fileName>
var envDir = Environment.GetEnvironmentVariable("OVERFIT_MODEL_DIR");
var envDir = Environment.GetEnvironmentVariable(OverfitEnvironment.ModelDir);
if (!string.IsNullOrWhiteSpace(envDir))
{
var fromEnv = Path.Combine(envDir, fileName);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2026 DevOnBike.
// Copyright (c) 2026 DevOnBike.
// This file is part of DevonBike Overfit.
// DevonBike Overfit is licensed under the GNU AGPLv3.
// For commercial licensing options, contact: devonbike@gmail.com
Expand Down Expand Up @@ -36,7 +36,8 @@ public ApiKeyAuthMiddleware(RequestDelegate next, IConfiguration configuration,
logger.LogWarning(
"API-key auth is OFF — any caller can reach the agent. Set 'ApiKey' (config or env) before exposing it.");
}
else

if (!(string.IsNullOrWhiteSpace(key)))
{
_keyHash = SHA256.HashData(Encoding.UTF8.GetBytes(key.Trim()));
logger.LogInformation("API-key auth is ON — callers must present 'X-API-Key' or 'Authorization: Bearer'.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
// DevonBike Overfit is licensed under the GNU AGPLv3.
// For commercial licensing options, contact: devonbike@gmail.com

using DevOnBike.Overfit.Runtime;

namespace DevOnBike.Overfit.Demo.LocalAgent.Infrastructure
{
internal static class ModelPathResolver
Expand All @@ -25,7 +27,7 @@ public static string Resolve(IConfiguration config)
}

// 2) Env var `OVERFIT_MODEL_DIR` — a directory; prefer a *.gguf inside, else model.safetensors.
var fromEnv = Environment.GetEnvironmentVariable("OVERFIT_MODEL_DIR");
var fromEnv = Environment.GetEnvironmentVariable(OverfitEnvironment.ModelDir);
if (!string.IsNullOrWhiteSpace(fromEnv) && Directory.Exists(fromEnv))
{
var ggufs = Directory.GetFiles(fromEnv, "*.gguf");
Expand Down
8 changes: 5 additions & 3 deletions Demo/LocalAgentAspNetDemo/Rag/RagService.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// Copyright (c) 2026 DevOnBike.
// Copyright (c) 2026 DevOnBike.
// This file is part of DevonBike Overfit.
// DevonBike Overfit is licensed under the GNU AGPLv3.
// For commercial licensing options, contact: devonbike@gmail.com

using DevOnBike.Overfit.Runtime;
using System.Diagnostics;
using System.Security.Cryptography;
using System.Text;
Expand Down Expand Up @@ -260,7 +261,8 @@ private void TrySaveCache(PersistentVectorStore store, string cachePath, float[]
File.Delete(meanPath);
}
}
else

if (!(mean is null))
{
using var stream = new FileStream(meanPath, FileMode.Create, FileAccess.Write);
using var writer = new BinaryWriter(stream);
Expand Down Expand Up @@ -512,7 +514,7 @@ private string ResolveEmbeddingDir()
}

// 2) Env var OVERFIT_EMBEDDING_DIR.
var fromEnv = Environment.GetEnvironmentVariable("OVERFIT_EMBEDDING_DIR");
var fromEnv = Environment.GetEnvironmentVariable(OverfitEnvironment.EmbeddingDir);
if (!string.IsNullOrWhiteSpace(fromEnv) && Directory.Exists(fromEnv))
{
return fromEnv;
Expand Down
Loading
Loading