Skip to content

fix(addie): revalidate credential authority before mutation dispatch - #7476

Draft
bokelley wants to merge 321 commits into
mainfrom
conductor/addie-authority-epoch-dispatch
Draft

bokelley wants to merge 321 commits into
mainfrom
conductor/addie-authority-epoch-dispatch

Conversation

@bokelley

@bokelley bokelley commented Sep 13, 2026 •

Copy link
Copy Markdown
Contributor

Refreshes the unique #7476 mutation safeguards on main de70d9952f229442668dc679916cc08f885923b0, after #7450 landed. The current source replaces the obsolete conflicted continuation; the original head 5654b799 remains a merge parent so this is the same PR and branch.

An Addie turn can assemble privileged tools, wait for the model or durable checkpoint, then dispatch after the authenticated credential loses authority. This change binds the final tool surface to the exact credential and rechecks positive local lifecycle, immutable request authority, live WorkOS identity/email, selected organization and conditional platform-admin/committee authority before and after reservation. Missing or uncertain authority fails closed. Web, all seven Slack reservations and Tavus retain committed row receipts; all four shared executors receive the authority check.

A denied action carries an application-owned no-dispatch receipt for its exact reservation. Database settlement and restart replay agree on row ID, tool and parameters. A pre-reservation denial cannot release an older unknown action; an ambiguous reservation commit stays fenced. Existing known local outcomes and typed GitHub receipts retain their current semantics.

Current guarded membership commits bump exact target epochs in their own transaction, including caller-owned deletions. Unchanged provider role/membership-ID refreshes do not invalidate every user's turn. Site-admin grant/revoke audits require exact persisted row receipts and preserve authenticated/canonical actor attribution. Inactive revoke targets return a distinct 409 rather than a misleading 404, retaining the guard and requiring reconciliation.

Validation: the full normal commit gate passed on parent 297f0162005f715656fbe43a28d7cfd4e4ea595b: 1,106 root tests and 12,593 server tests across 752 files, with 31 existing skips, plus both complete typechecks. Focused real PostgreSQL suites passed 331 tests, with final inactive-target and row-scoped replay suites passing 7 and 60 tests respectively. Focused dispatch/authority units passed 98 tests; final Tavus units passed 56. Inventory uses code version 2026.10.6. Earlier failed/interrupted gate receipts remain recorded; the isolated normal gate passed without timeout, assertion or hook changes.

Current head e2b039b29aa80353336300b404eefc733d9b2f45 adds only an integration-fixture correction: preserve the real admin-tool module exports while overriding the existing privilege mock. No production or unit-test bytes changed from the qualified parent. All 20 member-role-policy tests passed against real PostgreSQL; Haiku cleared the small diff. The latest normal commit gate passed 1,106 root tests and both complete typechecks; normal staged-scope detection skipped server units for this integration-only change. Normal pre-push checks passed. The prior CI integration shard failed on the fixture's missing ADMIN_TOOLS export; that failure remains recorded. Fresh exact-head GitHub CI is complete: 31 successful checks, one neutral check and the expected draft AI-review skip. All four canonical, server-unit and integration shards, plus their aggregates, passed. Historical or parent-head results do not substitute for that service gate.

Read-only Sonnet review found no Must Fix and cleared the inactive-target correction against primary contracts. Haiku found no Must Fix; it retains non-blocking review questions about selected-organization mismatch returning a conservative 503 and the shared compatibility type allowing a void reservation receipt. Current production reservers all return receipts; a missing receipt cannot release a reservation. Context hydration conflates definitive absence and lookup uncertainty, so this port preserves fail-closed provenance rather than returning forbidden from an untrusted/missing context. These automated readings are not human security approval.

No migrations, immutable releases, 3.3 or GCS rollout implementation changed. Already-landed positive lifecycle guards remain intact. Historical disabled merge/domain-auto-join/alias-consolidation flows and old credential-grant creation routes are not reintroduced. External WorkOS revocation and local handler entry cannot share a transaction; final live checks reduce but cannot eliminate that timing window. This PR does not close #6827.

Remain Draft. Auto-merge stays off. Do not merge or deploy before human security review and deployment approval.

Existing workspace.

