@@ -44,12 +44,13 @@ reported wall-clock — keep CNC clocks on UTC so the dedup key
|
||||
`(OccurrenceTime, AlarmNumber, AlarmType)` stays stable across DST
|
||||
transitions.
|
||||
|
||||
## Write safety — issue #269, plan PR F4-b
|
||||
## Write safety — issue #269 (PARAM/MACRO, F4-b) + issue #270 (PMC, F4-c)
|
||||
|
||||
The FOCAS driver supports `cnc_wrparam` and `cnc_wrmacro` writes behind
|
||||
multiple independent opt-ins. A misdirected parameter write can put the
|
||||
CNC in a bad state, so the runbook below MUST be followed before flipping
|
||||
the granular kill switches on.
|
||||
The FOCAS driver supports `cnc_wrparam`, `cnc_wrmacro`, and `pmc_wrpmcrng`
|
||||
writes behind multiple independent opt-ins. A misdirected parameter write
|
||||
can put the CNC in a bad state; a misdirected PMC write can move motion or
|
||||
latch a feedhold. The runbook below MUST be followed before flipping any
|
||||
of the granular kill switches on.
|
||||
|
||||
### Operator pre-checks (every deployment, every change)
|
||||
|
||||
@@ -72,6 +73,35 @@ the granular kill switches on.
|
||||
`BadNotWritable` until you flip the granular flag, so you can confirm
|
||||
the tag list before any wire write fires.
|
||||
|
||||
### PMC pre-checks (in addition to the above) — F4-c
|
||||
|
||||
PMC writes have a higher blast radius than PARAM/MACRO writes because PMC
|
||||
is the ladder's working memory — bits in R/G/F/D directly drive servo
|
||||
enables, feedhold latches, and safety interlocks. Before flipping
|
||||
`Writes.AllowPmc` on:
|
||||
|
||||
1. **E-stop verified live + reachable.** The first PMC write of a session
|
||||
should be issued with the operator's hand on the e-stop. PMC writes
|
||||
bypass the ladder's normal MDI-mode protections; a misdirected bit can
|
||||
move motion the moment it lands on the wire.
|
||||
2. **Machine in JOG mode (or equivalent low-energy mode).** Auto / MEM
|
||||
modes interpret PMC state immediately; JOG / MDI surface symptoms
|
||||
slowly enough that the e-stop is the recovery path. **Never issue the
|
||||
first PMC write of a deployment in Auto.**
|
||||
3. **Audit the PMC tag list against the ladder print-out.** `R100.3` on
|
||||
one machine is "homing complete"; on another it's "feedhold released".
|
||||
The driver has no way to distinguish — the ladder source is the only
|
||||
ground truth.
|
||||
4. **Bit writes are read-modify-write — see
|
||||
[`docs/drivers/FOCAS.md`](../drivers/FOCAS.md) "PMC bit-write read-modify-write semantics".**
|
||||
`pmc_wrpmcrng` is byte-addressed; the driver reads the parent byte
|
||||
first, masks the target bit, and writes the byte back. Concurrent
|
||||
ladder writes to the same byte create a small race window. Coordinate
|
||||
through a ladder-side handshake when this matters.
|
||||
5. **Dry run with `Writable = true` but `Writes.AllowPmc = false`.** Same
|
||||
staged-opt-in pattern as PARAM/MACRO — confirm tag mapping before any
|
||||
PMC byte hits the wire.
|
||||
|
||||
### LDAP group requirements
|
||||
|
||||
Per [`docs/security.md`](../security.md) the server-layer ACL maps
|
||||
@@ -108,6 +138,14 @@ produce the same audit entries with the failure status code so a
|
||||
post-incident reviewer sees the same shape regardless of whether the write
|
||||
succeeded.
|
||||
|
||||
**Audit PMC writes specifically.** Because PMC writes have the highest blast
|
||||
radius of the three write kinds, ops should set up a saved-search /
|
||||
dashboard query for `Driver=FOCAS` + `Address` matching the PMC letter
|
||||
prefixes (`R*`, `G*`, `F*`, `D*`, `Y*`, etc.) and review on the same
|
||||
cadence as ladder change reviews. A spike in PMC write rate or a write
|
||||
to an address outside the audited tag list is the leading indicator of a
|
||||
misconfigured client or compromised credential.
|
||||
|
||||
### Granular config example
|
||||
|
||||
```jsonc
|
||||
@@ -120,7 +158,8 @@ succeeded.
|
||||
"Writes": {
|
||||
"Enabled": true,
|
||||
"AllowMacro": true, // recipe / setpoint writes — operator role
|
||||
"AllowParameter": false // commissioning only — keep locked except during planned work
|
||||
"AllowParameter": false, // commissioning only — keep locked except during planned work
|
||||
"AllowPmc": false // PMC writes — keep locked unless the deployment specifically needs them
|
||||
},
|
||||
"Tags": [
|
||||
{ "Name": "Recipe.PartCount", "DeviceHostAddress": "focas://10.0.0.5:8193",
|
||||
@@ -128,13 +167,19 @@ succeeded.
|
||||
"Writable": true, "WriteIdempotent": true },
|
||||
{ "Name": "MaxFeedrate", "DeviceHostAddress": "focas://10.0.0.5:8193",
|
||||
"Address": "PARAM:1815", "DataType": "Int32",
|
||||
"Writable": false /* keep read-only until commissioning window */ }
|
||||
"Writable": false /* keep read-only until commissioning window */ },
|
||||
{ "Name": "OperatorRequest", "DeviceHostAddress": "focas://10.0.0.5:8193",
|
||||
"Address": "R100.3", "DataType": "Bit",
|
||||
"Writable": false /* keep PMC read-only until ladder handshake reviewed */ }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Flipping `AllowParameter` on for the commissioning window (and back off
|
||||
afterward) is the recommended deployment cadence — the granular kill
|
||||
switch is a lightweight runtime toggle, not a config-DB redeploy.
|
||||
Flipping `AllowParameter` / `AllowPmc` on for the commissioning window
|
||||
(and back off afterward) is the recommended deployment cadence — the
|
||||
granular kill switches are lightweight runtime toggles, not config-DB
|
||||
redeploys. PMC in particular should default OFF in production and only
|
||||
flip on for windows where the ladder team has signed off on the write
|
||||
path.
|
||||
|
||||
Reference in New Issue
Block a user