Files
wwtools/graccesscli
Joseph Doherty bd95ace1c5 graccesscli: fail fast on package-only attribute writes (writeback gap fix)
Investigation findings: IAttribute.SetValue silently no-ops for any
attribute whose AttributeCategory starts with `MxCategoryPackageOnly`.
The COM call returns Successful=true and the dispatcher reports OK,
but a verify-read via direct IAttribute.GetValue confirms the value
is unchanged.

Discovered while validating the new --field flag round-trip on
\$DelmiaReceiver.ProcessRecipe.ExecuteText:

- BEFORE write: ExecuteText body = `Me.RecipeDownloadFlag = false;`
- WRITE: scripts set --field ExecuteText --file marker.txt → OK
- AFTER write: ExecuteText body = `Me.RecipeDownloadFlag = false;`
  (UNCHANGED — the marker prefix from marker.txt is absent)
- ConfigurableAttributes shows `ProcessRecipe.ExecuteText` category =
  `MxCategoryPackageOnly_Lockable`. Same for DeclarationsText,
  StartupText, ShutdownText, OnScanText, OffScanText, Expression.
- Per docs/script-parsing.md:8, "Object-level scripts ... may appear
  as attributes, extension attributes, or only inside exported object
  packages" — script-text fields are in the third bucket.

Trigger settings (TriggerType, TriggerPeriod) are
`MxCategoryWriteable_C_Lockable` and remain effective via SetValue —
verified by `scripts settings set --trigger-period-ms 1000` returning
OK on a clean checkout state.

Add `EnsureMutableViaSetValue(IAttribute, name)` helper that throws
InvalidOperationException with a clear remediation hint when called on
a package-only attribute. Wired into three write sites:

- `case "value-set"` (object attribute value set)
- `ObjectScriptSet` (scripts set body writer)
- `SetScriptSettings` Expression branch (the one trigger-related field
  that's package-only; TriggerType/TriggerPeriod stay unguarded)

Validation against live ZB galaxy:

- Before fix: `scripts set --field ExecuteText` returned
  `success: true` but didn't mutate the body.
- After fix: same call returns `success: false` with
  `"Attribute 'ProcessRecipe.ExecuteText' has category
  'MxCategoryPackageOnly_Lockable'. Package-only attributes silently
  no-op via IAttribute.SetValue and can only be edited through the
  package import/export round-trip..."` (exit code 1).
- `scripts settings set --trigger-period-ms 1000` against the same
  script: still OK (TriggerPeriod is Writeable_C_Lockable).

The real fix for editing script bodies is the package-rewrite path —
export `.aaPKG`, modify the binary script-extension records, re-import
via `galaxy.ImportObjects`. graccesscli already has the read half
(`PackageSnapshotParser.Parse`); the write half is a separate followup.

61 → 63 → 63 (no test count delta this commit; the new helper is exercised
end-to-end by the live validation above; unit tests for the failure path
require a mock IAttribute proxy that's out of scope here).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 15:45:07 -04:00
..

graccesscli

A .NET Framework 4.8 / x86 CliFx-based CLI for automating AVEVA / Wonderware System Platform Galaxy configuration through the ArchestrA GRAccess COM interop library (ZB.MOM.WW.GRAccess.Cli).

Hard constraints

GRAccess is a 32-bit COM stack. Skipping any of these will fail at load or corrupt Galaxy state:

  • Target framework / arch: net48, x86, [STAThread]. No exceptions.
  • Cannot be loaded from a .NET 10 / x64 process — see GRAccess-DLL-and-DotNet10-Notes.md.
  • AVEVA System Platform must be installed locally (or ArchestrA.GRAccess.dll registered in the GAC at C:\Windows\assembly\GAC\Archestra.GRAccess\1.7.0.0_23106a86e706d0ae\). The bundled copy in lib/ is for build-time reference only.
  • In daemon mode, every COM call must be marshalled through Session/StaComThread.cs; calling GRAccess from any other thread will deadlock or corrupt state.
  • Keep the root GRAccessApp alive for the lifetime of any derived IGalaxy / IgObject handle.
  • Mutation flow is fixed: CheckOut → modify → Save → CheckIn(comment). Skipping CheckIn leaves the object locked in the Galaxy repo.
  • Build requires Visual Studio / MSBuild with the x86 platform target.

Layout

graccesscli/
  ZB.MOM.WW.GRAccess.Cli.slnx        # solution
  lib/ArchestrA.GRAccess.dll         # bundled COM interop assembly (reference only)
  src/ZB.MOM.WW.GRAccess.Cli/        # CLI project (net48, x86, CliFx)
  tests/ZB.MOM.WW.GRAccess.Cli.Tests # test project
  docs/                              # CLI workflows, LLM contract, parsing/editing guides
  AGENTS.md                          # coding-agent rules for this tool
  CLAUDE.md                          # detailed agent guide
  graccess_documentation.md          # full GRAccess API reference
  graccess_operations.md             # GRAccess operations grouped by functional area
  usage.md                           # compatibility copy of docs/usage.md
  GRAccess-DLL-and-DotNet10-Notes.md # platform / 32-bit COM / .NET 10 incident notes
  requirements-mutation-typelib-fix.md # active mutation-path defect tracker

Resource index

Task Go to
Coding-agent rules for working in this folder AGENTS.md
General agent guide (project overview, references) CLAUDE.md
Full GRAccess API surface (types, methods) graccess_documentation.md
GRAccess operations grouped by functional area, with page refs graccess_operations.md
CLI commands, options, session mode, IPC protocol docs/usage.md
LLM-facing operating contract (envelopes, safety, batch) docs/llm-integration.md
Add a new CLI command end-to-end docs/adding-features.md
Inspect / read existing templates (read-only) docs/template-parsing.md
Parse template attributes and setting families docs/attribute-parsing.md
Parse script libraries and object-level scripts docs/script-parsing.md
Edit existing templates safely docs/template-editing.md
Create / edit template instances, areas, engine assignments, I/O docs/template-instance-editing.md
Edit template attributes, UDAs, extensions, setting families docs/attribute-editing.md
Edit script libraries and script-bearing template content docs/script-editing.md
Live ZB galaxy reference (read-only capture) docs/zb-galaxy.md
Live ZB $TestMachine template family reference docs/zb-testmachine.md
CliFx framework reference (commands, options, DI, testing) docs/clifx_reference.md
GRAccess DLL / 32-bit COM / .NET 10 platform notes GRAccess-DLL-and-DotNet10-Notes.md
Active mutation-path COM lifecycle defects requirements-mutation-typelib-fix.md
Index for docs/ only docs/README.md

Maintenance

Documentation rules live in ../DOCS-GUIDE.md; the root task → tool index lives in ../CLAUDE.md. When adding, renaming, or removing any doc in this folder, update the resource index above in the same change. When the user-facing CLI surface changes, update docs/usage.md (and keep usage.md aligned).