Learnings hygiene
A sustainable workflow for keeping AGENTS.md markers and chat-created Learnings accurate as your repo evolves.
Suppressions are like dependencies: easy to add, easy to forget. A suppression that was correct six months ago can be silently wrong today, because the code that justified it has moved, been deleted, or has had its surrounding context change. This playbook is the workflow we use to keep the suppression set honest over time.
Why suppressions go stale
Three failure modes account for almost all stale suppressions:
- The path moved. A marker says
# sebastion: ignore X in lib/legacy/**, butlib/legacy/was renamed tolib/v1/in a refactor. The marker now suppresses nothing. The rule re-fires and somebody re-suppresses it on the new path, never noticing the old marker was now dead weight. - The justification disappeared. A chat-created Learning was added when the input was sanitised three calls upstream. That sanitisation was removed in a later PR. The Learning now silences a real finding.
- The rule itself changed. Rare, but when we tune a rule to be more precise, a suppression that was needed under the old definition may no longer be needed under the new one. The suppression becomes harmless clutter rather than a security risk, but it still costs cognitive overhead.
The first two are the dangerous ones. Hygiene is mostly about catching them before they bite.
The quarterly review
Every three months, spend an hour on this:
Step 1. Dump the active Learnings
The dashboard at
app.foundationmachines.ai/sebastion/learnings
lists every active Learning for your installation, grouped by source
(chat / auto_detect / manual) with count, created_at and
last_seen_at.
The count and last_seen_at fields are your starting point:
count = 0for anauto_detectLearning means the marker exists in yourAGENTS.md(or similar) but no finding has ever matched it. Either you got the glob wrong, or the rule has been permanently quiet on that path. Investigate.last_seen_atmore than 90 days ago for any Learning is a signal that the underlying pattern may have moved. Worth a look.
Step 2. Walk the agent-file markers
Open every file Sebastion reads markers from:
AGENTS.mdCLAUDE.md.cursorrules.github/copilot-instructions.md
…plus any nested copies (e.g. bin/AGENTS.md,
packages/legacy/AGENTS.md). For each # sebastion: ignore line:
- Does the glob still match real files?
git ls-filesagainst the glob is the quickest check. - Is the rule still firing on those files? If
count = 0from step 1, the marker may have been written defensively for a rule you have since stopped triggering. Defensible to leave; defensible to remove for clarity. - Is the reason still true? This is the hardest question. The
marker doesn't store the reason — only the rule and glob. The
reason should live in a
#comment line above the marker so the reviewer can re-evaluate it in a year.
Recommended format for new markers (and a refactor target for old ones):
# Our bin/ scripts intentionally use console.log for CLI output.
# Suppressing the rule there keeps the audit signal clean without
# disabling it project-wide. Reviewed: 2026-05.
# sebastion: ignore js.console-log in scripts/**The "Reviewed: YYYY-MM" line gives you a quick visual cue at the next quarterly review of which markers have been examined recently.
Step 3. Walk the chat-created Learnings
In the dashboard, filter to source = chat. For each entry:
- Open the original PR comment thread (linked from the audit trail) and re-read the reason the contributor gave.
- Decide: is this still a one-off legitimate exception, or has
it become a pattern across multiple files? If the same
(rule, directory)shows up three or more times, promote it to anAGENTS.mdmarker and drop the individual chat Learnings (via support, until self-serve delete ships).
The dashboard caps at 500 active Learnings per installation. If you are at 80%+ of cap, we will already have alerted you — but the quarterly review is when you should be pruning, not when you hit the ceiling.
Step 4. Walk the disable_rules
Open .sebastionai.yml. For each entry in disable_rules:
- Is this still org policy? Did the team that owned it move on? Did the framework change?
- Has the rule become more precise? Sometimes a rule that was too noisy to keep on six months ago is now fine to re-enable. Try removing it on a branch and seeing what fires.
Operational rules that pay off
A few habits that compound:
- Every new marker gets a
#comment line above it explaining why. Without this, the next reviewer has no context and is forced to either preserve the suppression defensively or risk removing it without understanding. - Markers live close to the code they describe. A marker
scoped to
packages/legacy/**is better placed inpackages/legacy/AGENTS.mdthan in the repo-rootAGENTS.md— the scope of the marker matches the scope of the file, so renamingpackages/legacy/to something else takes the marker with it. - Chat suppressions with no free-text reason are a smell. When you see one, follow up on the PR thread asking why. The reason is recorded in your event log only if it was given.
- Quarterly review is on the calendar. If it is not scheduled, it does not happen. We do ours on the first Monday of every quarter.
What to do when you find a problem
For each kind of issue, here is the action:
| Issue | Action |
|---|---|
auto_detect Learning with count = 0 for > 90 days | Remove the marker line; ship in a normal PR. |
chat Learning where the reason no longer applies | Contact support to remove the Learning. The rule will fire on the next audit; fix the underlying code or re-suppress correctly. |
disable_rules entry the team has forgotten about | Remove from .sebastionai.yml; run a few PRs and see if the rule re-emerges as a real signal. |
Marker glob that doesn't match any files (git ls-files returns nothing) | Either fix the glob or remove the marker — a glob that matches nothing is a marker that lies. |
Same (rule, directory) Learning created 3+ times by chat | Promote to an AGENTS.md marker; drop the chat Learnings. |
Related
- False positives and Learnings — full security model, lifecycle and audit trail of every Learning.
- Suppression strategy — how to pick the right mechanism in the first place.
- Rate limits — the per-install caps that make pruning matter.
Suppression strategy
A decision tree for picking the right suppression tool — disable_rules vs AGENTS.md markers vs the @sebastionai ignore chat command.
CWE-502 deserialization of untrusted data
A worked example — what insecure deserialization looks like in real code, how Sebastion flags it, and the one-line fix. Based on RAGFlow PR