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
311 changes: 159 additions & 152 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,66 +1,13 @@
# Groundkeeper
# groundkeeper

Groundkeeper is a deterministic, YAML-driven repository maintenance agent that runs primarily in GitHub Actions. It is designed to be safe, reviewable, and boring: every output is structured, validated, and generated under strict budgets and scope rules.
A deterministic, YAML-driven repository maintenance agent that runs as a GitHub Action. Safe, reviewable, and boring: every change is structured, validated, and generated under strict budgets and scope rules.

## Philosophy & Safety
## Quick Start (GitHub Action)

- **YAML is the source of truth** — `.github/agent.yml` defines scope, budgets, and runtime settings.
- **Report-only by default** — publishing is opt-in and gated by config.
- **Deterministic stages** — fixed stages with schema-validated I/O.
- **No hidden automation** — no auto-merge, no background services.
- **Scoped execution** — out-of-scope changes are rejected before LLM calls.

## Features

- **Schema-validated configuration** via `packages/schemas/agent.schema.json`
- **Strict stage boundaries**: Preflight → Analysis → Plan → Patch → Verify → Publish
- **Prompt templates** per stage in `prompts/`
- **CLI + GitHub Action** wrapper for consistent automation

## Repository Layout

- `packages/cli` — CLI entrypoint and command handling
- `packages/core` — stage runner, config validation, scope, and budgets
- `packages/runtimes` — LLM runtime adapters (OpenAI, Copilot)
- `packages/schemas` — agent config schema and stage I/O schemas
- `prompts/` — stage prompt templates (analysis, plan, patch, verify, publish)

## Installation

### As a CLI tool

```bash
npm install -g groundkeeper
```

### As a GitHub Action

Add to your workflow file (e.g., `.github/workflows/groundkeeper.yml`):

```yaml
name: Repository Maintenance
on:
schedule:
- cron: '0 0 * * 0' # Weekly on Sunday
workflow_dispatch:

jobs:
maintenance:
runs-on: ubuntu-latest
steps:
- name: Run Groundkeeper
uses: efremidze/groundkeeper@v1
with:
config: .github/agent.yml
github-token: ${{ secrets.GITHUB_TOKEN }}
```

## Quick Start

1. **Create `.github/agent.yml`**:
1. **Create `.github/agent.yml`** in your repository:

```yaml
$schema: ../packages/schemas/agent.schema.json
$schema: https://raw.githubusercontent.com/efremidze/groundkeeper/main/packages/schemas/agent.schema.json
Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

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

The schema URL points to the main branch on GitHub. This will only work if this schema file has already been pushed to the main branch. Users who copy this example before the changes are merged might encounter a 404 error. Consider using a relative path like ../packages/schemas/agent.schema.json or adding a note that this URL only works after the schema is published.

Copilot uses AI. Check for mistakes.
version: '1.0'
mode: report-only

Expand All @@ -72,6 +19,7 @@ scope:
exclude:
- node_modules/**
- dist/**
- .git/**

budgets:
maxFiles: 100
Expand All @@ -92,150 +40,209 @@ publish:
enabled: false
```

2. **Run Groundkeeper**:
2. **Create `.github/workflows/groundkeeper.yml`**:

```bash
groundkeeper run --config .github/agent.yml
```

## Usage

### CLI Commands

#### `groundkeeper run`

Run the deterministic stage pipeline:
```yaml
name: Repository Maintenance

```bash
groundkeeper run [options]
on:
schedule:
- cron: '0 0 * * 0' # Weekly on Sunday
workflow_dispatch:

Options:
-c, --config <path> Path to configuration file (default: ".github/agent.yml")
-d, --directory <path> Working directory (default: current directory)
jobs:
groundkeeper:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
issues: write

steps:
- uses: actions/checkout@v4

- name: Run Groundkeeper
uses: efremidze/groundkeeper@v1
with:
config: .github/agent.yml
github-token: ${{ secrets.GITHUB_TOKEN }}
Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

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

The github-token input is optional and defaults to github.token in the action definition. This line could be omitted from the example since the default will work correctly. Alternatively, consider using the newer ${{ github.token }} syntax instead of ${{ secrets.GITHUB_TOKEN }} for consistency with modern GitHub Actions practices.

Suggested change
github-token: ${{ secrets.GITHUB_TOKEN }}

Copilot uses AI. Check for mistakes.
```

3. **Done!** Groundkeeper will run on schedule or when manually triggered. Reports are saved to `.groundkeeper/report.md`.

## Configuration

The configuration file is validated against `packages/schemas/agent.schema.json`. Groundkeeper reads `.github/agent.yml` as the source of truth by default.
The `.github/agent.yml` file defines how Groundkeeper analyzes your repository.

### Schema
### Configuration Schema

```yaml
version: string # Configuration version (required)
mode: report-only # Safety mode
version: '1.0' # Configuration version

scope: # Allowed repo paths
include: [string]
exclude: [string]
mode: report-only # Safety mode (always report-only in v1)

budgets: # Hard limits before LLM calls
maxFiles: number
maxDiffLines: number
maxTokens: number
scope:
include: [string] # Paths to analyze (glob patterns)
exclude: [string] # Paths to skip

rules: # Allowed/denied rule categories
allow: [string]
deny: [string]
budgets:
maxFiles: number # Max files to analyze
maxDiffLines: number # Max diff lines in patches
maxTokens: number # Max LLM tokens per stage

runtime: # LLM runtime selection
provider: openai | copilot
rules:
allow: [string] # Allowed change types
deny: [string] # Denied change types

publish: # Publishing behavior (opt-in)
enabled: boolean
target: pr | issue
```
runtime:
provider: openai | copilot # LLM provider

## Stages
publish:
enabled: boolean # Create PR/issue with findings (opt-in)
target: pr | issue # Publish target
```

