Curtis “Ovid” Poe — Politics, programming, and prose
Articles

PAAD v2: Make It Yours, Keep Your Secrets Out of Git



Introduction

Yes, you can write production-quality code with AI. PAAD makes it much easier. After weeks of testing, PAAD v2.0.0 is now available on GitHub (opens in new tab).

Two changes matter most:

  1. You can now configure PAAD to match how you work.
  2. Security findings no longer end up in your commits.

No skill was renamed or removed, and no arguments changed.

Make PAAD Yours: Per-project Configuration

Until now, PAAD behaved the way I thought it should. If you wanted something different, such as an extra review agent, a house style for reports, output in another language or a log of what the verifier threw away, you had to fork PAAD, or write a wrapper skill around it, or retype the same instructions on every run.

This is a constant problem I hit with every skill collection I use, so I decided it should no longer be a problem for PAAD.

Now you write it down once:

  • paad/config/paad.md applies to every PAAD skill.
  • paad/config/<skill-name>.md applies to one skill, such as paad/config/agentic-review.md.

These files are plain instructions, written the way you would type them after the slash command. The skill reads them when it starts.

Many requests to change PAAD no longer need a change to PAAD. They need a file in paad/config/. For example, I often work with teams for whom English is a second (or third!) language, so inside paad/config/paad.md:

Use simplified technical english for all output.

That’s a huge win because Simplified Technical English (opens in new tab) (STE) is specifically designed to communicate technical information to those with only a basic command of English. I’m a native English speaker, but even I find STE easier to follow.

Before STE

🤖 AI Review · src/payments/client.py line 142

💡 Suggestion

Consider revisiting the retry logic here. While wrapping submit_payment() in the @retry decorator is a nice resilience improvement, it’s worth noting that this call isn’t idempotent, which could potentially lead to duplicate charges in scenarios where the upstream provider processes the request but the response is lost due to a timeout. You may want to either pass an idempotency key (the provider’s API supports this via the Idempotency-Key header) or restrict retries to connection errors that occur before it’s sent. Additionally, the backoff strategy could benefit from jitter to avoid thundering-herd issues under load. Overall, nice work on improving the robustness of this module! 🚀

After STE

AI Review · src/payments/client.py line 142

Finding 1 — Severity: High

Problem: The @retry decorator can send the same payment request two times. If the provider accepts the payment request but the response does not arrive before the timeout, the client sends the payment request again. The customer then pays two times.

Fix: Do one of these:

Add an Idempotency-Key header to each payment request. Use the same key for all retries of that request. Retry only when the connection fails before the client sends the payment request.

Finding 2 — Severity: Low

Problem: The backoff delays do not have a random component. If many clients fail at the same time, they all retry at the same time. This can put too much load on the provider.

Fix: Add a random value (jitter) to each backoff delay.

The STE version is much clearer for many readers, but this should not be part of PAAD. Instead, you can use the config system to decide this, or other changes, for yourself.

Config is experimental, so read CONFIG.md (opens in new tab) before you rely on it. And a paad/config/ directory in a repo you cloned was written by someone else, so read it before you run anything.

Security findings stay out of your committed reports

/agentic-owasp exists to find security problems. /test-roadmap regularly finds them while it writes tests. Until now, those findings went into reports that you commit. For open source projects, if you don’t notice this, you could be pushing security vulnerabilities to a public repository! Even for closed-source repos, there’s a good chance you don’t want this to happen.

In v2.0.0, anything a skill finds that would help an attacker goes to paad/security/ instead, and that directory tells git to ignore it. Where a security finding would have gone, the committed report keeps only a count:

2 security finding(s) written to paad/security/<file>

/agentic-owasp no longer writes a committed report at all.

Why 2.0.0, if nothing breaks?

Your PAAD skills keep working, and old reports stay where they are. But new security findings now land somewhere else. Scripts or CI jobs that read paad/owasp-reviews/ won’t see new reports there, and if your team shares findings by committing PAAD reports, the security ones stop arriving. They exist only on the machine that ran the skill.

It’s a guard rail, not a vault: anything you already committed stays in git history. The README (opens in new tab) lists the limits.

Upgrading

  1. Update the plugin. In Claude Code: /plugin → Installed → paad → Update now, or run claude plugin update paad@paad. With npx, run npx skills@latest add Ovid/paad again.
  2. Ignore paad/security/ yourself as well. Add it to your root .gitignore, or to .git/info/exclude to keep the rule private. The directory already ignores itself; your rule is a second guard in case that file gets deleted.

If you already committed OWASP reports or security backlog entries, the README (opens in new tab) explains how to move them. Also, don’t run /fix-architecture on an architecture report written by 1.x: it keeps security flaws inline, so the commit messages would name them. Re-run /agentic-architecture first.

Also New

Many of these skills create “backlog” items. For example, when running /agentic-review on your PR, you get items marked as critical, important, or “suggestions.” The latter are often items that are out-of-scope for the current PR, but should still be addressed. For myself (and as reported by others), that’s basically a long list of items that people don’t pay attention to.

/backlog helps to fix this.

  • /backlog [clean|fix] (experimental) works through the out-of-scope bug backlog. clean drops entries that are already fixed. fix fixes the next entry and removes it only after an independent check confirms the bug is gone. It never commits. See /paad-help backlog.

But isn’t that just a bunch of “tickets” that belong in a ticket tracking system? Yes, they are! But I don’t know what you use, so you can now write paad/config/backlog.md to handle this. This is your PAAD, not mine.

What Didn’t Get In?

Right now, PAAD still writes to paad/ directories. Changing this is the most common request, but it’s a hard problem. The Config system could help, but there are so many approaches to making this actually work that I’m unsure of the best.

Some people want docs/paad/ to be the top-level directory. Others want .agents/paad/ or .reviews/. Frankly, AI metadata is a mess, it’s not standardized, and we don’t know where it’s going. I have my personal preferences, but they shouldn’t be forced on you the way I picked paad/ for the top-level directory.

It’s a big enough change that I don’t want to get it wrong, so paad/ stays until there’s a clean migration path.

Other changes

  • /rethink, /test-roadmap and /handoff are no longer experimental. Their arguments and output now get the same semver promise as the other skills.
  • Report headers record the model and PAAD version that produced them.
  • Skills are less likely to stall after announcing themselves.
  • /paad-help links to the full tutorial at curtispoe.org/paad/.

Full details are in CHANGELOG.md (opens in new tab).

Please leave a comment below!



If you'd like top-notch consulting or training, email me and let's discuss how I can help you. Read more about me to learn more about my background.

↑