C3: DelTep extended-property delete — live server-accept test blocked by native single-connection working-set #4

Closed
opened 2026-06-27 11:58:31 -04:00 by dohertj2 · 1 comment
Owner

Summary

The extended-property DELETE (DelTep) wire format is captured and the serializer is
golden-verified, but there is no live integration test proving the server accepts the delete,
because the SDK's per-service WCF channel cannot reproduce the native single-connection working-set
the server requires. This issue tracks closing that test gap (or formally deciding it stays
unexposed).

Current state — the code IS covered

  • DelTep inBuff is captured and decoded
    (docs/reverse-engineering/wcf-add-tag-extended-properties.md §Delete).
  • …Protocol.SerializeDeleteRequest produces the exact bytes; WcfTagExtendedPropertyWriteProtocolTests
    golden-verifies it.
  • HistorianClient deliberately exposes no public delete to avoid a silently-failing write API.
    The private scaffolding (HistorianWcfTagWriteOrchestrator.DeleteTagExtendedPropertiesAsync, the
    PrimeThenDelete helper) exists for follow-up.

Blocker

The native DeleteTagExtendedPropertiesByName gate requires the same HistorianAccess session
that read-synced the property (a per-connection working set); the capture only works via a
cross-session prime trick (scripts/Capture-DeleteTagExtendedProperties.ps1). Over the SDK's
per-service WCF channels the server returns the "not in working set" rejection, so a live delete is
not accepted — hence no integration test
(tests/AVEVA.Historian.Client.Tests/HistorianClientIntegrationTests.cs:627–631).

What's needed

  1. Determine whether the SDK can hold a single multiplexed HistorianAccess session across
    GetTepByNm → DelTep (reproducing the native working-set), or prove per-service channels
    structurally cannot.
  2. If reproducible: add a live integration test (sandbox create → add → prime-read → delete → verify
    gone) and expose a guarded public delete.
  3. If not reproducible: record it as a permanent SDK limitation (delete stays unexposed by design)
    so it is no longer carried as an open "gap."

Acceptance criteria

  • Either a green live DelTep round-trip test + a documented public delete surface, or a
    closing note in the §Delete doc that per-service channels cannot satisfy the working-set gate (with
    the evidence), flipping this from "deferred" to "won't-expose".

