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
S
Description
No description provided
3.4 MiB
Languages
C# 93.3%
TSQL 4.2%
PowerShell 1.5%
Shell 0.7%
Python 0.3%