Skip to Content
Roadmap

Roadmap

DDK is delivered in five phases. Each phase is a GitHub milestone with a clear goal; the progress bars and issue lists below are loaded from those milestones when you open the page. Phase 1 shipped as donkey-kit 0.1.0, and its stabilisation release, 0.1.1, is the current release on PyPI . Phase 2 is next.

Status synced from GitHub milestones on 2 October 2026.

Complete every issue in the milestone is closed · In progress work has landed and more is open · Planned designed, not started. Want to help move a phase forward? See Contribute.

Phase 1 — Build the MVP

Version 0.1.0 · Goal: a developer who tries DDK for fifteen minutes finds three things they cannot get from a base_url and two headers — and one of them saves them from a production incident.

The shared governed transport and the capabilities that hang off it: typed refusals, budget & pacing, the local simulator, simulate() and the conformance suite, OpenTelemetry GenAI spans, correlation IDs and cost tags. Plus a deep LangGraph adapter, connection_kwargs() for seven more frameworks, the decorators and CLI, the documentation site, and the PyPI release. The phase closed with steering the gateway’s semantic cache, surfacing cache hits and semantic-routing matches (topic and score) on last_call, and fixing model-substitution detection when the gateway strips a provider prefix.

100% complete · 135 done · 0 open

Done (135)
  • ●#9 Epic: Testing — the adapter conformance kit, contract fixtures, nightly matrix
  • ●#10 core/config: DonkeyConfig resolution order and all-at-once validation
  • ●#11 core/transport: the single shared HTTP client that injects every governed header
  • ●#12 core/auth: AuthProvider protocol, AnypointConnectedApp, StaticToken, ChainedAuth
  • ●#13 core/errors: the governed error taxonomy and classify()
  • ●#14 core/telemetry: correlation IDs, run_context, and optional OpenTelemetry spans
  • ●#16 Donkey facade: lazy per-framework adapters, curated ImportError, async and sync lifecycle
  • ●#17 core: keep core framework-free — import-linter contracts as a blocking CI gate
  • ●#18 llm: donkey.llm.client() — the framework-free governed OpenAI client (async + blocking overloads)
  • ●#24 adapter/langgraph: chat_model() returning a native ChatOpenAI (Tier 1)
  • ●#33 adapters: connection_kwargs() and module-level factories across all eight frameworks
  • ●#179 transport: add the four lifecycle hooks every Phase 1 feature attaches to
  • ●#180 donkey: Donkey.openai() returns a native openai.AsyncOpenAI
  • ●#181 errors: re-align classify() to the documented v1.11-v1.13 rejection contracts
  • ●#182 errors: require a non-empty remediation on every PolicyViolation
  • ●#183 errors: prove policy refusals are terminal and openai's built-in 429 retry never fires
  • ●#184 errors: honest fall-through for guardrail verdicts whose shape is unconfirmed
  • ●#185 budget: Budget as a first-class object parsed from x-token-* headers
  • ●#186 budget: wait_for_reset() and pace(reserve=) raising BudgetReserveReached
  • ●#187 simulator: donkey mock — a local HTTP server that replays real rejection fixtures
  • ●#188 simulator: scenario scripting for PII, budget and injection
  • ●#189 simulator: the honesty guarantee — x-donkey-simulator header and a stock-client test
  • ●#190 testing: donkey.simulate() — in-process refusal injection with no server
  • ●#191 testing: the pytest plugin and the conformance suite customers run against their own agent
  • ●#192 telemetry: OTel GenAI spans at a pinned semconv version, dual-emitted with a stable donkey.* namespace
  • ●#193 telemetry: a refused request still produces a span, and streaming produces exactly one
  • ●#194 telemetry: zero-config OTLP export, one-flag opt-out, <1ms overhead benchmarked in CI
  • ●#195 telemetry: per-call and per-run correlation IDs via donkey.run()
  • ●#196 telemetry: validated cost-attribution tags (team, project, env, enduser.id)
  • ●#197 adapters: demote seven adapters to connection_kwargs-only and cut the conformance roster to LangGraph
  • ●#198 adapter/langgraph: deepen to the one conformance-gated adapter
  • ●#199 demos: langgraph-support-triage implements Scenario A end-to-end against the simulator
  • ●#200 decorators: @donkey.governed and @donkey.tool
  • ●#201 cli: the donkey command surface — init, plus consistent flags and exit codes across all four
  • ●#202 cli: donkey doctor — tell wrong credentials from wrong URL from model-not-allowed
  • ●#203 docs: a 15-minute quickstart that needs no gateway
  • ●#204 docs: scenario pages, the refusal cookbook, and per-framework connection_kwargs pages
  • ●#205 docs: publish llms.txt so coding assistants can read the SDK docs
  • ●#206 release: publish to PyPI with semver and a changelog
  • ●#207 meta: replace the build plan with the phase-based plan and realign CLAUDE.md and the skills
  • ●#259 epic: Phase 1 — Build the MVP
  • ●#266 docs: migrate the ~497 legacy §N.N citations to BG §N.N and retire spec/archive
  • ●#267 docs: realign the docs site to the phase model and cut the retired surfaces
  • ●#270 docs: drop the Omni Gateway architecture image from the feature overview
  • ●#273 Remove demos/ after moving it to a dedicated companion repo
  • ●#277 adapters: free donkey.openai by renaming the Agents SDK adapter
  • ●#278 testing: an out-of-process gateway fixture tests can assert against
  • ●#281 Git-ignore the .playwright-mcp/ local MCP artifact directory
  • ●#285 mypy --strict fails on core/telemetry.py get_tracer under opentelemetry-api 1.44
  • ●#286 Negative Retry-After header makes the retry sleep raise ValueError
  • ●#289 errors: type the documented Regex-Prompt-Guard and Content-Safety refusals; reconcile PIIDetected.entities
  • ●#292 Realign ARCHITECTURE.md with the code and add an implement-stage skill
  • ●#295 testing: end-to-end pace→resume test against the local gateway simulator
  • ●#296 Codify "deferred scope → dedicated follow-up issue" as a stated rule in the skills
  • ●#306 telemetry: keep prompt and completion content out of spans by default
  • ●#307 budget: surface cached and reasoning token counts from the live usage payload
  • ●#339 Publish donkey-kit to PyPI and wire project URLs
  • ●#349 Wire the DDK stacked-black logo into README and the docs site
  • ●#352 budget: Budget never observes on a live 200 — the gateway emits x-llm-proxy-ratelimit, not x-token-*
  • ●#353 simulator: happy-path budget overlay emits x-token-*, but the live 200 emits x-llm-proxy-ratelimit
  • ●#362 skeleton: define the last-call record once — #307 and #309 each assume a different container, and gateway identity is surfaced nowhere
  • ●#363 refusals: overriding correlation_header silently breaks DonkeyError.correlation_id read-back through classify()
  • ●#366 Quickstart Configure step omits how to get client_id/client_secret
  • ●#379 errors: a typed GatewayUnavailable for transport-level failures
  • ●#383 Move Claude config & skills to a private companion repo
  • ●#397 docs: document @donkey.governed / @donkey.tool decorators (follow-up to #396)
  • ●#400 Sandbox test suite against the provisioned LLM Gateway proxies
  • ●#410 release: add workflow_dispatch → TestPyPI dry-run path (dev snapshots aren't GitHub Releases)
  • ●#413 docs: README logo uses a relative path → broken on the PyPI project page
  • ●#415 docs: document the versioning & naming convention publicly (it lives only in a private skill)
  • ●#418 chore(release): bump version to 0.1.0.dev1 for a fresh TestPyPI dry-run
  • ●#423 Upgrade website to Nextra 4 + Next 16 (supersedes #422)
  • ●#425 Distinguish internal and fork contributors in CONTRIBUTING.md
  • ●#434 docs: build plan still says standing-invariant § anchors resolve into the deleted archive
  • ●#438 chore(website): pin @xmldom/xmldom to 0.9.12 to clear 13 Dependabot alerts
  • ●#440 Set least-privilege GITHUB_TOKEN permissions in ci, nightly-matrix, rebrand-completeness workflows
  • ●#445 Gitignore the .claude/settings.json symlink in the public repo
  • ●#448 bug(skeleton): Donkey.aclose()/close() leaks the control-plane auth's httpx client
  • ●#449 test(skeleton): no unit coverage for the AnypointConnectedApp OAuth2 token path
  • ●#450 docs(skeleton): core/auth.py narrates the (verified) OAuth2 token path as UNVERIFIED
  • ●#451 bug(refusals): classify() AuthError cites control-plane §1 for a data-plane §2 rejection
  • ●#452 bug(budget): pace()+wait_for_reset() recovery loop can livelock after window exhaustion
  • ●#453 test(simulator): packaged (pip install) fixture-resolution path is never exercised
  • ●#454 docs(testing): gateway-identity conformance exemptions asserted in code but not published as credibility
  • ●#455 docs(telemetry): telemetry.mdx banners the shipped OTel GenAI feature as "not yet shipped"
  • ●#456 docs(adapters): adapter import comments falsely claim framework class names are "verified"
  • ●#457 test(adapters): AgentFrameworkAdapter.policy_middleware() and chat_client() blocked-path are uncovered
  • ●#458 chore(cli): refused provisioning control-plane is marketed in --help and exported in top-level __all__
  • ●#459 docs: README headlines "provisioning-as-code" as a flagship capability (a "Do not build" surface)
  • ●#460 docs(cli): stale citations in provisioning/cli.py docstrings (deleted-v1 milestones; wrong BG §1.8)
  • ●#461 test(cli): provisioning spec/planner/applier/lint and the hidden CLI commands have zero coverage
  • ●#462 bug(tools): ToolSet.filter() mutates the receiver in place instead of returning an independent view
  • ●#463 bug(tools): duplicate AssetType symbols — package exports the Enum, AssetRef.type expects the Literal
  • ●#464 test(tools): no test exercises the _verify.blocked() guards in registry/ and tools/session.py
  • ●#465 docs: docs/unsupported-boundary.md is an empty template but README promises it classifies platform APIs
  • ●#471 Distinguish shipped Phase 1 cards from roadmap proposals
  • ●#484 AuthError.remediation gives data-plane advice for control-plane token rejections
  • ●#486 Replace remaining M0/M4 milestone citations outside provisioning
  • ●#487 pace() retry loop spins at zero delay when reset_at is None
  • ●#488 Correct the "one retry" claim for pace() after the window resets
  • ●#489 Inject the clock into pace() and route the e2e retry through pace()
  • ●#491 Expose fixture-lock helpers that work outside a source checkout
  • ●#496 Retire M0/M1/M4 milestone vocabulary outside python/src
  • ●#497 Clarify paired export verification messages
  • ●#501 Cover remaining verification-blocked surfaces
  • ●#504 Reconcile header-only adapters with correlation conformance
  • ●#509 Support JWT/model-wallet auth mode for the LLM proxy data plane
  • ●#510 Document apikey/bearer auth convenience and DDK's two-header stance
  • ●#517 Drop :8081 from the sandbox proxies.toml base_url guidance
  • ●#522 Verify inbound correlation and cost-tag request header names against the live gateway
  • ●#533 Group Typed refusals under the six-piece-minimum sidebar separator
  • ●#535 Docs site typography: tighten sidebar items and hero tagline size
  • ●#541 Document the proxy ingress Format (OpenAI/Anthropic/Gemini) to adapter mapping
  • ●#542 request_id is None on Bedrock routes: x-request-id is the upstream provider's header, not the gateway's
  • ●#548 classify() types a Gemini upstream 400 as a gateway PolicyViolation: list-shaped error envelope is discarded
  • ●#556 epic(docs): restructure the docs site into end-user documentation organised by capability pillars
  • ●#557 docs(intro): rewrite the Introduction around gateway awareness, with architecture and before/after sections
  • ●#558 docs(quickstart): simplify the Quickstart and mark each capability Live or Roadmap
  • ●#559 docs(feature-overview): high-level capability tour with the gateway-aware image
  • ●#560 docs(nav): restructure the sidebar from phase separators into capability pillars
  • ●#561 docs(pages): remove issue refs, phase labels and verification narration from capability pages
  • ●#562 docs(examples): add an Examples pillar built on the donkey-development-kit-demos repo
  • ●#563 docs(roadmap): phases in order with live milestone progress and the issues in each
  • ●#564 docs(community): add a Team (About us) page with Creator/Contributor pills
  • ●#565 docs(community): add a Contribute page condensed from CONTRIBUTING.md
  • ●#566 docs(site): open-source disclaimer footer, metadata and optimised images
  • ●#568 errors: flip Amazon Bedrock Guardrails refusal from documented-only to VERIFIED (LIVE) after the acceptance capture
  • ●#586 last_call.substituted is always True for provider/model names (gateway strips the routing prefix)
  • ●#587 Support gateway semantic caching: steer requests and surface hits
  • ●#590 Surface the semantic-routing match topic and score on last_call
  • ●#592 docs(roadmap): fetch milestone status live from GitHub, keep the snapshot as fallback
  • ●#593 docs(site): sync pages with the current code and the issues filed since the restructure
  • ●#595 errors: PolicyViolation's default remediation still calls content-moderation shapes under-documented
  • ●#597 mypy --strict fails under openai<3 with 4 stale ignore/cast guards
  • ●#601 docs: extend the gateway-identity example with a semantic-routing walkthrough (follow-up to #599)

Phase 1.1 — Stabilize the MVP

Version 0.1.1 · Goal: make the 0.1.0 surface safe and dependable to build on, without adding Phase 2 scope.

Credentials scoped to the plane and the config source they belong to, endpoint trust (no credentials sent to unchecked or non-loopback http:// endpoints), and secrets kept out of printed output and refusal messages. Adapter and transport fixes across the frameworks, a typed AgentKilled refusal for the Agent Kill Switch, an all extra that installs, a native donkey.adk.gemini() model for Gemini-format proxies, and a pass over the docs. Upgrading from 0.1.0? See the migration guide .

100% complete · 83 done · 0 open

Done (83)
  • ●#630 Adapter factories raise TypeError when a governed kwarg is overridden
  • ●#631 LangGraph agent example misdescribes last_call and budget after the loop
  • ●#658 langgraph: surface the gateway's served provider/model per message, not just on last_call
  • ●#659 docs/langgraph: explain model_provider vs the served provider, and how to read it per call and per message
  • ●#660 docs(contributing): codify live-capture, attribution and multi-PR guidelines
  • ●#661 docs: state that Omni/Flex Gateway Local Mode is not supported; the simulator is the local dev loop
  • ●#663 Add a PyPI version badge to the docs site top bar
  • ●#664 Add a PyPI version badge to the org homepage README
  • ●#669 reject.injection-protection fixture has an empty body; live capture returned the real 79-byte message
  • ●#670 reject.injection-protection fixture headers capture only 3 of ~10 live response headers
  • ●#671 Add a PyPI version badge to the package README and drop the hardcoded version
  • ●#674 Split release.yml into publish-pypi and publish-testpypi workflows
  • ●#675 Remove the rebrand-completeness CI guard and migration scaffolding
  • ●#680 Track §8 verification-ledger follow-ups from PR #679 review
  • ●#681 Reconcile §8 constructor-status vocabulary in verified-apis.md
  • ●#682 Fix stale §4 cross-reference for the /responses data plane (should be §2)
  • ●#683 Deduplicate the CrewAI return-class finding across §8 and §8.1
  • ●#684 donkey.crewai.llm() is annotated -> crewai.LLM but returns OpenAICompletion
  • ●#687 Refresh docs/releasing.md wording that predates the 0.1.0 publish
  • ●#688 docs: document how to configure the local simulator's port (CLI flag, serve(), no env var)
  • ●#691 ADK: donkey.adk.gemini() — native Gemini model bound to a Format=Gemini proxy
  • ●#692 Add production-only Cloudflare Web Analytics beacon to the docs site
  • ●#694 classify() mis-types the Agent Kill Switch 403 as UpstreamRequestError
  • ●#697 pip install donkey-kit[all] fails with resolution-too-deep
  • ●#701 donkey.anthropic.client() raises TypeError with anthropic>=1.0 (httpx2)
  • ●#715 bug(errors): export every documented error and give every DonkeyError a remediation
  • ●#716 bug(typing): make governed() and the adapter API type-check for downstream mypy --strict users
  • ●#718 docs(src): stop restating verification status in docstrings and fix the drifted ones
  • ●#725 bug(adapters): back module-level adapter factories with one process-default governed runtime
  • ●#733 bug(adapters): never hand the owning shared client to a framework (Strands closes it after one call)
  • ●#734 bug(adapters): turn off framework retries so a policy refusal is sent exactly once
  • ●#735 bug(adk): guard gemini() against google-adk versions that silently drop the governed client
  • ●#736 bug(langgraph): route sync invoke() through the governed transport and define sync support per adapter
  • ●#737 bug(conformance): never pass, and never reach the network, when the agent bypasses the Donkey client
  • ●#738 bug(anthropic): keep correlation and call IDs on refusals that pass through the httpx2 bridge
  • ●#739 bug(agent-framework): fix or withdraw policy_middleware()
  • ●#741 bug(adapters): raise the same curated missing-dependency error from every form
  • ●#743 bug(deps): raise the extras floors to the lowest verified versions
  • ●#773 docs(config): remove non-existent from_env() kwargs and document the real construction and precedence
  • ●#775 docs: reconcile adapter verification status across README, ARCHITECTURE, the site and verified-apis §8
  • ●#777 docs(migration): fix the conformance flag, the CLI list and the never-emitted telemetry names
  • ●#779 docs(site): label roadmap features on the home page and README extras, and align the discovery sketch
  • ●#781 docs(config): update the header and attribution docs to the verified gateway facts
  • ●#783 docs(conformance): publish the missing JWT-refresh exemption and correct the JWT-capable adapter list
  • ●#785 docs(contributing): remove links to untracked files, dead docs-sync targets and a harness that doesn't exist
  • ●#787 docs(site): fix broken links and anchors, make the PyPI README links absolute, and point site links at main
  • ●#789 docs(architecture): fix the ARCHITECTURE.md divergences from the code
  • ●#791 docs(refusals): fix the typed-refusals example whose except clauses can never fire
  • ●#793 docs(examples): use DonkeyConfig.validated() in the examples and fix the verification contradictions
  • ●#801 bug(simulator): simulate(), donkey mock and the conformance harness must stay offline under HTTP(S)_PROXY
  • ●#803 bug(telemetry): stop binding one correlation ID to the whole async context outside donkey.run()
  • ●#805 bug(telemetry): classify streamed refusals before recording the span
  • ●#807 bug(transport): make the shared async client safe to reuse across event loops
  • ●#809 bug(config): validate config values and raise ConfigError instead of builtin exceptions
  • ●#811 bug(cli): make doctor honour --config/--env, route the entry point through main(), and avoid SystemExit at import
  • ●#813 bug(errors): raise typed errors on the documented surfaces (doctor outage detection, token fetch, closed client)
  • ●#815 bug(config): read [targets] from the XDG config, and never return a negative retry_after
  • ●#817 bug(telemetry): a failing span recorder silently drops streamed usage from donkey.last_call
  • ●#825 bug(refusals): stop typing the bare-model-name 400 as a PolicyViolation
  • ●#826 bug(agent-framework): chat_client() hits /responses; Azure routes 404
  • ●#827 bug(anthropic): last_call misses request-id, cache and streamed tokens
  • ●#828 bug(adapters): jwt mode sends the api_key placeholder as the bearer
  • ●#829 bug(llamaindex): prefixed names get temperature 0.1 and a 3,900 window
  • ●#830 upstream: Gemini-routed chat streams one chat.completion, not chunk deltas
  • ●#833 bug(transport): send LLM-proxy-only headers only on data-plane requests
  • ●#834 bug(ci): install the local and otel extras in the nightly langgraph job so its example smoke step can pass
  • ●#835 bug(adapters): raise ConfigError from the header-only adapter forms in jwt mode
  • ●#836 feat(adapters): add a first-class bearer-token option for LLM-proxy model calls
  • ●#837 bug(config): read ~/.config/.donkey-kit.toml when XDG_CONFIG_HOME is unset
  • ●#838 chore(release): close the pending security advisories after 0.1.1
  • ●#850 donkey.last_call stays UNOBSERVED after ChatOpenAI.ainvoke()
  • ●#865 LangGraph interrupt() in async nodes fails on Python 3.10
  • ●#881 develop is red: CLI entrypoint test asserts the pre-#857 region error
  • ●#882 CLI entrypoint test asserts the pre-#857 unknown-region message, failing CI on every PR
  • ●#883 test_cli_entrypoint asserts the pre-#857 region error, so CI on develop is red
  • ●#891 Make ModelNotRoutable simulatable via simulate() and donkey mock
  • ●#899 Check whether non-LangGraph adapters leave last_call UNOBSERVED after a single async call
  • ●#901 test_main_reports_donkey_error_without_traceback fails on develop after #857 reworded the region error
  • ●#903 Teach the shared-client test helpers about anthropic>=1's bridged httpx2 client
  • ●#907 docs(examples): resync demo 08's verification wording in the framework-objects example
  • ●#909 Serve the SDK docs site from the docs.donkey-kit.dev custom domain
  • ●#915 Update release docs and version references for the 0.1.1 release
  • ●#916 Enable the Cloudflare Web Analytics beacon on docs.donkey-kit.dev

Phase 2 — Differentiate, go beyond

Version 0.2.0 · Goal: capabilities no generic LLM client offers, because they depend on the platform behind the gateway.

Governed tool access (MCP discovery and binding), A2A serve / expose / dev, on-behalf-of identity, human-in-the-loop, scan & publish to the registry with a GitHub Action, declarative refusal handlers and a classification registry for custom policies, typed federated guardrail verdicts, kill-switch awareness with the kill reason, and a second deep framework adapter chosen by demand.

Around them: an inbound correlation ID carried across MCP and A2A hops, a stated concurrency contract for budget and telemetry under parallel fan-out, a per-request business group for shared multi-tenant clients, bring-your-own provider keys, and a token and registry cache. Also in this phase: governed access to TypeSafe Jev , a System One decision model, with the same typed refusals, spans, budget and simulator support as LLM calls, plus worked patterns for confidence-gated review, tool ranking and budget-aware routing. Now that the package is published, the phase also picks up archiving daily PyPI adoption metrics.

2% complete · 1 done · 47 open

Open issues (47)
  • ○#15 core/cache: TTLCache for tokens and registry lookups, with DONKEY_NO_CACHE escape hatch
  • ○#42 tools: ToolSet.filter() — allow/deny/predicate filtering and descriptor token accounting
  • ○#208 refusals: declarative reaction handlers registered once, applied at the transport
  • ○#209 refusals: enforce that a handler can react but never un-refuse
  • ○#210 classify: a registry so custom gateway policies become typed exceptions
  • ○#211 hitl: one vocabulary for pause-and-ask-a-human
  • ○#212 hitl: map the vocabulary onto LangGraph interrupt() and Command(resume=)
  • ○#213 hitl: mappings for OpenAI Agents, ADK, Strands and MCP elicitation
  • ○#214 hitl: route escalation through gateway step-up (Trusted Agent Identity)
  • ○#215 identity: donkey.as_user() — RFC 8693 token exchange and header placement
  • ○#216 identity: a missing or expired user token fails typed, never falls back to service identity
  • ○#217 scanner: donkey scan walks the repo and writes donkey.yaml + agent-card.json
  • ○#218 scanner: donkey publish registers the manifest with Exchange / Agent Registry
  • ○#219 scanner: the scan-and-publish GitHub Action
  • ○#220 killswitch: recognise the kill-switch rejection and stop cleanly
  • ○#221 tools: donkey.tools.discover() returns governed MCP tools as native framework tools
  • ○#222 tools: allow/deny filtering and descriptor token accounting
  • ○#223 adapters: a second deep adapter, chosen by Phase 1 demand
  • ○#224 a2a: donkey.serve() — an A2A listener in one line, wrapping the official a2a-sdk
  • ○#225 a2a: governance-aware inbound — correlation, tags, spans and typed refusals on served tasks
  • ○#226 a2a: donkey expose — provision the A2A proxy, policies and registry entry in one command
  • ○#227 a2a: donkey dev — a gateway in front of the laptop, real or simulated
  • ○#260 epic: Phase 2 — Differentiate, go beyond
  • ○#308 telemetry: adopt an inbound correlation ID and propagate it across MCP and A2A hops
  • ○#310 skeleton: per-request business group for shared, multi-tenant gateway clients
  • ○#311 budget + telemetry: state and test the concurrency contract under parallel fan-out
  • ○#312 tools: a typed refusal for a tool outside the consumer's MCP access profile
  • ○#313 refusals: type federated guardrail verdicts (Akamai, CrowdStrike, Google Armor)
  • ○#314 killswitch: carry the kill reason — manual, anomaly, or eval drift
  • ○#322 testing: --donkey-mode server path for the conformance plugin
  • ○#367 skeleton: bring-your-own-key via a configurable proxy key header (Dynamic key)
  • ○#444 conformance: wire the Phase 2–2.8 scenario bodies as their features land
  • ○#503 scanner: define how a @donkey.tool is attributed to an MCP server / Exchange asset
  • ○#572 epic(jev): support TypeSafe Jev (System One models) as a governed decision surface
  • ○#573 verify: govern TypeSafe's System One endpoint through Omni Gateway and capture its shapes
  • ○#574 adapters: donkey.typesafe — a governed native TypeSafeClient / AsyncTypeSafeClient
  • ○#575 retry: tell a gateway budget 429 apart from TypeSafe's own 429/529 on the Jev route
  • ○#576 refusals: classify System One failures into the DDK error taxonomy
  • ○#577 telemetry: a correlated span per System One call, with usage and confidence
  • ○#578 budget: expose the Jev route's rate-limit window through donkey.budget
  • ○#579 simulator: serve /v1/systemone in donkey mock and simulate()
  • ○#580 spike: run system-one-adapter over a governed DDK proxy (the OpenAI-compatible route)
  • ○#581 example(jev): confidence-gated human review through the HITL vocabulary
  • ○#582 example(jev): rank governed MCP tools and A2A agents with a Choice question
  • ○#583 example(jev): advisory pre-screen to avoid gateway refusals (gateway stays the enforcement point)
  • ○#584 example(jev): budget-aware cascade across code, small and large governed models
  • ○#585 docs(site): document TypeSafe Jev support, examples and System One sections
Done (1)
  • ●#309 skeleton: surface gateway-side routing and fallback, and never double-retry it

Phase 3 — Platform capabilities

Version 0.3.0 · Goal: agents that know the rules before they call, not only after they are refused.

The policy handshake (read the in-force policy set, advisory only), policy updates pushed to the code at run boundaries, a governed structured-output path, a model catalog with honest model resolution, evaluation hooks on the run span, monetary spend and wallet warnings, custom cost dimensions, and run-level cost rollups. Much of this phase depends on new gateway endpoints tracked under Upstream gaps.

0% complete · 0 done · 10 open

Open issues (10)
  • ○#19 llm/catalog: ModelHandle, resolve(), and an honest list_models() with no /models endpoint
  • ○#228 policies: the policy handshake client — read the in-force policy set
  • ○#229 policies: advisory only — the gateway always wins, and the client learns from the refusal
  • ○#230 policies: to-the-code push — refresh at run boundaries, never mid-run
  • ○#231 llm: keep the .parse() structured-output path governed, and support it in the simulator
  • ○#232 telemetry: evaluation hooks that attach a score to the run span
  • ○#261 epic: Phase 3 — Platform capabilities
  • ○#315 budget: monetary spend and the wallet threshold warning
  • ○#316 telemetry: arbitrary validated cost dimensions beyond the fixed four
  • ○#317 telemetry: a run-scoped rollup answering "what did this task cost"

Phase 4 — Enterprise readiness

Version 0.4.0 · Goal: everything a security, compliance and platform team asks for before rolling DDK out broadly.

Independent security review and supply-chain hardening, a latency and overhead budget enforced in CI, a full pass over every error message, the public API contract and deprecation policy, compliance evidence mapping (EU AI Act Art. 12, ISO 42001, OWASP LLM Top 10), log shipping, data residency, workload identity, air-gapped operation, opt-in gateway failover, a clear boundary against the platform’s infrastructure-as-code, and a support model with a release cadence.

0% complete · 0 done · 14 open

Open issues (14)
  • ○#233 security: independent security review and supply-chain hardening
  • ○#234 perf: a latency and overhead budget enforced in CI
  • ○#235 errors: a full pass over every remediation string and error message
  • ○#236 docs: migration guide, deprecation policy, and the public API contract
  • ○#237 compliance: map correlation and span data to EU AI Act Art. 12 and ISO 42001 evidence
  • ○#238 telemetry: structured log shipping to the control plane
  • ○#239 config: data-residency and region routing hints
  • ○#240 identity: evaluate workload identity (SPIFFE / Entra Agent ID) for agent-to-gateway auth
  • ○#241 ops: support model, issue templates and release cadence
  • ○#262 epic: Phase 4 — Enterprise readiness
  • ○#318 refusals: map the typed refusal taxonomy to the OWASP LLM Top 10
  • ○#319 provisioning: state the boundary against the platform's LLM Gateway IaC
  • ○#320 ops: air-gapped and private-cloud operation, proved by an egress-denied CI job
  • ○#380 skeleton: opt-in failover to a second Connected-Mode gateway endpoint

Phase 5 — Complete rollout

Version 1.0.0 · Goal: a stable, multi-language SDK with guarantees.

A TypeScript port of the core capabilities with conformance scenarios shared across Python and TypeScript, the remaining framework adapters brought to the full bar by demand, framework-docs partnerships and launch channels, and the 1.0 release with stability guarantees.

0% complete · 0 done · 6 open

Open issues (6)
  • ○#242 typescript: port the six-piece minimum
  • ○#243 typescript: shared conformance scenarios across Python and TypeScript
  • ○#244 adapters: bring back remaining frameworks by demand, each to the full bar
  • ○#245 gtm: framework-docs partner PRs and launch channels
  • ○#246 release: 1.0.0 with stability guarantees
  • ○#263 epic: Phase 5 — Complete rollout

Cross-cutting tracks

These milestones run alongside every phase.

VerificationIn progress

Every endpoint, header, class name and constructor argument DDK relies on is checked against the real platform and the installed framework packages before features are built on it. The semantic-caching and semantic-routing header contracts are now live-captured; next up is scoping mTLS as a consumer auth option for the LLM proxy.

26% complete · 12 done · 34 open

Open issues (34)
  • ○#1 Epic: M0 — verify every endpoint, header and class name before building on it
  • ○#21 Verify the business-group attribution header name (highest-priority M0 unknown)
  • ○#22 Verify Anypoint control-plane region hosts for EU, CA and JP Hyperforce
  • ○#23 Verify connected-app scopes and admin-context requirements per operation
  • ○#34 Verify the eight framework constructor signatures against installed packages (§8)
  • ○#53 Verify the Exchange asset search API and whether wildcard query is server-side
  • ○#54 Verify whether applied policies can be fetched in bulk per environment
  • ○#79 Verify Exchange publication mechanics: metadata/tags for the digest, lifecycle states, docs pages
  • ○#88 Verify the MCP Bridge provisioning API, or confirm the Terraform/CLI fallback
  • ○#101 meta: verified-apis.md as the living source of truth, and the _verify.blocked discipline
  • ○#114 Verify Exchange draft/unlisted publication states and provenance metadata for scanner-derived assets
  • ○#123 Verify Flex Gateway Connected Mode registration from a laptop or CI runner, and the per-developer instance cost
  • ○#135 Verify PDK capabilities before any custom policy is designed (§6.9.7)
  • ○#253 verify: re-confirm the v1.11-v1.13 rejection contracts against current docs and a sandbox
  • ○#254 verify: the A2A proxy provisioning API, or confirm there is no supported path
  • ○#255 verify: the Trusted Agent Identity token-exchange endpoint and header
  • ○#257 verify: whether Anypoint Monitoring or Agent Visualizer ingests OTLP GenAI spans
  • ○#258 verify: self-managed gateway image availability and licensing for local development
  • ○#279 verify: whether the local simulator can be hosted on a2d-ai.com
  • ○#300 verify: whether the gateway echoes the client x-correlation-id or mints its own
  • ○#302 verify: upstream error envelopes for Bedrock, Gemini and Microsoft Foundry
  • ○#303 verify: the MCP access-profile denial shape
  • ○#305 verify: federated guardrail verdict shapes for Akamai, CrowdStrike and Google Armor
  • ○#607 Scope and verify mTLS as a consumer auth option for the LLM proxy
  • ○#636 verify(adk): installed constructor, MCP binding and descriptor APIs (§§8–10)
  • ○#637 verify(strands): installed constructor, MCP binding and descriptor APIs (§§8–10)
  • ○#638 verify(openai_agents): installed constructor, MCP binding and descriptor APIs (§§8–10)
  • ○#639 verify(anthropic): installed constructor, MCP binding and descriptor APIs (§§8–10)
  • ○#641 verify(llamaindex): installed constructor, MCP binding and descriptor APIs (§§8–10)
  • ○#642 verify(langgraph): installed constructor, MCP binding and descriptor APIs (§§8–10)
  • ○#652 verify(agent-framework): MCP binding and descriptor APIs (§§9–10)
  • ○#653 verify(fastmcp): native versus protocol tool descriptors (§10)
  • ○#704 verify: model-wallet Spend (USD) budget refusal shape
  • ○#894 verification: capture /chat/completions and /responses per upstream as §2 fixtures
Done (12)
  • ●#65 Verify Local Mode capabilities: can it run the LLM Proxy and MCP Bridge, and does it need a licence artifact
  • ●#256 verify: the Agent Kill Switch rejection shape
  • ●#301 verify: model-wallet spend headers and the threshold-warning signal
  • ●#304 verify: the Anthropic-native Messages route on the LLM proxy
  • ●#354 docs/verify: answer #253 — the live 200 does carry budget state, as prose in x-llm-proxy-ratelimit
  • ●#372 verify: model-wallet JWT ingress auth (X-Client-Id + client_id claim, IdP/JWKS)
  • ●#520 agent_framework.chat_client() passes an unsupported model_id kwarg
  • ●#540 verify: whether the LLM proxy exposes a Gemini-native ingress route
  • ●#588 verify: the semantic-caching policy header contract on the LLM proxy
  • ●#589 verify: the semantic-routing success header (topic + score) on the LLM proxy
  • ●#640 verify(crewai): installed constructor, MCP binding and descriptor APIs (§§8–10)
  • ●#650 verify(local): registration prerequisite and stock-image policy probes

Requests to the Omni Gateway team for platform capabilities DDK needs — such as a budget-query endpoint, policy discovery, a dry-run mode and richer guardrail verdicts. They land whenever the gateway ships them.

0% complete · 0 done · 7 open

Open issues (7)
  • ○#247 upstream: 429 carries no Retry-After, only x-token-reset
  • ○#248 upstream: no budget-query endpoint — remaining budget is only visible in-band
  • ○#249 upstream: no policy-discovery endpoint — clients cannot ask what is in force
  • ○#250 upstream: no dry-run mode — policy cannot be evaluated without blocking
  • ○#251 upstream: guardrail-verdict error contract is under-documented
  • ○#252 upstream: no outbound-connect or tunnel path for A2A ingress
  • ○#381 upstream: no highly available or multi-region LLM proxy endpoint

What DDK will not build

At each of these boundaries the job is to make the platform’s own capability reachable and typed, not to reproduce it:

  • Client-side policy enforcement — the gateway is the enforcement point.
  • Client-side semantic caching — DDK steers the gateway’s semantic cache and reports hits, but never caches responses itself.
  • A provisioning control plane competing with API Manager or Terraform.
  • Re-implementations of Agent Scanners, Kill Switch or Trusted Agent Identity.
  • An approval UI or queue.
  • An evaluation framework.
  • The gateway inside your agent process.
  • A home-grown A2A protocol implementation — the official a2a-sdk is used.
Last updated on