Phase 3+4 rename reorg: repo dir renames + startnet.cmd menu

Pairs with Phase 1+2 from earlier (alias maps in Install-FromManifest,
GE-Enforce, Get-PCProfile, verify-state). See project-shopfloor-rename-reorg
memory for the plan.

Phase 3 (repo + paths):
- git mv per-PC-type dirs to gea-shopfloor-* names:
    Standard      -> gea-shopfloor-collections
    CMM           -> gea-shopfloor-cmm
    Keyence       -> gea-shopfloor-keyence
    Genspect      -> gea-shopfloor-genspect
    WaxAndTrace   -> gea-shopfloor-waxtrace
    Display       -> gea-shopfloor-display
    Lab           -> gea-shopfloor-common (folded; Timeclock+Lab merge)
- New gea-shopfloor-nocollections/ (clone of collections sans UDC scripts).
- New gea-shopfloor-heattreat/ (placeholder, README only).
- Move Standard/ntlars-backups/ -> _ntlars-backups/ (per-MN, not per-type).
- Run-ShopfloorSetup.ps1: Resolve-PCTypeDir helper walks alias group when
  the on-disk dir for the current pcType is missing. Set-MachineNumber
  helper-copy gated on collections|nocollections|legacy Standard-Machine.
- Update-MachineNumber.ps1: pcProfiles lookups try gea-shopfloor-collections
  first, fall back to legacy Standard-Machine. PowerShell 5.1 compatible
  (no null-coalesce).

Phase 4 (startnet.cmd menu):
- Choice 3 "GEA Shopfloor" now drills into a 9-item sub-menu instead of
  going straight to enrollment. Sub-cats:
    1. Machine with Collections        -> gea-shopfloor-collections
    2. Machine without Collections     -> gea-shopfloor-nocollections
    3. Common (Timeclock, Lab)         -> gea-shopfloor-common
    4. Keyence                         -> gea-shopfloor-keyence
    5. CMM                             -> gea-shopfloor-cmm
    6. Genspect                        -> gea-shopfloor-genspect
    7. Heattreat                       -> gea-shopfloor-heattreat
    8. Wax and Trace                   -> gea-shopfloor-waxtrace
    9. Display                         -> gea-shopfloor-display
- Office menu (existing 6-option) follows for every sub-cat.
- Machine number prompt only for collections + nocollections.
- pc-subtype.txt + display-type.txt no longer written. PCTYPE is a
  single full string (gea-shopfloor-*); subtype-aware code paths fall
  back to empty and resolve via the alias map.
- CMM bootstrap stage gate switched from "%PCTYPE%"=="CMM" to
  "%PCTYPE%"=="gea-shopfloor-cmm".

Test harness:
- B-enforce/run.sh PCSUBTYPE default changed from "Machine" to "" so
  single-arg invocation matches the new single-string scheme. Two-arg
  legacy form ("Standard Machine") still works via aliasing.
- B-enforce/tamper.ps1 alias-aware Test-MatrixEntryMatches mirroring
  verify-state.ps1.

Smoke-tested on win11 VM as SYSTEM via qga: B-enforce harness 5-phase
cycle (stage / baseline / tamper / heal / idempotent) passes 10/10
with PCType=gea-shopfloor-collections AND with legacy "Standard Machine"
two-arg form.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
cproudlock
2026-05-04 08:09:16 -04:00
parent 48e20a7e73
commit 6dcf96e40a
262 changed files with 592 additions and 455 deletions

View File

@@ -20,8 +20,11 @@
set -euo pipefail
PCTYPE="${1:-Standard}"
PCSUBTYPE="${2:-Machine}"
PCTYPE="${1:-gea-shopfloor-collections}"
# Empty string (no subtype) is the new default. The legacy two-arg form
# ("Standard Machine") still works thanks to alias maps. To explicitly
# pass an empty subtype use a single arg: ./run.sh gea-shopfloor-cmm
PCSUBTYPE="${2-}"
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TEST_ROOT="$(cd "$HERE/.." && pwd)"

View File

@@ -18,7 +18,34 @@ param(
$ErrorActionPreference = 'Continue'
$matrix = Get-Content -LiteralPath $MatrixPath -Raw | ConvertFrom-Json
$entry = $matrix.pcTypes | Where-Object { $_.PCType -eq $PCType -and ($_.PCSubType -eq $PCSubType -or [string]::IsNullOrEmpty($_.PCSubType)) } | Select-Object -First 1
# Same alias map as verify-state.ps1 so harness invocations with the new
# gea-shopfloor-* names find the correct matrix row even when that row's
# PCType field is still the legacy "Standard"+"Machine" form.
$pcTypeAliasGroups = @(
@('Standard-Machine','gea-shopfloor-collections'),
@('Standard-Machine-NoCollections','gea-shopfloor-nocollections'),
@('Standard-Timeclock','Lab','gea-shopfloor-common'),
@('CMM','gea-shopfloor-cmm'),
@('Keyence','gea-shopfloor-keyence'),
@('WaxAndTrace','gea-shopfloor-waxtrace'),
@('Genspect','gea-shopfloor-genspect'),
@('Display','gea-shopfloor-display'),
@('Heattreat','gea-shopfloor-heattreat'),
@('Shopfloor')
)
function Test-MatrixEntryMatches {
param($Entry, [string]$Type, [string]$SubType)
$entryKey = if ($Entry.PCSubType) { "$($Entry.PCType)-$($Entry.PCSubType)" } else { $Entry.PCType }
$requestKey = if ($SubType) { "$Type-$SubType" } else { $Type }
if ($entryKey -ieq $requestKey) { return $true }
foreach ($g in $pcTypeAliasGroups) {
if ($g -icontains $entryKey -and $g -icontains $requestKey) { return $true }
}
return $false
}
$entry = $matrix.pcTypes | Where-Object { Test-MatrixEntryMatches -Entry $_ -Type $PCType -SubType $PCSubType } | Select-Object -First 1
if (-not $entry) { Write-Host "[FAIL] no matrix entry for $PCType/$PCSubType"; exit 1 }
foreach ($d in $entry.driftScenarios) {