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
19 changes: 19 additions & 0 deletions .github/workflows/ci_local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,22 @@ jobs:
run: |
go test -race -coverprofile=coverage.out -covermode=atomic ./...
go tool cover -func=coverage.out | tail -1

module-sync:
name: Module Sync Check
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false

- name: Verify module copies match sources
run: |
diff -r skills/mcp-setup module/skills/mcp-setup
diff -r skills/audit-pipeline module/skills/audit-pipeline
diff -r skills/pack-assessment module/skills/pack-assessment
diff .opencode/commands/comply-setup.md module/commands/comply-setup.md
diff .opencode/commands/comply-pipeline.md module/commands/comply-pipeline.md
diff .opencode/commands/comply-pack.md module/commands/comply-pack.md
24 changes: 24 additions & 0 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,30 @@ Or use the setup command to generate it interactively:
| `/comply-pack` | Generate Rego policies from the child policy |
| `/comply-pipeline` | Run the comply pipeline (scoping, mapping, adherence)|

## Lola (any AI assistant)

Install the complypack module with [lola](https://lobstertrap.org/lola/):

```bash
lola mod add https://github.com/complytime/complypack.git
lola install complypack -a opencode --scope project
```

This installs skills and commands into `.opencode/skills/` and
`.opencode/commands/`. After installation, the `/comply-setup`,
`/comply-pipeline`, and `/comply-pack` commands are available in OpenCode.

To update after complypack releases new skills:

```bash
lola mod update complypack
lola install complypack -a opencode --scope project
```

> **Note:** The MCP server still requires separate configuration. Run
> `/comply-setup` after installation to generate the MCP config, or
> edit `mcps.json` manually with your registry and schema values.

## SELinux (Fedora / RHEL)

On systems with SELinux enforcing, volume mounts require the `:z` suffix so
Expand Down
23 changes: 23 additions & 0 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,29 @@ tasks:
generates:
- json-schema/*.json

sync-module:
desc: Copy skills and commands into module/ for lola distribution
cmds:
- rm -rf module/skills/mcp-setup module/skills/audit-pipeline module/skills/pack-assessment
- rm -f module/commands/comply-setup.md module/commands/comply-pipeline.md module/commands/comply-pack.md
- mkdir -p module/skills module/commands
- cp -r skills/mcp-setup module/skills/mcp-setup

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is kind of odd to me. Is the intent to support lola as well as other mechanisms?

lola will install to both claude and opencode.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the intent is to support lola alongside the existing tool-specific plugin directories. Currently lola installs to OpenCode only. The root-level skills/ directory is the canonical source; .opencode/skills/ contains symlinks back to it for local complypack development (so OpenCode discovers the skills when working on this repo). module/ is the lola-distributable copy. sync-module keeps module/ in sync with the canonical sources so both paths stay current.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lola will install to OpenCode, Claude, Gemini, and Cursor.

- cp -r skills/audit-pipeline module/skills/audit-pipeline
- cp -r skills/pack-assessment module/skills/pack-assessment
- cp .opencode/commands/comply-setup.md module/commands/comply-setup.md
- cp .opencode/commands/comply-pipeline.md module/commands/comply-pipeline.md
- cp .opencode/commands/comply-pack.md module/commands/comply-pack.md

check-module-sync:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[MEDIUM] check-module-sync is described as "CI-friendly" in the PR description, but no workflow in .github/workflows/ runs it. Without CI enforcement, drift between canonical sources (skills/, .opencode/commands/) and module/ copies will go undetected after future edits to canonical files. Consider adding a CI job that runs this target, or note in the PR description that CI integration is planned for a follow-up.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in fd6f701: added a module-sync job to ci_local.yml that runs the diff checks on every push and PR to main. Used diff directly rather than task check-module-sync to avoid requiring Taskfile as a CI dependency. Automated syncing via a pre-commit hook is tracked in #139.

desc: Verify module/ skills and commands match their sources
cmds:
- diff -r skills/mcp-setup module/skills/mcp-setup
- diff -r skills/audit-pipeline module/skills/audit-pipeline
- diff -r skills/pack-assessment module/skills/pack-assessment
- diff .opencode/commands/comply-setup.md module/commands/comply-setup.md
- diff .opencode/commands/comply-pipeline.md module/commands/comply-pipeline.md
- diff .opencode/commands/comply-pack.md module/commands/comply-pack.md

default:
cmds:
- task: generate-schemas
57 changes: 57 additions & 0 deletions docs/adr/018-lola-module-distribution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# ADR 018: Lola Module for Skill Distribution

**Status:** Proposed

**Date:** 2026-07-13

**Context:**

Complypack provides AI coding assistants with compliance pipeline skills (audit-pipeline, mcp-setup, pack-assessment) and slash commands (comply-setup, comply-pipeline, comply-pack). These artifacts are authored in two canonical locations:

- `skills/` — skill definitions (markdown with frontmatter)
- `.opencode/commands/` — slash command definitions

Consumer repositories need these skills and commands installed into their own tool-specific directories. Before this change, the only installation path was manual: clone the repo, copy files into the right directories, and repeat on every update. Tool-specific plugin directories (`.claude-plugin/`, `.cursor-plugin/`, `gemini-extension.json`) reference `skills/` directly but only work within the complypack repository itself.

[Lola](https://lobstertrap.org/lola/concepts/skills-and-modules/) provides a standard layout (`module/`) and install command (`lola install`) for distributing AI coding assistant artifacts across repositories. It currently supports OpenCode as the install target.

The challenge is maintaining two sets of files — canonical sources and distributable copies — without them silently drifting apart.

**Decision:**

Add a `module/` directory following the lola AI Context Module layout. Module files are exact copies of their canonical sources, not symlinks, because lola requires a self-contained directory that it can copy into consumer repositories.

**Drift prevention** uses two Taskfile targets:

1. **`task sync-module`** — copies canonical sources into `module/`. Run by contributors after editing canonical files.
2. **`task check-module-sync`** — diffs module copies against sources, exits non-zero on divergence. A `Module Sync Check` job in `ci_local.yml` runs this on every push and PR, preventing drift from reaching `main`.

A pre-commit hook to automate step 1 is tracked separately.

**`mcps.json` version strategy:** The module includes a `mcps.json` with `VERSION` placeholders rather than a pinned release tag or a floating tag like `latest`/`main`. Floating tags were rejected per the constitution's container standards ("MUST use a specific base image tag or digest. MUST NOT use `latest` or floating tags"). Pinning a release tag would go stale on next release. The `mcp-setup` skill handles interactive version resolution at runtime, so the placeholder is the honest representation — users run `/comply-setup` or substitute the version manually.

**Command scope:** Only the three `/comply-*` commands (comply-setup, comply-pipeline, comply-pack) are included. The `review-pr.md` command (a general-purpose PR review workflow) is excluded because it is not a compliance command and consumer repos may have their own review workflows.

**Module `AGENTS.md` scope:** The module's `AGENTS.md` is a consumer-facing overview — what complypack is, what the skills do, the pipeline flow, and how to invoke commands. It does not reuse the root `AGENTS.md`, which contains contributor-focused architecture notes (domain packages, transport layers, testing split) that are irrelevant to consumers.

The existing tool-specific integrations (`.claude-plugin/`, `.cursor-plugin/`, `.opencode/skills/` symlinks, `gemini-extension.json`) remain unchanged. The `.opencode/skills/` symlinks serve local complypack development — they point back to `skills/` at the repo root so OpenCode discovers the skills when working on this repo. They are not part of any distribution mechanism.

**Consequences:**

**Benefits:**

- Consumer repos install with `lola mod add` + `lola install` instead of manual file copying
- CI catches drift between canonical sources and module copies before merge
- Existing tool integrations are unaffected (backwards compatible)
- Canonical sources remain the single source of truth

**Drawbacks:**

- Every canonical file has an exact copy in `module/`, increasing maintenance surface
- Contributors must run `task sync-module` after editing canonical files (until pre-commit hook is added)
- Lola currently supports OpenCode only; other tools still require their own plugin directories

**Related:**

- ADR 012: Container-Based MCP Server Distribution
- ADR 015: Comply Pipeline as Plugin Skills
45 changes: 45 additions & 0 deletions module/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# ComplyPack

ComplyPack provides AI coding assistants with compliance pipeline skills
and an MCP server for working with [Gemara](https://github.com/gemaraproj)
control catalogs.

## MCP Server

The complypack MCP server serves Gemara artifacts (catalogs, policies,
mappings) and provides tools for policy validation, assessment triage,
and parameter analysis. Configure it via `/comply-setup` or manually
in your tool's MCP configuration. See `mcps.json` for the base template.

## Skills

| Skill | Trigger | Purpose |
|-------|---------|---------|
| `mcp-setup` | User wants to configure MCP servers | Interactive setup wizard for complypack and gemara MCP servers |
| `audit-pipeline` | User wants to build compliance artifacts or prepare for audit | Three-stage pipeline: scoping, mapping, adherence |
| `pack-assessment` | User mentions Rego, Conftest, OPA, or policy generation | Generate Rego policies from Gemara catalogs |

### Pipeline Flow

```
scoping -> mapping -> adherence -> pack-assessment
```

1. **Scoping** -- Characterize the system, scope control catalogs, identify gaps
2. **Mapping** -- Crosswalk frameworks, harmonize parameters across layers
3. **Adherence** -- Compile a Gemara Policy with assessment plans
4. **Pack** -- Generate Rego policies for automated assessment plans

## Commands

| Command | Description |
|---------|-------------|
| `/comply-setup` | Configure complypack MCP server for this project |
| `/comply-pipeline` | Run the comply pipeline (scoping, mapping, adherence) |
| `/comply-pack` | Generate Rego policies from the child policy |

## Safety

All control IDs, requirement IDs, and parameter values MUST come from MCP
resources. Skills enforce this constraint to prevent hallucinated policy
content. The MCP server is the single source of truth.
6 changes: 6 additions & 0 deletions module/commands/comply-pack.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
description: Generate Rego policies from the child policy
---

Load the `pack` skill and execute it. Read `.complytime/child-policy.yaml`
for the assessment plans to generate Rego policies from.
6 changes: 6 additions & 0 deletions module/commands/comply-pipeline.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
description: Run the comply pipeline (scoping, mapping, adherence)
---

Load the `pipeline` skill and execute it. Check `.complytime/` for existing
artifacts to determine which stage to resume from.
6 changes: 6 additions & 0 deletions module/commands/comply-setup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
description: Configure complypack MCP server for this project
---

Load the `setup` skill and execute it. Generate `.mcp.json` with the
complypack MCP server configuration for the current project.
14 changes: 14 additions & 0 deletions module/mcps.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"mcpServers": {
"complypack": {
"command": "podman",
"args": [
"run", "--rm", "-i",
"ghcr.io/complytime/complypack:VERSION",
"mcp", "serve",
"--source", "oci://YOUR_REGISTRY/YOUR_CATALOG:VERSION",
"--schema", "YOUR_PLATFORM"
]
}
}
}
52 changes: 52 additions & 0 deletions module/skills/audit-pipeline/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
name: audit-pipeline
description: Use when user wants to build Gemara Policy artifacts for audit preparation or compliance program setup
---

# /comply:audit-pipeline — ComplyTime Audit Pipeline

Guide users through building a Gemara Policy (applicability statement) from their system architecture and governance sources. The Gemara Policy is the formal contract between audit and engineering, functionally equivalent to an ISO 27001 Statement of Applicability or a NIST System Security Plan.

## Safety

**CRITICAL:** Every stage MUST read control IDs, requirement IDs, and parameter values from MCP resources. DO NOT generate these from memory. The MCP server is the source of truth.

## Pipeline Stages

| Stage | Artifact | Purpose |
|-----------|-----------------------------------|------------------------------------------------------------------|
| scoping | `.complytime/scoping.yaml` | System profile + Control Catalog scoping + gap analysis |
| mapping | `.complytime/delta-report.yaml` | Parameter delta analysis + harmonization across framework layers |
| adherence | `.complytime/child-policy.yaml` | Compile the child Policy with adherence plan |

After adherence, invoke `/comply:pack-assessment` to generate assessment logic for use with `complyctl`.

## Router Logic

1. Check if `.complytime/` directory exists and which artifacts are present
2. Determine pipeline state:
- No `.complytime/` directory → start at **scoping**
- `scoping.yaml` exists but no `delta-report.yaml` → offer **mapping**
- `delta-report.yaml` exists but no `child-policy.yaml` → offer **adherence**
- `child-policy.yaml` exists → pipeline complete, offer to re-run any stage or proceed to `/comply:pack-assessment`
3. If the user specified a stage, validate prerequisites:
- **mapping** requires `scoping.yaml`
- **adherence** requires `delta-report.yaml`
4. Dispatch to the appropriate stage skill

## Dispatching

Read the stage instructions from this skill's base directory before proceeding:

Comment thread
trevor-vaughan marked this conversation as resolved.
- **scoping** → `scoping.md`
- **mapping** → `mapping.md`
- **adherence** → `adherence.md`

## Status Display

```text
/comply:audit-pipeline status:
[done] scoping — .complytime/scoping.yaml
[done] mapping — .complytime/delta-report.yaml
[next] adherence — not yet run
```
Loading
Loading