# BirthBiologic — 2026-06-26 migration corruption: recovery + corrected re-migration plan

Status: PLAN (approved direction 2026-06-29 by Mike — corrected re-migration from intact Datto
source; Datto 06-24 accepted as Master Donor source). Execution gated per phase.

## Summary of the incident

The 2026-06-26 Datto -> SharePoint push corrupted a large set of files. Root cause is fully
diagnosed: the upload path wrote each file's **byte array as space-separated DECIMAL TEXT**
instead of raw binary (a `"$bytes"` stringification bug in the base64/stdout-capture upload
workaround used during the 06-26 session). Proof:

- Corrupt `.xlsx` begin `80 75 3 4 20 0 6 0 ...` = decimal of `0x50 0x4B 0x03 0x04 0x14 0x00 0x06 0x00`
  (the real `PK..` OOXML signature).
- Corrupt `.pdf` begin `37 80 68 70 ...` = decimal of `0x25 0x50 0x44 0x46` (`%PDF`).

Because it operated on raw bytes, the bug is **format-agnostic** — `.xlsx`, `.docx`, and `.pdf`
were all hit, and corrupt files are inflated ~3-4x (each byte became 2-4 ASCII chars + space).

### Blast radius (as of 2026-06-29, read-only probe on ACG-DWP-X-BB)

