A lockfile for your prompts. Diff and fail CI on drift.
Project description
promptlock
A
package-lock.jsonfor 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.
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 updateis 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
- mcp-rec — VCR for MCP servers.
- llm-cache-proxy — disk cache for OpenAI/Anthropic API calls.
License
MIT © yubinkim444
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
08a05427d29365f26b8d572c6785a75a20d9b3d483ca030220df68a46125d533
|
|
| MD5 |
0fe00f857e3c92f72ab1ee28eac53e3f
|
|
| BLAKE2b-256 |
3434e439ebfb05453dab8b650f55b57023d67e6034a5d307b9144c676b6f3168
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3efbb46f23ff8d596e4bf90ee518b05926984358ebc0ed149438e6567ed8a154
|
|
| MD5 |
783e732a3a6506a87e0e8dae43172023
|
|
| BLAKE2b-256 |
f20c97e2307c6ca100624a3fe68e6e0efed305b660e0ee69e8025cbcd271518b
|