@bokelley
bokelley requested a review from a team September 13, 2026 15:46
@bokelley
bokelley changed the base branch from conductor/secure-exact-credential-admin-auth to main September 13, 2026 15:49
@bokelley bokelley closed this Sep 13, 2026
@bokelley bokelley reopened this Sep 13, 2026
@bokelley
bokelley changed the base branch from main to conductor/secure-exact-credential-admin-auth September 13, 2026 15:49
@bokelley
bokelley changed the base branch from conductor/secure-exact-credential-admin-auth to main September 13, 2026 15:50
@bokelley bokelley closed this Sep 13, 2026
@bokelley bokelley reopened this Sep 13, 2026
@bokelley
bokelley changed the base branch from main to conductor/secure-exact-credential-admin-auth September 13, 2026 15:55
@bokelley
bokelley changed the base branch from conductor/secure-exact-credential-admin-auth to main September 13, 2026 22:37
@bokelley bokelley closed this Sep 13, 2026
@bokelley bokelley reopened this Sep 13, 2026
@bokelley
bokelley changed the base branch from main to conductor/secure-exact-credential-admin-auth September 13, 2026 22:37
@bokelley
bokelley changed the base branch from conductor/secure-exact-credential-admin-auth to main September 13, 2026 22:38
@bokelley bokelley closed this Sep 13, 2026
@bokelley bokelley reopened this Sep 13, 2026
@bokelley
bokelley changed the base branch from main to conductor/secure-exact-credential-admin-auth September 13, 2026 22:39
@bokelley
bokelley changed the base branch from conductor/secure-exact-credential-admin-auth to main September 14, 2026 00:45
@bokelley bokelley closed this Sep 14, 2026
@bokelley bokelley reopened this Sep 14, 2026
@bokelley
bokelley changed the base branch from main to conductor/secure-exact-credential-admin-auth September 14, 2026 00:46
@bokelley
bokelley force-pushed the conductor/secure-exact-credential-admin-auth branch from f853452 to dcabf2c Compare September 14, 2026 00:53
@bokelley
bokelley force-pushed the conductor/addie-authority-epoch-dispatch branch from 3f59fad to 0b2f199 Compare September 14, 2026 02:57
@bokelley
bokelley changed the base branch from conductor/secure-exact-credential-admin-auth to main September 14, 2026 02:57
@bokelley bokelley closed this Sep 14, 2026
@bokelley bokelley reopened this Sep 14, 2026
@bokelley
bokelley changed the base branch from main to conductor/secure-exact-credential-admin-auth September 14, 2026 02:57
@bokelley
bokelley removed the request for review from a team September 14, 2026 02:57
bokelley and others added 30 commits October 8, 2026 20:56
Refs #7777

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
…8059)

* docs(audiences): specify uids[].value wire form for sync_audiences

Refs #6872

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* docs(audiences): scope uids[] not-hashed note to exclude hashed_email

Refs #6872

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
Closes #7345

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
* test(ledger): synchronize concurrent recovery and isolate attempt fixtures

