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: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ Adapters are used by both `export` and `run`. Available adapters:
| `copilot` | GitHub Copilot instructions (export only) |
| `codex` | OpenAI Codex CLI instructions (export only) |
| `kiro` | Kiro agent format (export only) |
| `gitclaw` | GitClaw agent format |
| `gitagent` | Gitagent agent format |

```bash
# Export to system prompt
Expand Down
2 changes: 1 addition & 1 deletion docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,7 @@ opengap run [options]

Either `--repo` or `--dir` is required.

`--workspace` lets an agent definition live separately from the repository it operates on. It is honored by adapters that can safely set the spawned process working directory directly, including `claude`, `openai`, `crewai`, `openclaw`, and `nanobot`. Adapters that generate an isolated runtime workspace, such as `opencode`, `gemini`, and `gitclaw`, continue to run from that prepared workspace to avoid overwriting files such as `AGENTS.md`, `GEMINI.md`, or `agent.yaml` in the target repository.
`--workspace` lets an agent definition live separately from the repository it operates on. It is honored by adapters that can safely set the spawned process working directory directly, including `claude`, `openai`, `crewai`, `openclaw`, and `nanobot`. Adapters that generate an isolated runtime workspace, such as `opencode`, `gemini`, and `gitagent`, continue to run from that prepared workspace to avoid overwriting files such as `AGENTS.md`, `GEMINI.md`, or `agent.yaml` in the target repository.

**Available adapters:**

Expand Down
10 changes: 5 additions & 5 deletions paper/open-gap.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ OpenGAP Working Group

AI agents are being deployed into regulated, high-stakes environments faster than the tooling to govern them has matured. Today, an agent's *identity* lives in a Python class, its *policy* lives in a dashboard, its *memory* lives in a vector store, its *audit trail* lives nowhere in particular, and its *version* is whatever commit someone happens to deploy. This paper argues that the right unit of an agent is not a process, not a model, not a config file, and not a dashboard, but a **git repository** — and presents the **GitAgentProtocol (OpenGAP)**, an open standard that makes that abstraction concrete.

Under OpenGAP, an agent is fully described by files in a directory: identity (`SOUL.md`), hard constraints (`RULES.md`), segregation-of-duties (`DUTIES.md`), skills, tools, knowledge, memory, hooks, sub-agents, and regulatory-compliance artifacts. A single canonical definition deterministically exports to **15 execution environments** (Claude Code, OpenAI Agents SDK, CrewAI, Cursor, Gemini CLI, Codex, OpenCode, Kiro, Lyzr, OpenClaw, Nanobot, GitHub Copilot, GitHub Models, GitClaw, system-prompt) with a documented **fidelity profile** per target. **Fourteen lifecycle patterns** — which we show decompose into four meta-patterns: *structural guarantees*, *lifecycle operations*, *collaboration primitives*, and *runtime hooks* — emerge naturally from the git substrate. Compliance is a first-class spec element, mapped onto FINRA 3110/4511/2210, SEC Reg BI/Reg S-P/17a-4, Federal Reserve SR 11-7, and CFPB Circular 2022-03, and enforced through `pre_tool_use` hooks with `fail_open: false` semantics. We prove a simple **structural SOD theorem**: any segregation-of-duties conflict declared in `DUTIES.md` is unbypassable by the agent itself, provided branch-protection rules are active and the agent has no force-push rights.
Under OpenGAP, an agent is fully described by files in a directory: identity (`SOUL.md`), hard constraints (`RULES.md`), segregation-of-duties (`DUTIES.md`), skills, tools, knowledge, memory, hooks, sub-agents, and regulatory-compliance artifacts. A single canonical definition deterministically exports to **15 execution environments** (Claude Code, OpenAI Agents SDK, CrewAI, Cursor, Gemini CLI, Codex, OpenCode, Kiro, Lyzr, OpenClaw, Nanobot, GitHub Copilot, GitHub Models, Gitagent, system-prompt) with a documented **fidelity profile** per target. **Fourteen lifecycle patterns** — which we show decompose into four meta-patterns: *structural guarantees*, *lifecycle operations*, *collaboration primitives*, and *runtime hooks* — emerge naturally from the git substrate. Compliance is a first-class spec element, mapped onto FINRA 3110/4511/2210, SEC Reg BI/Reg S-P/17a-4, Federal Reserve SR 11-7, and CFPB Circular 2022-03, and enforced through `pre_tool_use` hooks with `fail_open: false` semantics. We prove a simple **structural SOD theorem**: any segregation-of-duties conflict declared in `DUTIES.md` is unbypassable by the agent itself, provided branch-protection rules are active and the agent has no force-push rights.

Spec v0.4 adds three concrete extensions to this surface: portable `mcp_servers` declarations that export to each runtime's native MCP configuration, a `financial_governance` block with spending caps and approval thresholds for payment-capable agents, and an accepted RFC for an optional Ed25519 cryptographic-identity layer.

Expand Down Expand Up @@ -313,7 +313,7 @@ Fifteen targets currently ship:
| `nanobot` | ✓ | ✓ | Nanobot CLI | Nanobot config |
| `copilot` | ✓ | – | GitHub Copilot | `.github/copilot-*` |
| `github` | ✓ | ✓ | GitHub Models | GitHub Actions workflow |
| `gitclaw` | ✓ | ✓ | GitClaw | GitClaw workspace |
| `gitagent` | ✓ | ✓ | Gitagent | Gitagent workspace |
| `system-prompt` | ✓ | – | any LLM | Concatenated text |

### 5.4 Fidelity profile
Expand Down Expand Up @@ -663,7 +663,7 @@ As of May 2026, the reference repository `open-gitagent/opengap` has:
- **Three spec features shipped from community RFCs/PRs** in v0.4: portable `mcp_servers`, the `financial_governance` block, and the accepted cryptographic-identity RFC
- **Provenance-signed** releases on npm as `@open-gitagent/opengap` v0.4.0 (the unscoped root `opengap` is blocked by npm's package-similarity policy, so the scoped name is canonical)
- **CI on Node 18 / 20 / 22** building and validating the bundled example agents on every push
- **Cross-community pollination**: GAP agents appear in registries that predate it (the Lyzr registry) and in new registries that postdate it (GitClaw, the OpenClaw ecosystem)
- **Cross-community pollination**: GAP agents appear in registries that predate it (the Lyzr registry) and in new registries that postdate it (Gitagent, the OpenClaw ecosystem)

External adapter and spec contributions are the strongest signal that the protocol is perceived as a **neutral substrate**, not a vendor product. No single contributor has standing to force a breaking change in favor of their framework.

Expand Down Expand Up @@ -841,7 +841,7 @@ The OpenGAP working group thanks contributors to the reference implementation an
| `nanobot` | F | F | P | F | F | P | P | ⊥ | ⊥ |
| `copilot` | F | F | P | P | P | ⊥ | ⊥ | ⊥ | ⊥ |
| `github` | F | F | P | P | F | ⊥ | ⊥ | ⊥ | P |
| `gitclaw` | F | F | F | F | F | F | F | F | F |
| `gitagent` | F | F | F | F | F | F | F | F | F |
| `system-prompt` | F | F | P | P | ⊥ | ⊥ | ⊥ | ⊥ | ⊥ |

**Legend:** **F** = fully preserved · **P** = partially preserved (text present, semantics dropped) · **⊥** = not representable in the target format. Columns correspond to $I$=identity, $R$=rules, $D$=duties, $S$=skills, $T$=tools, $H$=hooks, $Me$=memory, $A$=sub-agents, $C$=compliance.
Expand Down Expand Up @@ -887,7 +887,7 @@ A CLI or library is **GAP-conformant at level $k$** iff:
- **Level 2 (export):** for at least one target $t$, it produces an output artifact whose fidelity profile matches the specification's published profile for $t$.
- **Level 3 (run):** for at least one target $t$, it launches the target runtime in a way that honors $(R, D, H)$ when those elements are present.

The reference implementation `opengap` is Level 3-conformant on Claude Code, OpenCode, Gemini, CrewAI, OpenAI, Lyzr, OpenClaw, Nanobot, GitHub, and GitClaw.
The reference implementation `opengap` is Level 3-conformant on Claude Code, OpenCode, Gemini, CrewAI, OpenAI, Lyzr, OpenClaw, Nanobot, GitHub, and Gitagent.

---

Expand Down
8 changes: 4 additions & 4 deletions paper/open-gap.tex
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
From this single source of truth, the reference CLI (\texttt{opengap}) deterministically
exports the same agent into fifteen different execution environments, including Claude
Code, OpenAI Agents SDK, CrewAI, Cursor, Gemini CLI, Codex, OpenCode, Kiro, Lyzr,
OpenClaw, Nanobot, GitHub Copilot, GitHub Models, GitClaw, and a plain system-prompt
OpenClaw, Nanobot, GitHub Copilot, GitHub Models, Gitagent, and a plain system-prompt
target. We describe the repository-as-agent abstraction, the adapter model underlying
this portability, fourteen architectural patterns that emerge when agents are defined
git-natively (human-in-the-loop learning, agent versioning, branch-based deployment,
Expand Down Expand Up @@ -414,7 +414,7 @@ \subsection{Adapter inventory}
\texttt{nanobot} & \checkmark & \checkmark & Nanobot CLI & Nanobot config \\
\texttt{copilot} & \checkmark & - & GitHub Copilot & \texttt{.github/copilot-*} \\
\texttt{github} & \checkmark & \checkmark & GitHub Models & GitHub Actions workflow \\
\texttt{gitclaw} & \checkmark & \checkmark & GitClaw & GitClaw workspace \\
\texttt{gitagent} & \checkmark & \checkmark & Gitagent & Gitagent workspace \\
\texttt{system-prompt} & \checkmark & - & any LLM & Concatenated text \\
\bottomrule
\end{tabular}
Expand Down Expand Up @@ -457,7 +457,7 @@ \subsection{Fidelity profile}
\end{tabular}
\caption{Abbreviated fidelity profile. \textbf{F} = fully preserved, \textbf{P} =
partially (text only, semantics dropped), \textbf{-} = not representable. Rows for
\texttt{copilot}, \texttt{github}, \texttt{gitclaw} omitted for space; see
\texttt{copilot}, \texttt{github}, \texttt{gitagent} omitted for space; see
Appendix~\ref{app:fidelity}.}
\label{tab:fidelity}
\end{table}
Expand Down Expand Up @@ -1044,7 +1044,7 @@ \section{Full Fidelity Matrix}\label{app:fidelity}
\texttt{nanobot} & F & F & P & F & F & P & P & - & - \\
\texttt{copilot} & F & F & P & P & P & - & - & - & - \\
\texttt{github} & F & F & P & P & F & - & - & - & P \\
\texttt{gitclaw} & F & F & F & F & F & F & F & F & F \\
\texttt{gitagent} & F & F & F & F & F & F & F & F & F \\
\texttt{system-prompt} & F & F & P & P & - & - & - & - & - \\
\bottomrule
\end{tabular}
Expand Down
2 changes: 1 addition & 1 deletion paper/tables/fidelity-matrix.csv
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ openclaw,F,F,P,F,F,P,F,F,F
nanobot,F,F,P,F,F,P,P,-,-
copilot,F,F,P,P,P,-,-,-,-
github,F,F,P,P,F,-,-,-,P
gitclaw,F,F,F,F,F,F,F,F,F
gitagent,F,F,F,F,F,F,F,F,F
system-prompt,F,F,P,P,-,-,-,-,-
26 changes: 13 additions & 13 deletions src/adapters/gitclaw.ts → src/adapters/gitagent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { loadAgentManifest, loadFileIfExists } from '../utils/loader.js';
import { loadAllSkills } from '../utils/skill-loader.js';

/**
* Export a gitagent to gitclaw format.
* Export a gitagent to gitagent format.
*
* Gitclaw uses the same git-native directory structure but with differences:
* Gitagent uses the same git-native directory structure but with differences:
* - agent.yaml model format: "provider:model-id" (colon, not slash)
* - knowledge/index.yaml uses "entries" (not "documents")
* - tools are a flat string array of built-in names in agent.yaml
Expand All @@ -16,7 +16,7 @@ import { loadAllSkills } from '../utils/skill-loader.js';
* Most files (SOUL.md, RULES.md, DUTIES.md, skills/, hooks/) pass through
* unchanged. The adapter transforms agent.yaml and knowledge/index.yaml.
*/
export interface GitclawExport {
export interface GitagentExport {
agentYaml: string;
soulMd: string | null;
rulesMd: string | null;
Expand All @@ -27,7 +27,7 @@ export interface GitclawExport {
hooks: string | null;
}

export function exportToGitclaw(dir: string): GitclawExport {
export function exportToGitagent(dir: string): GitagentExport {
const agentDir = resolve(dir);
const manifest = loadAgentManifest(agentDir);

Expand All @@ -43,8 +43,8 @@ export function exportToGitclaw(dir: string): GitclawExport {
return { agentYaml, soulMd, rulesMd, dutiesMd, knowledgeIndex, skills, tools, hooks };
}

export function exportToGitclawString(dir: string): string {
const exp = exportToGitclaw(dir);
export function exportToGitagentString(dir: string): string {
const exp = exportToGitagent(dir);
const parts: string[] = [];

parts.push('# === agent.yaml ===');
Expand Down Expand Up @@ -102,14 +102,14 @@ function buildAgentYaml(
if (manifest.author) gc.author = manifest.author;
if (manifest.license) gc.license = manifest.license;

// Model: convert to gitclaw "provider:model-id" format
// Model: convert to gitagent "provider:model-id" format
if (manifest.model) {
const model: Record<string, unknown> = {};
if (manifest.model.preferred) {
model.preferred = toGitclawModel(manifest.model.preferred);
model.preferred = toGitagentModel(manifest.model.preferred);
}
if (manifest.model.fallback) {
model.fallback = manifest.model.fallback.map(toGitclawModel);
model.fallback = manifest.model.fallback.map(toGitagentModel);
}
if (manifest.model.constraints) {
model.constraints = manifest.model.constraints;
Expand Down Expand Up @@ -152,11 +152,11 @@ function buildAgentYaml(
}

/**
* Convert gitagent model name to gitclaw "provider:model-id" format.
* Convert gitagent model name to gitagent "provider:model-id" format.
* gitagent: "claude-sonnet-4-5" or "anthropic/claude-sonnet-4-5"
* gitclaw: "anthropic:claude-sonnet-4-5"
* gitagent: "anthropic:claude-sonnet-4-5"
*/
function toGitclawModel(model: string): string {
function toGitagentModel(model: string): string {
// Already in provider:model format
if (model.includes(':') && !model.includes('://')) return model;

Expand Down Expand Up @@ -191,7 +191,7 @@ function collectToolNames(agentDir: string): string[] {
}

/**
* Convert gitagent knowledge/index.yaml (documents) to gitclaw format (entries).
* Convert gitagent knowledge/index.yaml (documents) to gitagent format (entries).
*/
function buildKnowledgeIndex(agentDir: string): string | null {
const indexPath = join(agentDir, 'knowledge', 'index.yaml');
Expand Down
2 changes: 1 addition & 1 deletion src/adapters/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ export { exportToCursorString, exportToCursor } from './cursor.js';
export { exportToGeminiString, exportToGemini } from './gemini.js';
export { exportToCodexString, exportToCodex } from './codex.js';
export { exportToKiroString, exportToKiro } from './kiro.js';
export { exportToGitclawString, exportToGitclaw } from './gitclaw.js';
export { exportToGitagentString, exportToGitagent } from './gitagent.js';
10 changes: 5 additions & 5 deletions src/commands/export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
exportToGeminiString,
exportToCodexString,
exportToKiroString,
exportToGitclawString,
exportToGitagentString,
} from '../adapters/index.js';
import { exportToLyzrString } from '../adapters/lyzr.js';
import { exportToGitHubString } from '../adapters/github.js';
Expand All @@ -27,7 +27,7 @@ interface ExportOptions {

export const exportCommand = new Command('export')
.description('Export agent to other formats')
.requiredOption('-f, --format <format>', 'Export format (system-prompt, claude-code, openai, crewai, openclaw, nanobot, lyzr, github, copilot, opencode, cursor, gemini, codex, kiro, gitclaw)')
.requiredOption('-f, --format <format>', 'Export format (system-prompt, claude-code, openai, crewai, openclaw, nanobot, lyzr, github, copilot, opencode, cursor, gemini, codex, kiro, gitagent)')
.option('-d, --dir <dir>', 'Agent directory', '.')
.option('-o, --output <output>', 'Output file path')
.action(async (options: ExportOptions) => {
Expand Down Expand Up @@ -82,12 +82,12 @@ export const exportCommand = new Command('export')
case 'kiro':
result = exportToKiroString(dir);
break;
case 'gitclaw':
result = exportToGitclawString(dir);
case 'gitagent':
result = exportToGitagentString(dir);
break;
default:
error(`Unknown format: ${options.format}`);
info('Supported formats: system-prompt, claude-code, openai, crewai, openclaw, nanobot, lyzr, github, copilot, opencode, cursor, gemini, codex, kiro, gitclaw');
info('Supported formats: system-prompt, claude-code, openai, crewai, openclaw, nanobot, lyzr, github, copilot, opencode, cursor, gemini, codex, kiro, gitagent');
process.exit(1);
}

Expand Down
10 changes: 5 additions & 5 deletions src/commands/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { runWithGitHub } from '../runners/github.js';
import { runWithGit } from '../runners/git.js';
import { runWithOpenCode } from '../runners/opencode.js';
import { runWithGemini } from '../runners/gemini.js';
import { runWithGitclaw } from '../runners/gitclaw.js';
import { runWithGitagent } from '../runners/gitagent.js';

interface RunOptions {
repo?: string;
Expand All @@ -30,7 +30,7 @@ interface RunOptions {
export const runCommand = new Command('run')
.description('Run an agent from a git repository or local directory')
.option('-r, --repo <url>', 'Git repository URL')
.option('-a, --adapter <name>', 'Adapter: claude, openai, crewai, openclaw, nanobot, lyzr, github, opencode, gemini, gitclaw, git, prompt', 'claude')
.option('-a, --adapter <name>', 'Adapter: claude, openai, crewai, openclaw, nanobot, lyzr, github, opencode, gemini, gitagent, git, prompt', 'claude')
.option('-b, --branch <branch>', 'Git branch/tag to clone', 'main')
.option('--refresh', 'Force re-clone (pull latest)', false)
.option('--no-cache', 'Clone to temp dir, delete on exit')
Expand Down Expand Up @@ -126,8 +126,8 @@ export const runCommand = new Command('run')
case 'gemini':
runWithGemini(agentDir, manifest, { prompt: options.prompt, workspace: options.workspace });
break;
case 'gitclaw':
runWithGitclaw(agentDir, manifest, { prompt: options.prompt, workspace: options.workspace });
case 'gitagent':
runWithGitagent(agentDir, manifest, { prompt: options.prompt, workspace: options.workspace });
break;
case 'git':
if (!options.repo) {
Expand All @@ -148,7 +148,7 @@ export const runCommand = new Command('run')
break;
default:
error(`Unknown adapter: ${options.adapter}`);
info('Supported adapters: claude, openai, crewai, openclaw, nanobot, lyzr, github, opencode, gemini, gitclaw, git, prompt');
info('Supported adapters: claude, openai, crewai, openclaw, nanobot, lyzr, github, opencode, gemini, gitagent, git, prompt');
process.exit(1);
}
} catch (e) {
Expand Down
Loading