Skip to content

feat(antd-csharp, antd-php): signed quotes on pointer prepare - #369

Merged
Nic-dorman merged 3 commits into
mainfrom
nic/pointers-signed-quotes-cs-php
Oct 19, 2026
Merged

Nic-dorman merged 3 commits into
mainfrom
nic/pointers-signed-quotes-cs-php

Conversation

@Nic-dorman

Copy link
Copy Markdown
Member

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 to main once #367 lands.

Contract

  • include_signed_quotes on POST /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_quotes in the result: present only when asked for and payment is required, otherwise an empty list.
  • The quote and sidecar bytes are base64 on both transports. gRPC bytes are re-encoded to match REST (daemon grpc/service.rs ~146-165).
  • Neither SDK had a signed-quote type yet, not even for upload prepare, so each gets a new SignedQuoteEntry.

API (additive, source-compatible)

C#

  • PointerPrepareRequest.IncludeSignedQuotes { get; init; }. The Create/Update/Transfer factories take a trailing bool includeSignedQuotes = false.
  • PointerPrepareResult.SignedQuotes (List<SignedQuoteEntry>, default empty).
  • record SignedQuoteEntry(string QuoteHash, string Quote, string? CommitmentSidecar = null).
  • The positional record constructors and IAntdClient.PointerPrepareAsync are unchanged.

PHP

  • A trailing bool $includeSignedQuotes = false on PointerPrepareRequest and its factories. toArray() adds the key only when true.
  • A trailing array $signedQuotes = [] on PointerPrepareResult.
  • New readonly class SignedQuoteEntry.

Tests

  • C#: dotnet test passed 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.
  • PHP: PHPUnit 10.5 on PHP 8.3 ran 197 tests and 983 assertions with 0 failures; the 2 skips are live tests. The new testPrepareSignedQuotesFlagSentOnlyWhenTrue covers the default, true, both entry shapes and the async path.

Refs V2-1568.

🤖 Generated with Claude Code

Nic-dorman and others added 2 commits October 19, 2026 09:40
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 dirvine left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 --check passes; 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

Comment thread antd-csharp/Antd.Sdk/PointerModels.cs Outdated
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 dirvine left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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, Update and Transfer retain their original three-/three-/two-parameter signatures and implementations. Signed-quote opt-in uses with { 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.dll with the current-head assembly. All three factories and their legacy delegates run successfully without recompiling the consumer. The previous CS0123 and MissingMethodException failures 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 --check passes; 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

@Nic-dorman
Nic-dorman changed the base branch from nic/stack-integration-preview to main October 19, 2026 16:19
@Nic-dorman Nic-dorman closed this Oct 19, 2026
@Nic-dorman Nic-dorman reopened this Oct 19, 2026
@Nic-dorman
Nic-dorman merged commit 14b3c43 into main Oct 19, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants