# Dataforth Test-Data Chain — Ground-Truth Audit (AD2)

**Auditor:** Autonomous read-only agent (Claude), launched via RMM
**Host:** AD2 / `192.168.0.6` — Windows Server 2019 Standard 10.0.17763 (booted 2026-06-18)
**Audit window:** 2026-07-01 ~16:32–16:55 UTC
**Mode:** STRICTLY READ-ONLY. No file was created, modified, moved, renamed, or deleted except this deliverable (`C:\Users\sysadmin\ad2-audit\FINDINGS.md`). No git/service/task/DB writes were performed. The Postgres DB was queried inside `BEGIN TRANSACTION READ ONLY`; the NAS was accessed via read-only `rsync --list-only` and `ssh` only.

> **Reading guide.** The supplied briefing was explicitly ~3 months stale ("treat as hints only"). Several premises are now wrong on the ground (SQLite → PostgreSQL; drive letters; which sync script runs; which scripts are deployed vs abandoned). Each such correction is called out. Every material claim cites live evidence (file + size + mtime, log line, DB count, or NAS listing) so other models can re-verify.

---

## 1. Executive summary

The **outbound** test-results pipeline (DOS stations → NAS → AD2 → database → web delivery) is **operational and current** — data landed in the database as recently as **2026-07-01 13:41 UTC** (same day as this audit). The **inbound** spec/software-distribution pipeline is **partially broken**: the master specification `.DAT` files are **not** distributed to the DOS stations, which is a precise, reproducible root cause for Syncro #32489. A single stray file (`TS-21\ProdSW`) makes the 15-minute sync report `ERRORS` on **every** run, masking real failures. The primary datastore has been migrated from SQLite to **PostgreSQL 18** and the web-delivery mechanism from the broken ASP.NET/`For_Web` path to an **HTTP API uploader**; neither change is reflected in the briefing.

### Severity-ranked findings

