Skip to content

Flag Marshal

CLI reference

Run the latest version without installing:

npx @stackblender/flag-marshal scan .

Or install globally. marshal is a shorter alias for flag-marshal.

npm install --global @stackblender/flag-marshal
flag-marshal scan .

scan

Inventories the feature flags in a repository and reports findings.

flag-marshal scan [path]
Option Effect
--format=human Readable terminal output (default): a debt summary, the flags most worth reviewing, the inventory, and findings
--format=json or --json Machine-readable report for scripts and agents
--format=markdown A report suitable for sharing or a pull-request comment
--format=sarif SARIF 2.1.0 for code-scanning tools
--no-git Skip repository history. Output becomes fully deterministic, but flag-age evidence is unavailable

scan always exits with code 0. Flag age and staleness come from Git history, so in CI check out the full history (for example fetch-depth: 0 with actions/checkout).

init

Writes a starter .flagmarshal.yml, declaring any flag helper the scan finds and listing every policy option commented out. It never replaces an existing file.

flag-marshal init [path]

check

Enforces the policy in .flagmarshal.yml: required owners and expiry dates, maximum flag age, and a flag budget. Inferred findings such as staleness are reported by scan and never enforced.

flag-marshal check --update-baseline   # accept today's violations, once
flag-marshal check                     # exits 2 only on violations added since

The baseline is written to .flagmarshal-baseline.json; commit it so everyone shares one. check accepts --format and --no-git like scan.

Exit code Meaning
0 No new violations
1 Usage error
2 A new policy violation

trend

Shows how accepted flag debt has moved over time, read from the committed baseline’s own Git history. --json is supported.

serve –stdio

A long-running JSON-RPC 2.0 analysis server with Content-Length framing, for editor integrations. It answers initialize, flagMarshal/scan, shutdown, and exit.

Configuration

.flagmarshal.yml at the repository root. Every section is optional:

customPatterns:
  methods: [isFeatureOn]      # your own flag helpers

policy:
  requireOwner: true
  requireExpiry: true
  maxAgeDays: 180             # 0 disables
  budget: 50                  # 0 disables
  allowlist:
    - example-kill-switch

flags:
  example-flag:
    owner: team-example
    expiry: 2027-01-31

Owner and expiry can also sit beside the flag in any comment syntax: // flag-marshal: example-flag owner=team-example expiry=2027-01-31.

Limitations

  • Static analysis is not runtime proof that a flag can be removed. Review the evidence before changing production code.
  • A call is recognized only when its file imports the provider. Code that receives an already-constructed client may be missed; declaring your helper usually recovers it.
  • Unsupported languages and unresolved keys are reported as coverage limitations and lower the confidence of affected findings.

If a flag is reported wrongly or missed, use the detection problem form.