Signals
Per-signal reference — what each check looks at, when it runs, what failure looks like, and the shape of the repair prompt.
Foyer ships eight signals today. Each section below covers: what the signal checks, what failure looks like in the PR comment, and a sample of the attached repair prompt.
scope_alignment
- Checks: every atomic requirement extracted from the PR's intent
source (Linear issue, GitHub issue, PR body, plan artifact) against
the diff. Verdict is one of
exact,superset,subset,divergent. - Fails when: any requirement is missed, or the verdict is
divergent. - Common failure copy:
2/4 requirements met (verdict: subset). Missing: "redirect to /login on 401". - Repair prompt: prompt names each missed requirement; context carries the requirement list and the diff snippet that didn't satisfy it.
This is Foyer's headline differentiator vs. CodeRabbit / Greptile / Bugbot.
They check whether the code is correct in isolation; scope_alignment
checks whether the code did what you asked.
plan_alignment
- Checks: when a plan artifact is attached (via
foyer plan attach/foyer plan save), the diff is compared against the plan's stated scope. Catches scope creep and scope misses against an explicitly approved plan, even when the original Linear ticket is vague. - Fails when: the diff includes changes the plan didn't mention, or omits changes the plan promised.
- Repair prompt: prompt asks the agent to either trim out-of-scope edits or implement the missing item; context carries the plan text and the offending file list.
code_review
- Checks: independent reviewer pass. The LLM reads the diff and looks
for: bugs, race conditions, missed edge cases, contract drift, broken
error handling, security smells the dedicated
securityrunner won't catch. - Fails when: the reviewer surfaces P1 findings (severity P1 is the
gate — P2 / P3 surface as
warning, notfailed). - Repair prompt: prompt is one section per finding; context carries the file/line/severity triples.
security
- Checks: secrets pattern match (AWS, GCP, GitHub, Stripe, …),
dangerous AST shapes (
eval,Function(...), untyped exec), known vulnerability signatures. - Fails when: any P1 finding (real secret, real exec sink). P2 / P3
surface as
warning. - Repair prompt: prompt asks for credential rotation + commit removal; context carries the secret pattern (truncated) and the file path.
hallucinated_api
- Checks: every newly-introduced symbol reference (
foo.bar(),import { x } from 'y') against tree-sitter index of what actually exists in the repo and its dependencies. Targets the most common AI-PR failure mode: confident reference to a function that was never there. - Fails when: a referenced symbol can't be resolved against the repo or its declared dependencies.
- Repair prompt: prompt lists each unresolved symbol + the line that references it; context carries the resolution attempts so the fixing agent doesn't repeat them.
template_cruft
- Checks: scaffolding placeholders that escaped into committed code —
TODO: replace with real implementation,lorem ipsum,your-domain.com, template-generator boilerplate,<NAME_OF_PROJECT>. - Fails when: placeholders appear in non-test, non-doc files.
- Repair prompt: prompt asks for either real values or removal; context carries the file/line/placeholder triples.
dependency_hygiene
- Checks:
package.jsonand lockfile consistency across every detected workspace. Catches: dependency added topackage.jsonbut not the lockfile (forgottenyarn install), version mismatches between workspaces, phantom dependencies imported but not declared. - Fails when: any inconsistency that would break a fresh
yarn installornpm ci. - Repair prompt: prompt is the exact
yarn install/npm ciinvocation to run; context carries the diff ofpackage.jsonvs. lockfile.
dead_code
- Checks: exports added in this PR that nothing imports — runs
knipagainst the project graph, then filters findings to files touched by the diff. Avoids the AI failure mode of "added a helper, never wired it up." - Fails when: a newly-exported symbol has zero in-repo importers.
- Repair prompt: prompt asks for either a caller or removal; context carries the symbol name and file path.
Per-signal status values
Every signal returns one of:
passed— check ran, no findings.warning— check ran, findings exist but below the gate threshold (e.g. P2 reviewer notes). Does not block merge.failed— check ran, findings above the gate threshold. Repair prompt is attached.unavailable— check couldn't run (no test runner detected, sandbox boot timed out, dependency couldn't be installed). Distinct fromfailed; you can still merge but you don't have a signal.unsupported_on_provider— the signal is GitHub-only and you're on GitLab.
See also
- Concepts — the vocabulary used above.
- CLI reference — run all the static signals locally via
foyer review. - MCP server — pull a signal's repair prompt directly into your agent.