atlas-portfolio :: OneDrive for Business backup playbook¶
Set up: 2026-05-25 by Atlas at Sush's request. Why this exists: Sush asked "do we have a backup for this repo in OneDrive for Business that is my corp OneDrive — if not after completing the whole polish work can you please add a backup of this repo to OneDrive for business pls to my Microsoft OneDrive and document everything in learn-doc."
TL;DR¶
| Source | C:\ssClawy\atlas-portfolio\ |
| Destination (corp OneDrive) | C:\Users\ssutheesh\OneDrive - Microsoft\_AtlasPortfolio-backup\ |
| Size | ~28 MB (data/, dist/, src/, scripts/, styles/, docs/, top-level files) |
| Excluded | node_modules/, .git/, .copilot/, *.log |
| Mode | Robocopy /MIR (mirror — deletes at dest what's gone at source) |
| Schedule | Sundays 06:30 NZST (30 min before AtlasPortfolioFullRefresh at 07:00) |
| Task name | \Atlas\AtlasPortfolioOneDriveBackup |
| Script | C:\ssClawy\atlas-portfolio\scripts\backup-to-onedrive.ps1 |
| Manual run | pwsh C:\ssClawy\atlas-portfolio\scripts\backup-to-onedrive.ps1 |
| Dry run | pwsh C:\ssClawy\atlas-portfolio\scripts\backup-to-onedrive.ps1 -DryRun |
Why corp OneDrive (not personal OneDrive, not GitHub alone)¶
| Backup tier | Status | Reason |
|---|---|---|
GitHub (ssutheesh_microsoft/atlas-portfolio) |
✅ Active | All source code, BUILD-LOG, scripts. DOES NOT include data/ or dist/ — gitignored per Standing Rule #4 (MS Confidential data stays on local disk). |
Corp OneDrive (OneDrive - Microsoft) |
✅ Active (this playbook) | Full working dir INCLUDING data/ (snapshot-customers-*.json, lynx-snapshots/, etc.) and dist/index.html + per-account HTML. This is the only backup of the MICROSOFT CONFIDENTIAL data layer. |
~~Personal OneDrive (OneDrive / "personal Microsoft account")~~ |
⚠️ Pre-existing — needs cleanup | A backup exists at C:\Users\ssutheesh\OneDrive\CopilotCLI_Backups\ssclawy-mirror\atlas-portfolio\. This is the wrong location for MS Confidential data per Standing Rule #4. Recommend Sush deletes it OR moves it to the corp OneDrive location. See "Cleanup TODO" below. |
What's in the backup¶
_AtlasPortfolio-backup/
├── BUILD-LOG.md (~230 KB · phase-by-phase history)
├── README.md (~7 KB)
├── .gitignore (~0.5 KB)
├── package.json + package-lock.json
├── data/ (~12 MB · MICROSOFT CONFIDENTIAL)
│ ├── snapshot-customers-YYYY-MM-DD.json (MSX customer snapshots)
│ ├── lynx-snapshots/ (per-tenant Lynx scrapes)
│ ├── atlas-insights-cache.json (LLM-generated commentary cache)
│ └── ...
├── dist/ (~14 MB · rendered HTML, contains real customer data)
│ ├── index.html (main dashboard)
│ └── account/<tpid>.html (54 per-customer pages)
├── src/ (~0.4 MB · source JS modules)
├── styles/ (~0.1 MB · CSS)
├── scripts/ (~0.3 MB · build / refresh / smoke / probes)
├── docs/ (~0.07 MB · misc project docs)
└── reference/ (~0.3 MB · PAC mockups for design reference)
What's NOT in the backup (and why)¶
| Excluded | Reason |
|---|---|
node_modules/ (~15 MB) |
Reproducible from package.json via npm install. |
.git/ |
The git repo IS the source-code backup (lives on GitHub). |
.copilot/ |
Session/local state, not project content. |
*.log |
Transient. |
How to verify the backup is working¶
- Check OneDrive sync status — taskbar tray icon should show "Up to date" (cloud icon).
- Inspect the dest folder directly:
- Check the scheduled task's last run:
Get-ScheduledTaskInfo -TaskName "AtlasPortfolioOneDriveBackup" -TaskPath "\Atlas\" | Select-Object LastRunTime, LastTaskResult, NextRunTimeLastTaskResult: 0= success. - Check the script log:
- Verify on OneDrive web — sign in to
office.com→ OneDrive →_AtlasPortfolio-backupfolder should be browsable.
How to restore from the backup¶
If the local working directory at C:\ssClawy\atlas-portfolio\ is lost or corrupted:
# 1. Clone source code from GitHub (excluding data/dist which are gitignored):
gh repo clone ssutheesh_microsoft/atlas-portfolio C:\ssClawy\atlas-portfolio
# 2. Restore data/, dist/, and other non-tracked files from OneDrive backup:
robocopy "C:\Users\ssutheesh\OneDrive - Microsoft\_AtlasPortfolio-backup" `
"C:\ssClawy\atlas-portfolio" `
/E /XD .git /R:1 /W:1
# 3. Re-install npm deps:
cd C:\ssClawy\atlas-portfolio
npm install
# 4. Verify:
node scripts\build.mjs
node scripts\refresh-qa.mjs # must be 25/25 green
Standing rule honoured (Microsoft Confidential data)¶
Per atlas-portfolio Standing Rule #4 (BUILD-LOG): "Microsoft Confidential data stays on local disk. data/ and dist/*.html are gitignored."
The corp OneDrive for Business is an acceptable storage location for MS Confidential data — it's tenant-managed, ACL-controlled to Sush only, complies with Microsoft data-residency policy. Personal OneDrive is NOT — it's a consumer service outside the corp tenant.
Cleanup TODO (Sush to action)¶
A pre-existing backup was found in PERSONAL OneDrive:
This contains MICROSOFT CONFIDENTIAL data in the wrong location. Recommendation: delete it. The corp OneDrive backup (this playbook) supersedes it.
# Inspect first:
Get-ChildItem "C:\Users\ssutheesh\OneDrive\CopilotCLI_Backups\ssclawy-mirror\atlas-portfolio" | Select-Object Name, Length
# When ready to delete:
Remove-Item -Recurse -Force "C:\Users\ssutheesh\OneDrive\CopilotCLI_Backups\ssclawy-mirror\atlas-portfolio"
# AND: remove the whole ssclawy-mirror tree if it ONLY contains atlas-portfolio
Implementation details for future Atlas¶
- Why robocopy and not Copy-Item? Robocopy handles long paths, retries, multi-thread, and produces a clean exit-code contract (0=no change, 1=copied, 2=extras-mirrored, ≥8=failure). Copy-Item would either fail or silently skip on long-path edge cases.
- Why
/MIR(mirror)? Re-runs delete anything at dest that's gone from source. This means snapshots from deleted lynx scrapes etc. don't accumulate forever in the backup. If Sush wants point-in-time snapshots, that's a different mechanism (would do dated folders like_AtlasPortfolio-snapshots\2026-05-25\). - Why Sunday 06:30 not 07:00? The existing
AtlasPortfolioFullRefreshtask fires Sunday 07:00 NZST. Running the backup 30 min before snapshots the state BEFORE the refresh starts. This way: - If the refresh fails, the backup still has the previous-week good state.
- If the refresh succeeds, the next week's backup at 06:30 will pick up the fresh data.
- Why exclude
node_modules? Reproducible frompackage.json. Saves ~15 MB per run and OneDrive sync cycles. - Why no
*.logexcluded but the script writes a log to$env:TEMP? Logs are in%TEMP%, outside the repo — already excluded. - OneDrive auto-sync — the corp OneDrive client uploads changes to the cloud automatically. No need for a separate "push to cloud" step. The robocopy is the local-disk→OneDrive-folder step; OneDrive handles cloud sync.
Audit trail¶
| Date | Event |
|---|---|
| 2026-05-25 | Initial backup created. ~28 MB / 247 files mirrored. Scheduled task registered (\Atlas\AtlasPortfolioOneDriveBackup, Sun 06:30 NZST). Script at scripts/backup-to-onedrive.ps1. Standing-rule cleanup TODO logged for personal-OneDrive duplicate. |
Read this whenever: - atlas-portfolio backup behaviour changes (schedule, source, dest) - Cleaning up the personal-OneDrive duplicate (see Cleanup TODO above) - Restoring atlas-portfolio after a local-disk failure (see "How to restore" above) - Auditing what's in the backup vs what should be (e.g., during a quarterly memory audit)