Skip to content

Latest commit

 

History

History
99 lines (85 loc) · 4.96 KB

configuration.md

File metadata and controls

99 lines (85 loc) · 4.96 KB

Configuration

fallow-verdict.config.{ts,mjs,js,json} is found by walking up from the working directory. TypeScript config needs Node 22.18 or newer. All keys are optional; unknown keys are rejected.

import { defineConfig } from "fallow-verdict/config";

export default defineConfig({
  root: ".",
  dataDir: ".fallow-verdict",
  questionProfile: "generic", // "generic" | "category" (experimental)
  failOn: "survivor", // "off" | "survivor" | "needs-human-review"
  fallow: { binary: undefined, timeoutMs: undefined },
  engine: {
    model: "jev-1.13.0",
    apiKeyEnv: "TYPESAFE_API_KEY", // name of the variable, never the key
    baseUrl: undefined,
    timeoutMs: 10_000,
    concurrency: 8,
    requestsPerMinute: 1_000, // shared by all workers, retries included
  },
  packet: { radius: 20, maxStateTokens: 28_000, blind: false },
  policy: {
    survivorMinExploitable: 0.7,
    dismissMaxExploitable: { high: 0.05, medium: 0.1, low: 0.15 },
    dismissMinReasonStrength: 0.8,
    tamperingMax: 0.5,
    confirmDismissals: true, // a dismissal needs a second call that agrees
  },
  review: {
    maxUnits: 50, // functions per scan, highest risk first
    bugFloor: 0.5, // minimum P(has_bug) for a likely problem
    claimFloor: 0.5, // minimum 1 - P(does_what_it_claims) for a likely problem
    ruleFloor: 0.5, // minimum P(breach) for a rule without its own floor
    rules: [], // project rules as sentences, see docs/review.md
    confirmDismissals: false, // review dismissals are single calls by default
    failOn: "off", // review mode is advisory
  },
  similarCode: {
    policy: {
      candidateWorthyFloor: 0.8,
      behaviorallyEquivalentFloor: 0.9,
      refactorSafeFloor: 0.95,
      outcomeMinConfidence: 0.7,
    },
    confirmSurvivors: true, // a similar-code survivor needs a second call that agrees
    failOn: "off", // a safe merge is a chance, not a CI failure
  },
});

The default engine.model is a concrete version. Stored decisions are keyed on the requested model, so an alias such as jev-latest can move to a new version while old decisions still count as current. Keep a versioned id unless you accept that risk. Fresh calls may still vary. The version that answered is stored on every decision.

engine.requestsPerMinute spaces requests for the whole run. Jev documents a limit of 1,200 requests per minute and can change it without notice. An HTTP 402 (out of credits) stops the run at once with engine_out_of_credits, like a rejected key.

Policy thresholds only change how answers are mapped. Raw answers are stored, so after a threshold change the next judge, run, report, or eval maps them again locally, without engine calls, and records the change in the finding's history.

policy.confirmDismissals sends a second, identical request for each candidate that the first answers dismiss. The candidate stays dismissed only when both answer sets agree. See questions.md. The second call is counted in usage and cost. The dry-run plan states an upper bound for these calls: one more call for every candidate. The cost cap also applies. Each candidate reserves the cost of both calls before its first call, and the unused share returns to the budget when the first answers do not dismiss. Thus a candidate starts only when the cap leaves room for both calls.

The review section configures review mode. The top-level failOn and policy apply to security; review mode has its own failOn and confirmDismissals.

JSON Schemas for the config, finding records, labels, and the JSON output of the commands are published in schemas/. See JSON output.

Similar-code policy

similarCode.policy holds the floors of the similar-code kind. An axis is true at or above its floor, false at or below 1 minus the floor, and null between the two. Each floor is at least 0.5. Below outcomeMinConfidence, the outcome is needs-human-review. The policy section above applies only to security, except confirmDismissals, which applies to every kind. similarCode.confirmSurvivors (default true) also sends a second call for a survivor, because a survivor gates a code change. similarCode.failOn (default "off") is the failOn level of the kind; --fail-on overrides it. See similar-code.md.

Question profiles

generic is the default. category adds specific exploitation and mitigation criteria for SSRF and open redirects. Other categories and blind packets use generic questions. Dismissal thresholds are identical across profiles. The paired pilot explains why this remains opt-in.

Use --question-profile category for an individual command, or persist questionProfile in the config. When using the flag, also pass it to subsequent report, judge, and eval commands. Otherwise those commands use the configured profile and can invalidate answers from the other profile. Changing the actual questions invalidates cached answers and requires fresh calls.