Commit Graph

3 Commits

Author SHA1 Message Date
Joseph Doherty c8f31bd653 mxaccesscli: add --secured / --verifier-* options for WriteSecured
WriteCommand grows three new options:

  --secured                Route the write through
                           LMXProxyServer.WriteSecured(currentUserId,
                           verifierUserId, value) instead of plain
                           Write(value, userId). Required for attributes
                           classified as Secured Write or Verified Write,
                           and useful for testing whether the audit
                           subsystem propagates user identity when
                           explicitly told the write is "secured".

  --verifier-username      Galaxy / OS username of the verifier for a
                           two-person Verified Write. Implies --secured.
  --verifier-domain        Domain composed with --verifier-username as
                           '<domain>\<username>'.
  --verifier-password      Verifier password. Redacted in the JSON
                           query echo.

When --secured is on without a verifier, the same auth_user_id is
used for both currentUserId and verifierUserId (single-user Secured
Write semantics). When a verifier is provided, the CLI authenticates
both users and bails cleanly with "verifier-authentication-failed"
on a verifier credential mismatch.

The JSON envelope's results[] gains `secured` and `verifier_user_id`
fields so an agent can confirm which path ran.

MxItem grows WriteSecured(value, currentUserId, verifierUserId).

Verified live against TestMachine_001.TestAlarm002.AckMsg under
eOSUserBased + ArchestraUsers role: --secured succeeds with
auth_user_id=1, verifier_user_id=1, MxCategoryOk. User_Name in the
Historian Events row remains NULL — same as plain Write. The
audit-attribution gate is not Write vs WriteSecured; running engines
likely still need a redeploy to pick up the new security mode.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 23:48:17 -04:00
Joseph Doherty 9de8660688 mxaccesscli: route write through Advise vs AdviseSupervisory by user
WriteCommand now picks the LMXProxyServer advise variant based on
whether credentials were supplied:

  --username given  -> Advise            (operator action; the write
                                          is attributed to the
                                          authenticated Galaxy user
                                          in the alarm/event audit
                                          trail)
  no --username     -> AdviseSupervisory (supervisory action; the
                                          write is attributed to the
                                          hosting client itself, no
                                          Galaxy user claimed)

MxItem grows AdviseSupervisory() alongside Advise() and shares the
same UnAdvise / RemoveItem teardown.

Verified live with the trigger / ack-as-dohertj2 / clear sequence on
TestMachine_001.TestAlarm002. The Set (anonymous, supervisory) and
Clear (anonymous, supervisory) rows pair with the Acknowledged row
(authenticated, Advise) under one Alarm_ID. On this development
galaxy every action still maps to User_Name=DefaultUser regardless
of advise variant — that's a galaxy-security configuration trait,
not a CLI bug. The routing is in place and will differentiate
correctly on a strict galaxy with real user records.

docs/usage.md gains an "Advise variant" section explaining the rule
and the expected User_Name population on strict vs permissive
galaxies.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 22:10:25 -04:00
Joseph Doherty ab202a1fa1 mxaccesscli: read/write/subscribe System Platform tags via MxAccess
New tool wrapping ArchestrA.MxAccess.LMXProxyServerClass (the same COM
proxy aaObjectViewer / WindowViewer use) as a CliFx CLI for LLM-driven
debugging.

Commands:
- mxa info      — loaded MxAccess assembly identity, supported value
                   types, MxStatusCategory enum.
- mxa read      — fetch one or more tag values; subscribes briefly,
                   captures first OnDataChange per tag, tears down.
- mxa write     — write a value with optional --type coercion; advises
                   first to resolve the attribute type, then waits for
                   OnWriteComplete with a per-call timeout.
- mxa subscribe — stream OnDataChange events for --seconds; JSON Lines
                   under --llm-json for piped agent consumption.
- mxa diag      — minimal smoke test on a private STA thread; bypasses
                   the CliFx pipeline for diagnosing apartment / pump
                   issues.

Implementation notes documented in docs/api-notes.md (reverse-engineered
because AVEVA does not publish a single canonical MxAccess reference):

- Net48 / x86 / [STAThread] are non-negotiable. The CLI runs the entire
  CliFx pipeline on a dedicated STA thread.
- COM events are dispatched as Win32 messages; AutoResetEvent.WaitOne
  alone does not pump them on this configuration. MxSession.WaitForUpdate
  loops Application.DoEvents() + drain + Sleep(20ms) instead.
- Write requires the target attribute's type to be resolved first.
  WriteCommand advises and waits for the initial OnDataChange before
  calling LMXProxyServerClass.Write to avoid ArgumentException
  "Value does not fall within the expected range".
- Errors carry the full MXSTATUS_PROXY[] from MxAccess (Success,
  Category, DetectedBy, Detail) so an agent can tell exactly which
  layer rejected a request.

Verified against the live ZB galaxy with a writeable tag identified
via grdb (TestChildObject.TestInt, mx_attribute_category=10):
  read:      99 (q=192, MxCategoryOk)
  write 7:   round-tripped — read returned 7 — written back to 99
  write str: TestChildObject.TestString round-tripped a timestamp
  subscribe: captured initial value plus subsequent change from a
             separate process

The vendored ArchestrA.MxAccess.dll is gitignored — it is copied from
C:\Program Files (x86)\ArchestrA\Framework\Bin\ on any System Platform
install per the README.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 20:02:51 -04:00