PersonaSpec toolkit for LLM agents
Project description
larva
larva is the PersonaSpec toolkit for the opifex stack. It validates,
normalizes, registers, resolves, updates, exports, and projects persona specs.
Status: this document describes the implemented registry-local variants public surface and the target contract/variant registry storage model. Assembly/component public surfaces have been removed.
The canonical PersonaSpec contract authority is opifex. larva consumes that contract; it does not redefine it.
What larva is for
Use larva when you want a stable local registry/admission/projection authority for registered agent persona instances instead of ad hoc prompt files scattered across tools and repos.
- Validate PersonaSpec JSON before it reaches runtime
- Store canonical personas in a local registry under
~/.larva/ - Manage registry-local variants without changing the PersonaSpec schema
- Resolve, clone, update, delete, and export personas across tools
- Project the active variant of each registered persona into OpenCode
- Expose the same operations through MCP, CLI, Python, and a small web UI
larva does not run agents, call LLMs, enforce gateway policy, or manage memory.
larva opencode is only a launcher for the real OpenCode runtime.
Install
pip install larva
Development checkout:
uv sync
uv run larva --help
Quick start
Create a complete PersonaSpec JSON file:
{
"spec_version": "0.1.0",
"id": "code-reviewer",
"description": "Reviews code changes with read-focused tooling.",
"prompt": "You are a senior code reviewer.",
"model": "openai/gpt-5.5",
"capabilities": {"shell": "read_only"}
}
Then validate, register, and resolve:
larva validate code-reviewer.json
larva register code-reviewer.json
larva resolve code-reviewer --json
Core concepts
PersonaSpec
The main larva artifact is a flat JSON object called PersonaSpec.
Key rules:
idis required and must be flat kebab-casepromptis opaque executable text; larva stores and validates it as text and does not parse placeholders or infer runtime behavior from itspec_versionis schema identity, not persona revisioning- v1 pins
spec_versionto"0.1.0" spec_digestis recomputed by larva from canonical content- there is no inheritance,
base:, orvariantfield in canonical output
Registry-local variants
Variants are local registry metadata, not PersonaSpec fields. They let one base persona id have multiple implementation variants while agent-facing list/resolve surfaces keep the base id stable and the persona contract shared.
~/.larva/
registry/
code-reviewer/
manifest.json # {"active": "default"}
contract.json # id, description, capabilities, can_spawn, spec_version
variants/
default.json # prompt, model, model_params, compaction_prompt
tacit.json # prompt, model, model_params, compaction_prompt
Important behavior:
larva listshows base persona ids, not variant metadatalarva resolve code-reviewermaterializes the active variant as a canonical PersonaSpeclarva resolve code-reviewer --variant tacitreturns a specific variantvariantis passed as an operation parameter or registry envelope metadata; it is never accepted inside a PersonaSpec objectmanifest.jsonstores only the active pointer ({"active": "default"}); missing or corrupt manifests fail closed instead of being auto-createdcontract.jsonowns persona identity, description, capability intent,can_spawn, andspec_version; variant files own prompt/model execution fields only- assembly/component inputs are removed; register full canonical PersonaSpecs directly
Interfaces
MCP
larva_validate(spec) -> ValidationReport
larva_register(spec, variant?) -> {id, registered}
larva_resolve(id, overrides?, variant?) -> PersonaSpec
larva_list() -> [{id, description, spec_digest, model}]
larva_update(id, patches, variant?) -> PersonaSpec
larva_update_batch(where, patches, dry_run?) -> {items, matched, updated}
larva_clone(source_id, new_id) -> PersonaSpec
larva_delete(id) -> {id, deleted}
larva_clear(confirm) -> {cleared, count}
larva_export(all?, ids?) -> [PersonaSpec, ...]
larva_variant_list(id) -> registry variant metadata
larva_variant_activate(id, variant) -> {id, active}
larva_variant_delete(id, variant) -> {id, variant, deleted}
Removed MCP tools:
larva_assemble
larva_component_list
larva_component_show
Start larva as an MCP server:
larva mcp
CLI
larva validate <spec.json> [--json]
larva register <spec.json> [--variant <name>] [--json]
larva resolve <id> [--variant <name>] [--override key=value]... [--json]
larva list [--json]
larva update <id> [--variant <name>] --set key=value [--set ...] [--json]
larva clone <source-id> <new-id> [--json]
larva delete <id> [--json]
larva clear --confirm "CLEAR REGISTRY" [--json]
larva export --all [--json]
larva export --id <id> [--id <id>]... [--json]
larva variant list <id> [--json]
larva variant activate <id> <variant> [--json]
larva variant delete <id> <variant> [--json]
larva doctor [--json]
larva opencode [OPENCODE_ARG ...]
Update rules: without --variant, contract-only patches update the shared
persona contract and implementation-only patches update the active variant. With
--variant, only prompt, model, model_params, and compaction_prompt are
patchable. description, capabilities, and can_spawn are contract patches;
id, spec_version, and spec_digest are never patchable. Mixed-scope patches
are rejected.
Python API
from larva.shell.python_api import (
validate,
register,
resolve,
update,
update_batch,
clone,
list,
delete,
clear,
export_all,
export_ids,
variant_list,
variant_activate,
variant_delete,
)
Web UI
larva serve
The packaged web UI shows base persona ids and active variant state for human
management. Registry variant endpoints return {_registry, spec} envelopes;
_registry is local metadata and spec is canonical PersonaSpec.
OpenCode plugin
larva opencode
larva opencode --agent python-senior
larva opencode launches the real OpenCode CLI with a temporary dynamic config
built from the active variant of each base persona id in the larva registry. The
OpenCode agent name is the Larva base persona id; inactive registry-local
variants are not projected as separate OpenCode agents.
The wrapper/plugin path uses placeholder agents at startup and replaces each
[larva:<id>] placeholder inside OpenCode's system-prompt transform before a
model request. This gives persona prompts system-prompt strength rather than
ordinary MCP/tool-result context.
The hardening contract for this path is: existing persona ids refresh by
re-resolving the selected id, cache is performance-only, raw placeholders must
never reach the model, and no /larva refresh command is required. Adding or
deleting persona ids still requires restarting larva opencode so OpenCode can
see the new agent list. See contrib/opencode-plugin/README.md for current
behavior, target refresh semantics, and failure handling.
Architecture
larva uses a strict layered structure enforced by Invar.
| Layer | Path | Role |
|---|---|---|
| Core | src/larva/core/ |
Pure logic, contracts, no I/O |
| App | src/larva/app/ |
Use-case orchestration |
| Shell | src/larva/shell/ |
CLI, MCP, filesystem, web adapters |
Read next
docs/README.md- documentation map by categorydocs/guides/USER_GUIDE.md- detailed human-oriented usage guidedocs/guides/USAGE.md- agent-oriented operational guidedocs/reference/INTERFACES.md- public interface specificationdocs/reference/ARCHITECTURE.md- module boundaries and dependency designdesign/registry-local-variants-and-assembly-removal.md- accepted design for variant routing and assembly removaldocs/adr/ADR-001-spec-version-boundary.md-spec_versiondesign decisiondocs/adr/ADR-002-capability-intent-without-runtime-policy.md- capability intent modeldocs/adr/ADR-003-canonical-requiredness-authority.md- canonical requiredness authoritydocs/adr/ADR-004-empty-capabilities-and-unrestricted-semantics.md- empty capability semantics and unrestricted boundary
License
AGPL-3.0-or-later
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 larva-0.4.10.tar.gz.
File metadata
- Download URL: larva-0.4.10.tar.gz
- Upload date:
- Size: 961.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
39aee97d7cc3d9da33688aaca0a940b092e560bbc0779d1f8f6dd03c9769ad0d
|
|
| MD5 |
ee692bdc166c02c96271ce986b5396e4
|
|
| BLAKE2b-256 |
2c00f08954c8f18f3393cc33bb183179361e34ae6c916513fa6ef1faa0f41bd0
|
Provenance
The following attestation bundles were made for larva-0.4.10.tar.gz:
Publisher:
publish.yml on Tefx/larva
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
larva-0.4.10.tar.gz -
Subject digest:
39aee97d7cc3d9da33688aaca0a940b092e560bbc0779d1f8f6dd03c9769ad0d - Sigstore transparency entry: 1439287945
- Sigstore integration time:
-
Permalink:
Tefx/larva@de8b9d65dbae4d9475e20213a4857bb9237a82ea -
Branch / Tag:
refs/tags/v0.4.10 - Owner: https://github.com/Tefx
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@de8b9d65dbae4d9475e20213a4857bb9237a82ea -
Trigger Event:
release
-
Statement type:
File details
Details for the file larva-0.4.10-py3-none-any.whl.
File metadata
- Download URL: larva-0.4.10-py3-none-any.whl
- Upload date:
- Size: 111.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
364f275ff253b7e405aee4295969799917c54b96c2297ff25d0815cfc10af554
|
|
| MD5 |
f8c2063fe14ef7856c20e3757ab79fda
|
|
| BLAKE2b-256 |
ed6893d7cf92da80ab5f34af4a1758822c522903d4695edb5bb07ab7fbef5e1f
|
Provenance
The following attestation bundles were made for larva-0.4.10-py3-none-any.whl:
Publisher:
publish.yml on Tefx/larva
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
larva-0.4.10-py3-none-any.whl -
Subject digest:
364f275ff253b7e405aee4295969799917c54b96c2297ff25d0815cfc10af554 - Sigstore transparency entry: 1439287949
- Sigstore integration time:
-
Permalink:
Tefx/larva@de8b9d65dbae4d9475e20213a4857bb9237a82ea -
Branch / Tag:
refs/tags/v0.4.10 - Owner: https://github.com/Tefx
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@de8b9d65dbae4d9475e20213a4857bb9237a82ea -
Trigger Event:
release
-
Statement type: