RootDown is a platform-agnostic file organization standard with a Python deployer and auditor. It defines a canonical folder structure, reads it from a JSON manifest, and creates it on any machine — Windows, macOS, or Linux/WSL — with a single command. A profile system allows per-machine and per-user overrides without modifying the standard itself.
The canonical data root is C:\Data on Windows and ~/Data on macOS and Linux. All organized material lives under this root.
| Folder | Purpose |
|---|---|
00_INBOX |
Landing zone for unsorted or newly captured material awaiting review and placement |
10_PROJECTS |
Active and completed project work, organized using the standard project template |
20_OPERATIONS |
Reusable business, administrative, and operational materials that are not project-specific |
25_PERSONAL |
Personal records, household administration, and structured personal information |
30_MEDIA |
Photos, videos, audio, graphics, and other media-first assets |
40_REFERENCE |
Manuals, guides, knowledge resources, and non-active reference content |
50_SYSTEM |
Scripts, exports, drivers, installers, configuration files, and system support material |
90_ARCHIVE |
Inactive or historical material retained for recordkeeping and long-term storage |
The full standard including subfolders, lifecycle policies, and naming conventions is defined in standard/organization-standard.json.
Windows:
git clone https://github.com/jniplig/rootdown.git
cd rootdown
.\install.ps1macOS / Linux / WSL:
git clone https://github.com/jniplig/rootdown.git
cd rootdown
./install.shWith a profile:
.\install.ps1 --profile profiles/profile-personal.json./install.sh --profile profiles/profile-personal.jsonLive deploy (writes to disk):
.\install.ps1 --no-dry-run./install.sh --no-dry-runA profile is a JSON file that customizes a deployment without changing the standard. Use a profile to:
- Override the data root path for a specific machine
- Add folders that are not in the universal standard (e.g.
09_Personal_Projectsunder25_PERSONAL) - Adjust lifecycle policies per folder
Start from the template:
cp profiles/profile-template.json profiles/profile-mymachine.jsonEdit profile_name, machine, owner, and any overrides, then pass it to the deployer:
python deploy.py --profile profiles/profile-mymachine.jsonaudit.py checks an existing deployment against the standard and reports drift. It never modifies anything on disk.
# Summary to console
python audit.py
# Verbose — print every finding
python audit.py --verbose
# Write a CSV report
python audit.py --report audit.csv
# Audit with a specific profile
python audit.py --profile profiles/profile-personal.json --report audit.csvFindings are classified as:
| Classification | Meaning |
|---|---|
OK |
Folder exists and is accounted for in the standard or profile |
MISSING |
A required standard folder does not exist on disk |
UNKNOWN |
A folder exists on disk but is not in the standard or profile |
INBOX_AGE |
A file in 00_INBOX exceeds the lifecycle review age |
migrate.py moves existing files and folders from an unorganized source root into the RootDown standard. It runs in three explicit stages: scan, triage, and apply. Nothing is moved until --apply is explicitly passed — the scan and triage stages are entirely read-only, and the apply stage uses a copy-first strategy that verifies each copy before deleting the source.
python migrate.py --report migrate.csvThe scanner reads every item at the top level of the source root (default: home directory), classifies each as HIGH_RISK, CAUTION, or SAFE, and suggests a destination folder. Results are written to triage-log.json and optionally to a CSV for review.
python migrate.py --profile profiles/profile-personal.jsonEach item is presented for a decision: (m)ove, (s)kip, (p)rotect, or (d)efer. Items are grouped by risk tier and presented in order:
| Tier | Meaning |
|---|---|
HIGH_RISK |
Matches a protected path pattern (AppData, .git, .venv, etc.) — reviewed individually, never batched |
CAUTION |
No strong risk or safety signal — reviewed individually or in same-parent batches |
SAFE |
Clear user content (photo, document, audio) — reviewed as destination-grouped batches |
Triage sessions persist between runs. Quitting mid-session saves all decisions so far; the next run resumes where it left off and re-presents only undecided and deferred items. defer means "ask me again next session"; skip means "leave it where it is permanently".
python migrate.py --applyThe apply pass reads triage-log.json and processes every item with decision: "move". Before anything moves, it prints a summary and requires you to type CONFIRM:
Type CONFIRM to proceed, or anything else to abort:
>
Each item is copied first (shutil.copy2 for files, copytree for directories), verified, and only then deleted from the source. If a filename already exists at the destination, the copy is written as name_1.ext, name_2.ext, and so on — the original is never overwritten. Every outcome is logged back to triage-log.json (apply_status: moved | failed | delete_failed), which serves as a permanent audit trail. Use --report apply.csv to export results.
HIGH_RISKitems are always reviewed individually — they are never included in a batch decision.- Every
(p)rotectdecision appends the item's path pattern toprotected-paths.json, so it is automatically guarded in all future scans. - A copy is fully verified before the source is deleted. If verification fails, the partial copy is removed and the source is left untouched.
- Failed copies are recorded in
triage-log.jsonwithapply_status: failed. The source file is never deleted on a failed or unverified copy.
RootDown/
├── deploy.py # Deployer — creates folder structure on any platform
├── audit.py # Auditor — drift detection and reporting
├── standard/
│ └── organization-standard.json # Canonical folder manifest (source of truth)
├── profiles/
│ ├── profile-template.json # Blank starting point for new profiles
│ └── profile-personal.json # Single-user profile with personal project folder
├── lib/
│ └── common.py # Shared utilities (load_json, resolve_data_root)
├── docs/ # Extended documentation and migration records
└── legacy/ # Original machine-specific scripts (reference only)
- Safe by default. The deployer runs in dry-run mode unless
--no-dry-runis explicitly passed. The auditor never writes, moves, or deletes anything. - Manifest-driven. The folder standard lives in a single JSON file. The deployer and auditor read from it — there is no logic that hardcodes folder names.
- Platform-agnostic. Platform detection is automatic. The data root resolves to
C:\Dataon Windows and~/Dataelsewhere, or to whatever the profile specifies. - Profile-scoped customization. Machine-specific or user-specific variations belong in profiles, not in the standard. The standard stays universal.
- Non-destructive. The deployer skips folders that already exist. The auditor reports findings without taking action. No existing content is ever modified.