References

  • Doc: docs/reverse-engineering/wcf-add-tag-extended-properties.md §Delete (§"Why the SDK delete is
    server-blocked", §"the cross-session trick").
  • Test gap: tests/AVEVA.Historian.Client.Tests/HistorianClientIntegrationTests.cs:627–631.
  • Tooling: scripts/Capture-DeleteTagExtendedProperties.ps1, scripts/decode-del-tep-capture.py.
  • Downstream tracking: HistorianGateway pending.md C3 (the serializer is golden-verified there
    via the carried-over vendored test; only this live-accept test is deferred).

https://claude.ai/code/session_012SDSQ3AcaXqPcBtDESBRii

## Summary The extended-property **DELETE** (`DelTep`) wire format is captured and the serializer is golden-verified, but there is **no live integration test** proving the server accepts the delete, because the SDK's per-service WCF channel cannot reproduce the **native single-connection working-set** the server requires. This issue tracks closing that test gap (or formally deciding it stays unexposed). ## Current state — the code IS covered - `DelTep` inBuff is captured and decoded (`docs/reverse-engineering/wcf-add-tag-extended-properties.md` §Delete). - `…Protocol.SerializeDeleteRequest` produces the exact bytes; `WcfTagExtendedPropertyWriteProtocolTests` golden-verifies it. - `HistorianClient` deliberately exposes **no public delete** to avoid a silently-failing write API. The private scaffolding (`HistorianWcfTagWriteOrchestrator.DeleteTagExtendedPropertiesAsync`, the `PrimeThenDelete` helper) exists for follow-up. ## Blocker The native `DeleteTagExtendedPropertiesByName` gate requires the **same** `HistorianAccess` session that read-synced the property (a **per-connection working set**); the capture only works via a cross-session prime trick (`scripts/Capture-DeleteTagExtendedProperties.ps1`). Over the SDK's per-service WCF channels the server returns the "not in working set" rejection, so a live delete is not accepted — hence no integration test (`tests/AVEVA.Historian.Client.Tests/HistorianClientIntegrationTests.cs:627–631`). ## What's needed 1. Determine whether the SDK can hold a single multiplexed `HistorianAccess` session across `GetTepByNm` → `DelTep` (reproducing the native working-set), or prove per-service channels structurally cannot. 2. If reproducible: add a live integration test (sandbox create → add → prime-read → delete → verify gone) and expose a guarded public delete. 3. If not reproducible: record it as a **permanent SDK limitation** (delete stays unexposed by design) so it is no longer carried as an open "gap." ## Acceptance criteria - Either a green live `DelTep` round-trip test + a documented public delete surface, **or** a closing note in the §Delete doc that per-service channels cannot satisfy the working-set gate (with the evidence), flipping this from "deferred" to "won't-expose". ## References - Doc: `docs/reverse-engineering/wcf-add-tag-extended-properties.md` §Delete (§"Why the SDK delete is server-blocked", §"the cross-session trick"). - Test gap: `tests/AVEVA.Historian.Client.Tests/HistorianClientIntegrationTests.cs:627–631`. - Tooling: `scripts/Capture-DeleteTagExtendedProperties.ps1`, `scripts/decode-del-tep-capture.py`. - Downstream tracking: HistorianGateway `pending.md` **C3** (the serializer is golden-verified there via the carried-over vendored test; only this live-accept test is deferred). https://claude.ai/code/session_012SDSQ3AcaXqPcBtDESBRii
Author
Owner

Investigation complete — requires transport-level connection multiplexing (deferred by design)

The question "can the SDK reproduce the native single-connection working-set for DelTep?" is now
answered: no, not without transport-level connection multiplexing.

  • The DelTep wire format is captured, decoded, and golden-verified
    (WcfTagExtendedPropertyWriteProtocolTests) — byte-identical to the server-accepted native bytes.
  • The native client multiplexes Hist/Retr/Stat/Trx over one connection under a single
    HistorianAccess session; its GetTepByNm seeds a per-connection working set that the
    same-connection DelTep consults.
  • The SDK opens separate per-service WCF channels; even priming via a borrowed-GUID Retrieval
    channel held open across the delete (HistorianWcfTagWriteOrchestrator.PrimeThenDelete) does not
    satisfy the server's per-connection check, which fails with SErrorException.
  • Therefore HistorianClient deliberately exposes no public delete (avoids a silently-failing
    write API).

Conclusion: a known design limitation, not a protocol-evidence gap. Closing the investigation;
exposing delete would require connection multiplexing (a substantial transport refactor) and can be
reopened as a feature request if wanted. Documented in
docs/reverse-engineering/wcf-add-tag-extended-properties.md §Delete. (HistorianGateway pending.md
C3 notes the serializer is golden-verified and only the live-accept test is deferred.)

https://claude.ai/code/session_012SDSQ3AcaXqPcBtDESBRii

## Investigation complete — requires transport-level connection multiplexing (deferred by design) The question "can the SDK reproduce the native single-connection working-set for DelTep?" is now answered: **no**, not without transport-level connection multiplexing. - The DelTep wire format is captured, decoded, and golden-verified (`WcfTagExtendedPropertyWriteProtocolTests`) — byte-identical to the server-accepted native bytes. - The native client multiplexes Hist/Retr/Stat/Trx over **one** connection under a single `HistorianAccess` session; its `GetTepByNm` seeds a **per-connection working set** that the same-connection `DelTep` consults. - The SDK opens **separate per-service WCF channels**; even priming via a borrowed-GUID Retrieval channel held open across the delete (`HistorianWcfTagWriteOrchestrator.PrimeThenDelete`) does not satisfy the server's per-connection check, which fails with `SErrorException`. - Therefore `HistorianClient` deliberately exposes **no public delete** (avoids a silently-failing write API). **Conclusion:** a known design limitation, not a protocol-evidence gap. Closing the *investigation*; exposing delete would require connection multiplexing (a substantial transport refactor) and can be reopened as a feature request if wanted. Documented in `docs/reverse-engineering/wcf-add-tag-extended-properties.md §Delete`. (HistorianGateway `pending.md` C3 notes the serializer is golden-verified and only the live-accept test is deferred.) https://claude.ai/code/session_012SDSQ3AcaXqPcBtDESBRii
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dohertj2/histsdk#4