Groundkeeper executes fixed stages with schema-validated inputs/outputs:
### Stages

1. **Preflight** — deterministic repo metadata and validation (no LLM)
2. **Analysis** — read-only analysis (LLM)
3. **Plan** — plan only (LLM)
4. **Patch** — diff-only output (LLM)
5. **Verify** — runner executes checks; LLM interprets results
6. **Publish** — report content for PR/issue (LLM), published by CLI if enabled
Groundkeeper executes a deterministic pipeline:

## Core Principles
| Stage | Description | LLM |
|-------|-------------|-----|
| **Preflight** | Validate repo and scope | No |
| **Analysis** | Identify maintenance items | Yes |
| **Plan** | Create action plan | Yes |
| **Patch** | Generate diffs (report-only) | Yes |
| **Verify** | Run checks and validate | Yes |
| **Publish** | Generate PR/issue content | Yes |

### YAML is the Spec
## Safety & Design

All behavior is defined in `.github/agent.yml`. This makes the agent's behavior explicit and version-controlled.
- **YAML is the spec** — `.github/agent.yml` defines all behavior
- **Report-only by default** — no changes without explicit `publish.enabled: true`
- **Deterministic output** — same config + repo = same results
- **Hard budgets** — scoped execution before LLM calls
- **Structured validation** — all LLM outputs validated against schemas
- **No auto-merge** — all PRs require manual review

### Read-only by Default
## CLI Usage (Local Testing)

Groundkeeper will not publish changes unless `publish.enabled` is explicitly set to `true`.
For local development or testing:

### Deterministic Output
```bash
# Install locally
npm install -g groundkeeper

Given the same repository state and configuration, Groundkeeper produces the same structured outputs.
# Run against your repository
groundkeeper run --config .github/agent.yml

### No Direct Commits
# Check the report
cat .groundkeeper/report.md
```

Groundkeeper does not commit changes directly. Publishing is handled by the CLI and Action with explicit configuration.
### CLI Commands

### No Auto-merge
```bash
groundkeeper run [options]

Even when publishing, Groundkeeper never auto-merges.
Options:
-c, --config <path> Path to agent.yml (default: .github/agent.yml)
-d, --directory <path> Working directory (default: current directory)
```

## Examples

### Generate a maintenance report
### Minimal Configuration (Report Only)

```bash
groundkeeper run --config .github/agent.yml
cat .groundkeeper/report.md
```yaml
version: '1.0'
mode: report-only

scope:
include: ['**']
exclude: ['node_modules/**', 'dist/**']

budgets:
maxFiles: 50
maxDiffLines: 500
maxTokens: 5000

runtime:
provider: openai

publish:
enabled: false
```
Comment on lines +156 to 174
Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

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

The "Minimal Configuration (Report Only)" example is missing the runtime field, which is needed for the tool to function properly. Without specifying a runtime provider (openai or copilot), all LLM stages will be skipped and the tool won't perform any analysis. Consider adding the runtime field to make this a functional minimal example.

Copilot uses AI. Check for mistakes.

### Run in CI/CD
### Advanced Configuration

```yaml
# .github/workflows/groundkeeper.yml
name: Weekly Maintenance
on:
schedule:
- cron: '0 0 * * 0'
version: '1.0'
mode: report-only

jobs:
groundkeeper:
runs-on: ubuntu-latest
steps:
- uses: efremidze/groundkeeper@v1
with:
config: .github/agent.yml
```
scope:
include:
- src/**
- tests/**
- docs/**
- README.md
- package.json
exclude:
- node_modules/**
- dist/**
- coverage/**
- .git/**

## Development
budgets:
maxFiles: 100
maxDiffLines: 1000
maxTokens: 15000

### Setup
rules:
allow:
- documentation
- formatting
- tests
deny:
- breaking-changes
- dependency-upgrades

```bash
git clone https://github.com/efremidze/Groundkeeper.git
cd Groundkeeper
npm install
runtime:
provider: openai
# Optional: copilot for GitHub Copilot SDK
Copy link

Copilot AI Jan 24, 2026

Choose a reason for hiding this comment

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

The comment "# Optional: copilot for GitHub Copilot SDK" could be misleading. The provider field itself is what determines whether to use OpenAI or Copilot. Consider clarifying this comment to say something like "# Change to 'copilot' to use GitHub Copilot SDK" or remove the comment entirely since the valid values are already documented in the Configuration Schema section.

Suggested change
# Optional: copilot for GitHub Copilot SDK
# Change to 'copilot' to use GitHub Copilot SDK

Copilot uses AI. Check for mistakes.

publish:
enabled: false # Set to true to enable PR creation
target: pr # or 'issue'
```

### Build
## Inputs & Outputs

```bash
npm run build
```
### GitHub Action Inputs

### Run locally
| Input | Description | Required | Default |
|-------|-------------|----------|---------|
| `config` | Path to `.github/agent.yml` | No | `.github/agent.yml` |
| `github-token` | GitHub API token | No | `${{ github.token }}` |
| `working-directory` | Working directory for the action | No | `.` |

```bash
npm start
```
### Outputs

### Test
| Output | Description |
|--------|-------------|
| `report-path` | Path to generated report (e.g., `.groundkeeper/report.md`) |

```bash
npm test
```
### Generated Files

After running, Groundkeeper creates:

- `.groundkeeper/report.md` — Human-readable analysis report
- `.groundkeeper/analysis.json` — Structured analysis results
- `.groundkeeper/plan.json` — Proposed changes plan
- `.groundkeeper/patch.json` — Generated patches (report-only mode)

## Contributing
## For Contributors & Maintainers

Contributions are welcome! Please feel free to submit a Pull Request.
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, architecture overview, and internal design principles.

## License

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading