Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
2000 commits
Select commit Hold shift + click to select a range
d9e56d6
fix(#353): emit status on update_media_buy pause/resume/cancel respon…
bokelley May 12, 2026
3b22afc
fix(#354): resolve tenant_id from auth_info on list_accounts/sync_acc…
bokelley May 12, 2026
8026c6c
feat(#352): emit proposals[] on get_products when buying_mode=brief (…
bokelley May 12, 2026
aaeaaf4
fix(#338): use url_for and relabel button to "Advertisers" on webhook…
bokelley May 12, 2026
8692acb
fix(#362): hide AXE Set Key controls on embedded tenants (#368)
bokelley May 12, 2026
6676495
fix(embedded): opt remaining read-only POST probes into embedded-writ…
bokelley May 12, 2026
42ba8b6
fix(#365): allow AI/Logfire test-connection probes on embedded tenant…
bokelley May 12, 2026
3ad8a7f
fix(#363): unblock Policies & Workflows writes on embedded tenants (#…
bokelley May 12, 2026
d83f84a
fix(#364): explain empty Allowed Principals dropdown on embedded tena…
bokelley May 12, 2026
64ce051
fix(#374): coerce update_media_buy status to wire enum at response bo…
bokelley May 12, 2026
8cdb985
fix(transport): env-gated stateless MCP mode for multi-replica deploy…
bokelley May 12, 2026
c7a0c18
chore(deps): bump adcp 5.2.0 → 5.3.0 (#379)
bokelley May 12, 2026
105279d
fix(#377): four-state aao_status_kind + permissive unbound resolution…
bokelley May 13, 2026
71503e9
fix(compliance): residual fixes from 7.1.0 probe — INVALID_REQUEST, I…
bokelley May 13, 2026
1d12612
feat(proposal): implement v1 refine_products + flip capabilities.refi…
bokelley May 13, 2026
d560251
fix(#336): enable Add Publisher on embedded view + fix(scheduler): De…
bokelley May 13, 2026
43a56e4
fix(#357): use url_for() for tenant admin links so embedded-mode moun…
bokelley May 13, 2026
dd0e5f1
chore(deps): bump adcp 5.3.0 → 5.4.0; drop three local workarounds (#…
bokelley May 13, 2026
8c477e5
chore(logs): strip debug instrumentation + collapse audit fan-out (#395)
bokelley May 13, 2026
269c043
chore(logs): drop /mcp+/health access spam, rate-limit geo warning, f…
bokelley May 13, 2026
0f4bcc4
feat(proposal): wire Postgres-backed ProposalStore for create_media_b…
bokelley May 13, 2026
3d6e32d
refactor(types): adopt SchemaVariant for 12 cross-class schema overri…
bokelley May 13, 2026
ab3ee75
refactor: drop SchedulerLifespanMiddleware, use serve(on_startup=, on…
bokelley May 13, 2026
c2f7967
refactor: swap AgentCardPublicUrlMiddleware for public_url callable (…
bokelley May 13, 2026
212e1e1
feat(ops): add tenant export/import for legacy → embedded migration (…
bokelley May 13, 2026
6db80f4
fix(admin-mount): serve /robots.txt as public Disallow / instead of 4…
bokelley May 14, 2026
22c207e
chore(embedded-guard): inline auth-flag diagnostics in rejection erro…
bokelley May 14, 2026
4bc793b
chore(logs): drop /mcp 401 access spam in UvicornAccessNoiseFilter (#…
bokelley May 14, 2026
fc7dfde
feat(freewheel): full Publisher API adapter — auth, inventory sync, t…
bokelley May 14, 2026
05e1370
fix(audit): stop double-encoding audit_logs.details + repair migratio…
bokelley May 14, 2026
9434410
fix(migration): reconcile divergent alembic heads from PR #381 + #409…
bokelley May 14, 2026
521eb34
feat(adapters): shared sync orchestration + uniform contract (#382) (…
bokelley May 14, 2026
2678ece
feat(admin): surface 500 tracebacks + warn on missing storefront pref…
bokelley May 14, 2026
0d77b70
fix(tenant-export): suspend user triggers during bulk tenant delete (…
bokelley May 14, 2026
fcda6d2
fix(tenant-export): strip + remap autoincrement int PKs when retarget…
bokelley May 14, 2026
b20d186
fix(tenant-export): remap globally-unique string PKs on retarget (clo…
bokelley May 14, 2026
5444009
feat(admin): add ALLOW_SIGNUPS env var to close self-service registra…
bokelley May 14, 2026
70041ee
feat(admin): hide Buyer Agents tab on embedded; rename Settings → Ten…
bokelley May 15, 2026
2ffbde0
fix(admin): scope dashboard activity ledger to last 7 days (#421)
bokelley May 15, 2026
3257883
fix(admin): exempt S2S API blueprints from cross-origin CSRF guard (#…
EmmaLouise2018 May 15, 2026
99e6b94
refactor(admin): drop redundant X-Identity-Subject CSRF bypass (#424)
bokelley May 15, 2026
e3c0f7e
feat(springserve): add SpringServe (Magnite) ad-server adapter — dire…
bokelley May 15, 2026
3c58544
feat(proposal): adopt adcp 5.5.0 — framework derivation + PgProposalS…
bokelley May 15, 2026
b9c3287
feat(embedded): EMBEDDED_CAPABILITIES flag + Tenant Settings section …
bokelley May 16, 2026
a92e67d
feat(embedded): hard-hide signing keys + OIDC on embedded + review-dr…
bokelley May 16, 2026
406b251
feat(admin): promote Publishers to standalone Configure peer page (Sp…
bokelley May 16, 2026
b33e7ca
feat(admin): promote Signing Keys to standalone Configure peer page (…
bokelley May 16, 2026
b99d22a
feat(admin): promote Policies & Workflows to standalone Configure pee…
bokelley May 16, 2026
4c23529
feat(admin): promote Integrations to standalone Configure peer page (…
bokelley May 16, 2026
d09ed5c
feat(embedded): collapse Tenant Settings on embedded — locked page (S…
bokelley May 16, 2026
78bb135
fix(tests): sweep test-debt — admin/MCP/error-code fixes (#438)
bokelley May 17, 2026
dd1b034
fix(seed): bootstrap tenant_management_api_key in seed_demo_data (#440)
bokelley May 17, 2026
b391cf2
feat(signals): embedded composition API + TenantSignal-based adapter …
bokelley May 17, 2026
09d253d
docs: publish Tenant Management OpenAPI spec at repo root (#450)
bokelley May 17, 2026
e670644
fix(provision): make provisioning synchronous + binary, no polling (#…
bokelley May 17, 2026
150bae0
feat(webhooks): expand event catalog — creative, principal, product (…
bokelley May 17, 2026
b6a4cc7
fix(scripts): harden run_all_tests.sh against pipefail aborts (#432) …
bokelley May 17, 2026
16663bc
feat(admin-nav): promote Products/Inventory/Signals to top nav + dev-…
bokelley May 17, 2026
5de203d
feat(adapter): widen probes — FreeWheel inventory binding, Broadstree…
bokelley May 17, 2026
0cb6395
feat(single-tenant): derive SALES_AGENT_DOMAIN from tenant virtual_ho…
bokelley May 17, 2026
fd37b9d
fix(broadstreet): flip supports_inventory_sync=False until implementa…
bokelley May 17, 2026
d0a14c9
feat(adapter): add preview paths for FreeWheel, Broadstreet, SpringSe…
bokelley May 17, 2026
e10027b
feat(webhooks): wire creative.created and media_buy.created from agen…
bokelley May 17, 2026
64500bb
feat(signals): source-first authoring + auto-generated signal_id (#458)
bokelley May 17, 2026
105809d
feat(single-tenant): normalize virtual_host, log DB lookup failures, …
bokelley May 17, 2026
066a04a
feat(signals): complex GAM targeting via embedded TargetingWidget (#462)
bokelley May 17, 2026
fcb5486
feat(webhooks): emit media_buy.status_changed when GAM background app…
bokelley May 17, 2026
71fa628
fix(signals): unescaped JSON literal in form re-render JS (#464)
bokelley May 17, 2026
c4175ee
feat(signals): bulk-map UX — tick GAM entities, click Create (#466)
bokelley May 17, 2026
f6e6f2d
feat(adapters): split ADAPTER_CONNECTION_FAILED into typed sub-codes …
bokelley May 17, 2026
23947da
feat(webhooks): wire sync.completed/sync.failed + 409 retry contract …
bokelley May 18, 2026
3f5c4da
feat(signals): composite builder + 'Maps to' edit panel + bulk-map po…
bokelley May 18, 2026
af15ea7
feat(admin): remove in-page Products + Inventory tabs (Sprint 7 Phase…
bokelley May 18, 2026
758efb6
feat(signals): ad-ops polish — search, delete warning, preview, clean…
bokelley May 18, 2026
6cd9c3f
docs(embedded): update sprint-7 + sprint-4 + parent embedded-mode aft…
bokelley May 18, 2026
d31c2fb
fix(embedded): /status setup_tasks honors EMBEDDED_CAPABILITIES (#483)
bokelley May 18, 2026
8077749
feat(admin): Sprint 7 IA refinements — inventory_sync flag, Publisher…
bokelley May 18, 2026
bbdb8c5
fix(embedded): require_auth honors ?tenant_id= query arg for X-Identi…
bokelley May 18, 2026
f8432f7
docs(embedded): correct OpenAPI spec URL and remove shipped sprint de…
bokelley May 18, 2026
7e2b39f
feat(dashboard): three-job seller workbench (#471) (#495)
bokelley May 18, 2026
21de20b
feat(embedded): drop StatusPackagesBlock.last_24h_impressions (#496)
bokelley May 18, 2026
f63c959
feat(adapters): role-gap 404s, unified vendor_fault, upstream_unavail…
bokelley May 18, 2026
0fa30ae
feat(dashboard): Job 1 inventory coverage analytics (#485 PR-1) (#497)
bokelley May 18, 2026
1aaf751
feat(signals): active-buy reference counts + typed-DELETE confirmatio…
bokelley May 18, 2026
fce977f
feat(signals): persisted GAM targeting values + bulk-map polish (#490)
bokelley May 18, 2026
1099ff2
feat(signals): tags + bulk operations + edit-page polish (#484)
bokelley May 18, 2026
c01095d
feat(signals): source-centric Signals page redesign (Claude Design ha…
bokelley May 18, 2026
dc9c144
feat(signals): v2 design — split-row source→signal grid (#504)
bokelley May 18, 2026
a14846d
feat(tenant-management): expose initial_principal.access_token on pro…
EmmaLouise2018 May 19, 2026
ef42860
chore: regenerate OpenAPI spec after exposing initial_principal.acces…
EmmaLouise2018 May 19, 2026
3a494f7
Merge pull request #506 from bokelley/emma/expose-embedded-principal-…
EmmaLouise2018 May 19, 2026
2f39a58
feat(buyer-protocol): accept X-Identity-* / X-Principal-Id from trust…
EmmaLouise2018 May 19, 2026
af57efa
Merge pull request #507 from bokelley/emma/buyer-protocol-embedded-id…
EmmaLouise2018 May 19, 2026
e3ef361
feat(adapters): SpringServe (Magnite) integration — inventory, signal…
bokelley May 19, 2026
df0c451
refactor(dashboard): reframe inventory coverage as bundle-reference (…
bokelley May 19, 2026
b445957
fix(adapters/springserve): Talpa launch — Line Item class + correct w…
bokelley May 19, 2026
bdaccc6
feat(inventory): redesign bundles list — coverage strip + multi-use r…
bokelley May 20, 2026
922612c
fix(admin): edit inventory profile uses profile.format_ids, not profi…
bokelley May 20, 2026
807ad43
feat(auth): gate MCP discovery tools at transport layer (adcp 5.6.0) …
bokelley May 20, 2026
6726c6c
ux(inventory-bundle): hide internal fields, upgrade description, alig…
bokelley May 20, 2026
aed406a
refactor: post-#515 cleanup (dead MCPAuthMiddleware, list_authorized_…
bokelley May 20, 2026
a60f56b
feat(capabilities): publisher_domains portfolio + CI modernization (#…
bokelley May 20, 2026
36b624c
feat(inventory-bundle): wire duplicate action — POST /<id>/duplicate …
bokelley May 21, 2026
9baba84
fix: parallelize creative agent format fetch with global timeout cap …
bokelley May 21, 2026
8b8d6b9
feat(inventory-bundle): seed suggestions + reuse menu (list v2) (#526)
bokelley May 21, 2026
ee8809b
fix(creative-agents): serve stale cache + STALE_RESPONSE warning when…
bokelley May 21, 2026
b486d69
feat(inventory-bundle): edit page redesign — sidebar, blast radius, s…
bokelley May 21, 2026
6341679
fix(security): bump supercronic v0.2.41 → v0.2.45 to clear Go stdlib …
EmmaLouise2018 May 21, 2026
4ef41b6
Merge pull request #533 from bokelley/EmmaLouise2018/trivy-cve-gate-b…
EmmaLouise2018 May 21, 2026
c545aef
feat(inventory-bundle): resolve external IDs to names + expand 'Used …
bokelley May 21, 2026
b0b970d
feat(inventory-bundle): property-tag typeahead + click-to-add chip pi…
bokelley May 21, 2026
d4f46d5
feat(inventory-bundle): real Preview page — buyer's-eye view (#531) (…
bokelley May 21, 2026
7b10aee
feat(inventory-bundle): live sidebar validation (#529) (#537)
bokelley May 21, 2026
6018df9
feat(inventory-bundle): multi-domain publisher_properties editor (#53…
bokelley May 21, 2026
ff08a64
fix(security): build supercronic from source on Go 1.26.3 + bump temp…
EmmaLouise2018 May 21, 2026
1dce653
Merge pull request #540 from bokelley/EmmaLouise2018/trivy-cve-gate-b…
EmmaLouise2018 May 21, 2026
91d0f9e
feat(inventory-bundle): reverse-add Reuse page (closes #524) (#541)
bokelley May 21, 2026
2471486
feat(inventory-bundle): adapter framework — protocol + GAM impl + FW/…
bokelley May 22, 2026
f0b2ff5
feat(inventory-bundle): per-chip Reuse action on editor inventory chi…
bokelley May 22, 2026
3ddb2c8
refactor: use adcp.decisioning state graph for media_buy terminal-sta…
bokelley May 22, 2026
0d0e99c
fix(dev): require CONDUCTOR_PORT, recreate proxy on compose-up (#505)
bokelley May 22, 2026
6ca637a
fix(inventory-bundle): drop shipped-alert 'Browse' buttons + polish s…
bokelley May 22, 2026
7d0a0d2
fix(media-buy): persist cancel before approval gate (#551)
bokelley May 22, 2026
d90ab5d
feat(inventory-bundle): finish editor follow-up polish
bokelley May 22, 2026
e80dec2
fix: allow wholesale get_products without search criteria (#554)
bokelley May 22, 2026
196b5e6
fix: Handle embedded targeting value refresh (#552)
bokelley May 22, 2026
f4f518c
feat: add tree-first inventory picker
bokelley May 22, 2026
3e92e63
fix: Return absolute tenant management surface URLs
bokelley May 22, 2026
4d4dad8
fix: Allow tenant subdomain MCP hosts
bokelley May 22, 2026
00855a6
feat: simplify bundles and add inventory capabilities
bokelley May 22, 2026
c8eda64
feat: add FreeWheel nightly forecast delivery fallback
bokelley May 23, 2026
57ed023
feat: add composition API product authoring
bokelley May 23, 2026
72dd99d
feat: support signal discovery catalog webhooks (#561)
bokelley May 24, 2026
8ab9c32
fix: invalidate publisher authorization on agent URL changes (#566)
bokelley May 24, 2026
0bb06a8
fix: harden get_products catalog serialization (#569)
bokelley May 24, 2026
17abdad
feat(admin): sync publisher partners from AAO directory inverse-looku…
bokelley May 24, 2026
30066d0
perf: Slim Python runtime image
bokelley May 24, 2026
95e9808
chore: Align Python tooling targets
bokelley May 24, 2026
59ba973
chore: Standardize Python formatting on Ruff
bokelley May 24, 2026
4a7ecc4
fix: secure agent credentials and GAM import revocation (#573)
bokelley May 24, 2026
65435fb
fix: Resolve publisher_properties dict selectors (#575)
bokelley May 24, 2026
f336d11
fix: Preserve wholesale pricing options
bokelley May 24, 2026
883656e
fix: Repair admin action controls
bokelley May 24, 2026
6c99af7
chore: Delete core auth skeleton
bokelley May 24, 2026
894a23c
docs: Update idempotency escape hatch comment
bokelley May 25, 2026
c6599a6
refactor: Replace star import re-exports
bokelley May 25, 2026
33a7229
refactor: Enable Ruff B904
bokelley May 25, 2026
e5b05f8
fix: Remove auth-chain account default
bokelley May 25, 2026
a540ab0
test: cover composition wholesale pricing options (#583)
bokelley May 25, 2026
d3f150e
fix: Align pending creatives status semantics
bokelley May 25, 2026
79513af
chore: Clean up local type ignores
bokelley May 25, 2026
6ff53d4
feat: Surface webhook signing capabilities (#587)
bokelley May 25, 2026
fbcb0ad
fix: Harden admin CSRF checks (#588)
bokelley May 25, 2026
08ee816
fix: Require HTTPS webhook delivery URLs (#589)
bokelley May 25, 2026
50d25d8
fix: Reject tenant IDs containing colons (#590)
bokelley May 25, 2026
0d40b61
fix: Bound tenant signal input sizes
bokelley May 25, 2026
80d76fb
fix: Harden targeting value live fetches
bokelley May 25, 2026
a97e5bc
fix: Optimize signals list performance
bokelley May 25, 2026
bdf7763
fix: Improve signals menu accessibility
bokelley May 25, 2026
c61d636
fix: Include proposals in tenant exports
bokelley May 25, 2026
2cf46c7
feat: Add expired proposal cleanup job
bokelley May 25, 2026
dffee76
fix: Collect orphaned core tests
bokelley May 25, 2026
689f941
fix: cover idempotency conflict wire envelopes (#598)
bokelley May 25, 2026
71782b7
fix: Cover idempotency wire regressions (#599)
bokelley May 25, 2026
797145a
feat: publish adapter tenant-management contracts
bokelley May 25, 2026
5a19b5d
Merge pull request #601 from bokelley/triage/openapi-contracts-600
bokelley May 25, 2026
e20a657
fix: isolate nested database sessions
bokelley May 25, 2026
4e2cbaa
Merge pull request #602 from bokelley/triage/session-nesting-391
bokelley May 25, 2026
d8fc382
fix: reject unknown MCP fields in dev mode (#603)
bokelley May 25, 2026
2f36e86
feat: expose adapter runtime config API
EmmaLouise2018 May 25, 2026
ec3df8f
Merge pull request #604 from bokelley/bokelley/issue-600
EmmaLouise2018 May 25, 2026
581641a
fix: grant access when resyncing accounts
bokelley May 26, 2026
6d7feb2
ci: add storyboard validation smoke
bokelley May 26, 2026
6a9c038
ci: broaden storyboard validation gate
bokelley May 26, 2026
59335ad
ci: add non-guaranteed storyboard assessment
bokelley May 26, 2026
30a9fd5
ci: enable webhook storyboard receiver testing
bokelley May 26, 2026
ec43423
ci: run storyboards on mcp and a2a
bokelley May 26, 2026
6d2e1c0
ci: harden storyboard validation lanes
bokelley May 26, 2026
541b54e
feat: integrate AdCP 3.1 beta support (#610)
bokelley May 26, 2026
224f584
fix: echo create media buy idempotency keys
bokelley May 26, 2026
d6173ac
fix: Scope publisher setup to wholesale products (#608)
bokelley May 26, 2026
5a73669
fix: gate storefront-owned embedded surfaces (#612)
bokelley May 26, 2026
7edd9d0
chore: merge origin/main into storyboard branch
bokelley May 26, 2026
d9b6362
refactor: Remove adapter-specific OpenAPI setup specs (#613)
bokelley May 26, 2026
dde52cb
Merge remote-tracking branch 'origin/main' into bokelley/investigate-…
bokelley May 26, 2026
5a73951
chore: Update AdCP SDK beta 4 (#615)
bokelley May 26, 2026
6a1560b
Merge remote-tracking branch 'origin/main' into bokelley/investigate-…
bokelley May 26, 2026
db08788
Merge pull request #611 from bokelley/bokelley/investigate-200k-rows
bokelley May 26, 2026
bdc9213
feat: Add embedded wholesale product authoring API (#616)
bokelley May 26, 2026
71364fc
fix: use SDK-native webhook signing capabilities (#617)
bokelley May 26, 2026
b815990
fix: harden authoring APIs and healthchecks (#618)
bokelley May 26, 2026
fd94c57
feat: Use canonical creative formats across adapters (#619)
bokelley May 26, 2026
a5b495b
feat: Add OpenTelemetry distributed tracing (#620)
benminer May 26, 2026
d1b8ec0
fix: reduce GAM startup DB and geo regressions (#622)
bokelley May 27, 2026
f9f8388
fix: Address OTEL tracing review issues (#621)
bokelley May 27, 2026
bb33140
fix: advertise embedded compose capability state (#623)
bokelley May 27, 2026
872b66c
fix: allow storefront-owned approvals in embedded protocol flow
bokelley May 27, 2026
9c96944
chore: speed up local quality checks (#633)
bokelley May 27, 2026
cb692a3
fix: Tolerate ADCP beta envelope and catalog webhooks (#632)
bokelley May 27, 2026
6f2e16b
fix: raise MCP server startup timeout in CI (#635)
bokelley May 27, 2026
8f6bea0
ci: reduce unneeded image builds (#634)
bokelley May 27, 2026
0c65552
fix: Add media buy revision concurrency controls (#631)
bokelley May 27, 2026
46954f9
fix: support catalog webhooks and publisher property selectors (#636)
bokelley May 27, 2026
d6ef058
fix: Validate standard creative format aliases locally (#639)
bokelley May 27, 2026
a4b9553
fix: improve FreeWheel login diagnostics
bokelley May 27, 2026
3fb14f9
fix: Reject invalid creative format agents (#641)
bokelley May 27, 2026
581488b
fix: improve FreeWheel login diagnostics (#642)
bokelley May 27, 2026
61fc290
feat: add embedded sync health contract (#647)
bokelley May 28, 2026
eceb072
feat: Add server-owned sync schedulers (#648)
bokelley May 28, 2026
418c2af
fix: reject inactive tenant service tokens (#650)
bokelley May 28, 2026
e9b6c47
feat: add GAM advertiser ensure endpoint
bokelley May 28, 2026
0fe3acd
fix: Bump AdCP SDK to 6.3.0-beta.6 (#651)
bokelley May 28, 2026
7e104c5
feat: add GAM pricing availability sync (#656)
bokelley May 28, 2026
a26e0e1
fix: Adopt SDK beta.6 compatibility helpers (#655)
bokelley May 28, 2026
85a812f
fix: enforce single-currency media buys (#652)
bokelley May 28, 2026
2ed5bf7
feat: add GAM advertiser readiness routing (#658)
bokelley May 29, 2026
2541a13
fix: pin multi-tenant deployment to production mode (#660)
bokelley May 29, 2026
9da7d8c
feat: add sandbox trafficking mode (#662)
bokelley May 29, 2026
9db569c
fix: enforce sandbox zero-rate accounts (#661)
bokelley May 29, 2026
e9da072
fix: Address creative sync and tenant API regressions (#668)
bokelley May 29, 2026
54c76bb
fix: address media buy E2E regressions (#672)
bokelley May 29, 2026
2eedf46
fix: Resolve stale custom targeting sync health (#673)
bokelley May 30, 2026
fa08a99
fix: Self-heal local example publisher authorization
bokelley May 30, 2026
334e77e
fix: clear stale sync retry health after success (#675)
bokelley May 30, 2026
48e9cc8
fix: hide embedded-only setup tasks (#677)
bokelley May 30, 2026
78d38e6
fix: add MCP session guard configuration (#678)
bokelley May 30, 2026
c1f0226
fix: Project wholesale products from inventory bundles (#679)
bokelley May 30, 2026
6dacc96
fix: Bridge embedded buyer auth through SDK gate (#683)
bokelley May 31, 2026
d1baf81
fix: accept embedded approval settings on provision (#685)
bokelley Jun 1, 2026
86ed4ad
fix: Canonicalize wholesale creative format refs (#686)
bokelley Jun 1, 2026
d4bec1c
fix: clarify wholesale forecast and pricing metadata contract (#684)
bokelley Jun 2, 2026
0678f8a
fix: set default GAM advertiser from cache on tenant provision (#687)
nastassiafulconis Jun 5, 2026
50d0024
fix: defer SpringServe demand_partner_id check to buyer-facing operat…
nastassiafulconis Jun 5, 2026
c1cd46d
fix: harden inventory sync recovery
bokelley Jun 9, 2026
aadceaf
fix: harden inventory sync recovery
bokelley Jun 9, 2026
d091fc2
fix: chunk truncated GAM pricing reports
bokelley Jun 9, 2026
a250dc6
fix: chunk truncated GAM pricing reports
bokelley Jun 9, 2026
5b4dada
fix: tolerate single-placement GAM pricing caps
bokelley Jun 9, 2026
5a07c90
fix: tolerate single-placement GAM pricing caps
bokelley Jun 9, 2026
8cc15f7
fix: harden sync health status reporting
bokelley Jun 9, 2026
11fee26
fix: Align tenant status with wholesale products (#696)
bokelley Jun 9, 2026
6689aac
fix: handle inapplicable GAM derived sync status
bokelley Jun 9, 2026
329a758
fix: support GAM ad unit pricing availability (#698)
bokelley Jun 9, 2026
3f7f866
Merge pull request #697 from bokelley/derived-sync-root-cause
bokelley Jun 9, 2026
634ecd9
fix: clear supercronic CVE scan gate (#700)
bokelley Jun 9, 2026
db5a0ad
fix: avoid empty creative format authoring catalogs (#702)
bokelley Jun 9, 2026
516bcc2
feat: FreeWheel API-Access client_credentials auth + sandbox support …
bokelley Jun 10, 2026
117e1db
Merge remote-tracking branch 'bokelley/main' into merge-master
sadrultoaha Jun 11, 2026
d9fe9ab
Dockerfile merged with develop
sadrultoaha Jun 11, 2026
8210971
fix: handle GAM order approval permission denied gracefully
sadrultoaha Jun 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/test-coverage-remediation.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ Already configured in `.pre-commit-config.yaml`:
```yaml
- id: detect-test-antipatterns
entry: uv run python scripts/detect_test_antipatterns.py
files: '^(tests/.*\.py|src/a2a_server/adcp_a2a_server\.py)$'
files: '^tests/.*\.py$'
```

## Testing Philosophy
Expand Down
140 changes: 140 additions & 0 deletions .github/workflows/publish-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
name: Publish Image

on:
push:
branches: [ main, develop ]
tags: ['v*.*.*']
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

jobs:
build-and-push:
name: Build and Push to GHCR
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- name: Checkout
run: |
git config --global --add safe.directory "$GITHUB_WORKSPACE"
git init "$GITHUB_WORKSPACE"
cd "$GITHUB_WORKSPACE"
git remote add origin "https://github.com/${GITHUB_REPOSITORY}.git"
git fetch --no-tags --prune --depth=1 origin "$GITHUB_REF"
git -c advice.detachedHead=false checkout --force FETCH_HEAD
git clean -ffdx

- name: Set up QEMU
run: docker run --privileged --rm tonistiigi/binfmt --install amd64,arm64

- name: Set up Docker Buildx
run: |
docker buildx create --name salesagent-builder --use
docker buildx inspect --bootstrap

- name: Log in to GHCR
env:
GHCR_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: echo "${GHCR_TOKEN}" | docker login "${REGISTRY}" -u "${{ github.actor }}" --password-stdin

- name: Extract metadata
id: meta
run: |
set -euo pipefail

image="${REGISTRY}/${IMAGE_NAME}"
tags=()

if [ "${GITHUB_REF_TYPE}" = "branch" ]; then
safe_ref="${GITHUB_REF_NAME//\//-}"
tags+=("${image}:${safe_ref}")
fi

if [[ "${GITHUB_REF_TYPE}" = "tag" && "${GITHUB_REF_NAME}" =~ ^v?([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then
version="${GITHUB_REF_NAME#v}"
IFS=. read -r major minor patch <<< "${version}"
tags+=("${image}:${version}")
tags+=("${image}:${major}.${minor}")
fi

tags+=("${image}:sha-${GITHUB_SHA:0:7}")

if [ "${GITHUB_REF_NAME}" = "${{ github.event.repository.default_branch }}" ]; then
tags+=("${image}:latest")
fi

{
echo "tags<<EOF"
printf '%s\n' "${tags[@]}"
echo "EOF"
echo "labels<<EOF"
echo "org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}"
echo "org.opencontainers.image.revision=${GITHUB_SHA}"
echo "EOF"
} >> "$GITHUB_OUTPUT"

- name: Compute lockfile hash
id: lockhash
run: |
# ``LOCKFILE_HASH`` invalidates the uv install layer when
# uv.lock changes — otherwise a BuildKit cache-mount edge case
# can reuse a stale venv across dep bumps. See CLAUDE.md.
echo "value=$(shasum -a 256 uv.lock | awk '{print $1}')" >> "$GITHUB_OUTPUT"

- name: Build image for vulnerability scan
env:
LOCKFILE_HASH: ${{ steps.lockhash.outputs.value }}
SCAN_IMAGE: salesagent-scan:${{ github.sha }}
run: |
set -euo pipefail

docker buildx build \
--platform linux/amd64 \
--load \
--tag "${SCAN_IMAGE}" \
--build-arg "LOCKFILE_HASH=${LOCKFILE_HASH}" \
--build-arg "GIT_SHA=${GITHUB_SHA}" \
--build-arg "GIT_BRANCH=${GITHUB_REF_NAME}" \
.

- name: Trivy vulnerability gate
env:
SCAN_IMAGE: salesagent-scan:${{ github.sha }}
run: scripts/ci/trivy_image_gate.sh "${SCAN_IMAGE}"

- name: Build and push
env:
TAGS: ${{ steps.meta.outputs.tags }}
LABELS: ${{ steps.meta.outputs.labels }}
LOCKFILE_HASH: ${{ steps.lockhash.outputs.value }}
run: |
set -euo pipefail

tag_args=()
while IFS= read -r tag; do
[ -n "$tag" ] && tag_args+=(--tag "$tag")
done <<< "$TAGS"

label_args=()
while IFS= read -r label; do
[ -n "$label" ] && label_args+=(--label "$label")
done <<< "$LABELS"

docker buildx build \
--platform linux/amd64,linux/arm64 \
--push \
"${tag_args[@]}" \
"${label_args[@]}" \
--build-arg "LOCKFILE_HASH=${LOCKFILE_HASH}" \
--build-arg "GIT_SHA=${GITHUB_SHA}" \
--build-arg "GIT_BRANCH=${GITHUB_REF_NAME}" \
.
28 changes: 28 additions & 0 deletions .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,30 @@ jobs:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Compute lockfile hash
id: lockhash
run: |
# ``LOCKFILE_HASH`` invalidates the uv install layer when
# uv.lock changes — otherwise a BuildKit cache-mount edge case
# can reuse a stale venv across dep bumps. See CLAUDE.md.
echo "value=$(shasum -a 256 uv.lock | awk '{print $1}')" >> "$GITHUB_OUTPUT"

- name: Build image for vulnerability scan
uses: docker/build-push-action@v5
with:
context: .
file: Dockerfile
load: true
tags: salesagent-scan:${{ github.sha }}
build-args: |
LOCKFILE_HASH=${{ steps.lockhash.outputs.value }}
GIT_SHA=${{ github.sha }}
GIT_BRANCH=${{ github.ref_name }}
cache-from: type=gha

- name: Trivy vulnerability gate
run: scripts/ci/trivy_image_gate.sh "salesagent-scan:${{ github.sha }}"

- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
Expand Down Expand Up @@ -72,5 +96,9 @@ jobs:
platforms: linux/amd64,linux/arm64
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
LOCKFILE_HASH=${{ steps.lockhash.outputs.value }}
GIT_SHA=${{ github.sha }}
GIT_BRANCH=${{ github.ref_name }}
cache-from: type=gha
cache-to: type=gha,mode=max
192 changes: 192 additions & 0 deletions .github/workflows/storyboard.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
name: Storyboard Validation

on:
pull_request:
branches: [ main, develop ]
push:
branches: [ main, develop ]
schedule:
# Nightly latest-SDK drift check.
- cron: "23 9 * * *"
workflow_dispatch:
inputs:
latest_sdk_full:
description: "Also run the latest-SDK full assessment"
required: false
default: "false"
type: choice
options:
- "false"
- "true"

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

env:
CONDUCTOR_PORT: "8000"
SEED_DEMO_AUTO_APPROVE: "1"

permissions:
contents: read

jobs:
pinned-smoke:
name: Pinned Storyboard Gate
runs-on: ubuntu-latest
timeout-minutes: 20

steps:
- uses: actions/checkout@v6

- name: Set up Node
uses: actions/setup-node@v5
with:
node-version: "24"

- name: Start services with docker compose
run: |
export LOCKFILE_HASH=$(shasum -a 256 uv.lock | awk '{print $1}')
docker compose up -d --wait --wait-timeout 180

- name: Run pinned storyboard gate
env:
AGENT_URL: http://localhost:8000
AGENT_TOKEN: ci-test-token
ADCP_SDK_VERSION: "7.11.0"
ALLOW_HTTP: "1"
PROTOCOLS: mcp,a2a
STORYBOARDS: capability_discovery,pagination_integrity_list_accounts,get_signals_pagination_integrity,signal_owned
REPORT_DIR: ${{ runner.temp }}/storyboard-pinned-smoke
TIMEOUT: "180"
run: ./scripts/storyboard-check.sh

- name: Upload storyboard reports
if: always()
uses: actions/upload-artifact@v4
with:
name: storyboard-pinned-smoke
path: ${{ runner.temp }}/storyboard-pinned-smoke
if-no-files-found: ignore

- name: Cleanup
if: always()
run: docker compose down -v

pinned-sales-non-guaranteed:
name: Pinned Sales Non-Guaranteed Assessment
runs-on: ubuntu-latest
timeout-minutes: 35

steps:
- uses: actions/checkout@v6

- name: Set up Node
uses: actions/setup-node@v5
with:
node-version: "24"

- name: Start services with docker compose
run: |
export LOCKFILE_HASH=$(shasum -a 256 uv.lock | awk '{print $1}')
docker compose up -d --wait --wait-timeout 180

- name: Run pinned sales non-guaranteed assessment
shell: bash
env:
AGENT_URL: http://localhost:8000
AGENT_TOKEN: ci-test-token
ADCP_SDK_VERSION: "7.11.0"
ALLOW_HTTP: "1"
PROTOCOLS: mcp,a2a
SPECIALISMS: sales-non-guaranteed
EXCLUDED_STORYBOARDS: security_baseline
BETWEEN_PROTOCOLS_HOOK: ./scripts/storyboard-reset-compose.sh
REPORT_DIR: ${{ runner.temp }}/storyboard-sales-non-guaranteed
TIMEOUT: "240"
run: |
set +e
./scripts/storyboard-check.sh
rc=$?
if [[ $rc -eq 1 ]]; then
echo "Non-blocking storyboard assertion failures recorded; see uploaded reports."
exit 0
fi
exit "$rc"

- name: Upload storyboard reports
if: always()
uses: actions/upload-artifact@v4
with:
name: storyboard-sales-non-guaranteed
path: ${{ runner.temp }}/storyboard-sales-non-guaranteed
if-no-files-found: ignore

- name: Collect service logs
if: always()
run: docker compose logs > "${{ runner.temp }}/storyboard-sales-non-guaranteed-compose.log" 2>&1 || true

- name: Cleanup
if: always()
run: docker compose down -v

- name: Upload service logs
if: always()
uses: actions/upload-artifact@v4
with:
name: storyboard-sales-non-guaranteed-compose-logs
path: ${{ runner.temp }}/storyboard-sales-non-guaranteed-compose.log
if-no-files-found: ignore

latest-sdk-full:
name: Latest SDK Storyboard Drift
runs-on: ubuntu-latest
timeout-minutes: 35
if: github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && inputs.latest_sdk_full == 'true')

steps:
- uses: actions/checkout@v6

- name: Set up Node
uses: actions/setup-node@v5
with:
node-version: "24"

- name: Start services with docker compose
run: |
export LOCKFILE_HASH=$(shasum -a 256 uv.lock | awk '{print $1}')
docker compose up -d --wait --wait-timeout 180

- name: Run latest-SDK full assessment
shell: bash
env:
AGENT_URL: http://localhost:8000
AGENT_TOKEN: ci-test-token
ADCP_SDK_VERSION: latest
ALLOW_HTTP: "1"
PROTOCOLS: mcp,a2a
STORYBOARD: ""
BETWEEN_PROTOCOLS_HOOK: ./scripts/storyboard-reset-compose.sh
REPORT_DIR: ${{ runner.temp }}/storyboard-latest-sdk
TIMEOUT: "240"
run: |
set +e
./scripts/storyboard-check.sh
rc=$?
if [[ $rc -eq 1 ]]; then
echo "Non-blocking storyboard assertion failures recorded; see uploaded reports."
exit 0
fi
exit "$rc"

- name: Upload storyboard reports
if: always()
uses: actions/upload-artifact@v4
with:
name: storyboard-latest-sdk
path: ${{ runner.temp }}/storyboard-latest-sdk
if-no-files-found: ignore

- name: Cleanup
if: always()
run: docker compose down -v
Loading
Loading