---
name: content-hash
description: OS-aware content hashing for files and workspace fingerprints using built-in system tools only.
---

# Content Hash

Use this skill when an agent needs deterministic hashes for files or a workspace fingerprint without external dependencies.

## Protocol

Use only tools that are present by default on the target OS.
Do not require Python, Node.js, or external packages.
Prefer `md5`-compatible output across all platforms.

## Detect OS

Select the command family by OS:

1. Linux: `md5sum`
2. macOS: `md5`
3. Windows: PowerShell `Get-FileHash -Algorithm MD5`

If the agent already knows the OS from runtime context, use it directly.

## File Hash

### Linux

```sh
md5sum "docs/ARCHITECTURE.md" | awk '{print $1}'
```

### macOS

```sh
md5 -q "docs/ARCHITECTURE.md"
```

### Windows PowerShell

```powershell
(Get-FileHash -Algorithm MD5 'docs/ARCHITECTURE.md').Hash.ToLower()
```

## Workspace Fingerprint

To compute a workspace fingerprint, hash a deterministic manifest of relevant files.
Sort paths before hashing.
Include both relative path and file content digest in the manifest.

### Linux

```sh
{
    for path in $(printf '%s\n' docs/ARCHITECTURE.md docs/CODE_STYLE.md docs/FINDINGS.md | sort); do
        if [ -f "$path" ]; then
            printf '%s:' "$path"
            md5sum "$path" | awk '{print $1}'
        fi
    done
} | md5sum | awk '{print $1}'
```

### macOS

```sh
{
    for path in $(printf '%s\n' docs/ARCHITECTURE.md docs/CODE_STYLE.md docs/FINDINGS.md | sort); do
        if [ -f "$path" ]; then
            printf '%s:' "$path"
            md5 -q "$path"
            printf '\n'
        fi
    done
} | md5 -q
```

### Windows PowerShell

```powershell
$paths = @('docs/ARCHITECTURE.md', 'docs/CODE_STYLE.md', 'docs/FINDINGS.md') | Sort-Object
$manifest = foreach ($path in $paths) {
    if (Test-Path $path) {
        $hash = (Get-FileHash -Algorithm MD5 $path).Hash.ToLower()
        "${path}:$hash"
    }
}
$bytes = [System.Text.Encoding]::UTF8.GetBytes(($manifest -join "`n"))
$stream = [System.IO.MemoryStream]::new(,$bytes)
try {
    (Get-FileHash -Algorithm MD5 -InputStream $stream).Hash.ToLower()
} finally {
    $stream.Dispose()
}
```

## Output Normalization

Normalize all emitted hashes to lowercase hexadecimal.
Do not include filenames, labels, or surrounding prose in the stored hash fields.

## Error Handling

If the OS-native hashing command is unavailable on the current platform:

1. report that hash evidence could not be computed
2. set the relevant trust state to `unknown`
3. write a concrete reason naming the missing hashing command

If a file is missing, do not fabricate a hash.
Only hash files that actually exist.