@remnic/bench 9.3.710 → 9.3.712
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +57 -0
- package/baselines/coding-graph-baseline.json +30 -0
- package/dist/index.d.ts +328 -5
- package/dist/index.js +421 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -200,3 +200,60 @@ If you're an AI agent extending a Remnic-based stack: **do not** import `@remnic
|
|
|
200
200
|
## License
|
|
201
201
|
|
|
202
202
|
MIT. See the root [LICENSE](https://github.com/joshuaswarren/remnic/blob/main/LICENSE) file.
|
|
203
|
+
|
|
204
|
+
## Coding-graph benchmark harness (issue #1557)
|
|
205
|
+
|
|
206
|
+
A dedicated benchmark suite for [`@remnic/coding-graph`](https://www.npmjs.com/package/@remnic/coding-graph) — the symbol-extraction engine + SQLite knowledge-graph store for codebase memory. The harness is the authority for every performance claim: no number ships in docs without a harness measurement behind it (rule 55, #1527 stub-honesty).
|
|
207
|
+
|
|
208
|
+
### What it measures
|
|
209
|
+
|
|
210
|
+
| Metric | Description |
|
|
211
|
+
|---|---|
|
|
212
|
+
| `fullIndexMs` | Wall time to index the entire fixture in one batch. |
|
|
213
|
+
| `fullIndexLocsPerSecond` | Sustained LOC/s during full index (higher is better). |
|
|
214
|
+
| `incrementalUpdateP50Ms` / `incrementalUpdateP95Ms` | Single-file re-ingest latency (p50/p95 over ≥20 iterations). |
|
|
215
|
+
| `tracePathP95Ms` | `trace_path` (BFS, depth ≤ 5) p95. |
|
|
216
|
+
| `searchGraphP95Ms` | `search_graph` name-pattern p95. |
|
|
217
|
+
| `deadCodeMs` | Dead-code query wall time. |
|
|
218
|
+
| `dbBytesPerKloc` | SQLite DB bytes per KLOC after index. |
|
|
219
|
+
|
|
220
|
+
### Synthetic fixture generator
|
|
221
|
+
|
|
222
|
+
The harness ships a **deterministic** synthetic repo generator (`generateSyntheticRepo`): parameterized by files × symbols-per-file × call-density × language. Same seed + same params always produces byte-identical IR output (rule 38). Fixtures are synthetic code only — no real repos, no user data (public-repo policy).
|
|
223
|
+
|
|
224
|
+
### Baseline + regression gate
|
|
225
|
+
|
|
226
|
+
The measured numbers live in [`baselines/coding-graph-baseline.json`](./baselines/coding-graph-baseline.json) — bench-owned, separate from the structural ratchets in `scripts/ratchet-baseline.json`. The regression gate (`checkCodingGraphRegression`) compares a report against the baseline with a generous tolerance (default 30%). It hard-fails on gross regression — a real failing step, not a warning (rule 50). Tightening the baseline is a deliberate PR act (mirrors `check-ratchets --update`).
|
|
227
|
+
|
|
228
|
+
### Measured numbers (first baseline)
|
|
229
|
+
|
|
230
|
+
> Numbers below are from the **baseline JSON file** — this section is checked against it so prose can't drift from measurement. Run `remnic bench coding-graph` to reproduce.
|
|
231
|
+
|
|
232
|
+
| Metric | Value | Machine |
|
|
233
|
+
|---|---|---|
|
|
234
|
+
| Full index | ~17.6 ms, ~115k LOC/s | Apple M2 Max, Node v22 |
|
|
235
|
+
| Incremental update p95 | ~0.26 ms | Apple M2 Max |
|
|
236
|
+
| trace_path p95 | ~0.14 ms | Apple M2 Max |
|
|
237
|
+
| search_graph p95 | ~0.29 ms | Apple M2 Max |
|
|
238
|
+
| dead_code | ~0.67 ms | Apple M2 Max |
|
|
239
|
+
| DB size | ~2 KB/KLOC | Apple M2 Max |
|
|
240
|
+
|
|
241
|
+
These are **working targets on a small fixture (20 files, 200 symbols)**, NOT parity claims against codebase-memory-mcp's published numbers (28M LOC in 3 min, <1ms Cypher). Scale targets at 1M+ LOC are tracked as stretch goals — the harness will measure them when Tier-L fixtures are wired (issue #1557 PR2).
|
|
242
|
+
|
|
243
|
+
### Usage
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
import { runCodingGraphBenchmark, checkCodingGraphRegression } from "@remnic/bench";
|
|
247
|
+
|
|
248
|
+
const report = await runCodingGraphBenchmark({
|
|
249
|
+
fixture: { fileCount: 1000, symbolsPerFile: 10, callDensity: 0.2 },
|
|
250
|
+
iterations: 25,
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
const baseline = require("@remnic/bench/baselines/coding-graph-baseline.json");
|
|
254
|
+
const gate = checkCodingGraphRegression(report, baseline, 30);
|
|
255
|
+
if (!gate.passed) {
|
|
256
|
+
console.error(gate.summary);
|
|
257
|
+
process.exit(1);
|
|
258
|
+
}
|
|
259
|
+
```
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"machine": {
|
|
4
|
+
"arch": "arm64",
|
|
5
|
+
"platform": "darwin",
|
|
6
|
+
"nodeVersion": "v22.20.0",
|
|
7
|
+
"cpuModel": "Apple M2 Max",
|
|
8
|
+
"cpuCores": 12,
|
|
9
|
+
"totalMemoryMb": 98304
|
|
10
|
+
},
|
|
11
|
+
"fixtureConfig": {
|
|
12
|
+
"seed": 42,
|
|
13
|
+
"fileCount": 20,
|
|
14
|
+
"symbolsPerFile": 10,
|
|
15
|
+
"callDensity": 0.3,
|
|
16
|
+
"language": "typescript"
|
|
17
|
+
},
|
|
18
|
+
"metrics": {
|
|
19
|
+
"fullIndexMs": 14.864042000000154,
|
|
20
|
+
"fullIndexLocsPerSecond": 136302,
|
|
21
|
+
"incrementalUpdateP50Ms": 0.19358299999998962,
|
|
22
|
+
"incrementalUpdateP95Ms": 0.26237500000002,
|
|
23
|
+
"tracePathP95Ms": 0.15750000000002728,
|
|
24
|
+
"searchGraphP95Ms": 0.19700000000011642,
|
|
25
|
+
"deadCodeMs": 2.29424999999992,
|
|
26
|
+
"dbBytesPerKloc": 280636
|
|
27
|
+
},
|
|
28
|
+
"createdAt": "2026-07-06T10:50:56.821Z",
|
|
29
|
+
"note": "Initial baseline — first harness run with WAL-aware DB sizing (issue #1557 PR1)."
|
|
30
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -487,7 +487,7 @@ interface SavedBaseline {
|
|
|
487
487
|
timestamp: string;
|
|
488
488
|
metrics: Record<string, number>;
|
|
489
489
|
}
|
|
490
|
-
interface RegressionGateResult {
|
|
490
|
+
interface RegressionGateResult$1 {
|
|
491
491
|
passed: boolean;
|
|
492
492
|
regressions: RegressionDetail[];
|
|
493
493
|
}
|
|
@@ -2276,7 +2276,7 @@ declare function loadBaseline(baselinePath?: string): SavedBaseline | undefined;
|
|
|
2276
2276
|
declare function saveBaseline(baselinePath: string, baseline: SavedBaseline): void;
|
|
2277
2277
|
declare function runExplain(service: EngramAccessService, query: string): Promise<ExplainResult>;
|
|
2278
2278
|
declare function runBenchSuite(service: EngramAccessService, config?: BenchConfig): Promise<BenchmarkSuiteResult>;
|
|
2279
|
-
declare function checkRegression(metrics: Record<string, number>, baseline: SavedBaseline | undefined, tolerance: number): RegressionGateResult;
|
|
2279
|
+
declare function checkRegression(metrics: Record<string, number>, baseline: SavedBaseline | undefined, tolerance: number): RegressionGateResult$1;
|
|
2280
2280
|
declare function generateReport(results: RecallMetrics[], reportPath?: string): BenchmarkReport;
|
|
2281
2281
|
|
|
2282
2282
|
/**
|
|
@@ -2785,7 +2785,7 @@ interface SeededRng {
|
|
|
2785
2785
|
* Deterministic 32-bit PRNG. Mulberry32 is small, fast, and sufficient for
|
|
2786
2786
|
* shuffling benchmark tasks. Do NOT use for cryptographic operations.
|
|
2787
2787
|
*/
|
|
2788
|
-
declare function createSeededRng$
|
|
2788
|
+
declare function createSeededRng$2(seed: number): SeededRng;
|
|
2789
2789
|
/**
|
|
2790
2790
|
* Fisher-Yates shuffle using a seeded PRNG. Returns a new array.
|
|
2791
2791
|
*/
|
|
@@ -3705,7 +3705,7 @@ interface ExtractionAttackResult {
|
|
|
3705
3705
|
/**
|
|
3706
3706
|
* Tiny mulberry32 PRNG — stable across Node versions.
|
|
3707
3707
|
*/
|
|
3708
|
-
declare function createSeededRng(seed: number): HarnessRng;
|
|
3708
|
+
declare function createSeededRng$1(seed: number): HarnessRng;
|
|
3709
3709
|
/**
|
|
3710
3710
|
* Entry point. See `types.ts` for the options contract.
|
|
3711
3711
|
*/
|
|
@@ -3873,4 +3873,327 @@ interface MitigatedTargetConfig {
|
|
|
3873
3873
|
*/
|
|
3874
3874
|
declare function createMitigatedTarget(config: MitigatedTargetConfig): ExtractionAttackTarget;
|
|
3875
3875
|
|
|
3876
|
-
export { AMA_BENCH_DIAGNOSTIC_VARIANTS, ASSISTANT_AGENT_CONFIG_KEY, ASSISTANT_JUDGE_CONFIG_KEY, ASSISTANT_MEETING_PREP_SCENARIOS, ASSISTANT_MEETING_PREP_SMOKE_SCENARIOS, ASSISTANT_MORNING_BRIEF_SCENARIOS, ASSISTANT_MORNING_BRIEF_SMOKE_SCENARIOS, ASSISTANT_NEXT_BEST_ACTION_SCENARIOS, ASSISTANT_NEXT_BEST_ACTION_SMOKE_SCENARIOS, ASSISTANT_RUBRIC_DIMENSIONS, ASSISTANT_RUBRIC_ID_KEY, ASSISTANT_SEEDS_CONFIG_KEY, ASSISTANT_SPOT_CHECK_DIR_KEY, ASSISTANT_SYNTHESIS_SCENARIOS, ASSISTANT_SYNTHESIS_SMOKE_SCENARIOS, type AbstentionRetrievalCase, type AggregateMetrics, type AmaBenchDiagnosticAdapterOptions, type AmaBenchDiagnosticAnswererMode, type AmaBenchDiagnosticBreakdown, type AmaBenchDiagnosticMatrixArtifact, type AmaBenchDiagnosticRecallMode, type AmaBenchDiagnosticRunContext, type AmaBenchDiagnosticTaskEvidence, type AmaBenchDiagnosticTaskRow, type AmaBenchDiagnosticVariant, type AmaBenchDiagnosticVariantSummary, type AnthropicProviderConfig, type AssistantAgent, type AssistantMemoryFact, type AssistantMemoryGraph, type AssistantRubricDimension, type AssistantRubricScores, type AssistantRunnerOptions, type AssistantScenario, type AssistantStance, type AttackRecallOptions, type AttackRetrievalHit, type AttackerMode, BENCHMARK_ARTIFACT_SCHEMA_VERSION, BENCHMARK_INTEGRITY_META_SCHEMA, BENCHMARK_REPRO_MANIFEST_FILENAME, BENCHMARK_REPRO_MANIFEST_SCHEMA_VERSION, BENCHMARK_RESULT_SCHEMA, BENCHMARK_SPLIT_TYPES, type BaselineRow, type BaselineScenario, type BeamDatasetPreview, type BenchConfig, type BenchJudge, type BenchJudgeResult, type BenchMemoryAdapter, type BenchModelSource, type BenchReasoningEffort, type BenchRecallOptions, type BenchResponder, type BenchResponse, type BenchRuntimeProfile, type BenchTier, type BenchmarkArtifact, type BenchmarkArtifactEnvironment, type BenchmarkArtifactHardware, type BenchmarkArtifactJudgeCalibration, type BenchmarkArtifactPerTaskScore, type BenchmarkArtifactSystem, type BenchmarkArtifactTier, type BenchmarkCategory, type BenchmarkDefinition, type BenchmarkIntegrityMeta, type BenchmarkMeta, type BenchmarkMode, type BenchmarkReport, type BenchmarkReproManifest, type BenchmarkReproManifestDataset, type BenchmarkReproManifestFile, type BenchmarkReproManifestResult, type BenchmarkResult, type BenchmarkSplitType, type BenchmarkStatus, type BenchmarkSuiteResult, type BenchmarkTier, type BuildBenchmarkArtifactInput, type BuildBenchmarkPublishFeedOptions, type BuildBenchmarkReproManifestOptions, type BuiltInProvider, CALIBRATION_SLICE_SIZE, CANARY_FIXED_RECALL, CANARY_SCORE_FLOOR, type CalibrationAnswer, type CalibrationVerdictPair, type CanaryAdapterOptions, type CanaryFloorCheck, type CodexCliProviderConfig, type CohenKappaResult, type ComparisonMetricDelta, type ComparisonResult, type CompletionOpts, type CompletionResult, type ConfidenceInterval, type ContaminationCheckResult, type ContaminationEntry, type ContaminationManifest, type CustomBenchmarkScoring, type CustomBenchmarkSpec, type CustomBenchmarkTask, DEFAULT_ABLATION_BOOTSTRAP_SEED, DEFAULT_ASSISTANT_RUBRIC_ID, DEFAULT_BASELINE_SCENARIOS, DEFAULT_JUDGE_BINARIZATION_THRESHOLD, type DatasetSource, type DiscoveredModel, EMPTY_CONTAMINATION_MANIFEST, type EffectSizeInterpretation, type EffectSizeSummary, type ExplainResult, type ExtractedEntity, type ExtractedLink, type ExtractedPage, type ExtractionAttackOptions, type ExtractionAttackResult, type ExtractionAttackTarget, type FixtureGenerator, type FixtureOutput, type FixtureVariant, type GeneratedFile, type GoldEntity, type GoldEntityType, type GoldGraph, type GoldLink, type GoldPage, type HarnessRng, INTEGRITY_CIPHER_ALGORITHM, INTEGRITY_HASH_ALGORITHM, INTEGRITY_META_FIELDS, type IngestionBenchAdapter, type IngestionLog, JUDGE_CALIBRATION_KAPPA_THRESHOLD, type JudgeCalibrationIdentities, type JudgeCalibrationResult, type JudgeCategory, LOCAL_LAB_PROVIDER_KINDS, LOCOMO_DATASET_FILENAMES, LONG_MEM_EVAL_DATASET_FILENAMES, type LeaderboardArtifactWrite, type LlmJudge, type LlmProvider, type LoadDatasetOptions, type LoadSealedQrelsOptions, type LoadedDataset, type LoadedJudgeCalibrationState, type LocalLabManifest, type LocalLabManifestNotes, type LocalLabPhase, type LocalLabPhaseDescriptor, type LocalLabPhaseExecute, type LocalLabPhaseName, type LocalLabPhaseOutcome, LocalLabPreflightError, type LocalLabPreflightFailure, type LocalLabPreflightInput, type LocalLabPreflightOptions, type LocalLabPreflightResult, type LocalLabPreflightSuccess, type LocalLabProviderKind, type LocalLabRoleConfig, type LocalLlmProviderConfig, MEMORY_EVAL_DIMENSIONS, MEMORY_EVAL_PUBLIC_LINE, MIN_CALIBRATION_SOURCE_TASKS, MITIGATED_BASELINE_SCENARIOS, type MemCorrectGeneratorOptions, type MemCorrectSystemAdapter, type MemoryEvalCategory, type MemoryEvalDimension, type MemoryEvalDimensionId, type MemoryEvalMetric, type MemoryGraph, type MemoryStats, type MemorySystem, type Message, type MetricAggregate, type MitigatedBaselineConfig, type MitigatedTargetConfig, type MultipleChoiceQuestion, OTHER_NAMESPACE_MEMORIES, type OllamaProviderConfig, type OpenAiCompatibleProviderConfig, PROCEDURAL_REAL_SCENARIOS, PROCEDURAL_REAL_SCENARIOS_SMOKE, PUBLISHED_BENCHMARK_ARTIFACT_IDS, type PersonalizationRetrievalCase, type PreflightDiscoveredModel, type ProceduralAblationArtifact, type ProceduralAblationPerCase, type ProceduralAblationScenario, type ProceduralRealScenario, type ProceduralRealScenarioCategory, type ProviderBaseConfig, type ProviderConfig, type ProviderDiscoveryResult, type ProviderFactoryConfig, type PublishSkipReason, type PublishSkipRecord, type PublishedBenchmarkFeed, type PublishedBenchmarkFeedEntry, type PublishedBenchmarkId, REQUIRED_FRONTMATTER_FIELDS, type RecallMetrics, type RecoveredMemory, type RegressionDetail, type RegressionGateResult, type RemnicAdapterOptions, type ResolveBenchRuntimeProfileOptions, type ResolvedBenchRuntimeProfile, type ResolvedLocalLabProfile, type ResolvedLocalLabRole, type ResolvedRunBenchmarkOptions, type RotatedChoices, type RunBenchmarkOptions, type RunJudgeCalibrationOptions, type RunProceduralAblationCliArgs, type RunProceduralAblationOptions, type RunSequentialPhasesOptions, SCHEMA_TIER_FIXTURE, SCHEMA_TIER_SMOKE_FIXTURE, SEALED_PROMPT_REGISTRY, SYNTHETIC_MEMORIES, type SanitizedDiagnosticProvider, type SavedBaseline, type SchemaTierCorpus, type SchemaTierFixture, type SchemaTierName, type SchemaTierPage, type SchemaTierPageFrontmatter, type SealedArtifact, type SealedJudgeDecision, type SealedJudgeInput, type SealedQrelsArtifact, type SealedQrelsHandle, type SealedRubric, type SearchResult, type SeededMemory, type SeededRng, type SequentialPhaseHooks, type SpotCheckLogger, type StatisticalReport, type StructuredJudge, type SyntheticEmailIngestionAdapterOptions, type SyntheticTargetOptions, type TaskResult, type TaskTokenUsage, type TemporalRetrievalCase, type TierDetail, type TimelineEntry, type TokenUsage, type WriteBenchmarkArtifactResult, addContaminationEntry, aggregateTaskScores, answerBenchmarkQuestion, assertCanaryUnderFloor, assertIntegrityMetaPresent, assertPublishableIntegrity, assertSha256Hex, assistantMeetingPrepDefinition, assistantMorningBriefDefinition, assistantNextBestActionDefinition, assistantSynthesisDefinition, backlinkF1, binarizeJudgeScore, bootstrapMeanConfidenceInterval, buildAmaBenchDiagnosticMatrixArtifact, buildAmaBenchDiagnosticVariantSummary, buildAmaBenchLeaderboardRows, buildBenchmarkArtifact, buildBenchmarkArtifactFilename, buildBenchmarkPublishFeed, buildBenchmarkReproManifest, buildBenchmarkRunSeeds, buildJudgePayload, buildOracleTrajectoryRecall, buildSchemaTierFixture, buildSchemaTierSmokeFixture, calendarFixture, canonicalJsonStringify, chatFixture, checkDatasetContamination, checkRegression, clampScore, cohensD, compareResults, computeCohensKappa, computeSealHash, containsAnswer, createSeededRng as createAdamSeededRng, createAmaBenchDiagnosticAdapter, createAnthropicProvider, createCanaryAdapter, createCodexCliProvider, createDeterministicSpotCheckLogger, createGatewayResponder, createLightweightAdapter, createLiteLlmProvider, createLocalLlmProvider, createMitigatedTarget, createOllamaProvider, createOpenAiCompatibleProvider, createSeededRandom as createProceduralAblationSeededRandom, createProvider, createProviderBackedAmaBenchRecommendedJudge, createProviderBackedJudge, createProviderBackedResponder, createProviderBackedStructuredJudge, createRemnicAdapter, createResponderFromProvider, createSeededRng$1 as createSeededRng, createSpotCheckFileLogger, createStructuredJudgeFromProvider, createSyntheticEmailIngestionAdapter, createSyntheticTarget, createTimeoutGuardedAdapter, defaultBenchmarkBaselineDir, defaultBenchmarkPublishPath, deleteBenchmarkResults, discoverAllProviders, discoveryEndpointFor, emailFixture, entityRecall, exactMatch, extractMarkdownSectionsByTitle, f1Score, fixtureToAblationScenarios, formatHandoffNote, formatMissingDatasetError, generateReport, getBenchmark, getBenchmarkLowerIsBetter, getMemoryEvalDimension, getRemnicVersion, hashBenchmarkArtifact, hashBytes, hashCanonicalJson, hashString, integrityMetaIsComplete, interpretEffectSize, isAmaBenchUnknownLikeAnswer, isContaminationEntry, isContaminationManifest, isSealedQrelsArtifact, isSha256Hex, linkMatches, listBenchmarkBaselines, listBenchmarkResults, listBenchmarks, listMemoryEvalBenchmarkIds, listMemoryEvalDimensions, llmJudgeScore, llmJudgeScoreDetailed, loadAblationFixture, loadBaseline, loadBeamDatasetPreview, loadBenchmarkArtifact, loadBenchmarkBaseline, loadBenchmarkResult, loadCustomBenchmarkFile, loadJudgeCalibrationState, loadLoCoMo10, loadLocalLabManifest, loadLongMemEvalS, loadSealKeyFromEnv, loadSealedQrels, loadSealedRubric, matchEntity, mergeContaminationManifests, openSeal, orchestrateBenchmarkRuns, pairedDeltaConfidenceInterval, parseBenchmarkArtifact, parseCustomBenchmark, parseLocalLabManifest, parseRubricResponse, parseSealedQrels, precisionAtK, preflightLocalLabRole, projectFolderFixture, recallAtK, redactBenchmarkResultSecrets, renderBaselineMarkdown, renderBenchmarkResultExport, renderMemorySummaryForJudge, renderMemoryViewForAgent, resolveAssistantAgent, resolveAssistantRubricId, resolveAssistantSeeds, resolveAssistantSpotCheckDir, resolveBenchRuntimeProfile, resolveBenchmarkPhaseTimeoutMs, resolveBenchmarkProgressLogging, resolveBenchmarkResultReference, resolveBenchmarkRunCount, resolveLocalLabProfile, resolveLocalLabRole, resolveStructuredJudge, rotateDistractors, rougeL, runAssistantBenchmark, runAssistantMeetingPrepBenchmark, runAssistantMorningBriefBenchmark, runAssistantNextBestActionBenchmark, runAssistantSynthesisBenchmark, runBaseline, runBenchSuite, runBenchmark, runCustomBenchmarkFile, runExplain, runExtractionAttack, runJudgeCalibration, runMitigatedBaseline, runProceduralAblation, runProceduralAblationCli, runSealedJudge, runSequentialPhases, safeHexEqual, saveBaseline, saveBenchmarkBaseline, schemaCompleteness, sealPayload, selectAmaBenchDiagnosticVariants, selectCalibrationSlice, selectFixtureVariant, serializeBenchmarkArtifact, serializeJsonl, serializeSealedQrels, shuffleTasks, timed, verifyRubricDigest, writeBenchmarkArtifact, writeBenchmarkPublishFeed, writeBenchmarkReproManifest, writeBenchmarkResult, writeJudgeCalibrationState, writeLeaderboardArtifactsForResult, zeroScores };
|
|
3876
|
+
/**
|
|
3877
|
+
* Coding-graph benchmark types (issue #1557).
|
|
3878
|
+
*
|
|
3879
|
+
* These types define the metric report shape, the benchmark configuration,
|
|
3880
|
+
* and the regression-gate contract. The harness writes a {@link CodingGraphBenchReport};
|
|
3881
|
+
* the regression step compares it against a tracked {@link CodingGraphBaseline}.
|
|
3882
|
+
*
|
|
3883
|
+
* Design rules (from the issue):
|
|
3884
|
+
* - Metrics are recorded as a tracked baseline (same philosophy as
|
|
3885
|
+
* scripts/ratchet-baseline.json), NOT inline thresholds.
|
|
3886
|
+
* - The comparison step hard-fails on gross regression (rule 50) with a
|
|
3887
|
+
* generous tolerance — perf thresholds in CI flake.
|
|
3888
|
+
* - Every metric that enters the report must have a plausible type so
|
|
3889
|
+
* the smoke test can assert presence without knowing exact values.
|
|
3890
|
+
* - The report includes a machine fingerprint so baselines are comparable
|
|
3891
|
+
* across runs (the issue calls this out explicitly).
|
|
3892
|
+
*/
|
|
3893
|
+
/**
|
|
3894
|
+
* Parameters for the deterministic synthetic repo generator. Same seed +
|
|
3895
|
+
* same params → byte-identical IR output (rule 38 — generator determinism).
|
|
3896
|
+
*/
|
|
3897
|
+
interface SyntheticRepoConfig {
|
|
3898
|
+
/** PRNG seed — same seed + params = identical output. */
|
|
3899
|
+
readonly seed: number;
|
|
3900
|
+
/** Number of synthetic source files. */
|
|
3901
|
+
readonly fileCount: number;
|
|
3902
|
+
/** Symbols (functions/classes/methods) per file. */
|
|
3903
|
+
readonly symbolsPerFile: number;
|
|
3904
|
+
/**
|
|
3905
|
+
* Edge density — probability [0,1] that any given symbol calls another.
|
|
3906
|
+
* Higher = denser call graph (more edges per node).
|
|
3907
|
+
*/
|
|
3908
|
+
readonly callDensity: number;
|
|
3909
|
+
/** Language tier label (informational — the IR is language-agnostic). */
|
|
3910
|
+
readonly language: string;
|
|
3911
|
+
}
|
|
3912
|
+
/**
|
|
3913
|
+
* Generated fixture — the IR plus approximate LOC and a structural summary.
|
|
3914
|
+
*/
|
|
3915
|
+
interface GeneratedRepo {
|
|
3916
|
+
readonly files: readonly SyntheticFileIR[];
|
|
3917
|
+
/** Approximate LOC (symbolsPerFile × fileCount × avgLinesPerSymbol). */
|
|
3918
|
+
readonly approximateLoc: number;
|
|
3919
|
+
readonly config: SyntheticRepoConfig;
|
|
3920
|
+
}
|
|
3921
|
+
/**
|
|
3922
|
+
* Minimal IR shape for the synthetic generator. Matches the subset of
|
|
3923
|
+
* {@link StoreFileIR} the harness exercises: symbols + CALLS edges. The
|
|
3924
|
+
* generator emits this shape directly so the benchmark measures the STORE,
|
|
3925
|
+
* not the parser (parser benchmarks are a separate concern).
|
|
3926
|
+
*/
|
|
3927
|
+
interface SyntheticFileIR {
|
|
3928
|
+
readonly path: string;
|
|
3929
|
+
readonly language: string;
|
|
3930
|
+
readonly contentHash: string;
|
|
3931
|
+
readonly symbols: readonly SyntheticSymbol[];
|
|
3932
|
+
readonly edges: readonly SyntheticEdge[];
|
|
3933
|
+
}
|
|
3934
|
+
interface SyntheticSymbol {
|
|
3935
|
+
readonly qualifiedName: string;
|
|
3936
|
+
readonly name: string;
|
|
3937
|
+
readonly kind: string;
|
|
3938
|
+
readonly startByte: number;
|
|
3939
|
+
readonly endByte: number;
|
|
3940
|
+
}
|
|
3941
|
+
interface SyntheticEdge {
|
|
3942
|
+
readonly srcQualifiedName: string;
|
|
3943
|
+
readonly dstQualifiedName: string;
|
|
3944
|
+
readonly type: string;
|
|
3945
|
+
readonly confidence: number;
|
|
3946
|
+
readonly provenance: string;
|
|
3947
|
+
}
|
|
3948
|
+
interface MachineFingerprint {
|
|
3949
|
+
readonly arch: string;
|
|
3950
|
+
readonly platform: string;
|
|
3951
|
+
readonly nodeVersion: string;
|
|
3952
|
+
readonly cpuModel: string | null;
|
|
3953
|
+
readonly cpuCores: number;
|
|
3954
|
+
readonly totalMemoryMb: number;
|
|
3955
|
+
}
|
|
3956
|
+
/**
|
|
3957
|
+
* Micro-metric result with percentile distribution. `samples` is the raw
|
|
3958
|
+
* array of per-iteration measurements (ms); p50/p95 are computed from it.
|
|
3959
|
+
*/
|
|
3960
|
+
interface MicroMetric {
|
|
3961
|
+
/** Median (p50) in milliseconds. */
|
|
3962
|
+
readonly p50: number;
|
|
3963
|
+
/** 95th percentile in milliseconds. */
|
|
3964
|
+
readonly p95: number;
|
|
3965
|
+
/** Number of iterations measured. */
|
|
3966
|
+
readonly iterations: number;
|
|
3967
|
+
/** Raw per-iteration timings (ms) — kept so the report is auditable. */
|
|
3968
|
+
readonly samplesMs: readonly number[];
|
|
3969
|
+
}
|
|
3970
|
+
/** A single wall-clock measurement (ms) with no distribution. */
|
|
3971
|
+
interface WallMetric {
|
|
3972
|
+
readonly ms: number;
|
|
3973
|
+
readonly detail?: string;
|
|
3974
|
+
}
|
|
3975
|
+
/**
|
|
3976
|
+
* All metric keys that the harness can produce. Each is lower-is-better
|
|
3977
|
+
* except `fullIndexLocsPerSecond` (higher is better).
|
|
3978
|
+
*
|
|
3979
|
+
* The regression gate compares only keys present in BOTH the report and
|
|
3980
|
+
* the baseline — new metrics are additive, never blocking.
|
|
3981
|
+
*/
|
|
3982
|
+
type CodingGraphMetricKey = "fullIndexMs" | "fullIndexLocsPerSecond" | "incrementalUpdateP50Ms" | "incrementalUpdateP95Ms" | "tracePathP95Ms" | "searchGraphP95Ms" | "deadCodeMs" | "dbBytesPerKloc";
|
|
3983
|
+
interface CodingGraphBenchReport {
|
|
3984
|
+
/** Schema version — bump when the report shape changes. */
|
|
3985
|
+
readonly schemaVersion: number;
|
|
3986
|
+
readonly timestamp: string;
|
|
3987
|
+
readonly machine: MachineFingerprint;
|
|
3988
|
+
readonly fixture: {
|
|
3989
|
+
readonly config: SyntheticRepoConfig;
|
|
3990
|
+
readonly approximateLoc: number;
|
|
3991
|
+
readonly fileCount: number;
|
|
3992
|
+
readonly symbolCount: number;
|
|
3993
|
+
readonly edgeCount: number;
|
|
3994
|
+
};
|
|
3995
|
+
/** Full-index wall time (ms) for the entire fixture. */
|
|
3996
|
+
readonly fullIndexMs: WallMetric;
|
|
3997
|
+
/** LOC/s sustained during full index (higher is better). */
|
|
3998
|
+
readonly fullIndexLocsPerSecond: number;
|
|
3999
|
+
/** Incremental single-file update latency distribution. */
|
|
4000
|
+
readonly incrementalUpdate: MicroMetric;
|
|
4001
|
+
/** trace_path (depth ≤ 5) latency distribution. */
|
|
4002
|
+
readonly tracePath: MicroMetric;
|
|
4003
|
+
/** search_graph name-pattern latency distribution. */
|
|
4004
|
+
readonly searchGraph: MicroMetric;
|
|
4005
|
+
/** Dead-code query wall time (ms). */
|
|
4006
|
+
readonly deadCodeMs: WallMetric;
|
|
4007
|
+
/** DB bytes per KLOC after index. */
|
|
4008
|
+
readonly dbBytesPerKloc: number;
|
|
4009
|
+
/** Peak RSS (bytes) at the end of the run. */
|
|
4010
|
+
readonly peakRssBytes: number;
|
|
4011
|
+
/** DB file size in bytes after index. */
|
|
4012
|
+
readonly dbBytes: number;
|
|
4013
|
+
/** Total node + edge count after index. */
|
|
4014
|
+
readonly graphNodeCount: number;
|
|
4015
|
+
readonly graphEdgeCount: number;
|
|
4016
|
+
}
|
|
4017
|
+
/**
|
|
4018
|
+
* Tracked baseline JSON (bench-owned, separate file from the structural
|
|
4019
|
+
* ratchets in scripts/ratchet-baseline.json per issue #1557).
|
|
4020
|
+
*/
|
|
4021
|
+
interface CodingGraphBaseline {
|
|
4022
|
+
readonly schemaVersion: number;
|
|
4023
|
+
readonly machine: MachineFingerprint;
|
|
4024
|
+
readonly fixtureConfig: SyntheticRepoConfig;
|
|
4025
|
+
readonly metrics: Readonly<Record<string, number>>;
|
|
4026
|
+
readonly createdAt: string;
|
|
4027
|
+
/** Human-readable note about how the baseline was captured. */
|
|
4028
|
+
readonly note: string;
|
|
4029
|
+
}
|
|
4030
|
+
/**
|
|
4031
|
+
* Per-metric regression detail. `direction` encodes whether higher or
|
|
4032
|
+
* lower is better; `regressed` is true when the measured value exceeds
|
|
4033
|
+
* the tolerance-adjusted baseline.
|
|
4034
|
+
*/
|
|
4035
|
+
interface RegressionMetricDetail {
|
|
4036
|
+
readonly key: string;
|
|
4037
|
+
readonly baseline: number;
|
|
4038
|
+
readonly measured: number;
|
|
4039
|
+
/** Percentage change relative to baseline (positive = worse). */
|
|
4040
|
+
readonly percentChange: number;
|
|
4041
|
+
readonly direction: "lower-is-better" | "higher-is-better";
|
|
4042
|
+
readonly tolerancePercent: number;
|
|
4043
|
+
readonly regressed: boolean;
|
|
4044
|
+
}
|
|
4045
|
+
interface RegressionGateResult {
|
|
4046
|
+
readonly passed: boolean;
|
|
4047
|
+
readonly regressions: readonly RegressionMetricDetail[];
|
|
4048
|
+
readonly summary: string;
|
|
4049
|
+
}
|
|
4050
|
+
interface CodingGraphBenchConfig {
|
|
4051
|
+
/** Fixture parameters. Defaults to a small, fast smoke fixture. */
|
|
4052
|
+
readonly fixture?: Partial<SyntheticRepoConfig>;
|
|
4053
|
+
/**
|
|
4054
|
+
* Iterations for micro-metrics (p50/p95). Minimum 20 per the issue.
|
|
4055
|
+
* Default 20.
|
|
4056
|
+
*/
|
|
4057
|
+
readonly iterations?: number;
|
|
4058
|
+
/** BFS depth for trace_path measurements. Default 5. */
|
|
4059
|
+
readonly traceDepth?: number;
|
|
4060
|
+
/**
|
|
4061
|
+
* Regression tolerance (percent). A metric must regress by MORE than
|
|
4062
|
+
* this to count as a failure. Default 30 (generous — perf thresholds
|
|
4063
|
+
* in CI flake).
|
|
4064
|
+
*/
|
|
4065
|
+
readonly tolerancePercent?: number;
|
|
4066
|
+
}
|
|
4067
|
+
/** Default fixture — small enough for a sub-second smoke run. */
|
|
4068
|
+
declare const DEFAULT_SMOKE_FIXTURE: SyntheticRepoConfig;
|
|
4069
|
+
/** Default fixture for a 10k-node scale run (~1k files × 10 symbols). */
|
|
4070
|
+
declare const DEFAULT_10K_FIXTURE: SyntheticRepoConfig;
|
|
4071
|
+
/** Minimum iterations for percentile metrics (issue #1557: ≥20). */
|
|
4072
|
+
declare const MIN_ITERATIONS = 20;
|
|
4073
|
+
/** Default regression tolerance (issue #1557: generous, e.g. 30%). */
|
|
4074
|
+
declare const DEFAULT_TOLERANCE_PERCENT = 30;
|
|
4075
|
+
/** Report schema version — bump when the shape changes. */
|
|
4076
|
+
declare const CODING_GRAPH_BENCH_SCHEMA_VERSION = 1;
|
|
4077
|
+
|
|
4078
|
+
/**
|
|
4079
|
+
* Deterministic synthetic repo generator (issue #1557 design (a)).
|
|
4080
|
+
*
|
|
4081
|
+
* Produces {@link GeneratedRepo} — a set of synthetic StoreFileIR-shaped
|
|
4082
|
+
* files with symbols and CALLS edges. The generator is parameterized:
|
|
4083
|
+
* files × functions × call-density × language. Same seed + same params
|
|
4084
|
+
* always yields byte-identical output (rule 38 — generator determinism).
|
|
4085
|
+
*
|
|
4086
|
+
* The generator emits IR directly (not source code) because:
|
|
4087
|
+
* 1. The benchmark measures the GRAPH STORE, not the parser. Parser
|
|
4088
|
+
* benchmarks are a separate concern (the parser has its own test
|
|
4089
|
+
* suite in packages/coding-graph/src/engine/).
|
|
4090
|
+
* 2. Emitting IR avoids coupling the store benchmark to grammar
|
|
4091
|
+
* availability, which varies by platform (rule 30).
|
|
4092
|
+
* 3. Synthetic IR is deterministic by construction — no parsing
|
|
4093
|
+
* nondeterminism can leak into the benchmark.
|
|
4094
|
+
*
|
|
4095
|
+
* Public-repo policy: fixtures are synthetic only. No real source code
|
|
4096
|
+
* is committed or fetched by this generator. Pinned OSS repos are a
|
|
4097
|
+
* separate prepare step (issue step 4 — not this PR).
|
|
4098
|
+
*/
|
|
4099
|
+
|
|
4100
|
+
/**
|
|
4101
|
+
* Create a deterministic PRNG from a 32-bit seed. Returns a function that
|
|
4102
|
+
* produces floats in [0, 1). Same seed → identical sequence (rule 38).
|
|
4103
|
+
*/
|
|
4104
|
+
declare function createSeededRng(seed: number): () => number;
|
|
4105
|
+
/**
|
|
4106
|
+
* Generate a deterministic synthetic repo from the given config.
|
|
4107
|
+
*
|
|
4108
|
+
* Determinism guarantee (rule 38): calling this function twice with the
|
|
4109
|
+
* same {@link SyntheticRepoConfig} produces structurally identical output
|
|
4110
|
+
* — same files, same symbols, same edges, same byte spans, same hashes.
|
|
4111
|
+
*/
|
|
4112
|
+
declare function generateSyntheticRepo(config: SyntheticRepoConfig): GeneratedRepo;
|
|
4113
|
+
/**
|
|
4114
|
+
* Pick a random qualified name from the repo for query benchmarking.
|
|
4115
|
+
* Deterministic given the same seed (so trace/search benchmarks use a
|
|
4116
|
+
* stable start node across runs).
|
|
4117
|
+
*/
|
|
4118
|
+
declare function pickStableQualifiedName(repo: GeneratedRepo, index: number): string;
|
|
4119
|
+
|
|
4120
|
+
/**
|
|
4121
|
+
* Coding-graph benchmark harness (issue #1557).
|
|
4122
|
+
*
|
|
4123
|
+
* Runs the full metric set against a synthetic fixture and produces a
|
|
4124
|
+
* {@link CodingGraphBenchReport}. The harness is the authority for
|
|
4125
|
+
* performance claims — no number ships in docs without a harness
|
|
4126
|
+
* measurement behind it (rule 55).
|
|
4127
|
+
*
|
|
4128
|
+
* Metrics measured (per the issue):
|
|
4129
|
+
* - full-index wall time + LOC/s
|
|
4130
|
+
* - incremental single-file update latency p50/p95
|
|
4131
|
+
* - trace_path (depth ≤ 5) p95
|
|
4132
|
+
* - search_graph name-pattern p95
|
|
4133
|
+
* - dead-code query wall time
|
|
4134
|
+
* - DB bytes per KLOC
|
|
4135
|
+
* - peak RSS
|
|
4136
|
+
*
|
|
4137
|
+
* Timing uses `performance.now()` (monotonic). p95 computed over ≥20
|
|
4138
|
+
* iterations for micro metrics. The report includes a machine fingerprint
|
|
4139
|
+
* so baselines are comparable.
|
|
4140
|
+
*/
|
|
4141
|
+
|
|
4142
|
+
declare function captureMachineFingerprint(): MachineFingerprint;
|
|
4143
|
+
/**
|
|
4144
|
+
* Run the coding-graph benchmark suite against a synthetic fixture.
|
|
4145
|
+
*
|
|
4146
|
+
* Produces a {@link CodingGraphBenchReport} with every metric key. The
|
|
4147
|
+
* report is fully JSON-serializable so it can be written to disk, compared
|
|
4148
|
+
* against a baseline, or embedded in docs.
|
|
4149
|
+
*
|
|
4150
|
+
* @param config Run configuration. Defaults to a small smoke fixture.
|
|
4151
|
+
*/
|
|
4152
|
+
declare function runCodingGraphBenchmark(config?: CodingGraphBenchConfig): Promise<CodingGraphBenchReport>;
|
|
4153
|
+
|
|
4154
|
+
/**
|
|
4155
|
+
* Coding-graph regression gate (issue #1557 step 3).
|
|
4156
|
+
*
|
|
4157
|
+
* Compares a benchmark report against a tracked baseline with a generous
|
|
4158
|
+
* tolerance. Hard-fails on gross regression — a real failing step, not a
|
|
4159
|
+
* warning (rule 50: no `|| true`). Tightening the baseline is a deliberate
|
|
4160
|
+
* PR act, mirroring `check-ratchets --update` (rule 50).
|
|
4161
|
+
*
|
|
4162
|
+
* The baseline is bench-owned (separate file from the structural ratchets
|
|
4163
|
+
* in scripts/ratchet-baseline.json). New metrics are additive: only keys
|
|
4164
|
+
* present in BOTH the report and the baseline are compared.
|
|
4165
|
+
*/
|
|
4166
|
+
|
|
4167
|
+
declare const METRIC_DIRECTION: {
|
|
4168
|
+
fullIndexMs: "lower-is-better";
|
|
4169
|
+
fullIndexLocsPerSecond: "higher-is-better";
|
|
4170
|
+
incrementalUpdateP95Ms: "lower-is-better";
|
|
4171
|
+
incrementalUpdateP50Ms: "lower-is-better";
|
|
4172
|
+
tracePathP95Ms: "lower-is-better";
|
|
4173
|
+
searchGraphP95Ms: "lower-is-better";
|
|
4174
|
+
deadCodeMs: "lower-is-better";
|
|
4175
|
+
dbBytesPerKloc: "lower-is-better";
|
|
4176
|
+
};
|
|
4177
|
+
type RegressionMetricKey = keyof typeof METRIC_DIRECTION;
|
|
4178
|
+
/**
|
|
4179
|
+
* Extract the flat metric map from a report for comparison.
|
|
4180
|
+
*/
|
|
4181
|
+
declare function extractMetrics(report: CodingGraphBenchReport): Record<string, number>;
|
|
4182
|
+
/**
|
|
4183
|
+
* Compare a report against a baseline. Returns a gate result that exits
|
|
4184
|
+
* non-zero when any metric regresses beyond the tolerance.
|
|
4185
|
+
*
|
|
4186
|
+
* @param report The current run's metrics.
|
|
4187
|
+
* @param baseline The tracked baseline to compare against.
|
|
4188
|
+
* @param tolerancePercent How much worse a metric can be before it counts
|
|
4189
|
+
* as a regression. Default 30 (generous — perf in CI flake).
|
|
4190
|
+
*/
|
|
4191
|
+
declare function checkCodingGraphRegression(report: CodingGraphBenchReport, baseline: CodingGraphBaseline, tolerancePercent?: number): RegressionGateResult;
|
|
4192
|
+
/**
|
|
4193
|
+
* Build a baseline object from a report, suitable for writing to the
|
|
4194
|
+
* tracked baseline JSON file. This is the "deliberate PR act" that
|
|
4195
|
+
* tightens the baseline (mirrors `check-ratchets --update`).
|
|
4196
|
+
*/
|
|
4197
|
+
declare function buildBaselineFromReport(report: CodingGraphBenchReport, note: string): CodingGraphBaseline;
|
|
4198
|
+
|
|
4199
|
+
export { AMA_BENCH_DIAGNOSTIC_VARIANTS, ASSISTANT_AGENT_CONFIG_KEY, ASSISTANT_JUDGE_CONFIG_KEY, ASSISTANT_MEETING_PREP_SCENARIOS, ASSISTANT_MEETING_PREP_SMOKE_SCENARIOS, ASSISTANT_MORNING_BRIEF_SCENARIOS, ASSISTANT_MORNING_BRIEF_SMOKE_SCENARIOS, ASSISTANT_NEXT_BEST_ACTION_SCENARIOS, ASSISTANT_NEXT_BEST_ACTION_SMOKE_SCENARIOS, ASSISTANT_RUBRIC_DIMENSIONS, ASSISTANT_RUBRIC_ID_KEY, ASSISTANT_SEEDS_CONFIG_KEY, ASSISTANT_SPOT_CHECK_DIR_KEY, ASSISTANT_SYNTHESIS_SCENARIOS, ASSISTANT_SYNTHESIS_SMOKE_SCENARIOS, type AbstentionRetrievalCase, type AggregateMetrics, type AmaBenchDiagnosticAdapterOptions, type AmaBenchDiagnosticAnswererMode, type AmaBenchDiagnosticBreakdown, type AmaBenchDiagnosticMatrixArtifact, type AmaBenchDiagnosticRecallMode, type AmaBenchDiagnosticRunContext, type AmaBenchDiagnosticTaskEvidence, type AmaBenchDiagnosticTaskRow, type AmaBenchDiagnosticVariant, type AmaBenchDiagnosticVariantSummary, type AnthropicProviderConfig, type AssistantAgent, type AssistantMemoryFact, type AssistantMemoryGraph, type AssistantRubricDimension, type AssistantRubricScores, type AssistantRunnerOptions, type AssistantScenario, type AssistantStance, type AttackRecallOptions, type AttackRetrievalHit, type AttackerMode, BENCHMARK_ARTIFACT_SCHEMA_VERSION, BENCHMARK_INTEGRITY_META_SCHEMA, BENCHMARK_REPRO_MANIFEST_FILENAME, BENCHMARK_REPRO_MANIFEST_SCHEMA_VERSION, BENCHMARK_RESULT_SCHEMA, BENCHMARK_SPLIT_TYPES, type BaselineRow, type BaselineScenario, type BeamDatasetPreview, type BenchConfig, type BenchJudge, type BenchJudgeResult, type BenchMemoryAdapter, type BenchModelSource, type BenchReasoningEffort, type BenchRecallOptions, type BenchResponder, type BenchResponse, type BenchRuntimeProfile, type BenchTier, type BenchmarkArtifact, type BenchmarkArtifactEnvironment, type BenchmarkArtifactHardware, type BenchmarkArtifactJudgeCalibration, type BenchmarkArtifactPerTaskScore, type BenchmarkArtifactSystem, type BenchmarkArtifactTier, type BenchmarkCategory, type BenchmarkDefinition, type BenchmarkIntegrityMeta, type BenchmarkMeta, type BenchmarkMode, type BenchmarkReport, type BenchmarkReproManifest, type BenchmarkReproManifestDataset, type BenchmarkReproManifestFile, type BenchmarkReproManifestResult, type BenchmarkResult, type BenchmarkSplitType, type BenchmarkStatus, type BenchmarkSuiteResult, type BenchmarkTier, type BuildBenchmarkArtifactInput, type BuildBenchmarkPublishFeedOptions, type BuildBenchmarkReproManifestOptions, type BuiltInProvider, CALIBRATION_SLICE_SIZE, CANARY_FIXED_RECALL, CANARY_SCORE_FLOOR, DEFAULT_10K_FIXTURE as CODING_GRAPH_10K_FIXTURE, CODING_GRAPH_BENCH_SCHEMA_VERSION, DEFAULT_TOLERANCE_PERCENT as CODING_GRAPH_DEFAULT_TOLERANCE, MIN_ITERATIONS as CODING_GRAPH_MIN_ITERATIONS, DEFAULT_SMOKE_FIXTURE as CODING_GRAPH_SMOKE_FIXTURE, type CalibrationAnswer, type CalibrationVerdictPair, type CanaryAdapterOptions, type CanaryFloorCheck, type CodexCliProviderConfig, type CodingGraphBaseline, type CodingGraphBenchConfig, type CodingGraphBenchReport, type MachineFingerprint as CodingGraphMachineFingerprint, type CodingGraphMetricKey, type RegressionMetricDetail as CodingGraphRegressionDetail, type RegressionMetricKey as CodingGraphRegressionKey, type RegressionGateResult as CodingGraphRegressionResult, type CohenKappaResult, type ComparisonMetricDelta, type ComparisonResult, type CompletionOpts, type CompletionResult, type ConfidenceInterval, type ContaminationCheckResult, type ContaminationEntry, type ContaminationManifest, type CustomBenchmarkScoring, type CustomBenchmarkSpec, type CustomBenchmarkTask, DEFAULT_ABLATION_BOOTSTRAP_SEED, DEFAULT_ASSISTANT_RUBRIC_ID, DEFAULT_BASELINE_SCENARIOS, DEFAULT_JUDGE_BINARIZATION_THRESHOLD, type DatasetSource, type DiscoveredModel, EMPTY_CONTAMINATION_MANIFEST, type EffectSizeInterpretation, type EffectSizeSummary, type ExplainResult, type ExtractedEntity, type ExtractedLink, type ExtractedPage, type ExtractionAttackOptions, type ExtractionAttackResult, type ExtractionAttackTarget, type FixtureGenerator, type FixtureOutput, type FixtureVariant, type GeneratedFile, type GeneratedRepo, type GoldEntity, type GoldEntityType, type GoldGraph, type GoldLink, type GoldPage, type HarnessRng, INTEGRITY_CIPHER_ALGORITHM, INTEGRITY_HASH_ALGORITHM, INTEGRITY_META_FIELDS, type IngestionBenchAdapter, type IngestionLog, JUDGE_CALIBRATION_KAPPA_THRESHOLD, type JudgeCalibrationIdentities, type JudgeCalibrationResult, type JudgeCategory, LOCAL_LAB_PROVIDER_KINDS, LOCOMO_DATASET_FILENAMES, LONG_MEM_EVAL_DATASET_FILENAMES, type LeaderboardArtifactWrite, type LlmJudge, type LlmProvider, type LoadDatasetOptions, type LoadSealedQrelsOptions, type LoadedDataset, type LoadedJudgeCalibrationState, type LocalLabManifest, type LocalLabManifestNotes, type LocalLabPhase, type LocalLabPhaseDescriptor, type LocalLabPhaseExecute, type LocalLabPhaseName, type LocalLabPhaseOutcome, LocalLabPreflightError, type LocalLabPreflightFailure, type LocalLabPreflightInput, type LocalLabPreflightOptions, type LocalLabPreflightResult, type LocalLabPreflightSuccess, type LocalLabProviderKind, type LocalLabRoleConfig, type LocalLlmProviderConfig, MEMORY_EVAL_DIMENSIONS, MEMORY_EVAL_PUBLIC_LINE, MIN_CALIBRATION_SOURCE_TASKS, MITIGATED_BASELINE_SCENARIOS, type MemCorrectGeneratorOptions, type MemCorrectSystemAdapter, type MemoryEvalCategory, type MemoryEvalDimension, type MemoryEvalDimensionId, type MemoryEvalMetric, type MemoryGraph, type MemoryStats, type MemorySystem, type Message, type MetricAggregate, type MicroMetric, type MitigatedBaselineConfig, type MitigatedTargetConfig, type MultipleChoiceQuestion, OTHER_NAMESPACE_MEMORIES, type OllamaProviderConfig, type OpenAiCompatibleProviderConfig, PROCEDURAL_REAL_SCENARIOS, PROCEDURAL_REAL_SCENARIOS_SMOKE, PUBLISHED_BENCHMARK_ARTIFACT_IDS, type PersonalizationRetrievalCase, type PreflightDiscoveredModel, type ProceduralAblationArtifact, type ProceduralAblationPerCase, type ProceduralAblationScenario, type ProceduralRealScenario, type ProceduralRealScenarioCategory, type ProviderBaseConfig, type ProviderConfig, type ProviderDiscoveryResult, type ProviderFactoryConfig, type PublishSkipReason, type PublishSkipRecord, type PublishedBenchmarkFeed, type PublishedBenchmarkFeedEntry, type PublishedBenchmarkId, REQUIRED_FRONTMATTER_FIELDS, type RecallMetrics, type RecoveredMemory, type RegressionDetail, type RegressionGateResult$1 as RegressionGateResult, type RemnicAdapterOptions, type ResolveBenchRuntimeProfileOptions, type ResolvedBenchRuntimeProfile, type ResolvedLocalLabProfile, type ResolvedLocalLabRole, type ResolvedRunBenchmarkOptions, type RotatedChoices, type RunBenchmarkOptions, type RunJudgeCalibrationOptions, type RunProceduralAblationCliArgs, type RunProceduralAblationOptions, type RunSequentialPhasesOptions, SCHEMA_TIER_FIXTURE, SCHEMA_TIER_SMOKE_FIXTURE, SEALED_PROMPT_REGISTRY, SYNTHETIC_MEMORIES, type SanitizedDiagnosticProvider, type SavedBaseline, type SchemaTierCorpus, type SchemaTierFixture, type SchemaTierName, type SchemaTierPage, type SchemaTierPageFrontmatter, type SealedArtifact, type SealedJudgeDecision, type SealedJudgeInput, type SealedQrelsArtifact, type SealedQrelsHandle, type SealedRubric, type SearchResult, type SeededMemory, type SeededRng, type SequentialPhaseHooks, type SpotCheckLogger, type StatisticalReport, type StructuredJudge, type SyntheticEdge, type SyntheticEmailIngestionAdapterOptions, type SyntheticFileIR, type SyntheticRepoConfig, type SyntheticSymbol, type SyntheticTargetOptions, type TaskResult, type TaskTokenUsage, type TemporalRetrievalCase, type TierDetail, type TimelineEntry, type TokenUsage, type WallMetric, type WriteBenchmarkArtifactResult, addContaminationEntry, aggregateTaskScores, answerBenchmarkQuestion, assertCanaryUnderFloor, assertIntegrityMetaPresent, assertPublishableIntegrity, assertSha256Hex, assistantMeetingPrepDefinition, assistantMorningBriefDefinition, assistantNextBestActionDefinition, assistantSynthesisDefinition, backlinkF1, binarizeJudgeScore, bootstrapMeanConfidenceInterval, buildAmaBenchDiagnosticMatrixArtifact, buildAmaBenchDiagnosticVariantSummary, buildAmaBenchLeaderboardRows, buildBaselineFromReport, buildBenchmarkArtifact, buildBenchmarkArtifactFilename, buildBenchmarkPublishFeed, buildBenchmarkReproManifest, buildBenchmarkRunSeeds, buildJudgePayload, buildOracleTrajectoryRecall, buildSchemaTierFixture, buildSchemaTierSmokeFixture, calendarFixture, canonicalJsonStringify, captureMachineFingerprint, chatFixture, checkCodingGraphRegression, checkDatasetContamination, checkRegression, clampScore, cohensD, compareResults, computeCohensKappa, computeSealHash, containsAnswer, createSeededRng$1 as createAdamSeededRng, createAmaBenchDiagnosticAdapter, createAnthropicProvider, createCanaryAdapter, createCodexCliProvider, createSeededRng as createCodingGraphSeededRng, createDeterministicSpotCheckLogger, createGatewayResponder, createLightweightAdapter, createLiteLlmProvider, createLocalLlmProvider, createMitigatedTarget, createOllamaProvider, createOpenAiCompatibleProvider, createSeededRandom as createProceduralAblationSeededRandom, createProvider, createProviderBackedAmaBenchRecommendedJudge, createProviderBackedJudge, createProviderBackedResponder, createProviderBackedStructuredJudge, createRemnicAdapter, createResponderFromProvider, createSeededRng$2 as createSeededRng, createSpotCheckFileLogger, createStructuredJudgeFromProvider, createSyntheticEmailIngestionAdapter, createSyntheticTarget, createTimeoutGuardedAdapter, defaultBenchmarkBaselineDir, defaultBenchmarkPublishPath, deleteBenchmarkResults, discoverAllProviders, discoveryEndpointFor, emailFixture, entityRecall, exactMatch, extractMetrics as extractCodingGraphMetrics, extractMarkdownSectionsByTitle, f1Score, fixtureToAblationScenarios, formatHandoffNote, formatMissingDatasetError, generateReport, generateSyntheticRepo, getBenchmark, getBenchmarkLowerIsBetter, getMemoryEvalDimension, getRemnicVersion, hashBenchmarkArtifact, hashBytes, hashCanonicalJson, hashString, integrityMetaIsComplete, interpretEffectSize, isAmaBenchUnknownLikeAnswer, isContaminationEntry, isContaminationManifest, isSealedQrelsArtifact, isSha256Hex, linkMatches, listBenchmarkBaselines, listBenchmarkResults, listBenchmarks, listMemoryEvalBenchmarkIds, listMemoryEvalDimensions, llmJudgeScore, llmJudgeScoreDetailed, loadAblationFixture, loadBaseline, loadBeamDatasetPreview, loadBenchmarkArtifact, loadBenchmarkBaseline, loadBenchmarkResult, loadCustomBenchmarkFile, loadJudgeCalibrationState, loadLoCoMo10, loadLocalLabManifest, loadLongMemEvalS, loadSealKeyFromEnv, loadSealedQrels, loadSealedRubric, matchEntity, mergeContaminationManifests, openSeal, orchestrateBenchmarkRuns, pairedDeltaConfidenceInterval, parseBenchmarkArtifact, parseCustomBenchmark, parseLocalLabManifest, parseRubricResponse, parseSealedQrels, pickStableQualifiedName, precisionAtK, preflightLocalLabRole, projectFolderFixture, recallAtK, redactBenchmarkResultSecrets, renderBaselineMarkdown, renderBenchmarkResultExport, renderMemorySummaryForJudge, renderMemoryViewForAgent, resolveAssistantAgent, resolveAssistantRubricId, resolveAssistantSeeds, resolveAssistantSpotCheckDir, resolveBenchRuntimeProfile, resolveBenchmarkPhaseTimeoutMs, resolveBenchmarkProgressLogging, resolveBenchmarkResultReference, resolveBenchmarkRunCount, resolveLocalLabProfile, resolveLocalLabRole, resolveStructuredJudge, rotateDistractors, rougeL, runAssistantBenchmark, runAssistantMeetingPrepBenchmark, runAssistantMorningBriefBenchmark, runAssistantNextBestActionBenchmark, runAssistantSynthesisBenchmark, runBaseline, runBenchSuite, runBenchmark, runCodingGraphBenchmark, runCustomBenchmarkFile, runExplain, runExtractionAttack, runJudgeCalibration, runMitigatedBaseline, runProceduralAblation, runProceduralAblationCli, runSealedJudge, runSequentialPhases, safeHexEqual, saveBaseline, saveBenchmarkBaseline, schemaCompleteness, sealPayload, selectAmaBenchDiagnosticVariants, selectCalibrationSlice, selectFixtureVariant, serializeBenchmarkArtifact, serializeJsonl, serializeSealedQrels, shuffleTasks, timed, verifyRubricDigest, writeBenchmarkArtifact, writeBenchmarkPublishFeed, writeBenchmarkReproManifest, writeBenchmarkResult, writeJudgeCalibrationState, writeLeaderboardArtifactsForResult, zeroScores };
|
package/dist/index.js
CHANGED
|
@@ -34709,6 +34709,414 @@ function createMitigatedTarget(config) {
|
|
|
34709
34709
|
listEntities: target.listEntities ? async () => target.listEntities() : void 0
|
|
34710
34710
|
};
|
|
34711
34711
|
}
|
|
34712
|
+
|
|
34713
|
+
// src/coding-graph/generator.ts
|
|
34714
|
+
import { createHash as createHash12 } from "crypto";
|
|
34715
|
+
function createSeededRng3(seed) {
|
|
34716
|
+
let state = seed >>> 0;
|
|
34717
|
+
return function rng() {
|
|
34718
|
+
state |= 0;
|
|
34719
|
+
state = state + 1831565813 | 0;
|
|
34720
|
+
let t = Math.imul(state ^ state >>> 15, 1 | state);
|
|
34721
|
+
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
|
|
34722
|
+
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
34723
|
+
};
|
|
34724
|
+
}
|
|
34725
|
+
var SYMBOL_KINDS = [
|
|
34726
|
+
"function",
|
|
34727
|
+
"function",
|
|
34728
|
+
"function",
|
|
34729
|
+
"method",
|
|
34730
|
+
"method",
|
|
34731
|
+
"class",
|
|
34732
|
+
"interface",
|
|
34733
|
+
"type"
|
|
34734
|
+
];
|
|
34735
|
+
var EDGE_TYPE_WEIGHTS = [
|
|
34736
|
+
["CALLS", 0.7],
|
|
34737
|
+
["USES_TYPE", 0.2],
|
|
34738
|
+
["IMPLEMENTS", 0.1]
|
|
34739
|
+
];
|
|
34740
|
+
var PROVENANCE_VALUES = ["heuristic", "heuristic", "heuristic", "trace"];
|
|
34741
|
+
var AVG_BYTES_PER_LINE = 40;
|
|
34742
|
+
function hashContent(input) {
|
|
34743
|
+
return createHash12("sha256").update(input).digest("hex").slice(0, 16);
|
|
34744
|
+
}
|
|
34745
|
+
function generateSyntheticRepo(config) {
|
|
34746
|
+
const rng = createSeededRng3(config.seed);
|
|
34747
|
+
const files = [];
|
|
34748
|
+
const edgesByFile = [];
|
|
34749
|
+
let totalLoc = 0;
|
|
34750
|
+
const allSymbols = [];
|
|
34751
|
+
for (let f = 0; f < config.fileCount; f++) {
|
|
34752
|
+
const filePath = `src/module_${f}/index.ts`;
|
|
34753
|
+
const symbols = [];
|
|
34754
|
+
let byteCursor = 0;
|
|
34755
|
+
for (let s = 0; s < config.symbolsPerFile; s++) {
|
|
34756
|
+
const kind = SYMBOL_KINDS[Math.floor(rng() * SYMBOL_KINDS.length)];
|
|
34757
|
+
const name = `${kind}_${f}_${s}`;
|
|
34758
|
+
const qualifiedName = `module_${f}.${name}`;
|
|
34759
|
+
const spanLines = 5 + Math.floor(rng() * 11);
|
|
34760
|
+
const spanBytes = spanLines * AVG_BYTES_PER_LINE;
|
|
34761
|
+
const startByte = byteCursor;
|
|
34762
|
+
const endByte = byteCursor + spanBytes;
|
|
34763
|
+
byteCursor = endByte;
|
|
34764
|
+
symbols.push({
|
|
34765
|
+
qualifiedName,
|
|
34766
|
+
name,
|
|
34767
|
+
kind,
|
|
34768
|
+
startByte,
|
|
34769
|
+
endByte
|
|
34770
|
+
});
|
|
34771
|
+
allSymbols.push({ fileIndex: f, qualifiedName, name, kind });
|
|
34772
|
+
}
|
|
34773
|
+
totalLoc += Math.ceil(byteCursor / AVG_BYTES_PER_LINE);
|
|
34774
|
+
const fileEdges = [];
|
|
34775
|
+
edgesByFile.push(fileEdges);
|
|
34776
|
+
files.push({
|
|
34777
|
+
path: filePath,
|
|
34778
|
+
language: config.language,
|
|
34779
|
+
contentHash: hashContent(`file_${f}_${config.seed}`),
|
|
34780
|
+
symbols,
|
|
34781
|
+
edges: fileEdges
|
|
34782
|
+
// filled in phase 2
|
|
34783
|
+
});
|
|
34784
|
+
}
|
|
34785
|
+
let edgeCount = 0;
|
|
34786
|
+
for (let i = 0; i < allSymbols.length; i++) {
|
|
34787
|
+
const src = allSymbols[i];
|
|
34788
|
+
const edgeRolls = Math.ceil(config.callDensity * 3);
|
|
34789
|
+
for (let e = 0; e < edgeRolls; e++) {
|
|
34790
|
+
if (rng() > config.callDensity) continue;
|
|
34791
|
+
const targetIdx = Math.floor(rng() * allSymbols.length);
|
|
34792
|
+
if (targetIdx === i) continue;
|
|
34793
|
+
const dst = allSymbols[targetIdx];
|
|
34794
|
+
const edgeType = weightedPick(EDGE_TYPE_WEIGHTS, rng);
|
|
34795
|
+
const confidence = 0.5 + rng() * 0.5;
|
|
34796
|
+
const provenance = PROVENANCE_VALUES[Math.floor(rng() * PROVENANCE_VALUES.length)];
|
|
34797
|
+
const edge = {
|
|
34798
|
+
srcQualifiedName: src.qualifiedName,
|
|
34799
|
+
dstQualifiedName: dst.qualifiedName,
|
|
34800
|
+
type: edgeType,
|
|
34801
|
+
confidence,
|
|
34802
|
+
provenance
|
|
34803
|
+
};
|
|
34804
|
+
edgesByFile[src.fileIndex].push(edge);
|
|
34805
|
+
edgeCount++;
|
|
34806
|
+
}
|
|
34807
|
+
}
|
|
34808
|
+
return {
|
|
34809
|
+
files,
|
|
34810
|
+
approximateLoc: totalLoc,
|
|
34811
|
+
config
|
|
34812
|
+
};
|
|
34813
|
+
}
|
|
34814
|
+
function weightedPick(weights, rng) {
|
|
34815
|
+
const total = weights.reduce((sum, [, w]) => sum + w, 0);
|
|
34816
|
+
let roll = rng() * total;
|
|
34817
|
+
for (const [value, w] of weights) {
|
|
34818
|
+
roll -= w;
|
|
34819
|
+
if (roll <= 0) return value;
|
|
34820
|
+
}
|
|
34821
|
+
return weights[weights.length - 1][0];
|
|
34822
|
+
}
|
|
34823
|
+
function pickStableQualifiedName(repo, index) {
|
|
34824
|
+
const allNames = [];
|
|
34825
|
+
for (const file of repo.files) {
|
|
34826
|
+
for (const sym of file.symbols) {
|
|
34827
|
+
allNames.push(sym.qualifiedName);
|
|
34828
|
+
}
|
|
34829
|
+
}
|
|
34830
|
+
if (allNames.length === 0) {
|
|
34831
|
+
throw new Error("generateSyntheticRepo: no symbols generated");
|
|
34832
|
+
}
|
|
34833
|
+
return allNames[index % allNames.length];
|
|
34834
|
+
}
|
|
34835
|
+
|
|
34836
|
+
// src/coding-graph/harness.ts
|
|
34837
|
+
import { performance as performance2 } from "perf_hooks";
|
|
34838
|
+
import { mkdtemp as mkdtemp12, rm as rm14 } from "fs/promises";
|
|
34839
|
+
import { statSync } from "fs";
|
|
34840
|
+
import { tmpdir as tmpdir7 } from "os";
|
|
34841
|
+
import path36 from "path";
|
|
34842
|
+
import os10 from "os";
|
|
34843
|
+
import {
|
|
34844
|
+
GraphStore
|
|
34845
|
+
} from "@remnic/coding-graph";
|
|
34846
|
+
|
|
34847
|
+
// src/coding-graph/types.ts
|
|
34848
|
+
var DEFAULT_SMOKE_FIXTURE = {
|
|
34849
|
+
seed: 42,
|
|
34850
|
+
fileCount: 20,
|
|
34851
|
+
symbolsPerFile: 10,
|
|
34852
|
+
callDensity: 0.3,
|
|
34853
|
+
language: "typescript"
|
|
34854
|
+
};
|
|
34855
|
+
var DEFAULT_10K_FIXTURE = {
|
|
34856
|
+
seed: 42,
|
|
34857
|
+
fileCount: 1e3,
|
|
34858
|
+
symbolsPerFile: 10,
|
|
34859
|
+
callDensity: 0.2,
|
|
34860
|
+
language: "typescript"
|
|
34861
|
+
};
|
|
34862
|
+
var MIN_ITERATIONS = 20;
|
|
34863
|
+
var DEFAULT_TOLERANCE_PERCENT = 30;
|
|
34864
|
+
var CODING_GRAPH_BENCH_SCHEMA_VERSION = 1;
|
|
34865
|
+
|
|
34866
|
+
// src/coding-graph/harness.ts
|
|
34867
|
+
function captureMachineFingerprint() {
|
|
34868
|
+
const cpus = os10.cpus();
|
|
34869
|
+
return {
|
|
34870
|
+
arch: process.arch,
|
|
34871
|
+
platform: process.platform,
|
|
34872
|
+
nodeVersion: process.version,
|
|
34873
|
+
cpuModel: cpus.length > 0 ? cpus[0].model : null,
|
|
34874
|
+
cpuCores: cpus.length,
|
|
34875
|
+
totalMemoryMb: Math.round(os10.totalmem() / (1024 * 1024))
|
|
34876
|
+
};
|
|
34877
|
+
}
|
|
34878
|
+
function percentile2(sorted, p) {
|
|
34879
|
+
if (sorted.length === 0) return 0;
|
|
34880
|
+
if (sorted.length === 1) return sorted[0];
|
|
34881
|
+
const idx = Math.ceil(p / 100 * sorted.length) - 1;
|
|
34882
|
+
return sorted[Math.max(0, idx)];
|
|
34883
|
+
}
|
|
34884
|
+
function computeMicroMetric(samplesMs) {
|
|
34885
|
+
const sorted = [...samplesMs].sort((a, b) => a - b);
|
|
34886
|
+
return {
|
|
34887
|
+
p50: percentile2(sorted, 50),
|
|
34888
|
+
p95: percentile2(sorted, 95),
|
|
34889
|
+
iterations: samplesMs.length,
|
|
34890
|
+
samplesMs
|
|
34891
|
+
};
|
|
34892
|
+
}
|
|
34893
|
+
function toStoreFiles(repo) {
|
|
34894
|
+
return repo.files.map((f) => ({
|
|
34895
|
+
path: f.path,
|
|
34896
|
+
language: f.language,
|
|
34897
|
+
contentHash: f.contentHash,
|
|
34898
|
+
symbols: f.symbols.map((s) => ({
|
|
34899
|
+
qualifiedName: s.qualifiedName,
|
|
34900
|
+
name: s.name,
|
|
34901
|
+
kind: s.kind,
|
|
34902
|
+
span: { startByte: s.startByte, endByte: s.endByte }
|
|
34903
|
+
})),
|
|
34904
|
+
edges: f.edges.map(
|
|
34905
|
+
(e) => ({
|
|
34906
|
+
srcQualifiedName: e.srcQualifiedName,
|
|
34907
|
+
dstQualifiedName: e.dstQualifiedName,
|
|
34908
|
+
type: e.type,
|
|
34909
|
+
confidence: e.confidence,
|
|
34910
|
+
provenance: e.provenance
|
|
34911
|
+
})
|
|
34912
|
+
)
|
|
34913
|
+
}));
|
|
34914
|
+
}
|
|
34915
|
+
async function timeAsync(fn) {
|
|
34916
|
+
const start = performance2.now();
|
|
34917
|
+
const result = await fn();
|
|
34918
|
+
return { ms: performance2.now() - start, result };
|
|
34919
|
+
}
|
|
34920
|
+
function timeSync(fn) {
|
|
34921
|
+
const start = performance2.now();
|
|
34922
|
+
const result = fn();
|
|
34923
|
+
return { ms: performance2.now() - start, result };
|
|
34924
|
+
}
|
|
34925
|
+
async function runCodingGraphBenchmark(config = {}) {
|
|
34926
|
+
const fixtureConfig = {
|
|
34927
|
+
...DEFAULT_SMOKE_FIXTURE,
|
|
34928
|
+
...config.fixture
|
|
34929
|
+
};
|
|
34930
|
+
const iterations = Math.max(MIN_ITERATIONS, config.iterations ?? MIN_ITERATIONS);
|
|
34931
|
+
const traceDepth = config.traceDepth ?? 5;
|
|
34932
|
+
const repo = generateSyntheticRepo(fixtureConfig);
|
|
34933
|
+
const storeFiles = toStoreFiles(repo);
|
|
34934
|
+
let peakRss = 0;
|
|
34935
|
+
const sampleRss = () => {
|
|
34936
|
+
peakRss = Math.max(peakRss, process.memoryUsage().rss);
|
|
34937
|
+
};
|
|
34938
|
+
const dir = await mkdtemp12(path36.join(tmpdir7(), "coding-graph-bench-"));
|
|
34939
|
+
const dbPath = path36.join(dir, "bench.sqlite");
|
|
34940
|
+
try {
|
|
34941
|
+
const store = await GraphStore.open({ dbPath });
|
|
34942
|
+
try {
|
|
34943
|
+
const fullIndex = await timeAsync(() => store.upsertFileBatch(storeFiles));
|
|
34944
|
+
if (!fullIndex.result.ok) {
|
|
34945
|
+
throw new Error(`full-index failed: ${fullIndex.result.code}`);
|
|
34946
|
+
}
|
|
34947
|
+
const locsPerSecond = fullIndex.ms > 0 ? repo.approximateLoc / (fullIndex.ms / 1e3) : 0;
|
|
34948
|
+
sampleRss();
|
|
34949
|
+
const stats = store.schemaStats();
|
|
34950
|
+
const graphNodeCount = stats.ok ? stats.stats.nodes : 0;
|
|
34951
|
+
const graphEdgeCount = stats.ok ? stats.stats.edges : 0;
|
|
34952
|
+
const incrementalSamples = [];
|
|
34953
|
+
for (let i = 0; i < iterations; i++) {
|
|
34954
|
+
const fileIdx = i % storeFiles.length;
|
|
34955
|
+
const incResult = await timeAsync(
|
|
34956
|
+
() => store.upsertFileBatch([storeFiles[fileIdx]])
|
|
34957
|
+
);
|
|
34958
|
+
if (!incResult.result.ok) {
|
|
34959
|
+
throw new Error(`incremental update failed: ${incResult.result.code}`);
|
|
34960
|
+
}
|
|
34961
|
+
incrementalSamples.push(incResult.ms);
|
|
34962
|
+
}
|
|
34963
|
+
const startName = repo.files[0]?.symbols[0]?.qualifiedName;
|
|
34964
|
+
const traceSamples = [];
|
|
34965
|
+
if (startName) {
|
|
34966
|
+
for (let i = 0; i < iterations; i++) {
|
|
34967
|
+
const traceRes = timeSync(
|
|
34968
|
+
() => store.traverse({
|
|
34969
|
+
start: startName,
|
|
34970
|
+
maxDepth: traceDepth,
|
|
34971
|
+
direction: "outgoing"
|
|
34972
|
+
})
|
|
34973
|
+
);
|
|
34974
|
+
if (!traceRes.result.ok) {
|
|
34975
|
+
throw new Error(
|
|
34976
|
+
`trace_path failed: ${traceRes.result.code}`
|
|
34977
|
+
);
|
|
34978
|
+
}
|
|
34979
|
+
traceSamples.push(traceRes.ms);
|
|
34980
|
+
}
|
|
34981
|
+
}
|
|
34982
|
+
const searchSamples = [];
|
|
34983
|
+
for (let i = 0; i < iterations; i++) {
|
|
34984
|
+
const searchRes = timeSync(
|
|
34985
|
+
() => store.searchGraph({
|
|
34986
|
+
namePattern: "%function%",
|
|
34987
|
+
limit: 50
|
|
34988
|
+
})
|
|
34989
|
+
);
|
|
34990
|
+
if (!searchRes.result.ok) {
|
|
34991
|
+
throw new Error(
|
|
34992
|
+
`search_graph failed: ${searchRes.result.code}`
|
|
34993
|
+
);
|
|
34994
|
+
}
|
|
34995
|
+
searchSamples.push(searchRes.ms);
|
|
34996
|
+
}
|
|
34997
|
+
const deadCode = timeSync(() => store.deadCode());
|
|
34998
|
+
if (!deadCode.result.ok) {
|
|
34999
|
+
throw new Error(`dead_code failed: ${deadCode.result.code}`);
|
|
35000
|
+
}
|
|
35001
|
+
await store.drain();
|
|
35002
|
+
let dbBytes = statSync(dbPath).size;
|
|
35003
|
+
try {
|
|
35004
|
+
dbBytes += statSync(dbPath + "-wal").size;
|
|
35005
|
+
} catch {
|
|
35006
|
+
}
|
|
35007
|
+
const kloc = Math.max(1, repo.approximateLoc / 1e3);
|
|
35008
|
+
const dbBytesPerKloc = dbBytes / kloc;
|
|
35009
|
+
sampleRss();
|
|
35010
|
+
const peakRssBytes = peakRss;
|
|
35011
|
+
return {
|
|
35012
|
+
schemaVersion: CODING_GRAPH_BENCH_SCHEMA_VERSION,
|
|
35013
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
35014
|
+
machine: captureMachineFingerprint(),
|
|
35015
|
+
fixture: {
|
|
35016
|
+
config: fixtureConfig,
|
|
35017
|
+
approximateLoc: repo.approximateLoc,
|
|
35018
|
+
fileCount: repo.files.length,
|
|
35019
|
+
symbolCount: repo.files.reduce((sum, f) => sum + f.symbols.length, 0),
|
|
35020
|
+
edgeCount: repo.files.reduce((sum, f) => sum + f.edges.length, 0)
|
|
35021
|
+
},
|
|
35022
|
+
fullIndexMs: { ms: fullIndex.ms },
|
|
35023
|
+
fullIndexLocsPerSecond: Math.round(locsPerSecond),
|
|
35024
|
+
incrementalUpdate: computeMicroMetric(incrementalSamples),
|
|
35025
|
+
tracePath: computeMicroMetric(traceSamples.length > 0 ? traceSamples : [0]),
|
|
35026
|
+
searchGraph: computeMicroMetric(searchSamples),
|
|
35027
|
+
deadCodeMs: { ms: deadCode.ms },
|
|
35028
|
+
dbBytesPerKloc: Math.round(dbBytesPerKloc),
|
|
35029
|
+
peakRssBytes,
|
|
35030
|
+
dbBytes,
|
|
35031
|
+
graphNodeCount,
|
|
35032
|
+
graphEdgeCount
|
|
35033
|
+
};
|
|
35034
|
+
} finally {
|
|
35035
|
+
await store.close();
|
|
35036
|
+
}
|
|
35037
|
+
} finally {
|
|
35038
|
+
await rm14(dir, { recursive: true, force: true });
|
|
35039
|
+
}
|
|
35040
|
+
}
|
|
35041
|
+
|
|
35042
|
+
// src/coding-graph/regression.ts
|
|
35043
|
+
var METRIC_DIRECTION = {
|
|
35044
|
+
fullIndexMs: "lower-is-better",
|
|
35045
|
+
fullIndexLocsPerSecond: "higher-is-better",
|
|
35046
|
+
incrementalUpdateP95Ms: "lower-is-better",
|
|
35047
|
+
incrementalUpdateP50Ms: "lower-is-better",
|
|
35048
|
+
tracePathP95Ms: "lower-is-better",
|
|
35049
|
+
searchGraphP95Ms: "lower-is-better",
|
|
35050
|
+
deadCodeMs: "lower-is-better",
|
|
35051
|
+
dbBytesPerKloc: "lower-is-better"
|
|
35052
|
+
};
|
|
35053
|
+
function extractMetrics(report) {
|
|
35054
|
+
return {
|
|
35055
|
+
fullIndexMs: report.fullIndexMs.ms,
|
|
35056
|
+
fullIndexLocsPerSecond: report.fullIndexLocsPerSecond,
|
|
35057
|
+
incrementalUpdateP50Ms: report.incrementalUpdate.p50,
|
|
35058
|
+
incrementalUpdateP95Ms: report.incrementalUpdate.p95,
|
|
35059
|
+
tracePathP95Ms: report.tracePath.p95,
|
|
35060
|
+
searchGraphP95Ms: report.searchGraph.p95,
|
|
35061
|
+
deadCodeMs: report.deadCodeMs.ms,
|
|
35062
|
+
dbBytesPerKloc: report.dbBytesPerKloc
|
|
35063
|
+
};
|
|
35064
|
+
}
|
|
35065
|
+
function checkCodingGraphRegression(report, baseline, tolerancePercent = DEFAULT_TOLERANCE_PERCENT) {
|
|
35066
|
+
const measured = extractMetrics(report);
|
|
35067
|
+
const baselineMetrics = baseline.metrics;
|
|
35068
|
+
const regressions = [];
|
|
35069
|
+
const reportFixture = report.fixture.config;
|
|
35070
|
+
const baselineFixture = baseline.fixtureConfig;
|
|
35071
|
+
const mismatchedKeys = Object.keys(baselineFixture).filter((key) => reportFixture[key] !== baselineFixture[key]);
|
|
35072
|
+
if (mismatchedKeys.length > 0) {
|
|
35073
|
+
const diffs = mismatchedKeys.map(
|
|
35074
|
+
(key) => `${key}: report=${reportFixture[key]} baseline=${baselineFixture[key]}`
|
|
35075
|
+
).join(", ");
|
|
35076
|
+
return {
|
|
35077
|
+
passed: false,
|
|
35078
|
+
regressions: [],
|
|
35079
|
+
summary: `Fixture mismatch (${diffs}). Metrics are not comparable across different fixtures.`
|
|
35080
|
+
};
|
|
35081
|
+
}
|
|
35082
|
+
for (const key of Object.keys(METRIC_DIRECTION)) {
|
|
35083
|
+
const baseVal = baselineMetrics[key];
|
|
35084
|
+
const measVal = measured[key];
|
|
35085
|
+
if (baseVal == null || measVal == null) continue;
|
|
35086
|
+
if (baseVal === 0) continue;
|
|
35087
|
+
const direction = METRIC_DIRECTION[key];
|
|
35088
|
+
const ratio2 = measVal / baseVal;
|
|
35089
|
+
const percentChange2 = direction === "lower-is-better" ? (ratio2 - 1) * 100 : (1 - ratio2) * 100;
|
|
35090
|
+
const regressed = percentChange2 > tolerancePercent;
|
|
35091
|
+
if (regressed) {
|
|
35092
|
+
regressions.push({
|
|
35093
|
+
key,
|
|
35094
|
+
baseline: baseVal,
|
|
35095
|
+
measured: measVal,
|
|
35096
|
+
percentChange: Math.round(percentChange2 * 10) / 10,
|
|
35097
|
+
direction,
|
|
35098
|
+
tolerancePercent,
|
|
35099
|
+
regressed: true
|
|
35100
|
+
});
|
|
35101
|
+
}
|
|
35102
|
+
}
|
|
35103
|
+
const passed = regressions.length === 0;
|
|
35104
|
+
const summary = passed ? "All metrics within tolerance." : `${regressions.length} metric(s) regressed beyond ${tolerancePercent}% tolerance:
|
|
35105
|
+
` + regressions.map(
|
|
35106
|
+
(r) => ` ${r.key}: ${r.baseline} \u2192 ${r.measured} (${r.percentChange > 0 ? "+" : ""}${r.percentChange}% vs baseline)`
|
|
35107
|
+
).join("\n");
|
|
35108
|
+
return { passed, regressions, summary };
|
|
35109
|
+
}
|
|
35110
|
+
function buildBaselineFromReport(report, note) {
|
|
35111
|
+
return {
|
|
35112
|
+
schemaVersion: report.schemaVersion,
|
|
35113
|
+
machine: report.machine,
|
|
35114
|
+
fixtureConfig: report.fixture.config,
|
|
35115
|
+
metrics: extractMetrics(report),
|
|
35116
|
+
createdAt: report.timestamp,
|
|
35117
|
+
note
|
|
35118
|
+
};
|
|
35119
|
+
}
|
|
34712
35120
|
export {
|
|
34713
35121
|
AMA_BENCH_DIAGNOSTIC_VARIANTS,
|
|
34714
35122
|
ASSISTANT_AGENT_CONFIG_KEY,
|
|
@@ -34734,6 +35142,11 @@ export {
|
|
|
34734
35142
|
CALIBRATION_SLICE_SIZE,
|
|
34735
35143
|
CANARY_FIXED_RECALL,
|
|
34736
35144
|
CANARY_SCORE_FLOOR,
|
|
35145
|
+
DEFAULT_10K_FIXTURE as CODING_GRAPH_10K_FIXTURE,
|
|
35146
|
+
CODING_GRAPH_BENCH_SCHEMA_VERSION,
|
|
35147
|
+
DEFAULT_TOLERANCE_PERCENT as CODING_GRAPH_DEFAULT_TOLERANCE,
|
|
35148
|
+
MIN_ITERATIONS as CODING_GRAPH_MIN_ITERATIONS,
|
|
35149
|
+
DEFAULT_SMOKE_FIXTURE as CODING_GRAPH_SMOKE_FIXTURE,
|
|
34737
35150
|
DEFAULT_ABLATION_BOOTSTRAP_SEED,
|
|
34738
35151
|
DEFAULT_ASSISTANT_RUBRIC_ID,
|
|
34739
35152
|
DEFAULT_BASELINE_SCENARIOS,
|
|
@@ -34777,6 +35190,7 @@ export {
|
|
|
34777
35190
|
buildAmaBenchDiagnosticMatrixArtifact,
|
|
34778
35191
|
buildAmaBenchDiagnosticVariantSummary,
|
|
34779
35192
|
buildAmaBenchLeaderboardRows,
|
|
35193
|
+
buildBaselineFromReport,
|
|
34780
35194
|
buildBenchmarkArtifact,
|
|
34781
35195
|
buildBenchmarkArtifactFilename,
|
|
34782
35196
|
buildBenchmarkPublishFeed,
|
|
@@ -34788,7 +35202,9 @@ export {
|
|
|
34788
35202
|
buildSchemaTierSmokeFixture,
|
|
34789
35203
|
calendarFixture,
|
|
34790
35204
|
canonicalJsonStringify,
|
|
35205
|
+
captureMachineFingerprint,
|
|
34791
35206
|
chatFixture,
|
|
35207
|
+
checkCodingGraphRegression,
|
|
34792
35208
|
checkDatasetContamination,
|
|
34793
35209
|
checkRegression,
|
|
34794
35210
|
clampScore,
|
|
@@ -34802,6 +35218,7 @@ export {
|
|
|
34802
35218
|
createAnthropicProvider,
|
|
34803
35219
|
createCanaryAdapter,
|
|
34804
35220
|
createCodexCliProvider,
|
|
35221
|
+
createSeededRng3 as createCodingGraphSeededRng,
|
|
34805
35222
|
createDeterministicSpotCheckLogger,
|
|
34806
35223
|
createGatewayResponder,
|
|
34807
35224
|
createLightweightAdapter,
|
|
@@ -34832,12 +35249,14 @@ export {
|
|
|
34832
35249
|
emailFixture,
|
|
34833
35250
|
entityRecall,
|
|
34834
35251
|
exactMatch,
|
|
35252
|
+
extractMetrics as extractCodingGraphMetrics,
|
|
34835
35253
|
extractMarkdownSectionsByTitle,
|
|
34836
35254
|
f1Score,
|
|
34837
35255
|
fixtureToAblationScenarios,
|
|
34838
35256
|
formatHandoffNote,
|
|
34839
35257
|
formatMissingDatasetError,
|
|
34840
35258
|
generateReport,
|
|
35259
|
+
generateSyntheticRepo,
|
|
34841
35260
|
getBenchmark,
|
|
34842
35261
|
getBenchmarkLowerIsBetter,
|
|
34843
35262
|
getMemoryEvalDimension,
|
|
@@ -34885,6 +35304,7 @@ export {
|
|
|
34885
35304
|
parseLocalLabManifest,
|
|
34886
35305
|
parseRubricResponse,
|
|
34887
35306
|
parseSealedQrels,
|
|
35307
|
+
pickStableQualifiedName,
|
|
34888
35308
|
precisionAtK,
|
|
34889
35309
|
preflightLocalLabRole,
|
|
34890
35310
|
projectFolderFixture,
|
|
@@ -34916,6 +35336,7 @@ export {
|
|
|
34916
35336
|
runBaseline,
|
|
34917
35337
|
runBenchSuite,
|
|
34918
35338
|
runBenchmark,
|
|
35339
|
+
runCodingGraphBenchmark,
|
|
34919
35340
|
runCustomBenchmarkFile,
|
|
34920
35341
|
runExplain,
|
|
34921
35342
|
runExtractionAttack,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remnic/bench",
|
|
3
|
-
"version": "9.3.
|
|
3
|
+
"version": "9.3.712",
|
|
4
4
|
"description": "Retrieval latency ladder benchmarks + CI regression gates for @remnic/core",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -36,7 +36,8 @@
|
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"hyparquet": "^1.25.7",
|
|
38
38
|
"yaml": "^2.4.2",
|
|
39
|
-
"@remnic/
|
|
39
|
+
"@remnic/coding-graph": "^9.3.712",
|
|
40
|
+
"@remnic/core": "^9.3.712"
|
|
40
41
|
},
|
|
41
42
|
"devDependencies": {
|
|
42
43
|
"tsup": "^8.5.1",
|