Skip to content

v2.92.1: rule packs, boundaries v2, bigger security engine, agent evidence

Choose a tag to compare

@BartWaardenburg BartWaardenburg released this 10 Jun 19:55
· 117 commits to main since this release
v2.92.1
1f9aaac

v2.92.1 turns project policy into data, ships a second generation of architecture boundaries, expands the security candidate engine, and gives coding agents richer evidence to act on.

Policy as data: declarative rule packs

The new rulePacks config key lists standalone JSON/JSONC pack files of banned-call and banned-import rules. Packs load as pure data: loading one never executes project code.

// .fallowrc.json
{ "rulePacks": ["./rule-packs/team-policy.jsonc"] }

Matches report as policy-violation findings identified by <pack>/<rule-id> across human, JSON, SARIF, CodeClimate, compact, and markdown output, LSP diagnostics, baselines, audit attribution, regression counts, and the GitHub Action / GitLab CI summaries. banned-call matching is segment-aware and import-resolved (one child_process.* pattern covers named, namespace, and default imports of child_process / node:child_process); banned-import matches raw specifiers segment-aware (moment covers moment/locale/nl, never moment-timezone). Rules scope via files / exclude globs and carry an optional per-rule severity over the new rules."policy-violation" master (default warn for a safe first rollout). Suppress with // fallow-ignore-next-line policy-violation. The new fallow rule-pack-schema command prints the pack JSON Schema for editor autocomplete.

Boundaries v2: forbidden calls and full-file coverage

Boundary zones gained two policy sections.

boundaries.calls.forbidden bans callee patterns per zone, so a domain layer can stay free of process execution or logging:

{
  "boundaries": {
    "calls": {
      "forbidden": [
        { "from": "domain", "callee": "child_process.*" },
        { "from": "domain", "callee": ["console.*", "process.exit"] }
      ]
    }
  }
}

Matching is segment-aware and import-resolved, including optional-chaining call sites. Violations report as boundary_call_violations, sharing the boundary-violation severity and suppression token.

boundaries.coverage.requireAllFiles reports any analyzed source file that falls into no configured zone as a boundary_coverage_violations finding, with allowUnmatched for generated or intentionally unzoned paths.

A bigger security candidate engine

fallow security got a large batch of accuracy, scoping, and output work this release:

  • Newly-reachable gate. fallow security --gate newly-reachable --changed-since <ref> exits 8 only when an existing sink that was not runtime-reachable in the base tree becomes runtime-reachable in head. The GitHub Action exposes this as security-gate: newly-reachable; GitLab as FALLOW_SECURITY_GATE.
  • Multi-hop local taint. Source-backing now follows up to three chained same-module local bindings, so injection shapes routed through one or two intermediate variables upgrade to arg-level confidence with the trace anchored at the original read.
  • Fewer false positives. Trusted local sanitizer flows are suppressed, statically constant values no longer fire sink rules, and fixed-origin dynamic URLs are classified separately from SSRF / open-redirect candidates (url_shape).
  • Richer JSON. Security JSON and summary JSON now carry version, elapsed_ms, a privacy-safe config block, optional unresolved_callee_diagnostics, and a compact summary payload. The independent security JSON schema version is now "6".
  • Configurable request receivers. security.requestReceivers adds project-local request object names to the built-in req / request / ctx / context / event allowlist.
  • Clearer human output. The renderer now leads by explaining that findings are items to check, not confirmed vulnerabilities, with plain-language evidence labels.

Evidence for agents

  • fallow init --agents scaffolds a starter AGENTS.md, prefilling install, test, and typecheck commands and the monorepo module-boundary line from package.json and pnpm-workspace.yaml when the project shape is reliably detectable, and leaving anything ambiguous blank.
  • MCP inspect_target returns one typed evidence bundle per file or exported symbol, composing trace, dead-code, duplication, complexity, and security signals.
  • MCP code_execute (read-only Code Mode) runs a bounded QuickJS sandbox with a frozen allowlisted fallow host API, so an agent can compose several analysis calls in one JavaScript run without shelling out repeatedly. Mutating fix tools are rejected.
  • fallow health --targets --format json can now include direct importers with imported symbols and duplicate-code siblings with stable clone fingerprints.

Bug fixes

  • fallow audit no longer diffs against a stale local default branch. With no --base, auto-detection now resolves the comparison base to the git merge-base against the branch's upstream or the remote default, so long-lived worktree checkouts no longer surface the whole already-merged delta as changed. A new FALLOW_AUDIT_BASE environment variable pins the base, and the human audit scope line shows the resolved base with its provenance. Thanks @Zain-Bin-Arshad for the detailed report.
  • VS Code sidebar clicks now recover encoded dynamic route brackets before opening files, so an already-encoded segment like %5BactivityId%5D no longer double-encodes and opens a nonexistent file in VS Code or Cursor. Thanks @Ados12 for the report.
  • napi-rs prebuilt platform packages no longer report as unused optional dependencies. Fallow now reads package.json#napi metadata and credits only matching optionalDependencies entries.
  • A single huge minified bundle no longer exhausts memory during discovery. Large one-line JS assets are treated as generated output and skipped (skipped-minified-file diagnostic) while the max-file-size guard is enabled; --max-file-size 0 opts out.
  • fallow security --help no longer lists global flags the command rejects.
  • VS Code tooltips now escape names taken from analyzed code, and the extension serializes binary installs across windows so concurrent windows cannot collide.

Install

npm install -g fallow@2.92.1
# or
cargo install fallow-cli@2.92.1

Full Changelog: v2.91.0...v2.92.1