# Three autonomous layers that guard the repo without me

> I wired three automated layers into a mostly static repo so it defends itself while I am not looking: a broken build cannot merge, and a vulnerable dependency cannot sit unnoticed.

This garden runs almost no server code, a static SPA plus a couple of small Vercel functions, and nobody watching it around the clock, so I wanted the security to run itself. Three tools do the watching: one fires on every push, one gates the merge, one patrols the advisory feed while I sleep. Here is what each one does on its own, and why two of the three are named Snyk and Dependabot.

![Three autonomous layers of repo security. Steps: 1) CI blocks a broken build: Typecheck plus the vitest suite on every PR and push to main; 2) Snyk gates the merge: Scans deps and my code; a high or critical finding fails the build; 3) Dependabot feeds fixes: Flags new advisories and opens the version-bump PRs](/garden-assets/tinkering/atom_notes/securing-the-repo/securing-the-repo-flow.svg?v=3c1237c473)

Three autonomous layers, top to bottom: block, gate, feed.

## What runs without me

Three layers, each fired by an event or a schedule, none needing me to press start:

* **CI** (`ci.yml`): typecheck plus the vitest suite, which locks the [content compiler](/garden/build-time-content-compiler)'s data contract, fires on every pull request and every push to `main`. A red check blocks the merge. I never trigger it.
* **Snyk** (`snyk.yml`): a dependency scan and a code scan, scoped to my own source with a repo-root `.snyk`, runs on the same pushes and fails the build only on high or critical findings. See [Why I run Snyk on the garden](/garden/snyk) for what it is and why it earns a slot.
* **Dependabot** (`dependabot.yml`): watches the advisory feed around the clock and runs a weekly bump for npm and GitHub Actions, opening the PRs on its own. See [Dependabot watches my dependencies so I do not have to](/garden/dependabot) for the full case.

## What the automation has caught

* **Seven high or critical advisories, closed in one line.** `undici` came in transitively through the shadcn CLI and dotenvx. I pinned it in `package.json` `overrides` instead of adding a dependency, and the advisories were gone with no new surface.
* **No broken build reaches the deploy.** Vercel builds on push to `main`; CI fails the same commit first if typecheck or a test breaks.
* **Dependency drift is nobody's job now.** Dependabot opens the update PRs on its schedule, so I review and merge instead of hunting for stale packages.

## Why Snyk, why Dependabot

They cover each other's blind spots, and both run unattended.

**Snyk gates.** It scans my dependencies and the code I wrote on every push, and fails the build on a high or critical finding, which Dependabot never does.

**Dependabot patrols.** It flags a newly disclosed vulnerability the moment the advisory lands, no commit required, then opens a PR to bump past it. Snyk finds the hole; Dependabot ships the patch. Neither costs a cent on a private repo.

## Where the autonomy stops

The repo does not fully run itself, and I would not claim it does. I still read and click merge on every Dependabot PR, so the automation proposes and I approve. And the platform fights the automation at the edges. Uploading Snyk results to GitHub Code Scanning needs GitHub Advanced Security, which a private personal repo does not get, so I dropped it and let Dependabot alerts fill that tab. Snyk also cannot run on Dependabot's own PRs, where the token has no access to `SNYK_TOKEN`, so that job is gated to skip them. This is unattended scanning on a small, static surface, not a self-healing server.

## The bottom line

Let the tools watch so I do not have to. Wire security to fire on every push and patrol the advisory feed on a schedule, keep one human gate at the merge, and expect the platform to fight the automation at the edges. The repo now defends itself between my visits, and the setup cost nothing.
