Skip to content

feat(negotiation): add proposal refinement APIs - #2551

Merged
bokelley merged 4 commits into
mainfrom
sdk-2542
Aug 16, 2026
Merged

feat(negotiation): add proposal refinement APIs#2551
bokelley merged 4 commits into
mainfrom
sdk-2542

Conversation

@bokelley

Copy link
Copy Markdown
Contributor

Summary

  • add typed AdCP 3.2 refine_proposals buyer APIs with capability-aware preflight and verified results
  • add first-class seller registration with scoped storage, replay-safe dispatch, and atomic CAS-backed finalization
  • add orchestration helpers for retries, counteroffer selection, hold expiry, and acceptance
  • document migration from legacy get_products refinement and provide runnable buyer/seller examples

Why

AdCP 3.2 moves structured proposal negotiation into refine_proposals. The SDK needs a safe default path that preserves idempotency, tenant isolation, immutable proposal lineage, and all-or-nothing finalization for both buyer and seller agents.

Closes #2542.

Validation

  • npm run typecheck
  • npm run typecheck:examples
  • npm run build:lib
  • proposal negotiation unit/integration tests (61 passing)
  • npm run test:protocols
  • npm run test:node:fast (13,177 passing, 7 skipped)

Review

Protocol, code-quality, security, and adopter-DX expert passes were run before publication. Their convergent findings drove the first-class server pipeline, authenticated scope, CAS finalization, complete runtime validation, successor identity, and Unicode digest hardening in this revision.

@bokelley
bokelley enabled auto-merge (squash) August 16, 2026 05:08
Comment thread src/lib/utils/jcs.ts Outdated
Comment thread src/lib/negotiation/verification.ts
aao-secretariat[bot]
aao-secretariat Bot previously approved these changes Aug 16, 2026

@aao-secretariat aao-secretariat Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Ladon verdict: Approve

Approve — AdCP 3.2 proposal negotiation added as a transitional forward surface with correct minor changeset, official MCP client usage, and ~1,500 lines of tests covering retry-key reuse, CAS double-hold prevention, immutable snapshots, and reason-code precedence.

Medium findings (non-blocking):

  • src/lib/utils/jcs.ts:141 — JCS canonicalize now throws on lone surrogates; shared by idempotency hashing and signing
  • src/lib/negotiation/verification.ts:359 — Response verifier enforces closed key sets while types declare open [key: string]: unknown

Decision trace: No critical/high findings (row 1 n/a). gated_paths is false (row 2 n/a). high_risk false, no deletions (rows 3, 5 n/a). Both medium findings are category verification/hashing logic — not data-loss/schema/infra (row 4 n/a). No prior decision (row 6 n/a). No no-auto-approve team match (row 7 n/a). Only 2 medium findings, below the 3-medium threshold (row 8 n/a). Falls through to row 9 → approve.

Note: review_decision is REVIEW_REQUIRED, but since gated_paths is false, row 2 does not apply and standard GitHub branch protection (not Ladon) governs the required-reviewer gate. The two medium findings are worth a maintainer glance — the JCS surrogate change and the closed-key-set verifier both have blast radius beyond the proposal path — but neither is blocking.

Medium findings

  • src/lib/utils/jcs.ts:141 — JCS canonicalize now throws on lone surrogates; shared by idempotency hashing and signing
  • src/lib/negotiation/verification.ts:359 — Response verifier enforces closed key sets while types declare open [key: string]: unknown

aao-secretariat[bot]
aao-secretariat Bot previously approved these changes Aug 16, 2026

@aao-secretariat aao-secretariat Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Ladon verdict: Approve

Approve — delta since prior approve is clean.

This subsequent review looks at the schemas-ensure / sync-schemas delta backing the AdCP 3.2 proposal-negotiation feature. The new hasProposalNegotiationCache guard mirrors the existing STABLE_3_0 pattern (early-exit conjunction + conditional sync push), and the final pointLatestAtCurrent restore keeps the latest symlink pinned to ADCP_VERSION. No new correctness, security, wire-shape, or changeset issues in the delta.

The two prior medium findings (jcs.ts:141 lone-surrogate throw; verification.ts:359 closed key-set enforcement) are outside this delta and were not re-surfaced; the changeset (.changeset/add-proposal-negotiation.md) is present for the src/lib/** changes.

No blocking findings, no medium findings in the current run. gated_paths false, high_risk false, no no-auto-approve team match. Falls through to row 9.

aao-secretariat[bot]
aao-secretariat Bot previously approved these changes Aug 16, 2026

@aao-secretariat aao-secretariat Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Ladon verdict: Approve

Approve — clean diff, no blocking or medium findings.

This is a subsequent review after a prior approve. The only delta since the prior head is a single cosmetic change in scripts/schemas-ensure.ts: the six-operand if (currentV3Ok && stableV30Ok && ...) guard collapsed from six lines to one, with the same operands in the same order and no behavior change.

Checks confirmed:

  • No critical/high/medium findings in this run.
  • Changeset present (.changeset/add-proposal-negotiation.md) covering the src/lib/** changes, so changeset-vs-wire-impact is satisfied.
  • No no-auto-approve team match; gated_paths is false; high_risk is false.

None of decision-table rows 1–8 fire, so the outcome falls through to row 9 (approve).

@aao-secretariat aao-secretariat Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Ladon verdict: Approve

Approve.

Checked the delta scoping of JCS strictness: the shared canonicalize in jcs.ts is restored to main's lone-surrogate-preserving behavior (net change vs main is comment-only), and strict I-JSON validation is correctly relocated to the proposal boundary via assertIJsonString/canonicalProposalTerms. verification.ts now canonicalizes commercial_terms once for both the digest comparison and the distinctness set, closing a real accessor-getter TOCTOU. types.ts index-signature removals are compile-time-only with no runtime/witness impact.

Gate checks: no no-auto-approve team match; gated_paths is false; high_risk is false. Changeset present (.changeset/add-proposal-negotiation.md) covering the src/lib/** changes. No witness-not-translator or transport-client concerns. Prior decision was also approve.

No critical, high, or medium findings. Falls through to row 9.

@bokelley
bokelley merged commit a719f6c into main Aug 16, 2026
32 checks passed
@bokelley
bokelley deleted the sdk-2542 branch August 16, 2026 06:51
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.

feat(negotiation): add first-class buyer and seller proposal APIs

1 participant