vibecheck-ai 2.0.1 → 5.0.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/bin/.generated +25 -0
- package/bin/_deprecations.js +463 -0
- package/bin/_router.js +46 -0
- package/bin/cli-hygiene.js +241 -0
- package/bin/dev/run-v2-torture.js +30 -0
- package/bin/registry.js +656 -0
- package/bin/runners/CLI_REFACTOR_SUMMARY.md +229 -0
- package/bin/runners/ENHANCEMENT_GUIDE.md +121 -0
- package/bin/runners/REPORT_AUDIT.md +64 -0
- package/bin/runners/cli-utils.js +1070 -0
- package/bin/runners/context/ai-task-decomposer.js +337 -0
- package/bin/runners/context/analyzer.js +513 -0
- package/bin/runners/context/api-contracts.js +427 -0
- package/bin/runners/context/context-diff.js +342 -0
- package/bin/runners/context/context-pruner.js +291 -0
- package/bin/runners/context/dependency-graph.js +414 -0
- package/bin/runners/context/generators/claude.js +107 -0
- package/bin/runners/context/generators/codex.js +108 -0
- package/bin/runners/context/generators/copilot.js +119 -0
- package/bin/runners/context/generators/cursor-enhanced.js +2525 -0
- package/bin/runners/context/generators/cursor.js +514 -0
- package/bin/runners/context/generators/mcp.js +169 -0
- package/bin/runners/context/generators/windsurf.js +180 -0
- package/bin/runners/context/git-context.js +304 -0
- package/bin/runners/context/index.js +1110 -0
- package/bin/runners/context/insights.js +173 -0
- package/bin/runners/context/mcp-server/generate-rules.js +337 -0
- package/bin/runners/context/mcp-server/index.js +1176 -0
- package/bin/runners/context/mcp-server/package.json +24 -0
- package/bin/runners/context/memory.js +200 -0
- package/bin/runners/context/monorepo.js +215 -0
- package/bin/runners/context/multi-repo-federation.js +404 -0
- package/bin/runners/context/patterns.js +253 -0
- package/bin/runners/context/proof-context.js +1264 -0
- package/bin/runners/context/security-scanner.js +541 -0
- package/bin/runners/context/semantic-search.js +350 -0
- package/bin/runners/context/shared.js +264 -0
- package/bin/runners/context/team-conventions.js +336 -0
- package/bin/runners/lib/__tests__/entitlements-v2.test.js +295 -0
- package/bin/runners/lib/agent-firewall/ai/false-positive-analyzer.js +474 -0
- package/bin/runners/lib/agent-firewall/change-packet/builder.js +488 -0
- package/bin/runners/lib/agent-firewall/change-packet/schema.json +228 -0
- package/bin/runners/lib/agent-firewall/change-packet/store.js +200 -0
- package/bin/runners/lib/agent-firewall/claims/claim-types.js +21 -0
- package/bin/runners/lib/agent-firewall/claims/extractor.js +303 -0
- package/bin/runners/lib/agent-firewall/claims/patterns.js +24 -0
- package/bin/runners/lib/agent-firewall/critic/index.js +151 -0
- package/bin/runners/lib/agent-firewall/critic/judge.js +432 -0
- package/bin/runners/lib/agent-firewall/critic/prompts.js +305 -0
- package/bin/runners/lib/agent-firewall/enforcement/gateway.js +1059 -0
- package/bin/runners/lib/agent-firewall/enforcement/index.js +98 -0
- package/bin/runners/lib/agent-firewall/enforcement/mode.js +318 -0
- package/bin/runners/lib/agent-firewall/enforcement/orchestrator.js +484 -0
- package/bin/runners/lib/agent-firewall/enforcement/proof-artifact.js +418 -0
- package/bin/runners/lib/agent-firewall/enforcement/schemas/change-event.schema.json +173 -0
- package/bin/runners/lib/agent-firewall/enforcement/schemas/intent.schema.json +181 -0
- package/bin/runners/lib/agent-firewall/enforcement/schemas/verdict.schema.json +222 -0
- package/bin/runners/lib/agent-firewall/enforcement/verdict-v2.js +333 -0
- package/bin/runners/lib/agent-firewall/evidence/auth-evidence.js +88 -0
- package/bin/runners/lib/agent-firewall/evidence/contract-evidence.js +75 -0
- package/bin/runners/lib/agent-firewall/evidence/env-evidence.js +127 -0
- package/bin/runners/lib/agent-firewall/evidence/resolver.js +102 -0
- package/bin/runners/lib/agent-firewall/evidence/route-evidence.js +213 -0
- package/bin/runners/lib/agent-firewall/evidence/side-effect-evidence.js +145 -0
- package/bin/runners/lib/agent-firewall/fs-hook/daemon.js +19 -0
- package/bin/runners/lib/agent-firewall/fs-hook/installer.js +87 -0
- package/bin/runners/lib/agent-firewall/fs-hook/watcher.js +184 -0
- package/bin/runners/lib/agent-firewall/git-hook/pre-commit.js +163 -0
- package/bin/runners/lib/agent-firewall/ide-extension/cursor.js +107 -0
- package/bin/runners/lib/agent-firewall/ide-extension/vscode.js +68 -0
- package/bin/runners/lib/agent-firewall/ide-extension/windsurf.js +66 -0
- package/bin/runners/lib/agent-firewall/index.js +200 -0
- package/bin/runners/lib/agent-firewall/integration/index.js +20 -0
- package/bin/runners/lib/agent-firewall/integration/ship-gate.js +437 -0
- package/bin/runners/lib/agent-firewall/intent/alignment-engine.js +634 -0
- package/bin/runners/lib/agent-firewall/intent/auto-detect.js +426 -0
- package/bin/runners/lib/agent-firewall/intent/index.js +102 -0
- package/bin/runners/lib/agent-firewall/intent/schema.js +352 -0
- package/bin/runners/lib/agent-firewall/intent/store.js +283 -0
- package/bin/runners/lib/agent-firewall/interception/fs-interceptor.js +502 -0
- package/bin/runners/lib/agent-firewall/interception/index.js +23 -0
- package/bin/runners/lib/agent-firewall/interceptor/base.js +308 -0
- package/bin/runners/lib/agent-firewall/interceptor/cursor.js +35 -0
- package/bin/runners/lib/agent-firewall/interceptor/vscode.js +35 -0
- package/bin/runners/lib/agent-firewall/interceptor/windsurf.js +34 -0
- package/bin/runners/lib/agent-firewall/lawbook/distributor.js +465 -0
- package/bin/runners/lib/agent-firewall/lawbook/evaluator.js +604 -0
- package/bin/runners/lib/agent-firewall/lawbook/index.js +304 -0
- package/bin/runners/lib/agent-firewall/lawbook/registry.js +514 -0
- package/bin/runners/lib/agent-firewall/lawbook/schema.js +420 -0
- package/bin/runners/lib/agent-firewall/logger.js +141 -0
- package/bin/runners/lib/agent-firewall/policy/default-policy.json +90 -0
- package/bin/runners/lib/agent-firewall/policy/engine.js +103 -0
- package/bin/runners/lib/agent-firewall/policy/loader.js +451 -0
- package/bin/runners/lib/agent-firewall/policy/rules/auth-drift.js +50 -0
- package/bin/runners/lib/agent-firewall/policy/rules/contract-drift.js +50 -0
- package/bin/runners/lib/agent-firewall/policy/rules/fake-success.js +79 -0
- package/bin/runners/lib/agent-firewall/policy/rules/ghost-env.js +227 -0
- package/bin/runners/lib/agent-firewall/policy/rules/ghost-route.js +191 -0
- package/bin/runners/lib/agent-firewall/policy/rules/scope.js +93 -0
- package/bin/runners/lib/agent-firewall/policy/rules/unsafe-side-effect.js +57 -0
- package/bin/runners/lib/agent-firewall/policy/schema.json +183 -0
- package/bin/runners/lib/agent-firewall/policy/verdict.js +54 -0
- package/bin/runners/lib/agent-firewall/proposal/extractor.js +394 -0
- package/bin/runners/lib/agent-firewall/proposal/index.js +212 -0
- package/bin/runners/lib/agent-firewall/proposal/schema.js +251 -0
- package/bin/runners/lib/agent-firewall/proposal/validator.js +386 -0
- package/bin/runners/lib/agent-firewall/reality/index.js +332 -0
- package/bin/runners/lib/agent-firewall/reality/state.js +625 -0
- package/bin/runners/lib/agent-firewall/reality/watcher.js +322 -0
- package/bin/runners/lib/agent-firewall/risk/index.js +173 -0
- package/bin/runners/lib/agent-firewall/risk/scorer.js +328 -0
- package/bin/runners/lib/agent-firewall/risk/thresholds.js +322 -0
- package/bin/runners/lib/agent-firewall/risk/vectors.js +421 -0
- package/bin/runners/lib/agent-firewall/session/collector.js +451 -0
- package/bin/runners/lib/agent-firewall/session/index.js +26 -0
- package/bin/runners/lib/agent-firewall/simulator/diff-simulator.js +472 -0
- package/bin/runners/lib/agent-firewall/simulator/import-resolver.js +346 -0
- package/bin/runners/lib/agent-firewall/simulator/index.js +181 -0
- package/bin/runners/lib/agent-firewall/simulator/route-validator.js +380 -0
- package/bin/runners/lib/agent-firewall/time-machine/incident-correlator.js +661 -0
- package/bin/runners/lib/agent-firewall/time-machine/index.js +267 -0
- package/bin/runners/lib/agent-firewall/time-machine/replay-engine.js +436 -0
- package/bin/runners/lib/agent-firewall/time-machine/state-reconstructor.js +490 -0
- package/bin/runners/lib/agent-firewall/time-machine/timeline-builder.js +530 -0
- package/bin/runners/lib/agent-firewall/truthpack/index.js +67 -0
- package/bin/runners/lib/agent-firewall/truthpack/loader.js +137 -0
- package/bin/runners/lib/agent-firewall/unblock/planner.js +337 -0
- package/bin/runners/lib/agent-firewall/utils/ignore-checker.js +118 -0
- package/bin/runners/lib/ai-bridge.js +416 -0
- package/bin/runners/lib/analysis-core.js +309 -0
- package/bin/runners/lib/analyzers.js +2500 -0
- package/bin/runners/lib/api-client.js +269 -0
- package/bin/runners/lib/approve-output.js +235 -0
- package/bin/runners/lib/artifact-envelope.js +540 -0
- package/bin/runners/lib/assets/vibecheck-logo.png +0 -0
- package/bin/runners/lib/audit-bridge.js +391 -0
- package/bin/runners/lib/auth-shared.js +977 -0
- package/bin/runners/lib/auth-truth.js +193 -0
- package/bin/runners/lib/auth.js +215 -0
- package/bin/runners/lib/authority-badge.js +425 -0
- package/bin/runners/lib/backup.js +62 -0
- package/bin/runners/lib/billing.js +107 -0
- package/bin/runners/lib/checkpoint.js +941 -0
- package/bin/runners/lib/claims.js +118 -0
- package/bin/runners/lib/classify-output.js +204 -0
- package/bin/runners/lib/cleanup/engine.js +571 -0
- package/bin/runners/lib/cleanup/index.js +53 -0
- package/bin/runners/lib/cleanup/output.js +375 -0
- package/bin/runners/lib/cleanup/rules.js +1060 -0
- package/bin/runners/lib/cli-output.js +400 -0
- package/bin/runners/lib/cli-ui.js +540 -0
- package/bin/runners/lib/compliance-bridge-new.js +0 -0
- package/bin/runners/lib/compliance-bridge.js +165 -0
- package/bin/runners/lib/contracts/auth-contract.js +202 -0
- package/bin/runners/lib/contracts/env-contract.js +181 -0
- package/bin/runners/lib/contracts/external-contract.js +206 -0
- package/bin/runners/lib/contracts/guard.js +168 -0
- package/bin/runners/lib/contracts/index.js +89 -0
- package/bin/runners/lib/contracts/plan-validator.js +311 -0
- package/bin/runners/lib/contracts/route-contract.js +199 -0
- package/bin/runners/lib/contracts.js +804 -0
- package/bin/runners/lib/default-config.js +127 -0
- package/bin/runners/lib/detect.js +89 -0
- package/bin/runners/lib/detectors-v2.js +622 -0
- package/bin/runners/lib/doctor/autofix.js +254 -0
- package/bin/runners/lib/doctor/diagnosis-receipt.js +454 -0
- package/bin/runners/lib/doctor/failure-signatures.js +526 -0
- package/bin/runners/lib/doctor/fix-script.js +336 -0
- package/bin/runners/lib/doctor/index.js +37 -0
- package/bin/runners/lib/doctor/modules/build-tools.js +453 -0
- package/bin/runners/lib/doctor/modules/dependencies.js +325 -0
- package/bin/runners/lib/doctor/modules/index.js +105 -0
- package/bin/runners/lib/doctor/modules/network.js +250 -0
- package/bin/runners/lib/doctor/modules/os-quirks.js +706 -0
- package/bin/runners/lib/doctor/modules/project.js +312 -0
- package/bin/runners/lib/doctor/modules/repo-integrity.js +485 -0
- package/bin/runners/lib/doctor/modules/runtime.js +224 -0
- package/bin/runners/lib/doctor/modules/security.js +350 -0
- package/bin/runners/lib/doctor/modules/system.js +213 -0
- package/bin/runners/lib/doctor/modules/vibecheck.js +394 -0
- package/bin/runners/lib/doctor/reporter.js +262 -0
- package/bin/runners/lib/doctor/safe-repair.js +384 -0
- package/bin/runners/lib/doctor/service.js +262 -0
- package/bin/runners/lib/doctor/types.js +113 -0
- package/bin/runners/lib/doctor/ui.js +263 -0
- package/bin/runners/lib/doctor-enhanced.js +233 -0
- package/bin/runners/lib/doctor-output.js +226 -0
- package/bin/runners/lib/doctor-v2.js +608 -0
- package/bin/runners/lib/drift.js +425 -0
- package/bin/runners/lib/enforcement.js +72 -0
- package/bin/runners/lib/engine/ast-cache.js +210 -0
- package/bin/runners/lib/engine/auth-extractor.js +211 -0
- package/bin/runners/lib/engine/billing-extractor.js +112 -0
- package/bin/runners/lib/engine/enforcement-extractor.js +100 -0
- package/bin/runners/lib/engine/env-extractor.js +207 -0
- package/bin/runners/lib/engine/express-extractor.js +208 -0
- package/bin/runners/lib/engine/extractors.js +849 -0
- package/bin/runners/lib/engine/index.js +207 -0
- package/bin/runners/lib/engine/repo-index.js +514 -0
- package/bin/runners/lib/engine/types.js +124 -0
- package/bin/runners/lib/engines/accessibility-engine.js +190 -0
- package/bin/runners/lib/engines/api-consistency-engine.js +162 -0
- package/bin/runners/lib/engines/ast-cache.js +99 -0
- package/bin/runners/lib/engines/attack-detector.js +1192 -0
- package/bin/runners/lib/engines/code-quality-engine.js +255 -0
- package/bin/runners/lib/engines/console-logs-engine.js +115 -0
- package/bin/runners/lib/engines/cross-file-analysis-engine.js +268 -0
- package/bin/runners/lib/engines/dead-code-engine.js +198 -0
- package/bin/runners/lib/engines/deprecated-api-engine.js +226 -0
- package/bin/runners/lib/engines/empty-catch-engine.js +150 -0
- package/bin/runners/lib/engines/file-filter.js +131 -0
- package/bin/runners/lib/engines/hardcoded-secrets-engine.js +251 -0
- package/bin/runners/lib/engines/mock-data-engine.js +272 -0
- package/bin/runners/lib/engines/parallel-processor.js +71 -0
- package/bin/runners/lib/engines/performance-issues-engine.js +265 -0
- package/bin/runners/lib/engines/security-vulnerabilities-engine.js +243 -0
- package/bin/runners/lib/engines/todo-fixme-engine.js +115 -0
- package/bin/runners/lib/engines/type-aware-engine.js +152 -0
- package/bin/runners/lib/engines/unsafe-regex-engine.js +225 -0
- package/bin/runners/lib/engines/vibecheck-engines/README.md +53 -0
- package/bin/runners/lib/engines/vibecheck-engines/index.js +15 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/ast-cache.js +164 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/code-quality-engine.js +291 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/console-logs-engine.js +83 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/dead-code-engine.js +198 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/deprecated-api-engine.js +275 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/empty-catch-engine.js +167 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/file-filter.js +217 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/hardcoded-secrets-engine.js +139 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/mock-data-engine.js +140 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/parallel-processor.js +164 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/performance-issues-engine.js +234 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/type-aware-engine.js +217 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/unsafe-regex-engine.js +78 -0
- package/bin/runners/lib/engines/vibecheck-engines/package.json +13 -0
- package/bin/runners/lib/enterprise-detect.js +603 -0
- package/bin/runners/lib/enterprise-init.js +942 -0
- package/bin/runners/lib/entitlements-v2.js +265 -0
- package/bin/runners/lib/entitlements.generated.js +0 -0
- package/bin/runners/lib/entitlements.js +340 -0
- package/bin/runners/lib/env-resolver.js +417 -0
- package/bin/runners/lib/env-template.js +66 -0
- package/bin/runners/lib/env.js +189 -0
- package/bin/runners/lib/error-handler.js +368 -0
- package/bin/runners/lib/error-messages.js +289 -0
- package/bin/runners/lib/evidence-pack.js +684 -0
- package/bin/runners/lib/exit-codes.js +275 -0
- package/bin/runners/lib/extractors/client-calls.js +990 -0
- package/bin/runners/lib/extractors/fastify-route-dump.js +573 -0
- package/bin/runners/lib/extractors/fastify-routes.js +426 -0
- package/bin/runners/lib/extractors/index.js +363 -0
- package/bin/runners/lib/extractors/next-routes.js +524 -0
- package/bin/runners/lib/extractors/proof-graph.js +431 -0
- package/bin/runners/lib/extractors/route-matcher.js +451 -0
- package/bin/runners/lib/extractors/truthpack-v2.js +377 -0
- package/bin/runners/lib/extractors/ui-bindings.js +547 -0
- package/bin/runners/lib/finding-id.js +69 -0
- package/bin/runners/lib/finding-sorter.js +89 -0
- package/bin/runners/lib/findings-schema.js +281 -0
- package/bin/runners/lib/fingerprint.js +377 -0
- package/bin/runners/lib/firewall-prompt.js +50 -0
- package/bin/runners/lib/fix-output.js +228 -0
- package/bin/runners/lib/global-flags.js +250 -0
- package/bin/runners/lib/graph/graph-builder.js +265 -0
- package/bin/runners/lib/graph/html-renderer.js +413 -0
- package/bin/runners/lib/graph/index.js +32 -0
- package/bin/runners/lib/graph/runtime-collector.js +215 -0
- package/bin/runners/lib/graph/static-extractor.js +518 -0
- package/bin/runners/lib/help-formatter.js +413 -0
- package/bin/runners/lib/html-proof-report.js +913 -0
- package/bin/runners/lib/html-report.js +650 -0
- package/bin/runners/lib/init-wizard.js +601 -0
- package/bin/runners/lib/interactive-menu.js +1496 -0
- package/bin/runners/lib/json-output.js +76 -0
- package/bin/runners/lib/llm.js +75 -0
- package/bin/runners/lib/logger.js +38 -0
- package/bin/runners/lib/meter.js +61 -0
- package/bin/runners/lib/missions/briefing.js +427 -0
- package/bin/runners/lib/missions/checkpoint.js +753 -0
- package/bin/runners/lib/missions/evidence.js +126 -0
- package/bin/runners/lib/missions/hardening.js +851 -0
- package/bin/runners/lib/missions/plan.js +648 -0
- package/bin/runners/lib/missions/safety-gates.js +645 -0
- package/bin/runners/lib/missions/schema.js +478 -0
- package/bin/runners/lib/missions/templates.js +317 -0
- package/bin/runners/lib/next-action.js +560 -0
- package/bin/runners/lib/packs/bundle.js +675 -0
- package/bin/runners/lib/packs/evidence-pack.js +671 -0
- package/bin/runners/lib/packs/pack-factory.js +837 -0
- package/bin/runners/lib/packs/permissions-pack.js +686 -0
- package/bin/runners/lib/packs/proof-graph-pack.js +779 -0
- package/bin/runners/lib/patch.js +40 -0
- package/bin/runners/lib/permissions/auth-model.js +213 -0
- package/bin/runners/lib/permissions/idor-prover.js +205 -0
- package/bin/runners/lib/permissions/index.js +45 -0
- package/bin/runners/lib/permissions/matrix-builder.js +198 -0
- package/bin/runners/lib/pkgjson.js +28 -0
- package/bin/runners/lib/policy.js +295 -0
- package/bin/runners/lib/polish/accessibility.js +62 -0
- package/bin/runners/lib/polish/analyzer.js +93 -0
- package/bin/runners/lib/polish/backend.js +87 -0
- package/bin/runners/lib/polish/configuration.js +83 -0
- package/bin/runners/lib/polish/documentation.js +83 -0
- package/bin/runners/lib/polish/frontend.js +817 -0
- package/bin/runners/lib/polish/index.js +27 -0
- package/bin/runners/lib/polish/infrastructure.js +80 -0
- package/bin/runners/lib/polish/internationalization.js +85 -0
- package/bin/runners/lib/polish/libraries.js +180 -0
- package/bin/runners/lib/polish/observability.js +75 -0
- package/bin/runners/lib/polish/performance.js +64 -0
- package/bin/runners/lib/polish/privacy.js +110 -0
- package/bin/runners/lib/polish/resilience.js +92 -0
- package/bin/runners/lib/polish/security.js +78 -0
- package/bin/runners/lib/polish/seo.js +71 -0
- package/bin/runners/lib/polish/styles.js +62 -0
- package/bin/runners/lib/polish/utils.js +104 -0
- package/bin/runners/lib/preflight.js +142 -0
- package/bin/runners/lib/prerequisites.js +149 -0
- package/bin/runners/lib/prove-output.js +220 -0
- package/bin/runners/lib/reality/correlation-detectors.js +359 -0
- package/bin/runners/lib/reality/index.js +318 -0
- package/bin/runners/lib/reality/request-hashing.js +416 -0
- package/bin/runners/lib/reality/request-mapper.js +453 -0
- package/bin/runners/lib/reality/safety-rails.js +463 -0
- package/bin/runners/lib/reality/semantic-snapshot.js +408 -0
- package/bin/runners/lib/reality/toast-detector.js +393 -0
- package/bin/runners/lib/reality-findings.js +84 -0
- package/bin/runners/lib/reality-output.js +231 -0
- package/bin/runners/lib/receipts.js +179 -0
- package/bin/runners/lib/redact.js +29 -0
- package/bin/runners/lib/replay/capsule-manager.js +154 -0
- package/bin/runners/lib/replay/index.js +263 -0
- package/bin/runners/lib/replay/player.js +348 -0
- package/bin/runners/lib/replay/recorder.js +331 -0
- package/bin/runners/lib/report-engine.js +626 -0
- package/bin/runners/lib/report-html.js +1233 -0
- package/bin/runners/lib/report-output.js +366 -0
- package/bin/runners/lib/report-templates.js +967 -0
- package/bin/runners/lib/report.js +135 -0
- package/bin/runners/lib/route-detection.js +1209 -0
- package/bin/runners/lib/route-truth.js +1322 -0
- package/bin/runners/lib/safelist/index.js +96 -0
- package/bin/runners/lib/safelist/integration.js +334 -0
- package/bin/runners/lib/safelist/matcher.js +696 -0
- package/bin/runners/lib/safelist/schema.js +948 -0
- package/bin/runners/lib/safelist/store.js +438 -0
- package/bin/runners/lib/sandbox/index.js +59 -0
- package/bin/runners/lib/sandbox/proof-chain.js +399 -0
- package/bin/runners/lib/sandbox/sandbox-runner.js +205 -0
- package/bin/runners/lib/sandbox/worktree.js +174 -0
- package/bin/runners/lib/scan-cache.js +330 -0
- package/bin/runners/lib/scan-output-schema.js +344 -0
- package/bin/runners/lib/scan-output.js +631 -0
- package/bin/runners/lib/scan-runner.js +135 -0
- package/bin/runners/lib/schema-validator.js +350 -0
- package/bin/runners/lib/schemas/ajv-validator.js +464 -0
- package/bin/runners/lib/schemas/contracts.schema.json +160 -0
- package/bin/runners/lib/schemas/error-envelope.schema.json +105 -0
- package/bin/runners/lib/schemas/finding-v3.schema.json +151 -0
- package/bin/runners/lib/schemas/finding.schema.json +100 -0
- package/bin/runners/lib/schemas/mission-pack.schema.json +206 -0
- package/bin/runners/lib/schemas/proof-graph.schema.json +176 -0
- package/bin/runners/lib/schemas/reality-report.schema.json +162 -0
- package/bin/runners/lib/schemas/report-artifact.schema.json +120 -0
- package/bin/runners/lib/schemas/run-request.schema.json +108 -0
- package/bin/runners/lib/schemas/share-pack.schema.json +180 -0
- package/bin/runners/lib/schemas/ship-manifest.schema.json +251 -0
- package/bin/runners/lib/schemas/ship-report.schema.json +117 -0
- package/bin/runners/lib/schemas/truthpack-v2.schema.json +303 -0
- package/bin/runners/lib/schemas/validator.js +465 -0
- package/bin/runners/lib/schemas/verdict.schema.json +140 -0
- package/bin/runners/lib/score-history.js +282 -0
- package/bin/runners/lib/security-bridge.js +249 -0
- package/bin/runners/lib/server-usage.js +513 -0
- package/bin/runners/lib/share-pack.js +239 -0
- package/bin/runners/lib/ship-gate.js +832 -0
- package/bin/runners/lib/ship-manifest.js +1153 -0
- package/bin/runners/lib/ship-output-enterprise.js +239 -0
- package/bin/runners/lib/ship-output.js +1128 -0
- package/bin/runners/lib/snippets.js +67 -0
- package/bin/runners/lib/status-output.js +340 -0
- package/bin/runners/lib/terminal-ui.js +356 -0
- package/bin/runners/lib/truth.js +1691 -0
- package/bin/runners/lib/ui.js +562 -0
- package/bin/runners/lib/unified-cli-output.js +947 -0
- package/bin/runners/lib/unified-output.js +197 -0
- package/bin/runners/lib/upsell.js +410 -0
- package/bin/runners/lib/usage.js +153 -0
- package/bin/runners/lib/validate-patch.js +156 -0
- package/bin/runners/lib/verdict-engine.js +628 -0
- package/bin/runners/lib/verification.js +345 -0
- package/bin/runners/lib/why-tree.js +650 -0
- package/bin/runners/reality/engine.js +917 -0
- package/bin/runners/reality/flows.js +122 -0
- package/bin/runners/reality/report.js +378 -0
- package/bin/runners/reality/session.js +193 -0
- package/bin/runners/runAIAgent.js +229 -0
- package/bin/runners/runAgent.d.ts +5 -0
- package/bin/runners/runAgent.js +161 -0
- package/bin/runners/runAllowlist.js +418 -0
- package/bin/runners/runApprove.js +320 -0
- package/bin/runners/runAudit.js +692 -0
- package/bin/runners/runAuth.js +731 -0
- package/bin/runners/runCI.js +353 -0
- package/bin/runners/runCheckpoint.js +530 -0
- package/bin/runners/runClassify.js +928 -0
- package/bin/runners/runCleanup.js +343 -0
- package/bin/runners/runContext.d.ts +4 -0
- package/bin/runners/runContext.js +175 -0
- package/bin/runners/runDoctor.js +877 -0
- package/bin/runners/runEvidencePack.js +362 -0
- package/bin/runners/runFirewall.d.ts +5 -0
- package/bin/runners/runFirewall.js +134 -0
- package/bin/runners/runFirewallHook.d.ts +5 -0
- package/bin/runners/runFirewallHook.js +56 -0
- package/bin/runners/runFix.js +1355 -0
- package/bin/runners/runForge.js +451 -0
- package/bin/runners/runGuard.js +262 -0
- package/bin/runners/runInit.js +1927 -0
- package/bin/runners/runIntent.js +906 -0
- package/bin/runners/runKickoff.js +878 -0
- package/bin/runners/runLabs.js +424 -0
- package/bin/runners/runLaunch.js +2000 -0
- package/bin/runners/runLink.js +785 -0
- package/bin/runners/runMcp.js +1875 -0
- package/bin/runners/runPacks.js +2089 -0
- package/bin/runners/runPolish.d.ts +4 -0
- package/bin/runners/runPolish.js +390 -0
- package/bin/runners/runPromptFirewall.js +211 -0
- package/bin/runners/runProve.js +1411 -0
- package/bin/runners/runQuickstart.js +531 -0
- package/bin/runners/runReality.js +2260 -0
- package/bin/runners/runReport.js +726 -0
- package/bin/runners/runRuntime.js +110 -0
- package/bin/runners/runSafelist.js +1190 -0
- package/bin/runners/runScan.js +688 -0
- package/bin/runners/runShield.js +1282 -0
- package/bin/runners/runShip.js +1660 -0
- package/bin/runners/runTruth.d.ts +5 -0
- package/bin/runners/runTruth.js +101 -0
- package/bin/runners/runValidate.js +179 -0
- package/bin/runners/runWatch.js +478 -0
- package/bin/runners/utils.js +360 -0
- package/bin/scan.js +617 -0
- package/bin/vibecheck.js +1617 -0
- package/dist/guardrail/index.d.ts +2405 -0
- package/dist/guardrail/index.js +9747 -0
- package/dist/guardrail/index.js.map +1 -0
- package/dist/scanner/index.d.ts +282 -0
- package/dist/scanner/index.js +3395 -0
- package/dist/scanner/index.js.map +1 -0
- package/package.json +123 -104
- package/README.md +0 -491
- package/dist/index.js +0 -99711
- package/dist/index.js.map +0 -1
|
@@ -0,0 +1,661 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Time Machine Incident Correlator
|
|
3
|
+
*
|
|
4
|
+
* Links incidents to their causal chain.
|
|
5
|
+
* Finds the "first bad change" that led to problems.
|
|
6
|
+
*
|
|
7
|
+
* Codename: Time Machine
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
"use strict";
|
|
11
|
+
|
|
12
|
+
const fs = require("fs");
|
|
13
|
+
const path = require("path");
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @typedef {Object} Incident
|
|
17
|
+
* @property {string} id - Incident ID
|
|
18
|
+
* @property {string} title - Incident title
|
|
19
|
+
* @property {string} description - Incident description
|
|
20
|
+
* @property {Date} reportedAt - When reported
|
|
21
|
+
* @property {string} severity - Incident severity
|
|
22
|
+
* @property {string[]} affectedFiles - Files affected
|
|
23
|
+
* @property {string[]} affectedServices - Services affected
|
|
24
|
+
* @property {string} status - open, investigating, resolved
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @typedef {Object} CausalLink
|
|
29
|
+
* @property {string} fromEvent - Source event ID
|
|
30
|
+
* @property {string} toEvent - Target event ID
|
|
31
|
+
* @property {string} relationship - Type of causal relationship
|
|
32
|
+
* @property {number} confidence - Confidence score (0-1)
|
|
33
|
+
* @property {string[]} evidence - Evidence supporting the link
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @typedef {Object} IncidentReport
|
|
38
|
+
* @property {Incident} incident - The incident
|
|
39
|
+
* @property {Object[]} causalChain - Chain of events leading to incident
|
|
40
|
+
* @property {Object} rootCause - Identified root cause
|
|
41
|
+
* @property {Object[]} contributingFactors - Other contributing events
|
|
42
|
+
* @property {Object} recommendations - Recommendations to prevent recurrence
|
|
43
|
+
* @property {Date} generatedAt - When report was generated
|
|
44
|
+
*/
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Relationship types for causal links
|
|
48
|
+
*/
|
|
49
|
+
const RELATIONSHIP_TYPES = {
|
|
50
|
+
DIRECT_CAUSE: "direct_cause", // A directly caused B
|
|
51
|
+
CONTRIBUTING: "contributing", // A contributed to B
|
|
52
|
+
CORRELATING: "correlating", // A and B happened together
|
|
53
|
+
OVERRIDE_LED_TO: "override_led_to", // Override led to issue
|
|
54
|
+
HIGH_RISK_CHANGE: "high_risk_change", // High risk change preceded issue
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Incident Correlator class
|
|
59
|
+
*/
|
|
60
|
+
class IncidentCorrelator {
|
|
61
|
+
constructor(options = {}) {
|
|
62
|
+
this.projectRoot = options.projectRoot || process.cwd();
|
|
63
|
+
this.incidentsDir = path.join(this.projectRoot, ".vibecheck", "incidents");
|
|
64
|
+
this.packetsDir = path.join(this.projectRoot, ".vibecheck", "packets");
|
|
65
|
+
this.auditDir = path.join(this.projectRoot, ".vibecheck", "audit");
|
|
66
|
+
|
|
67
|
+
// Correlation settings
|
|
68
|
+
this.lookbackWindow = options.lookbackWindow || 24 * 60 * 60 * 1000; // 24 hours
|
|
69
|
+
this.minConfidence = options.minConfidence || 0.5;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Record a new incident
|
|
74
|
+
* @param {Object} incidentData - Incident data
|
|
75
|
+
* @returns {Incident} Created incident
|
|
76
|
+
*/
|
|
77
|
+
recordIncident(incidentData) {
|
|
78
|
+
const incident = {
|
|
79
|
+
id: incidentData.id || `INC-${Date.now()}-${Math.random().toString(36).slice(2, 6).toUpperCase()}`,
|
|
80
|
+
title: incidentData.title || "Unnamed incident",
|
|
81
|
+
description: incidentData.description || "",
|
|
82
|
+
reportedAt: new Date().toISOString(),
|
|
83
|
+
severity: incidentData.severity || "medium",
|
|
84
|
+
affectedFiles: incidentData.affectedFiles || [],
|
|
85
|
+
affectedServices: incidentData.affectedServices || [],
|
|
86
|
+
status: "open",
|
|
87
|
+
metadata: incidentData.metadata || {},
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
// Save incident
|
|
91
|
+
this.saveIncident(incident);
|
|
92
|
+
|
|
93
|
+
return incident;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Save an incident to disk
|
|
98
|
+
* @param {Incident} incident - Incident to save
|
|
99
|
+
*/
|
|
100
|
+
saveIncident(incident) {
|
|
101
|
+
if (!fs.existsSync(this.incidentsDir)) {
|
|
102
|
+
fs.mkdirSync(this.incidentsDir, { recursive: true });
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Save as individual file
|
|
106
|
+
fs.writeFileSync(
|
|
107
|
+
path.join(this.incidentsDir, `${incident.id}.json`),
|
|
108
|
+
JSON.stringify(incident, null, 2)
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
// Also append to incidents log
|
|
112
|
+
const logPath = path.join(this.incidentsDir, "incidents.jsonl");
|
|
113
|
+
fs.appendFileSync(logPath, JSON.stringify(incident) + "\n");
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Load an incident by ID
|
|
118
|
+
* @param {string} incidentId - Incident ID
|
|
119
|
+
* @returns {Incident|null} Incident or null
|
|
120
|
+
*/
|
|
121
|
+
loadIncident(incidentId) {
|
|
122
|
+
const incidentPath = path.join(this.incidentsDir, `${incidentId}.json`);
|
|
123
|
+
|
|
124
|
+
if (fs.existsSync(incidentPath)) {
|
|
125
|
+
try {
|
|
126
|
+
return JSON.parse(fs.readFileSync(incidentPath, "utf-8"));
|
|
127
|
+
} catch {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Correlate an incident with firewall events
|
|
137
|
+
* @param {string} incidentId - Incident ID
|
|
138
|
+
* @param {Object} options - Correlation options
|
|
139
|
+
* @returns {IncidentReport} Incident report
|
|
140
|
+
*/
|
|
141
|
+
async correlateIncident(incidentId, options = {}) {
|
|
142
|
+
const incident = this.loadIncident(incidentId);
|
|
143
|
+
if (!incident) {
|
|
144
|
+
throw new Error(`Incident ${incidentId} not found`);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const lookback = options.lookbackWindow || this.lookbackWindow;
|
|
148
|
+
const incidentTime = new Date(incident.reportedAt);
|
|
149
|
+
const lookbackTime = new Date(incidentTime.getTime() - lookback);
|
|
150
|
+
|
|
151
|
+
// Load events in the lookback window
|
|
152
|
+
const events = await this.loadEventsInWindow(lookbackTime, incidentTime);
|
|
153
|
+
|
|
154
|
+
// Filter to events affecting the same files/services
|
|
155
|
+
const relevantEvents = this.filterRelevantEvents(events, incident);
|
|
156
|
+
|
|
157
|
+
// Build causal chain
|
|
158
|
+
const causalChain = this.buildCausalChain(relevantEvents, incident);
|
|
159
|
+
|
|
160
|
+
// Identify root cause
|
|
161
|
+
const rootCause = this.identifyRootCause(causalChain, relevantEvents);
|
|
162
|
+
|
|
163
|
+
// Find contributing factors
|
|
164
|
+
const contributingFactors = this.findContributingFactors(relevantEvents, rootCause);
|
|
165
|
+
|
|
166
|
+
// Generate recommendations
|
|
167
|
+
const recommendations = this.generateRecommendations(incident, rootCause, contributingFactors);
|
|
168
|
+
|
|
169
|
+
const report = {
|
|
170
|
+
incident,
|
|
171
|
+
causalChain,
|
|
172
|
+
rootCause,
|
|
173
|
+
contributingFactors,
|
|
174
|
+
recommendations,
|
|
175
|
+
eventsAnalyzed: events.length,
|
|
176
|
+
relevantEvents: relevantEvents.length,
|
|
177
|
+
generatedAt: new Date().toISOString(),
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
// Save report
|
|
181
|
+
this.saveReport(incidentId, report);
|
|
182
|
+
|
|
183
|
+
return report;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Load events in a time window
|
|
188
|
+
* @param {Date} start - Start time
|
|
189
|
+
* @param {Date} end - End time
|
|
190
|
+
* @returns {Object[]} Events
|
|
191
|
+
*/
|
|
192
|
+
async loadEventsInWindow(start, end) {
|
|
193
|
+
const events = [];
|
|
194
|
+
|
|
195
|
+
// Load from firewall audit
|
|
196
|
+
const firewallLog = path.join(this.auditDir, "firewall-events.jsonl");
|
|
197
|
+
if (fs.existsSync(firewallLog)) {
|
|
198
|
+
const content = fs.readFileSync(firewallLog, "utf-8");
|
|
199
|
+
const lines = content.trim().split("\n").filter(l => l);
|
|
200
|
+
|
|
201
|
+
for (const line of lines) {
|
|
202
|
+
try {
|
|
203
|
+
const event = JSON.parse(line);
|
|
204
|
+
const eventTime = new Date(event.timestamp);
|
|
205
|
+
|
|
206
|
+
if (eventTime >= start && eventTime <= end) {
|
|
207
|
+
events.push({
|
|
208
|
+
...event,
|
|
209
|
+
source: "firewall",
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
} catch {
|
|
213
|
+
// Skip invalid lines
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Load from change packets
|
|
219
|
+
if (fs.existsSync(this.packetsDir)) {
|
|
220
|
+
const packets = fs.readdirSync(this.packetsDir)
|
|
221
|
+
.filter(f => f.endsWith(".json"));
|
|
222
|
+
|
|
223
|
+
for (const packetFile of packets) {
|
|
224
|
+
try {
|
|
225
|
+
const packet = JSON.parse(
|
|
226
|
+
fs.readFileSync(path.join(this.packetsDir, packetFile), "utf-8")
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
const packetTime = new Date(packet.timestamp || packet.createdAt);
|
|
230
|
+
|
|
231
|
+
if (packetTime >= start && packetTime <= end) {
|
|
232
|
+
events.push({
|
|
233
|
+
...packet,
|
|
234
|
+
source: "packet",
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
} catch {
|
|
238
|
+
// Skip invalid packets
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Sort by timestamp
|
|
244
|
+
events.sort((a, b) =>
|
|
245
|
+
new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime()
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
return events;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Filter events relevant to an incident
|
|
253
|
+
* @param {Object[]} events - All events
|
|
254
|
+
* @param {Incident} incident - The incident
|
|
255
|
+
* @returns {Object[]} Relevant events
|
|
256
|
+
*/
|
|
257
|
+
filterRelevantEvents(events, incident) {
|
|
258
|
+
const affectedFiles = new Set(incident.affectedFiles || []);
|
|
259
|
+
const affectedServices = new Set(incident.affectedServices || []);
|
|
260
|
+
|
|
261
|
+
return events.filter(event => {
|
|
262
|
+
// Check file match
|
|
263
|
+
const eventFiles = this.extractFilesFromEvent(event);
|
|
264
|
+
const hasFileMatch = eventFiles.some(f => {
|
|
265
|
+
for (const affected of affectedFiles) {
|
|
266
|
+
if (f.includes(affected) || affected.includes(f)) {
|
|
267
|
+
return true;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
return false;
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
if (hasFileMatch) return true;
|
|
274
|
+
|
|
275
|
+
// Check service match
|
|
276
|
+
const eventServices = event.services || [];
|
|
277
|
+
const hasServiceMatch = eventServices.some(s => affectedServices.has(s));
|
|
278
|
+
|
|
279
|
+
if (hasServiceMatch) return true;
|
|
280
|
+
|
|
281
|
+
// Include high-risk events
|
|
282
|
+
if ((event.riskScore || 0) >= 70) return true;
|
|
283
|
+
|
|
284
|
+
// Include overrides
|
|
285
|
+
if (event.overrideUsed || event.proof?.overrideUsed) return true;
|
|
286
|
+
|
|
287
|
+
return false;
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Extract files from an event
|
|
293
|
+
* @param {Object} event - Event
|
|
294
|
+
* @returns {string[]} Files
|
|
295
|
+
*/
|
|
296
|
+
extractFilesFromEvent(event) {
|
|
297
|
+
const files = [];
|
|
298
|
+
|
|
299
|
+
if (event.file) files.push(event.file);
|
|
300
|
+
if (event.filePath) files.push(event.filePath);
|
|
301
|
+
|
|
302
|
+
for (const op of event.operations || []) {
|
|
303
|
+
if (op.path) files.push(op.path);
|
|
304
|
+
if (op.file) files.push(op.file);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
return files;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Build causal chain from events to incident
|
|
312
|
+
* @param {Object[]} events - Relevant events
|
|
313
|
+
* @param {Incident} incident - The incident
|
|
314
|
+
* @returns {CausalLink[]} Causal chain
|
|
315
|
+
*/
|
|
316
|
+
buildCausalChain(events, incident) {
|
|
317
|
+
const chain = [];
|
|
318
|
+
|
|
319
|
+
// Sort events by time (newest last)
|
|
320
|
+
const sorted = [...events].sort((a, b) =>
|
|
321
|
+
new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime()
|
|
322
|
+
);
|
|
323
|
+
|
|
324
|
+
// Find events that could have caused the incident
|
|
325
|
+
for (const event of sorted) {
|
|
326
|
+
const confidence = this.calculateCausalConfidence(event, incident);
|
|
327
|
+
|
|
328
|
+
if (confidence >= this.minConfidence) {
|
|
329
|
+
const link = {
|
|
330
|
+
fromEvent: event.id || event.changeId,
|
|
331
|
+
toEvent: incident.id,
|
|
332
|
+
relationship: this.determineRelationship(event, incident),
|
|
333
|
+
confidence,
|
|
334
|
+
evidence: this.gatherEvidence(event, incident),
|
|
335
|
+
timestamp: event.timestamp,
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
chain.push(link);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// Link events to each other in the chain
|
|
343
|
+
for (let i = 0; i < chain.length - 1; i++) {
|
|
344
|
+
// Check if earlier events caused later events
|
|
345
|
+
const earlier = events.find(e => e.id === chain[i].fromEvent);
|
|
346
|
+
const later = events.find(e => e.id === chain[i + 1].fromEvent);
|
|
347
|
+
|
|
348
|
+
if (earlier && later && this.eventsCausally Related(earlier, later)) {
|
|
349
|
+
chain.splice(i + 1, 0, {
|
|
350
|
+
fromEvent: chain[i].fromEvent,
|
|
351
|
+
toEvent: chain[i + 1].fromEvent,
|
|
352
|
+
relationship: RELATIONSHIP_TYPES.CONTRIBUTING,
|
|
353
|
+
confidence: 0.6,
|
|
354
|
+
evidence: ["Events affected same files"],
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
return chain;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Check if two events are causally related
|
|
364
|
+
* @param {Object} earlier - Earlier event
|
|
365
|
+
* @param {Object} later - Later event
|
|
366
|
+
* @returns {boolean} Are related
|
|
367
|
+
*/
|
|
368
|
+
eventsCausallyRelated(earlier, later) {
|
|
369
|
+
// Same file affected
|
|
370
|
+
const earlierFiles = new Set(this.extractFilesFromEvent(earlier));
|
|
371
|
+
const laterFiles = this.extractFilesFromEvent(later);
|
|
372
|
+
|
|
373
|
+
return laterFiles.some(f => earlierFiles.has(f));
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Calculate confidence that event caused incident
|
|
378
|
+
* @param {Object} event - Event
|
|
379
|
+
* @param {Incident} incident - Incident
|
|
380
|
+
* @returns {number} Confidence score
|
|
381
|
+
*/
|
|
382
|
+
calculateCausalConfidence(event, incident) {
|
|
383
|
+
let confidence = 0;
|
|
384
|
+
|
|
385
|
+
// Override events are highly suspicious
|
|
386
|
+
if (event.overrideUsed || event.proof?.overrideUsed) {
|
|
387
|
+
confidence += 0.4;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
// High risk score
|
|
391
|
+
const riskScore = event.riskScore || event.proof?.riskScore || 0;
|
|
392
|
+
if (riskScore >= 70) {
|
|
393
|
+
confidence += 0.3;
|
|
394
|
+
} else if (riskScore >= 50) {
|
|
395
|
+
confidence += 0.2;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
// File match
|
|
399
|
+
const eventFiles = this.extractFilesFromEvent(event);
|
|
400
|
+
const hasFileMatch = eventFiles.some(f =>
|
|
401
|
+
incident.affectedFiles?.some(af => f.includes(af) || af.includes(f))
|
|
402
|
+
);
|
|
403
|
+
|
|
404
|
+
if (hasFileMatch) {
|
|
405
|
+
confidence += 0.3;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
// Temporal proximity (closer = more likely)
|
|
409
|
+
const eventTime = new Date(event.timestamp).getTime();
|
|
410
|
+
const incidentTime = new Date(incident.reportedAt).getTime();
|
|
411
|
+
const hoursBefore = (incidentTime - eventTime) / (1000 * 60 * 60);
|
|
412
|
+
|
|
413
|
+
if (hoursBefore <= 1) {
|
|
414
|
+
confidence += 0.2;
|
|
415
|
+
} else if (hoursBefore <= 6) {
|
|
416
|
+
confidence += 0.1;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
return Math.min(confidence, 1);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Determine the relationship type between event and incident
|
|
424
|
+
* @param {Object} event - Event
|
|
425
|
+
* @param {Incident} incident - Incident
|
|
426
|
+
* @returns {string} Relationship type
|
|
427
|
+
*/
|
|
428
|
+
determineRelationship(event, incident) {
|
|
429
|
+
if (event.overrideUsed || event.proof?.overrideUsed) {
|
|
430
|
+
return RELATIONSHIP_TYPES.OVERRIDE_LED_TO;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
const riskScore = event.riskScore || event.proof?.riskScore || 0;
|
|
434
|
+
if (riskScore >= 70) {
|
|
435
|
+
return RELATIONSHIP_TYPES.HIGH_RISK_CHANGE;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
const eventFiles = this.extractFilesFromEvent(event);
|
|
439
|
+
const hasFileMatch = eventFiles.some(f =>
|
|
440
|
+
incident.affectedFiles?.some(af => f.includes(af) || af.includes(f))
|
|
441
|
+
);
|
|
442
|
+
|
|
443
|
+
if (hasFileMatch) {
|
|
444
|
+
return RELATIONSHIP_TYPES.DIRECT_CAUSE;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
return RELATIONSHIP_TYPES.CONTRIBUTING;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* Gather evidence for a causal link
|
|
452
|
+
* @param {Object} event - Event
|
|
453
|
+
* @param {Incident} incident - Incident
|
|
454
|
+
* @returns {string[]} Evidence
|
|
455
|
+
*/
|
|
456
|
+
gatherEvidence(event, incident) {
|
|
457
|
+
const evidence = [];
|
|
458
|
+
|
|
459
|
+
if (event.overrideUsed || event.proof?.overrideUsed) {
|
|
460
|
+
evidence.push(`Override was used: ${event.proof?.overrideReason || "No reason given"}`);
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
const riskScore = event.riskScore || event.proof?.riskScore || 0;
|
|
464
|
+
if (riskScore > 0) {
|
|
465
|
+
evidence.push(`Risk score was ${riskScore}`);
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
const eventFiles = this.extractFilesFromEvent(event);
|
|
469
|
+
const matchingFiles = eventFiles.filter(f =>
|
|
470
|
+
incident.affectedFiles?.some(af => f.includes(af) || af.includes(f))
|
|
471
|
+
);
|
|
472
|
+
|
|
473
|
+
if (matchingFiles.length > 0) {
|
|
474
|
+
evidence.push(`Modified files: ${matchingFiles.join(", ")}`);
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
if (event.verdict === "BLOCK") {
|
|
478
|
+
evidence.push("Change was initially blocked by firewall");
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
return evidence;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* Identify the root cause from the causal chain
|
|
486
|
+
* @param {CausalLink[]} chain - Causal chain
|
|
487
|
+
* @param {Object[]} events - All relevant events
|
|
488
|
+
* @returns {Object|null} Root cause
|
|
489
|
+
*/
|
|
490
|
+
identifyRootCause(chain, events) {
|
|
491
|
+
if (chain.length === 0) return null;
|
|
492
|
+
|
|
493
|
+
// Sort by confidence and find the first event (chronologically) with high confidence
|
|
494
|
+
const highConfidence = chain
|
|
495
|
+
.filter(link => link.confidence >= 0.7)
|
|
496
|
+
.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
|
|
497
|
+
|
|
498
|
+
if (highConfidence.length > 0) {
|
|
499
|
+
const rootLink = highConfidence[0];
|
|
500
|
+
const rootEvent = events.find(e =>
|
|
501
|
+
e.id === rootLink.fromEvent || e.changeId === rootLink.fromEvent
|
|
502
|
+
);
|
|
503
|
+
|
|
504
|
+
return {
|
|
505
|
+
event: rootEvent,
|
|
506
|
+
link: rootLink,
|
|
507
|
+
reason: `First high-confidence change (${Math.round(rootLink.confidence * 100)}%)`,
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
// Fall back to the first event in the chain
|
|
512
|
+
const firstLink = chain[0];
|
|
513
|
+
const firstEvent = events.find(e =>
|
|
514
|
+
e.id === firstLink.fromEvent || e.changeId === firstLink.fromEvent
|
|
515
|
+
);
|
|
516
|
+
|
|
517
|
+
return {
|
|
518
|
+
event: firstEvent,
|
|
519
|
+
link: firstLink,
|
|
520
|
+
reason: "First change in causal chain",
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* Find contributing factors beyond root cause
|
|
526
|
+
* @param {Object[]} events - All relevant events
|
|
527
|
+
* @param {Object} rootCause - Identified root cause
|
|
528
|
+
* @returns {Object[]} Contributing factors
|
|
529
|
+
*/
|
|
530
|
+
findContributingFactors(events, rootCause) {
|
|
531
|
+
if (!rootCause) return [];
|
|
532
|
+
|
|
533
|
+
return events
|
|
534
|
+
.filter(e => {
|
|
535
|
+
const eventId = e.id || e.changeId;
|
|
536
|
+
return eventId !== rootCause.link?.fromEvent;
|
|
537
|
+
})
|
|
538
|
+
.filter(e => {
|
|
539
|
+
// Include events with some risk
|
|
540
|
+
const riskScore = e.riskScore || e.proof?.riskScore || 0;
|
|
541
|
+
return riskScore >= 30 || e.overrideUsed || e.proof?.overrideUsed;
|
|
542
|
+
})
|
|
543
|
+
.slice(0, 5); // Limit to top 5
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
/**
|
|
547
|
+
* Generate recommendations based on analysis
|
|
548
|
+
* @param {Incident} incident - The incident
|
|
549
|
+
* @param {Object} rootCause - Root cause
|
|
550
|
+
* @param {Object[]} contributingFactors - Contributing factors
|
|
551
|
+
* @returns {Object} Recommendations
|
|
552
|
+
*/
|
|
553
|
+
generateRecommendations(incident, rootCause, contributingFactors) {
|
|
554
|
+
const recommendations = {
|
|
555
|
+
immediate: [],
|
|
556
|
+
shortTerm: [],
|
|
557
|
+
longTerm: [],
|
|
558
|
+
};
|
|
559
|
+
|
|
560
|
+
if (rootCause?.event?.overrideUsed || rootCause?.event?.proof?.overrideUsed) {
|
|
561
|
+
recommendations.immediate.push({
|
|
562
|
+
action: "Review override policy",
|
|
563
|
+
reason: "Incident was caused by an overridden firewall block",
|
|
564
|
+
priority: "high",
|
|
565
|
+
});
|
|
566
|
+
|
|
567
|
+
recommendations.shortTerm.push({
|
|
568
|
+
action: "Add invariant rule to prevent similar overrides",
|
|
569
|
+
reason: `Consider blocking changes to ${incident.affectedFiles?.join(", ")}`,
|
|
570
|
+
priority: "medium",
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
const highRiskChanges = contributingFactors.filter(e =>
|
|
575
|
+
(e.riskScore || e.proof?.riskScore || 0) >= 70
|
|
576
|
+
);
|
|
577
|
+
|
|
578
|
+
if (highRiskChanges.length > 0) {
|
|
579
|
+
recommendations.immediate.push({
|
|
580
|
+
action: "Review high-risk changes",
|
|
581
|
+
reason: `${highRiskChanges.length} high-risk changes preceded this incident`,
|
|
582
|
+
priority: "high",
|
|
583
|
+
});
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
recommendations.longTerm.push({
|
|
587
|
+
action: "Add automated tests for affected functionality",
|
|
588
|
+
reason: "Prevent regression of the fixed issue",
|
|
589
|
+
priority: "medium",
|
|
590
|
+
});
|
|
591
|
+
|
|
592
|
+
if (incident.affectedFiles?.length > 0) {
|
|
593
|
+
recommendations.longTerm.push({
|
|
594
|
+
action: `Consider protecting ${incident.affectedFiles[0]}`,
|
|
595
|
+
reason: "Add to lawbook as a sensitive file",
|
|
596
|
+
priority: "low",
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
return recommendations;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
/**
|
|
604
|
+
* Save an incident report
|
|
605
|
+
* @param {string} incidentId - Incident ID
|
|
606
|
+
* @param {IncidentReport} report - Report to save
|
|
607
|
+
*/
|
|
608
|
+
saveReport(incidentId, report) {
|
|
609
|
+
const reportsDir = path.join(this.incidentsDir, "reports");
|
|
610
|
+
|
|
611
|
+
if (!fs.existsSync(reportsDir)) {
|
|
612
|
+
fs.mkdirSync(reportsDir, { recursive: true });
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
fs.writeFileSync(
|
|
616
|
+
path.join(reportsDir, `${incidentId}-report.json`),
|
|
617
|
+
JSON.stringify(report, null, 2)
|
|
618
|
+
);
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
/**
|
|
622
|
+
* Get all incidents
|
|
623
|
+
* @returns {Incident[]} All incidents
|
|
624
|
+
*/
|
|
625
|
+
getAllIncidents() {
|
|
626
|
+
const incidents = [];
|
|
627
|
+
|
|
628
|
+
if (!fs.existsSync(this.incidentsDir)) {
|
|
629
|
+
return incidents;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
const files = fs.readdirSync(this.incidentsDir)
|
|
633
|
+
.filter(f => f.endsWith(".json") && !f.includes("-report"));
|
|
634
|
+
|
|
635
|
+
for (const file of files) {
|
|
636
|
+
try {
|
|
637
|
+
const incident = JSON.parse(
|
|
638
|
+
fs.readFileSync(path.join(this.incidentsDir, file), "utf-8")
|
|
639
|
+
);
|
|
640
|
+
incidents.push(incident);
|
|
641
|
+
} catch {
|
|
642
|
+
// Skip invalid files
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
return incidents.sort((a, b) =>
|
|
647
|
+
new Date(b.reportedAt).getTime() - new Date(a.reportedAt).getTime()
|
|
648
|
+
);
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
/**
|
|
653
|
+
* Create an incident correlator instance
|
|
654
|
+
* @param {Object} options - Options
|
|
655
|
+
* @returns {IncidentCorrelator} Incident correlator
|
|
656
|
+
*/
|
|
657
|
+
function createIncidentCorrelator(options = {}) {
|
|
658
|
+
return new IncidentCorrelator(options);
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
module.exports = { IncidentCorrelator, createIncidentCorrelator, RELATIONSHIP_TYPES };
|