| # | Sev | Finding | Status |
|---|-----|---------|--------|
| F1 | **HIGH** | NWTOC.BAT v5.0 distributes **no** master spec `.DAT` files to stations (by design: "removed DATA folder copies"). Root cause of Syncro #32489. | Confirmed |
| F2 | **HIGH** | Deployed `NWTOC.BAT` v5.0 and `CTONWTXT.BAT` v2.3 use `COPY /Y`, **not a native MS-DOS 6.22 switch**. If stations run true 6.22, the station *downloader* silently fails entirely. | Confirmed in code; **needs station verification** |
| F3 | **MED** | `C:\Shares\test\TS-21\ProdSW` is a **file, not a directory** → rsync push fails (`exit 3`) on every 15-min run; sync status is permanently `ERRORS`. | Confirmed |
| F4 | **MED** | Server-side datasheet generation reads specs from `testdatadb\specdata\` — a **frozen 2026-03-27 snapshot**, not the live engineering masters (e.g. `5BMAIN.DAT` updated 2026-06-26). | Confirmed |
| F5 | **MED** | Plaintext credentials (NAS root SSH password, rsync daemon password, Postgres app password) hard-coded in scripts under `C:\Shares\test\scripts\` and `...\testdatadb\database\db.js`. | Confirmed |
| F6 | LOW | `For_Web` web-delivery output is **dead since 2026-05-11**; superseded by the API uploader. Legacy ASP.NET path effectively retired but not documented as such. | Confirmed |
| F7 | LOW | Duplicate/abandoned batch drafts in `C:\Shares\test\` root use NT-only constructs (`FOR /F`, `SET /A`, `CALL :label`, `%~dpnF`) that would fail on 6.22. Not in the boot path, but a confusion/cleanup hazard. | Confirmed |
| F8 | LOW | NAS share littered with junk/stray entries (`.DS_Store`, `NUL)`, files named `BAT`/`C`, case-dup `5b39data.dat`/`5B39DATA.DAT`, old v1.0 scripts at share root). | Confirmed |
| F9 | INFO | SSH key auth to NAS `root@192.168.0.9` is **not configured/broken** (publickey denied); the production sync does not use it (uses rsync daemon), so impact is nil today. | Confirmed |

---

## 2. As-verified chain topology (corrections in **bold**)

**NAS = `D2TESTNAS` = `192.168.0.9`** (a Linux box; `uname` blocked by SSH auth but rsync daemon + DOS AUTOEXEC confirm identity). Serves SMB shares `\\D2TESTNAS\test` (→ Linux `/data/test`) and `\\D2TESTNAS\datasheets`, plus an **rsync daemon on port 873, module `test` → `/data/test`**.

Stations (DOS 6.22, QuickBASIC ATE — `BRUN45.EXE`, `MENUX.EXE` present on NAS) map `T: = \\D2TESTNAS\test` and `X: = \\D2TESTNAS\datasheets` (per deployed `AUTOEXEC.BAT` v3.0, lines 45–46).

> **Correction to briefing:** On **AD2 itself**, `T:` is **not** the NAS — `net use` shows `T: → \\ad2\e-drive` (AD2's own engineering share) and `X: → \\ad2\webshare`. The DOS-station `T:`/`X:` mappings above apply on the *stations*, not on AD2. AD2 reaches the NAS only over SSH/rsync to `192.168.0.9`, never via a drive letter.

```
OUTBOUND (test results):
  DOS station  C:\ATE\{5B,7B,8B,DSC,HV,PWR,SCT,VAS}LOG\*.DAT
    │  (boot: AUTOEXEC → CTONW.BAT v5.0, plain COPY)
    ▼
  NAS  /data/test/TS-XX/LOGS/<type>/*.DAT   +  /TS-XX/Reports/*.TXT  +  /STAGE/TS-XX/*.TXT
    │  (AD2 scheduled task "Sync-FromNAS", every 15 min, rsync --remove-source-files)
    ▼
  AD2  C:\Shares\test\TS-XX\LOGS\...        → node import.js / import-work-orders.js / import-all-stage.js
    ▼
  PostgreSQL 18  db "testdatadb"  (test_records, work_orders, work_order_lines, *_quarantine)
    │  (export-datasheets.js / render-datasheet.js → text datasheets;  upload-to-api.js → website)
    ▼
  X:\webshare\Test_Datasheets (current)      [ For_Web = legacy, dead since 2026-05-11 ]
  + HTTP API upload (active: 472,290 records flagged api_uploaded)

INBOUND (specs / software):
  Engineering master specs  C:\Shares\test\Ate\ProdSW\{5B,7B,8B,DSC,SCT}DATA\*MAIN*.DAT
    │  (AD2→NAS push, rsync --update:  reaches NAS OK)
    ▼
  NAS  /data/test/Ate/ProdSW/<type>DATA/*.DAT   ← 5BMAIN.DAT present & current (83,200 b, 2026-06-26)
    │  (station boot: NWTOC.BAT v5.0)
    ▼
  ✗  NWTOC v5.0 copies only  T:\COMMON\ProdSW\*.BAT → C:\BAT  and  T:\Ate\ProdSW\*.EXE → C:\ATE.
     It copies NO *.DAT.  →  Master specs never reach the stations.   ← ROOT CAUSE (F1)
```

---

## 3. INBOUND spec distribution — root cause of Syncro #32489 (F1)

**The deployed downloader is `T:\COMMON\ProdSW\NWTOC.BAT`, version 5.0** (`C:\Shares\test\COMMON\ProdSW\NWTOC.BAT`, 972 bytes, mtime 2026-03-16; identical copy verified on NAS `COMMON/ProdSW/NWTOC.BAT` 972 b). Its own header states the cause verbatim:

```
Line 3:  REM Version: 5.0 - Added EXE copy, removed DATA folder copies (avoid cyclic overwrites)
Line 18: COPY /Y T:\COMMON\ProdSW\*.BAT C:\BAT
Line 22: COPY /Y T:\Ate\ProdSW\*.EXE C:\ATE
Line 26: COPY /Y T:\COMMON\NET\*.* C:\NET
```

There is **no `.DAT` copy anywhere in NWTOC v5.0.** The "removed DATA folder copies" change is exactly what broke master-spec refresh on the stations.

**The specs exist and are current everywhere except the stations**, which makes the impact concrete:

- Engineering master on AD2: `C:\Shares\test\Ate\ProdSW\5BDATA\5BMAIN.DAT` = **83,200 b, mtime 2026-06-26 11:43**.
- Same file on the NAS (pushed successfully): `/data/test/Ate/ProdSW/5BDATA/5BMAIN.DAT` = **83,200 b, 2026-06-26 11:43** (rsync listing).
- NWTOC v5.0 will never fetch it → stations keep whatever `5BMAIN.DAT` they last received.

Other live masters (all under `Ate\ProdSW\<type>DATA\`), showing engineering *is* editing them: `7BMAIN.DAT` 47,940 b 2025-06-10; `8BMAIN.DAT` 24,124 b 2024-10-14; `DSCMAIN4.DAT` 65,508 b 2026-01-16; `SCTMAIN.DAT` 20,933 b 2024-08-21. (There is also a non-8.3 `8BMAIN(2013-02-15).DAT` that the sync correctly skips — see F8.)

**Even the older NWTOC drafts never distributed COMMON master specs.** The abandoned v1.0 draft (`C:\Shares\test\NWTOC.BAT`) copies machine-specific `T:\%MACHINE%\ProdSW\*.DAT` (its lines 165–167) but never `T:\COMMON\ProdSW\*.DAT`, and `COMMON\ProdSW` contains **zero** `.DAT` files anyway (verified: 22 files, all `.BAT`). So there is no version of the download tool that pushes the shared master specs to stations. The recommended fix (F1 in §11) must **add** a DATA copy, it cannot merely "restore" one.

---

## 4. MS-DOS 6.22 command-structure analysis (focus area)

A crucial distinction the briefing blurs: **the scripts that actually run on stations live in `COMMON\ProdSW\` (and are mirrored to the NAS), NOT in the `C:\Shares\test\` root.** The root-level `NWTOC.BAT/CTONW.BAT/CHECKUPD.BAT/STAGE.BAT` are **abandoned earlier drafts** and are riddled with NT-cmd-only constructs; the deployed versions were deliberately cleaned. Judging DOS-compatibility off the root drafts would be a mistake.

### 4a. Deployed scripts (station boot path) — DOS-6.22 status

Boot flow (deployed `AUTOEXEC.BAT` v3.0): `STARTNET.BAT` → `NWTOC.BAT` (download) → `CTONW.BAT` (upload) → `CD \ATE` → `menux`.

| Deployed script | Ver | DOS 6.22 verdict | Notes |
|---|---|---|---|
| `AUTOEXEC.BAT` | 3.0 | Clean | `SET`, `IF EXIST T:\*.*`, `CALL`, `GOTO` only |
| `STARTNET.BAT` | — | (not read; maps T:/X:) | out of scope, recommend spot-check |
| `NWTOC.BAT` | 5.0 | **`COPY /Y` risk (F2)** | see below |
| `CTONW.BAT` | 5.0 | Clean | uses **plain** `COPY` (no `/Y`); silently overwrites, correct on 6.22 |
| `CTONWTXT.BAT` | 2.3 | **`COPY /Y` risk (F2)** | `COPY /Y C:\STAGE\*.TXT T:\STAGE\%MACHINE%` |
| `DEPLOY.BAT` | 2.4 | Clean | header: "Use COPY instead of XCOPY (DOS 6.22 compatibility)" |
| `CHECKUPD.BAT` | 1.4 | Clean | header: "removed CALL :label subroutines"; uses `SET FLAG=` + `GOTO`, no `SET /A` |
| `STAGE.BAT` | (rev) | Clean **but orphaned** | line 133 now `TYPE ... >>` (was `FOR /F "skip=1"`); however NWTOC v5.0 never calls it, so the `AUTOEXEC.NEW`/`CONFIG.NEW` auto-update mechanism is dead code |

### 4b. F2 — `COPY /Y` is not a native MS-DOS 6.22 switch  (HIGH, needs station confirmation)

MS-DOS 6.22's internal `COPY` supports `/A /B /V` only. The `/Y` (and `/-Y`) overwrite-suppression switch was introduced in **MS-DOS 7.0 (Windows 95)**. On a genuine 6.22 `COMMAND.COM`, `COPY /Y src dst` returns **`Invalid switch - /Y`** and performs **no copy**.

- Deployed **`NWTOC.BAT` v5.0** uses `COPY /Y` for **all three** of its copy steps (batch files, EXEs, NET files). If the stations are truly 6.22, NWTOC copies **nothing** — a broader failure than F1 (stations would receive no batch/EXE/NET updates at all).
- Deployed **`CTONWTXT.BAT` v2.3** likewise uses `COPY /Y`.
- The upload path survives regardless, because **`CTONW.BAT` v5.0 uses plain `COPY`** — which is why test data keeps flowing (see §5) even if NWTOC is silently dead.

**This cannot be confirmed from AD2** (the stations were not in scope/reachable for this audit). It is the single highest-value item for a cross-checker to verify **on a station**: run `VER` (confirm the exact DOS version) and test `COPY /Y NUL C:\x.txt`. If 6.22, replace `COPY /Y` → `COPY` in `NWTOC.BAT` and `CTONWTXT.BAT`. If the stations are actually MS-DOS 7.x (Win9x DOS mode), `/Y` is fine and F2 is a non-issue — the fact that F1's "removed DATA copies" note exists implies NWTOC has been running successfully, which is weak evidence the stations tolerate `/Y`; still worth a definitive check.

### 4c. F7 — Abandoned root-level drafts (LOW, cleanup)

`C:\Shares\test\NWTOC.BAT` (v1.0), `CTONW.BAT` (v1.2), `CHECKUPD.BAT` (v1.0), `STAGE.BAT` all use constructs invalid on 6.22 and should be removed to avoid someone deploying them by mistake:

- `FOR /F "skip=1 delims=" %%L IN (C:\AUTOEXEC.BAT)` — `FOR /F` is NT-only (root `STAGE.BAT` line 133).
- `SET /A SYSFILE=SYSFILE+1` — `SET /A` arithmetic is NT-only (root `CHECKUPD.BAT`).
- `CALL :CHECK_COMMON_FILE` and `GOTO :EOF` — call-to-label / `:EOF` are NT-only (root `CHECKUPD.BAT`).
- `%%~dpnF`, `%~nx1` — tilde path modifiers are NT-only (root `CTONW.BAT` line 189; root `CHECKUPD.BAT` line 187).
- `T: 2>NUL` and `... >NUL 2>NUL` — handle-specific `2>` stderr redirection is NT-only; 6.22 `COMMAND.COM` supports only `>`, `>>`, `<`.

(Note: the classic `IF EXIST T:\NUL` directory test and `CHOICE /C:YN` *are* valid 6.22 and appear in these drafts — but the items above are not.)

### 4d. Other 6.22 considerations (INFO)

- **Environment space.** Deployed `AUTOEXEC.BAT`/`DEPLOY.BAT` set `MACHINE`, `PATH`, `TEMP`, `TMP`. 6.22's default environment is 256 bytes and can overflow ("Out of environment space"). Ensure each station's `CONFIG.SYS` has `SHELL=C:\DOS\COMMAND.COM C:\DOS /E:512 /P`. `CONFIG.SYS` is station-local and was not inspectable from AD2 — recommend spot-check.
- **8.3 filenames.** The whole chain assumes 8.3 names; the sync explicitly skips non-8.3 files (see §5). Any master spec saved with a long name (e.g. `8BMAIN(2013-02-15).DAT`) is invisible to DOS anyway.

---

## 5. Sync engine (AD2 ↔ NAS)

> **Correction to briefing:** the scheduled task **`Sync-FromNAS` runs `Sync-FromNAS-rsync.ps1`**, not `Sync-FromNAS.ps1`. Verified from the task action: `powershell.exe -ExecutionPolicy Bypass -NonInteractive -File C:\Shares\test\scripts\Sync-FromNAS-rsync.ps1`. The non-rsync `Sync-FromNAS.ps1` (per-file SCP, NAS root creds) is dormant. The live status header `_SYNC_STATUS.txt` confirms it — it reads `... Status (rsync)` with `WO Reports Imported`/`STAGE TXT Files` fields that exist only in the rsync script's template.

- **Task:** `Sync-FromNAS`, State **Running**, trigger every 15 min from 2026-01-20; `LastRunTime 2026-07-01 09:30`, **`LastTaskResult = 1`** (non-zero, i.e. errors), `NumberOfMissedRuns 0`. (Task-scheduler clock/report lags the log, which shows runs continuing to 13:41.)
- **Mechanism:** rsync daemon `rsync://rsync@192.168.0.9/test`, PULL uses `--archive --include=*.DAT --exclude=* --remove-source-files` per station per log-type; imports pulled files via `node import.js`. PUSH uses `--update` with an 8.3 `--files-from` allowlist.

### F3 — permanent `ERRORS` from one stray file (MED)

Every run today (39 runs) ends `Sync complete: PULL=n, PUSH=0, Errors=1`. The single error is identical each run:

```
2026-07-01 09:35:28 :   ERROR: rsync push failed (exit 3): rsync.exe : rsync:
   [sender] change_dir "/cygdrive/c/Shares/test/TS-21/ProdSW/" failed: Not a directory
```

Ground truth: `C:\Shares\test\TS-21\ProdSW` is a **file** — `Mode -a----`, **79,116 bytes**, mtime 2026-06-26; its sibling `LOGS\` and `Reports\` are directories. The file's first bytes are an `MZ` header containing the string `7BMAIN4` — i.e. a **misplaced DOS executable** dropped where a `ProdSW` *directory* is expected. The rsync PUSH loop (`Sync-FromNAS-rsync.ps1` line 723, `Push-DirectoryToNAS $prodSwPath`) cannot `change_dir` into a file → exit 3 → `errorCount=1` → status `ERRORS` forever. This is cosmetic to data flow but **masks any new, real error** and keeps `LastTaskResult=1`.

### PULL side is healthy (evidence outbound works)

Today's per-run `PULL` counts include `12,623` (06:44), `806` (09:21), `661` (08:50), most others `0` (because `--remove-source-files` drains the NAS, so steady-state is 0). The big pulls are backlog flushes. Import into Postgres is landing — see §6.

The per-run PUSH log also shows the expected 8.3 skips (not errors), e.g. `Skipping (non-8.3): Copy of QB.EXE`, `_KDSCOUT1.EXE`, `8BDATA/8BMAIN(2013-02-15).DAT`, `PWRDATA/8BPWR - (2012-09-13).DAT`.

### NAS read-only verification

`rsync --list-only` confirmed: module root `/data/test` (3,730 entries), **62** `TS-*` station folders, `COMMON/ProdSW/` holding the v5.0 deployed set (NWTOC 972 b, CTONW 1,504 b, CTONWTXT 392 b, DEPLOY 4,142 b, CHECKUPD 3,239 b), `Ate/ProdSW/5BDATA/5BMAIN.DAT` current (83,200 b 2026-06-26), and `STAGE/` per-station folders (TS-11L/TS-11R updated 2026-07-01 06:35 — fresh STAGE TXT activity).

### F9 — SSH root key auth to NAS is broken (INFO)

`ssh -i C:\Users\sysadmin\.ssh\id_ed25519 root@192.168.0.9` → `Permission denied (publickey,password)`. The dormant SCP script relies on this key; the live rsync path does not, so there is no operational impact today, but the SCP fallback would fail if ever re-enabled.

---

## 6. Database & generation

> **Correction to briefing:** the datastore is **PostgreSQL 18.3**, not SQLite. `database\db.js`: *"PostgreSQL Database Abstraction Layer … Replaces better-sqlite3 singleton with pg.Pool."* `package.json` v2.0.0 depends on `pg ^8.20.0` (no `better-sqlite3`). Service `postgresql-18` is **Running** (PID 6044, listening `::1:5432`). The old SQLite file survives only as an archive: `database\archive\testdata.db` = **4,401,168,384 bytes (4.4 GB), mtime 2026-04-03** — the migration cutover date (`migrate-data.js`, `schema-pg.sql`). All queries below were run inside `BEGIN TRANSACTION READ ONLY`.

Row counts (db `testdatadb`, schema `public`):

| Table | Rows |
|---|---|
| `test_records` | **475,553** |
| `work_orders` | 34,149 |
| `work_order_lines` | 64,051 |
| `test_records_quarantine` | **3** (clean; dedup healthy) |
| `test_records_dedup_bak_20260415` | (backup table, stale artifact) |

Recency / pipeline liveness (from `test_records`):

- `max(import_date)` = **2026-07-01 13:41:53 UTC** (day of audit); `max(test_date)` = 2026-06-30.
- Imported last 24h: **111**; last 7d: **623**. `work_orders` last import **2026-07-01 13:43 UTC**.
- Per `log_type` last import: `5BLOG` & `7BLOG` → 07-01 (current); `DSCLOG` → 06-30; `8BLOG`,`PWRLOG` → 06-26; `VASLOG`,`SCTLOG` → 06-18. (8B/PWR/VAS/SCT trailing is plausibly just no production on those lines; not proven to be a fault — worth a glance.)

Web-delivery stage flags (`test_records`): `api_uploaded_at` set on **472,290 / 475,553 (99.3%)**, with **33,908** uploaded in the last 7 days → the **HTTP API uploader (`upload-to-api.js`) is the active delivery path**. `forweb_exported_at` = 300,781 and `datasheet_exported_at` = 298,155 are legacy counters that have stopped growing.

### F4 — server-side spec staleness (MED)

`parsers/spec-reader.js` line 19: `const DEFAULT_SPEC_DIR = path.join(__dirname, '..', 'specdata')` and line 366 defaults to it. So the **server** generates datasheets from `C:\Shares\testdatadb\specdata\`, whose spec DATs are a **2026-03-27 snapshot** (e.g. `specdata\5BMAIN.DAT` 83,200 b 2026-03-27 vs engineering's `Ate\ProdSW\5BDATA\5BMAIN.DAT` 83,200 b **2026-06-26**; `specdata\5B49DATA.DAT` is **0 bytes**). `specdata\` is not fed from the engineering masters by any automation observed. Net effect: **both** the station-side and the server-side spec refreshes are stale/manual. If a spec limit changed after 2026-03-27, generated datasheets may use outdated limits even though the outbound data pipeline is otherwise healthy.

### F6 — `For_Web` output dead since 2026-05-11 (LOW)

`X:\webshare\For_Web` = **7,517 files, newest 2026-05-11 09:53**, oldest 2023-10-04. `X:\webshare\Test_Datasheets` newest = **2026-06-29 11:09** (WO 180554). Generation now targets `Test_Datasheets` + API; the ASP.NET/`For_Web` path is effectively retired (consistent with the briefing's "largely broken/404"). Recommend documenting `For_Web` as deprecated so it is not mistaken for a live output.

---

## 7. F5 — Security: plaintext credentials (MED)

Hard-coded secrets discovered in-place (already plaintext on this host; **not** copied into any vault by this read-only audit — flagged for rotation + proper vaulting):

- `C:\Shares\test\scripts\Sync-FromNAS-rsync.ps1` L22–24: rsync daemon user `rsync` / password `IQ2…19`.
- `C:\Shares\test\scripts\Sync-FromNAS.ps1` (dormant) L19–22: NAS `root` SSH password `Pap…nas`, plus host key.
- `C:\Shares\testdatadb\database\db.js` L11–21: Postgres `testdatadb_app` / password `DfT…26!` (also the process-env default).

Recommend: rotate all three, move to environment/DPAPI/SOPS, and scrub the scripts. (These are also world-readable via the `test` SMB share.)

---

## 8. F8 — Share hygiene / clutter (LOW)

- NAS `/data/test` root carries junk and stale duplicates: `.DS_Store`, `._.DS_Store`, a 0-byte file literally named `NUL)`, stray files named `BAT` and `C`, a case-duplicate pair `5b39data.dat` + `5B39DATA.DAT`, and **old v1.0** `NWTOC.BAT` (8,925 b) / `CTONW.BAT` (11,341 b) / `CHECKUPD.BAT` (6,495 b) at the share root (superseded by `COMMON\ProdSW`).
- AD2 `C:\Shares\test\` root mirrors the mess: files named `-`, `C`, `X`, `TS-21.stray-dat-file`, `TS-27.old.file`, plus ~10 `Sync-FromNAS.ps1.backup-*` copies and abandoned v1.x batch drafts.
- `C:\Shares\testdatadb\` has dozens of `_*.js`/`*.bak-*` scratch/debug files intermixed with production code — recommend relocating to a `scratch/` folder for clarity (no functional impact).

---

## 9. Discrepancies vs the supplied briefing (for cross-checkers)

1. **Datastore:** briefing says SQLite `database\testdata.db`; reality is **PostgreSQL 18** (`testdatadb`). SQLite is a 4.4 GB archive from the 2026-04-03 cutover.
2. **Which sync script runs:** briefing implies `Sync-FromNAS.ps1`; the task runs **`Sync-FromNAS-rsync.ps1`**.
3. **`T:` on AD2:** briefing implies `T:` = NAS staging; on AD2 `T:` = `\\ad2\e-drive`. NAS is reached by SSH/rsync to `192.168.0.9`.
4. **`import.js` path:** exists at `database\import.js` (referenced correctly), **not** repo root.
5. **CTONWTXT "gap" (prior memory):** `CTONWTXT.BAT` **is** invoked — `CTONW.BAT` v5.0 line 30 `CALL C:\BAT\CTONWTXT.BAT`. Its output (`T:\STAGE\%MACHINE%`) is now largely redundant given server-side generation, but the call is live and STAGE TXT still flows (TS-11L/R today).
6. **NWTOC "v5.0" identity:** the deployed downloader header literally reads `Version: 5.0`; the v1.0 file in the share root is an abandoned draft. Syncro #32489's "v5.0" reference is correct and points at `COMMON\ProdSW\NWTOC.BAT`.

## 10. What I could NOT verify (scope/reachability limits)

- **Station-side reality:** no station was inspected. F2 (`COPY /Y` on true 6.22), `CONFIG.SYS` environment sizing, `STARTNET.BAT`, and the actual `VER` are **station-confirmable only**. This is the top cross-check.
- **NAS OS/uname/df:** SSH root auth denied (F9); only rsync-daemon listings were available. NAS free space not measured.
- **Website endpoints:** the API uploader's *server* (target of `upload-to-api.js`) was not probed (out of read-only scope / avoid outward calls). Only the DB `api_uploaded_at` flags evidence success.
- **8B/PWR/VAS/SCT import lull:** observed but not root-caused (could be normal no-production).

---

## 11. Recommendations (NONE applied — read-only audit)

Priority order. All are proposals; no change was made.

1. **(F1, HIGH) Restore master-spec distribution to stations.** Add a DATA copy to `NWTOC.BAT` — e.g. `COPY T:\Ate\ProdSW\5BDATA\*.DAT C:\ATE\5BDATA` (and 7B/8B/DSC/SCT), or a dedicated `NWSPEC.BAT`. Must be a *pull to a distinct local dir* to avoid the "cyclic overwrite" the v5.0 note was avoiding — i.e. don't push station DATA back up. Verify against how the ATE program locates `*MAIN*.DAT`.
2. **(F2, HIGH) Confirm DOS version on a station; if 6.22, replace `COPY /Y` → `COPY`** in `NWTOC.BAT` v5.0 (3 lines) and `CTONWTXT.BAT` v2.3. If MS-DOS 7.x, document that and close F2.
3. **(F3, MED) Remove/relocate the stray `C:\Shares\test\TS-21\ProdSW` file** (it is a misplaced `7BMAIN4`-ish EXE). Then verify sync returns `Errors: 0`. Consider hardening `Push-DirectoryToNAS` to skip a `ProdSW` that is not a container (the PULL side already guards this pattern; the PUSH side does not).
4. **(F4, MED) Feed `testdatadb\specdata\` from the engineering masters** (scheduled copy from `Ate\ProdSW\<type>DATA\*MAIN*.DAT`, with 8.3 + non-empty checks; note `5B49DATA.DAT` is currently 0 bytes), or point `spec-reader.js` `DEFAULT_SPEC_DIR` at the live master directory.
5. **(F5, MED) Rotate & vault** the rsync, NAS-root, and Postgres passwords; remove plaintext from scripts; tighten `test` share ACLs.
6. **(F6/F7/F8, LOW) Cleanup:** mark `For_Web` deprecated; delete the abandoned v1.x root batch drafts and NAS root duplicates/junk; move `_*.js`/`*.bak-*` scratch out of the app dir.
7. **(F9, INFO)** Either fix `id_ed25519` auth for `root@192.168.0.9` or delete the dormant SCP script so the two sync scripts don't diverge.

---

## 12. Evidence appendix — commands run (all read-only)

- Host/shares: `hostname`, `Get-NetIPAddress`, `Get-CimInstance Win32_OperatingSystem`, `net use`, `Get-SmbShare`, `Get-PSDrive`.
- Scheduled task: `Get-ScheduledTask/Info Sync-FromNAS` (Action/Trigger/LastResult).
- Batch/PS sources read in full: deployed `COMMON\ProdSW\{NWTOC,CTONW,CTONWTXT,AUTOEXEC,DEPLOY,CHECKUPD,STAGE}.BAT`; abandoned root drafts `test\{CTONW,NWTOC,CHECKUPD,STAGE,UPDATE}.BAT`; `scripts\Sync-FromNAS.ps1`, `scripts\Sync-FromNAS-rsync.ps1`; `testdatadb\database\db.js`, `package.json`, `parsers\spec-reader.js` (grep).
- Logs: `scripts\sync-from-nas.log` (today's ERROR + summary lines), `_SYNC_STATUS.txt`.
- DB (read-only txn): `information_schema` table/column introspection; `COUNT(*)`, `max(import_date/test_date)`, interval filters, per-`log_type` aggregation; `version()`, `current_database()`.
- NAS (read-only): `ssh -o BatchMode=yes` (auth denied, recorded); `rsync --list-only` on module root, `COMMON/ProdSW/`, `Ate/ProdSW/5BDATA/`, `STAGE/`.
- Filesystem: `Get-ChildItem`/`Get-Item` for sizes/mtimes across `C:\Shares\{test,TestDataDB,webshare}`; `Get-Content -TotalCount` to identify the `TS-21\ProdSW` stray by header.

*End of report.*
