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
2 changes: 2 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Pull Request

## Summary
_Please include a summary of the changes and the context of this PR._

Expand Down
19 changes: 19 additions & 0 deletions .markdownlint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"default": true,
"MD004": false,
"MD007": {
"indent": 2
},
"MD013": false,
"MD024": {
"siblings_only": true
},
"MD026": {
"punctuation": ".,;:!。,;:"
Comment thread
trevor-vaughan marked this conversation as resolved.
},
"MD029": false,
"MD033": false,
"MD036": false,
"MD041": false,
"blank_lines": false
}
3 changes: 2 additions & 1 deletion .mega-linter.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# https://megalinter.io/latest/supported-linters/
ADDITIONAL_EXCLUDED_DIRECTORIES:
- vendor
MARKDOWN_MARKDOWNLINT_FILTER_REGEX_EXCLUDE: "(vendor/)"
- .opencode
MARKDOWN_MARKDOWNLINT_FILTER_REGEX_EXCLUDE: "(vendor/|\\.opencode/)"
PROTOBUF_PROTOLINT_FILTER_REGEX_EXCLUDE: "(vendor/)"
ENABLE_LINTERS:
- ACTION_ZIZMOR
Expand Down
2 changes: 1 addition & 1 deletion .specify/memory/constitution.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ Decrease the number of decisions a developer or user needs to make. Provide defa
Every repository under the ComplyTime organization MUST contain the following standard files in the root directory to ensure a consistent developer experience:

| File | Description | Standard |
|:---|:----|:----|
| :--- | :---- | :---- |
| `README.md` | Project overview, installation, and usage. | Markdown |
| `LICENSE` | Legal terms of use. | **Apache License 2.0** |
| `CONTRIBUTING.md` | Guidelines for contributors. | Link to org-wide guide or repo-specific details. |
Expand Down
18 changes: 9 additions & 9 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ make crapload-check # check for CRAP regressions against baseline
### CI Workflow Structure

| Workflow | File | Purpose |
|----------|------|---------|
| ---------- | ------ | --------- |
| CI | `ci_checks.yml` | Standardized CI via org-infra reusable workflow |
| Unit Test | `unit_test.yml` | Unit tests + buf lint |
| E2E Test | `e2e_test.yml` | End-to-end tests with mock registry |
Expand Down Expand Up @@ -206,19 +206,19 @@ These rules are non-negotiable. Violations are CRITICAL severity.

### PR Review Commands

| Command | When | Scope |
|---------|------|-------|
| `/review-council` | Pre-PR (local) | 5+ Divisor agents |
| `/review-pr [N]` | Post-PR (GitHub) | Single agent, CI analysis |
| Command | When | Scope |
|-------------------|------------------|---------------------------|
| `/review-council` | Pre-PR (local) | 5+ Divisor agents |
| `/review-pr [N]` | Post-PR (GitHub) | Single agent, CI analysis |

## Specification Workflow

All non-trivial changes MUST be preceded by a spec workflow.

| Tier | Tool | When | Artifacts |
|------|------|------|-----------|
| Strategic | Speckit | >= 3 stories, cross-repo | `specs/NNN-*/` |
| Tactical | OpenSpec | < 3 stories, single-repo | `openspec/changes/*/` |
| Tier | Tool | When | Artifacts |
|------------|----------|---------------------------|------------------------|
| Strategic | Speckit | >= 3 stories, cross-repo | `specs/NNN-*/` |
| Tactical | OpenSpec | < 3 stories, single-repo | `openspec/changes/*/` |

