docs(archreview): R2-06 live gate 5/6 + U-7 retype policy answered
v2-ci / build (push) Successful in 4m21s
v2-ci / unit-tests (push) Failing after 8m44s

- StorageRateMs bug found+fixed (PR #439); live suite 3/6 -> 5/6
- U-7: EnsureTags is a real upsert; supported-type retype ACCEPTED (Float->Double);
  Int1 not creatable on this histsdk (ProtocolEvidenceMissingException, Int1-only)
- record the observed retype policy in docs/Historian.md (fills the placeholder)
This commit is contained in:
Joseph Doherty
2026-07-13 19:31:47 -04:00
parent 666908d792
commit 416789c6ab
3 changed files with 66 additions and 46 deletions
+19 -7
View File
@@ -157,13 +157,25 @@ mapper code change is needed or wanted). Consequences:
1. **New Boolean tags provision correctly as Int1.** This is the fix arriving as a silent, zero-diff
semantic change from the bump.
2. **Pre-bump Boolean tags exist historian-side as Float.** On the next deploy that dispatches provisioning
for such a tag, the gateway is asked (via the upsert) to update it to Int1. The AVEVA-side outcome of an
in-place analog retype is the one thing the contract does not pin; the candidate behaviors are
(i) **accepted with tag versioning** (history preserved under the old version, new writes under Int1),
(ii) **accepted as a plain retype**, or (iii) **rejected per-tag**`TagOperationResult.Success=false`
→ counted in the provisioner's `failed=N` dispatch tally. Only a live run distinguishes these — see the
**retype probe** (`EnsureTags_type_change_outcome_is_observable`) in the [Live /run gate](#live-run-gate).
*(This list is replaced with the observed answer after the first live run.)*
for such a tag, the gateway is asked (via the upsert) to update it to Int1.
**Observed live (2026-07-13, real 0.2.0 gateway → real AVEVA historian on `wonder-sql-vd03`, probed via
`grpcurl` — archreview R2-06 T12):**
- `EnsureTags` is a **real create-or-update upsert** — re-`EnsureTags` of an existing tag at the same type
returns `Success=true`.
- An **in-place retype between SUPPORTED types is ACCEPTED**`Float→Double` on an existing tag returns
`Success=true` (hypothesis **(ii) accepted as a plain retype**, not rejected).
- **BUT `Int1` — the 0.2.0 Boolean target — is *not a creatable type* on this historian's histsdk:**
`EnsureTags(Int1)` returns `Success=false, Error="ProtocolEvidenceMissingException"` (the vendored client's
"no capture evidence for this type" guard → gRPC `Unimplemented`), both for a fresh tag and as a retype
target. A type sweep confirmed it is **Int1-specific**: `Int2/UInt2/Int4/UInt4/Float/Double` all provision
`Success=true`; only `Int1` fails.
- **Net for a pre-bump Float Boolean tag asked to become Int1:** the provision **fails** (per-tag
`Success=false``failed=N` tally). It is **neither silently retyped nor data-lost** — the tag stays Float
and remains readable; the Int1 provision simply doesn't land until the gateway's histsdk gains `Int1`
create-evidence. (Prerequisite for reaching this outcome at all: the provisioner must stamp a **positive
`StorageRateMs`** — a `0` made `EnsureTags` throw `ArgumentOutOfRangeException` and fail *every* provision;
fixed in `GatewayTagProvisioner`, PR #439.)
3. **The failure mode is bounded and observable either way.** Provisioning is fire-and-forget and never
blocks/fails a deploy; a per-tag rejection surfaces only as the tally's `failed` count. Values written to
a still-Float tag by the recorder remain readable (Float supersets Int1's 0/1 range); nothing is lost