Skip to content

Configure

Domain packs

Focused checks for the places general review misses: money, database migrations, tenancy and auth, personal data, and your own architecture rules.

A domain pack adds two things to a review: deterministic checks that run on the diff for almost nothing, and a focused prompt that tells the reviewer what matters in that domain. Findings from a pack are labelled with the pack's name, so you can see which pack raised them.

The packs

Pack idLooks for
moneyAmounts held as floats, rounding with toFixed or floor and ceil on money, parseFloat on prices, hard-coded VAT rates. The prompt checks integer minor units, VAT applied once per band, and rounding rules.
migrationsCREATE INDEX without CONCURRENTLY, NOT NULL columns added without a default, drops, type changes, constraints added without NOT VALID, UPDATE or DELETE without WHERE or without batching, and no way back.
tenancy-authTenant ids taken from client input, records fetched by id with no tenant filter (IDOR), controllers or routes mounted without an auth guard.
piiPersonal data or credentials written to logs, whole user records returned from an API, personal data in URLs, new personal-data columns (with retention and GDPR deletion in mind).
architectureImports that break the layering you declare in .forseti/architecture.yml (below). It only enforces your rules, never invented ones.

The most serious deterministic hits are Blocking, for example an UPDATE with no WHERE, a tenant id read from the request body, or a lookup by id with no tenant filter.

Turning packs on

Packs are off until you turn them on. Three places, from broad to narrow:

  • Workspace default: in Policies, for every repo.
  • Policy rule: for matching repos, branches, paths or labels. For example, the migrations pack only on PRs touching db/**.
  • In the repo: a packs list in .forseti.yaml.
.forseti.yaml
packs: ["money", "migrations", "tenancy-auth"]

Each list takes up to 20 packs.

Declaring your architecture

The architecture pack reads .forseti/architecture.yml from the base branch. Name your layers as globs, then write rules with from and cannot_import, each a layer name or a glob, and an optional message that is quoted in the finding.

.forseti/architecture.yml
# .forseti/architecture.yml (on the base branch)
layers:
  domain: ["src/domain/**"]
  infra: ["src/infra/**"]
  web: ["src/web/**"]
rules:
  - from: domain
    cannot_import: [infra, web]
    message: "Domain must not depend on infrastructure or the web layer"
  - from: web
    cannot_import: ["src/infra/db/**"]
    message: "Controllers go through services, never the database client"

A rule missing from or cannot_import is reported and skipped; the others still apply.

Custom packs

A workspace can define its own packs: a name (lower case letters, digits and hyphens) and between 1 and 20 rules in plain English, such as “Every public endpoint must check the caller's plan”. A custom pack is turned on the same way as a built-in one, by its name.

What packs cost

The deterministic checks cost nothing measurable. The focused prompt adds model work in proportion to the size of the change, charged in credits as part of the review.