| name | pyrite-dev |
| description | This skill should be used when working in the /Users/markr/pyrite repo — fixing a bug, adding a feature, writing or running tests, debugging, completing or filing a backlog item, releasing dev→main, or deploying to demo.pyrite.wiki / capturecascade.org / pyrite.ink. Enforces TDD, root-cause debugging, evidence-before-claims verification, and CLI-driven backlog management. |
Pyrite Development Skill
Overview
Systematic development workflow for Pyrite. Covers the full cycle: understand → plan → implement (TDD) → verify → complete.
Announce at start: "I'm using the pyrite-dev skill."
The Iron Laws
1. NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST
2. NO FIX ATTEMPTS WITHOUT ROOT CAUSE INVESTIGATION
3. NO COMPLETION CLAIMS WITHOUT FRESH VERIFICATION EVIDENCE
4. NO BACKLOG CHANGES WITHOUT USING THE CLI (`pyrite update`, `pyrite create`)
Thinking "skip this just once"? That's rationalization. These exist because skipping them always costs more time than following them.
Git Workflow (ADR-0025)
Branches
| Branch | Purpose | Deploys to |
|---|
dev | Daily development (default) | demo.pyrite.wiki (auto on CI pass) |
main | Stable releases only | capturecascade.org, early adopters, PyPI |
feature/* | Large multi-day changes (optional) | Nothing — merge to dev when ready |
All work happens on dev. You should be on the dev branch. Check with git branch --show-current if unsure.
Committing
Commit early and often to dev. The pre-commit hooks (ruff, tests) run automatically. Small, focused commits are better than large batches.
Releasing & Deploying
Daily development does not touch main or run the deploy script. When the user asks to release (dev → main), tag and ship a version, deploy to demo/cascade/pyrite.ink, or hotfix a release, follow release-runbook.md — it holds the full step-by-step process, the deploy.sh commands, and the site→branch mapping.
Development Process
Before Writing Code
Read the relevant backlog item, ADR, or design doc. Understand the goal and the reason for the work before writing code.
CHECKLIST — before any implementation:
- [ ] Read the backlog item / design doc / ADR
- [ ] Check kb/adrs/ for relevant architecture decisions
- [ ] Identify which files need to change (see Key Source Files)
- [ ] Check existing tests for the area being modified
- [ ] If multi-step: create tasks with TaskCreate, set dependencies
Test-Driven Development
RED → GREEN → REFACTOR. No exceptions.
For detailed TDD patterns and anti-patterns, see tdd.md.
Quick version:
- RED — Write one failing test showing desired behavior
- Verify RED — Run it. Confirm it fails for the right reason (feature missing, not typo)
- GREEN — Write minimal code to pass the test. Nothing more.
- Verify GREEN — Run it. Confirm it passes. Confirm other tests still pass.
- REFACTOR — Clean up while staying green. Don't add behavior.
- Commit — Frequent, small commits.
Wrote code before the test? Delete it. Start over. Don't keep it as "reference."
| Rationalization | Reality |
|---|
| "Too simple to test" | Simple code breaks. Test takes 30 seconds. |
| "I'll test after" | Tests passing immediately prove nothing. |
| "Need to explore first" | Fine. Throw away exploration, start with TDD. |
| "TDD will slow me down" | TDD is faster than debugging. Always. |
| "Manual test faster" | Manual doesn't prove edge cases. Can't re-run. |
Systematic Debugging
When something breaks: investigate root cause before attempting fixes.
For the full 4-phase debugging process and supporting techniques, see debugging.md.
Quick version:
- Read error messages carefully — stack traces, line numbers, exact messages
- Reproduce consistently — exact steps, every time
- Check recent changes —
git diff, recent commits, new deps
- Trace data flow — where does bad value originate? Trace backward through call chain.
- Form hypothesis — "I think X because Y." Test minimally. One variable at a time.
- Fix at root cause — not at symptom. Add validation at every layer the data passes through.
If 3+ fix attempts fail: Stop. Question the architecture. Discuss before attempting more fixes.
| Red Flag | Action |
|---|
| "Quick fix, investigate later" | STOP. Investigate now. |
| "Just try changing X" | STOP. Form hypothesis first. |
| "Add multiple changes, see what works" | STOP. One variable at a time. |
| "I don't fully understand but this might work" | STOP. Understand first. |
Verification Before Completion
Evidence before claims. Always.
BEFORE claiming any work is complete:
1. IDENTIFY: What command proves this claim?
2. RUN: Execute the FULL verification (not partial, not cached)
3. READ: Check output — exit code, failure count, warnings
4. VERIFY: Does output confirm the claim?
- YES → State claim WITH evidence
- NO → State actual status with evidence
5. ONLY THEN: Make the claim
Pyrite verification commands:
| Claim | Run | Look For |
|---|
| Backend tests pass | cd /Users/markr/pyrite && .venv/bin/pytest tests/ -v | X passed, 0 failed |
| Frontend unit tests pass | cd web && npm run test:unit | All tests pass |
| E2E tests pass | cd web && npm run test:e2e | All tests pass |
| Build succeeds | cd web && npm run build | dist/ created, exit 0 |
| Linting passes | ruff check pyrite/ | No errors |
| Type check passes | cd web && npm run check | No errors |
| KB index healthy | .venv/bin/pyrite index health | ✓ Index is healthy |
| KB content findable | .venv/bin/pyrite search "<feature>" -k pyrite | Relevant results appear |
| Components documented | .venv/bin/pyrite sw components | New services listed |
| Backlog current | .venv/bin/pyrite sw backlog | Statuses match reality |
Forbidden words without evidence: "should work", "looks correct", "probably passes", "I'm confident"
Pre-Commit Checklist: Use the CLI
Dogfood Pyrite's own tools to manage the KB. Don't hand-edit markdown when the CLI can do it.
⚠️ PRE-COMMIT: KB DOCUMENTATION (use CLI)
───────────────────────────────────────────
1. Sync the index to pick up any files changed during this work:
.venv/bin/pyrite index sync
2. Search for existing docs that may need updating:
.venv/bin/pyrite search "<feature name>" -k pyrite
3. Check current component/ADR/backlog state:
.venv/bin/pyrite sw components
.venv/bin/pyrite sw adrs
.venv/bin/pyrite sw backlog --status proposed
4. Create or update KB entries via CLI:
.venv/bin/pyrite create -k pyrite -t component --title "..." -b "..." --tags core,api
.venv/bin/pyrite update <entry-id> -k pyrite -b "new body"
5. For new ADRs (TITLE is positional, not --title; always pass -k or the file
lands in ./adrs/ in your cwd instead of kb/adrs/ — see gotchas.md):
.venv/bin/pyrite sw new-adr "Title Here" -k pyrite --status accepted
6. Verify the new content is findable:
.venv/bin/pyrite search "<key terms>" -k pyrite
7. Check index health:
.venv/bin/pyrite index health
Use the correct type frontmatter for KB entries so plugin tools can find them:
type: component (with kind, path, owner, dependencies) → shows in pyrite sw components
type: adr (with adr_number, status, date) → shows in pyrite sw adrs
type: backlog_item (with kind, status, priority, effort) → shows in pyrite sw backlog
type: standard → shows in pyrite sw standards
⚠️ PRE-COMMIT: UPDATE BACKLOG (use CLI — no BACKLOG.md)
─────────────────────────────────────────────────────────
The backlog has no index file. `pyrite sw backlog` is the source of truth.
- Completed an item?
.venv/bin/pyrite update <id> -k pyrite -f status=done
git mv kb/backlog/<id>.md kb/backlog/done/
.venv/bin/pyrite index sync
Use `status=done` — never `completed`. `completed` is off-enum for backlog
items; it passes silently but drifts the board (it once stranded 75 items on
an undetected status). `done` is the canonical value (see gotchas.md).
- Check current state:
.venv/bin/pyrite sw backlog
- Discovered new work?
.venv/bin/pyrite create -k pyrite -t backlog_item --title "..." -b "..." --tags <tags>
- Unblocked downstream items? Note it in the item body via `pyrite update -b`.
Ask: "Did this work change the status of any backlog item, or reveal new work?"
⚠️ PRE-COMMIT: UPDATE GOTCHAS
───────────────────────────────
- Hit a surprising behavior? → Append to .claude/skills/pyrite-dev/gotchas.md
- Resolved an existing gotcha? → Update or remove it from gotchas.md
- Found a new _resolve_entry_type mapping issue? → Document it
Ask: "Did I encounter any non-obvious behavior that would trip up the next agent?"
Wave Completion Checklist
Run this at the end of every wave, before the final commit. This is both process enforcement and dogfooding.
.venv/bin/pyrite index sync
.venv/bin/pyrite index health
.venv/bin/pyrite search "<wave feature 1>" -k pyrite
.venv/bin/pyrite search "<wave feature 2>" -k pyrite
.venv/bin/pyrite sw components
.venv/bin/pyrite sw adrs
.venv/bin/pyrite sw backlog
.venv/bin/pytest tests/ -v
Completing a Feature
When implementation + verification are done, follow the backlog process:
- Update the item's status via CLI (validates + syncs index automatically):
.venv/bin/pyrite update <item-id> -k pyrite -f status=done
Never hand-edit YAML frontmatter for status changes — the CLI validates field values and keeps the index in sync. Hand-editing skips validation and leaves the index stale until the next pyrite index sync.
- Move the file from
kb/backlog/ to kb/backlog/done/ (git mv)
- Re-sync the index so the move is reflected:
.venv/bin/pyrite index sync
- If work revealed new tech debt or follow-on features:
- Verify with
pyrite sw backlog — it is the source of truth (no BACKLOG.md file exists)
- Commit the backlog changes
Architecture Quick Reference
Key source files
For the canonical file map (plugins, models, schema, CLI, storage, server, all services), see architecture.md. Consult it when planning a change to know where to look first.
Architecture decisions
See kb/adrs/ for full details:
| ADR | Decision |
|---|
| 0001 | Git-native markdown storage |
| 0002 | Plugin system via entry points |
| 0003 | Two-tier durability (content: git, engagement: SQLite) |
| 0006 | MCP three-tier tools (read/write/admin) |
| 0007 | AI integration: three surfaces, BYOK, Anthropic+OpenAI SDKs |
| 0008 | Structured data: schema-as-config, field types, object refs |
| 0017 | Entry protocol mixins (promoted indexed columns) |
| 0025 | Release workflow: dev branch default, tagged releases, deploy tiers |
| 0026 | FIPS/state as promoted entry columns |
The list above is a curated subset (the repo is at ADR-0028). Run pyrite sw adrs
for the current full set before relying on a decision being recorded.
6 plugin integration points
- Entry type resolution —
get_entry_class() consults registry before GenericEntry
- CLI commands —
cli/__init__.py adds plugin Typer sub-apps
- MCP tools —
mcp_server.py merges plugin tools per tier
- Validators —
schema.py runs plugin validators always (even for undeclared types)
- Relationship types —
schema.py merges plugin relationship types
- PluginContext —
set_context(ctx) injects config, db, and services into plugins at startup
Parallel Agent Work
For wave planning, agent launch checklists, and the merge protocol, see parallel-agents.md.
Critical: Do NOT use isolation: "worktree". Agents work directly on the current branch (usually dev). Edit tool retries on conflict are cheaper than worktree merge ceremonies. See CLAUDE.md and parallel-agents.md.
Quick rules:
- No worktrees — agents write directly to the working tree, no isolation parameter
- Each wave item must list its file footprint — minimize shared modified files
- When agents share a file, Edit's exact-match fails gracefully on conflict — the agent retries
- Max 3 parallel agents per wave
- Commit all pending work before launching agents
- Run full test suite after all agents complete
Extension Building
For complete scaffolding recipes, entry type contracts, plugin class templates, and validator/preset patterns, see extensions.md.
Testing Conventions
For the 8-section test structure, fixture patterns, and test-specific gotchas, see testing.md.
Data Pipelines
For the entry lifecycle (create → validate → build → save → index → embed), type resolution behavior, and the build_entry factory, see data-pipelines.md.
Gotchas
For known pitfalls with hooks, DB access, entry IDs, validators, and two-tier durability, see gotchas.md.