* test(ledger): leave headroom for recovery observation
…t_exclude targeting (#8078)

The training agent now fetches buyer property lists from the referenced list
agent (SSRF-guarded, Bearer only when a token is supplied, cached per session
until cache_valid_until), applies include/exclude to the product's properties
on create and update, and rejects the whole request when a list cannot be
fetched or leaves no eligible inventory. Declares both capability flags and
Product.overlay_support, and resolves the acme-outdoor test-kit lists so the
inventory_list_* storyboards run.

Refs #7911

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
* fix(compliance): correct hosted credentials, probes, and URL audit

* build(openapi): refresh static credential removal operation

* fix(deps): patch sharp librsvg vulnerability

* test: keep storyboard loopback connections alive during validation

* fix(auth): preserve callback gates in OAuth error handling
* fix(ci): retain pending IPR checks during PR bursts

* docs(ci): cite current GitHub concurrency queue support
…h no query (#8076)

* test(compliance): cover step 5 for an empty path with no query

Step 5 reads "If the path is empty AND an authority is present, substitute
`/`". The query is not part of that condition -- it appears only in the
step's illustrative example, `https://host?x=1` to `https://host/?x=1`.

The vector set could not tell the two readings apart. Of its 37 cases
exactly one had an empty path, and that one carried `?x=1`, so an
implementation that gated step 5 on the query passed 37 of 37 while
emitting `https://host` for `https://host`.

Four cases close it: the bare authority, a non-default port, an IPv6
literal, and the empty-query spelling where steps 5 and 7 compose to
`https://host/?`. Measured against the Python SDK, these four fail before
its step-5 fix and pass after it, with the original 37 green throughout.

* test(compliance): add changeset for the step 5 vectors
…7969)

* fix(compliance): correct hosted credentials, probes, and URL audit

* build(openapi): refresh static credential removal operation

* fix(runtime): persist cold-boot idempotency and preserve heartbeat cadence
* fix(compliance): correct hosted credentials, probes, and URL audit

* build(openapi): refresh static credential removal operation

* fix(compliance): restore published 3.0.27 hosted artifacts

* test(compliance): pin registered 3.0 defaults to 3.0.27
… training seller (#8085)

* fix(docs): replace phantom REPORTING_REVISION_NOT_FOUND with REFERENCE_NOT_FOUND in get_media_buy_delivery

The task reference doc named REPORTING_REVISION_NOT_FOUND as the error
code for unknown/inaccessible reporting_revision_id reads. That code
does not exist in the error-code enum; the enum's own MUST rule requires
REFERENCE_NOT_FOUND for typed parameters without a dedicated standard
code. Also adds REFERENCE_NOT_FOUND to the Error Handling table
(pre-existing omission, now surfaced by the prose fix). Fixes #8083.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019YVwwJHNCoXYXqDtPJ4bb3

* chore: remove changeset — docs/media-buy/ is not protocol-scoped per CI policy

The changeset-scope check only recognises docs/reference/ as protocol-scoped;
docs/media-buy/task-reference/ is outside that boundary, so a changeset for
`adcontextprotocol` is a policy violation here. No semantic change.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019YVwwJHNCoXYXqDtPJ4bb3

* fix(docs): resolve compliance pseudo-link to canonical target

Replace adcp: pseudo-link with the canonical compliance catalog anchor.
The link-compliance-symbols script rewrites adcp:error-code/* pseudo-links
to their computed targets on build; applying the rewrite in source keeps
the file in sync with the build:compliance --check gate.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019YVwwJHNCoXYXqDtPJ4bb3

* chore: keep the reporting correction within the existing changeset policy

---------

Co-authored-by: Claude <noreply@anthropic.com>
…8079)

* feat(protocol): report SDK identity and integration in capabilities

* docs(protocol): use published schema alias in SDK example

* fix(ci): isolate Python SDK candidate schema sync

* docs(protocol): tighten component table and add three-tier buyer guidance

Per @bokelley's review:
- schema_validation: claim only when SDK enforces payload rejection, not advisory/warning-only validation
- signing and lifecycle: claim only when both bundled behaviors are covered across applicable task paths
- Using the report: add three-tier framing (unknown/partial/no-verification → full/no-verification → current verification) with example buyer messaging and "full applicable" semantics

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D9oM3XxbkwLngP4xKZMCMQ

* fix(protocol): clarify SDK coverage and verification guidance

---------

Co-authored-by: Claude <noreply@anthropic.com>
* feat(training-agent): add private GCS reporting with SDK 15.2

* fix(training-agent): provision reporting schema outside runtime boundary

* fix(training-agent): isolate reporting readiness from liveness

* docs(training): require reporting namespace before bootstrap

* docs(deploy): require namespace before manual migrations

* feat(training-agent): support WorkOS buyer sign-in and keyless canary credentials (#8039)

* feat(training-agent): support WorkOS buyer sign-in for private reporting

* fix(training-agent): bound buyer refresh and reporting requests

* fix(training-agent): reuse short-lived WorkOS buyer tokens

* chore(training-agent): stage keyless Fly reporting credentials

* fix(training-agent): log sanitized buyer authorization outages

* test(training): assert exact buyer request origins
Complete the profile-3.2 counterparts for unsigned and malformed/duplicate signing-header requests, with required Content-Digest coverage, independently verified real signatures where possible, and strict mirror parity. The existing step-ordering question remains in #7577. Parent #8066 is merged.

Validation: all 60 exact-head service checks passed and the existing review approves that same source. Independently ran the unchanged official vector test on SDK15.2: 92 passes and 2 explicitly documented TODOs; the generator verifies all43 profile-3.2 vectors. The non-ASCII-host TODO now passes, while the malformed-Host TODO remains an upstream SDK gap. No native gates were waived.

Closes #7733.
* feat(reporting): add REVISION_UNREADABLE status issue code

A published revision still owed within status_retention_days whose
content cannot be served or verified now has a precise seller-owned
issue. Authorized exact reads return SERVICE_UNAVAILABLE, never
REFERENCE_NOT_FOUND. Closes #8082.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* fix(reporting): pair REVISION_UNREADABLE severity and action with if/else

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
status_retention_days keeps metadata for every revision and content for
the current revision, its immediate predecessor, snapshots within the
recovery grace, and caller-pinned revisions. Older superseded snapshots
may compact to metadata only once the six-week notice lapses.
Closes #8081.

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Closes #8089

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
…ed finalize (#8104)

* feat(media-buy): expected_confirmation_at on refine_proposals submitted finalize

A finalize whose hold waits on a creator, host or talent can say when to
check back. Optional date-time on the submitted arm of refine_proposals;
forbidden on completed. core/compact-task-submitted.json is unchanged because
decline_proposals, control_media_buy and request_proposals share it.

Refs #8086

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* fix(media-buy): carry normative text and 3.3 marker for refine_proposals expected_confirmation_at

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
…proposal (#8106)

* feat(training-agent): add CreatorLoop creator marketplace publisher and proposal

Refs #8093

Ten fictional creators as kind: channel collections, each sold as a
guaranteed flat-rate product with upcoming sponsored-video installments
(talking_points -> script -> draft material deadlines), sample-content
reference assets, seller-declared age composition and provider-scoped
gender evidence, plus a four-creator proposal.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* fix(training-agent): keep creator products out of non-creator briefs

Address review: gate creator products to creator briefs, fix deadline
ordering (booking <= cancellation <= material), relative dates per UTC
day, honest capability claims, and fictional copy.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* fix(training-agent): keep audience_activation on creator products

Every training product carries audience_activation (asserted by the
list_products canonical test); only the geo and frequency-cap claims are
dropped for creator slots.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* fix(training-agent): drop per-day shows getter the catalog cache defeats

The catalog is built once per process, so the getter never refreshed
slot dates. Compute them once and document the limit.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
… sales-broadcast-tv (#8046)

* feat(compliance): certify an authorized CPM-on-demo TV transaction in sales-broadcast-tv

Refresh the sales_broadcast_tv storyboard so the badge certifies one intentional,
authorized TV transaction under agreed terms, and run it against the reference seller.

Refs #8032

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* fix(compliance): address review of sales-broadcast-tv transaction storyboard

Make spot lifecycle observations advisory, assign creatives on the buy, send delta
deliveries, use a fictional measurement vendor, and disclose the tightening.

Refs #8032

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* test(compliance): mirror raised /sales floors in the local matrix runner

Refs #8032

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* feat(compliance): accept cpp for sales-broadcast-tv, record a grace window for 1.0.x claims

Refs #8032

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* feat(compliance): grade guaranteed and fixed-price non-guaranteed paths in sales-broadcast-tv

A seller earns the badge by completing at least one path. Adds a fixed-price,
seller-approved, non-guaranteed scatter path with an optional hold-confirm step
gated on force_media_buy_confirmation, and an assert_contribution gate.

Refs #8032

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
…RTED_FEATURE (#8052)

* feat(schema): add unsupported-targeting-dimension details for UNSUPPORTED_FEATURE

Closes #6978

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* fix(schema): use real targeting fields in examples, clarify removed vs deprecated

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* fix(schema): use an illustrative removed dimension in examples

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
* feat(schema): add experimental trust.json v1 schemas (RFC #7809)

Schemas only, marked x-status: experimental (feature id identity.trust_json).
Nothing consumes trust.json in 3.3: no identity.trust_url capability field,
no resolver or precedence changes, no storyboard changes, and no requirement
to publish /.well-known/trust.json. brand.json behavior is unchanged. The
document name and path may change before graduation while the JournalList
naming outreach is open.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

* chore(schema): ratchet oneOf baseline for trust/v1/trust.json

The top-level oneOf (Authoritative Location Redirect vs Trust Record) is
genuinely disjoint but disambiguated via anyOf, not, and
additionalProperties: false, which audit-oneof cannot see.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
…cords (#7970)

* fix(compliance): correct hosted credentials, probes, and URL audit

* build(openapi): refresh static credential removal operation

* docs(governance): publish the announced founding board roster
* fix(training-agent): publish private closed-day reporting source

* fix: isolate GCS canary reads and allow startup probe headroom
…sals (#8128)

Mirror the criteria-only guard on the exactProductIds paths so explicitly
selected products priced in different currencies cannot share the first
product's budget currency. Follow-up to #7863.


Claude-Session: https://claude.ai/code/session_01VHwHg8skXvfficerUbeoVd

Co-authored-by: Claude <noreply@anthropic.com>

This branch has not been deployed

No deployments
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.

Identity linking: isolate organization authorization to the authenticated credential