Skip to content

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.

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_positive to false_positive once 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.

  1. Open Settings → AI Knowledge (or the AI Memory tab on a project page if the memory should be project-scoped).
  2. Click Add memory — or, on a finding detail page, click Add memory from this finding to draft one with the relevant binding pre-filled.
  3. Write the fact in 1–2 sentences. Be specific.
  4. Pick a bindingNone (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.
  5. (Optional) Tick This project only to scope to one project. Leave unticked for org-wide.
  6. (Optional) Tick Re-evaluate these N findings after saving to refresh existing AI verdicts that match the new memory.
  7. Save.

The next AI run picks up matching memories automatically.

Good (specific, contextual, durable):

  • “All SQL access goes through repo/ modules that parameterize via SQLAlchemy. Direct db.execute() calls outside repo/ 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-x until 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.

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.

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}/reverify later from the API.

Or use Re-Analyze on the Findings list to force re-verification across selected rows.

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.

Two signals tell you a memory is doing its job:

  • Verification verdicts shift. Open a previously-verified true_positive after adding a contradicting memory and re-verify — the verdict should flip to false_positive with 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.