Catalog PyPI
PACKAGE EXPLORERView in registry

agent-sdlc

PyPI

Diff-scoped mutation gate for pre-commit and agent Stop hooks

Versions collected1
Direct dependencies2From release 0.4.1
Last observed20 Oct, 23:18 UTC

README

Version 0.4.1 documentation

agent-sdlc

CI

A software development lifecycle shipped as agent config for Claude Code and Codex: rules, skills, slash commands, hooks, and a diff-scoped mutation gate.

Docs: https://pavelguzenfeld.com/agent-sdlc/

Why

A coding agent writes the code and the tests for it, and tests written next to the code tend to agree with it, bugs included. We planted small realistic bugs in a mature, well-tested project, and the suite stayed green for 57% of them. Unit tests can each pass while the feature, entered the way a user enters it, still fails. agent-sdlc puts those checks, plus scope, intent and git safety, into hooks and a gate instead of leaving them to the agent's memory.

ProblemWhat catches it
Tests that pass but assert nothingmutation-gate: a surviving mutant blocks the commit
Tests shaped to the codeAn adversary review that sees intent and tests, never the code
Unit tests green, feature brokenOne vertical-slice test per ticket, entered where a real consumer enters, red before any code
Scope creep40-line limit without a ticket; one ticket, one branch, one PR
Code bloatSmallest-change and zero-comment rules; a no-comments hook; every added line must kill its mutants
Design notes rotting in the treeNew .md files are blocked; intent lives in the tracker
Destructive gitA hook that denies reset --hard, add -A, force-push
AI tells and leaked identity in commitscommit-msg and no-leaks hooks

How it fits together

x marks a blocker. [name] is the rule in rules/ that applies.

 rules/*.md sync into .claude/rules and AGENTS.md; every session loads them

  idea
   |  /grill, or gh issue create
   v
 +--------------------------+
 | ticket                   |  intent lives here, not in the tree  [tickets]
 +--------------------------+
   |  triage: model:* label + assignee
   v                       x assigned to someone else: /kata stops
                           unlabelled or unassigned: /kata asks first
 +--------------------------+
 | /kata N                  |  one ticket, one branch, one PR      [tickets]
 | branch off origin/main   |
 +--------------------------+
   v
 +--------------------------+
 | red slice test           |  enters where a user enters,         [testing]
 |                          |  watched failing first
 +--------------------------+
   v
 +--------------------------+
 | implement                |  smallest change           [diff-discipline]
 |                          |  no comments, canonical names
 +--------------------------+         [code-clarity] [naming]
   |  every Bash call: git-guardrail  x reset --hard, add -A, force-push
   v
 +--------------------------+
 | git commit               |
 |  pre-commit              |
 |   rules-check            |  x .claude/rules drifted from the pack
 |   mutation-gate ---------+- x surviving mutant --> new test, or waiver
 |   no-new-docs            |  x new .md file not allowlisted
 |  commit-msg              |
 |   commit-msg             |  x banned words, AI attribution    [voice]
 |   diff-discipline        |  x over 40 lines, no ticket ref
 |   no-leaks               |  x email, private IP, home path
 +--------------------------+
   |  gate green -> adversary review: sees intent and tests, never
   |  the code; reports, never blocks; answer every finding
   |  Stop hook: runs the same gate if no commit did
   v
 +--------------------------+
 | push, PR "Closes #N"     |  x CI red
 +--------------------------+
   v
 +--------------------------+
 | you review, type LGTM    |  squash merge, branch deleted
 +--------------------------+
   v
  /done: handoff, follow-up tickets --> back to "ticket"

Example

def is_adult(age):
    return age >= 18

def test_adult():
    assert is_adult(30)

def test_child():
    assert not is_adult(5)
BLOCKED: 2 mutant(s) survived with no waiver.
  age.py:2:11:operator:age >= 18 => age > 18
  age.py:2:18:literal:18 => 19

Add assert is_adult(18) and assert not is_adult(17), and the gate passes.

Install

Claude Code:

claude plugin marketplace add PavelGuzenfeld/agent-sdlc
claude plugin install agent-sdlc@agent-sdlc

Tools the gate needs, and Codex:

git clone https://github.com/PavelGuzenfeld/agent-sdlc
cd agent-sdlc
./install.sh --deps
WantDo
Claude CodeThe plugin above; --scope local or --scope project keeps it to one repo
Codex./install.sh --target codex, or add the repo as a Codex marketplace source
Gate dependencies./install.sh --deps (--deps=say adds voice)
Only the gatepip install agent-sdlc (WordNet check: agent-sdlc[vocabulary])
The gate on a repoAdd .mutation-gate.toml, wire the pre-commit hooks
  • install.sh links skills/ into ~/.codex and renders commands/ as Codex skills. It installs nothing into ~/.claude. A second run changes nothing.
  • Installed an older install.sh into ~/.claude? ./install.sh --uninstall-legacy removes those links and hooks, or every hook fires twice.
  • ast-grep-cli adds an sg shim that can shadow the system sg; call ast-grep.

Use it

In Claude Code (Codex: $name instead of /name):

  1. Install the plugin and ./install.sh --deps
  2. In your repo: touch .mutation-gate.toml && mutation-gate rules sync
  3. claude, then /grill <idea> or gh issue create …
  4. Approve the ticket: gh issue edit 42 --add-label model:sonnet
  5. /kata 42: a worker writes the failing slice test, implements, gates, opens the PR
  6. Review, then type LGTM: it squash-merges and cleans up
  7. /done to close out the session

Full walkthrough, and what differs in Codex: https://pavelguzenfeld.com/agent-sdlc/usage/

With standard

standard runs C++ and Python quality gates on the PR. agent-sdlc runs before the commit. Use both:

 agent session  ->  git commit  ->  PR  ->  merge
 '------ agent-sdlc -------'       '-- standard --'

Run standard's setup first, then mutation-gate rules sync. Copying its AGENTS.md afterwards drops the rules block. In CI, the agent-sdlc diff checks need --range, because pre-commit run --from-ref doesn't enforce them. Setup order, the CI job and the docs/ allowlist: https://pavelguzenfeld.com/agent-sdlc/usage/#with-standard

What's inside

PathWhat
rules/How to work; synced into a repo with mutation-gate rules sync
commands/Slash commands: /kata, /done, /grill, /rectify …
skills/On-demand playbooks: /diagnose, /sol-budget, /verify-generated-diff …
bin/Hooks and helpers: git-guardrail.sh, the /say stack
mutation_gate/The gate and the mutation-gate CLI

CI runs scripts/no-leaks.sh on every PR. It flags emails, RFC1918 addresses, user-at-host references, /home/<user>/ paths and non-personal ghcr.io/ paths, and prints only file:line.

MIT, see LICENSE and NOTICE.md for one vendored third-party skill. Contributions: CONTRIBUTING.md, bound by CODE_OF_CONDUCT.md. Security: SECURITY.md.

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Versions 1

Collected releases
VersionPublishedDirect dependenciesOpen version
0.4.17 Oct 20262

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Repository

PENDING
pavelguzenfeld/agent-sdlc

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 23:18 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:db2b7ae42f2c9a6326e9e3ef7638e5878b581484b5535f8f63138b261f286c87