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,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Policy Engine
|
|
3
|
+
*
|
|
4
|
+
* Main policy engine that evaluates all rules deterministically.
|
|
5
|
+
* Uses AI to reduce false positives when enabled.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
"use strict";
|
|
9
|
+
|
|
10
|
+
const ghostRoute = require("./rules/ghost-route");
|
|
11
|
+
const ghostEnv = require("./rules/ghost-env");
|
|
12
|
+
const authDrift = require("./rules/auth-drift");
|
|
13
|
+
const contractDrift = require("./rules/contract-drift");
|
|
14
|
+
const fakeSuccess = require("./rules/fake-success");
|
|
15
|
+
const scope = require("./rules/scope");
|
|
16
|
+
const unsafeSideEffect = require("./rules/unsafe-side-effect");
|
|
17
|
+
const { generateVerdict } = require("./verdict");
|
|
18
|
+
const { analyzeFalsePositive } = require("../ai/false-positive-analyzer");
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Evaluate policy against change packet
|
|
22
|
+
* @param {object} params
|
|
23
|
+
* @param {object} params.policy - Policy configuration
|
|
24
|
+
* @param {array} params.claims - Extracted claims
|
|
25
|
+
* @param {array} params.evidence - Evidence resolution results
|
|
26
|
+
* @param {array} params.files - Changed files
|
|
27
|
+
* @param {string} params.intent - Agent intent message
|
|
28
|
+
* @returns {Promise<object>} Verdict object
|
|
29
|
+
*/
|
|
30
|
+
async function evaluatePolicy({ policy, claims, evidence, files, intent }) {
|
|
31
|
+
const violations = [];
|
|
32
|
+
|
|
33
|
+
// Evaluate all rules
|
|
34
|
+
const ruleEvaluators = [
|
|
35
|
+
ghostRoute,
|
|
36
|
+
ghostEnv,
|
|
37
|
+
authDrift,
|
|
38
|
+
contractDrift,
|
|
39
|
+
fakeSuccess,
|
|
40
|
+
unsafeSideEffect
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
// Evaluate claim-based rules
|
|
44
|
+
for (const evaluator of ruleEvaluators) {
|
|
45
|
+
try {
|
|
46
|
+
const violation = evaluator.evaluate({ claims, evidence, policy });
|
|
47
|
+
if (violation) {
|
|
48
|
+
// Use AI to check if this is a false positive
|
|
49
|
+
const claim = claims.find(c =>
|
|
50
|
+
c.type === violation.claim?.type &&
|
|
51
|
+
c.value === violation.claim?.value
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
if (claim && policy.rules?.ai_false_positive_detection?.enabled) {
|
|
55
|
+
try {
|
|
56
|
+
const aiAnalysis = await analyzeFalsePositive({
|
|
57
|
+
violation,
|
|
58
|
+
claim,
|
|
59
|
+
filePath: claim.file || violation.claim?.file || "unknown",
|
|
60
|
+
projectRoot: process.cwd(),
|
|
61
|
+
policy
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// If AI determines it's a false positive with high confidence, skip it
|
|
65
|
+
if (aiAnalysis.isFalsePositive && aiAnalysis.confidence >= 0.8) {
|
|
66
|
+
// Log but don't add to violations
|
|
67
|
+
if (policy.rules?.ai_false_positive_detection?.logSkipped) {
|
|
68
|
+
console.log(`[AI] Skipping false positive: ${violation.message} (confidence: ${aiAnalysis.confidence}, reason: ${aiAnalysis.reason})`);
|
|
69
|
+
}
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
} catch (aiError) {
|
|
73
|
+
// If AI analysis fails, proceed with the violation
|
|
74
|
+
console.warn(`[AI] False positive analysis failed: ${aiError.message}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
violations.push(violation);
|
|
79
|
+
}
|
|
80
|
+
} catch (error) {
|
|
81
|
+
console.warn(`Rule evaluation error: ${error.message}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Evaluate scope rule (file-based)
|
|
86
|
+
try {
|
|
87
|
+
const violation = scope.evaluate({ files, intent, policy });
|
|
88
|
+
if (violation) {
|
|
89
|
+
violations.push(violation);
|
|
90
|
+
}
|
|
91
|
+
} catch (error) {
|
|
92
|
+
console.warn(`Scope rule evaluation error: ${error.message}`);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Generate final verdict
|
|
96
|
+
const verdict = generateVerdict(violations);
|
|
97
|
+
|
|
98
|
+
return verdict;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
module.exports = {
|
|
102
|
+
evaluatePolicy
|
|
103
|
+
};
|
|
@@ -0,0 +1,451 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Policy Loader
|
|
3
|
+
*
|
|
4
|
+
* Loads and validates agent firewall policy from:
|
|
5
|
+
* - .vibecheck/policy.json (JSON policy)
|
|
6
|
+
* - .vibecheck/rules.yaml (YAML rule DSL)
|
|
7
|
+
* - .vibecheckrc (legacy)
|
|
8
|
+
*
|
|
9
|
+
* Falls back to default policy if not found.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
"use strict";
|
|
13
|
+
|
|
14
|
+
const fs = require("fs");
|
|
15
|
+
const path = require("path");
|
|
16
|
+
const Ajv = require("ajv").default || require("ajv");
|
|
17
|
+
|
|
18
|
+
// Try to load YAML parser
|
|
19
|
+
let yaml = null;
|
|
20
|
+
try {
|
|
21
|
+
yaml = require("js-yaml");
|
|
22
|
+
} catch {
|
|
23
|
+
// js-yaml not available, YAML support disabled
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Load schema
|
|
27
|
+
const schemaPath = path.join(__dirname, "schema.json");
|
|
28
|
+
const schema = JSON.parse(fs.readFileSync(schemaPath, "utf8"));
|
|
29
|
+
|
|
30
|
+
// Load default policy
|
|
31
|
+
const defaultPolicyPath = path.join(__dirname, "default-policy.json");
|
|
32
|
+
const defaultPolicy = JSON.parse(fs.readFileSync(defaultPolicyPath, "utf8"));
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Load YAML rules file
|
|
36
|
+
* @param {string} rulesPath - Path to rules.yaml
|
|
37
|
+
* @returns {Array} Parsed rules array
|
|
38
|
+
*/
|
|
39
|
+
function loadYamlRules(rulesPath) {
|
|
40
|
+
if (!yaml) {
|
|
41
|
+
console.warn("js-yaml not installed, YAML rules not loaded");
|
|
42
|
+
return [];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
const content = fs.readFileSync(rulesPath, "utf8");
|
|
47
|
+
const parsed = yaml.load(content);
|
|
48
|
+
|
|
49
|
+
if (!parsed || !parsed.rules) {
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return normalizeYamlRules(parsed.rules);
|
|
54
|
+
} catch (error) {
|
|
55
|
+
console.warn(`Failed to load YAML rules: ${error.message}`);
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Normalize YAML rules to policy format
|
|
62
|
+
* @param {Array} rules - Raw YAML rules
|
|
63
|
+
* @returns {Array} Normalized rules
|
|
64
|
+
*/
|
|
65
|
+
function normalizeYamlRules(rules) {
|
|
66
|
+
return rules.map(rule => {
|
|
67
|
+
// Map YAML DSL actions to policy severity
|
|
68
|
+
const severityMap = {
|
|
69
|
+
block: "block",
|
|
70
|
+
warn: "warn",
|
|
71
|
+
allow: "allow",
|
|
72
|
+
require_confirmation: "warn",
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
id: rule.id,
|
|
77
|
+
description: rule.description || "",
|
|
78
|
+
severity: severityMap[rule.action] || "warn",
|
|
79
|
+
enabled: rule.enabled !== false,
|
|
80
|
+
match: rule.match || {},
|
|
81
|
+
action: rule.action || "warn",
|
|
82
|
+
message: rule.message || rule.description || "",
|
|
83
|
+
// Custom rule evaluator info
|
|
84
|
+
custom: rule.custom || null,
|
|
85
|
+
block_if_domain: rule.block_if_domain || [],
|
|
86
|
+
};
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Merge YAML rules into policy
|
|
92
|
+
* @param {object} policy - Policy object
|
|
93
|
+
* @param {Array} yamlRules - Normalized YAML rules
|
|
94
|
+
* @returns {object} Policy with merged rules
|
|
95
|
+
*/
|
|
96
|
+
function mergeYamlRulesIntoPolicy(policy, yamlRules) {
|
|
97
|
+
if (!yamlRules || yamlRules.length === 0) {
|
|
98
|
+
return policy;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const merged = { ...policy };
|
|
102
|
+
merged.rules = merged.rules || {};
|
|
103
|
+
merged.customRules = merged.customRules || [];
|
|
104
|
+
|
|
105
|
+
for (const rule of yamlRules) {
|
|
106
|
+
// Add to custom rules array
|
|
107
|
+
merged.customRules.push(rule);
|
|
108
|
+
|
|
109
|
+
// Also add to rules object for backward compatibility
|
|
110
|
+
if (rule.id) {
|
|
111
|
+
merged.rules[rule.id] = {
|
|
112
|
+
severity: rule.severity,
|
|
113
|
+
enabled: rule.enabled,
|
|
114
|
+
block_if_domain: rule.block_if_domain,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return merged;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Load policy from project root
|
|
124
|
+
* @param {string} projectRoot - Project root directory
|
|
125
|
+
* @param {object} overrides - Optional policy overrides
|
|
126
|
+
* @returns {object} Loaded and validated policy
|
|
127
|
+
*/
|
|
128
|
+
function loadPolicy(projectRoot, overrides = {}) {
|
|
129
|
+
const policyPath = path.join(projectRoot, ".vibecheck", "policy.json");
|
|
130
|
+
const yamlRulesPath = path.join(projectRoot, ".vibecheck", "rules.yaml");
|
|
131
|
+
const legacyRcPath = path.join(projectRoot, ".vibecheckrc");
|
|
132
|
+
|
|
133
|
+
let policy;
|
|
134
|
+
|
|
135
|
+
// Try to load project policy (JSON)
|
|
136
|
+
if (fs.existsSync(policyPath)) {
|
|
137
|
+
try {
|
|
138
|
+
policy = JSON.parse(fs.readFileSync(policyPath, "utf8"));
|
|
139
|
+
} catch (error) {
|
|
140
|
+
throw new Error(`Failed to parse policy file: ${error.message}`);
|
|
141
|
+
}
|
|
142
|
+
} else if (fs.existsSync(legacyRcPath)) {
|
|
143
|
+
// Try legacy .vibecheckrc
|
|
144
|
+
try {
|
|
145
|
+
policy = JSON.parse(fs.readFileSync(legacyRcPath, "utf8"));
|
|
146
|
+
} catch (error) {
|
|
147
|
+
// Might be YAML format
|
|
148
|
+
if (yaml) {
|
|
149
|
+
try {
|
|
150
|
+
policy = yaml.load(fs.readFileSync(legacyRcPath, "utf8"));
|
|
151
|
+
} catch {
|
|
152
|
+
throw new Error(`Failed to parse .vibecheckrc: ${error.message}`);
|
|
153
|
+
}
|
|
154
|
+
} else {
|
|
155
|
+
throw new Error(`Failed to parse .vibecheckrc: ${error.message}`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
} else {
|
|
159
|
+
// Use default policy
|
|
160
|
+
policy = JSON.parse(JSON.stringify(defaultPolicy));
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Load and merge YAML rules if present
|
|
164
|
+
if (fs.existsSync(yamlRulesPath)) {
|
|
165
|
+
const yamlRules = loadYamlRules(yamlRulesPath);
|
|
166
|
+
policy = mergeYamlRulesIntoPolicy(policy, yamlRules);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Apply overrides (deep merge)
|
|
170
|
+
if (Object.keys(overrides).length > 0) {
|
|
171
|
+
policy = deepMerge(policy, overrides);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Validate against schema
|
|
175
|
+
const ajv = new Ajv({ allErrors: true, strict: false });
|
|
176
|
+
const validate = ajv.compile(schema);
|
|
177
|
+
const valid = validate(policy);
|
|
178
|
+
|
|
179
|
+
if (!valid) {
|
|
180
|
+
const errors = validate.errors.map(e =>
|
|
181
|
+
`${e.instancePath || 'root'} ${e.message}`
|
|
182
|
+
).join(', ');
|
|
183
|
+
throw new Error(`Policy validation failed: ${errors}`);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return policy;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Deep merge two objects
|
|
191
|
+
* @param {object} target - Target object
|
|
192
|
+
* @param {object} source - Source object to merge
|
|
193
|
+
* @returns {object} Merged object
|
|
194
|
+
*/
|
|
195
|
+
function deepMerge(target, source) {
|
|
196
|
+
const output = Object.assign({}, target);
|
|
197
|
+
|
|
198
|
+
if (isObject(target) && isObject(source)) {
|
|
199
|
+
Object.keys(source).forEach(key => {
|
|
200
|
+
if (isObject(source[key])) {
|
|
201
|
+
if (!(key in target)) {
|
|
202
|
+
Object.assign(output, { [key]: source[key] });
|
|
203
|
+
} else {
|
|
204
|
+
output[key] = deepMerge(target[key], source[key]);
|
|
205
|
+
}
|
|
206
|
+
} else {
|
|
207
|
+
Object.assign(output, { [key]: source[key] });
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return output;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Check if value is a plain object
|
|
217
|
+
* @param {*} item - Value to check
|
|
218
|
+
* @returns {boolean}
|
|
219
|
+
*/
|
|
220
|
+
function isObject(item) {
|
|
221
|
+
return item && typeof item === 'object' && !Array.isArray(item);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Get default policy
|
|
226
|
+
* @returns {object} Default policy
|
|
227
|
+
*/
|
|
228
|
+
function getDefaultPolicy() {
|
|
229
|
+
return JSON.parse(JSON.stringify(defaultPolicy));
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Save policy to project root
|
|
234
|
+
* @param {string} projectRoot - Project root directory
|
|
235
|
+
* @param {object} policy - Policy to save
|
|
236
|
+
*/
|
|
237
|
+
function savePolicy(projectRoot, policy) {
|
|
238
|
+
const vibecheckDir = path.join(projectRoot, ".vibecheck");
|
|
239
|
+
const policyPath = path.join(vibecheckDir, "policy.json");
|
|
240
|
+
|
|
241
|
+
// Ensure .vibecheck directory exists
|
|
242
|
+
if (!fs.existsSync(vibecheckDir)) {
|
|
243
|
+
fs.mkdirSync(vibecheckDir, { recursive: true });
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Validate before saving
|
|
247
|
+
const ajv = new Ajv({ allErrors: true, strict: false });
|
|
248
|
+
const validate = ajv.compile(schema);
|
|
249
|
+
const valid = validate(policy);
|
|
250
|
+
|
|
251
|
+
if (!valid) {
|
|
252
|
+
const errors = validate.errors.map(e =>
|
|
253
|
+
`${e.instancePath || 'root'} ${e.message}`
|
|
254
|
+
).join(', ');
|
|
255
|
+
throw new Error(`Policy validation failed: ${errors}`);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
fs.writeFileSync(policyPath, JSON.stringify(policy, null, 2));
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Save YAML rules to project root
|
|
263
|
+
* @param {string} projectRoot - Project root directory
|
|
264
|
+
* @param {Array} rules - Rules array
|
|
265
|
+
*/
|
|
266
|
+
function saveYamlRules(projectRoot, rules) {
|
|
267
|
+
if (!yaml) {
|
|
268
|
+
throw new Error("js-yaml not installed, cannot save YAML rules");
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
const vibecheckDir = path.join(projectRoot, ".vibecheck");
|
|
272
|
+
const rulesPath = path.join(vibecheckDir, "rules.yaml");
|
|
273
|
+
|
|
274
|
+
// Ensure .vibecheck directory exists
|
|
275
|
+
if (!fs.existsSync(vibecheckDir)) {
|
|
276
|
+
fs.mkdirSync(vibecheckDir, { recursive: true });
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
const content = yaml.dump({ rules }, {
|
|
280
|
+
lineWidth: 120,
|
|
281
|
+
quotingType: '"',
|
|
282
|
+
forceQuotes: false,
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
fs.writeFileSync(rulesPath, content);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/**
|
|
289
|
+
* Create default YAML rules file
|
|
290
|
+
* @param {string} projectRoot - Project root directory
|
|
291
|
+
*/
|
|
292
|
+
function createDefaultYamlRules(projectRoot) {
|
|
293
|
+
const defaultRules = [
|
|
294
|
+
{
|
|
295
|
+
id: "no-phantom-env",
|
|
296
|
+
description: "Block undeclared environment variables",
|
|
297
|
+
match: { type: "env", exists: false },
|
|
298
|
+
action: "block",
|
|
299
|
+
message: "Env vars must be declared before use",
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
id: "no-ghost-routes",
|
|
303
|
+
description: "Block routes that reference unregistered paths",
|
|
304
|
+
match: { type: "route", registered: false },
|
|
305
|
+
action: "block",
|
|
306
|
+
message: "Routes must be registered in the router",
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
id: "core-folder-protection",
|
|
310
|
+
description: "Require confirmation for changes to core code",
|
|
311
|
+
match: { path: "^src/core/" },
|
|
312
|
+
action: "require_confirmation",
|
|
313
|
+
message: "Changes to core require explicit confirmation",
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
id: "no-silent-deletes",
|
|
317
|
+
description: "Require confirmation for file deletions",
|
|
318
|
+
match: { operation: "delete" },
|
|
319
|
+
action: "require_confirmation",
|
|
320
|
+
message: "File deletions require explicit confirmation",
|
|
321
|
+
},
|
|
322
|
+
{
|
|
323
|
+
id: "auth-changes-high-risk",
|
|
324
|
+
description: "Flag authentication changes as high risk",
|
|
325
|
+
match: { tags: ["auth", "security"] },
|
|
326
|
+
action: "warn",
|
|
327
|
+
block_if_domain: ["payments"],
|
|
328
|
+
message: "Auth changes require careful review",
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
id: "max-files-per-change",
|
|
332
|
+
description: "Limit number of files in a single change",
|
|
333
|
+
match: { files_count: { gt: 10 } },
|
|
334
|
+
action: "require_confirmation",
|
|
335
|
+
message: "Large changes (>10 files) require confirmation",
|
|
336
|
+
},
|
|
337
|
+
];
|
|
338
|
+
|
|
339
|
+
saveYamlRules(projectRoot, defaultRules);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Get custom rules from policy
|
|
344
|
+
* @param {object} policy - Policy object
|
|
345
|
+
* @returns {Array} Custom rules
|
|
346
|
+
*/
|
|
347
|
+
function getCustomRules(policy) {
|
|
348
|
+
return policy.customRules || [];
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Evaluate a custom YAML rule against a change
|
|
353
|
+
* @param {object} rule - Rule definition
|
|
354
|
+
* @param {object} context - Change context
|
|
355
|
+
* @returns {object|null} Violation if rule triggered, null otherwise
|
|
356
|
+
*/
|
|
357
|
+
function evaluateCustomRule(rule, context) {
|
|
358
|
+
if (!rule.enabled) return null;
|
|
359
|
+
|
|
360
|
+
const match = rule.match || {};
|
|
361
|
+
let triggered = false;
|
|
362
|
+
|
|
363
|
+
// Match by type
|
|
364
|
+
if (match.type) {
|
|
365
|
+
const claims = context.claims || [];
|
|
366
|
+
const typeClaims = claims.filter(c => c.type === match.type);
|
|
367
|
+
|
|
368
|
+
if (typeClaims.length > 0) {
|
|
369
|
+
if (match.exists === false) {
|
|
370
|
+
// Check if any claim doesn't exist
|
|
371
|
+
triggered = typeClaims.some(c => !c.exists);
|
|
372
|
+
} else if (match.registered === false) {
|
|
373
|
+
triggered = typeClaims.some(c => !c.registered);
|
|
374
|
+
} else {
|
|
375
|
+
triggered = true;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// Match by path pattern
|
|
381
|
+
if (match.path) {
|
|
382
|
+
const files = context.files || [];
|
|
383
|
+
const regex = new RegExp(match.path);
|
|
384
|
+
triggered = triggered || files.some(f => regex.test(f.path || f));
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// Match by operation
|
|
388
|
+
if (match.operation) {
|
|
389
|
+
const operations = context.operations || [];
|
|
390
|
+
triggered = triggered || operations.some(op => op.type === match.operation);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// Match by file count
|
|
394
|
+
if (match.files_count) {
|
|
395
|
+
const fileCount = (context.files || []).length;
|
|
396
|
+
if (match.files_count.gt && fileCount > match.files_count.gt) {
|
|
397
|
+
triggered = true;
|
|
398
|
+
}
|
|
399
|
+
if (match.files_count.lt && fileCount < match.files_count.lt) {
|
|
400
|
+
triggered = true;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// Match by tags
|
|
405
|
+
if (match.tags && Array.isArray(match.tags)) {
|
|
406
|
+
const domains = context.domains || [];
|
|
407
|
+
triggered = triggered || match.tags.some(tag => domains.includes(tag));
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
if (!triggered) return null;
|
|
411
|
+
|
|
412
|
+
// Check block_if_domain upgrade
|
|
413
|
+
let severity = rule.severity || rule.action;
|
|
414
|
+
if (rule.block_if_domain && rule.block_if_domain.length > 0) {
|
|
415
|
+
const domains = context.domains || [];
|
|
416
|
+
if (rule.block_if_domain.some(d => domains.includes(d))) {
|
|
417
|
+
severity = "block";
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
return {
|
|
422
|
+
rule: rule.id,
|
|
423
|
+
type: "custom_rule",
|
|
424
|
+
severity,
|
|
425
|
+
message: rule.message || rule.description || `Rule ${rule.id} triggered`,
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
/**
|
|
430
|
+
* Check if YAML support is available
|
|
431
|
+
* @returns {boolean} YAML support available
|
|
432
|
+
*/
|
|
433
|
+
function hasYamlSupport() {
|
|
434
|
+
return yaml !== null;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
module.exports = {
|
|
438
|
+
loadPolicy,
|
|
439
|
+
getDefaultPolicy,
|
|
440
|
+
savePolicy,
|
|
441
|
+
loadYamlRules,
|
|
442
|
+
saveYamlRules,
|
|
443
|
+
createDefaultYamlRules,
|
|
444
|
+
getCustomRules,
|
|
445
|
+
evaluateCustomRule,
|
|
446
|
+
mergeYamlRulesIntoPolicy,
|
|
447
|
+
normalizeYamlRules,
|
|
448
|
+
hasYamlSupport,
|
|
449
|
+
schema,
|
|
450
|
+
defaultPolicy
|
|
451
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Drift Rule
|
|
3
|
+
*
|
|
4
|
+
* Blocks if auth restriction claimed but not enforced.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
"use strict";
|
|
8
|
+
|
|
9
|
+
const { CLAIM_TYPES } = require("../../claims/claim-types");
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Evaluate auth drift rule
|
|
13
|
+
* @param {object} params
|
|
14
|
+
* @param {array} params.claims - Extracted claims
|
|
15
|
+
* @param {array} params.evidence - Evidence resolution results
|
|
16
|
+
* @param {object} params.policy - Policy configuration
|
|
17
|
+
* @returns {object|null} Violation or null
|
|
18
|
+
*/
|
|
19
|
+
function evaluate({ claims, evidence, policy }) {
|
|
20
|
+
const ruleConfig = policy.rules?.auth_drift;
|
|
21
|
+
|
|
22
|
+
if (!ruleConfig || !ruleConfig.enabled) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Find auth claims with CONTRADICTS evidence
|
|
27
|
+
for (let i = 0; i < claims.length; i++) {
|
|
28
|
+
const claim = claims[i];
|
|
29
|
+
|
|
30
|
+
if (claim.type === CLAIM_TYPES.AUTH) {
|
|
31
|
+
const ev = evidence.find(e => e.claimId === `claim_${i}`);
|
|
32
|
+
|
|
33
|
+
if (ev && ev.result === "CONTRADICTS") {
|
|
34
|
+
return {
|
|
35
|
+
rule: "auth_drift",
|
|
36
|
+
severity: ruleConfig.severity || "block",
|
|
37
|
+
message: `Auth drift: ${claim.value} claims auth restriction but route is not protected`,
|
|
38
|
+
claimId: `claim_${i}`,
|
|
39
|
+
claim
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
module.exports = {
|
|
49
|
+
evaluate
|
|
50
|
+
};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Contract Drift Rule
|
|
3
|
+
*
|
|
4
|
+
* Blocks if API contract mismatch.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
"use strict";
|
|
8
|
+
|
|
9
|
+
const { CLAIM_TYPES } = require("../../claims/claim-types");
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Evaluate contract drift rule
|
|
13
|
+
* @param {object} params
|
|
14
|
+
* @param {array} params.claims - Extracted claims
|
|
15
|
+
* @param {array} params.evidence - Evidence resolution results
|
|
16
|
+
* @param {object} params.policy - Policy configuration
|
|
17
|
+
* @returns {object|null} Violation or null
|
|
18
|
+
*/
|
|
19
|
+
function evaluate({ claims, evidence, policy }) {
|
|
20
|
+
const ruleConfig = policy.rules?.contract_drift;
|
|
21
|
+
|
|
22
|
+
if (!ruleConfig || !ruleConfig.enabled) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Find contract claims with CONTRADICTS evidence
|
|
27
|
+
for (let i = 0; i < claims.length; i++) {
|
|
28
|
+
const claim = claims[i];
|
|
29
|
+
|
|
30
|
+
if (claim.type === CLAIM_TYPES.CONTRACT) {
|
|
31
|
+
const ev = evidence.find(e => e.claimId === `claim_${i}`);
|
|
32
|
+
|
|
33
|
+
if (ev && ev.result === "CONTRADICTS") {
|
|
34
|
+
return {
|
|
35
|
+
rule: "contract_drift",
|
|
36
|
+
severity: ruleConfig.severity || "block",
|
|
37
|
+
message: `Contract drift: ${claim.value} API contract mismatch`,
|
|
38
|
+
claimId: `claim_${i}`,
|
|
39
|
+
claim
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
module.exports = {
|
|
49
|
+
evaluate
|
|
50
|
+
};
|