{"id":30261593,"url":"https://github.com/stabla/syntegrity","last_synced_at":"2026-07-15T09:31:52.652Z","repository":{"id":304349665,"uuid":"1018449056","full_name":"stabla/syntegrity","owner":"stabla","description":"System \u0026 Integrity: Compute cryptographic hashes to follow your system structure integrity. 9.37 GB, 7039 files, in 0.09s.","archived":false,"fork":false,"pushed_at":"2026-03-04T07:33:40.000Z","size":30,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-10T08:29:10.711Z","etag":null,"topics":["integrity","itsec","itsecurity","security","system"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stabla.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-07-12T09:32:56.000Z","updated_at":"2026-03-04T07:34:57.000Z","dependencies_parsed_at":"2025-07-12T15:26:36.640Z","dependency_job_id":"357968ca-462f-46a8-987d-571047899a4c","html_url":"https://github.com/stabla/syntegrity","commit_stats":null,"previous_names":["stabla/syntegrity"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/stabla/syntegrity","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stabla%2Fsyntegrity","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stabla%2Fsyntegrity/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stabla%2Fsyntegrity/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stabla%2Fsyntegrity/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stabla","download_url":"https://codeload.github.com/stabla/syntegrity/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stabla%2Fsyntegrity/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35499864,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-15T02:00:06.706Z","response_time":131,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["integrity","itsec","itsecurity","security","system"],"created_at":"2025-08-15T20:08:33.079Z","updated_at":"2026-07-15T09:31:52.646Z","avatar_url":"https://github.com/stabla.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Syntegrity\n\nA fast file integrity checker written in Go. Computes cryptographic hashes for files and folders to detect content and structural changes. Uses a Merkle tree for folder hashing and concurrent goroutines for speed.\n\n## What it does\n\nSyntegrity scans directories recursively and computes:\n- Individual file hashes (SHA-256)\n- Folder content hashes (hash1) - Merkle tree of all children's hashes\n- Folder structure hashes (hash2) - based on immediate children names and sizes\n\nThis lets you detect both content changes and structural modifications in your file system.\n\n## Features\n\n- **Fast** - Concurrent hashing with goroutines, ~6x faster than equivalent Python\n- **Smart caching** - JSON-based cache with mtime+size validation, ~25x faster on repeat runs\n- **Dual hash system** - Separate hashes for content vs structure integrity\n- **Change detection** - Tracks file/folder additions, deletions, modifications between runs\n- **Single binary** - No runtime dependencies, just build and run\n\n### Benchmark\n\nTested on ~/Documents (9.37 GB, 7039 files, Apple Silicon M3):\n\n| Run | Time |\n| --- | --- |\n| Cold (no cache) | 2.73s |\n| Cached | 0.09s |\n\n## Quick start\n\n```bash\ngo build -o syntegrity .\n./syntegrity /path/to/directory\n```\n\nSupports multiple paths and individual files:\n\n```bash\n./syntegrity /etc/config /var/log /path/to/file.txt\n```\n\n## Usage\n\n```\nsyntegrity [options] \u003cpath\u003e [path...]\n```\n\n| Flag | Description |\n| --- | --- |\n| (none) | Silent mode, only shows change detection results |\n| `-v`, `--verbose` | Show file/folder hashes and hierarchical structure |\n| `--json` | Output change detection as JSON |\n| `-t`, `--time` | Show processing time |\n\n### Default output\n\n```\nMODIFIED_FILE: config.txt\nNEW_FILE: data.csv\nFOLDER_CONTENTS_CHANGED: .\n```\n\n### Verbose output (`-v`)\n\n```\nProcessing directory: /home/data\n--------------------------------------------------\nProcessing files:\n/home/data/file1: 32c66107...\n/home/data/file2: 85df9a7c...\nProcessed 2 files\n\nProcessing folders:\ndata:[content_hash];[structure_hash]\nsubfolder:[content_hash];[structure_hash]\nProcessed 2 folders\n\nHierarchical Structure:\n--------------------------------------------------\n[root_hash[file_hash/file_hash/subfolder_hash[child_hash]]]\n\nNo changes detected.\n```\n\n### JSON output (`--json`)\n\n```json\n[\n  {\"type\": \"MODIFIED_FILE\", \"path\": \"config.txt\"},\n  {\"type\": \"NEW_FILE\", \"path\": \"data.csv\"}\n]\n```\n\nFor folders, the format is: `foldername:[hash1];[hash2]`\n\n- **hash1** = content integrity (Merkle tree of all children)\n- **hash2** = structure integrity (immediate children names and sizes)\n\n## How it works\n\n### Hash1 (Content Hash)\nMerkle tree computed bottom-up: each folder's hash is the SHA-256 of its sorted children entries (`type:name:hash`). Any change in a descendant propagates up to the root.\n\n### Hash2 (Structure Hash)\nSHA-256 of immediate children names and sizes (for files) or names (for directories). Detects structural changes like renames, additions, or deletions without false positives from timestamp changes.\n\n### Change Detection\n\nSyntegrity saves state between runs and reports the following event types:\n\n| Event | Description |\n| --- | --- |\n| `DELETED_FILE` | A file that existed in the previous run is now gone |\n| `DELETED_FOLDER` | A folder that existed in the previous run is now gone |\n| `MODIFIED_FILE` | A file's content hash has changed |\n| `NEW_FOLDER` | A folder that didn't exist in the previous run |\n| `NEW_FILE` | A file that didn't exist in the previous run |\n| `FOLDER_CONTENTS_CHANGED` | A folder's content hash (hash1) changed, files inside were added, removed, or modified |\n| `FOLDER_STRUCTURE_CHANGED` | A folder's structure hash (hash2) changed, immediate children were added, removed, or resized |\n\n## Use cases\n\n- Detect unauthorized file modifications\n\n- Monitor system configuration changes\n- Verify backup integrity\n- Ensure build artifacts haven't changed\n\n## FAQ\n\n### Does caching prevent detecting file changes?\n\nNo. A cached hash is only used when the file's mtime and size are both unchanged. If a file is modified, its mtime updates, the cache entry is invalidated, and the hash is recomputed. This is the same trust model used by git, make, and rsync.\n\n### What if the content of a file changes?\n\nYes, it detects it. Every file is hashed with SHA-256. When a file's content changes, its hash changes, and Syntegrity reports it as `MODIFIED_FILE`. Because folder hashes are built as a Merkle tree from their children, a single file change also propagates up and every parent folder's content hash (hash1) will change too.\n\n### Why two hashes per folder?\n\nHash1 (content) tells you *what* is inside. If any file's content changes anywhere in the tree, hash1 changes. Hash2 (structure) tells you *how* it's organized. If files are added, removed, or renamed, hash2 changes. A file modified in place changes hash1 but not hash2. A file renamed changes hash2 but not hash1. This separation lets you distinguish between content tampering and structural reorganization.\n\n## Troubleshooting\n\n### Cache issues\n\nClear the cache to force full recomputation:\n```bash\nrm .syntegrity_cache.json\n```\n\n### Permission errors\n\nPermission errors are logged to stderr. The tool continues processing accessible files.\n\n## Technical details\n\n- **Hash algorithm**: SHA-256\n- **Folder hashing**: O(n) Merkle tree (bottom-up)\n- **Concurrency**: goroutine pool, up to `min(NumCPU, 16)` workers\n- **Cache**: `.syntegrity_cache.json` with mtime+size validation\n- **State**: `\u003cdir\u003e_state.json` for change detection between runs\n\n## Requirements\n\n- Go 1.21+\n- Standard library only (no external dependencies)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstabla%2Fsyntegrity","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstabla%2Fsyntegrity","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstabla%2Fsyntegrity/lists"}