Auto: focas-f4b — cnc_wrmacro + cnc_wrparam writes

Closes #269
This commit is contained in:
Joseph Doherty
2026-04-26 04:54:28 -04:00
parent 71af554497
commit f48f31cfc7
15 changed files with 1066 additions and 36 deletions

View File

@@ -54,6 +54,35 @@ public sealed record FocasWritesOptions
/// <c>"writes disabled at driver level"</c>.
/// </summary>
public bool Enabled { get; init; } = false;
/// <summary>
/// Issue #269, plan PR F4-b — granular kill-switch for <c>cnc_wrparam</c>
/// parameter writes (defense in depth on top of <see cref="Enabled"/> and the
/// per-tag <see cref="FocasTagDefinition.Writable"/>). Default <c>false</c>: an
/// operator who flips <see cref="Enabled"/> on without explicitly opting into
/// parameter writes still gets <see cref="FocasStatusMapper.BadNotWritable"/>
/// for every <c>PARAM:</c> tag. A misdirected parameter write can put the CNC
/// in a bad state, so the third opt-in keeps the blast radius bounded.
/// <para>Server-layer ACL: <c>PARAM:</c> tags additionally surface a
/// <see cref="Core.Abstractions.SecurityClassification.Configure"/> classification
/// so the OPC UA gate requires <c>WriteConfigure</c> group membership; this
/// flag is the driver-level kill switch the operator team can flip without a
/// redeploy.</para>
/// </summary>
public bool AllowParameter { get; init; } = false;
/// <summary>
/// Issue #269, plan PR F4-b — granular kill-switch for <c>cnc_wrmacro</c> macro
/// variable writes (defense in depth on top of <see cref="Enabled"/> and the
/// per-tag <see cref="FocasTagDefinition.Writable"/>). Default <c>false</c>:
/// macro writes are gated separately from parameter writes because they're a
/// normal HMI-driven recipe / setpoint surface where parameter writes are
/// mostly emergency commissioning territory.
/// <para>Server-layer ACL: <c>MACRO:</c> tags surface
/// <see cref="Core.Abstractions.SecurityClassification.Operate"/> so the OPC UA
/// gate requires <c>WriteOperate</c> group membership.</para>
/// </summary>
public bool AllowMacro { get; init; } = false;
}
/// <summary>