carousell/rctp

Draft 0.4 proposal: Listing Terms and Agent Grants

Status: adopted for v0.2 on 27 October 2026 (#21); superseded by Draft 0.4, which is the normative text. Where this proposal and the draft differ, the draft wins. This proposal keeps the reasoning. · Proposed 20 October 2026 · Replaces Draft 0.3 section 4 (Seller Mandate) if adopted · Resolves A-1 to A-14 in ../AMBIGUITIES.md · Revised 21 October: section 13 aligns the proposal with UCP and AP2 and overrides earlier sections where they differ · Incorporated into the Draft 0.4 editor's draft, which is the text to review; this proposal keeps the reasoning

Section numbers in brackets, such as [4.1], refer to Draft 0.3. Key words follow BCP 14 and apply to the proposed text only.

Summary

  • Two objects replace the Seller Mandate. An Agent Grant says which agent may act for which seller and with which verbs. Listing Terms say what the seller will accept for one item.
  • The seller sets terms once per item, when they ask their agent to list it. The platform holds the terms privately and enforces them on every call. No agent, buyer or seller, ever receives the floor.
  • Buyers get a deterministic answer. Below the floor: refused, with the seller's counter if they set one. At or above: delivered to the seller agent, which negotiates.
  • Terms adapt per category through term sets: a floor everywhere, plus deposits, inspections or delivery windows where the category needs them.
  • The grant is local to the platform. It is an OAuth 2.0 grant bound to the agent's key, not a verifiable credential. Revocation takes effect on the next call, with no status list. Portable credentials remain for facts that travel: identity [5] and items [6].
  • All fourteen v0.1 ambiguities close. Five disappear with the mandate, nine get a firm rule (section 9).
  • Minimum core on UCP and AP2 (section 13). RCTP reuses every verb and noun UCP or AP2 already defines, and keeps five things of its own: offers, Listing Terms, the decision, signed proof of who did what, and portable credentials.

1. Why change

Peer review found the mandate confusing, and the v0.1 build shows why. The mandate is signed once, at connect time, but it keys price_floor by listing ID [4.1]. A listing the agent creates later has no floor: buyer offers on it bypass the agent and reach the seller as ordinary marketplace offers, and the agent's own counters and accepts are refused not_in_scope (A-7). The v0.1 seller-agent sample lists an item and then cannot negotiate on it. The only fix in Draft 0.3 is a fresh consent on the issuer's page for every new listing, after the seller has already approved the listing itself.

The mandate also bundles three things with different lifecycles:

Bundled in the mandate today Changes when Belongs to
Which agent acts for the seller, and with which verbs Rarely: connect, disconnect The seller's account
Floor, counter, reprice band, deposits Every time an item is listed or repriced The listing
Offer budget, approval surfaces, timeouts Never per seller Platform policy

Three questions put to the editors on 18 October settled the direction:

  1. Will a seller's permission ever be enforced by a party other than the platform that issued it? Not likely. A verifiable credential buys nothing here; a platform-local grant is enough.
  2. May the seller agent accept within the terms without asking the seller each time? Maybe. It stays a per-seller choice, with ask as the default.
  3. Is a floor enough, or do terms also need an auto-accept price? A floor is enough, but terms must vary by category.

This narrows repository decision 4 (multi-issuer) in ../README.md: it keeps applying to portable credentials [5, 6], and no longer to the seller's permission for an agent.

2. The model

sequenceDiagram
    autonumber
    actor S as Seller
    participant SA as Seller agent
    participant P as Platform (enforcement point)
    participant BA as Buyer agent
    S->>P: Connect agent once (consent page)
    P-->>SA: Agent Grant, bound to the agent's key
    S->>SA: "List my camera"
    SA->>P: listing.create (item, list price)
    P-->>SA: 202 ask
    S->>P: Hosted page: confirm item, set terms (floor 300), passkey
    P-->>SA: Listing live (terms stay with the platform)
    BA->>P: offer.create 250
    P-->>BA: 403 below_floor, counter 340
    BA->>P: offer.create 320
    P-->>SA: Offer delivered
    SA->>P: offer.counter 335
    P-->>BA: Counter 335
    BA->>P: offer.create 335
    SA->>P: offer.accept
    P-->>BA: Single-use checkout

The seller touches the system twice: once to connect the agent, once per item to approve the listing with its terms. Draft 0.3 already makes listing.create an ask in every category [15.2], so the second touch adds no step.

3. Agent Grant (replaces [4])

3.1 What it is

An Agent Grant is the seller's permission for one agent to act for them on one marketplace. It is a record held by the marketplace, issued through OAuth 2.0, and presented as an access token bound to the agent's key. It carries no prices and no listings.

Field Content
grant_id grt_ followed by a unique identifier
seller Pairwise pseudonymous seller ID, scoped to the marketplace and the operator. No personal data (INV-9).
operator_id, agent_id From the operator record [8]
cnf.jkt RFC 7638 thumbprint of the agent key the grant is bound to
verbs The registered actions the agent may use (section 5.3). The fixed forbids can never be granted.
tiers Optional per-verb overrides, only within each verb's allowed tiers (section 5.3)
consent Consent screen version and time; identity assurance of the account. Kept by the marketplace, not in the token.
iat, exp Issue and expiry times. Lifetime is marketplace policy; RECOMMENDED at most 90 days, renewed by refresh.
status active, revoked or expired

3.2 Issuance

  1. The marketplace's authorization server MUST issue a grant only after the seller confirms it on a Trusted Surface that names the agent, its operator, every verb with its tier, and the expiry, in plain language.
  2. Issuance uses the authorization code flow with PKCE (RFC 7636) and RFC 9396 authorization details of type dev.rctp.agent_grant carrying verbs and tiers.
  3. The consent screen MUST NOT ask for prices. Prices belong to Listing Terms (section 4).

3.3 Use on every call

  1. The agent sends the grant's access token in Authorization: Bearer <token>. The token format is the marketplace's choice: opaque, or a JWT access token (RFC 9068).
  2. The token MUST be sender-constrained with cnf.jkt (RFC 7800). The enforcement point MUST check that the RFC 9421 keyid equals cnf.jkt and that the request signature covers authorization. No separate DPoP proof is needed: every request is already signed with the bound key.
  3. The enforcement point MUST look the grant up on every call and refuse a grant that is unknown, revoked, expired or bound to another key (section 7).

3.4 Revocation

  1. The seller can revoke a grant at any time in the marketplace app. Operators can revoke their own tokens (RFC 7009).
  2. A revoked or expired grant MUST fail the next signed call (INV-7). Because the enforcement point reads the grant's live status, no status list and no cache lifetime are involved.

3.5 Where each mandate claim goes

Mandate claim [4.1] Goes to
accountable_human Grant consent, held by the marketplace
agent Grant operator_id, agent_id, cnf.jkt
inventory_scope Implicit: the seller's own listings that have terms (section 4.6)
commercial (price_floor, preset_counter, reprice_band) Listing Terms
actions Grant verbs and tiers, within registry limits
ask (surfaces, timeout) Platform policy, published in discovery
offer_budget Platform policy (section 5.4)
counterparty_requirements, handover_windows, settlement_requirements Listing Terms, where the category's term set defines them

4. Listing Terms (new)

4.1 What they are

Listing Terms are the seller's private negotiating envelope for one listing. The seller sets them once, on a Trusted Surface, when they approve the listing their agent proposed. The platform stores them, enforces them on every call, and never discloses the private ones to any agent or counterparty.

4.2 Setting terms

  1. The seller agent calls listing.create with the item and its public list price. It sends no terms.
  2. listing.create is always ask (section 5.3). The 202 response carries the approval request [9.4]; its display text names the item and list price only.
  3. The hosted approval page shows the listing and a terms form built from the category's term set (section 4.3). The seller fills in the terms and approves with their passkey.
  4. The approval challenge MUST bind the listing hash and terms_commitment (section 4.5). The platform MUST store exactly the terms the seller signed.
  5. The listing goes live. The seller agent learns the outcome, the term set ID and terms_commitment, never the values.

Listings a seller creates by hand in the marketplace app follow the same rule: the app shows the same terms form.

4.3 Term sets per category

A term set defines which terms a category takes, their types and limits, and which check enforces each one. Term sets live in a new registry, term-sets, and are versioned (goods.small/1). A listing records the term set version it was approved under.

Every term set MUST include floor. Everything else is per category.

Term Type Visibility Enforced at goods.small/1 vehicles/1 property.rental/1
floor money private offer.create, offer.counter, offer.accept, listing.reprice required required required
counter money private sent with below_floor optional optional —
protected_payment_only boolean public checkout [9.2] default true default true default true
deliver_within_days integer public refunds (section 6) default 7 — —
deposit_pct percent public deal.accept_deposit — optional required
inspection_before_deposit boolean public deal.accept_deposit — default true —
handover_windows time slots public handover.book_slot — optional optional

Each term carries constraints from a closed set, so every platform checks them the same way:

Constraint Meaning Example
min, max Bounds on the value deposit_pct between 5 and 50
gt_term, lt_term Greater or less than another term counter gt_term: floor
lte_list_price At most the listing's public price floor
min_ratio_of_list_price At least this share of the public price floor ≥ 0.2 × list price, to catch typos

A sketch of one entry:

{
  "id": "goods.small/1",
  "categories": ["mobile-phones", "cameras", "consoles", "small-electronics"],
  "terms": [
    { "name": "floor", "type": "money", "visibility": "private", "required": true,
      "constraints": { "lte_list_price": true, "min_ratio_of_list_price": 0.2 } },
    { "name": "counter", "type": "money", "visibility": "private", "required": false,
      "constraints": { "gt_term": "floor", "lte_list_price": true } },
    { "name": "protected_payment_only", "type": "boolean", "visibility": "public", "default": true },
    { "name": "deliver_within_days", "type": "integer", "visibility": "public", "default": 7,
      "constraints": { "min": 1, "max": 30 } }
  ]
}

Rules:

  1. A platform MUST advertise the term sets it enforces, with versions, in its UCP profile under dev.rctp.terms.
  2. A platform MUST refuse terms that break a constraint, with 422 terms_invalid, before the seller can approve them.
  3. A term named x-… is an extension. It MUST NOT change a decision unless the platform advertises it.
  4. Adding a term set, or a term to a new version of a set, needs no change to the protocol.

4.4 Changing terms

  1. listing.set_terms changes a listing's terms. Its only allowed tier is ask: the seller sets the new values on the hosted page, as in section 4.2.
  2. listing.reprice changes the public list price. A new price below the floor MUST be refused with below_floor.
  3. Offers already open are re-evaluated against the new terms the next time any party acts on them.

4.5 Keeping private terms private

  1. Private terms MUST NOT appear in listing data, offers, decisions, approval request bodies, webhooks, logs a partner can read, or attestation entries (INV-1).
  2. Attestation entries record terms_commitment instead: SHA-256 over the RFC 8785 canonical JSON of {salt, terms}, where salt is 128 random bits kept by the platform. A bare hash of a small number can be reversed by trying every price; the salt prevents that.
  3. The platform discloses terms only to the seller, in the marketplace app, and to an arbiter in a dispute the seller is party to.

4.6 Listings without terms

A listing with no approved terms is not open to agent negotiation. Offers on it reach the seller as ordinary marketplace offers, outside RCTP. A seller agent acting on it is refused not_in_scope.

5. Decisions (replaces the check order in [9])

5.1 Check order

Step Check Refusal
1 Signature and operator 401 signature_invalid, operator_unknown
2 Grant: known, bound to the signing key, active, verb granted 401 grant_invalid; 403 grant_revoked, grant_expired, action_forbidden
3 Listing: belongs to the grant's seller, has terms, is open 403 not_in_scope
4 Counterparty requirements, where the term set has them (later levels) 403 counterparty_requirements_unmet
5 Terms: floor, offer budget, other enforced terms 403 below_floor (+ counter); 429 offer_budget_exhausted
6 Tier: the grant's override or the registry default 200 auto; 202 ask

Buyer calls skip step 2: the buyer's permission comes from its own AP2 mandate [9.3].

5.2 Offers

Call By Below the floor At or above the floor
offer.create Buyer agent 403 below_floor, with counter if the seller set one; counts against the offer budget 201: delivered to the seller agent
offer.counter Seller agent 403 below_floor Tier, default auto
offer.counter Buyer agent Treated as offer.create at the counter amount
offer.accept Seller agent 403 below_floor Tier, default ask; the seller may choose auto
offer.accept Buyer agent 403 action_forbidden: a counter is an invitation, not a commitment

A buyer who agrees to a seller's counter sends offer.create at that amount. Acceptance always runs offer.accept on the seller side, so an auto counter can never bypass an ask on accept.

5.3 Verbs and tiers

The registry gives each verb a default tier and the tiers a seller may choose. A grant may only pick from the allowed set.

Verb By Default Allowed Notes
listing.create seller agent ask ask Terms are set at this approval
listing.set_terms seller agent ask ask New verb
listing.reprice seller agent auto auto, ask Never below the floor
listing.answer_buyer seller agent auto auto, ask Answers from structured listing facts
offer.create buyer agent — — New verb; checked against terms, no tier
offer.counter seller agent auto auto, ask Never below the floor
offer.accept seller agent ask ask, auto Never below the floor
deal.sign_contract — forbid forbid Fixed (INV-3)
account.update — forbid forbid Fixed (INV-3)

Category defaults for later verbs (handover.book_slot, deal.accept_deposit, passport.disclose_full_report) carry over from [15.2] unchanged.

5.4 Offer budget

  1. The platform MUST count below-floor offers per buyer agent per listing, and MUST also apply a ceiling per buyer operator per listing of N times the per-agent budget. The platform publishes both numbers in discovery.
  2. Past either limit, every offer from that agent, or from that operator, on that listing gets 429 offer_budget_exhausted until the window frees a slot. Above-floor offers are included, so 201-versus-429 cannot reveal the floor.
  3. An operator that rotates agent keys to dodge the per-agent budget still meets the operator ceiling, and breaches its partner terms [8].

6. Starter checkpoints and refunds (amends [7.3] and [16.2])

The Starter set becomes funds_held, accepted, rejected, return_received, released, refunded.

  1. released requires funds_held and then accepted.
  2. rejected carries a reason: not_as_described or not_received.
  3. After rejected with not_as_described, refunded requires return_received, written by the seller or a custodian.
  4. not_received is allowed only once deliver_within_days (from the term set) has passed since funds_held. After it, refunded needs no return.
  5. Any other order fails with 409 release_condition_unmet.
  6. In Starter, not_received rests on the buyer's word. Categories where that is too weak use the verified custody lane [6.4], where a courier signs delivered.

7. Reason codes (amends [12])

Change Reason HTTP When
New grant_invalid 401 The grant is unknown, or not bound to the signing key. Fix the integration.
Renamed from mandate_revoked grant_revoked 403 The seller or operator revoked the grant. Ask the seller to reconnect.
Renamed from mandate_expired grant_expired 403 The grant is past exp. Refresh or reconnect.
New terms_invalid 422 Proposed terms break a term-set constraint
Narrowed not_in_scope 403 The listing is not the grant's seller's, or has no terms

All other Draft 0.3 reasons are unchanged.

8. Invariants

ID Draft 0.3 Proposed
INV-1 A refusal for a low offer says below_floor and never states the floor Private terms never leave the platform. No agent or counterparty receives them. A refusal says below_floor and may carry the seller's counter.
INV-2 An ask that expires is a decline Unchanged
INV-3 deal.sign_contract and account.update are always forbid Unchanged
INV-4 Only the seller signs approvals Unchanged
INV-5 No agent input can change a tier, floor or budget; only a new mandate can Only the seller, on a Trusted Surface, can create or change a grant or listing terms. No agent input can.
INV-6 An accepted offer becomes a single-use, business-signed checkout Unchanged
INV-7 A revoked or expired mandate fails the next signed call A revoked or expired grant fails the next signed call
INV-8 No custom cryptography Unchanged
INV-9 No personal data in RCTP objects Unchanged

INV-1 moves from a promise about what the platform says to a property of who knows what: the seller agent cannot leak a floor it never received.

9. Resolution of the v0.1 ambiguities

Dissolved means the question no longer exists under this proposal. Resolved means the proposal states the answer as a rule.

ID Issue Question Status Resolution Section
A-1 #2 How does the enforcement point receive the mandate? Dissolved Nothing travels but a key-bound access token. The platform holds the grant and the terms. 3.3
A-2 #3 Is sending the mandate a presentation needing SD-JWT+KB? Dissolved No credential is presented to the enforcement point. Proof of possession is the RFC 9421 signature with keyid = cnf.jkt. Key-binding JWTs [3.2(1)] still apply to credentials agents present to each other [5, 6]. 3.3
A-3 #4 Which reason for an unverifiable mandate? Resolved grant_invalid (401) for unknown or unbound grants; grant_revoked, grant_expired (403). Each has one remedy. 7
A-4 #5 May a refusal's counter equal the floor? Resolved The term set requires counter gt_term: floor; such terms are refused terms_invalid before approval. The enforcement point still sends counter only when it is above the floor. 4.3
A-5 #6 After the budget is spent, do above-floor offers pass? Resolved No: every offer gets 429 until a slot frees. The budget is counted per buyer agent with an operator ceiling, so one abusive user no longer locks out a whole operator. 5.4
A-6 #7 Which action does an inbound offer evaluate? Resolved New verb offer.create, checked against the terms, with no tier. 5.2, 5.3
A-7 #8 Is a listing in scope by ID or category? What if it has no floor? Dissolved Scope is the seller's own listings that have terms. Every term set requires a floor, so a listing with terms always has one. 4.6
A-8 #9 Does the floor apply to the seller's own counter? Resolved Yes, and to listing.reprice as well. 5.2, 4.4
A-9 #10 Who may accept? Resolved Only the seller side, under offer.accept. A counter is an invitation; the buyer agrees by offer.create at that amount. 5.2
A-10 #11 Which reason for an approval response after expires_at? Resolved The late response is refused approval_invalid; the approval is reported expired with approval_timeout; the action is declined (INV-2). [9.4] as clarified
A-11 #12 Status-list caching versus "the next call fails" Dissolved Grants are checked live; no status list is involved. Status lists stay for portable credentials, where the 60-second lifetime rule [3.3] applies. 3.4
A-12 #13 What must precede refunded? Resolved rejected with a reason. not_as_described needs return_received first; not_received is allowed only after deliver_within_days. 6
A-13 #14 How is the seller's passkey registered? Resolved Out of RCTP's scope: the seller's existing marketplace account passkey is the approval key. The enrolment ticket stays a sandbox feature. —
A-14 #15 No REST routes for checkout, checkpoints or fixed forbids Resolved Section 11 of the draft adds POST /deals (redeem a checkout), POST /deals/{id}/checkpoints and POST /listings/{id}/terms (opens a listing.set_terms approval). The always-refused routes stay test hooks in the binding, not the draft. [11] as amended

10. Conformance

Vector Change
V1, V3, V7 Floors come from Listing Terms instead of the mandate. Expectations unchanged.
V4 Budget per buyer agent, plus a new case for the operator ceiling
V6 A revoked grant fails the next signed call
V10 (new) A listing the seller agent creates is negotiable as soon as the seller sets terms, with no new consent
V11 (new) Private terms never reach any agent: listing data, decisions, approval request body, webhooks and attestation entries
V12 (new) Terms with counter at or below floor are refused terms_invalid
V13 (new) After rejected with not_as_described, refunded without return_received fails with release_condition_unmet

11. Impact on the reference implementation

Area Change
Schemas Remove mandate.seller.open.1. Add agent-grant, listing-terms, term-set. listing-create-request is unchanged; approval request display loses any price but the list price.
Registries New term-sets. actions gains allowed_tiers, offer.create and listing.set_terms. Reason codes as in section 7.
Gateway (Go) The mandate package shrinks to grant lookup. New terms store with salted commitments. Decision engine reads terms by listing. Hosted page renders the terms form from the term set.
Sandbox The mock issuer becomes an authorization server that issues grants. The status list and SD-JWT minting for mandates go.
SDKs SellerConnect returns a grant token; RctpClient sends Authorization and signs it. decodeMandate and verifyMandate are removed until credentials [5] arrive.
Docs Quickstart, concepts, decisions and errors, security, partner profile.

Net effect: less code. The credential, status-list and per-call mandate paths go; a terms store and one form come in.

12. Open questions for review

  1. Agent-suggested terms. May the seller agent propose a floor that pre-fills the form? It helps sellers price, but the agent would then know the suggested value, and sellers may anchor on it. Proposed: not in Draft 0.4.
  2. Default tier for offer.accept. ask is proposed. Is auto within terms a sensible default for low-value categories?
  3. First term sets. goods.small/1 and vehicles/1 are proposed for Draft 0.4; property later.
  4. Grant lifetime. At most 90 days with refresh is proposed. Should the platform also expire grants after a period of no use?
  5. Disclosure to the seller's own agent. Should a seller be able to opt in to their agent seeing the floor? Proposed: no. Negotiating blind costs the agent little, and it removes the leak path.

13. Revision: minimum core on UCP and AP2

Principle: simplicity is the ultimate complexity. RCTP defines the minimum a marketplace must implement and run. Categories and logistics chains extend it through open values, not new protocol. Where UCP or AP2 already defines a verb or noun, RCTP reuses it. Checked against UCP at commit f2626c2 (20 October 2026) and AP2 v0.2.

13.1 Reused, not redefined

Need Defined by RCTP adds
Agent identity, request signing UCP Signatures: UCP-Agent, keys in the /.well-known/ucp profile, RFC 9421 legal_entity and incident_contact in the profile
Seller's permission for an agent UCP Identity Linking: OAuth 2.0 at the marketplace, scopes {capability}:{scope} with per-scope policy RCTP scopes; a tier (auto, ask) in each scope's policy; token bound to the agent key
Buyer questions UCP Ask Seller agent answers from structured facts only
Delivery method, carrier, windows, cost UCP Fulfillment (open method types) Nothing; marketplaces add types such as meetup or locker
When payment is due UCP Payment Terms Nothing
Paying into escrow AP2 Payment Mandate: payment.allowed_payees Nothing; the payee is the holder of funds
Shipped, delivered, returned, refunded UCP Order: fulfillment events and adjustments (open types) Who signs each one (13.2)
Webhooks UCP signed webhooks (Standard Webhooks headers, RFC 9421) Nothing

13.2 RCTP's core

Nothing in UCP or AP2 covers these:

  1. Offers. dev.rctp.offer, a UCP checkout extension: create, counter, accept, decline. UCP has no negotiation; discussion #502 is open and invites vendor-namespaced prototypes. RCTP's offer is one.
  2. Listing Terms (section 4).
  3. The decision: auto, ask or forbid, with one registered reason.
  4. Signed proof. UCP order events are asserted by the business alone. RCTP attests who did what (first_hand by the carrier, holder or buyer agent; relayed by the marketplace) and which proofs release money.
  5. Portable credentials: party bands, identity facts, item passport [5, 6]. UCP and AP2 do not describe the person or the item.

13.3 Fixed rules

Only these are fixed. Everything else is an open value named by reverse domain, as in UCP.

  1. The platform enforces the seller's terms, not the agent.
  2. No answer means no.
  3. Private terms never reach any agent.
  4. Money moves only on signed proof.
  5. Facts about people, never identities.
  6. No custom cryptography.

13.4 Review decisions

Question Decision
Is RCTP the place to book shipping? No. RCTP covers proof and deal terms; booking, quotes and tracking stay in UCP Fulfillment and carrier APIs.
Who holds the buyer's money? A role, not a company: the AP2 payee, either the marketplace or a licensed payment partner. It signs funds_held, release and refund.
When are carrier- or inspector-signed checks required? Not in the core. An optional term in a category's term set, used by marketplaces that offer the category.
Can a seller require buyer identity or history? Yes, as a requirement in Listing Terms.

13.5 Changes to this proposal

  • Deal Terms. An offer carries a price plus a fulfillment option (UCP Fulfillment) and a payment term (UCP Payment Terms) chosen from those the listing allows. The platform enforces the choice like the floor. The checkout binds all of it.
  • Listing end date. Every term set gains available_until.
  • Operator record, key directory, RCTP-Operator: replaced by the UCP profile and UCP-Agent.
  • Agent Grant (section 3): a UCP Identity Linking grant with RCTP scopes; section 3.3 binding unchanged.
  • Webhooks: UCP signed webhooks replace the RCTP format.
  • Checkpoints (section 6): shipping, delivery, returns and refunds are UCP fulfillment events and adjustments, attested by RCTP. RCTP keeps only funds_held, accepted, rejected and released. A refund after not_as_described needs an attested, completed return adjustment.
  • UCP version is pinned in the binding.
  • Sections 3, 6, 7, 10 and 11 are rewritten to match once the review adopts this section.

13.6 Open for review

  1. Draft 0.3 [9.2(4)] forbids refusing a buyer for having no trading history when the deal uses the verified custody lane. A fixed rule (13.3) or a recommended default?
  2. RCTP scope names, for example dev.rctp.listing:create, dev.rctp.offer:counter, dev.rctp.offer:accept.
  3. The UCP version to pin.
  4. When to propose dev.rctp.offer to UCP discussion #502: after this review, or after v0.2 ships.

Source: spec/proposals/draft-0.4-listing-terms-and-agent-grants.md