@dotsetlabs/bellwether 0.10.0
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/CHANGELOG.md +291 -0
- package/LICENSE +21 -0
- package/README.md +739 -0
- package/dist/auth/credentials.d.ts +64 -0
- package/dist/auth/credentials.js +218 -0
- package/dist/auth/index.d.ts +6 -0
- package/dist/auth/index.js +6 -0
- package/dist/auth/keychain.d.ts +64 -0
- package/dist/auth/keychain.js +268 -0
- package/dist/baseline/ab-testing.d.ts +80 -0
- package/dist/baseline/ab-testing.js +236 -0
- package/dist/baseline/ai-compatibility-scorer.d.ts +95 -0
- package/dist/baseline/ai-compatibility-scorer.js +606 -0
- package/dist/baseline/calibration.d.ts +77 -0
- package/dist/baseline/calibration.js +136 -0
- package/dist/baseline/category-matching.d.ts +85 -0
- package/dist/baseline/category-matching.js +289 -0
- package/dist/baseline/change-impact-analyzer.d.ts +98 -0
- package/dist/baseline/change-impact-analyzer.js +592 -0
- package/dist/baseline/comparator.d.ts +64 -0
- package/dist/baseline/comparator.js +916 -0
- package/dist/baseline/confidence.d.ts +55 -0
- package/dist/baseline/confidence.js +122 -0
- package/dist/baseline/converter.d.ts +61 -0
- package/dist/baseline/converter.js +585 -0
- package/dist/baseline/dependency-analyzer.d.ts +89 -0
- package/dist/baseline/dependency-analyzer.js +567 -0
- package/dist/baseline/deprecation-tracker.d.ts +133 -0
- package/dist/baseline/deprecation-tracker.js +322 -0
- package/dist/baseline/diff.d.ts +55 -0
- package/dist/baseline/diff.js +1584 -0
- package/dist/baseline/documentation-scorer.d.ts +205 -0
- package/dist/baseline/documentation-scorer.js +466 -0
- package/dist/baseline/embeddings.d.ts +118 -0
- package/dist/baseline/embeddings.js +251 -0
- package/dist/baseline/error-analyzer.d.ts +198 -0
- package/dist/baseline/error-analyzer.js +721 -0
- package/dist/baseline/evaluation/evaluator.d.ts +42 -0
- package/dist/baseline/evaluation/evaluator.js +323 -0
- package/dist/baseline/evaluation/expanded-dataset.d.ts +45 -0
- package/dist/baseline/evaluation/expanded-dataset.js +1164 -0
- package/dist/baseline/evaluation/golden-dataset.d.ts +58 -0
- package/dist/baseline/evaluation/golden-dataset.js +717 -0
- package/dist/baseline/evaluation/index.d.ts +15 -0
- package/dist/baseline/evaluation/index.js +15 -0
- package/dist/baseline/evaluation/types.d.ts +186 -0
- package/dist/baseline/evaluation/types.js +8 -0
- package/dist/baseline/external-dependency-detector.d.ts +181 -0
- package/dist/baseline/external-dependency-detector.js +524 -0
- package/dist/baseline/golden-output.d.ts +162 -0
- package/dist/baseline/golden-output.js +636 -0
- package/dist/baseline/health-scorer.d.ts +174 -0
- package/dist/baseline/health-scorer.js +451 -0
- package/dist/baseline/incremental-checker.d.ts +97 -0
- package/dist/baseline/incremental-checker.js +174 -0
- package/dist/baseline/index.d.ts +31 -0
- package/dist/baseline/index.js +42 -0
- package/dist/baseline/migration-generator.d.ts +137 -0
- package/dist/baseline/migration-generator.js +554 -0
- package/dist/baseline/migrations.d.ts +60 -0
- package/dist/baseline/migrations.js +197 -0
- package/dist/baseline/performance-tracker.d.ts +214 -0
- package/dist/baseline/performance-tracker.js +577 -0
- package/dist/baseline/pr-comment-generator.d.ts +117 -0
- package/dist/baseline/pr-comment-generator.js +546 -0
- package/dist/baseline/response-fingerprint.d.ts +127 -0
- package/dist/baseline/response-fingerprint.js +728 -0
- package/dist/baseline/response-schema-tracker.d.ts +129 -0
- package/dist/baseline/response-schema-tracker.js +420 -0
- package/dist/baseline/risk-scorer.d.ts +54 -0
- package/dist/baseline/risk-scorer.js +434 -0
- package/dist/baseline/saver.d.ts +89 -0
- package/dist/baseline/saver.js +554 -0
- package/dist/baseline/scenario-generator.d.ts +151 -0
- package/dist/baseline/scenario-generator.js +905 -0
- package/dist/baseline/schema-compare.d.ts +86 -0
- package/dist/baseline/schema-compare.js +557 -0
- package/dist/baseline/schema-evolution.d.ts +189 -0
- package/dist/baseline/schema-evolution.js +467 -0
- package/dist/baseline/semantic.d.ts +203 -0
- package/dist/baseline/semantic.js +908 -0
- package/dist/baseline/synonyms.d.ts +60 -0
- package/dist/baseline/synonyms.js +386 -0
- package/dist/baseline/telemetry.d.ts +165 -0
- package/dist/baseline/telemetry.js +294 -0
- package/dist/baseline/test-pruner.d.ts +120 -0
- package/dist/baseline/test-pruner.js +387 -0
- package/dist/baseline/types.d.ts +449 -0
- package/dist/baseline/types.js +5 -0
- package/dist/baseline/version.d.ts +138 -0
- package/dist/baseline/version.js +206 -0
- package/dist/cache/index.d.ts +5 -0
- package/dist/cache/index.js +5 -0
- package/dist/cache/response-cache.d.ts +151 -0
- package/dist/cache/response-cache.js +287 -0
- package/dist/ci/index.d.ts +60 -0
- package/dist/ci/index.js +342 -0
- package/dist/cli/commands/auth.d.ts +12 -0
- package/dist/cli/commands/auth.js +352 -0
- package/dist/cli/commands/badge.d.ts +3 -0
- package/dist/cli/commands/badge.js +74 -0
- package/dist/cli/commands/baseline-accept.d.ts +15 -0
- package/dist/cli/commands/baseline-accept.js +178 -0
- package/dist/cli/commands/baseline-migrate.d.ts +12 -0
- package/dist/cli/commands/baseline-migrate.js +164 -0
- package/dist/cli/commands/baseline.d.ts +14 -0
- package/dist/cli/commands/baseline.js +449 -0
- package/dist/cli/commands/beta.d.ts +10 -0
- package/dist/cli/commands/beta.js +231 -0
- package/dist/cli/commands/check.d.ts +11 -0
- package/dist/cli/commands/check.js +820 -0
- package/dist/cli/commands/cloud/badge.d.ts +3 -0
- package/dist/cli/commands/cloud/badge.js +74 -0
- package/dist/cli/commands/cloud/diff.d.ts +6 -0
- package/dist/cli/commands/cloud/diff.js +79 -0
- package/dist/cli/commands/cloud/history.d.ts +6 -0
- package/dist/cli/commands/cloud/history.js +102 -0
- package/dist/cli/commands/cloud/link.d.ts +9 -0
- package/dist/cli/commands/cloud/link.js +119 -0
- package/dist/cli/commands/cloud/login.d.ts +7 -0
- package/dist/cli/commands/cloud/login.js +499 -0
- package/dist/cli/commands/cloud/projects.d.ts +6 -0
- package/dist/cli/commands/cloud/projects.js +44 -0
- package/dist/cli/commands/cloud/shared.d.ts +7 -0
- package/dist/cli/commands/cloud/shared.js +42 -0
- package/dist/cli/commands/cloud/teams.d.ts +8 -0
- package/dist/cli/commands/cloud/teams.js +169 -0
- package/dist/cli/commands/cloud/upload.d.ts +8 -0
- package/dist/cli/commands/cloud/upload.js +181 -0
- package/dist/cli/commands/contract.d.ts +11 -0
- package/dist/cli/commands/contract.js +280 -0
- package/dist/cli/commands/discover.d.ts +3 -0
- package/dist/cli/commands/discover.js +82 -0
- package/dist/cli/commands/eval.d.ts +9 -0
- package/dist/cli/commands/eval.js +187 -0
- package/dist/cli/commands/explore.d.ts +11 -0
- package/dist/cli/commands/explore.js +437 -0
- package/dist/cli/commands/feedback.d.ts +9 -0
- package/dist/cli/commands/feedback.js +174 -0
- package/dist/cli/commands/golden.d.ts +12 -0
- package/dist/cli/commands/golden.js +407 -0
- package/dist/cli/commands/history.d.ts +10 -0
- package/dist/cli/commands/history.js +202 -0
- package/dist/cli/commands/init.d.ts +9 -0
- package/dist/cli/commands/init.js +219 -0
- package/dist/cli/commands/interview.d.ts +3 -0
- package/dist/cli/commands/interview.js +903 -0
- package/dist/cli/commands/link.d.ts +10 -0
- package/dist/cli/commands/link.js +169 -0
- package/dist/cli/commands/login.d.ts +7 -0
- package/dist/cli/commands/login.js +499 -0
- package/dist/cli/commands/preset.d.ts +33 -0
- package/dist/cli/commands/preset.js +297 -0
- package/dist/cli/commands/profile.d.ts +33 -0
- package/dist/cli/commands/profile.js +286 -0
- package/dist/cli/commands/registry.d.ts +11 -0
- package/dist/cli/commands/registry.js +146 -0
- package/dist/cli/commands/shared.d.ts +79 -0
- package/dist/cli/commands/shared.js +196 -0
- package/dist/cli/commands/teams.d.ts +8 -0
- package/dist/cli/commands/teams.js +169 -0
- package/dist/cli/commands/test.d.ts +9 -0
- package/dist/cli/commands/test.js +500 -0
- package/dist/cli/commands/upload.d.ts +8 -0
- package/dist/cli/commands/upload.js +223 -0
- package/dist/cli/commands/validate-config.d.ts +6 -0
- package/dist/cli/commands/validate-config.js +35 -0
- package/dist/cli/commands/verify.d.ts +11 -0
- package/dist/cli/commands/verify.js +283 -0
- package/dist/cli/commands/watch.d.ts +12 -0
- package/dist/cli/commands/watch.js +253 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.js +178 -0
- package/dist/cli/interactive.d.ts +47 -0
- package/dist/cli/interactive.js +216 -0
- package/dist/cli/output/terminal-reporter.d.ts +19 -0
- package/dist/cli/output/terminal-reporter.js +104 -0
- package/dist/cli/output.d.ts +226 -0
- package/dist/cli/output.js +438 -0
- package/dist/cli/utils/env.d.ts +5 -0
- package/dist/cli/utils/env.js +14 -0
- package/dist/cli/utils/progress.d.ts +59 -0
- package/dist/cli/utils/progress.js +206 -0
- package/dist/cli/utils/server-context.d.ts +10 -0
- package/dist/cli/utils/server-context.js +36 -0
- package/dist/cloud/auth.d.ts +144 -0
- package/dist/cloud/auth.js +374 -0
- package/dist/cloud/client.d.ts +24 -0
- package/dist/cloud/client.js +65 -0
- package/dist/cloud/http-client.d.ts +38 -0
- package/dist/cloud/http-client.js +215 -0
- package/dist/cloud/index.d.ts +23 -0
- package/dist/cloud/index.js +25 -0
- package/dist/cloud/mock-client.d.ts +107 -0
- package/dist/cloud/mock-client.js +545 -0
- package/dist/cloud/types.d.ts +515 -0
- package/dist/cloud/types.js +15 -0
- package/dist/config/defaults.d.ts +160 -0
- package/dist/config/defaults.js +169 -0
- package/dist/config/loader.d.ts +24 -0
- package/dist/config/loader.js +122 -0
- package/dist/config/template.d.ts +42 -0
- package/dist/config/template.js +647 -0
- package/dist/config/validator.d.ts +2112 -0
- package/dist/config/validator.js +658 -0
- package/dist/constants/cloud.d.ts +107 -0
- package/dist/constants/cloud.js +110 -0
- package/dist/constants/core.d.ts +521 -0
- package/dist/constants/core.js +556 -0
- package/dist/constants/testing.d.ts +1283 -0
- package/dist/constants/testing.js +1568 -0
- package/dist/constants.d.ts +10 -0
- package/dist/constants.js +10 -0
- package/dist/contract/index.d.ts +6 -0
- package/dist/contract/index.js +5 -0
- package/dist/contract/validator.d.ts +177 -0
- package/dist/contract/validator.js +574 -0
- package/dist/cost/index.d.ts +6 -0
- package/dist/cost/index.js +5 -0
- package/dist/cost/tracker.d.ts +134 -0
- package/dist/cost/tracker.js +313 -0
- package/dist/discovery/discovery.d.ts +16 -0
- package/dist/discovery/discovery.js +173 -0
- package/dist/discovery/types.d.ts +51 -0
- package/dist/discovery/types.js +2 -0
- package/dist/docs/agents.d.ts +3 -0
- package/dist/docs/agents.js +995 -0
- package/dist/docs/contract.d.ts +51 -0
- package/dist/docs/contract.js +1681 -0
- package/dist/docs/generator.d.ts +4 -0
- package/dist/docs/generator.js +4 -0
- package/dist/docs/html-reporter.d.ts +9 -0
- package/dist/docs/html-reporter.js +757 -0
- package/dist/docs/index.d.ts +10 -0
- package/dist/docs/index.js +11 -0
- package/dist/docs/junit-reporter.d.ts +18 -0
- package/dist/docs/junit-reporter.js +210 -0
- package/dist/docs/report.d.ts +14 -0
- package/dist/docs/report.js +44 -0
- package/dist/docs/sarif-reporter.d.ts +19 -0
- package/dist/docs/sarif-reporter.js +335 -0
- package/dist/docs/shared.d.ts +35 -0
- package/dist/docs/shared.js +162 -0
- package/dist/docs/templates.d.ts +12 -0
- package/dist/docs/templates.js +76 -0
- package/dist/errors/index.d.ts +6 -0
- package/dist/errors/index.js +6 -0
- package/dist/errors/retry.d.ts +92 -0
- package/dist/errors/retry.js +323 -0
- package/dist/errors/types.d.ts +321 -0
- package/dist/errors/types.js +584 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +32 -0
- package/dist/interview/dependency-resolver.d.ts +11 -0
- package/dist/interview/dependency-resolver.js +32 -0
- package/dist/interview/interviewer.d.ts +232 -0
- package/dist/interview/interviewer.js +1939 -0
- package/dist/interview/mock-response-generator.d.ts +7 -0
- package/dist/interview/mock-response-generator.js +102 -0
- package/dist/interview/orchestrator.d.ts +237 -0
- package/dist/interview/orchestrator.js +1296 -0
- package/dist/interview/rate-limiter.d.ts +15 -0
- package/dist/interview/rate-limiter.js +55 -0
- package/dist/interview/response-validator.d.ts +10 -0
- package/dist/interview/response-validator.js +132 -0
- package/dist/interview/schema-inferrer.d.ts +8 -0
- package/dist/interview/schema-inferrer.js +71 -0
- package/dist/interview/schema-test-generator.d.ts +71 -0
- package/dist/interview/schema-test-generator.js +834 -0
- package/dist/interview/smart-value-generator.d.ts +155 -0
- package/dist/interview/smart-value-generator.js +554 -0
- package/dist/interview/stateful-test-runner.d.ts +19 -0
- package/dist/interview/stateful-test-runner.js +106 -0
- package/dist/interview/types.d.ts +561 -0
- package/dist/interview/types.js +2 -0
- package/dist/llm/anthropic.d.ts +41 -0
- package/dist/llm/anthropic.js +355 -0
- package/dist/llm/client.d.ts +123 -0
- package/dist/llm/client.js +42 -0
- package/dist/llm/factory.d.ts +38 -0
- package/dist/llm/factory.js +145 -0
- package/dist/llm/fallback.d.ts +140 -0
- package/dist/llm/fallback.js +379 -0
- package/dist/llm/index.d.ts +18 -0
- package/dist/llm/index.js +15 -0
- package/dist/llm/ollama.d.ts +37 -0
- package/dist/llm/ollama.js +330 -0
- package/dist/llm/openai.d.ts +25 -0
- package/dist/llm/openai.js +320 -0
- package/dist/llm/token-budget.d.ts +161 -0
- package/dist/llm/token-budget.js +395 -0
- package/dist/logging/logger.d.ts +70 -0
- package/dist/logging/logger.js +130 -0
- package/dist/metrics/collector.d.ts +106 -0
- package/dist/metrics/collector.js +547 -0
- package/dist/metrics/index.d.ts +7 -0
- package/dist/metrics/index.js +7 -0
- package/dist/metrics/prometheus.d.ts +20 -0
- package/dist/metrics/prometheus.js +241 -0
- package/dist/metrics/types.d.ts +209 -0
- package/dist/metrics/types.js +5 -0
- package/dist/persona/builtins.d.ts +54 -0
- package/dist/persona/builtins.js +219 -0
- package/dist/persona/index.d.ts +8 -0
- package/dist/persona/index.js +8 -0
- package/dist/persona/loader.d.ts +30 -0
- package/dist/persona/loader.js +190 -0
- package/dist/persona/types.d.ts +144 -0
- package/dist/persona/types.js +5 -0
- package/dist/persona/validation.d.ts +94 -0
- package/dist/persona/validation.js +332 -0
- package/dist/prompts/index.d.ts +5 -0
- package/dist/prompts/index.js +5 -0
- package/dist/prompts/templates.d.ts +180 -0
- package/dist/prompts/templates.js +431 -0
- package/dist/registry/client.d.ts +49 -0
- package/dist/registry/client.js +191 -0
- package/dist/registry/index.d.ts +7 -0
- package/dist/registry/index.js +6 -0
- package/dist/registry/types.d.ts +140 -0
- package/dist/registry/types.js +6 -0
- package/dist/scenarios/evaluator.d.ts +43 -0
- package/dist/scenarios/evaluator.js +206 -0
- package/dist/scenarios/index.d.ts +10 -0
- package/dist/scenarios/index.js +9 -0
- package/dist/scenarios/loader.d.ts +20 -0
- package/dist/scenarios/loader.js +285 -0
- package/dist/scenarios/types.d.ts +153 -0
- package/dist/scenarios/types.js +8 -0
- package/dist/security/index.d.ts +17 -0
- package/dist/security/index.js +18 -0
- package/dist/security/payloads.d.ts +61 -0
- package/dist/security/payloads.js +268 -0
- package/dist/security/security-tester.d.ts +42 -0
- package/dist/security/security-tester.js +582 -0
- package/dist/security/types.d.ts +166 -0
- package/dist/security/types.js +8 -0
- package/dist/transport/base-transport.d.ts +59 -0
- package/dist/transport/base-transport.js +38 -0
- package/dist/transport/http-transport.d.ts +67 -0
- package/dist/transport/http-transport.js +238 -0
- package/dist/transport/mcp-client.d.ts +141 -0
- package/dist/transport/mcp-client.js +496 -0
- package/dist/transport/sse-transport.d.ts +88 -0
- package/dist/transport/sse-transport.js +316 -0
- package/dist/transport/stdio-transport.d.ts +43 -0
- package/dist/transport/stdio-transport.js +238 -0
- package/dist/transport/types.d.ts +125 -0
- package/dist/transport/types.js +16 -0
- package/dist/utils/concurrency.d.ts +123 -0
- package/dist/utils/concurrency.js +213 -0
- package/dist/utils/formatters.d.ts +16 -0
- package/dist/utils/formatters.js +37 -0
- package/dist/utils/index.d.ts +8 -0
- package/dist/utils/index.js +8 -0
- package/dist/utils/jsonpath.d.ts +87 -0
- package/dist/utils/jsonpath.js +326 -0
- package/dist/utils/markdown.d.ts +113 -0
- package/dist/utils/markdown.js +265 -0
- package/dist/utils/network.d.ts +14 -0
- package/dist/utils/network.js +17 -0
- package/dist/utils/sanitize.d.ts +92 -0
- package/dist/utils/sanitize.js +191 -0
- package/dist/utils/semantic.d.ts +194 -0
- package/dist/utils/semantic.js +1051 -0
- package/dist/utils/smart-truncate.d.ts +94 -0
- package/dist/utils/smart-truncate.js +361 -0
- package/dist/utils/timeout.d.ts +153 -0
- package/dist/utils/timeout.js +205 -0
- package/dist/utils/yaml-parser.d.ts +58 -0
- package/dist/utils/yaml-parser.js +86 -0
- package/dist/validation/index.d.ts +32 -0
- package/dist/validation/index.js +32 -0
- package/dist/validation/semantic-test-generator.d.ts +50 -0
- package/dist/validation/semantic-test-generator.js +176 -0
- package/dist/validation/semantic-types.d.ts +66 -0
- package/dist/validation/semantic-types.js +94 -0
- package/dist/validation/semantic-validator.d.ts +38 -0
- package/dist/validation/semantic-validator.js +340 -0
- package/dist/verification/index.d.ts +6 -0
- package/dist/verification/index.js +5 -0
- package/dist/verification/types.d.ts +133 -0
- package/dist/verification/types.js +5 -0
- package/dist/verification/verifier.d.ts +30 -0
- package/dist/verification/verifier.js +309 -0
- package/dist/version.d.ts +19 -0
- package/dist/version.js +48 -0
- package/dist/workflow/auto-generator.d.ts +27 -0
- package/dist/workflow/auto-generator.js +513 -0
- package/dist/workflow/discovery.d.ts +40 -0
- package/dist/workflow/discovery.js +195 -0
- package/dist/workflow/executor.d.ts +82 -0
- package/dist/workflow/executor.js +611 -0
- package/dist/workflow/index.d.ts +10 -0
- package/dist/workflow/index.js +10 -0
- package/dist/workflow/loader.d.ts +24 -0
- package/dist/workflow/loader.js +194 -0
- package/dist/workflow/state-tracker.d.ts +98 -0
- package/dist/workflow/state-tracker.js +424 -0
- package/dist/workflow/types.d.ts +337 -0
- package/dist/workflow/types.js +5 -0
- package/package.json +94 -0
- package/schemas/bellwether-check.schema.json +651 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Confidence Calibration for Drift Detection
|
|
3
|
+
*
|
|
4
|
+
* Calibrates raw confidence scores to match actual accuracy.
|
|
5
|
+
* A calibrated confidence of 80% means the algorithm is correct ~80% of the time
|
|
6
|
+
* when it reports that confidence level.
|
|
7
|
+
*
|
|
8
|
+
* Calibration is based on evaluation against the golden dataset.
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Default calibration model based on golden dataset evaluation.
|
|
12
|
+
*
|
|
13
|
+
* These values should be updated as the algorithm improves.
|
|
14
|
+
* Current baseline: v1.0.1 (50 test cases)
|
|
15
|
+
*/
|
|
16
|
+
export const DEFAULT_CALIBRATION_MODEL = [
|
|
17
|
+
// High confidence predictions
|
|
18
|
+
{ min: 90, max: 101, calibratedAccuracy: 85, sampleCount: 12 },
|
|
19
|
+
{ min: 80, max: 90, calibratedAccuracy: 75, sampleCount: 15 },
|
|
20
|
+
// Medium confidence predictions
|
|
21
|
+
{ min: 70, max: 80, calibratedAccuracy: 65, sampleCount: 10 },
|
|
22
|
+
{ min: 60, max: 70, calibratedAccuracy: 55, sampleCount: 8 },
|
|
23
|
+
// Low confidence predictions
|
|
24
|
+
{ min: 50, max: 60, calibratedAccuracy: 45, sampleCount: 5 },
|
|
25
|
+
{ min: 0, max: 50, calibratedAccuracy: 35, sampleCount: 10 },
|
|
26
|
+
];
|
|
27
|
+
/**
|
|
28
|
+
* Calibrate a raw confidence score to reflect actual accuracy.
|
|
29
|
+
*
|
|
30
|
+
* @param rawScore - Raw confidence score (0-100)
|
|
31
|
+
* @param model - Calibration model to use (defaults to DEFAULT_CALIBRATION_MODEL)
|
|
32
|
+
* @returns Calibrated confidence score
|
|
33
|
+
*/
|
|
34
|
+
export function calibrateConfidence(rawScore, model = DEFAULT_CALIBRATION_MODEL) {
|
|
35
|
+
// Find the bucket for this score
|
|
36
|
+
const bucket = model.find(b => rawScore >= b.min && rawScore < b.max);
|
|
37
|
+
if (!bucket) {
|
|
38
|
+
// Score outside all buckets, return as-is
|
|
39
|
+
return rawScore;
|
|
40
|
+
}
|
|
41
|
+
return bucket.calibratedAccuracy;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Format confidence score with calibration information.
|
|
45
|
+
*
|
|
46
|
+
* @param rawScore - Raw confidence score
|
|
47
|
+
* @param showRaw - Whether to show raw score alongside calibrated
|
|
48
|
+
* @returns Formatted string
|
|
49
|
+
*/
|
|
50
|
+
export function formatCalibratedConfidence(rawScore, showRaw = false) {
|
|
51
|
+
const calibrated = calibrateConfidence(rawScore);
|
|
52
|
+
if (showRaw && calibrated !== rawScore) {
|
|
53
|
+
return `${calibrated}% (raw: ${rawScore}%)`;
|
|
54
|
+
}
|
|
55
|
+
return `${calibrated}%`;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get confidence label based on calibrated score.
|
|
59
|
+
*/
|
|
60
|
+
export function getCalibratedConfidenceLabel(rawScore) {
|
|
61
|
+
const calibrated = calibrateConfidence(rawScore);
|
|
62
|
+
if (calibrated >= 75)
|
|
63
|
+
return 'high';
|
|
64
|
+
if (calibrated >= 55)
|
|
65
|
+
return 'medium';
|
|
66
|
+
if (calibrated >= 40)
|
|
67
|
+
return 'low';
|
|
68
|
+
return 'very-low';
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Check if a calibrated confidence meets a threshold.
|
|
72
|
+
*
|
|
73
|
+
* @param rawScore - Raw confidence score
|
|
74
|
+
* @param threshold - Minimum required calibrated confidence
|
|
75
|
+
* @returns True if calibrated confidence meets threshold
|
|
76
|
+
*/
|
|
77
|
+
export function meetsCalibratedThreshold(rawScore, threshold) {
|
|
78
|
+
return calibrateConfidence(rawScore) >= threshold;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Update calibration model based on evaluation results.
|
|
82
|
+
* This recalculates accuracy for each bucket from test results.
|
|
83
|
+
*
|
|
84
|
+
* @param results - Array of {predictedConfidence, wasCorrect} pairs
|
|
85
|
+
* @returns Updated calibration model
|
|
86
|
+
*/
|
|
87
|
+
export function updateCalibrationModel(results) {
|
|
88
|
+
const bucketRanges = [
|
|
89
|
+
{ min: 90, max: 101 },
|
|
90
|
+
{ min: 80, max: 90 },
|
|
91
|
+
{ min: 70, max: 80 },
|
|
92
|
+
{ min: 60, max: 70 },
|
|
93
|
+
{ min: 50, max: 60 },
|
|
94
|
+
{ min: 0, max: 50 },
|
|
95
|
+
];
|
|
96
|
+
return bucketRanges.map(range => {
|
|
97
|
+
const bucketResults = results.filter(r => r.predictedConfidence >= range.min && r.predictedConfidence < range.max);
|
|
98
|
+
if (bucketResults.length === 0) {
|
|
99
|
+
return {
|
|
100
|
+
...range,
|
|
101
|
+
calibratedAccuracy: (range.min + range.max) / 2,
|
|
102
|
+
sampleCount: 0,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
const correctCount = bucketResults.filter(r => r.wasCorrect).length;
|
|
106
|
+
const accuracy = Math.round((correctCount / bucketResults.length) * 100);
|
|
107
|
+
return {
|
|
108
|
+
...range,
|
|
109
|
+
calibratedAccuracy: accuracy,
|
|
110
|
+
sampleCount: bucketResults.length,
|
|
111
|
+
};
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Calculate calibration error (ECE - Expected Calibration Error).
|
|
116
|
+
* Lower is better. 0 = perfectly calibrated.
|
|
117
|
+
*
|
|
118
|
+
* @param model - Calibration model
|
|
119
|
+
* @returns ECE as a percentage (0-100)
|
|
120
|
+
*/
|
|
121
|
+
export function calculateCalibrationError(model) {
|
|
122
|
+
let totalError = 0;
|
|
123
|
+
let totalSamples = 0;
|
|
124
|
+
for (const bucket of model) {
|
|
125
|
+
if (bucket.sampleCount > 0) {
|
|
126
|
+
const midpoint = (bucket.min + bucket.max) / 2;
|
|
127
|
+
const error = Math.abs(midpoint - bucket.calibratedAccuracy);
|
|
128
|
+
totalError += error * bucket.sampleCount;
|
|
129
|
+
totalSamples += bucket.sampleCount;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (totalSamples === 0)
|
|
133
|
+
return 0;
|
|
134
|
+
return Math.round(totalError / totalSamples);
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=calibration.js.map
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Category Matching and Relationship Scoring
|
|
3
|
+
*
|
|
4
|
+
* Provides multi-category detection and relationship scoring for improved
|
|
5
|
+
* recall in semantic matching. Instead of first-match-wins, this module
|
|
6
|
+
* extracts ALL matching categories and scores relationships between them.
|
|
7
|
+
*
|
|
8
|
+
* Key improvements over single-category matching:
|
|
9
|
+
* 1. Multi-category detection - finds all matching categories
|
|
10
|
+
* 2. Relationship scoring - related categories get partial credit
|
|
11
|
+
* 3. Best-match selection - finds highest-confidence category pair
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Result of category extraction with confidence.
|
|
15
|
+
*/
|
|
16
|
+
export interface CategoryMatch {
|
|
17
|
+
category: string;
|
|
18
|
+
confidence: number;
|
|
19
|
+
matchedKeywords: string[];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Category relationship groups.
|
|
23
|
+
* Categories in the same group are related and should get partial credit.
|
|
24
|
+
*
|
|
25
|
+
* IMPORTANT (v1.3.0): Groups are now more conservative to prevent false positives.
|
|
26
|
+
* - Authentication and Authorization are NOT grouped (they're different concerns)
|
|
27
|
+
* - Injection types are more narrowly grouped
|
|
28
|
+
* - Only truly similar vulnerabilities are grouped
|
|
29
|
+
*/
|
|
30
|
+
export declare const SECURITY_CATEGORY_GROUPS: Record<string, string[]>;
|
|
31
|
+
/**
|
|
32
|
+
* Limitation category relationship groups.
|
|
33
|
+
*/
|
|
34
|
+
export declare const LIMITATION_CATEGORY_GROUPS: Record<string, string[]>;
|
|
35
|
+
/**
|
|
36
|
+
* Extract ALL matching security categories from text with confidence scores.
|
|
37
|
+
* Unlike single-category extraction, this returns all matches ranked by confidence.
|
|
38
|
+
*/
|
|
39
|
+
export declare function extractSecurityCategories(text: string): CategoryMatch[];
|
|
40
|
+
/**
|
|
41
|
+
* Extract ALL matching limitation categories from text with confidence scores.
|
|
42
|
+
*/
|
|
43
|
+
export declare function extractLimitationCategories(text: string): CategoryMatch[];
|
|
44
|
+
/**
|
|
45
|
+
* Calculate relationship score between two security categories.
|
|
46
|
+
* Returns 0-100 where:
|
|
47
|
+
* - 100: Same category
|
|
48
|
+
* - 70-90: Categories in same group
|
|
49
|
+
* - 40-60: Related categories
|
|
50
|
+
* - 0-30: Unrelated categories
|
|
51
|
+
*/
|
|
52
|
+
export declare function calculateSecurityCategoryRelationship(cat1: string, cat2: string): number;
|
|
53
|
+
/**
|
|
54
|
+
* Calculate relationship score between two limitation categories.
|
|
55
|
+
*/
|
|
56
|
+
export declare function calculateLimitationCategoryRelationship(cat1: string, cat2: string): number;
|
|
57
|
+
/**
|
|
58
|
+
* Find the best category match between two texts.
|
|
59
|
+
* Returns the highest-scoring category pair and their relationship score.
|
|
60
|
+
*/
|
|
61
|
+
export declare function findBestSecurityCategoryMatch(categories1: CategoryMatch[], categories2: CategoryMatch[]): {
|
|
62
|
+
cat1: string;
|
|
63
|
+
cat2: string;
|
|
64
|
+
relationshipScore: number;
|
|
65
|
+
combinedConfidence: number;
|
|
66
|
+
} | null;
|
|
67
|
+
/**
|
|
68
|
+
* Find the best limitation category match between two texts.
|
|
69
|
+
*/
|
|
70
|
+
export declare function findBestLimitationCategoryMatch(categories1: CategoryMatch[], categories2: CategoryMatch[]): {
|
|
71
|
+
cat1: string;
|
|
72
|
+
cat2: string;
|
|
73
|
+
relationshipScore: number;
|
|
74
|
+
combinedConfidence: number;
|
|
75
|
+
} | null;
|
|
76
|
+
/**
|
|
77
|
+
* Check if two security categories are considered matching.
|
|
78
|
+
* Uses relationship scoring for partial credit.
|
|
79
|
+
*/
|
|
80
|
+
export declare function securityCategoriesMatch(cat1: string, cat2: string): boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Check if two limitation categories are considered matching.
|
|
83
|
+
*/
|
|
84
|
+
export declare function limitationCategoriesMatch(cat1: string, cat2: string): boolean;
|
|
85
|
+
//# sourceMappingURL=category-matching.d.ts.map
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Category Matching and Relationship Scoring
|
|
3
|
+
*
|
|
4
|
+
* Provides multi-category detection and relationship scoring for improved
|
|
5
|
+
* recall in semantic matching. Instead of first-match-wins, this module
|
|
6
|
+
* extracts ALL matching categories and scores relationships between them.
|
|
7
|
+
*
|
|
8
|
+
* Key improvements over single-category matching:
|
|
9
|
+
* 1. Multi-category detection - finds all matching categories
|
|
10
|
+
* 2. Relationship scoring - related categories get partial credit
|
|
11
|
+
* 3. Best-match selection - finds highest-confidence category pair
|
|
12
|
+
*/
|
|
13
|
+
import { EXTENDED_SECURITY_KEYWORDS } from '../utils/semantic.js';
|
|
14
|
+
/**
|
|
15
|
+
* Category relationship groups.
|
|
16
|
+
* Categories in the same group are related and should get partial credit.
|
|
17
|
+
*
|
|
18
|
+
* IMPORTANT (v1.3.0): Groups are now more conservative to prevent false positives.
|
|
19
|
+
* - Authentication and Authorization are NOT grouped (they're different concerns)
|
|
20
|
+
* - Injection types are more narrowly grouped
|
|
21
|
+
* - Only truly similar vulnerabilities are grouped
|
|
22
|
+
*/
|
|
23
|
+
export const SECURITY_CATEGORY_GROUPS = {
|
|
24
|
+
// File/path related vulnerabilities (narrowed)
|
|
25
|
+
file_access: ['path_traversal', 'file_upload'],
|
|
26
|
+
// SQL-specific injection (narrowed - SQL and command injection are different)
|
|
27
|
+
sql_issues: ['sql_injection'],
|
|
28
|
+
// Command execution issues
|
|
29
|
+
command_issues: ['command_injection'],
|
|
30
|
+
// XSS-specific
|
|
31
|
+
xss_issues: ['xss', 'output_encoding'],
|
|
32
|
+
// Access control (without auth/authz - they're different)
|
|
33
|
+
access: ['access_control'],
|
|
34
|
+
// Data handling issues (narrowed)
|
|
35
|
+
data: ['information_disclosure', 'cryptography'],
|
|
36
|
+
// Input handling
|
|
37
|
+
input_handling: ['input_validation'],
|
|
38
|
+
// Server-side issues (narrowed)
|
|
39
|
+
server_side: ['ssrf'],
|
|
40
|
+
// Deserialization standalone
|
|
41
|
+
deserialization_issues: ['deserialization'],
|
|
42
|
+
// XXE standalone (different from deserialization despite both being data handling)
|
|
43
|
+
xxe_issues: ['xxe'],
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Limitation category relationship groups.
|
|
47
|
+
*/
|
|
48
|
+
export const LIMITATION_CATEGORY_GROUPS = {
|
|
49
|
+
// Resource constraints
|
|
50
|
+
resource: ['size_limit', 'memory', 'rate_limit'],
|
|
51
|
+
// Time-related
|
|
52
|
+
temporal: ['timeout', 'rate_limit'],
|
|
53
|
+
// Access-related
|
|
54
|
+
access: ['permission', 'platform'],
|
|
55
|
+
// Format-related
|
|
56
|
+
format: ['encoding', 'format'],
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Direct category similarity scores (0-100).
|
|
60
|
+
* Used for categories that are similar but not in the same group.
|
|
61
|
+
*
|
|
62
|
+
* IMPORTANT (v1.3.0): Reduced similarity scores to prevent false positives.
|
|
63
|
+
* Authentication vs Authorization are now considered DIFFERENT (not related).
|
|
64
|
+
* Only truly similar categories get partial credit.
|
|
65
|
+
*/
|
|
66
|
+
const CATEGORY_SIMILARITY = {
|
|
67
|
+
path_traversal: {
|
|
68
|
+
file_upload: 40, // Reduced - only somewhat related
|
|
69
|
+
information_disclosure: 30, // Reduced
|
|
70
|
+
},
|
|
71
|
+
sql_injection: {
|
|
72
|
+
input_validation: 40, // Reduced - input validation is generic
|
|
73
|
+
},
|
|
74
|
+
xss: {
|
|
75
|
+
output_encoding: 50, // Reduced
|
|
76
|
+
input_validation: 30, // Reduced
|
|
77
|
+
},
|
|
78
|
+
// IMPORTANT: authentication and authorization are now DIFFERENT
|
|
79
|
+
// They are distinct security concerns and should not match
|
|
80
|
+
authentication: {
|
|
81
|
+
session_management: 40, // Only session mgmt is somewhat related
|
|
82
|
+
},
|
|
83
|
+
authorization: {
|
|
84
|
+
access_control: 50, // Access control is related but distinct
|
|
85
|
+
},
|
|
86
|
+
input_validation: {
|
|
87
|
+
output_encoding: 40,
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Extract ALL matching security categories from text with confidence scores.
|
|
92
|
+
* Unlike single-category extraction, this returns all matches ranked by confidence.
|
|
93
|
+
*/
|
|
94
|
+
export function extractSecurityCategories(text) {
|
|
95
|
+
const matches = [];
|
|
96
|
+
const lowerText = text.toLowerCase();
|
|
97
|
+
for (const [category, keywords] of Object.entries(EXTENDED_SECURITY_KEYWORDS)) {
|
|
98
|
+
const matchedKeywords = keywords.filter(keyword => lowerText.includes(keyword));
|
|
99
|
+
if (matchedKeywords.length > 0) {
|
|
100
|
+
// Calculate confidence based on keyword match quality
|
|
101
|
+
const confidence = calculateCategoryConfidence(text, matchedKeywords, keywords);
|
|
102
|
+
matches.push({
|
|
103
|
+
category,
|
|
104
|
+
confidence,
|
|
105
|
+
matchedKeywords,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// Sort by confidence (highest first)
|
|
110
|
+
return matches.sort((a, b) => b.confidence - a.confidence);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Limitation category keywords for multi-category extraction.
|
|
114
|
+
*/
|
|
115
|
+
const LIMITATION_KEYWORDS = {
|
|
116
|
+
size_limit: ['size limit', 'max size', 'file size', 'mb', 'gb', 'kb', 'bytes', 'too large', 'megabytes', 'gigabytes', 'kilobytes', 'maximum'],
|
|
117
|
+
rate_limit: ['rate limit', 'throttle', 'requests per', 'quota', 'too many requests', 'rate limiting'],
|
|
118
|
+
timeout: ['timeout', 'time out', 'time limit', 'seconds', 'timed out', 'deadline', 'expires'],
|
|
119
|
+
encoding: ['encoding', 'utf-8', 'ascii', 'binary', 'charset', 'unicode'],
|
|
120
|
+
format: ['format', 'json', 'xml', 'csv', 'type', 'mime', 'content-type'],
|
|
121
|
+
permission: ['permission', 'access', 'denied', 'forbidden', 'read-only', 'write', 'privileges'],
|
|
122
|
+
platform: ['platform', 'windows', 'linux', 'macos', 'os-specific', 'operating system'],
|
|
123
|
+
dependency: ['dependency', 'requires', 'prerequisite', 'library', 'package', 'module'],
|
|
124
|
+
concurrency: ['concurrent', 'parallel', 'thread', 'lock', 'race condition', 'simultaneous'],
|
|
125
|
+
memory: ['memory', 'ram', 'heap', 'out of memory', 'memory limit'],
|
|
126
|
+
network: ['network', 'connection', 'offline', 'unreachable', 'connectivity'],
|
|
127
|
+
};
|
|
128
|
+
/**
|
|
129
|
+
* Extract ALL matching limitation categories from text with confidence scores.
|
|
130
|
+
*/
|
|
131
|
+
export function extractLimitationCategories(text) {
|
|
132
|
+
const matches = [];
|
|
133
|
+
const lowerText = text.toLowerCase();
|
|
134
|
+
for (const [category, keywords] of Object.entries(LIMITATION_KEYWORDS)) {
|
|
135
|
+
const matchedKeywords = keywords.filter(keyword => lowerText.includes(keyword));
|
|
136
|
+
if (matchedKeywords.length > 0) {
|
|
137
|
+
const confidence = calculateCategoryConfidence(text, matchedKeywords, keywords);
|
|
138
|
+
matches.push({
|
|
139
|
+
category,
|
|
140
|
+
confidence,
|
|
141
|
+
matchedKeywords,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return matches.sort((a, b) => b.confidence - a.confidence);
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Calculate confidence for a category match based on keyword quality.
|
|
149
|
+
*/
|
|
150
|
+
function calculateCategoryConfidence(text, matchedKeywords, allKeywords) {
|
|
151
|
+
if (matchedKeywords.length === 0)
|
|
152
|
+
return 0;
|
|
153
|
+
// Base confidence from keyword count
|
|
154
|
+
const keywordRatio = matchedKeywords.length / Math.min(allKeywords.length, 5);
|
|
155
|
+
let confidence = Math.min(keywordRatio * 60, 60); // Max 60 from keyword count
|
|
156
|
+
// Bonus for longer/more specific keywords
|
|
157
|
+
const avgKeywordLength = matchedKeywords.reduce((sum, k) => sum + k.length, 0) / matchedKeywords.length;
|
|
158
|
+
if (avgKeywordLength > 10)
|
|
159
|
+
confidence += 20;
|
|
160
|
+
else if (avgKeywordLength > 5)
|
|
161
|
+
confidence += 10;
|
|
162
|
+
// Bonus for multiple distinct keywords
|
|
163
|
+
if (matchedKeywords.length >= 3)
|
|
164
|
+
confidence += 15;
|
|
165
|
+
else if (matchedKeywords.length >= 2)
|
|
166
|
+
confidence += 10;
|
|
167
|
+
// Penalty if text is very long but few keywords matched
|
|
168
|
+
const textLength = text.length;
|
|
169
|
+
if (textLength > 200 && matchedKeywords.length === 1) {
|
|
170
|
+
confidence -= 10;
|
|
171
|
+
}
|
|
172
|
+
return Math.min(Math.max(confidence, 10), 100);
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Calculate relationship score between two security categories.
|
|
176
|
+
* Returns 0-100 where:
|
|
177
|
+
* - 100: Same category
|
|
178
|
+
* - 70-90: Categories in same group
|
|
179
|
+
* - 40-60: Related categories
|
|
180
|
+
* - 0-30: Unrelated categories
|
|
181
|
+
*/
|
|
182
|
+
export function calculateSecurityCategoryRelationship(cat1, cat2) {
|
|
183
|
+
if (cat1 === cat2)
|
|
184
|
+
return 100;
|
|
185
|
+
// Check direct similarity scores
|
|
186
|
+
const directScore = CATEGORY_SIMILARITY[cat1]?.[cat2] ?? CATEGORY_SIMILARITY[cat2]?.[cat1];
|
|
187
|
+
if (directScore !== undefined)
|
|
188
|
+
return directScore;
|
|
189
|
+
// Check if in same group
|
|
190
|
+
for (const groupCategories of Object.values(SECURITY_CATEGORY_GROUPS)) {
|
|
191
|
+
if (groupCategories.includes(cat1) && groupCategories.includes(cat2)) {
|
|
192
|
+
return 70; // Same group gets 70%
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// Unrelated
|
|
196
|
+
return 0;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Calculate relationship score between two limitation categories.
|
|
200
|
+
*/
|
|
201
|
+
export function calculateLimitationCategoryRelationship(cat1, cat2) {
|
|
202
|
+
if (cat1 === cat2)
|
|
203
|
+
return 100;
|
|
204
|
+
// Check if in same group
|
|
205
|
+
for (const groupCategories of Object.values(LIMITATION_CATEGORY_GROUPS)) {
|
|
206
|
+
if (groupCategories.includes(cat1) && groupCategories.includes(cat2)) {
|
|
207
|
+
return 70;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return 0;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Find the best category match between two texts.
|
|
214
|
+
* Returns the highest-scoring category pair and their relationship score.
|
|
215
|
+
*/
|
|
216
|
+
export function findBestSecurityCategoryMatch(categories1, categories2) {
|
|
217
|
+
if (categories1.length === 0 || categories2.length === 0) {
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
let bestMatch = null;
|
|
221
|
+
let bestScore = 0;
|
|
222
|
+
for (const c1 of categories1) {
|
|
223
|
+
for (const c2 of categories2) {
|
|
224
|
+
const relationshipScore = calculateSecurityCategoryRelationship(c1.category, c2.category);
|
|
225
|
+
if (relationshipScore > 0) {
|
|
226
|
+
// Combined score considers both category confidence and relationship
|
|
227
|
+
const combinedConfidence = Math.round((c1.confidence * 0.4 + c2.confidence * 0.4 + relationshipScore * 0.2));
|
|
228
|
+
// Prefer higher relationship scores, then higher combined confidence
|
|
229
|
+
const totalScore = relationshipScore * 100 + combinedConfidence;
|
|
230
|
+
if (totalScore > bestScore) {
|
|
231
|
+
bestScore = totalScore;
|
|
232
|
+
bestMatch = {
|
|
233
|
+
cat1: c1.category,
|
|
234
|
+
cat2: c2.category,
|
|
235
|
+
relationshipScore,
|
|
236
|
+
combinedConfidence,
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return bestMatch;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Find the best limitation category match between two texts.
|
|
246
|
+
*/
|
|
247
|
+
export function findBestLimitationCategoryMatch(categories1, categories2) {
|
|
248
|
+
if (categories1.length === 0 || categories2.length === 0) {
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
251
|
+
let bestMatch = null;
|
|
252
|
+
let bestScore = 0;
|
|
253
|
+
for (const c1 of categories1) {
|
|
254
|
+
for (const c2 of categories2) {
|
|
255
|
+
const relationshipScore = calculateLimitationCategoryRelationship(c1.category, c2.category);
|
|
256
|
+
if (relationshipScore > 0) {
|
|
257
|
+
const combinedConfidence = Math.round((c1.confidence * 0.4 + c2.confidence * 0.4 + relationshipScore * 0.2));
|
|
258
|
+
const totalScore = relationshipScore * 100 + combinedConfidence;
|
|
259
|
+
if (totalScore > bestScore) {
|
|
260
|
+
bestScore = totalScore;
|
|
261
|
+
bestMatch = {
|
|
262
|
+
cat1: c1.category,
|
|
263
|
+
cat2: c2.category,
|
|
264
|
+
relationshipScore,
|
|
265
|
+
combinedConfidence,
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return bestMatch;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Check if two security categories are considered matching.
|
|
275
|
+
* Uses relationship scoring for partial credit.
|
|
276
|
+
*/
|
|
277
|
+
export function securityCategoriesMatch(cat1, cat2) {
|
|
278
|
+
const relationshipScore = calculateSecurityCategoryRelationship(cat1, cat2);
|
|
279
|
+
// Consider matching if relationship score is 50 or higher
|
|
280
|
+
return relationshipScore >= 50;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Check if two limitation categories are considered matching.
|
|
284
|
+
*/
|
|
285
|
+
export function limitationCategoriesMatch(cat1, cat2) {
|
|
286
|
+
const relationshipScore = calculateLimitationCategoryRelationship(cat1, cat2);
|
|
287
|
+
return relationshipScore >= 50;
|
|
288
|
+
}
|
|
289
|
+
//# sourceMappingURL=category-matching.js.map
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Change Impact Analyzer
|
|
3
|
+
*
|
|
4
|
+
* Provides semantic understanding of schema changes and their impact.
|
|
5
|
+
* Goes beyond simple hash comparison to understand what actually breaks.
|
|
6
|
+
*/
|
|
7
|
+
import type { BehaviorChange, ChangeSeverity, ToolFingerprint, BehavioralBaseline, BehavioralDiff, WorkflowSignature } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Type of schema change detected.
|
|
10
|
+
*/
|
|
11
|
+
export type SchemaChangeType = 'parameter_removed' | 'parameter_added' | 'parameter_type_changed' | 'parameter_required_added' | 'parameter_required_removed' | 'enum_value_removed' | 'enum_value_added' | 'constraint_added' | 'constraint_removed' | 'constraint_tightened' | 'constraint_relaxed' | 'description_changed' | 'default_changed' | 'format_changed';
|
|
12
|
+
/**
|
|
13
|
+
* Detailed information about a single schema change.
|
|
14
|
+
*/
|
|
15
|
+
export interface SchemaChangeDetail {
|
|
16
|
+
type: SchemaChangeType;
|
|
17
|
+
parameterPath: string;
|
|
18
|
+
breaking: boolean;
|
|
19
|
+
before: unknown;
|
|
20
|
+
after: unknown;
|
|
21
|
+
description: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Migration complexity levels.
|
|
25
|
+
*/
|
|
26
|
+
export type MigrationComplexity = 'trivial' | 'simple' | 'moderate' | 'complex';
|
|
27
|
+
/**
|
|
28
|
+
* Comprehensive impact analysis for a change.
|
|
29
|
+
*/
|
|
30
|
+
export interface ChangeImpact {
|
|
31
|
+
/** Overall severity of the change */
|
|
32
|
+
severity: ChangeSeverity;
|
|
33
|
+
/** List of affected workflow IDs */
|
|
34
|
+
affectedWorkflows: string[];
|
|
35
|
+
/** List of affected parameter paths */
|
|
36
|
+
affectedParameters: string[];
|
|
37
|
+
/** Estimated complexity to migrate */
|
|
38
|
+
migrationComplexity: MigrationComplexity;
|
|
39
|
+
/** Suggested migration approach */
|
|
40
|
+
suggestedMigration: string;
|
|
41
|
+
/** Detailed breakdown of schema changes */
|
|
42
|
+
schemaChanges: SchemaChangeDetail[];
|
|
43
|
+
/** Whether this change is backwards compatible */
|
|
44
|
+
backwardsCompatible: boolean;
|
|
45
|
+
/** Risk score (0-100) */
|
|
46
|
+
riskScore: number;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Impact analysis results for the entire diff.
|
|
50
|
+
*/
|
|
51
|
+
export interface DiffImpactAnalysis {
|
|
52
|
+
/** Overall severity of all changes */
|
|
53
|
+
overallSeverity: ChangeSeverity;
|
|
54
|
+
/** Total number of breaking changes */
|
|
55
|
+
breakingChangesCount: number;
|
|
56
|
+
/** Per-tool impact analysis */
|
|
57
|
+
toolImpacts: Map<string, ChangeImpact>;
|
|
58
|
+
/** Workflows that will fail due to changes */
|
|
59
|
+
brokenWorkflows: string[];
|
|
60
|
+
/** Overall migration complexity */
|
|
61
|
+
overallMigrationComplexity: MigrationComplexity;
|
|
62
|
+
/** Summary of all changes */
|
|
63
|
+
summary: string;
|
|
64
|
+
/** Action items for addressing the changes */
|
|
65
|
+
actionItems: ActionItem[];
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Action item for addressing a change.
|
|
69
|
+
*/
|
|
70
|
+
export interface ActionItem {
|
|
71
|
+
priority: 'critical' | 'high' | 'medium' | 'low';
|
|
72
|
+
tool: string;
|
|
73
|
+
description: string;
|
|
74
|
+
suggestedAction: string;
|
|
75
|
+
}
|
|
76
|
+
export { CHANGE_IMPACT } from '../constants.js';
|
|
77
|
+
/**
|
|
78
|
+
* Analyze the impact of changes between two tool fingerprints.
|
|
79
|
+
*/
|
|
80
|
+
export declare function analyzeToolChangeImpact(oldTool: ToolFingerprint, newTool: ToolFingerprint, workflows?: WorkflowSignature[]): ChangeImpact;
|
|
81
|
+
/**
|
|
82
|
+
* Analyze a complete diff and provide comprehensive impact analysis.
|
|
83
|
+
*/
|
|
84
|
+
export declare function analyzeDiffImpact(diff: BehavioralDiff, oldBaseline: BehavioralBaseline, newBaseline: BehavioralBaseline): DiffImpactAnalysis;
|
|
85
|
+
/**
|
|
86
|
+
* Analyze changes between two schemas and return detailed change information.
|
|
87
|
+
*/
|
|
88
|
+
export declare function analyzeSchemaChanges(oldSchema: Record<string, unknown> | undefined, newSchema: Record<string, unknown> | undefined): SchemaChangeDetail[];
|
|
89
|
+
/**
|
|
90
|
+
* Check if a behavior change is actually breaking based on semantic analysis.
|
|
91
|
+
* This enhances the simple hash-based comparison with semantic understanding.
|
|
92
|
+
*/
|
|
93
|
+
export declare function isBreakingChange(change: BehaviorChange): boolean;
|
|
94
|
+
/**
|
|
95
|
+
* Get a quick summary of breaking changes for CI output.
|
|
96
|
+
*/
|
|
97
|
+
export declare function getBreakingChangeSummary(analysis: DiffImpactAnalysis): string;
|
|
98
|
+
//# sourceMappingURL=change-impact-analyzer.d.ts.map
|