Skip to main content

A lockfile for your prompts. Diff and fail CI on drift.

Project description

promptlock

A package-lock.json for your prompts. Hash every prompt in your repo, fail CI when one changes without a re-eval. Catch the silent regression that kills agent quality at 3am.

PyPI Python License: MIT


The problem

You ship an LLM-powered feature. Six weeks later a teammate tweaks one sentence in your RAG_PROMPT. Your evals are out of date — nobody re-ran them. Production accuracy quietly drops 12% and nobody notices for a week.

This happens because prompts have no version contract. Code has package-lock.json and go.sum so a bumped dependency fails the build. Prompts have nothing.

promptlock is that nothing.


Install

pip install promptlocker
# or
uvx promptlocker --help

Zero dependencies. Pure Python ≥3.10.


Use it

# 1. Scaffold a prompts/ dir and a prompts.lock
cd your-repo
promptlock init

# 2. Edit your prompts. They're just markdown.
$EDITOR prompts/answer.md

# 3. After you re-evaluate, refresh the lock:
promptlock update

# 4. Wire it into CI so future drift fails the build:
promptlock check       # exits 1 if any prompt drifted vs the lockfile

That's the whole workflow.


Prompt file format

A prompt is a markdown file under prompts/ (configurable). Optional YAML-style frontmatter records which model + settings it was last evaluated against:

---
model: claude-sonnet-4
temperature: 0.0
last_evaluated: 2026-05-19
eval_pass_rate: 0.94
---
You are a helpful assistant. Answer the user's question based only on the
provided context. If you don't know, say so.

The file's name (relative to prompts/, with .md stripped) becomes the prompt's id. Nested folders use . separators, e.g. prompts/rag/answer.md → id rag.answer.


The lockfile

{
  "version": 1,
  "prompts": {
    "answer": {
      "file": "prompts/answer.md",
      "sha": "sha256:5b1a...",
      "meta": {"model": "claude-sonnet-4", "last_evaluated": "2026-05-19"}
    }
  }
}

The sha covers the prompt body (frontmatter excluded), so you can update metadata without invalidating the lock. The lockfile is committed to git — drift is then visible in PR reviews.


CLI

Command What it does
promptlock init Create prompts/ + prompts.lock + a starter prompt.
promptlock check Exit 1 if current prompts ≠ lockfile. Use in CI.
promptlock update Refresh the lockfile from current prompts.
promptlock diff Print {added, removed, changed} as JSON.
promptlock list List all discovered prompts with their hashes.

GitHub Actions

Drop this in .github/workflows/promptlock.yml:

name: promptlock
on: [pull_request]
jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with: { python-version: '3.12' }
      - run: pip install promptlocker
      - run: promptlocker check

Now any PR that touches a prompt without bumping the lockfile fails the build, forcing whoever made the change to explicitly acknowledge it.


Why this works

  • Two-keystroke workflow. Edit a prompt → promptlock update is one command. Skipping it = failing CI.
  • PR-visible. Lockfile drift shows up as a 1-line diff every reviewer spots.
  • Zero runtime cost. No instrumentation, no SDK lock-in. Your prompts stay in plain markdown your team can grep.
  • Tool-agnostic. Works with OpenAI, Anthropic, Cohere, local models, Cursor rules, Claude Code skills, anything that loads strings from files.

Companion projects


License

MIT © yubinkim444

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

promptlocker-0.1.0.tar.gz (6.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

promptlocker-0.1.0-py3-none-any.whl (7.4 kB view details)

Uploaded Python 3

File details

Details for the file promptlocker-0.1.0.tar.gz.

File metadata

  • Download URL: promptlocker-0.1.0.tar.gz
  • Upload date:
  • Size: 6.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for promptlocker-0.1.0.tar.gz
Algorithm Hash digest
SHA256 08a05427d29365f26b8d572c6785a75a20d9b3d483ca030220df68a46125d533
MD5 0fe00f857e3c92f72ab1ee28eac53e3f
BLAKE2b-256 3434e439ebfb05453dab8b650f55b57023d67e6034a5d307b9144c676b6f3168

See more details on using hashes here.

File details

Details for the file promptlocker-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: promptlocker-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 7.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for promptlocker-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3efbb46f23ff8d596e4bf90ee518b05926984358ebc0ed149438e6567ed8a154
MD5 783e732a3a6506a87e0e8dae43172023
BLAKE2b-256 f20c97e2307c6ca100624a3fe68e6e0efed305b660e0ee69e8025cbcd271518b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page