HAP studying and taking notes

Your Defense-in-Depth Playbook

Quick Reference

The four-layer defense system I learned at Station 6. Each layer is independent. Each catches what the others miss. Here is how to set them all up. 🟠

← Back to Station 6: AI and Your Event-Driven Code

The Four Layers

1

AGENTS.md — Prevention

Tells the AI what to generate and what to avoid. Architecture rules and code rules. First line of defense, but only works if the AI reads and follows it.

2

ESLint Plugins — Detection

eslint-plugin-unicorn: prefer-add-event-listener flags onclick assignments. eslint-plugin-no-unsanitized: flags innerHTML. These scan code regardless of who wrote it.

3

Husky + lint-staged — Enforcement

Runs ESLint at commit time. Already in ready-build. Even if warnings are ignored in the editor, bad code cannot enter the repo.

4

Copilot Code Review — AI Reviewer

gh pr edit --add-reviewer @copilot. Analyzes full repo context on every PR. Catches architectural mismatches, security issues, and subtle patterns that static analysis misses.

What Each Layer Catches

Wrong Architecture

AGENTS.md catches this. Tells the AI "this is an SPA" so it does not generate multi-page navigation. Copilot review can also catch architectural mismatches in PRs.

innerHTML Usage

AGENTS.md says "never innerHTML." eslint-plugin-no-unsanitized flags it automatically. Husky blocks the commit if ESLint fails.

onclick vs addEventListener

AGENTS.md says "use addEventListener." eslint-plugin-unicorn flags onclick assignments. Husky blocks the commit.

Patterns AI Invents

AI may generate patterns that are technically valid but architecturally wrong. Copilot review catches these because it sees the full repo context, not just one file.

AGENTS.md for Event-Driven Code

Add these rules to your AGENTS.md to prevent the most common AI mistakes with event code:

AGENTS.md additions:
# AGENTS.md — Event-Driven Code Rules

## Architecture
- This is a single-page app (SPA).
- Never generate code that creates new HTML files
  or uses window.location for navigation.
- All "pages" are view functions that show/hide
  content within index.html.

## Code rules
- Use addEventListener, not onclick property assignments.
- Never use innerHTML — use createElement and textContent.
- All event listeners use named callbacks or arrow functions
  passed to addEventListener.

ESLint Plugin Setup

Install the plugins:
# Install the ESLint plugins
npm install --save-dev eslint-plugin-unicorn
npm install --save-dev eslint-plugin-no-unsanitized
What the rules catch:
// In your ESLint config:

// eslint-plugin-unicorn
// Rule: prefer-add-event-listener
// Flags: btn.onclick = () => { ... }
// Suggests: btn.addEventListener('click', () => { ... })

// eslint-plugin-no-unsanitized (Mozilla)
// Rule: no-unsanitized/property
// Flags: element.innerHTML = value
// Flags: element.outerHTML = value

Husky + lint-staged

Already in ready-build:
# Husky + lint-staged (already in ready-build)
# Runs ESLint on every commit.
# If ESLint fails, the commit is blocked.

# To verify it's working:
git commit -m "test" --dry-run
# If lint-staged is configured, it will run ESLint
# on staged files before allowing the commit.

Copilot Code Review

Add Copilot as a reviewer:
# Add Copilot as a reviewer on a pull request:
gh pr edit --add-reviewer @copilot

# Copilot reviews the full repo context, not just the diff.
# It can catch architectural mismatches, security issues,
# and patterns that static analysis misses.

The Key Insight:

AGENTS.md tells the AI what to do. ESLint checks after the code is written. Husky blocks bad code at commit time. Copilot reviews the full picture on every PR. No single layer catches everything — but together, they catch what I miss. 🟠

See It in a Real Project 🟠

The Robot ID Card App AGENTS.md has these exact rules in action. The app itself uses addEventListener everywhere, createElement instead of innerHTML, and classList instead of inline styles. Explore the full source code to see how prevention works in practice.

← Back to Station 6: AI and Your Event-Driven Code