Organizational Memory
Organizational memory captures the context that makes a generic finding a false positive in your codebase: a sanitization helper the SAST rule doesn’t know about, a directory of intentional fixtures, a parameterized ORM that defeats a SQL-injection pattern, a CVE you’ve already accepted in a specific package. Once a memory is in place, every AI feature — verification, the security brief, container analysis — applies it consistently, so the same false positive never reaches your queue twice.
The false-positive problem memory solves
Section titled “The false-positive problem memory solves”Static rules fire on patterns. They don’t know that your db.execute() calls all flow through a parameterizing wrapper, that tests/fixtures/ is supposed to contain credential-shaped strings, or that your team accepts dangerouslySetInnerHTML inside components/markdown/ because content is sanitized upstream. Without that context, the same noisy verdict gets re-litigated by every developer who opens the finding.
Memory closes the gap. Concretely, well-scoped memories:
- Eliminate recurring false positives. A verdict that flipped from
true_positivetofalse_positiveonce a memory was in place stays that way for every future finding the memory matches — across new files, new branches, and new contributors. - Replace dozens of identical reviews. A triage decision encoded as a memory does the work of repeated “is this a real bug?” reviews on every future occurrence.
- Travel with new code. A project-scoped memory applies automatically to findings in code that didn’t exist when the memory was written, so onboarding a module doesn’t restart the noise cycle.
- Compose. Org-wide and project-scoped memories combine; rule-, package-, CVE-, and image-bound memories layer on top so you can encode broad guidance and narrow exceptions side by side.
The net effect: triage time spent on AI-verified findings drops over weeks as your team’s institutional knowledge accumulates in memory rather than in Slack threads.
Authoring a memory
Section titled “Authoring a memory”- Open Settings → AI Knowledge (or the AI Memory tab on a project page if the memory should be project-scoped).
- Click Add memory — or, on a finding detail page, click Add memory from this finding to draft one with the relevant binding pre-filled.
- Write the fact in 1–2 sentences. Be specific.
- Pick a binding — None (applies broadly), or one of Rule (a specific rule ID), Package (a package name), CVE (an advisory ID), or Image (an image reference). One binding type per memory.
- (Optional) Tick This project only to scope to one project. Leave unticked for org-wide.
- (Optional) Tick Re-evaluate these N findings after saving to refresh existing AI verdicts that match the new memory.
- Save.
The next AI run picks up matching memories automatically.
What makes a good memory
Section titled “What makes a good memory”Good (specific, contextual, durable):
- “All SQL access goes through
repo/modules that parameterize via SQLAlchemy. Directdb.execute()calls outsiderepo/are FP.” — bind to the relevant SAST rule. - “The
shared/fixtures/directory contains test doubles. Hardcoded credentials and tokens there are deliberate.” — bind to the relevant secrets rule, or leave unbound for org-wide. - “We accept CVE-2024-1234 on
package-xuntil 2026-Q3 — vendor patch ETA, mitigated by WAF rule 412.” — bind to the CVE.
Bad (vague, time-bound, sensitive):
- “Ignore false positives” — too broad to act on; the verifier already tries to do this.
- “John is on vacation, defer triage” — ephemeral.
- “Our AWS root key is
AKIA...” — never put secrets in memory.
The pattern: a good memory names a place, a rule, a package, a CVE, or a code construct, and states a durable fact about it. Vague memories don’t move verdicts; specific ones do.
How memories combine
Section titled “How memories combine”Multiple memories can apply to a single AI call:
- Org-wide memories apply to every AI run in your organization.
- Project-scoped memories add on top when analyzing that project.
- Bound memories (rule / package / CVE / image) add on top when the finding’s facets match.
There’s no exclude/override semantics — memories accumulate. To narrow application, scope down rather than negate. When two active memories with the same binding express opposing directives (“always FP” vs “always TP”), Vygl flags the conflict on save with an inline warning; both still apply, but the warning is your hint to retire one.
Refresh existing verdicts
Section titled “Refresh existing verdicts”New verifications pick up matching memories automatically. Existing verdicts don’t refresh on their own — they’re cached by fingerprint. Two ways to bring them up to date:
- Tick Re-evaluate these N findings after saving in the Add/Edit Memory dialog. Vygl queues re-verifications for findings that match the new memory’s facets.
- Hit
POST /memories/{id}/reverifylater from the API.
Or use Re-Analyze on the Findings list to force re-verification across selected rows.
Toggling without deleting
Section titled “Toggling without deleting”Each memory has an active toggle. Disable a memory temporarily without losing the wording — useful for “did this memory cause the regression?” experiments and for retiring a memory once the underlying code pattern is gone.
Measuring impact
Section titled “Measuring impact”Two signals tell you a memory is doing its job:
- Verification verdicts shift. Open a previously-verified
true_positiveafter adding a contradicting memory and re-verify — the verdict should flip tofalse_positivewith reasoning that references the new context. - Re-triage drops off. Findings whose verdicts the memory now governs stop showing up in your “uncertain” or “open” buckets after the next pass.
If a memory isn’t moving verdicts the way you expected, make it more specific — name the file path, the rule ID, the package name, or the function signature it’s meant to govern.