Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions docs/adr/0005-module-package-format.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# ADR-0005: Module Package Format

**Status**: Proposed
**Date**: 2026-04-29
**Authors**: Igor Brandao
**Reviewers**:

## Context

Lola modules bundle multiple components — skills, commands, agents, MCPs, and hooks — into a single distributable unit. Currently modules are fetched as loose files from git repositories, zip archives, or local folders. There is no manifest listing module contents, no integrity checksums, and no standard packaging format for registry-based distribution.

For Lola to support trusted skill catalogs (per the roadmap) and integrate with OCI-based registries (per the Lola + Skill Image collaboration), we need:

1. A dependency declaration file (`lola.mod`) replacing the existing `.lola-req`
2. An integrity verification file (`lola.sum`) tracking checksums of installed modules
3. An OCI artifact type for distributing modules via OCI registries
4. A tarball format for file-based distribution

The Lola + Skill Image collaboration establishes that skillctl handles single-skill OCI packaging and signing, while Lola handles multi-component module bundling and installation. This ADR addresses Lola's packaging side.

## Decision

Introduce `lola.mod` + `lola.sum` as the dependency and integrity pair (mirroring Go's `go.mod` + `go.sum`), and define OCI and tarball distribution formats for modules.

**`lola.mod`**: Declares module dependencies and version requirements. Replaces `.lola-req` which becomes a backwards-compatible alias. Written by `lola mod add`, consumed by `lola sync`.

**`lola.sum`**: Project-level file storing SHA256 checksums of all installed module files. Generated automatically during `lola mod add`. Validated during `lola sync` and `lola install`. Committed to version control alongside `lola.mod` for team reproducibility.

**OCI module artifact**: Modules are packageable as OCI images with artifact type `application/vnd.lola.module.v1`. A single cosign signature covers the entire artifact. Compatible with any OCI-compliant registry (Quay, GHCR, Docker Hub, private).

**Tarball package**: Modules are packageable as `.tar.gz` archives for git and file-based distribution. A single sigstore bundle (`.tar.gz.bundle`) covers the entire archive.

**`lola.yml`** (or `lola.toml`): Optional module metadata file within a module, declaring name, version, description, components, and hooks. When present, used instead of auto-discovery. Viper supports both YAML and TOML formats.

## Rationale

- `lola.mod` + `lola.sum` mirrors Go's proven dependency model — well understood by the Go community and simple to implement
- `.lola-req` backwards compatibility ensures existing projects continue working
- OCI artifact type aligns with skillimage and the broader cloud-native distribution ecosystem
- Tarball format covers the common case of git-based module distribution
- Single signature per module (not per file) scales to modules with many components

## Consequences

### Positive Consequences

- Teams get reproducible installs by committing `lola.mod` and `lola.sum` to version control
- Module integrity is verifiable at install time via checksums
- OCI distribution enables registry-based discovery and cosign signing
- Existing modules without `lola.yml` continue working via auto-discovery
- `.lola-req` backwards compatibility avoids breaking existing projects

### Negative Consequences

- Two new files (`lola.mod`, `lola.sum`) in projects — though they replace the existing `.lola-req`
- OCI module format requires collaboration with skillimage team on layer structure
- Module authors who want signing must learn tarball or OCI packaging workflows

## Alternatives Considered

### Alternative 1: Sign individual files
- Description: Each file in a module gets its own `.bundle` signature file
- Pros: No packaging step needed
- Cons: Does not scale — a module with 10 components needs 10+ signature files
- Reason for rejection: Per-file signing is impractical for multi-component modules

### Alternative 2: npm-style tarball with package.json
- Description: Use a `package.json` manifest with npm-like `lola pack` / `lola publish`
- Pros: Familiar to JavaScript developers
- Cons: Introduces npm conventions into a Go tool; JSON is inconsistent with Lola's YAML-first approach
- Reason for rejection: Go's `go.mod` + `go.sum` model is a better fit for a Go-based tool

### Alternative 3: No manifest, rely solely on sigstore
- Description: Skip `lola.sum` and use sigstore bundles for all integrity verification
- Pros: Single verification mechanism
- Cons: Sigstore requires signing infrastructure; many modules will not be signed initially; no lightweight integrity check for unsigned modules
- Reason for rejection: `lola.sum` provides integrity verification regardless of whether modules are signed

## Implementation Notes

See paired design document: `docs/dev-guide/design/module-package-format.md`

## References

- [ADR-0002: Go Migration](0002-go-migration.md) — Go tech stack and skillimage integration
- [CY26 Roadmap](../concepts/roadmap.md) — trusted catalogs vision
- [Lola + Skill Image Collaboration](https://skillimage.dev/) — responsibility split
- [GitHub Issue #84](https://github.com/LobsterTrap/lola/issues/84) — sigstore MVP
96 changes: 96 additions & 0 deletions docs/dev-guide/design/module-package-format.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# Module Package Format — Implementation Design

Paired with [ADR-0005: Module Package Format](../../adr/0005-module-package-format.md).

## lola.mod Format

Declares module dependencies. Replaces `.lola-req` (kept as backwards-compatible alias).

```
# lola.mod — Lola module requirements
# Equivalent to go.mod for Go projects

module myproject

require (
compliance-skills v1.2.0
react-helpers ^2.0
@mymarket/security-audit ~1.0
)
```

Version constraints follow the existing `.lola-req` syntax: `==`, `>=`, `<=`, `~` (tilde), `^` (caret).

## lola.sum Format

Stores SHA256 checksums of all installed module files. Generated automatically, committed to version control.

```
# lola.sum — Module integrity checksums
compliance-skills v1.2.0 skills/compliance-check/SKILL.md sha256:a1b2c3d4e5f6...
compliance-skills v1.2.0 commands/run-audit.md sha256:f6e5d4c3b2a1...
react-helpers v2.1.0 skills/react-hooks/SKILL.md sha256:1a2b3c4d5e6f...
```

Each line: `<module> <version> <filepath> sha256:<hash>`

## Dependency Flow

```mermaid
flowchart TD
REQ["lola.mod<br/>(requirements)"] -->|lola sync| RESOLVE[Resolve versions]
RESOLVE --> FETCH[Fetch modules]
FETCH --> CHECKSUM{lola.sum exists?}
CHECKSUM -->|yes| VALIDATE[Validate checksums]
CHECKSUM -->|no| GENERATE[Generate checksums]
VALIDATE -->|match| INSTALL[Install to target]
VALIDATE -->|mismatch| ERROR[Error: integrity check failed]
GENERATE --> INSTALL
INSTALL --> UPDATE_SUM[Update lola.sum]
```

## .lola-req Backwards Compatibility

When `lola.mod` is not present but `.lola-req` exists, Lola reads `.lola-req` using the same parser. No format conversion is needed — both files use the same syntax. `lola.mod` is the canonical name going forward.

## OCI Module Artifact

```mermaid
graph LR
subgraph "OCI Image: application/vnd.lola.module.v1"
CONFIG["Config JSON<br/>name, version, description"]
SKILLS["Layer: skills/<br/>SKILL.md files + scripts"]
COMMANDS["Layer: commands/<br/>command .md files"]
AGENTS["Layer: agents/<br/>agent .md files"]
MCPS["Layer: mcps.json"]
META["Layer: lola.yml<br/>module metadata"]
end
COSIGN["Cosign Signature<br/>(one per module)"] -.-> CONFIG
```

- Artifact type: `application/vnd.lola.module.v1`
- Each component directory is a separate layer for efficient caching
- `lola.yml` layer contains module metadata
- One cosign signature covers the entire OCI artifact
- Compatible with any OCI-compliant registry

## Tarball Package

```
module-v1.0.0.tar.gz
├── lola.yml # Module metadata (optional)
├── skills/
│ └── my-skill/
│ └── SKILL.md
├── commands/
│ └── my-command.md
├── agents/
│ └── my-agent.md
└── mcps.json # MCP server config (optional)

module-v1.0.0.tar.gz.bundle # Sigstore bundle (one signature)
```

- Standard `.tar.gz` archive
- Sigstore bundle covers the entire archive
- Used for git-based and file-based distribution
Loading