Repository navigation
feat(antd-csharp, antd-php): signed quotes on pointer prepare - #369
Conversation
Optional PointerPrepareRequest.IncludeSignedQuotes (default false, sent only when true on REST; set on the proto request over gRPC) and PointerPrepareResult.SignedQuotes (empty when absent), with a new SignedQuoteEntry model. gRPC bytes are mapped to base64 so both transports expose the same shape. Existing callers and IAntdClient implementers are unaffected. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Optional PointerPrepareRequest::$includeSignedQuotes (default false, sent as include_signed_quotes only when true) and PointerPrepareResult::$signedQuotes (empty list when absent), with a new SignedQuoteEntry model. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dirvine
left a comment
There was a problem hiding this comment.
Request changes — one C# compatibility regression
Reviewed WithAutonomi/ant-sdk #369 at 827bd184c3477c26cf436b17c097a4b3cb8c3400, relative to bc339abe3e8914104139cf63253913892ed28432 (nic/stack-integration-preview). All 12 incremental changed files were inspected.
[P2] Preserve the existing pointer factory overloads — PointerModels.cs:273–281. Appending an optional Boolean replaces the existing method signatures. The same method-group consumer compiles against the base SDK and fails with CS0123 against this head for Create, Update and Transfer. A base-built Transfer(owner, recipient) consumer also throws MissingMethodException when only the SDK assembly is upgraded. Ordinary direct source calls can omit the new argument; that does not make the whole change source-compatible.
Please retain the old three-/three-/two-parameter factories. Expose opt-in through non-ambiguous overloads or the existing init property, and add consumer compatibility regression tests. The inline finding contains the minimal reproducer. A scratch-only overload control restored both consumers and passed all 315 tests; the PR branch was not changed. The assembly probe does not establish that an affected NuGet version has shipped.
Executed evidence
- C#: Release build with warnings as errors, 315/315 tests, and NuGet pack pass at the reviewed head. Local runtime: .NET 8 on macOS arm64, using native
protoc/gRPC plugin overrides after the stock x64 compiler could not execute. Exact-head Linux CI also passes. - PHP: 195 passed, 2 live-daemon tests skipped, 983 assertions; Composer install/validate pass. Local PHP 8.5.11; CI covers PHP 8.2/8.3/8.4.
- Separate review probe: 48 mock-backed cases pass for create/update/transfer, flag defaults, sync/async responses, missing/null/empty quote lists and binary/base64 payloads.
- Base/head compatibility probes reproduce the regression. Scratch-only overload control restores old method groups, old compiled calls and new opt-in calls.
git diff --checkpasses; tracked checkout remains unchanged.
Review participation and adjudication
5/6 reviewed — partial panel. GLM 5.3, Qwen 3.8 and DS4 completed correctness reviews; GLM and Qwen completed adversarial reviews. DS4 adversarial produced no usable verdict: the first response and its one narrowed retry both exhausted the 8192-token output limit. This is missing coverage, not approval.
The completed first passes approved the quote-path implementation; GLM noted factory binary compatibility as a release concern. The additional real-consumer probe then established a source break as well. GLM and Qwen independently reviewed that new evidence and both returned CHANGES_REQUIRED. DS4's earlier correctness approval predates the probe; DS4 did not review the new finding. No full-team consensus is claimed. There is no unresolved material dissent among the reviewers of the reproduced finding.
Scope and remaining gates
The flag defaults, base64 mapping and absent/empty sidecar normalization match the unchanged daemon contracts in the inspected paths. No live-daemon, network or payment run was performed. Lenient malformed-response handling is a separate optional hardening item, not this blocker.
PR #367 is explicitly a DO NOT MERGE CI preview. Retarget #369 to main after the real stack lands and rerun affected checks. This review does not authorise a merge or release.
Exact-head CI, refreshed before publication
- Build + test (antd-csharp): SUCCESS
- Test (PHP 8.2): SUCCESS
- Test (PHP 8.3): SUCCESS
- Test (PHP 8.4): SUCCESS
- Split + consume as a Composer package: SUCCESS
Review on #369: appending an optional includeSignedQuotes to Create, Update and Transfer replaced their signatures. Method-group consumers stopped compiling (CS0123) and code built against the earlier assembly would throw MissingMethodException on Transfer(owner, recipient). The factories are back to their exact earlier signatures. Signed quotes are opted into through the existing init property: `PointerPrepareRequest.Update(owner, target) with { IncludeSignedQuotes = true }`. New tests bind each factory as a method group of its exact type and check by reflection that each earlier method still exists with its return type. They fail to compile against the previous head (CS0123 for all three). 317/317 tests pass; Release build with warnings as errors; pack ok. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
dirvine
left a comment
There was a problem hiding this comment.
Approve — the C# compatibility finding is resolved
Re-reviewed WithAutonomi/ant-sdk #369 at 32cf671e26bcf85deb4096e41ccaa4eebb34c224, against bc339abe3e8914104139cf63253913892ed28432 (nic/stack-integration-preview). Inspected all 12 current PR paths, including all eight handwritten production files, both test files and both READMEs, plus the three-file rectification delta. No new blocking finding.
Original P2: fixed and independently reproduced as passing
Create,UpdateandTransferretain their original three-/three-/two-parameter signatures and implementations. Signed-quote opt-in useswith { IncludeSignedQuotes = true }, rather than replacing an existing factory signature.- All three legacy method groups compile against the current SDK. The new regression tests guard those signatures and check that opt-in preserves the prepared write.
- I compiled a consumer against the real base SDK, then replaced only
Antd.Sdk.dllwith the current-head assembly. All three factories and their legacy delegates run successfully without recompiling the consumer. The previousCS0123andMissingMethodExceptionfailures no longer reproduce. A separate current-source probe verifies default false and opt-in field preservation for all three operations.
This supersedes the compatibility blocker in my earlier review. The assembly check does not establish anything about previously published NuGet versions.
Executed checks
- C#: 317/317 pass, including the two new compatibility regression tests; Release build with warnings as errors and NuGet pack pass. The packed SDK DLL matches the tested current-head DLL. Local toolchain: .NET SDK 8.0.426 on macOS arm64, with native protobuf/gRPC compiler overrides.
- PHP: 195 pass, 2 live-daemon tests skipped, 983 assertions; Composer install/validate pass. Local PHP 8.5.11. CI separately covers PHP 8.2, 8.3 and 8.4.
- 48 additional mock-backed PHP cases pass across all operations, flag defaults/opt-in, sync/async, absent/null/empty/populated quote lists, binary payloads and optional sidecars.
git diff --checkpasses; no tracked checkout edits. The base archive's 48 tracked files were checked against the frozen base Git blobs.
Review panel
6/6 reviewed — full panel. GLM 5.3 (z-ai/glm-5.3), Qwen 3.8 (qwen38-27b) and DS4 (deepseek-v4-flash) each completed independent correctness and adversarial reviews of this exact head. All six returned APPROVE. Model identities, evidence hashes, complete verdicts and normal stop reasons were verified from the saved receipts. No prior-revision vote was counted. No unresolved material dissent.
Limits and remaining merge gate
No live daemon, network or payment round trip was run. Signed quote bytes remain opaque to these SDKs; mock-backed tests do not prove live end-to-end behaviour. This approval covers #369's incremental change, not the integration-preview stack.
The base is still nic/stack-integration-preview; #367 remains an open DO NOT MERGE CI preview. Retarget #369 to main after the real stack lands and revalidate the resulting diff and checks. This code approval is not merge or release authority.
Exact-head CI, refreshed before publication
- Build + test (antd-csharp): SUCCESS
- Test (PHP 8.2): SUCCESS
- Test (PHP 8.3): SUCCESS
- Test (PHP 8.4): SUCCESS
- Split + consume as a Composer package: SUCCESS
Adds the optional signed quotes to pointer prepare in C# and PHP. The other 12 SDKs already have them. Hermes flagged the gap as a non-blocking API-parity follow-up on #328 (C#) and #334 (PHP).
Stacked on #367 (base
nic/stack-integration-preview), because the pointer code lives in the fan-out PRs. This PR doesn't change any reviewed fan-out PR, and it gets retargeted tomainonce #367 lands.Contract
include_signed_quotesonPOST /v1/pointers/prepare/PointerService.Prepare. It's opt-in and off by default, and the SDKs send it only when true, as Kotlin and JS do.signed_quotesin the result: present only when asked for and payment is required, otherwise an empty list.grpc/service.rs~146-165).SignedQuoteEntry.API (additive, source-compatible)
C#
PointerPrepareRequest.IncludeSignedQuotes { get; init; }. TheCreate/Update/Transferfactories take a trailingbool includeSignedQuotes = false.PointerPrepareResult.SignedQuotes(List<SignedQuoteEntry>, default empty).record SignedQuoteEntry(string QuoteHash, string Quote, string? CommitmentSidecar = null).IAntdClient.PointerPrepareAsyncare unchanged.PHP
bool $includeSignedQuotes = falseonPointerPrepareRequestand its factories.toArray()adds the key only when true.array $signedQuotes = []onPointerPrepareResult.readonly class SignedQuoteEntry.Tests
dotnet testpassed 315 of 315. There are 4 new tests: REST flag omitted vs sent, entries with and without a sidecar, gRPC flag mapping, and gRPC bytes→base64 through the existing mock pointer service.testPrepareSignedQuotesFlagSentOnlyWhenTruecovers the default, true, both entry shapes and the async path.Refs V2-1568.
🤖 Generated with Claude Code