Pipeline: `constitution → specify → clarify → plan → tasks →
analyze → checklist → implement`
Expand Down
74 changes: 36 additions & 38 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,38 @@
the full log file lives. The flag description is updated to
`"output debug logs to stderr and log file"`. (#614)

- `complyctl scan --format` reports (SARIF, OSCAL, Markdown) now written
to `.complytime/scan/` alongside the evaluation log, matching
documented behavior. Previously, format reports were written to the
workspace root. (#615)
- Generation freshness detection now tracks complypack digests alongside
policy digests. Previously, updating a complypack without changing the
policy would skip regeneration, causing providers to use stale
artifacts (#583).
- OCI reference parsing now supports standard `:tag` syntax (e.g.,
`registry.com/org/image:v0.4.0`) in addition to the existing `@version`
notation for both policies and complypacks. Digest references
(`@sha256:...`) are also supported. Invalid OCI references in
`complytime.yaml` are now detected at config load time with clear
error messages. (#594)
- `complyctl doctor` now reports invalid policy references in
`CheckPolicyActivePeriod` and `CheckComplypacks` as explicit
failures instead of silently skipping them. `CheckVariables`
now surfaces per-policy resolution errors with specific messages
instead of a silent counter. (#600)
- Scan reports now resolve assessment plan IDs to requirement IDs,
ensuring output displays meaningful identifiers instead of internal
plan references. Affects EvaluationLog, OSCAL, SARIF, and Markdown
output formats.
- `complyctl get` now detects and rejects duplicate evaluator-ids across
complypack entries. Previously, multiple complypacks resolving to the
same evaluator-id caused non-deterministic digest selection during
scan, leading to unnecessary regeneration or stale artifacts (#647).
- `complyctl get` now re-fetches complypack artifacts when the cache
directory is missing, even if `state.json` records a matching digest.
Previously, a deleted cache directory caused the sync to be permanently
skipped until the user manually cleared state (#649).

### Changed

- Release workflow gains preflight validation gate: tag format and
Expand All @@ -24,6 +56,10 @@
annotated tag creation. Concurrency group prevents parallel
releases. (#560)

- All commands now accept `--workspace` flag to specify workspace directory
- `NewWorkspace()` function signature changed from `NewWorkspace()` to `NewWorkspace(baseDir string)`
- Log file and scan output paths are now relative to resolved workspace directory

### Removed

- **BREAKING**: Removed collector export infrastructure (`COMPLYTIME_EXPORT_ENABLED`, `collector:` config block, Export RPC). This was speculative infrastructure added before backend design was finalized. Export functionality will be redesigned and reintroduced when the backend shape is known. (#606)
Expand Down Expand Up @@ -127,42 +163,4 @@
when `@version` syntax is detected. `@version` support will be removed
in a future release. (#600)

### Changed

- All commands now accept `--workspace` flag to specify workspace directory
- `NewWorkspace()` function signature changed from `NewWorkspace()` to `NewWorkspace(baseDir string)`
- Log file and scan output paths are now relative to resolved workspace directory

### Fixed

- `complyctl scan --format` reports (SARIF, OSCAL, Markdown) now written
to `.complytime/scan/` alongside the evaluation log, matching
documented behavior. Previously, format reports were written to the
workspace root. (#615)
- Generation freshness detection now tracks complypack digests alongside
policy digests. Previously, updating a complypack without changing the
policy would skip regeneration, causing providers to use stale
artifacts (#583).
- OCI reference parsing now supports standard `:tag` syntax (e.g.,
`registry.com/org/image:v0.4.0`) in addition to the existing `@version`
notation for both policies and complypacks. Digest references
(`@sha256:...`) are also supported. Invalid OCI references in
`complytime.yaml` are now detected at config load time with clear
error messages. (#594)
- `complyctl doctor` now reports invalid policy references in
`CheckPolicyActivePeriod` and `CheckComplypacks` as explicit
failures instead of silently skipping them. `CheckVariables`
now surfaces per-policy resolution errors with specific messages
instead of a silent counter. (#600)
- Scan reports now resolve assessment plan IDs to requirement IDs,
ensuring output displays meaningful identifiers instead of internal
plan references. Affects EvaluationLog, OSCAL, SARIF, and Markdown
output formats.
- `complyctl get` now detects and rejects duplicate evaluator-ids across
complypack entries. Previously, multiple complypacks resolving to the
same evaluator-id caused non-deterministic digest selection during
scan, leading to unnecessary regeneration or stale artifacts (#647).
- `complyctl get` now re-fetches complypack artifacts when the cache
directory is missing, even if `state.json` records a matching digest.
Previously, a deleted cache directory caused the sync to be permanently
skipped until the user manually cleared state (#649).
26 changes: 13 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ A lightweight compliance runtime that pulls [Gemara](https://gemara.openssf.org/

## Architecture

```
```text
┌──────────────────────────────────────────────────────────────────┐
│ Host │
│ │
Expand Down Expand Up @@ -51,7 +51,7 @@ A lightweight compliance runtime that pulls [Gemara](https://gemara.openssf.org/
**Components:**

| Component | Description |
|:---|:---|
| :--- | :--- |
| **OCI Registry** | Remote store for Gemara policies. Supports two OCI manifest layouts: split-layer (distinct media types per artifact) and Gemara bundle format (single artifact media type with annotation-based differentiation). Both formats are auto-detected and resolved transparently. |
| **Workspace** | Resolved workspace directory containing `.complytime/complytime.yaml` (or legacy `complytime.yaml` at root). Configurable via `--workspace` flag or `COMPLYTIME_WORKSPACE` env var. Defines which registry, policies, and targets to use. Scan output lands in `.complytime/scan/`. |
| **Cache** | Local OCI Layout stores under `~/.complytime/policies/`. One store per policy ID. `state.json` tracks digests for incremental sync. |
Expand All @@ -69,7 +69,7 @@ A lightweight compliance runtime that pulls [Gemara](https://gemara.openssf.org/
## CLI Commands

| Command | Description |
|:---|:---|
| :--- | :--- |
| `init` | Create a workspace configuration file |
| `get` | Fetch new/modified policies from OCI registry and update cache |
| `list` | List cached Gemara policies |
Expand All @@ -79,7 +79,7 @@ A lightweight compliance runtime that pulls [Gemara](https://gemara.openssf.org/
| `providers` | List discovered scanning providers and their health status |
| `version` | Print version |

Global flags:
Global flags:
- `--debug` / `-d` — output debug logs
- `--workspace` / `-w` — workspace directory (project root containing `.complytime/`, defaults to current directory)

Expand Down Expand Up @@ -138,19 +138,19 @@ complyctl list
complyctl list --policy-id nist-800-53-r5
```

| Flag | Description |
|:---|:---|
| `--policy-id` | Filter output to a single policy |
| Flag | Description |
|---------------|-----------------------------------|
| `--policy-id` | Filter output to a single policy |

### `generate`

```bash
complyctl generate --policy-id nist-800-53-r5
```

| Flag | Short | Description |
|:---|:---|:---|
| `--policy-id` | `-p` | Policy ID to generate (required) |
| Flag | Short | Description |
|---------------|-------|-----------------------------------|
| `--policy-id` | `-p` | Policy ID to generate (required) |

Resolves the policy dependency graph from cache, extracts assessment configurations, applies parameter overrides from `complytime.yaml`, and dispatches to the matching provider via Generate RPC.

Expand All @@ -174,7 +174,7 @@ complyctl scan --policy-id nist-800-53-r5 --format sarif
```

| Argument / Flag | Short | Description |
|:---|:---|:---|
| :--- | :--- | :--- |
| `[target]` | | Optional target ID to scope the scan (from `complytime.yaml`) |
| `--policy-id` | `-p` | Policy ID to scan (required when no target is given, or target has multiple policies) |
| `--format` | `-f` | Output format: `oscal`, `pretty`, `sarif` |
Expand All @@ -187,7 +187,7 @@ Output written to `./.complytime/scan/`.
#### Exit codes

| Exit Code | Meaning |
|:---|:---|
| :--- | :--- |
| `0` | Scan completed -- all targets evaluated (findings, if any, are in the report) |
| non-zero | Operational error -- one or more targets could not be evaluated, or zero requirements assessed (partial results written before exit) |

Expand Down Expand Up @@ -232,7 +232,7 @@ targets:
```

| Field | Description |
|:---|:---|
| :--- | :--- |
| `policies[].url` | Full OCI reference (registry + repository + optional `:tag`) |
| `policies[].id` | Optional shortname; if omitted, derived from last path segment of URL |
| `variables` | Workspace-scoped constants passed to providers via Generate RPC |
Expand Down
2 changes: 1 addition & 1 deletion cmd/mock-oci-registry/testdata/RH-WORKSTATION-AUDIT.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Automates the Red Hat external audit requirement to provide evidence of:

### Layer 1: Guidance (`rh-workstation-audit-guidance.yaml`)
- **Framework**: CIS Controls v8
- **Controls**:
- **Controls**:
- Control 4: Secure Configuration of Enterprise Assets
- Control 7: Continuous Vulnerability Management

Expand Down
6 changes: 3 additions & 3 deletions docs/AI_TOOLING.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Any AI agent that supports command loading can use this repository's AI tooling:

Reviews a pull request for alignment, security, and compliance. Designed to be token-efficient and CI-aware.

```
```none
/review-pr 42
```

Expand Down Expand Up @@ -107,7 +107,7 @@ Skills provide domain knowledge the agent loads as context when activated. Unlik
## Key Files

| File | Purpose |
|------|---------|
| ------ | --------- |
| `.specify/memory/constitution.md` | Organizational governance and coding standards |
| `docs/AI_TOOLING.md` | This file — AI tooling documentation |
| `.agents/skills/` | Directory for AI skills — agent-agnostic, auto-discovered by OpenCode |
Expand All @@ -119,7 +119,7 @@ Skills provide domain knowledge the agent loads as context when activated. Unlik

Features are managed via spec-driven development. SpecKit and OpenSpec use separate output directories with coordinated sequential numbering:

```
```text
specs/ # SpecKit output
├── 001-first-feature/
│ └── spec.md
Expand Down
2 changes: 1 addition & 1 deletion docs/CODE_OF_CONDUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,6 @@ All project maintainers are obligated to respect the privacy and security of the

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.1, available at https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.1, available at <https://www.contributor-covenant.org/version/2/1/code_of_conduct.html>

[homepage]: https://www.contributor-covenant.org
4 changes: 2 additions & 2 deletions docs/QUICK_START.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ installed before `complyctl scan` can run.
### Available providers

| Provider | Binary | What it evaluates | Prerequisites |
|----------|--------|-------------------|---------------|
| ---------- | -------- | ------------------- | --------------- |
| [openscap](https://github.com/complytime/complytime-providers/blob/main/cmd/openscap-provider/docs/configuration.md) | `complyctl-provider-openscap` | SCAP policies (CIS, STIG, HIPAA, OSPP, etc.) | `openscap-scanner`, `scap-security-guide` |
| [ampel](https://github.com/complytime/complytime-providers/tree/main/cmd/ampel-provider) | `complyctl-provider-ampel` | GitHub / GitLab branch protection | `snappy`, `ampel`, `GITHUB_TOKEN` or `GITLAB_TOKEN` |
| [opa](https://github.com/complytime/complytime-providers/tree/main/cmd/opa-provider) | `complyctl-provider-opa` | OPA/Rego policies via conftest | `conftest`, `git` |
Expand Down Expand Up @@ -94,7 +94,7 @@ targets:
```

| Section | Purpose |
|---------|---------|
| --------- | --------- |
| `policies` | OCI references to Gemara policy bundles. `id` is a short alias used by targets and for provider routing. |
| `complypacks` | Optional OCI references to provider-specific content bundles (policies, data files, scripts). Fetched alongside policies during `complyctl get`. |
| `variables` | Workspace-scoped constants passed to all providers (e.g., custom policy directories). |
Expand Down
10 changes: 5 additions & 5 deletions docs/RELEASE_PROCESS.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ This workflow needs to be associated with a [Tag](https://github.com/complytime/
```bash
git remote -v
...
upstream https://github.com/complytime/complyctl.git (push)
upstream https://github.com/complytime/complyctl.git (push)
```

```bash
Expand Down Expand Up @@ -85,7 +85,7 @@ fkinit -u <your_fas_id>

#### Fork the repository

Create a fork from https://src.fedoraproject.org/rpms/complyctl
Create a fork from <https://src.fedoraproject.org/rpms/complyctl>

```bash
fedpkg clone --anonymous forks/<your fedora id>/rpms/complyctl
Expand Down Expand Up @@ -148,7 +148,7 @@ fedpkg switch-branch rawhide
fedpkg build
```
- Follow the builds status in the following links:
- [Builds Status](https://koji.fedoraproject.org/koji/packageinfo?packageID=42298)
- [Builds Status](https://koji.fedoraproject.org/koji/packageinfo?packageID=42298)

### Submit Fedora updates

Expand All @@ -164,8 +164,8 @@ The new updates enter in `testing` state and are moved to stable after 7 days, o
After moving to `stable` state, the update is signed and awaits to be pushed to the repositories by the Release Engineering Team.

Check the package update status in the following links:
- [Updates Status](https://bodhi.fedoraproject.org/updates/?packages=complyctl)
- [Package Overview](https://src.fedoraproject.org/rpms/complyctl)
- [Updates Status](https://bodhi.fedoraproject.org/updates/?packages=complyctl)
- [Package Overview](https://src.fedoraproject.org/rpms/complyctl)

#### Troubleshooting

Expand Down
6 changes: 3 additions & 3 deletions docs/TESTING_ENVIRONMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ export GITHUB_TOKEN=<your-token>
### Binaries

| Binary | Location |
|--------|----------|
| -------- | ---------- |
| `complyctl` | `./bin/` |
| `mock-oci-registry` | `./bin/` |
| `snappy` | `$GOPATH/bin` |
Expand Down Expand Up @@ -266,7 +266,7 @@ Place raw Gemara YAML files in a directory and mount it
into the devcontainer at `/bundles/` (or set
`COMPLYCTL_BUNDLES_DIR` to a custom path):

```
```text
/bundles/
└── my-private-policy/
├── catalog.yaml
Expand Down Expand Up @@ -360,7 +360,7 @@ namespace remaps your host UID to a different UID inside the
container. This can change file ownership on the host after
the workspace stops, causing git to refuse operations:

```
```text
fatal: detected dubious ownership in repository at '/path/to/complyctl'
```

Expand Down
Loading
Loading