--- title: "Ford — Client Knowledge" aliases: [ford, ford-motor] tags: [client, ford, box, sftp, qc, automation] sources: [01 Projects/ford_qc, 01 Projects/ford-gechub-sftp] created: 2026-04-15 updated: 2026-04-29 --- > [!info] SSH Alias > SSH into the Ford QC server using `box-cli` (→ 10.220.176.3). `box-cli-01` does NOT resolve. # Ford Oliver Agency works with Ford on asset pack automation — QC validation and delivery to Ford's GECHUB SFTP system. ## Key Takeaways - Ford has **3 environments**: PROD, EDU, QA — each has separate Box folders and SFTP targets - Asset packs are ZIP files — QC runs 13 checks before delivery - Ford uses GECHUB as their SFTP-based delivery system - Box JWT service account (`ford_box_config.json`) — never commit this file - The Ford QC daemon runs as a **systemd service** on the production server ## Projects | Project | Purpose | Entry Point | |---------|---------|-------------| | [[01 Projects/ford_qc/Ford QC System\|Ford QC System]] | QC validation of asset pack ZIPs | systemd or `python qc_engine.py` | | [[01 Projects/ford-gechub-sftp/Ford SFTP Transfer\|Ford SFTP Transfer]] | Box → GECHUB SFTP transfer | `python main.py [--daemon]` | ## Environment Details | Env | Purpose | Box Folder | SFTP Target | |-----|---------|-----------|-------------| | PROD | Production assets | Box/PROD | GECHUB PROD | | EDU | Educational assets | Box/EDU | GECHUB EDU | | QA | QA testing | Box/QA | GECHUB QA | ## Box Folder IDs (Ford QC) | Folder | ID | |--------|-----| | Input hotfolder | 332861865120 | | Reports output | 332864939558 | | Archive | 332861653811 | ## Ford QC Checks (13 modules) - Image resolution, format, file size - Layer depth, colour existence - Linking validation - MEC/BAU compliance - Powertrain validation - Lifestyle inventory - HTML report generation ## Tech Preferences - Box API (JWT auth) — file exchange platform - SFTP (GECHUB) — delivery system - systemd for production daemons - Email notifications via Mailgun - QC profiles in JSON (configurable per asset type) - HTML reports (not PDFs) ## Quirks & Lessons - Ranger ptvl pattern must be configurable via QC profile — don't hardcode it (fix: 2026-03-16) - Always archive processed ZIPs immediately — daemon reprocesses if not archived - Ford has 3 completely separate environments — changes in PROD profiles don't affect EDU/QA - GECHUB SFTP credentials differ per environment ## Ford QC Server Path Confusion > [!warning] Always verify working directory before deploying > The systemd service for Ford QC runs from `ford_qc_git_dev/ford_qc/` — NOT from `FORD_ASSET_PACK_QC` or `FORD_ASSET_PACK_QC_NEW` (legacy directory names that still exist on disk). **SSH:** `box-cli` (→ 10.220.176.3). Do NOT use `box-cli-01` — it does not resolve. **Service names:** - Dev: `ford-qc-hotfolder.service` - Production: `ford-qc-hotfolder-PROD.service` **To find the real working directory before deploying:** ```bash systemctl show ford-qc-hotfolder-PROD --property=ExecStart # or systemctl cat ford-qc-hotfolder-PROD # WorkingDirectory=/home/box-cli/FORD_SCRIPTS/ford_qc_git_dev/ford_qc ``` Never assume the working directory from directory names alone. Always use `systemctl show` or `systemctl cat` to confirm. **Known directories on the Ford QC server (do not confuse):** | Directory | Status | Notes | |-----------|--------|-------| | `/home/box-cli/FORD_SCRIPTS/ford_qc_git_dev/ford_qc/` | **Active** | This is where the service runs | | `/home/box-cli/FORD_SCRIPTS/FORD_ASSET_PACK_QC/` | Legacy | Old deployment, do not use | | `/home/box-cli/FORD_SCRIPTS/FORD_ASSET_PACK_QC_NEW/` | Stale | Abandoned migration attempt | **Git pull with local edits on server:** ```bash git stash && git pull && git stash pop ``` **ford-gechub-sftp deploy path:** `/home/box-cli/FORD_SCRIPTS/ford-gechub-sftp` (different project) ## GPAS Zip Naming Convention > [!important] Zip filename format changed > Ford image packs must now end in `_GPAS.zip` — the old `_image.zip` suffix is no longer accepted. This is enforced by `zip_filename_check.py`. Packs with incorrect suffixes fail QC immediately at the filename check stage. Update any scripts or templates that generate pack filenames. | Old format | New format | |-----------|-----------| | `ford_pack_2026_image.zip` | `ford_pack_2026_GPAS.zip` | ## Ford BnP WERS Code Allowlist Pattern When validating WERS (World Engineering Release System) codes in Ford Build-and-Price asset packs, use an **allowlist** of known prefixes rather than exclusion-based stripping. **Shared code prefixes (always pass through QC):** ```python shared_code_prefixes = ["abm", "acm", "vs-", "se#", "bs-", "dr-", "dga", "en-", "ca#"] ``` **Critical distinctions:** - `TR-` = **transmission code**, NOT a trim code — do not strip it - `ptvl` must equal `model[:3]` — the powertrain validation level must match the first 3 chars of the model code - Pack type determines valid code combinations: - **PV (Passenger Vehicle)** = `VS-` + `ACM` pair required - **CV (Commercial Vehicle) non-Ranger** = `ABM-` only - **CV Ranger** = `SE#` + `ABM` pair required **Implementation pattern:** ```python def is_valid_shared_code(code: str, shared_code_prefixes: list[str]) -> bool: """Allowlist-based WERS code validation — preferred over exclusion stripping.""" code_lower = code.lower() return any(code_lower.startswith(prefix.lower()) for prefix in shared_code_prefixes) def validate_pack(pack_codes: list[str], pack_type: str, model: str) -> list[str]: errors = [] ptvl = next((c for c in pack_codes if c.lower().startswith("ptvl")), None) if ptvl and ptvl[4:7].lower() != model[:3].lower(): errors.append(f"ptvl mismatch: {ptvl} vs model {model}") # ... pack_type checks return errors ``` ## Related - [[wiki/architecture/hotfolder-daemon|hotfolder-daemon]] — the daemon pattern - [[wiki/tech-patterns/box-api-integration|box-api-integration]] — Box details