# Team-Shared Graph Artifact Format in codebase-memory-mcp: JSON Schema and Git Merge Handling

> Learn about the team shared graph artifact format in codebase-memory-mcp, a JSON schema, and how Git merge conflicts are handled with a custom merge driver for efficient team collaboration.

- Repository: [Martin Vogel/codebase-memory-mcp](https://github.com/DeusData/codebase-memory-mcp)
- Tags: deep-dive
- Published: 2026-07-20

---

**The DeusData/codebase-memory-mcp project stores team-shared code graphs in [`.codebase-memory/artifact.json`](https://github.com/DeusData/codebase-memory-mcp/blob/main/.codebase-memory/artifact.json), a JSON file containing nodes, edges, and commit metadata, and resolves Git merge conflicts using a custom merge driver that performs union-style merging with last-write-wins semantics for duplicate IDs.**

The `codebase-memory-mcp` repository from DeusData implements a structured **team-shared graph artifact format** that enables concurrent development on repository code graphs. This artifact persists graph data to a hidden directory in the repository, allowing teams to share structural code intelligence through version control while automatically handling merge conflicts.

## Understanding the Team-Shared Graph Artifact Format

The graph artifact is a JSON file located at [`repo/.codebase-memory/artifact.json`](https://github.com/DeusData/codebase-memory-mcp/blob/main/repo/.codebase-memory/artifact.json) that follows a strict schema defined in [`pipeline/artifact.h`](https://github.com/DeusData/codebase-memory-mcp/blob/main/pipeline/artifact.h) and implemented in [`pipeline/artifact.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/pipeline/artifact.c).

### Schema Structure and Location

The artifact resides in a hidden directory at the repository root. According to the source implementation, the JSON structure contains the following top-level fields:

- `schema_version`: Numeric identifier for artifact schema compatibility
- `commit`: Git SHA-1 hash of the commit that generated the artifact
- `nodes`: Array of node objects representing source files, functions, and classes
- `edges`: Array of edge objects defining relationships between nodes
- `metadata`: Free-form map for generation timestamps and tool versions

### Core Fields and Data Types

Each node object carries a stable **ID**, **type**, **name**, and optional **metadata**:

```json
{
  "id": "n1",
  "type": "function",
  "name": "main",
  "metadata": {
    "language": "c",
    "line": 12
  }
}

```

Edges link nodes via **source ID**, **target ID**, and **edge type**:

```json
{
  "source": "n1",
  "target": "n2",
  "type": "calls"
}

```

The export routine ensures atomic writes by using a write-then-rename pattern, guaranteeing that [`artifact.json`](https://github.com/DeusData/codebase-memory-mcp/blob/main/artifact.json) is either fully present or absent, never partially written.

## Generating and Consuming Artifacts

The C API provides explicit functions for artifact serialization and deserialization, implemented in [`pipeline/artifact.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/pipeline/artifact.c).

### Exporting with cbm_artifact_export()

The `cbm_artifact_export()` function generates the JSON artifact from an in-memory graph database. Before invoking external Git commands, the implementation validates that the repository path is shell-safe via `cbm_artifact_repo_path_is_shell_safe()` to prevent command injection attacks.

```c
int rc = cbm_artifact_export(g_db, repo_path, "my-project", CBM_ARTIFACT_BEST);
if (rc != 0) {
    fprintf(stderr, "Failed to export artifact: %s\n", cbm_artifact_export_last_error());
}

```

The function writes to a temporary file before atomically renaming it to [`.codebase-memory/artifact.json`](https://github.com/DeusData/codebase-memory-mcp/blob/main/.codebase-memory/artifact.json).

### Importing with cbm_artifact_import()

Consumption of shared artifacts occurs through `cbm_artifact_import()`, which validates the JSON schema version against the current implementation before loading data. Mismatched schema versions trigger an error, preventing corruption from outdated artifact formats.

```c
int rc = cbm_artifact_import(repo_path, import_db);
if (rc != 0) {
    fprintf(stderr, "Import failed: %s\n", cbm_artifact_import_last_error());
}

```

## Git Merge Conflict Handling Strategy

Because multiple developers may modify the artifact simultaneously, the repository implements a custom Git merge driver that automates conflict resolution.

### Gitattributes Configuration

The export routine automatically generates a `.gitattributes` entry in the repository:

```text
.codebase-memory/artifact.json merge=codebase_memory_artifact

```

This entry, verified in [`tests/test_artifact.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/tests/test_artifact.c) under the test case `artifact_gitattributes_created`, routes merge operations for the artifact file to the custom driver.

### Custom Merge Driver Implementation

The merge driver `codebase-memory-mcp-artifact-merge` receives Git's standard merge driver arguments: `%A` (ours), `%O` (base), `%B` (theirs), and `%L` (conflict label). The driver installation is handled by [`scripts/setup.sh`](https://github.com/DeusData/codebase-memory-mcp/blob/main/scripts/setup.sh), which configures Git to use the executable for artifact merges.

```text
[merge "codebase_memory_artifact"]
    name = codebase-memory-mcp artifact merge driver
    driver = /usr/local/bin/codebase-memory-mcp-artifact-merge %A %O %B %L

```

### Union-Based Resolution Logic

The merge driver parses both JSON versions and applies union-style merging to the `nodes` and `edges` arrays. When duplicate IDs exist, the driver applies **last-write-wins** resolution based on commit timestamp metadata, ensuring deterministic outcomes.

The simplified driver logic uses `jq` to concatenate disjoint collections:

```bash
#!/usr/bin/env bash
OUR=$1; BASE=$2; THEIR=$3; LABEL=$4

tmp=$(mktemp)
jq -s 'reduce .[] as $item ({}; .nodes += $item.nodes // []; .edges += $item.edges // [])' \
    "$OUR" "$THEIR" > "$tmp" || exit 1

mv "$tmp" "$OUR"
exit 0

```

If schema versions differ between merge inputs, the driver exits with a non-zero status, aborting the merge and forcing manual re-export via `cbm_artifact_export()`.

## Safety Mechanisms and Validation

The artifact system implements multiple safeguards to ensure data integrity:

- **Schema Validation**: `cbm_artifact_import()` rejects artifacts with incompatible `schema_version` values
- **Shell Safety**: Path validation prevents injection attacks before Git command execution
- **Atomic Writes**: The export routine uses temporary files and atomic renames to eliminate partial write corruption
- **Conflict Detection**: The merge driver aborts on structural incompatibilities rather than risking data loss

## Summary

- The **team-shared graph artifact format** uses JSON stored at [`.codebase-memory/artifact.json`](https://github.com/DeusData/codebase-memory-mcp/blob/main/.codebase-memory/artifact.json) with fields for `schema_version`, `commit`, `nodes`, `edges`, and `metadata`
- **Export and import operations** are handled by `cbm_artifact_export()` and `cbm_artifact_import()` in [`pipeline/artifact.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/pipeline/artifact.c), with atomic file operations and shell-safe path validation
- **Git merge conflicts** resolve automatically via the `codebase_memory_artifact` merge driver, which performs union merging of nodes and edges with last-write-wins semantics for duplicate IDs
- **Schema mismatches** trigger merge failures, requiring developers to re-export fresh artifacts using the current schema version

## Frequently Asked Questions

### What happens if two developers modify the same node in the artifact.json file?

When the merge driver detects overlapping node IDs, it applies **last-write-wins** resolution using the commit timestamp metadata embedded in each artifact version. The node from the more recent commit prevails, while the older version is discarded. If the schema versions differ, the merge aborts entirely and requires manual re-export.

### Where is the artifact schema version defined and validated?

The `schema_version` constant is defined in [`pipeline/artifact.h`](https://github.com/DeusData/codebase-memory-mcp/blob/main/pipeline/artifact.h) and validated during import by `cbm_artifact_import()` in [`pipeline/artifact.c`](https://github.com/DeusData/codebase-memory-mcp/blob/main/pipeline/artifact.c). The import function rejects any artifact where the schema version does not match the current implementation, preventing data corruption from outdated formats.

### How does the tool prevent security vulnerabilities when executing Git commands?

Before invoking any external Git processes, the code calls `cbm_artifact_repo_path_is_shell_safe()` to validate that the repository path contains no shell metacharacters. This prevents command injection attacks when the export routine interacts with the Git CLI to generate the `commit` field or `.gitattributes` entries.

### Can I manually edit the artifact.json file, or should I always use the export function?

While manual editing is possible, the repository expects specific formatting and metadata consistency. Always use `cbm_artifact_export()` to regenerate the file, as this ensures atomic writes, proper schema versioning, and valid commit hashes. Manual edits risk triggering schema validation errors on import or merge conflicts that the automated driver cannot resolve.