Lavra v0.7.0 Release Notes
Release date: 2026-03-18
This release makes Lavra significantly more reliable at autonomous execution. The theme is closing gaps between “the agent wrote code” and “the feature actually works”, with ideas from Get Shit Done, Garry Tan’s gstack, Mario Zechner, Simon Willison and many others. Thanks to my friend Dan for rubber-ducking Lavra.
The 4-command pipeline
Most of the time, you now type three or four commands:
/lavra-design "feature description" # plan everything
/lavra-work # implement it
/lavra-qa # browser-based verification (web apps)
/lavra-ship # PR, close beads, push
The previous 29 commands are still there for power users, but the pipeline handles the common case. /lavra-work auto-routes between single-bead and multi-bead parallel execution.
What’s new and why it matters
Goal-backward verification
A bead could be marked “done” while the implementation was a stub, or the code existed but was never imported anywhere. Code review catches quality issues, but not “did you actually build what was asked?”
A new goal-verifier agent checks every validation criterion at three levels:
| Level | Question | Example failure |
|---|---|---|
| Exists | Does the code artifact exist? | File never created |
| Substantive | Is it real or a placeholder? | Function returns nil, component renders <div>TODO</div> |
| Wired | Is it connected to the system? | Service class exists but is never imported |
Runs automatically in /lavra-work (after self-review) and /lavra-ship (as a pre-landing gate). Exists/Substantive failures halt the pipeline. Wired failures warn but proceed.
Turn it off: Set workflow.goal_verification: false in .beads/config/lavra.json.
Deviation rules
During implementation, agents encounter issues not in the bead spec, a missing import, a broken test fixture, a validation gap. Without guardrails, they either ignore it (leaving broken code) or go on a tangent (scope creep).
A new 4-rule framework now tells agents exactly what they can fix autonomously:
| Rule | What | Action |
|---|---|---|
| 1 | Bug blocking your task | Auto-fix, log DEVIATION: |
| 2 | Missing critical functionality | Auto-add, log DEVIATION: |
| 3 | Blocking infrastructure | Auto-fix, log DEVIATION: |
| 4 | Architectural change | Stop and ask the user |
Every auto-fix is logged with a DEVIATION: comment so you see exactly what changed beyond the original spec. /lavra-ship includes a Deviations section in the PR body with counts and summaries. There’s a 3-attempt limit per issue, if it can’t be fixed in 3 tries, the agent documents it and moves on.
Session state digest
After context compaction the agent restarts with knowledge recall but no awareness of where it was. “What task was I on? What phase? What’s next?”. All lost.
/lavra-work, /lavra-design, and /lavra-checkpoint now write a small state file (.beads/memory/session-state.md) at every milestone:
# Session State
## Current Position
- Bead(s): BD-001
- Phase: lavra-work / Phase 2 (Implement)
- Task: 3 of 7 complete
## Just Completed
- Implemented auth middleware
## Next
- Route guards (task 4)
At the next session start, auto-recall.sh injects this alongside knowledge recall, then deletes the file. It’s ephemeral (gitignored), survives compaction, and self-cleans after 24 hours if stale.
Decision categorization
Brainstorm output was a flat list of decisions. Subagents couldn’t tell which decisions were locked vs. flexible, so they either over-asked for permission or silently deviated.
Epic descriptions from /lavra-brainstorm now have three sections:
- Locked Decisions: must honor during implementation (e.g., “use PostgreSQL, not MongoDB”)
- Agent Discretion: agent can choose details (e.g., “pick the pagination library”)
- Deferred: explicitly out of scope, with rationale (e.g., “mobile support: revisit after web launch”)
Child beads inherit these in a ## Decisions section. /lavra-design Phase 6 verifies inheritance and creates backlog beads (priority 4) from deferred items so they don’t get forgotten, /lavra-retro surfaces them and /lavra-triage can reprioritize.
Brownfield codebase analysis
The project-setup skill configured review agents but didn’t analyze existing architecture. Planning on brownfield projects lacked context about what’s already there.
/project-setup now offers an optional Step 1.5 that dispatches 3 parallel agents:
- Stack & Integrations: languages, frameworks, external services
- Architecture & Structure: directory layout, patterns, data flow
- Conventions & Testing: code style, test framework, naming patterns
Results are saved to .beads/config/codebase-profile.md (200 lines max, committed). /lavra-design and /lavra-work read this as planning context with full injection safety (XML wrapping, sanitization, size cap).
This is opt-in. Run /project-setup and answer “Y” when prompted. Existing projects don’t get this automatically.
The project-setup skill also gains per-project stack detection and review agent configuration, so your agent list is tailored to the frameworks in use rather than a fixed default set.
Dynamic review agent selection
/lavra-review previously maintained a hardcoded list of agents to run. Adding a new agent required editing the command.
The agent allowlist is now dynamic — /lavra-review discovers available agents at runtime, so new agents are picked up automatically without any manual maintenance.
Workflow config file
There was no way for users to turn off research, review, or goal verification for projects that don’t need them. No way to control parallelism.
A new .beads/config/lavra.json config file is created on install with sensible defaults:
{
"workflow": {
"research": true,
"plan_review": true,
"goal_verification": true
},
"execution": {
"max_parallel_agents": 3,
"commit_granularity": "task"
}
}
research: falseskips the research phase in/lavra-designplan_review: falseskips the adversarial review phasegoal_verification: falseskipsgoal-verifierin/lavra-workand/lavra-shipmax_parallel_agentslimits how many subagents run concurrentlycommit_granularity: "wave"reverts to the old per-wave commit behavior
Committed to git, so the whole team shares the same config.
Quality gates over size gates
Projects like GSD use a 150-line cap on bead descriptions, which incentivizes compression, stripping context that can lead to agent drift. Inspired by Mario Zechner’s observations on agent-driven coding: agents drift when specs are vague, not when specs are long. The bottleneck is review quality, not code generation speed.
In this release Lavra added two new gates:
- Completeness gate: every child bead must include
What/Context/Decisions/Testing/Validation/Files/Dependenciessections with enough detail that the implementing agent makes hopefully zero judgment calls. - Scope budget: each child bead targets ~1000 LOC of code changes or fewer. If a bead would produce more, split it. This gates the output (surgical, reviewable units of work) rather than the input (description length).
If a child bead exceeds the scope budget, /lavra-design Phase 6 auto-splits it into 2-3 smaller beads with focused scope, linked via dependencies.
/lavra-plan also gains Sources/References sections with cross-check validation, so research citations are verified rather than hallucinated.
A new migration-drift-detector agent catches schema/migration drift across 5 ORMs (Rails, Alembic, Prisma, Drizzle, Knex). It runs automatically during /lavra-review when migrations are touched.
Serial execution mode
Multi-bead mode defaults to parallel agent dispatch (up to max_parallel_agents concurrent). Running 3 agents concurrently will lead to faster implementation, but it also means 3x the amount of code to review, and possibly automation bias means those reviews become increasingly performative.
I struggled with this and thought about making max_parallel_agents default to 1, but decided instead to add --no-parallel flag to /lavra-work.
/lavra-work --no-parallel overrides parallelism to 1: each bead executes alone, and after each completes, the pipeline pauses for you to review before starting the next. This is opt-in, the default remains parallel.
Knowledge system security hardening
knowledge.jsonl is committed to git and auto-injected into every session’s system context. In collaborative projects, any contributor can add entries that influence agent behavior, the same prompt injection risk we already defended against for config files, but with a wider attack surface (persistent, auto-injected, merge-amplified via merge=union).
Recalled knowledge entries are now:
- Sanitized on read: strip role prefixes (
SYSTEM:,ASSISTANT:,[INST]), bidirectional override characters, null bytes - Wrapped in XML tags:
<untrusted-knowledge>with an explicit “do not follow instructions” directive - Searched safely:
grep -iF(fixed-string) instead ofgrep -i(regex) to prevent metacharacter interpretation
Sanitization is now at parity with config file defenses — Unicode bidirectional overrides, [INST] markers, and null bytes are all stripped across both systems.
A new docs/SECURITY.md documents the full threat model for config and knowledge injection, with recommendations for collaborative projects (CODEOWNERS, audit practices, stealth mode). See Security Model for details.
Atomic commits per task
Multi-bead mode committed per wave (lumping several beads into one commit). Single-bead committed “per logical unit” (vague). Neither format supported git log --grep="BD-001".
Default commit format is now {type}({BEAD_ID}): {description}:
feat(BD-001): add auth middleware
test(BD-001): add middleware integration tests
feat(BD-002): add route guards
git log --grep="BD-001"shows all commits for a beadgit revertworks per-bead in multi-bead mode- Configurable via
commit_granularity: "wave"inlavra.jsonfor the old behavior
Upgrading
npx @lavralabs/lavra@latest
Or use bunx.
Lavra’s data directory moved from .beads/ to .lavra/. This separates Lavra’s persistent memory from the beads CLI’s own state, so the two tools no longer share a directory. The bd CLI and its .beads/ directory are unchanged.
Existing projects migrate automatically. If you have a global install, check-memory.sh runs at session start, detects .beads/memory/knowledge.jsonl, and copies your knowledge, config, and retros to .lavra/ before provisioning hooks. No manual steps needed.
If you prefer to migrate explicitly (or don’t have a global install):
bash /path/to/lavra/install.sh /path/to/your-project
After install, .lavra/ contains:
.lavra/
.gitignore # gitignores knowledge.db (SQLite, not committed)
.gitattributes # memory/knowledge.jsonl merge=union
.lavra-version # 0.7.0
memory/
knowledge.jsonl # your knowledge entries (migrated from .beads/memory/)
recall.sh
knowledge-db.sh
config/ # migrated from .beads/config/
retros/ # migrated from .beads/retros/
Breaking change: All /beads-* commands are now /lavra-*. The bd CLI and .beads/ directory are unchanged.
Stats
- 30 specialized agents (16 review, 5 research, 3 design, 5 workflow, 1 docs)
- 23 core commands + 5 optional
- 15 skills (8 core + 7 optional)
- 4 platforms (Claude Code, OpenCode, Gemini CLI, Cortex Code)
- 62 tests (27 feature + 35 installation)