Write down where device identity is going, in three phases
Phase 1 shipped without a plan around it, and the next two steps both touch a different repository and the live boot image, so the reasoning needs to outlive this week rather than being rediscovered from the code. The finding that shapes the whole thing: cmmid.txt CANNOT simply be retired. It is a PATH KEY, not just an identity - Verify-And-Heal-Staging stages installers-post\cmm\backups\<cmmid>, 09-Setup-CMM locates the staged set by it, and Restore-CMM restores from <BackupRoot>\<cmmid> as a same-bay operation. Only one of its five consumers is an identity use. That one is also the one doing the job badly, reporting a CMM's INSTRUMENT id in the machinenumber channel so the server can resolve it back to a measuring tool at step 4 of its own fallback chain. So phase 2 has imaging write asset-id.txt ALONGSIDE cmmid.txt - two files, two questions - and demotes the identity use while every path use stays exactly where it is. cmmid.txt survives phase 3 too; it is not on any deletion list. Phase 3 is the registry, HKLM:\SOFTWARE\GE\ShopDB\DeviceId. No new key and no new read path: the collector already opens that key for BaseUrl and ApiToken and Install-GEEnforce already writes it. The proposal argues for doing phase 3 BEFORE phase 2 rather than after, because then imaging writes the registry for new bays and skips the file era entirely - the file survives only for bays staged between phases, and the cleanup is deleting a branch instead of sweeping a fleet. Also recorded: the rail that must not be crossed (machinenumber is what TargetMachineNumbers gates on, so a device id in that channel stops every bay-gated entry from matching, silently, forever), what each phase does NOT change, per-phase rollback, and a note that phase 1 stops new duplicates without merging the ones a PC swap has already made - so the reconciliation backlog should be read BEFORE imaging starts writing identities over the top of it.
This commit is contained in:
176
docs/proposals/device-identity.md
Normal file
176
docs/proposals/device-identity.md
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
# 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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
### 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.
|
||||||
Reference in New Issue
Block a user