File Integrity Checking
This document explains how agconf detects and prevents unauthorized modifications to managed files.
Overview
agconf manages certain files in your repository:
- AGENTS.md (global block) - Company-wide engineering standards (
<!-- agconf:global:start/end -->) - AGENTS.md (rules section, Codex targets) - Concatenated rules (
<!-- agconf:rules:start/end -->) - Skill files (
.claude/skills/*/SKILL.md) - Synced skill definitions - Rule files (
.claude/rules/**/*.md) - Modular project instructions (Claude only) - Agent files (
.claude/agents/*.md) - Claude Code sub-agents (Claude only)
These files should not be manually edited because changes will be overwritten on the next sync. agconf provides multiple layers of protection:
- Content hashing - Detects modifications by comparing hashes
- Pre-commit hook - Prevents committing modified files locally
- CI workflow - Catches modifications in pull requests
How Detection Works
Content Hashing
Each managed file stores a content hash that allows agconf to detect modifications:
For skill files (.claude/skills/*/SKILL.md):
- Hash is stored in YAML frontmatter as
agconf_content_hash - Hash is computed from content excluding agconf metadata
- Example:
agconf_content_hash: "sha256:abc123def456"
For rule files (.claude/rules/**/*.md) and agent files (.claude/agents/*.md):
- Hash is stored in YAML frontmatter as
agconf_content_hash - Hash is computed from content excluding agconf metadata
- Example:
agconf_content_hash: "sha256:abc123def456"
For AGENTS.md (global block):
- Hash is stored in an HTML comment within the global block
- Hash is computed from the global block content excluding metadata comments
- Example:
<!-- Content hash: sha256:abc123def456 -->
For AGENTS.md (rules section, Codex targets):
- Hash is stored in an HTML comment within the rules section markers
- Hash is computed from the concatenated rules content
- Example:
<!-- Content hash: sha256:abc123def456 -->
Detection Logic
When checking for modifications:
- Read the stored hash from the file
- Compute the current hash of the content
- Compare: if hashes differ, the file has been modified
The check Command
The agconf check command verifies all managed files:
# Show detailed results
agconf check
# Exit code only (for scripts/CI)
agconf check --quiet
# Show hash computation details (for debugging)
agconf check --debug
Output Format
When modifications are detected:
agconf check
Checking managed files...
✗ 2 managed file(s) have been modified:
AGENTS.md (global block)
Expected hash: sha256:abc123def456
Current hash: sha256:789xyz012345
.claude/skills/git-conventions/SKILL.md
Expected hash: sha256:111222333444
Current hash: sha256:555666777888
These files are managed by agconf and should not be modified manually.
Run 'agconf sync' to restore them to the expected state.
When all files are unchanged:
agconf check
Checking managed files...
✓ All managed files are unchanged
Exit Codes
| Code | Meaning |
|---|---|
0 | All managed files unchanged (or repo not synced) |
1 | One or more managed files modified |
Pre-commit Hook
The CLI automatically installs a git pre-commit hook at .git/hooks/pre-commit.
How It Works
- Hook runs before each commit
- Checks if repository has been synced (lockfile exists)
- Checks if
agconfCLI is available - Runs
agconf check --quiet - Blocks commit if modifications detected
When Hook Blocks a Commit
Error: Cannot commit changes to agconf-managed files
To see details, run: agconf check
Options:
1. Discard your changes: git checkout -- <file>
2. Skip this check: git commit --no-verify
3. Restore managed files: agconf sync
4. For AGENTS.md: edit only the repo-specific block (between repo:start and repo:end)
5. For skills: create a new custom skill instead
Bypassing the Hook
In rare cases where you need to commit despite the warning:
git commit --no-verify -m "Your message"
Note: This should only be used when you understand why the files differ and have a valid reason (e.g., you’re updating the agconf repository itself).
Hook Installation
The hook is installed automatically during agconf init or agconf sync. If you need to reinstall:
# Re-run sync to reinstall the hook
agconf sync
The CLI will not overwrite existing custom pre-commit hooks. If you have a custom hook, you’ll need to integrate the agconf check manually.
CI Workflow Integration
The check-reusable.yml workflow runs agconf check in CI to catch modifications in pull requests.
Usage in Downstream Repos
The CLI automatically creates this workflow file when you run agconf init or agconf sync. The workflow references reusable workflows in your content repository:
# .github/workflows/agconf-check.yml (auto-generated)
name: agconf Check
on:
pull_request:
paths:
- 'AGENTS.md'
- '.claude/**'
- '.codex/**'
jobs:
check:
# Points to YOUR content repository, not a hardcoded default
uses: your-org/your-content-repo/.github/workflows/check-reusable.yml@v1.0.0
Note: The repository path and version are automatically set based on the source you specified during agconf init --source <owner/repo>.
Workflow Outputs
| Output | Description |
|---|---|
has_modifications | true if any files modified, false otherwise |
check_output | Full output from agconf check |
Resolving Modifications
When you discover modified managed files:
Option 1: Discard Changes
If you accidentally edited a managed file:
# Discard changes to specific file
git checkout -- AGENTS.md
git checkout -- .claude/skills/skill-name/SKILL.md
# Or restore all managed files
agconf sync
Option 2: Re-sync
If files are out of sync for any reason:
agconf sync
This will restore all managed files to their expected state.
Option 3: Customize Properly
If you need custom content:
For AGENTS.md:
- Edit only the repo-specific block (between
<!-- agconf:repo:start -->and<!-- agconf:repo:end -->) - The global block should never be edited manually
For skills, rules, or agents:
- Create a new custom file in the appropriate directory with a different name
- Custom files (without
agconf_managed: "true"in frontmatter) are not checked
Troubleshooting
“Not synced” Message
If agconf check shows “Not synced”:
- The repository hasn’t been initialized with agconf
- Run
agconf initto set up
False Positives
If files are flagged as modified but you haven’t changed them:
- Line ending differences (CRLF vs LF) can cause hash mismatches
- Run
agconf syncto normalize the files
Hook Not Running
If the pre-commit hook doesn’t run:
- Check if
.git/hooks/pre-commitexists and is executable - Check if
agconfCLI is in your PATH - Run
agconf syncto reinstall the hook