Skip to content

feat: let adopters put a vendor-namespaced ext on task envelopes and reads - #2861

Open
LukasGoTom wants to merge 1 commit into
adcontextprotocol:mainfrom
gotom-io:feat/task-handoff-ext
Open

feat: let adopters put a vendor-namespaced ext on task envelopes and reads#2861
LukasGoTom wants to merge 1 commit into
adcontextprotocol:mainfrom
gotom-io:feat/task-handoff-ext

Conversation

@LukasGoTom

Copy link
Copy Markdown

Problem

A seller that hands off to a task often already knows a vendor-side identity for the work — an order number, a campaign page, a ticket — and wants the buyer to see it while the task is still submitted. Today the framework leaves no compliant place for that:

  • dispatchHitl hard-codes the submitted envelope as { status: 'submitted', task_id }, although the spec's submitted branch (create-media-buy-response, sync-creatives-response, …) declares ext.
  • get_task_status / tasks_get / list_tasks project only spec fields off the TaskRecord, so a registry cannot add anything on reads either.
  • result is by spec the terminal artifact, so it cannot carry anything before completion.

Change

  • TaskHandoffOptions.ext — an optional, vendor-namespaced extension object. dispatchHitl echoes it verbatim on the submitted envelope, in both settlement modes.
  • TaskRecord.ext — projected as ext by get_task_status, tasks_get and list_tasks items. The built-in registries never persist it; a decorating registry attaches it at read time (that is how we use it: the media buy a booking task holds, read from our own ledger).

Doc comments state the contract: keys sit under a vendor namespace (ext.acme), never a spec field such as media_buy_id, which stays on the terminal artifact.

Tests

  • server-decisioning-mock-seller: the envelope echoes ext when the adopter passes one and omits it otherwise; no top-level media_buy_id leaks.
  • server-create-adcp-server: a decorating registry's ext shows up on get_task_status and on list_tasks items.

npm run build and both suites pass (173 tests). Prettier clean.

🤖 Generated with Claude Code

…reads

The spec's submitted branch declares `ext`, and the task-status responses are
open objects, but the framework hard-codes the submitted envelope as
{ status, task_id } and projects only spec fields on task reads. A seller that
already knows a vendor-side identity when it hands off (an order number, a
campaign page) therefore had nowhere compliant to surface it while the task
runs — `result` is terminal-only by spec.

- `TaskHandoffOptions.ext`: echoed verbatim on the submitted envelope by
  dispatchHitl (both settlement modes).
- `TaskRecord.ext`: projected as `ext` by get_task_status, tasks_get and
  list_tasks items. The built-in registries never persist it; a decorating
  registry attaches it at read time.

Keys are expected to sit under a vendor namespace (`ext.acme`), never a spec
field such as `media_buy_id`, which stays on the terminal artifact.
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

IPR Policy Agreement Required

@LukasGoTom — thanks for the contribution. Before this PR can be merged, the AgenticAdvertising.Org IPR Policy requires your agreement.

To agree, post a new comment on this PR with the exact phrase:

I have read the IPR Policy

Your signature is recorded once and covers all contributions to AAO repositories. See signatures/README.md for what gets recorded and why.

* never a spec field such as `media_buy_id` — those belong on the terminal
* artifact. Not persisted; a registry decorator may re-attach it on reads.
*/
ext?: Record<string, unknown>;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

MUST FIX: No changeset in this PR. It touches src/lib/** (non-generated) and adds new public API surface — TaskHandoffOptions.ext here, TaskRecord.ext in task-registry.ts, plus new ext projection on get_task_status/tasks_get/list_tasks. Per the repo's changeset-vs-wire-impact rule, a missing .changeset/*.md on a src/lib/** change is a blocking finding, and without it the feature never ships to npm. Additive new optional fields → minor. Run npm run changeset.

@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: Request changes

Request changes — 1 blocking finding.

Blocking findings

  • .changeset/*.md (missing) — New public API added under src/lib/** (TaskHandoffOptions.ext, TaskRecord.ext) without a changeset. Per the mandatory changeset-vs-wire-impact rule, a missing .changeset/*.md for a src/lib/** change is a high finding.

The code itself is clean and consistent with witness-not-translator: ext is echoed verbatim on the submitted envelope in both settlement modes and projected on get_task_status/tasks_get/list_tasks, with tests covering echo, omit, and the decorating-registry read path. The only blocker is the missing changeset for the new public API surface — add a .changeset/*.md entry (minor, since this adds new optional public fields) to resolve.

Blocking findings

  • (missing) .changeset/*.md — new public API (TaskHandoffOptions.ext, TaskRecord.ext) added under src/lib/** with no changeset; high per changeset-vs-wire-impact rule

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.

1 participant