Phase 3 was written as "the collector reads a registry value". It is all three components moving together: imaging writes DeviceId, GE-Enforce resolves device identity registry-first, and the collector reads the registry ahead of the file. The argument for it is already in the fleet's own code. Install-FromManifest resolves TargetMachineNumbers gating from the eDNC registry BEFORE machine-number.txt, and says why: the file is written ONCE by startnet.cmd at the PXE menu and is not updated on reassignment, so it goes stale. asset-id.txt inherits that defect exactly. Nothing rewrites it when a device is swapped, moved between bays or replaced, and phase 1 put it at the TOP of the resolution order - so a stale value is adopted with no warning, because it still resolves. A file only imaging writes cannot be the top of a resolution order for something that changes during a PC's life. Also records the consequence: phase 3 needs a reassignment path the way Set-MachineNumber exists for the bay number, or it moves the staleness from a file into a registry value instead of curing it.
226 lines
10 KiB
Markdown
226 lines
10 KiB
Markdown
# Proposal: one identity for the device a PC drives, ending in the registry
|
|
|
|
Status: PHASE 1 DONE (shipped after 0.12.0). Phases 2 and 3 not started.
|
|
Author: planning session 2026-08-20.
|
|
|
|
## 1. What this is
|
|
|
|
A shop-floor PC often drives something: a CMM, a Keyence, a Genspect, a
|
|
wax-trace unit, a part marker. ShopDB needs to know WHICH one, and the answer
|
|
has to survive the PC being replaced.
|
|
|
|
Today that answer is assembled from whatever each bay family happens to have,
|
|
and two of the three sources are derived from the PC itself, so they do not
|
|
survive a swap. This proposal converges them on one identity, moves it from
|
|
files to the registry, and does it in three phases so no bay is stranded.
|
|
|
|
## 2. Why PC-derived identity fails
|
|
|
|
Two mechanisms stand in for a real identity today:
|
|
|
|
- **Reuse**: look for a prior collector link from THIS PC asset.
|
|
- **Mint**: build `<PC assetnumber>-<SUFFIX>`, and a PC's asset number is its
|
|
hostname.
|
|
|
|
Both survive a re-image. Neither survives a PC SWAP. A new hostname is a new PC
|
|
asset with no prior link and a predicted number that has never existed, so the
|
|
same physical device gets a SECOND record while the first keeps its config and
|
|
its backup history under a dead PC's name.
|
|
|
|
That is not hypothetical: minting from the hostname left 43 legacy `MT-####`
|
|
tools shadowed by minted twins, three records deep in places.
|
|
|
|
## 3. The rail that must not be crossed
|
|
|
|
`machinenumber` answers "WHICH BAY is this" and is what GE-Enforce
|
|
`TargetMachineNumbers` gates on. The device identity answers "WHICH DEVICE is
|
|
this". They are different facts and must stay in different fields.
|
|
|
|
Putting a device id into the machine-number channel would silently stop every
|
|
bay-gated manifest entry from matching - a failure that looks like nothing
|
|
happening, on every cycle, with no error anywhere.
|
|
|
|
## 4. Where identity comes from today
|
|
|
|
| Bay family | Identity source | Survives a PC swap |
|
|
|---|---|---|
|
|
| DNC / collections | `MachineNo` in the eDNC/NTLARS registry | yes |
|
|
| CMM | `C:\Enrollment\cmm\cmmid.txt` | yes, but see below |
|
|
| Keyence, Genspect, wax-trace | nothing, before phase 1 | no |
|
|
| Part markers | nothing, before phase 1 | no |
|
|
|
|
**`cmmid.txt` is not only an identity file.** It is a PATH KEY, and that is why
|
|
it cannot simply be retired:
|
|
|
|
| Consumer | Use |
|
|
|---|---|
|
|
| `resolve-cmm-bay-config.ps1` | writes it |
|
|
| `Verify-And-Heal-Staging.ps1` | stages `installers-post\cmm\backups\<cmmid>` |
|
|
| `09-Setup-CMM.ps1` | locates the bay's staged backup set |
|
|
| `Restore-CMM.ps1` | restores from `<BackupRoot>\<cmmid>\`, same-bay by design |
|
|
| collector | reads it as `machineNo` |
|
|
|
|
Only the last row is an identity use. The rest address directories by it.
|
|
|
|
It is also doing the job badly: for a CMM bay it reports the INSTRUMENT's id in
|
|
the `machinenumber` channel, and the server then resolves it back to a measuring
|
|
tool at step 4 of its own fallback chain. That round trip is what phases 2 and 3
|
|
remove.
|
|
|
|
## Phase 1 - one field, one file (DONE)
|
|
|
|
The collector accepts a single `deviceid`, read from `C:\Enrollment\asset-id.txt`
|
|
and resolved BEFORE anything PC-derived, for every device family.
|
|
|
|
- One file for every bay with no `MachineNo` registry to identify it.
|
|
- It names the asset and NOT its type: the pc-type already says what kind of
|
|
device it is, through `SUBORDINATE_DEVICE_MAP`, so a device type declared
|
|
later through `subordinatedevice_<pctype>` needs no new file and no client
|
|
change.
|
|
- Wire field is `deviceid`, not `assetid`, because `assetid` is already this
|
|
contract's RESPONSE field for a PC's integer primary key.
|
|
- `measuringtoolid` (0.12.0) is accepted as an alias and the older file is still
|
|
read, so a bay staged in that window keeps reporting.
|
|
- Guards: an unresolvable value warns rather than minting a phantom, and a value
|
|
resolving to the WRONG KIND of asset is refused with the asset named.
|
|
|
|
Nothing was removed. Every previous fallback still runs, one place lower.
|
|
|
|
## Phase 2 - imaging writes it, and `cmmid.txt` stops being an identity
|
|
|
|
Repository: the PXE/imaging repo, not this one. **Needs deploying to the live
|
|
server, not only committing** - the live boot image is authoritative.
|
|
|
|
1. `resolve-cmm-bay-config.ps1` writes `C:\Enrollment\asset-id.txt` ALONGSIDE
|
|
`cmmid.txt`. Two files, two questions: the identity, and the backup-set key.
|
|
`cmmid.txt` keeps every path use it has today.
|
|
2. Every other device pc-type writes `asset-id.txt` at imaging from its bay
|
|
config. Bays with no device write nothing, and the file's absence stays
|
|
meaningful.
|
|
3. The collector demotes `cmmid.txt` to last place in the machine-number chain
|
|
and stops being the intended path for CMM identity. It is still read, so a
|
|
grandfathered bay that never gets re-imaged keeps reporting.
|
|
4. The value written is the device's `assetnumber` as ShopDB holds it. Where a
|
|
CMM's asset number is already its bay id (`CMM3`), phase 2 is a no-op in
|
|
content and a change only in which file carries it.
|
|
|
|
Exit criterion: a report from a re-imaged bay of each device family carries
|
|
`deviceid`, and no bay of those families relies on the `cmmid.txt` fallback.
|
|
The collector response warnings are the check: an adopted device is silent, a
|
|
minted one is not.
|
|
|
|
## Phase 3 - identity moves to the registry
|
|
|
|
`HKLM:\SOFTWARE\GE\ShopDB\DeviceId`.
|
|
|
|
This is the destination because the registry survives the profile cleanup and
|
|
disk hygiene that eats `C:\Enrollment`, is readable as SYSTEM with no file ACL
|
|
to get wrong, and is already how a DNC bay is identified. It needs no new key
|
|
and no new read path: the collector already opens
|
|
`HKLM:\SOFTWARE\GE\ShopDB` (and the `WOW6432Node` variant) for `BaseUrl` and
|
|
`ApiToken`, and `Install-GEEnforce.ps1` already writes that key.
|
|
|
|
**One value, every family.** `DeviceId` is a single registry value, not a key
|
|
per device type. The client sends one field and the pc-type decides which sync
|
|
consumes it, exactly as `asset-id.txt` works in phase 1, so:
|
|
|
|
| Bay | `DeviceId` holds | Replaces |
|
|
|---|---|---|
|
|
| CMM | the instrument's `assetnumber` | `cmmid.txt` as IDENTITY only |
|
|
| Keyence | the instrument's `assetnumber` | nothing; had none |
|
|
| Genspect | the instrument's `assetnumber` | nothing; had none |
|
|
| wax-trace | the instrument's `assetnumber` | nothing; had none |
|
|
| part marker | the marker's `assetnumber` | minting from the hostname |
|
|
|
|
A device family added later through `subordinatedevice_<pctype>` is covered on
|
|
the day it is declared, with no client change and no new registry value.
|
|
|
|
Resolution order after phase 3:
|
|
|
|
1. `HKLM:\SOFTWARE\GE\ShopDB\DeviceId`
|
|
2. `C:\Enrollment\asset-id.txt`
|
|
3. `C:\Enrollment\measuringtool-id.txt` (0.12.0 window)
|
|
4. `C:\Enrollment\cmm\cmmid.txt` as `machineNo` (grandfathered CMM bays)
|
|
|
|
Then, and only then, the file branches can be deleted one at a time, newest
|
|
first, each when no bay has reported through it for a full inventory cycle.
|
|
|
|
**`cmmid.txt` survives phase 3 regardless**, as the CMM backup-set path key. It
|
|
is not on the deletion list; only its identity use is.
|
|
|
|
### PXE and GE-Enforce prefer it too, not just the collector
|
|
|
|
Phase 3 is not only "the collector reads a registry value". All three writers
|
|
and readers move together:
|
|
|
|
| Component | Change |
|
|
|---|---|
|
|
| PXE / imaging | writes `DeviceId` at enrollment instead of (or as well as) the file |
|
|
| GE-Enforce | resolves device identity registry-first, mirroring how it already resolves the machine number |
|
|
| collector | reads the registry ahead of the file |
|
|
|
|
**GE-Enforce already made this exact decision for the machine number, and wrote
|
|
down why.** `Install-FromManifest.ps1` resolves `TargetMachineNumbers` gating
|
|
from the eDNC registry BEFORE `C:\Enrollment\machine-number.txt`, because:
|
|
|
|
> the imaging-time `machine-number.txt` is written ONCE by `startnet.cmd` at the
|
|
> PXE menu and is NOT updated on reassignment, so it goes stale.
|
|
|
|
**`asset-id.txt` inherits that defect exactly.** It is written once at imaging
|
|
and nothing updates it when a device is swapped, moved between bays, or
|
|
replaced. The bay then reports an identity that was true on imaging day, and the
|
|
collector - which now trusts that value FIRST, ahead of every other source -
|
|
adopts the wrong device with no warning, because the value still resolves.
|
|
|
|
That makes phase 3 a correctness fix rather than a tidy-up. A file that only
|
|
imaging writes cannot be the top of a resolution order for something that
|
|
changes during a PC's life.
|
|
|
|
It also implies a reassignment path, the way `Set-MachineNumber` /
|
|
`Update-MachineNumber` exist for the bay number: something that rewrites
|
|
`DeviceId` when a device is swapped, and migrates any per-device state with it.
|
|
Without that, phase 3 moves the staleness from a file to a registry value rather
|
|
than curing it.
|
|
|
|
### Doing phase 3 early is cheaper than doing it late
|
|
|
|
If the registry read lands before imaging is changed, phase 2 can write the
|
|
REGISTRY for new bays and skip the file era entirely for them. The file then
|
|
exists only for bays staged in the window between phase 1 and phase 2, and the
|
|
eventual cleanup is deleting a code branch rather than sweeping the fleet.
|
|
|
|
The cost of adding the read now is one branch in the client and one row in the
|
|
docs. The cost of adding it after every bay has a file is a migration.
|
|
|
|
## 5. What this does not change
|
|
|
|
- `machinenumber` and its GE-Enforce gating. Untouched in all three phases.
|
|
- A part marker still files `partof` the operation from `machinenumber`. The
|
|
device identity says WHICH marker the PC controls, not which operation that
|
|
marker belongs to.
|
|
- Minting. It stays as the last resort for a bay that names nothing, because a
|
|
device nobody declared is still better recorded than not recorded. Anything
|
|
minted should be treated as a placeholder to be reconciled.
|
|
|
|
## 6. Before phase 2: find what is already duplicated
|
|
|
|
Phase 1 stops NEW duplicates. It does not merge the ones a PC swap has already
|
|
created. Before imaging starts writing files, run a read-only query for device
|
|
assets whose controlling PC no longer exists, or whose asset number carries a
|
|
hostname that is not a current PC. That list is the reconciliation backlog, and
|
|
it is much easier to read before the fleet starts reporting new identities over
|
|
the top of it.
|
|
|
|
## 7. Rollback
|
|
|
|
Each phase is independently reversible because nothing is removed until the
|
|
phase after it proves the replacement:
|
|
|
|
- Phase 1: stop sending `deviceid` and every previous fallback still runs.
|
|
- Phase 2: stop writing `asset-id.txt` and bays fall back to what they used
|
|
before.
|
|
- Phase 3: stop writing the registry value and bays fall back to the file.
|
|
|
|
The only irreversible step is deleting a fallback branch, which is deliberately
|
|
outside all three phases.
|