- **15 of 16** locally-cached files modified 2026-06-26 in `C:\Users\Administrator\OneDrive -
  Birth Biologic, LLC\` are corrupt. Includes HR PII (`K Steen Confidential Disclosure
  Agreement.pdf`, Handbook Acknowledgement, Safety & Health Policy), Finance, Quality Designee
  docs, the **Master Donor Spreadsheet**, and **Inventory 2025/2026**.
- **~3,298** additional files modified 2026-06-26 are OneDrive **cloud-only** (dehydrated) and
  were skipped to avoid mass-hydration. They are almost certainly corrupted the same way — i.e.
  the true scope is likely the **entire 06-26 push** (hundreds-to-thousands of files).

### Data-loss assessment: NONE expected

- The **Datto Workplace source copies are intact** (`C:\Users\Public\Desktop\Datto Workplace
  Server Projects\`), confirmed clean `PK` headers on the affected spreadsheets.
- Even a corrupt file **with no source** is **losslessly recoverable** — it literally contains
  the original bytes as decimal numbers; split on whitespace -> `[byte]` -> `WriteAllBytes`.

## Authoritative source & path mapping

- **Source of truth:** `C:\Users\Public\Desktop\Datto Workplace Server Projects\` (ACG-DWP-X-BB).
- **Target libraries:** `C:\Users\Administrator\OneDrive - Birth Biologic, LLC\<Library> - Documents\`
  (OneDrive-synced SharePoint libraries on the same host).
- **Mapping rule:** dest `"<Folder> - Documents\..."`  <->  source `"<Folder>\..."`
  (strip the ` - Documents` suffix). Confirmed pairs: Admin, Donor Services, Supply Management
  (verify Quality Department + any other library before execution).

## Why this method (corrected re-migration, not file repair)

The corruption is systemic to the 06-26 batch, so file-by-file repair is the wrong altitude.
The clean fix exploits that **both trees live on the same machine** with OneDrive sync available:
copy intact source files into the OneDrive library folders and let **OneDrive sync them up** —
native, integrity-checked, no custom byte handling, no Graph chunked-upload, no RMM timeout.
(SPMT is the bulk alternative; the buggy custom-script upload path is retired for this work.)

## Plan

### Phase 0 — Freeze & notify (do first)
- Tell client/Annise: **do not open/edit/trust** files in the migrated SharePoint libraries
  dated 2026-06-26 — they are corrupt and will be replaced.
- Pause OneDrive editing on ACG-DWP-X-BB for those libraries during the re-push to avoid sync
  conflicts (409s).

### Phase 1 — RESULTS (completed 2026-06-29, read-only)

Method: local metadata enumeration on ACG-DWP-X-BB (size vs Datto source) + header reads;
Graph (Tenant Admin app, BirthBio tenant `19a568e8-...`) for SharePoint-side spot checks.

- **3,371** files modified 2026-06-26 across the OneDrive libraries.
- **84 CONFIRMED CORRUPT** (decimal-text header, not a valid signature):
  - By library: **Donor Services 67**, Admin 12, Supply Management 3, Quality Department 2.
  - By type: 59 `.pdf`, 20 `.docx`, 5 `.xlsx`.
  - Recovery routes: **83 RESTORE-FROM-SOURCE** (clean Datto source confirmed) + **1
    DECODE-OR-FIND-SOURCE** (`Donor Services\Suitability\3c. Cord For Life - Donor Suitability
    Datto Copy.docx` — no mapped source; decode the decimal-bytes or locate its source).
- **~3,197 clean** (3,168 size-matched to source + 29 header-verified).
- **89 DEFERRED** — cloud-only OneDrive files at `>=260`-char (MAX_PATH) paths, **no Datto
  source mapping** (Quality 59, Admin 30). Unassessable by header: Graph driveItem-by-path 404s
  them and local `[IO.File]::Open` fails MAX_PATH even with `\\?\` + .NET long-path switches.
  Must be checked/handled with a **long-path-native tool (robocopy / SPMT)** in execution.
  Lower corruption risk (no Datto source = not part of the Datto->SP byte-push) but NOT cleared.

Artifacts (committed):
- `2026-06-26-corruption-manifest.csv` — full 3,371-row inventory (verdict, sizes, source state).
- `2026-06-26-remediation-list.csv` — the 84 corrupt files + recovery route (Phase 3 input).

### Phase 1 — Full-scope inventory (READ-ONLY) [method, for reference]
- Enumerate **all** files (any type) modified 2026-06-26 across every OneDrive library on
  ACG-DWP-X-BB; classify corrupt (header != type signature / decimal-text) vs clean.
- Handle cloud-only files: either controlled batch-hydrate + header-check, or check via Graph
  (Tenant Admin app, `Sites.ReadWrite.All`) against the SharePoint side.
- Output: authoritative **corrupt-file manifest** with, per file: dest path, mapped source path,
  source-validity (clean header? exists?), and recovery route.

### Phase 2 — Pre-flight validation
- For each corrupt file confirm a **clean source** exists in the Datto tree (verify header).
- Partition into: **A** restore-from-source · **B** decimal-decode-recover (no clean source) ·
  **C** no recovery available (investigate; expected empty).

### Phase 3 — Corrected re-push (GATED — explicit go required)
- **List A:** copy source -> OneDrive library path (overwrite corrupt copy); let OneDrive sync.
  Work in batches; after each batch verify dest header flips to a valid signature.
- **List B:** decode decimal-text -> binary, write, verify header.
- Master Donor Spreadsheet: use Datto **2026-06-24 13:32** source (2,292,743 B) per Mike's call.

### Phase 4 — Verification & reconciliation
- Re-scan libraries: confirm **0 corrupt** remaining in the 06-26 set.
- Spot-open Master Donor, an Inventory, and a sample PDF to confirm they actually open.
- Reconcile file counts/sizes source vs dest. Update `wiki/clients/birth-biologic.md` + CONTEXT.

### Phase 5 — Root-cause closure
- Retire the custom-script byte-capture upload path for this client. If any custom upload
  remains, write binary with `[IO.File]::WriteAllBytes` — never stringify a byte array.
- Confirms logged in `errorlog.md` (migration/datto-to-sharepoint, 2026-06-29).

## Open items before execution
- Decide cloud-only handling for Phase 1 (batch-hydrate vs Graph) — Graph avoids 3,300 downloads.
- Confirm full library list + mapping (esp. Quality Department).
- Confirm no genuine 06-24->06-26 edits exist only in corrupt copies for files other than Master
  Donor (those would use the decimal-decode route to preserve latest content).
