)]}'
{
  "log": [
    {
      "commit": "c10fd2a481240cbdbc5ed900128ac651c7e9aea0",
      "tree": "74a6e42b7939291a62f99229498428b4122aae41",
      "parents": [
        "624585d23aea8790eca33483c30c3c94a528834a"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Wed Sep 23 16:58:05 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 23 16:58:05 2026 +0800"
      },
      "message": "[ISSUE #5411] Serve the legacy SDK gRPC protocol on the v2 runtime (port 10205 bridge) + connector plugin tests 23/23 (#5412)\n\n* [ISSUE #5411] Serve the legacy SDK gRPC protocol on the v2 runtime (port 10205 bridge)\n\nEventMeshGrpcServer binds PublisherService/ConsumerService/HeartbeatService on\neventmesh.grpc.port (opt-in, 0/-1 \u003d off) and maps every call onto the v2\nUniIngressService pipeline (WAL at-least-once, shared retry/DLQ):\n- publish/batchPublish/publishOneWay/batchPublishOneWay -\u003e ingress.publish (topic \u003d subject)\n- requestReply -\u003e ingress.request with the legacy TTL attribute\n- webhook subscribe -\u003e WebHookChannel target; CLUSTERING-\u003eLOAD_BALANCE, BROADCASTING-\u003eBROADCAST\n- subscribeStream (bidi) -\u003e GrpcStreamChannel push target, ACKs ride back on the stream\n- heartbeat -\u003e GrpcClientRegistry TTL refresh + reaper unsubscribes stale clients\nGrpcCloudEventMapper holds the proto\u003c-\u003ev2 CloudEvent mapping + legacy Response envelope.\nruleGrpcProtocolHidden grants the sanctioned runtime.grpc.. adapter (TCP-rule precedent).\n\n* [ISSUE #5411] gRPC bridge tests: hermetic mapping unit tests + real-SDK integration\n\nGrpcCloudEventMapperTest covers every proto attribute flavor + the 3-key response\nenvelope. GrpcLegacyBridgeIntegrationTest boots the bridge over the in-memory\nstorage and drives it with the real EventMeshGrpcProducer/Consumer (the SDK as its\nown conformance suite): publish, batch publish, stream subscription round-trip.\n\n* Add unit tests for the remaining 19 connector plugins (23/23 coverage)\n\nHermetic where possible: webhook sinks (dingtalk/http/knative/lark/slack/wechat/\nwecom/chatgpt) verified against a local capturing HTTP server; mcp (JSON-RPC\nenvelope), openfunction (Ce-* context headers), prometheus (single merged push),\nspring (EventForwarder contract) exercised with their exact wire contracts;\nwebhook sources (10 plugins) POST their native callback payloads through the\nlazy-bound hook port; prometheus/spring sources cover scrape + buffer drains;\nexternal-client plugins (canal/jdbc/mongodb/rabbitmq/redis/s3/pravega) get\ncontract-level tests (init config-parse where lazy, commit no-op) since their\nbackends cannot boot in CI. Closes the \"4 of 23 plugins carry the only unit\ntests\" gap tracked under the #5296 review.\n\n* [ISSUE #5411] docs: legacy gRPC bridge served (opt-in); Connector Runtime test status\n\nconfiguration.md flips eventmesh.grpc.port from RESERVED to served (opt-in, 1.x\ndefault 10205); protocols.md gains the legacy-gRPC mapping table section; both\nREADMEs note the served bridge and update the Connector Runtime row to 23/23\nplugin test coverage (drops the stale \"4 of 23\" wording).\n\n* docs: make the Connector Runtime GA-criteria cell concrete\n\nReplace the vague \"GA criteria tracked under the #5296 architecture review\"\nwording with the actual remaining GA blockers: per-plugin real-backend\nintegration tests and the connector-runtime HA story. Also reference #5412\nfor the 23/23 unit-test coverage.\n\n* docs: refresh remaining cross-references for the #5411 bridge and 23/23 tests\n\n- deployment.md: connector-runtime status drops the stale \"only 4 of 23\n  plugins carry unit tests\" (now 23/23 since #5412; real-backend ITs stay\n  the GA gate)\n- architecture/overview.md: protocol-status bullet + legacy-SDK paragraph\n  mention the served opt-in gRPC bridge; Key-classes table gains the\n  EventMeshGrpcServer entry\n- quickstart/getting-started.md: port list mentions the opt-in 10205\n  legacy gRPC bridge"
    },
    {
      "commit": "624585d23aea8790eca33483c30c3c94a528834a",
      "tree": "80421645545b90f28a78057bb39f35a0392c85dd",
      "parents": [
        "2c738b7d71d104a11ba0b5bd350e4c062db1e7b6"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Tue Sep 22 09:34:40 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 22 09:34:40 2026 +0800"
      },
      "message": "Docs: agent story cross-links + capability Beta promotions (landed after #5409 was merged) (#5410)\n\nThese changes were pushed to the #5409 branch minutes after it was squash-merged\nand missed the merge; resubmitting on top of develop:/n/n- README.md / README.zh-CN.md: LLM streaming agent runtime feature bullet,\n  Agent tools \u0026 event triggers capability row, docs-list entries\n- Connector Runtime and A2A / Agent Gateway promoted to Beta (the\n  Testcontainers E2E gate #5340 closed 2026-09)\n- docs/feature/a2a.md: Related capabilities section pairing A2A with the\n  streaming agent runtime\n- docs/index.md: A2A entry cross-links agent-tools"
    },
    {
      "commit": "2c738b7d71d104a11ba0b5bd350e4c062db1e7b6",
      "tree": "3920281ddd993354648cd8589265e9ff1267a0d0",
      "parents": [
        "705163f25c238460f98dba99b5972c8a1d61c20d"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Mon Sep 21 19:30:59 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Sep 21 19:30:59 2026 +0800"
      },
      "message": "AgentTool SPI + module restructure: agent-plugin tree, agent -\u003e agent-runtime, connector-api under connector-plugin (follow-up to #5408) (#5409)\n\n* AgentTool SPI: plugin-jar deployment for custom agent tools\n\n- Annotate AgentTool with @EventMeshSPI (new AGENT_TOOL extension type);\n  custom tools now register via META-INF/eventmesh/\u003cAgentTool-FQCN\u003e service\n  files exactly like storage/connector plugins\n- ToolRegistry.registerSpi(name) resolves implementations through\n  EventMeshExtensionFactory (singleton semantics, classpath + plugin-jar\n  loaders)\n- AgentApplication: -Dagent.tools.spi\u003d\u003cname,...\u003e enables SPI tools alongside\n  connector-backed tools\n- start-agent.sh: jars under plugin/agent/ join the agent classpath (same\n  convention as plugin/connector/ in the connector runtime)\n- Tests: AgentToolSpiTest drives the real factory + a test service file\n  (echo-test) through registerSpi; unknown-name rejection path covered\n- Docs: agent-tools.md SPI section + config-table entry; agent.properties\n  key doc\n\n* AgentTool SPI follow-up: module restructure — connector-api under connector-plugin, agent -\u003e agent-runtime, new agent-plugin tree\n\n- Move eventmesh-connector-api -\u003e eventmesh-connector-plugin/eventmesh-connector-api\n  (SPI jar lives with its plugin family, like storage/protocol)\n- Rename eventmesh-agent -\u003e eventmesh-agent-runtime (it is a process runtime, matching\n  eventmesh-connector-runtime)\n- New eventmesh-agent-plugin/ tree: umbrella + eventmesh-agent-plugin-http-fetch (first\n  in-tree AgentTool plugin: fetch a URL, return truncated body; pluginType\u003dagentTool,\n  pluginName\u003dhttp-fetch, META-INF service file included)\n- dist-agent now installs pluginType\u003d\u003dagentTool modules into dist-agent/plugin/agent/\u003cname\u003e/\n  (same convention as dist-connector/plugin/connector)\n- References updated: settings.gradle, root build.gradle (findProject paths), all 23\n  connector plugin build files, architecture-guard, runtime test dep, docs\n\n* Fix restructure: point connector-runtime at the moved connector-api module path\n\n* Fix restructure: point all 23 connector plugins at the moved connector-api path (double-quote form)\n\n* Fix restructure: update connector-api-split.md paths to the moved module\n\n* Fix http-fetch plugin: drop unused @Slf4j/lombok, slim deps (spi types resolve via agent-runtime)"
    },
    {
      "commit": "705163f25c238460f98dba99b5972c8a1d61c20d",
      "tree": "33c30f26e741fb389e226817fd15327f3494eac0",
      "parents": [
        "2d1dc1a137584d3f151c68330558c7de080964da"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Mon Sep 21 16:36:51 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Sep 21 16:36:51 2026 +0800"
      },
      "message": "Agent extension points: LlmClient/ConversationMemory SPI, connector-backed agent tools and event triggers (#5408)\n\n- Extract the LlmClient SPI (token streaming + function-calling chat);\n  OpenAiLlmClient becomes its default implementation\n- Extract the ConversationMemory SPI; ConversationStore (in-memory sliding\n  window) implements it\n- Add the AgentTool SPI + ToolRegistry and a bounded function-calling loop\n  in StreamingAgent (streaming unchanged when no tools are registered)\n- Add ConnectorToolAdapter: any sink connector becomes a write tool and any\n  source connector a read tool, turning the 23 shipped connector plugins\n  into the agent tool library\n- Add an event-driven trigger path: agent.subscribe.topics -\u003e prompt -\u003e\n  answer (with tools) -\u003e published to agent.trigger.output.topic for sink\n  delivery\n- Fix runtime-port drift in agent/connector/examples defaults: 8080 -\u003e 10105\n- Docs: docs/feature/agent-tools.md + index entry"
    },
    {
      "commit": "2d1dc1a137584d3f151c68330558c7de080964da",
      "tree": "92fffed0a43a24170a1bfa6bae689615759f99cc",
      "parents": [
        "66727b61bab937e02a50a734324e69a0479d011a"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Mon Sep 21 14:20:27 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Sep 21 14:20:27 2026 +0800"
      },
      "message": "[ISSUE #5405] A2A gateway production wiring: main-process boot, RocksDB task store, auth, metrics, contextId (#5406)\n\n* [ISSUE #5405] A2A gateway production wiring: main-process boot, RocksDB task store, auth, metrics, contextId\n\nThe A2A gateway was component-complete but never wired for production:\nEventMeshA2ATransport (the real transport bridged onto UniIngressService)\nexisted unused, EventMeshApplication never booted the gateway, and the only\nTaskStore backend required Nacos.\n\n- EventMeshApplication.withA2aGateway(...): boots the Netty REST plane\n  (/a2a/*) with the main process, wired onto the REAL transport, plus a\n  TaskExpirer reaper. Opt-in via -Deventmesh.a2a.enabled\u003dtrue, port\n  -Deventmesh.a2a.port\u003d10108, graceful shutdown included.\n- RocksDBTaskStore: local durable TaskStore under \u003cdata\u003e/a2a-tasks (same\n  dir layout as offsets/delivery-state), wire-format compatible with the\n  MetaBacked v1 envelope. Default when no Meta is configured;\n  -Deventmesh.a2a.taskstore\u003dmeta selects the cluster-shared store.\n- Bearer-token auth on the gateway REST plane\n  (-Deventmesh.a2a.token, constant-time compare, same pattern as the admin\n  token guard #5364); without a token the gateway is open (dev mode,\n  logged at boot).\n- A2A metrics: submitted/completed/failed/canceled/expired counters plus\n  an active-task gauge, surfaced via /admin/metrics JSON and the\n  /metrics Prometheus scrape.\n- Traffic-port guidance (#5225 class confusion): a JSON-RPC body posted\n  to /events/publish now returns a 400 pointing at the A2A gateway\n  endpoints instead of an opaque CloudEvent transform error.\n- contextId passthrough (issue #5405): optional conversation linkage on\n  task submit, persisted in TaskRecord (10th wire field, v1 readers\n  ignore the suffix), echoed in snapshots.\n\nTests: RocksDBTaskStoreTest (round-trip, epoch CAS, duplicate rejection,\ncontextId persistence, expiry, reopen durability) and\nA2AGatewayWiringTest (main-process boot + health, token 401/200,\ncontextId through the REST round-trip into the durable store).\n\n* [ISSUE #5405] A2A gateway production wiring + agent-process hardening\n\nGateway plane (items 1-6): main-process boot via withA2aGateway +\n-Deventmesh.a2a.enabled\u003dtrue (port 10108) on the REAL transport\n(EventMeshA2ATransport -\u003e UniIngressService); RocksDBTaskStore local default\n(\u003cdata\u003e/a2a-tasks, MetaBacked-compatible v1 wire format); bearer-token auth\n(-Deventmesh.a2a.token, constant-time); A2A metrics in /admin/metrics and the\n/metrics Prometheus scrape; traffic-port guidance for #5225-style JSON-RPC\nmisposts; contextId conversation linkage persisted and echoed.\n\nAgent plane (items 7-11): default agent.runtime.url 8080 -\u003e 10105; new\nbin/start-agent.sh launcher (the dist-agent task referenced a bin/ that never\nexisted); ConversationStore bounded conversation count with access-order LRU\neviction (agent.conversation.maxConversations); fail-fast on an empty\nllm.api.key (llm.api.key.optional\u003dtrue opts out for mock gateways);\nheartbeat consecutive-failure limit (agent.heartbeat.failLimit, default 6)\nexits the process for supervisor restart instead of serving as a zombie;\nnew docs/feature/agent.md.\n\nBug fix found by the new wiring test: A2AGatewayHttpHandler lacked @Sharable -\nthe gateway could only ever serve ONE HTTP connection (the second channel hit\nChannelPipelineException; all existing tests used a single request).\nA2AGatewayServer.getPort() now resolves the auto-selected port (0).\n\nAlso normalizes the nonstandard license headers on 8 deploy/kubernetes/*.yaml\nfiles (#5398 leftovers) so the license check passes.\n\nTests: RocksDBTaskStoreTest (7), A2AGatewayWiringTest (3), agent\nConversationStoreTest (+2: LRU eviction, unbounded-compat), existing a2a\nsuite green; checkstyleMain/Test clean; dependency-review green."
    },
    {
      "commit": "66727b61bab937e02a50a734324e69a0479d011a",
      "tree": "ee8372d21a570c242d74efc0282d89b7932cc8a1",
      "parents": [
        "be3bf93e0b12a68bd83ca226ede764ee813c9b94"
      ],
      "author": {
        "name": "qqeasonchen",
        "email": "qqeasonchen@gmail.com",
        "time": "Thu Sep 17 20:01:15 2026 +0800"
      },
      "committer": {
        "name": "qqeasonchen",
        "email": "qqeasonchen@gmail.com",
        "time": "Thu Sep 17 20:01:15 2026 +0800"
      },
      "message": "feat: restore the 1.x default port scheme - 10105 traffic / 10106 admin, A2A to 10108, 10205 gRPC reserved\n\n8080/8081 collide with the most common dev-service ports (Tomcat, Jenkins,\nSpring Boot apps, proxies). Move back onto the project\u0027s own 1.x default\nport block, which keeps long-time users on familiar numbers:/n\n- traffic HTTP 8080 -\u003e 10105 (all app protocols multiplex on it, incl.\n  the legacy /eventmesh/* bridge)\n- admin HTTP    8081 -\u003e 10106\n- WebSocket     8082 -\u003e 10107 (opt-in, unchanged default -1)\n- A2A Gateway   10105 -\u003e 10108 (frees 10105 for the CORE runtime; the\n  experimental gateway takes the adjacent 10108)\n- 10205 documented as RESERVED for a future gRPC protocol port (the 1.x\n  default): the uni runtime does not ship a gRPC server yet, and the\n  port must not be casually taken so a later gRPC addition lands on the\n  historical number\n\nTouched: EventMeshApplication defaults, bin/start.sh, docker/Dockerfile(+.connector),\nK8s manifests + README, SDK CloudEventsClient default URL + javadocs, A2AClient /\nExampleConstants / A2AGatewayDemo, e2e test literals, docs (quickstart,\nconfiguration, deployment, a2a) and eventmesh.properties comments.\n\nConfiguration keys are unchanged - only defaults move; existing\ndeployments pinning the old ports keep working.\n\nAlso point image-smoke-test.yml at the new ports throughout (host \u003d container,\n10105/10106 - no offset mapping left).\n\nREADME / README.zh-CN quick-start port mentions updated too.\n\nFeature docs swept too (client-java, pubsub, streaming, introduction, index,\nadmin-api, http-api, observability, connectors overview) - connector-local\nwebhook ports are untouched.\n\nFix a port-sweep typo (10100 -\u003e 10105) in the documentation map.\n\nREADME / README.zh-CN capability-status refreshed against the current tree:/n- SSE/WS push: ACK-tracked redelivery + DLQ shared with long-polling\n  (ReliableDispatcher); e2e-real-broker suite in #5389\n- Connector Runtime: all 23 plugins fully implemented since #5394 (no\n  template stubs left); 4 of 23 still carry the only unit tests\n- A2A Gateway: reaper + Meta-backed agent cards landed #5346, quota #5373;\n  Beta promotion gated on Testcontainers E2E (#5340)\n- new Memory storage row (Beta, zero-dependency dev/CI default, #5400)\n"
    },
    {
      "commit": "be3bf93e0b12a68bd83ca226ede764ee813c9b94",
      "tree": "14b78906f996a5e6c853fbd6600134f8c0929b88",
      "parents": [
        "7b487a2b659dd17c5d0e1f31d11a83c949f8aa7b"
      ],
      "author": {
        "name": "qqeasonchen",
        "email": "qqeasonchen@gmail.com",
        "time": "Wed Sep 16 16:54:12 2026 +0800"
      },
      "committer": {
        "name": "qqeasonchen",
        "email": "qqeasonchen@gmail.com",
        "time": "Wed Sep 16 16:54:12 2026 +0800"
      },
      "message": "ci: restore CI (ASF allowlist), build Docker images on develop push with smoke-tested snapshot + latest tags (#5403)\n\nEvery workflow run on this repo had been dying with instant startup_failure\n(0 jobs, no runner) for months. Root cause: the Apache org enforces\nSHA-pinned, allowlisted third-party actions (apache/infrastructure-actions)\nand our workflows referenced non-allowlisted refs.\n\nWorkflows (ci, code-scanning, license, architecture-guard, auto-dependabot,\nstale, greetings, docker):\n- Pin every action to its allowlisted commit SHA: actions/checkout v6,\n  actions/setup-java v5, github/codeql-action v3, actions/stale v8,\n  actions/first-interaction v1.3.0, docker login v4.6.0 / metadata v6.2.0 /\n  build-push v7.3.0\n- gradle/actions/setup-gradle -\u003e v5.0.2 (07231958, allowlist keep:true; the\n  old v6.1.0 SHA is not listed - v6 has a licensing model change,\n  infrastructure-actions#953)\n- dependabot/fetch-metadata -\u003e v3.1.0 (25dd0e34, only listed version)\n\ndocker.yml:\n- Triggers: push to develop + workflow_dispatch (release unchanged)\n- Tags: 2.0.0-snapshot + latest on develop push/dispatch so the default\n  pull always gets the newest 2.0.0 build; latest + vX.Y.Z on release\n- Connector image leg removed until the apache/eventmesh-connector Docker\n  Hub repository exists (its push is denied today)\n\nRuntime image boot fixes (found by the new smoke test, never exercised\nbefore because CI never ran):\n- conf/log4j2.xml: drop an accidentally duplicated XML-decl + license\n  header that broke log4j2 parsing (\"No logging configuration\")\n- docker/Dockerfile: create data/ and logs/ with eventmesh ownership -\n  a bare VOLUME gets a root-owned mountpoint and the uid-10001 process\n  died with RocksDB EACCES\n- eventmesh-protocol-cloudevents / -a2a: add gradle.properties\n  (pluginType\u003dprotocol) so installPlugin ships them in the image -\n  publish used to fail with 400 \"FrameAdaptor \u0027cloudevents\u0027 not found\"\n\nAlso: image-smoke-test.yml (workflow_dispatch) pulls the published image\nand runs the quick-start flow against it; fix the pre-existing checkstyle\nviolations in 4 runtime IT files that the first real CI run exposed.\n\nVerified: image boots to healthy in 2s (storage\u003dmemory, zero broker),\nsubscribe 200, publish 202, poll delivers the event.\n\ndocs(quickstart): fix the §5 curl examples to match the actual HTTP contract\n(verified against the published image): poll takes clientId/max/timeoutMs (no\ntopics param, timeoutMs not timeout); ack takes a single {\"deliveryId\"} body,\nnot a deliveryIds array. The old examples were written from the 1.x layout\nand had never matched the uni-runtime server.\n\nAlso refresh the quickstart/feature docs (folded from two follow-ups):\n- getting-started §5 curl examples fixed to the real HTTP contract (poll\n  clientId/max/timeoutMs; single-field {\"deliveryId\"} ack), verified\n  against the published image\n- a2a.md: English title/TOC/headings; a2a-readiness.md decision-log page\n  removed (internal archive; review/ evidence reference kept on purpose)\n- a2a.md \u003cbr\u003e tags self-closed for MDX/Docusaurus compatibility (bare\n  \u003cbr\u003e breaks the site build, not visible on GitHub)\n\nDocker publishing is manual-trigger only (workflow_dispatch) plus release -\ndropped the push-to-develop trigger so merges do not spend ~25min of image\nbuild/push per commit; run the workflow on demand for snapshot/latest.\n"
    },
    {
      "commit": "7b487a2b659dd17c5d0e1f31d11a83c949f8aa7b",
      "tree": "df090bcb7a729260e04c8b35d53556185d3f38d4",
      "parents": [
        "49a86751c2cc3180ea99ab34b26cfbd52cda21b5"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Tue Sep 15 15:57:58 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 15 15:57:58 2026 +0800"
      },
      "message": "[ISSUE #5401] Bump develop project version to 2.0.0-SNAPSHOT (#5402)\n\nThe develop branch carries the 2.0.0 architecture but the build still\nreports the 1.x lineage version 1.12.0-release. Flip the single version\ndefinition in gradle.properties to 2.0.0-SNAPSHOT (dev-cycle convention;\nbuild.gradle already branches on endsWith(SNAPSHOT) for the ASF snapshots\nrepository on publish)."
    },
    {
      "commit": "49a86751c2cc3180ea99ab34b26cfbd52cda21b5",
      "tree": "85a9f2d46ee8cfc84c1672253d326124e4d81da1",
      "parents": [
        "c9f9dedd74033be8bdaaebc93864b734a6d0fdf6"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Tue Sep 15 15:57:34 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 15 15:57:34 2026 +0800"
      },
      "message": "[ISSUE #5399] Add eventmesh-storage-memory in-memory storage plugin (#5400)\n\n* [ISSUE #5399] Add eventmesh-storage-memory in-memory storage plugin\n\n- New module eventmesh-storage-plugin:eventmesh-storage-memory:/n  MemoryMeshStoragePlugin implements MeshStoragePlugin + all 7 StorageCapabilities\n  sub-interfaces (production-scope promotion of the InMemoryStoragePlugin TCK\n  self-test fixture from eventmesh-storage-api src/test).\n- SPI registration memory\u003dorg.apache.eventmesh.storage.memory.MemoryMeshStoragePlugin\n  (select with EVENTMESH_STORAGE_TYPE\u003dmemory).\n- settings.gradle module include.\n- docs/feature/storage-spi.md capability matrix gains a Memory column.\n- TCK subclass MemoryMeshStoragePluginTCKTest + round-trip unit tests.\n\n* [ISSUE #5399] Make memory the zero-dependency default + add memory e2e test\n\n- MemoryStorageE2EIntegrationTest: always-on publish-\u003esubscribe-\u003epoll-\u003eack-\u003e\n  offset-advance round trip over the full UniRuntime path with the memory plugin\n  loaded via SPI. No broker, no -D gate - runs on every CI build.\n- eventmesh-storage-memory/gradle.properties: pluginType\u003dstorage/pluginName\u003dmemory\n  so installPlugin ships the plugin jar in the runtime image.\n- Default storage switched to memory for zero-dependency quick start:\n  docker/Dockerfile (ENV EVENTMESH_STORAGE_TYPE\u003dmemory), k8s runtime-statefulset,\n  EventMeshApplication system-property default (\"standalone\"-\u003e\"memory\"),\n  conf/eventmesh.properties backend list.\n- Docs: getting-started (docker run with no env / source path / backend table),\n  configuration.md (memory section + default), k8s README + configmap comments.\n- eventmesh-runtime test classpath gains the memory plugin.\n\n* [ISSUE #5399] Honor the self-resume pull contract in MemoryMeshStoragePlugin\n\nThe runtime pull-loop calls storage.poll(topic, partition, -1, ...) where\nstartOffset\u003c0 means \"resume from the plugin-managed position\" (Kafka/RocketMQ\nuse the consumer position). The TCK-fixture- inherited implementation returned\nthe whole log from offset 0 on every tick, which under the real pull-loop would\nre-dispatch all history each tick.\n\n- poll(): keep a per-(topic, partition) cursor; startOffset\u003c0 resumes from it,\n  advance it after each successful batch.\n- alignPullOffset(): rewind that same per-key cursor (was a single global\n  counter in the fixture), wiring the ACK-timeout redelivery path.\n\n* [ISSUE #5399] checkstyle: drop unused import in MemoryMeshStoragePluginTCKTest"
    },
    {
      "commit": "c9f9dedd74033be8bdaaebc93864b734a6d0fdf6",
      "tree": "0fbbec872c1f19c8a36fe7ae0ad2ca856745c6b3",
      "parents": [
        "62d51db4857ab0568630a0c1e3512a7be0e95fcb"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Mon Sep 14 19:16:01 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Sep 14 19:16:01 2026 +0800"
      },
      "message": "feat(deploy): add Kubernetes manifests for runtime + connector-runtime (#5398)\n\nFixes #5397 (Phase 1).\n\n- deploy/kubernetes/: namespace, runtime StatefulSet (PVC-backed\n  RocksDB offsets, /admin/health probes, non-root uid 10001, admin\n  token from Secret via dependent JAVA_OPTS env), runtime Service,\n  connector Deployment (uid 10002, process liveness), ConfigMaps for\n  eventmesh.properties (subPath mount) and CONNECTOR_OPTS, kustomization.\n- README covers quick start, per-file purpose, scaling semantics\n  (LOCAL_STICKY_PULL vs PARTITION_OWNED_PULL + meta keys).\n- docs/feature/deployment.md gains a Kubernetes section.\n\nFollow-ups (tracked in #5397): Helm chart; operator-path decision."
    },
    {
      "commit": "62d51db4857ab0568630a0c1e3512a7be0e95fcb",
      "tree": "1be868a9b93eba9468722e01c4c10db96b5f77cb",
      "parents": [
        "0dce0f6903eb72beace1fe57d8d8fdc405a03b55"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Fri Sep 11 17:36:03 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Sep 11 17:36:03 2026 +0800"
      },
      "message": "fix(connector): complete the 16 incomplete connector implementations (#5394)\n\n* fix(connector): complete the 16 incomplete connector implementations\n\nAll follow the new-architecture SourceConnector/SinkConnector contract\n(init/resume/poll/commit + init/put/commit); external-system logic ported\nfrom the master-branch (openconnect) implementations.\n\n- canal source: canal TCP client (getWithoutAck -\u003e CloudEvent; ack on commit)\n- canal sink: all-or-nothing JDBC batch (rollback + throw on failure)\n- chatgpt source: HTTP prompt endpoint + OpenAI REST completion\n- dingtalk/lark/slack/wechat/wecom sources: platform webhook receivers\n  (HMAC/SHA1/token signature verification, challenge handshakes)\n- mcp source/sink: JSON-RPC 2.0 notification receive + forward\n- openfunction source/sink: function output receive + HTTP trigger invoke\n- pravega source/sink: EventStreamReader / EventStreamWriter\n- prometheus sink: Pushgateway text-format push\n- spring sink: injectable EventForwarder bridge (fail-fast until wired)\n\nDependencies added: canal.client 1.1.7, pravega-client 0.11.0,\njackson-databind 2.18.0 (JSON plugins), mysql-connector-j compileOnly.\n\n* docs(connector): add per-plugin guides for all 23 connectors\n\nOverview (model, running, catalog, matrix) + one page per plugin\n(classes, source/sink behavior, config key tables from the actual\nprops.getProperty defaults, run examples). Replaces the master-era\nwebsite 03-connect docs (9 plugins) with full 23-plugin coverage\nmatching the new-architecture contract."
    },
    {
      "commit": "0dce0f6903eb72beace1fe57d8d8fdc405a03b55",
      "tree": "d7581152dc94fb8bda06a062aa05228f1046e4fc",
      "parents": [
        "e437a6a31c56ba680d245cc2263ca0ef3e5bd1d5"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Thu Sep 10 15:37:49 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Sep 10 15:37:49 2026 +0800"
      },
      "message": "docs: fix README factual drift (branch targets, ports, plugin claims) (#5393)\n\nUser-reported: READMEs not fully updated after the restructure. Fixes:\n\n- CodeCov badge + Examples link pointed at master; master is the legacy\n  1.x line (44 old top-level modules) while develop is the mainline -\u003e\n  both now target develop\n- Quick start claimed a standard \"8083 connector admin\" port; no such\n  default exists (connector.admin.port defaults to 0 \u003d auto-assign;\n  Dockerfile EXPOSEs only 8080/8081/8082) -\u003e removed in EN/zh READMEs\n  and getting-started\n- \"Pluggable storage: RocketMQ, Kafka, Pulsar, RabbitMQ, Redis\" and\n  \"Pluggable meta: Consul/Nacos/ETCD/ZK\" overstated what ships: storage\n  backends are RocketMQ 4.x/5.x + Kafka, meta is Nacos (multi-instance)\n  -\u003e claims scoped to shipping plugins + SPI path (EN/zh)"
    },
    {
      "commit": "e437a6a31c56ba680d245cc2263ca0ef3e5bd1d5",
      "tree": "785608190f1844b1a479d2a7f823a121fb20f3c3",
      "parents": [
        "fd1ed35ad64e1d4196cddade9487ca12b9635b1b"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Thu Sep 10 15:19:21 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Sep 10 15:19:21 2026 +0800"
      },
      "message": "docs: update all stale doc references after the docs/ restructure (#5392)\n\nFollow-up to #5390/#5391 sweeping every place outside docs/ that still\nreferenced the old flat doc names:\n\n- README.zh-CN.md: capability table + doc nav rewritten to the new\n  quickstart/feature/architecture layout (mirrors the EN README map)\n- CONTRIBUTING.md: arch-guard and storage-SPI matrix links\n- docker/Dockerfile: deployment-mode note -\u003e docs/feature/deployment.md\n- eventmesh.properties (+dist copy): Connector Runtime section comment -\u003e\n  docs/feature/deployment.md\n- DistributionMode javadoc -\u003e docs/architecture/redesign.md\n- sdk-java build.gradle OMA comment -\u003e docs/feature/protocols.md\n- sdk legacy-README.md links\n- docs/**: link display text and prose mentions still naming old files\n  (evidence.md, production-ha-plan.md, overview.md, client-java.md,\n  protocols.md, control-plane.md, a2a-readiness.md, architecture-guard.md)\n\nRepo-wide scan now finds zero stale references (the only remaining\ndocs/reference/ strings are opentelemetry.io spec URLs, untouched).\nAll 227 internal .md links across docs/ + READMEs + CONTRIBUTING resolve.\nTouched modules compile and pass checkstyleMain."
    },
    {
      "commit": "fd1ed35ad64e1d4196cddade9487ca12b9635b1b",
      "tree": "c089474001f2807a9727e0666483c1a7d598747a",
      "parents": [
        "32f03e8433e7925d331968bab08c81fe596c5ffc"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Thu Sep 10 14:57:16 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Sep 10 14:57:16 2026 +0800"
      },
      "message": "docs: fold reference/ into feature/, split offset-lb-frame into three EN pages, rewrite redesign.md in English (#5391)\n\nFollow-up to #5390 folding the tree further per review:\n\n- reference/ (7 pages) merged into feature/: client-java, http-api,\n  admin-api, observability, deployment, protocols, storage-spi\n- architecture/connector-api-split.md and architecture/control-plane.md\n  moved to feature/ (capability/mechanism pages)\n- architecture/offset-lb-frame.md (Chinese) split into three English\n  feature pages: offset-management.md (two offset layers, deferred ACK,\n  monotonic writes, takeover), load-balancing.md (full-stickiness model,\n  self-reported load, recommend loop), frame-protocol.md (EventMeshFrame\n  wire format, FrameAdaptor/WireCodec SPIs, per-protocol chains)\n- architecture/redesign.md rewritten in English as a design record\n  (executive summary, iron rules, target architecture, decision log\n  15.1-15.8, at-least-once vs exactly-once boundary, request-reply,\n  streaming; historical appendices folded into current docs)\n\ndocs/ is now: quickstart/ + feature/ + architecture/ (overview, security,\nredesign, review/) + index/introduction. All 199 internal .md links\nvalidated resolving."
    },
    {
      "commit": "32f03e8433e7925d331968bab08c81fe596c5ffc",
      "tree": "56433d22b30be3991f25ab5e297f2013d7f0d120",
      "parents": [
        "815eeccc359ca9e2cea5eb62d43aa10c7ae903c9"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Thu Sep 10 13:26:27 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Sep 10 13:26:27 2026 +0800"
      },
      "message": "docs: reorganize docs/ into audience-oriented structure (quickstart/feature/reference/architecture) (#5390)\n\nRestructure the 18-file flat docs/ tree into a navigable, website-ready\nlayout organized by audience and capability:\n\n- quickstart/  getting-started, configuration\n- feature/     one page per capability: pubsub, delivery-reliability,\n               streaming, lite-topic, a2a (+readiness), architecture-guard\n- reference/   client-java, http-api, admin-api, observability,\n               deployment, protocols, storage-spi\n- architecture/ overview, control-plane (+absorbed state-store failure\n               matrix), security (new), and historical design records\n               (redesign, offset-lb-frame, connector-api-split, review/)\n\nNew pages: index.md (documentation map), introduction.md, feature guides\n(pubsub/delivery-reliability/streaming/lite-topic), architecture/security,\nreference (http-api/admin-api/observability/deployment) - all written from\nthe current code (verified routes from UniHttpServer/UniAdminServer, config\nkeys from EventMeshApplication + eventmesh.properties, metric names from\nUniMetrics/prometheusMetrics).\n\nConsolidations:\n- eventmesh-features.md (469 lines) split into per-feature pages; module map\n  lives in index.md/introduction.md\n- production-readiness.md absorbed into reference/deployment.md (checklist,\n  runbook) and reference/observability.md (metrics/SLO/alerts)\n- state-store-failure-matrix.md absorbed into architecture/control-plane.md\n\nAccuracy fixes against code reality:\n- storage backends: rocketmq/rocketmq5/kafka only (docs previously listed\n  pulsar/rabbitmq/redis/rocksdb storage plugins that do not exist)\n- meta store: Nacos (plus in-memory single-instance); Consul/ETCD/ZK noted\n  as SPI work, not shipping\n- admin token guard (fail-closed 503), connector generation fencing,\n  recovery re-dispatch semantics (#5379), deployment modes (#5380)\n  documented from the landed code\n\nAll 186 internal .md links validated resolving; README documentation\nsection rewritten around the new map; naming normalized to lowercase\nhyphenated slugs with per-page audience banners."
    },
    {
      "commit": "815eeccc359ca9e2cea5eb62d43aa10c7ae903c9",
      "tree": "05bf565a35a4f0790b6ddef84a10d5c73507145c",
      "parents": [
        "61c26f1eb653467b746b05bd38e29c5253e20ce0"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Wed Sep 09 23:57:03 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 09 23:57:03 2026 +0800"
      },
      "message": "test: real-broker e2e for BatchPublish, Unsubscribe, RateLimit, RequestReply (#5389)\n\nThe previous e2e suite covered the publish/subscribe/streaming/legacy-tcp\nproduction paths over a real broker (rocketmq4 / rocketmq5 / kafka +\nnacos for legacy cluster). Half a dozen equally important feature\nbehaviours — batch publish, topic unsubscribe, rate-limit token bucket,\nrequest-reply routing — were only exercised over UniIngressService +\nan in-memory MeshStoragePlugin stub. Anything that depended on the\nbroker boundary (frame serialization, topic partition routing,\nsubscription lifecycle crossing the storage layer) could regress without\nany test failing.\n\nAdd four focused tests under the same broker-IT discipline (skipped\nwhen no broker is configured, gated on a system property):\n\n  - BatchPublishOverBrokerTest — publishes a 10-event batch, verifies\n    every event arrives over the real LitePullConsumer path.\n  - UnsubscribeOverBrokerTest — subscribes to two topics, unsubscribes\n    one, confirms the dropped topic stops receiving while the survivor\n    keeps working (this is the failure mode that caused the in-process\n    stub to be insufficient: dispatcher-level topic bookkeeping !\u003d broker\n    delivery routing).\n  - RateLimitOverBrokerTest — sets a 2-token bucket with 0 refill,\n    publishes 5 events, asserts 2 succeed + 3 fail with\n    RateLimitedException AND the rateLimited counter ticks up by 3. The\n    counter assertion is what catches \"the limiter silently drops\n    instead of rejecting\" — exactly the kind of behaviour the in-process\n    test papers over.\n  - RequestReplyOverBrokerTest — opens a /req round-trip end-to-end,\n    proving the request survives broker round-trip + subscription\n    rebalance before the responder\u0027s reply comes back.\n\nSupporting changes:\n\n  - FeatureBrokerHarness: shared bootstrap. Picks rocketmq or rocketmq5\n    backend by it.feature.storage, looks up the storage plugin via SPI\n    (the same path the real runtime uses), boots UniRuntime, and\n    closes it on tearDown. Skips cleanly when the plugin isn\u0027t on the\n    classpath so the build stays green without a broker.\n  - e2eFeature gradle task: selects tests by -Pfeature.test\u003dFQN\n    (without the property, all four run). Uses the existing\n    rocketmq4TestRuntimeClasspath so storage-rocketmq5 is excluded and\n    the 4.9 plugin wins, matching the e2eTest4 contract.\n  - BrokerDiscoverer: serialize admin RPC across the test JVM.\n    Without the lock, four tests creating topics back-to-back thrash the\n    broker\u0027s single-shard topic-create / heartbeat thread and the route\n    doesn\u0027t propagate in time (the \"no broker for topic queue 0\"\n    failure seen during batch runs).\n\nVerified:\n  - All four tests pass in isolation against a real RocketMQ 4.9.5\n    broker over a uni-runtime in UniRuntime-mode on macOS/aarch64.\n  - Storage plugins (rocketmq, rocketmq5, kafka) and runtime unit\n    tests remain green via ./gradlew check -x spotlessJava\n    -x :eventmesh-architecture-guard:test.\n  - The e2eFeature task is gated on -Dit.feature.storage so CI without\n    a broker stays green. CI does not run it (it\u0027s an opt-in gradle\n    task outside the default build chain).\n\nThe \"all four in one gradle invocation\" run is flaky on a single-shard\nbroker under topic-creation pressure; that\u0027s a broker-capacity limit,\nnot a test correctness bug. Running with -Pfeature.test\u003dFQN is\ndeterministic."
    },
    {
      "commit": "61c26f1eb653467b746b05bd38e29c5253e20ce0",
      "tree": "71ed592d9172239023f387d2e1252bfbdc1dded9",
      "parents": [
        "efa5a04a756ccfa6bfbd14628f3cfee994f2d70d"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Wed Sep 09 23:18:05 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 09 23:18:05 2026 +0800"
      },
      "message": "fix(#5357): use immutable frame for MQ offset/partition stamps (#5388)"
    },
    {
      "commit": "efa5a04a756ccfa6bfbd14628f3cfee994f2d70d",
      "tree": "35f2937ead7841fba851607376f7eec064780b9d",
      "parents": [
        "ba9d29d835390b4d9512e0f1863cf2fd138d008b"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Wed Sep 09 17:44:42 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 09 17:44:42 2026 +0800"
      },
      "message": "docs(#5380): complete the Dockerfile deployment-mode note (missed in #5385) (#5386)\n\nThe docker/Dockerfile comment hardening referenced by docs/eventmesh-features.md\nSS5b was left out of PR #5385 file list; this carries it. No code changes."
    },
    {
      "commit": "ba9d29d835390b4d9512e0f1863cf2fd138d008b",
      "tree": "4232fd38a9659e974c05696b1278439e5251ffd9",
      "parents": [
        "27c5282733be8713ef9ffdbc65f7957501e31085"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Wed Sep 09 17:41:13 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 09 17:41:13 2026 +0800"
      },
      "message": "fix(#5379,#5380,#5381,#5382): recovery re-dispatch, honest deployment modes, fail-closed security gate, connector generation fencing (#5385)\n\n#5379: ReliableDispatcher.recover() no longer advances the subscriber offset as if\nthe absent client had ACKed (a skip across the crash window). Recovery now\nRE-DISPATCHES each persisted in-flight record through a buffered poll channel with\nits attempt counter preserved; the offset advances exactly once - when the client\nactually ACKs. Legacy undecodable records retire without any offset advance. The\nold retire semantics stays as a @Deprecated private method for source compat.\nDeliveryRecoveryTest / CrossStoreFaultInjectionTest scenario 1/1b are updated to\nthe re-dispatch contract; new RecoveryRedispatchTest covers the crash-\u003ere-dispatch-\u003e\nACK-exactly-once shape.\n\n#5380: docs/eventmesh-features.md gains \"5b. Deployment modes\" (core Runtime /\nsession-streaming Runtime / A2A Gateway) so capability claims match what the\ndefault bootstrap actually starts; docker/Dockerfile note hardened accordingly.\n\n#5381: EventMeshApplication.main() wires a config-backed SecurityGate\n(eventmesh.security.profile, default \"production\"; eventmesh.security.tokens) via\nwithSecurityGate(gate) and installs it into the traffic httpServer; production\nprofile with empty token filters fails closed with IllegalStateException.\n\n#5382: ConnectorScheduler bumps a per-connector fencing generation on every\n(re)assignment or def change and splices \"generation\" into the /control/start\nenvelope; ConnectorManager.startConnector accepts a start iff gen \u003e\u003d running gen\n(stale delayed starts are rejected and logged), rebuilds on newer generation, and\nstopConnector clears the running generation. ConnectorDef (both runtime and\nconnector-runtime sides) carries the generation field; new\nConnectorGenerationFencingTest covers accept/reject/idempotent-re-push.\n\nLocal verification: :eventmesh-runtime:test :eventmesh-connector-runtime:test\n:eventmesh-architecture-guard:test + checkstyleMain/Test for both modules - all green."
    },
    {
      "commit": "27c5282733be8713ef9ffdbc65f7957501e31085",
      "tree": "0bd78ce43506e716678887facb4d9f764698da31",
      "parents": [
        "80847b2d89afa8e635d5c37fca453602bac560e0"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Wed Sep 09 15:30:44 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 09 15:30:44 2026 +0800"
      },
      "message": "fix(#5376,#5377,#5378): cluster routing, single ownership lifecycle, durable delivery bootstrap (#5383)\n\nThree coupled review findings on the default cluster bootstrap,\nfixed together because they compose into one wiring path.\n\n#5376 - cluster-wide subscription routing for PARTITION_OWNED_PULL:\n- EventMeshApplication.enableCluster() now builds the\n  ClusterSubscriptionStore (Meta prefix watch) + ClusterCoordinator\n  (local targets via deliverLocal, remote via the new HttpForwarder)\n  and injects it with withCluster(). The partition owner\u0027s poll loop\n  previously dispatched through its LOCAL SubscriptionManager only -\n  a subscriber on instance B was invisible to the owner on A\n  (starvation).\n- New HttpForwarder: POST /internal/forward to the target instance\n  (address via ClusterMembership.addressOf, bearer from\n  eventmesh.admin.token, frame base64-wrapped).\n- New POST /internal/forward on UniHttpServer: decodes and delivers\n  through the local reliable path, so ACK/redelivery semantics are\n  identical for forwarded and local deliveries; 401 when the internal\n  token is configured and missing.\n- ClusterSubscriptionStore put/remove now apply locally BEFORE the\n  Meta write: with a synchronously-notifying store, a trailing\n  own-apply escaped the authoritative Meta event order and could\n  resurrect a concurrently-deleted value in the local cache\n  (divergent views). The storm convergence test is now poll-stable.\n\n#5377 - one PartitionOwnership lifecycle per instance:\n- UniRuntime.startPartitionOwnership() REUSES the ownership that\n  EventMeshApplication.enableCluster() already built and installed\n  into the ingress (one membership, one heartbeat loop, one fencing\n  token); it self-constructs only when nobody wired one (embedder\n  path). Previously the #5359 topology flip made UniRuntime.start()\n  create a SECOND ClusterMembership + PartitionOwnership with a\n  different token and replace the ingress view - two divergent state\n  machines per runtime.\n\n#5378 - durable delivery + DLQ ledger in the default bootstrap:\n- ReliableDispatcher.withStateStore(withDeadLetterStore):\n  post-construction injection for boot wiring order; the swap fails\n  closed when deliveries are in flight.\n- EventMeshApplication.main() constructs RocksDBDeliveryStateStore\n  under \u003cdataDir\u003e/delivery-state and (clustered) a\n  MetaBackedDeadLetterStore, injects both, logs the effective\n  implementations at boot, and closes the store on shutdown so\n  in-flight records survive for restart recovery. The default path\n  previously fell back to InMemoryDeliveryStateStore - a crash lost\n  every pulled-but-unACKed delivery.\n\nTests (new ClusterBootstrapCompositionTest, 4 cases):\n- runtimeReusesPreInstalledOwnership (#5377)\n- coordinatorRoutesRemoteSubscriber (#5376: remote subscriber via\n  forward, exactly one forward)\n- durableStoresInjectIntoDispatcher (#5378: in-flight swap fails,\n  post-clear swap + ledger attach take effect)\n- rocksDbDeliveryStateStoreRoundTrips (#5378 durability baseline)\n\nLocal verification (Temurin 21.0.11): runtime tests + checkstyle\n(maxWarnings\u003d0) + architecture-guard tests all green.\n\nCloses #5376\nCloses #5377\nCloses #5378"
    },
    {
      "commit": "80847b2d89afa8e635d5c37fca453602bac560e0",
      "tree": "05d588fc9bc7ad583b7234a45c4af6302d22625d",
      "parents": [
        "20fda4129f67ef51ac24a225f9f835a8bfd8f799"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Wed Sep 09 13:25:05 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 09 13:25:05 2026 +0800"
      },
      "message": "docs(#5365): production-HA evidence table + plan closure (#5375)\n\nPhase 4 of the production-HA plan (#5354), sub-issue #5365: the final\nacceptance evidence and the closure of the three parent issues.\n\nevidence.md gains the \"Production-HA acceptance (#5354)\" section:\n- one row per executed sub-issue (#5356-#5362, #5364) with PR,\n  squash-commit, test files, reproducible test command, backend and\n  topology, all marked PASS under the full local-CI pipeline (the\n  verification of record during the Actions outage)\n- #5363 marked NOT PLANNED with the deferral rationale and the\n  compensating in-process coverage\n- a section documenting the blind-merge repairs #5367 carried (develop\n  was compile-red before it) so reviewers of the outage window have\n  the full picture\n- the 21-criterion mapping (A1-A5 / B1-B6 / C1-C10) from the three\n  parent issues to the landed sub-issues\n\nproduction-ha-plan.md is marked COMPLETE with pointers to the evidence\nsection.\n\nWith this, the plan\u0027s closure condition is met: the evidence table\nrecords every executed sub-issue, and the parents (#5352 data-path,\n#5353 control-plane, #5354 production HA) close on it.\n\nCloses #5365\nCloses #5352\nCloses #5353\nCloses #5354"
    },
    {
      "commit": "20fda4129f67ef51ac24a225f9f835a8bfd8f799",
      "tree": "d2d86c6143be17203c29b24d7b12d180e6da0e0b",
      "parents": [
        "5ecbc1503a2f2cce9560cd8b627368d665c32e74"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Wed Sep 09 13:21:48 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 09 13:21:48 2026 +0800"
      },
      "message": "fix(#5364): admin token guard (fail-closed) + chaos in-process cases (#5374)\n\nPhase 3 of the production-HA plan (#5354), sub-issue #5364. The\nTestcontainers-based chaos matrix (5 cases + rolling upgrade) is\ndeferred with #5363 (no Docker in the current environment); this PR\nlands the parts that do not need containers.\n\nAdmin security (fail-closed by default):\n- UniAdminServer guards EVERY endpoint (admin + /metrics scrape)\n  except /admin/health (liveness probe) behind a bearer token from\n  -Deventmesh.admin.token; constant-time compare\n- missing/wrong token -\u003e 401 with the remediation hint\n- NO token configured -\u003e 503 admin_locked for everything except\n  health: an operator who never set the property gets a locked admin\n  plane plus a pointed WARN, not a silently open one\n- 5 existing test classes updated to set withAdminToken(...) and\n  present the bearer (the breakage was the intended behavior change)\n\nChaos, in-process form:\n- MetaStoreOutageTest (case 1): Meta down -\u003e every call fails\n  observably (alertable) while held assignments + offsets survive;\n  on recovery the CAS fencing still rejects a stale writer\n  (expected\u003dnull cannot steal a held partition; the rightful\n  expected\u003dcurrent takeover succeeds) - offsets cannot regress\n  through re-assignment\n- RocksDBCorruptionTest (case 4): a corrupted SST refuses startup\n  with the documented error (\"restore from backup or wipe\n  deliberately\"); the healthy control case proves offsets survive a\n  clean restart (the durability baseline the corruption posture\n  protects). The refusal beats silently re-creating an empty DB,\n  which would reset every offset and replay everything.\n\nLocal verification (Temurin 21.0.11): runtime tests (full suite)\n+ checkstyle (maxWarnings\u003d0) all green.\n\nRefs #5364 (sub-issue of #5354)."
    },
    {
      "commit": "5ecbc1503a2f2cce9560cd8b627368d665c32e74",
      "tree": "9f52dc92e16bdae87e904892a043bc01adaa3863",
      "parents": [
        "13d0077922e6929caa234f5a5c094482ef97dbd1"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Wed Sep 09 12:55:04 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 09 12:55:04 2026 +0800"
      },
      "message": "fix(#5362): classify A2A operations for quota (SUBMIT\u003dBACKLOG, reads\u003dTHROUGHPUT) (#5373)\n\nPhase 2 of the production-HA plan (#5354), sub-issue #5362 (acceptance\nB6): A2A operations stop being one flat rate.\n\nThe gap: resourceFor(A2A) -\u003e THROUGHPUT for everything. A tenant\nsubmitting long-running tasks was charged the same as a health probe:\nno cap on concurrent live tasks (BACKLOG was never charged on the A2A\npath) and no release semantics existed anyway (#5358 added the\nQuotaHandle but no A2A call site used acquire()).\n\nClassification (RequestContext.A2aOperation, new enum):\n- SUBMIT: a task occupies agent capacity until it completes/cancels\n  -\u003e BACKLOG; the handle from SecurityGate.acquire() is the release\n- GET / CANCEL / STREAM: per-request work -\u003e THROUGHPUT (window\n  counters self-expire; handle close is a no-op)\n- null sub-operation: backward-compatible THROUGHPUT fallback\n\nWiring:\n- SecurityGate.resourceFor(ctx) consults the A2A sub-operation on the\n  A2A arm (signature op -\u003e ctx; PUBLISH/SUBSCRIBE/ACK unchanged)\n- A2AGatewayHttpHandler.classify(method, uri) derives the\n  sub-operation from the route shape (POST /a2a/tasks \u003d SUBMIT,\n  DELETE /a2a/tasks/{id} \u003d CANCEL, .../stream \u003d STREAM, GET/other \u003d\n  GET) before the gate check, so every endpoint charges the right\n  resource\n\nTests (new A2aOperationClassificationTest, 5 cases):\n- SUBMIT charges BACKLOG and the handle releases it exactly once\n- GET / CANCEL / STREAM charge THROUGHPUT with zero release events\n- null sub-operation falls back to THROUGHPUT\n- non-A2A resources unchanged (SUBSCRIBE -\u003e SUBSCRIPTIONS)\n- exhausted SUBMIT throws QuotaExceededException without consuming\n\nLocal verification (Temurin 21.0.11): runtime tests + checkstyle\n(maxWarnings\u003d0) + architecture-guard tests all green.\n\nRefs #5362 (sub-issue of #5354)."
    },
    {
      "commit": "13d0077922e6929caa234f5a5c094482ef97dbd1",
      "tree": "34a1e3b530bd55beec5c320acb8ba2c667cc50f7",
      "parents": [
        "017843ef1a60752e6a4a0b3450dd472fc2348a16"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Wed Sep 09 10:15:30 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 09 10:15:30 2026 +0800"
      },
      "message": "fix(#5361): FrameLimits — enforce wire bounds at encode AND decode (no-alloc rejects) (#5372)\n\nPhase 1 of the production-HA plan (#5354), sub-issue #5361 (acceptance\nA3: frame fuzz/boundary tests reject malformed input without OOM).\n\nThe gap: the frame codec accepted whatever sizes the header\nadvertised. A malformed or hostile frame declaring dataLen\u003d2^31-1\nmade the decoder allocate that much memory before failing on the\ntruncated body (OOM instead of a clean reject); truncated buffers\nescaped as BufferUnderflowException instead of IllegalArgumentException.\n\nNew FrameLimits (eventmesh-common/wire):\n- MAX_FRAME_BYTES 16 MiB, MAX_DATA_BYTES 8 MiB, MAX_ATTRIBUTES 64,\n  MAX_ATTR_NAME_BYTES 256, MAX_ATTR_VALUE_BYTES 4 KiB - generous for\n  streaming chunks / large CloudEvents payloads while bounding a\n  single frame\u0027s memory footprint.\n\nEncode boundary: a producer cannot build an oversized frame\n(attribute count, data length, attr name/value length, total encoded\nsize all fail fast with IllegalArgumentException).\n\nDecode boundary: advertised keyCount/dataLen are rejected BEFORE any\nallocation; every buffer read (attribute length prefixes, string\nbodies, the data bulk get) is guarded so a truncated frame fails as\nIllegalArgumentException - never BufferUnderflowException, never an\nover-allocation. decode is now total: any byte sequence either\ndecodes or throws IllegalArgumentException.\n\nTests (new FrameLimitsTest, 8 cases):\n- 4 encode-bound rejects + at-the-limit acceptance (boundary is \u003e)\n- hostile dataLen\u003dInteger.MAX_VALUE on a 64-byte buffer: clean\n  IllegalArgumentException, no allocation\n- hostile keyCount; dataLen beyond provided buffer\n- deterministic 20,000-iteration byte-mutation fuzz: every mutant\n  either decodes or throws IllegalArgumentException (found and fixed\n  the two underflow escapes above during development)\n\nLocal verification (Temurin 21.0.11): common tests + checkstyle\n(maxWarnings\u003d0) green; downstream runtime + architecture-guard +\nstorage-api tests green.\n\nRefs #5361 (sub-issue of #5354)."
    },
    {
      "commit": "017843ef1a60752e6a4a0b3450dd472fc2348a16",
      "tree": "22d1e2cdae982291e5f6c33418736dc21bb6e1ea",
      "parents": [
        "b3f9f75b40ffce2683740601bc0af0adf93aecf3"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Wed Sep 09 10:03:15 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 09 10:03:15 2026 +0800"
      },
      "message": "fix(#5360): fence stale owners from durable side effects (offsets / broker ACK) (#5371)\n\nPhase 1 of the production-HA plan (#5354), sub-issue #5360: a fenced\n(stale) partition owner must not produce durable side effects after\ntakeover.\n\nThe gap: PartitionOwnership acquires partitions via Meta CAS +\nFencingToken, but the dispatcher never consulted the ownership view.\nA stale owner whose lease was taken over kept writing offsets and\nACKing the broker - the new owner\u0027s offset state and the stale\nowner\u0027s writes interleaved (split-brain duplicates, B3/C2/C3).\n\nChanges:\n- ReliableDispatcher.withOwnershipGuard(BiPredicate\u003ctopic, partition\u003e):\n  installed by UniIngressService.withPartitionOwnership from the live\n  PartitionOwnership snapshot (ownedPartitions contains partition).\n- ack() consults the guard BEFORE any durable effect: a fenced owner\n  drops the delivery (state + live stores), emits no offset write,\n  fires no broker ACK callback, and raises StaleOwnerException (new,\n  carries topic/partition). The broker\u0027s POP invisibleTime redelivers\n  the message to the new owner - at-least-once is preserved and the\n  new owner\u0027s offsets stay authoritative.\n- The pull loop\u0027s null-ownership window is documented: with #5359 the\n  ownership view is always installed at boot in PARTITION_OWNED_PULL,\n  so null \u003d single-instance (poll-all is the documented mode), not a\n  gap.\n\nTests (new StaleOwnerFencingTest, 2 cases):\n- fencedOwnerAckWritesNoOffsetAndSkipsBrokerAck: partition 1 owned /\n  partition 0 fenced; owned ack writes its offset, fenced ack throws\n  StaleOwnerException with zero additional offset writes and zero\n  broker ACK callbacks, delivery no longer pending.\n- noGuardKeepsSingleInstanceBehaviour: no guard installed -\u003e ack\n  persists the offset (single-instance path unchanged).\n\nLocal verification (Temurin 21.0.11): runtime tests + checkstyle\n(maxWarnings\u003d0) all green.\n\nRefs #5360 (sub-issue of #5354)."
    },
    {
      "commit": "b3f9f75b40ffce2683740601bc0af0adf93aecf3",
      "tree": "3243cc107df6668cb84346b1c2d09edeacd407ce",
      "parents": [
        "d5200c83e9bb55ad69c00f27db65ffc72f74c5d1"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Tue Sep 08 20:01:22 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 08 20:01:22 2026 +0800"
      },
      "message": "fix(#5359): wire DeliveryTopology + MetaStore into runtime boot; rollback on failure (#5370)\n\nPhase 1 wiring of the production-HA plan (#5354), sub-issue #5359.\n\nThe gap: EventMeshApplication.enableCluster built a PartitionOwnership\nstate machine (Meta CAS + fencing) but never told the RUNTIME - the\npull loop kept its constructor-time topology (LOCAL_STICKY_PULL by\ndefault) and polled every partition on every instance while the app\nlayer believed ownership was exclusive. Two divergent ownership views;\nthe cluster looked healthy but delivered duplicates.\n\nBoot wiring:\n- enableCluster now flips the runtime topology to PARTITION_OWNED_PULL\n  and injects the shared MetaStore BEFORE runtime.start(), so the pull\n  loop consults the same PartitionOwnership (ownedPartitions) the app\n  built - one state machine, not two\n- UniRuntime.topology becomes volatile (flippable pre-start); new\n  withTopology / withClusterMeta builders reject post-start mutation\n  (fail fast, like the #5356 contract); new topology() / clusterMeta()\n  accessors\n\nStartup transactionality (#5359):\n- EventMeshApplication.start() wraps the whole boot in try/catch: on\n  any failure it runs shutdown() (stop schedulers, release ports,\n  release storage) with cleanup failures attached as suppressed, then\n  rethrows - no more half-started processes holding the admin port\n- single-line effective-config log at startup (topology / metaWired /\n  wsPort / tls) so operators can audit a running deployment\n\nTests (new EventMeshApplicationStartupTest, 4 cases):\n- enableCluster contract: topology flipped + shared meta injected\n- withTopology / withClusterMeta fail fast after start\n- null topology rejected\nLocal: runtime tests + checkstyle (maxWarnings\u003d0) all green.\n\nRefs #5359 (sub-issue of #5354)."
    },
    {
      "commit": "d5200c83e9bb55ad69c00f27db65ffc72f74c5d1",
      "tree": "792e15b22d4686698b7fe210e5231988a339ace1",
      "parents": [
        "7ac0ab824a95afdd64bf16c6ed66043260db90b1"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Tue Sep 08 19:40:59 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 08 19:40:59 2026 +0800"
      },
      "message": "fix(#5358): QuotaHandle (AutoCloseable) + gate-scoped QuotaManager access (#5369)\n\nPhase 0 enforcement of the production-HA plan (#5354), sub-issue\n#5358: gauge-style quota resources (CONNECTIONS / SUBSCRIPTIONS /\nBACKLOG) leak when acquire has no guaranteed release. Production\ncallers today (UniHttpServer x2, A2AGatewayHttpHandler,\nConnectorScheduler) all use one-shot THROUGHPUT check() and never\nrelease - correct for windows, but nothing structural stops the next\ngauge-style call site from leaking the same way.\n\nNew API (security.gate):\n- QuotaHandle implements AutoCloseable: close() releases exactly once,\n  double-close is a no-op, non-releasable (THROUGHPUT) handles do not\n  release (window counters self-expire)\n- SecurityGate.acquire(ctx, frame) -\u003e QuotaHandle: runs the same\n  auth/ACL-first check() then returns the paired handle; throws\n  QuotaExceededException (new) when exhausted, consuming no slot\n- callers wrap gauge work in try-with-resources so the release runs\n  on success, failure and cancellation alike\n\nArchUnit guardrail (15 -\u003e 16 rules):\n- ruleQuotaManagerOnlyFromGate: QuotaManager.tryAcquire/release may\n  only be called from the security.gate package - any direct manager\n  call outside the gate bypasses the pairing contract and fails the\n  build\n\nTests:\n- QuotaHandleTest (new, 4 cases): close-releases-exactly-once,\n  try-with-resources releases on exception, THROUGHPUT handle does\n  not release, exhausted acquire throws without consuming\n- checkstyleMain/Test + guard tests + full CI build all green\n\nRebased onto develop after #5368 (rule ordering in\nArchitectureRules.java); the 16-rule set now reads\n#5322(9) + #5348(2) + #5356(2) + #5357(1) + #5358(1).\n\nFull local CI parity (Temurin 21.0.11):\n- checkstyle + tests x (runtime, architecture-guard) -\u003e BUILD SUCCESSFUL\n- clean build dist jacocoTestReport (CI task set)   -\u003e BUILD SUCCESSFUL (7m59s)\n\nRefs #5358 (sub-issue of #5354)."
    },
    {
      "commit": "7ac0ab824a95afdd64bf16c6ed66043260db90b1",
      "tree": "dfaf34f9c7fa201ab6d303cac882334cca3f2ea2",
      "parents": [
        "3dffe955121dfdd1150f67685b512798ed1ddc14"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Tue Sep 08 19:34:12 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 08 19:34:12 2026 +0800"
      },
      "message": "fix(#5357): make EventMeshFrame immutable (defensive copy + unmodifiable view + withAttribute) (#5368)\n\nPhase 0 enforcement of the production-HA plan (#5354), sub-issue\n#5357: a frame that can be mutated after publish lets two concurrent\ndispatchers race on the same instance; the attribute map was also\naliased from codec accumulators at construction.\n\nEventMeshFrame changes:\n- constructor deep-copies the attrs map (a caller-held codec\n  accumulator can no longer alias frame state); null map/data are\n  normalized\n- attributes() returns Collections.unmodifiableMap\n- new withAttribute(name, value) derives a new frame with one\n  attribute set (null value removes); the source frame is unchanged\n\nCall-site migration (3 test files; production code had zero mutation\nsites - verified by grep over all 72 attributes() usages):\n- RestartCursorAlignmentTest / MqCursorRecordingTest: pop-cursor\n  stamping now chains withAttribute\n- FrameProtocolConversionTest.framePopCkStampedForDeferredAck:\n  converted from a mutability test to an immutability test (asserts\n  withAttribute derives a stamped frame, source unchanged, and\n  attributes() throws UnsupportedOperationException on put)\n\nArchUnit guardrail (14 -\u003e 15 rules):\n- ruleEventMeshFrameImmutable: only org.apache.eventmesh.common.wire..\n  may implement EventMeshFrame* types, so no other class can grow\n  frame-mutating APIs\n\nFull local CI parity (Temurin 21.0.11):\n- :eventmesh-architecture-guard:test + :eventmesh-common:test +\n  :eventmesh-runtime:test -\u003e BUILD SUCCESSFUL\n- checkstyleMain/Test x3 modules (maxWarnings\u003d0)              -\u003e BUILD SUCCESSFUL\n- clean build dist jacocoTestReport (CI task set)            -\u003e BUILD SUCCESSFUL (11m12s)\n\nRefs #5357 (sub-issue of #5354)."
    },
    {
      "commit": "3dffe955121dfdd1150f67685b512798ed1ddc14",
      "tree": "e6d5d0b5c9a3115b272c04c57497c480a0f286ab",
      "parents": [
        "592c98f56d139b43f58ad1815cce092120af318e"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Tue Sep 08 18:42:57 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 08 18:42:57 2026 +0800"
      },
      "message": "fix(#5356): fail fast on PARTITION_OWNED_PULL without shared MetaStore + arch-guard (#5367)\n\nPhase 0 enforcement of the production-HA plan (#5354): removes both\nsilent InMemoryMetaStore fallbacks, adds two ArchUnit guardrails, and\nrepairs the compile/test/checkstyle breaks that landed on develop via\nthe 2026-09-07/08 Actions-outage blind merges (all found by running\nthe full CI build locally).\n\nBoot changes (the #5356 core):\n- UniRuntime.startPartitionOwnership: clusterMeta \u003d\u003d null now throws\n  IllegalStateException instead of new InMemoryMetaStore().\n- EventMeshApplication: unsupported meta type in cluster mode fails\n  fast; single-instance mode keeps the documented in-memory store.\n\nArchUnit guardrails (12 -\u003e 14 rules):\n- ruleInMemoryMetaStoreOnlyFromBoot\n- rulePartitionOwnershipOnlyFromBootAndCluster (boot/cluster/ingress/admin)\n\nOutage blind-merge repairs:\n- missing DeliveryTopology import (#5344): compileJava failed on develop\n- guard module missing rocketmq5 dep + lz4-java capability conflict\n  (org.lz4 vs at.yawk.lz4) for FakeStorageCanary (#5348)\n- FakeStorageCanary in storage.fakeplugin.. never matched the\n  ruleStoragePluginsIsolated that-clause (#5348): moved to\n  storage.kafka test package\n- ClusterSubscriptionStore left empty topic buckets after last\n  subscriber removal (#5345): topics() returned ghosts; buckets now\n  dropped when empty\n- checkstyle (maxWarnings\u003d0) violations in #5345/#5346 test files:\n  unused imports (MetaListener, StandardCharsets, TaskStore, MetaStore,\n  OffsetStore), import order (A2AMessageTransport, org.junit before\n  io.cloudevents), local var names (aView/bView -\u003e viewA/viewB),\n  declaration-usage distance (reaper x2, SessionRegistry b)\n\nFull local CI parity (Temurin 21.0.11, same tasks as .github/workflows):\n- ./gradlew clean generateGrammarSource            -\u003e BUILD SUCCESSFUL\n- ./gradlew :eventmesh-architecture-guard:architectureCheck --no-daemon\n                                                  -\u003e BUILD SUCCESSFUL\n- ./gradlew clean build dist jacocoTestReport --parallel --daemon\n    -x spotlessJava -x generateGrammarSource -x generateDistLicense\n    -x checkDeniedLicense -x :eventmesh-architecture-guard:test\n                                                  -\u003e BUILD SUCCESSFUL (511 tasks, 10m47s)\n- ./gradlew installPlugin                         -\u003e BUILD SUCCESSFUL\n\nRefs #5356 (sub-issue of #5354)."
    },
    {
      "commit": "592c98f56d139b43f58ad1815cce092120af318e",
      "tree": "babf7763357ee4519fefcd2f9819e666a8ded849",
      "parents": [
        "59d4cabb0a0c0f00b2538736908a46457bb2a2a2"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Tue Sep 08 16:41:41 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 08 16:41:41 2026 +0800"
      },
      "message": "fix(#5350): run containers as non-root, add HEALTHCHECK, drop unused locale setup (#5351)\n\nBoth images (apache/eventmesh, apache/eventmesh-connector) shipped as\nroot-run containers with no HEALTHCHECK and a locales package that was\nnever selected by any ENV.\n\nChanges (both images):\n- dedicated non-root user (eventmesh uid 10001 / connector uid 10002)\n  with COPY --from\u003dbuilder --chown and USER before CMD\n- drop locales + localedef; ENV LANG\u003dC.UTF-8 LC_ALL\u003dC.UTF-8 (base\n  image already ships C.UTF-8, the generated en_US.UTF-8 was unused)\n- VOLUME for the data dir (RocksDB offsets / connector offsets)\n\nRuntime image:\n- HEALTHCHECK: GET /admin/health on 127.0.0.1:${EVENTMESH_ADMIN_PORT}\n  via bash /dev/tcp (no curl/wget layer added)\n- EXPOSE comment documents that the A2A gateway (EXPERIMENTAL) is not\n  started by bin/start.sh today\n\nConnector image:\n- HEALTHCHECK: pgrep -f ConnectorApplication (admin port is off by\n  default, so an HTTP probe would false-negative; swap in an HTTP\n  check when the admin API grows a health route)\n\nCloses #5350"
    },
    {
      "commit": "59d4cabb0a0c0f00b2538736908a46457bb2a2a2",
      "tree": "8b6e1ba7da94ec1dd08afb1336fc70bec92546e0",
      "parents": [
        "b08e591ac59c64479caf80bced59421bf7207262"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Tue Sep 08 16:40:12 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 08 16:40:12 2026 +0800"
      },
      "message": "docs(#5354): production-HA acceptance plan — 10-issue topology (#5356-#5365) (#5366)\n\nAdds docs/architecture-review/production-ha-plan.md splitting the\nproduction-HA acceptance work (#5352 / #5353 / #5354) into 10 tracking\nissues (#5356-#5365, Phase 0..4, Severity P0..P2) with an explicit\ndependency graph, per-issue acceptance criteria, and a PR plan.\n\nTopology summary:\n  Phase 0 enforcement (P0): #5356 ban poll-all + InMemoryMetaStore,\n    #5357 ban mutable EventMeshFrame, #5358 ban raw quota calls\n  Phase 1 wiring (P0): #5359 DeliveryTopology/MetaStore/FencingToken\n    boot wiring, #5360 fencing epoch propagation, #5361 FrameLimits\n  Phase 2 behavior (P1): #5362 QuotaHandle + A2A op classification,\n    #5363 Testcontainers cross-instance takeover tests\n  Phase 3 chaos (P1): #5364 chaos + rolling upgrade + admin security\n  Phase 4 docs (P2): #5365 doc sync + acceptance evidence\n\nAll 12 sub-issues (10 new + #5352 + #5353) are attached to parent\n#5354 via GitHub sub-issue relationships.\n\nRefs: #5352, #5353, #5354, #5356-#5365."
    },
    {
      "commit": "b08e591ac59c64479caf80bced59421bf7207262",
      "tree": "1b9b5cd6719190236fa9ce16f750058b8461fee4",
      "parents": [
        "c0ffb6e826cef46434a9bf1b300d8aae8f78b866"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Tue Sep 08 11:11:34 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 08 11:11:34 2026 +0800"
      },
      "message": "docs(#5337): add architecture-review evidence table for #5296 sub-issues (#5349)\n\nCloses #5337 (Q1 production validation evidence + Q8 closure criteria).\n\nLinks every closed sub-issue of #5296 to its PR, squash-commit hash, test\nfiles, test command, CI run, backend/version, deployment topology, and\nobserved result. The 7 reliability scenarios called out in #5337 (Q1)\nare answered in the \"Scenarios\" section with concrete PR + test refs.\n\nStatus legend distinguishes MERGED (PR landed; CI on record before the\nActions platform outage) from OPEN-CI-startup_failure (PR open; CI\nblocked by a repository-level runner availability issue affecting all\nworkflows since 2026-09-07 16:23 UTC). 19 PRs are catalogued, of which\n16 are MERGED and 3 are OPEN-CI-startup_failure (#5345 / #5346 / #5348,\nall blocked on the same platform issue).\n\nCo-authored-by: qqeasonchen \u003cqqeasonchen@gmail.com\u003e\n\nRetry-CI: Retry-CI-after-outage-1788836620"
    },
    {
      "commit": "c0ffb6e826cef46434a9bf1b300d8aae8f78b866",
      "tree": "f95198929580f37a80aa0df3acc7e4d171e3ae1f",
      "parents": [
        "40a6497fdb107efcd8f9e1e5e1c6dca9ec53d298"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Tue Sep 08 11:11:29 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 08 11:11:29 2026 +0800"
      },
      "message": "fix(#5342): storage capability matrix + arch-guard plugin boundary rules (#5348)\n\nCloses #5342 (Q6 storage capability coverage + Q7 architecture guardrails).\n\nAdds:\n- docs/storage-spi.md: 7-capability x 3-plugin matrix, TCK contract, future work\n- docs/architecture-guard.md: canonical reference for all 12 ArchUnit rules\n- CONTRIBUTING.md: contributor entry point, links arch-guard doc\n- ArchitectureRules.ruleStoragePluginsIsolated: kafka plugin must not depend on rocketmq*\n- ArchitectureRules.ruleStoragePluginsDependOnlyOnApi: storage plugin must not depend on eventmesh.runtime.*\n- ArchitectureRulesTest: 2 corresponding *_check tests + canary-catches test\n- FakeStorageCanary: intentional-violation canary mirroring FakePluginCanary\n- build.gradle: pull in eventmesh-storage-kafka for canary sampling\n\nCo-authored-by: qqeasonchen \u003cqqeasonchen@gmail.com\u003e\n\nRetry-CI: Retry-CI-after-outage-1788836620"
    },
    {
      "commit": "40a6497fdb107efcd8f9e1e5e1c6dca9ec53d298",
      "tree": "3187f85df8f9d6f99301ef3d83763bf6fb251aa7",
      "parents": [
        "913820044008b5b26f455cff127a79b40d86ab07"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Tue Sep 08 11:11:23 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 08 11:11:23 2026 +0800"
      },
      "message": "feat(#5340): A2A TaskExpirer + MetaAgentCardRegistry + failure-mode test (D2a) (#5346)\n\nPart of #5296 (Architecture Review, \u0027New review questions\u0027 2026-09-07, Q4).\nSub-PR D2a of #5302 (A2A onto Runtime).\n\nQ4 asks: are task expiry / reaping, Meta-backed AgentCard persistence,\nRuntime-dispatch integration, and real Meta / Runtime failure testing\ncomplete? Until they are, A2A remains explicitly Experimental.\n\nThis PR lands D2a: four of the five acceptance items from the #5340\nissue body. D2b (Testcontainers E2E) is a follow-up; the failure-mode\ntest in D2a pins the gateway\u0027s contract at the user-facing API, and D2b\nwill exercise the same scenarios end-to-end against a real Meta +\nbroker + multi-instance EM.\n\n## What this PR adds\n\n1. eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/a2a/TaskExpirer.java\n   - new reaper class with configurable TTL (default 24h) and scan\n     interval (default 60s). Calls TaskStore.expireStale() on a\n     daemon-thread ScheduledExecutor. Exposes a scan() method for\n     tests to drive the reaper synchronously. Idempotent\n     start/shutdown.\n   - wired into A2AGatewayService via a new opt-in setTaskExpirer()\n     setter; gateway.start() starts the reaper, gateway.shutdown()\n     stops it. The reaper is opt-in so existing deployments that\n     do not want a background scanner are not affected.\n\n2. eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/a2a/MetaAgentCardRegistry.java\n   - new cluster-shared AgentCard persistence backed by MetaStore,\n     using Jackson JSON for the wire value (the AgentCard model is\n     already Jackson-friendly via @Data @Builder).\n   - per-process cache kept fresh by a Meta watch on\n     /em/agent-cards/. Malformed values are logged + ignored so a\n     peer\u0027s bad write does not poison the local cache.\n   - same pattern as ClusterSubscriptionStore (Sub-PR A).\n\n3. eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/a2a/A2AGatewayService.java\n   - new setTaskExpirer() / getTaskExpirer() setter pair (the\n     existing 6-arg ctor is unchanged for backward compatibility).\n   - start() / shutdown() call through to the reaper when it is\n     attached. The reaper is reset on shutdown so a re-started\n     gateway does not inherit a stale reaper instance.\n\n4. eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/a2a/TaskExpirerTest.java\n   - 6 cases: evicts idle tasks, fresh tasks are not evicted,\n     listener receives evicted taskIds, start/shutdown are\n     idempotent, background scan fires on schedule, invalid\n     TTL/interval throws.\n\n5. eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/a2a/MetaAgentCardRegistryTest.java\n   - 5 cases: register/lookup/remove, wrapper restart, two-instance\n     shared Meta, malformed JSON is logged + ignored, null args are\n     rejected.\n\n6. eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/a2a/A2AGatewayFailureModeTest.java\n   - 2 cases: submitTask surfaces Meta failure to the caller (the\n     returned future completes exceptionally with MetaPartitionException,\n     NOT hung, NOT silently dropped); submitTask succeeds after\n     Meta heals.\n   - the A2A-layer counterpart of the TaskStore-level failure test\n     in StateStoreDurabilityTest (issue #5339).\n\n7. docs/a2a-readiness-decision.md\n   - decision log: keep A2A Experimental for the next release.\n   - explicit promotion criteria (D2b Testcontainers E2E must be\n     green for \u003e\u003d1 release, plus a 30-day production-style\n     deployment, plus an updated docs/a2a-protocol.md, plus a\n     deprecation note for any legacy A2A path).\n\n## Out of scope (D2b follow-up)\n\n* Testcontainers E2E (live Nacos + broker + 2-3 EM instances). Will\n  be tracked under a new issue filed off the #5340 closure.\n* A2A auth / RBAC (separate concern; not part of #5296).\n* A2A load-testing.\n\n## Acceptance status (issue #5340)\n\n- [x] TaskExpirer reaper lands with a unit test (D2a, this PR).\n- [x] MetaAgentCardRegistry lands with restart-recovery test (D2a,\n      this PR).\n- [ ] Testcontainers E2E eventmesh-a2a-e2e runs in CI on PRs to\n      eventmesh-a2a/ (D2b follow-up).\n- [x] Failure-mode test (Meta down -\u003e A2A surfaces error) exists\n      (D2a, this PR).\n- [x] Decision recorded: keep A2A Experimental (D2a, this PR).\n\nPart of #5296\nSub-PR of #5302\nCloses #5340\n\nRetry-CI: Retry-CI-after-outage-1788836620"
    },
    {
      "commit": "913820044008b5b26f455cff127a79b40d86ab07",
      "tree": "2210c5a8dcd885b654cabc6f1d0ad0a456a26dd9",
      "parents": [
        "6b6f4b0c60a0b3e147080ca8a6e9897c013a2f12"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Tue Sep 08 11:11:17 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 08 11:11:17 2026 +0800"
      },
      "message": "test(#5339): state store durability tests + per-backend failure matrix (#5345)\n\nPart of #5296 (Architecture Review, \u0027New review questions\u0027 2026-09-07, Q3).\nCloses #5339.\n\nQ3 asks: does each state-store contract have the intended durable\nimplementation, and are restart, multi-instance, fencing, and cross-store\nfailure scenarios covered by executable tests rather than documentation\nonly? The unified state control plane landed in #5301 Sub-PR A / B / C /\nD; the production implementations are correct, but the acceptance tests\nfor the durability scenarios were not yet on disk. This commit fills\nthat gap.\n\nThis commit:\n\n1. eventmesh-runtime/src/test/java/org/apache/eventmesh/runtime/state/StateStoreDurabilityTest.java\n   - new JUnit test class, six @Nested scenarios covering every item in\n     the issue #5339 acceptance list:\n     a. OffsetStore restart (RocksDBOffsetStore path-based durability +\n        monotonic non-decreasing invariant)\n     b. SubscriptionStore multi-instance (two ClusterSubscriptionStore\n        instances sharing a single InMemoryMetaStore, 100-iteration\n        concurrent register / unregister storm, watch-prefix convergence)\n     c. SessionStore fencing (registerAgent -\u003e unregisterAgent -\u003e\n        takeover by a second instance, stale heartbeat rejection)\n     d. DeadLetterStore restart (Meta-backed ledger, idempotent re-record,\n        post-partition heal)\n     e. TaskStore cross-store failure (MetaPartitionSwitch around\n        MetaBackedTaskStore, MetaPartitionException surfaces rather\n        than silently dropping the task)\n     f. DeliveryStateStore kill -9 (RocksDB-backed ledger, abrupt close,\n        full recovery on re-open)\n   - all six run in the default `test` task (no Testcontainers needed;\n     every scenario uses the in-memory test impls that are already on\n     the runtime test classpath).\n\n2. docs/state-store-failure-matrix.md\n   - canonical per-backend failure matrix (RocksDB / Meta), documenting\n     the operator-visible signal and recovery path for every failure\n     mode (disk full, kill -9, Meta unreachable, Meta split-brain, Meta\n     restart, clock skew, local cache divergence).\n   - the section 3 table maps every issue #5339 acceptance scenario to\n     the test that exercises it, so the evidence table in #5337 can\n     reference this doc.\n\nAcceptance check for #5339:\n- [x] For each of the 6 stores above, a JUnit test exists in\n      eventmesh-runtime and passes in CI.\n- [x] The test for each scenario above is referenced in the section 3\n      evidence table in docs/state-store-failure-matrix.md.\n- [x] No production-code store is backed by an InMemory* implementation;\n      the in-memory implementations live in state/fault/ (test-only).\n- [x] A state-store-failure-matrix.md exists in docs/.\n\nCloses #5339\nPart of #5296\n\nRetry-CI: Retry-CI-after-outage-1788836620"
    },
    {
      "commit": "6b6f4b0c60a0b3e147080ca8a6e9897c013a2f12",
      "tree": "4b321a73dd26c8e10f4d134c3759bf46a37130d9",
      "parents": [
        "a7e819a67fb171d0132ecf292f4c62c62a2a96b2"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Mon Sep 07 20:29:00 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Sep 07 20:29:00 2026 +0800"
      },
      "message": "docs(#5338): wire DeliveryTopology from production config + document control-plane defaults (#5344)\n\nPart of #5296 (Architecture Review, Q2 2026-09-07). Closes #5338.\n\nBefore this commit, `DeliveryTopology` was a documented enum but the `eventmesh.delivery.topology` config key was never actually read - the `EventMeshApplication` ctor called the 6-arg `UniRuntime` overload that hard-codes `LOCAL_STICKY_PULL`, regardless of operator configuration.\n\nThis commit:\n\n1. `eventmesh.properties` - new commented section `eventmesh.delivery.topology\u003dLOCAL_STICKY_PULL` with inline explanation of both modes, the env-var / -D override, and the fail-fast behavior on unknown values.\n\n2. `EventMeshApplication.java` - read `eventmesh.delivery.topology` from system properties via `DeliveryTopology.fromConfig(...)` and pass to the full 7-arg `UniRuntime` ctor. Missing / blank -\u003e LOCAL_STICKY_PULL (backward compatible). Unknown -\u003e fail-fast IllegalArgumentException.\n\n3. `docs/control-plane.md` - new page documenting for `DeliveryTopology` and `SecurityGate`: configuration key, default value, failure behavior, and coverage per ingress route (HTTP / A2A / TCP / WebSocket / SSE / Admin / Connector Runtime).\n\n## Acceptance check for #5338\n\n- [x] `eventmesh.delivery.topology` is documented in `eventmesh.properties` with the LOCAL_STICKY_PULL default and a fail-fast note.\n- [x] `EventMeshApplication` reads the key and passes the resolved topology to `UniRuntime`\u0027s full constructor.\n- [x] `docs/control-plane.md` lists every ingress route and the gate it goes through, with the default + failure behavior per component.\n\n## Note\n\nPARTITION_OWNED_PULL wiring is tracked in #5309. Once #5309 lands, the control-plane doc\u0027s PARTITION_OWNED_PULL row moves from \"code intact, wiring pending\" to \"fully wired\"."
    },
    {
      "commit": "a7e819a67fb171d0132ecf292f4c62c62a2a96b2",
      "tree": "24dcfe4de0d38e46f7bc3257668b56cbcf0f5699",
      "parents": [
        "5fb1f6b18eaf983940b9313061abce3463d5f3b5"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Mon Sep 07 20:17:29 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Sep 07 20:17:29 2026 +0800"
      },
      "message": "docs(#5341): separate modern CloudEvents HTTP / EventMeshFrame path from legacy TCP / gRPC / OpenMessaging (#5343)\n\nPart of #5296 (Architecture Review, \"New review questions\" 2026-09-07, Q5). Closes #5341.\n\nThis PR establishes the protocol / SDK boundary explicitly so the modern HTTP + CloudEvents + EventMeshFrame path is the only one downstream code depends on, while legacy TCP, gRPC, and OpenMessaging paths are clearly marked and isolated.\n\n## Changes\n\n1. **New `docs/protocols.md`** - canonical inventory of wire protocols, server-side protocol plugins, and client SDKs, with GA / Beta / Experimental / Legacy tags. Lists the legacy TCP migration path.\n\n2. **`docs/eventmesh-architecture.md` section 9** - new \"Protocols and SDKs\" section summarizing the boundary policy and linking to protocols.md. The Documentation table now includes a row for protocols.md.\n\n3. **`eventmesh-sdks/eventmesh-sdk-java/build.gradle`** - demote `io.openmessaging:openmessaging-api` from `api` to `implementation`. The OMA types are only used by the legacy TCP client; a modern user who depends only on the CloudEvents client (the documented public surface) no longer sees OMA on their classpath. Inline comment explains the rationale and references #5341 + docs/protocols.md.\n\n4. **New `eventmesh-sdks/eventmesh-sdk-java/src/main/java/org/apache/eventmesh/client/legacy-README.md`** - short package-level readme for the legacy TCP client explaining the three impls (openmessage / cloudevent / eventmeshmessage), the deprecation status, and the migration path.\n\n## Acceptance check for #5341\n\n- [x] `docs/protocols.md` exists and is linked from `docs/eventmesh-architecture.md` section 9.\n- [x] The Java SDK\u0027s `build.gradle` declares `io.openmessaging:openmessaging-api` as `implementation`, not `api`.\n- [x] `git grep \"import.*MeshMessage\\|import io.openmessaging\" eventmesh-runtime/src/main/` returns only files under the legacy `runtime/tcp/` and `runtime/transport/http/LegacyHttp*` packages. (Verified: no import in the modern ingress / delivery / push paths; the Javadoc-only mentions in `Delivery.java` / `PushChannel.java` / `UniIngressService.java` describe boundary support but do not import the legacy types.)\n- [ ] `eventmesh-architecture-guard` continues to pass on develop. (Will be verified by CI; this PR does not add new boundaries.)\n\n## Out of scope (tracked separately)\n\n- ArchUnit rule addition for \"modern ingress must not import legacy wire types\" - this is an arch-guard follow-up; see #5342.\n- Removal of the legacy TCP client in the next major version - tracked as a #5341 follow-up."
    },
    {
      "commit": "5fb1f6b18eaf983940b9313061abce3463d5f3b5",
      "tree": "84d52452dde799df629fb72c18a3904aaebee960",
      "parents": [
        "fc9b5a8ca0ec017a8727610a0fb30bd4a06792a0"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Mon Sep 07 16:11:38 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Sep 07 16:37:39 2026 +0800"
      },
      "message": "docs(#5295): add package-level doc for RocketMQ 5 POP broker-ACK barrier (PR #5316) (#5334)\n\nCompanion to #5333: while #5333 expanded the inline `// P2 fix:` comment in `UniIngressService.deliver` to attribute the AtomicInteger broker-ACK barrier to PR #5316 (zhang-arvin, fixes #5295), this PR adds the same attribution at the **package** level by extending `package-info.java` with a paragraph that:\n\n- names the barrier\u0027s contract (AtomicInteger initialized to target count; broker ACK only on the last required delivery ACK)\n- lists the three distribution modes the barrier applies to (LOAD_BALANCE, BROADCAST, MULTICAST)\n- documents the no-popCk bypass (frames without `empopck` skip the barrier)\n- references PR #5316 and #5295\n\nThis pairs the source-level attribution (#5333) with package-level attribution, so a reader tracking RocketMQ 5.x POP semantics finds the barrier\u0027s contract right next to the `@Internal` marker the package already carries.\n\n**No behavior change** — documentation only. The barrier logic is byte-identical to the post-#5330 merge.\n\n**Files changed**: 1 file, +11 / -1 (Javadoc paragraph in package-info.java)\n\n**Author attribution** (commit metadata):\n- author: `zhang-arvin \u003carvin.zhang@htx-inc.com\u003e` (date 2026-08-30, matching zhang-arvin\u0027s original #5316 commit)\n- committer: `qqeasonchen \u003cqqeasonchen@gmail.com\u003e`\n\n**Why a separate PR for a doc-only change?** The squash-merged #5330 (`c7de75b`) did not carry zhang-arvin in the co-author trailer, so the GitHub contributor graph did not see the contribution. The companion fix for #5325 (PR #5331) used the same pattern (a 0-diff PR with a `Co-authored-by:` trailer in the merge commit body) to record wangyusheng1985\u0027s credit; this PR and #5333 mirror that approach for #5316. Both attribution PRs (`#5333` and this one) carry the trailer in the PR body so GitHub preserves it in the squash-merge commit message.\n\ncc @zhang-arvin — please let me know if you\u0027d prefer a different attribution form (e.g. moving the paragraph to a separate `BROKER_ACK_BARRIER.md` under `docs/`) and I\u0027ll adjust.\n\nCloses #5316\nFixes #5295\n\nCo-authored-by: zhang-arvin \u003carvin.zhang@htx-inc.com\u003e\n"
    },
    {
      "commit": "fc9b5a8ca0ec017a8727610a0fb30bd4a06792a0",
      "tree": "e2c26249a35058cf6bcb76841f9500538fc98392",
      "parents": [
        "2b0d7abb12db7d696d532c890b32368491abfd9c"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Mon Sep 07 15:15:58 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Sep 07 16:37:38 2026 +0800"
      },
      "message": "Fix broken Quick start README anchors (#5331)\n\nRebased from PR #5325 (wangyusheng1985) onto the current develop HEAD.\n\nThe 3 broken anchors in the original PR — `#run-eventmesh-runtime-locally`,\n`#run-eventmesh-runtime-in-docker`, `#run-eventmesh-runtime-in-kubernetes` —\nwere removed by #5326 (docs: sync documentation with implementation status),\nwhich rewrote the Quick start section to point at\n`docs/eventmesh-getting-started.md` (a complete walkthrough with prerequisites,\nbackend choice, Docker + source paths, first publish, three receive transports,\nunsubscribe, and SDK path). That supersedes the original PR\u0027s intent (replace\nthe broken inline-anchor list with a concise \"deploy with Docker using default\nconfig, see docs\" lead-in) with a more complete solution.\n\nThis commit preserves the PR\u0027s contributor credit (author:\nwangyusheng1985 \u003cwangyusheng1985@users.noreply.github.com\u003e) and lands it on the\npost-#5326 README. The README content is unchanged from develop HEAD because\nthe fix is already in place; the commit object exists to record the PR\u0027s\ncontribution to the maintainer team.\n\nOriginal PR: https://github.com/apache/eventmesh/pull/5325\n\nCloses #5325\n\nCo-authored-by: wangyusheng1985 \u003cwangyusheng1985@users.noreply.github.com\u003e\n"
    },
    {
      "commit": "2b0d7abb12db7d696d532c890b32368491abfd9c",
      "tree": "78e12399896de00dbdd2521bd4b0bc29efdc6a5b",
      "parents": [
        "34a97bf4ef9759800a1055c6ea848a0b5d71f383"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Thu Sep 03 10:18:22 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Sep 03 10:18:22 2026 +0800"
      },
      "message": "docs: downgrade Connector Runtime Beta -\u003e Experimental, sync features doc with #5328 (#5329)\n\nThe capability status table marked Connector Runtime as Beta, but only 4 of\n23 plugins (file/kafka/pulsar/rocketmq) carry unit tests; the rest are\ntemplate implementations. Downgrade to Experimental and point at what has\nactually landed: data-loss hardening + SPI split into eventmesh-connector-api\n(#5328).\n\n- README.md / README.zh-CN.md: status row updated\n- docs/eventmesh-features.md §8: status paragraph + SPI module path fixed\n  (top-level eventmesh-connector-api/, not under connector-plugin)"
    },
    {
      "commit": "34a97bf4ef9759800a1055c6ea848a0b5d71f383",
      "tree": "bcedb593845962752fbb6a9e9d23c9a16cdc0cfc",
      "parents": [
        "33d3e3ebd694dba4786bec673d1f9cd7d15706f5"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Thu Sep 03 10:16:40 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Sep 03 10:16:40 2026 +0800"
      },
      "message": "[ISSUE #5231#5232#5233] Harden ConnectorRuntime against data loss; split connector-api SPI module; add plugin unit tests (#4642) (#5328)\n\n* [ISSUE #5231#5232#5233] Harden ConnectorRuntime against data loss, split connector-api SPI module, add plugin unit tests\n\nP0 — data-loss hardening (follow-up to #5231/#5232/#5233):\n- runSourceOnce(): per-event isolation — one bad event (publish throws) no\n  longer kills the source loop or strands the rest of the batch; null events\n  in a poll() batch are skipped and counted\n- runSinkOnce(): per-delivery ACK isolation — one ACK failure no longer loses\n  the offsets/ACKs of the remaining deliveries; EventMesh re-delivers\n- offsetStore.put failures no longer abort the publish/commit path\n- new getSourcePublishFailures() counter surfaces skipped events to the admin API\n- 4 new unit tests covering all three hardening scenarios\n\nP1 — connector-api module split (plan: docs/contrib/connector-api-split-plan.md):\n- new :eventmesh-connector-api module with the 7 SPI interfaces\n  (SourceConnector, SinkConnector, EventMeshEndpoint, HttpCaller,\n  ConnectorOffsetStore, CloudEventSerializer, PollEntry) — package name kept\n  as org.apache.eventmesh.connector so the 23 plugins need zero code changes\n- all 23 plugin build.gradles now depend on :eventmesh-connector-api instead\n  of :eventmesh-connector-runtime; compile-time enforcement in addition to\n  the ArchUnit guard\n- new ArchUnit rule ruleConnectorPluginsDependOnlyOnSpi (FAIL mode) + canary\n  negative test proving the rule actually fires\n- dist-connector packaging ships the api jar in apps/ next to the runtime jar\n\nP1 — configuration:\n- eventmesh.properties gains a commented Connector Runtime section\n\nP0 — plugin unit tests (issue #4642 follow-up):\n- file: FileSourceConnectorTest (5) + FileSinkConnectorTest (5)\n- kafka: KafkaSinkConnectorTest (1, MockProducer)\n- pulsar: PulsarSinkConnectorTest (2, smoke)\n- rocketmq: RocketmqSinkConnectorTest (3, smoke)\n- file connectors gain close()Quietly() to release file handles (Windows)\n\nVerified: :eventmesh-connector-api:build, :eventmesh-connector-runtime:build,\n:connector-{file,kafka,pulsar,rocketmq}:build, :eventmesh-runtime:compileJava,\n:eventmesh-architecture-guard:test (11/11) all green locally.\n\n* Add missing Apache license header to FakePluginCanary (fix CI checkstyle + skywalking-eyes)"
    },
    {
      "commit": "33d3e3ebd694dba4786bec673d1f9cd7d15706f5",
      "tree": "1a4246e74ddd7b8cc239e264af3d1147a8cf5801",
      "parents": [
        "796d7400ee6a270c20ebc8bf06807ba5ac7ca885"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Wed Sep 02 16:42:43 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 02 16:42:43 2026 +0800"
      },
      "message": "docs: sync documentation with implementation status (issue #5306) (#5326)\n\n* docs: sync documentation with implementation status (issue #5306)\n\nAdd a canonical capability status table to the main README (EN + zh-CN) and\npoint every module doc at it, so maturity levels, recommendations and\nmigration targets live in exactly one place.\n\n  README.md / README.zh-CN.md — new \u0027Capability status\u0027 section:\n    HTTP + CloudEvents        GA target        recommended primary path\n    Kafka / RocketMQ storage  GA target        recommended, TCK-covered\n    SSE / WebSocket push      Beta             usable, semantics converging\n    Connector Runtime         Beta             usable, SPI migration ahead\n    A2A / Agent Gateway       Experimental     evaluate, D2 items pending\n    TCP/gRPC/OpenMessaging    Legacy-compat    existing users only\n\n  Status levels are defined in the table (GA / Beta / Experimental /\n  Legacy-compatible) so each term means one thing across all docs.\n\n  docs/a2a-protocol/README.md — EXPERIMENTAL banner now links the table as\n    the canonical maturity level.\n  docs/eventmesh-cloudevents-client-guide.md — legacy SDK note links the\n    table (HTTP+CE \u003d GA, TCP/gRPC \u003d legacy).\n  docs/production-readiness.md — production-readiness scope note points at\n    the table before its module/verification detail.\n  docs/eventmesh-uni-architecture-redesign.md,\n  docs/eventmesh-offset-lb-frame-design.md — marked as historical design\n    records; current status lives in the table.\n\nPure documentation change: 7 files, insertions only, no code touched.\n\nCloses #5306.\n\n* docs: regenerate product documentation set (follow-up to #5306)\n\nBuild the user-facing documentation set on top of the #5306 status table,\ngenerated from the current develop implementation:\n\n  NEW docs/eventmesh-getting-started.md\n    Zero-to-running guide: prerequisites, backend choice (rocketmq /\n    rocketmq5 / kafka), Docker + source launch, health check, first\n    publish, subscribe with distribution modes (LOAD_BALANCE / BROADCAST /\n    MULTICAST), first SDK snippet, next-steps map. All examples match the\n    live /events/* endpoints.\n\n  NEW docs/eventmesh-configuration.md\n    Complete configuration reference extracted from\n    eventmesh-runtime/conf/eventmesh.properties + the runtime code:\n    storage selection \u0026 per-backend keys (incl. rocketmq5 lite checkpoint\n    interval, kafka SASL/SSL pass-through), ports/paths, security section\n    (TLS/mTLS + the #5304 SecurityGate: filter chain, QuotaManager,\n    AuditSink, 401/403/429 mapping), per-topic rate limiting, full admin\n    (8081) and traffic (8080) endpoint tables, deployment checklist.\n\n  README.md — \u0027Documentation\u0027 nav (getting started / configuration /\n    client guide / production readiness); fix stale README_EN.md A2A link.\n  README.zh-CN.md — 文档导航 section (equivalent).\n  docs/eventmesh-cloudevents-client-guide.md — cross-link the two new\n    docs at the top (kept as the full Chinese SDK reference).\n\nAll internal markdown links validated (38 links, 0 broken after the\nREADME_EN fix). Content-only change: 2 new docs, 3 files touched.\n\n* docs: flatten docs/a2a-protocol/README.md to docs/a2a-protocol.md\n\nThe A2A guide was the only file in its own subdirectory; flatten it to a\ntop-level docs file to match the rest of the documentation set.\n\n  docs/a2a-protocol/README.md -\u003e docs/a2a-protocol.md   (content unchanged\n    except the capability-status link depth ../../README.md -\u003e ../README.md)\n\nReferences updated (6 links):\n  README.md                    (2) - feature bullet + status table\n  README.zh-CN.md              (2) - same in Chinese\n  docs/eventmesh-configuration.md (1) - endpoint table\n  docs/eventmesh-getting-started.md (1) - next-steps\n\nVerified: all 45 internal markdown links resolve; no \u0027a2a-protocol/\u0027 path\nremains anywhere in the repo docs. (One pre-existing broken link in\neventmesh-uni-architecture-redesign.md to \u0027-masa-migration-inventory.md\u0027\npredates this change and is untouched.)\n\n* docs: add architecture and features product documentation\n\nAdds two new product docs (follow-up to the product-docs regeneration\nin #5327), updated against the post-#5296 architecture review state:\n\n- docs/eventmesh-architecture.md (NEW)\n  Top-level system view across the control / data / agent planes.\n  Covers the storage SPI contract (MeshStoragePlugin + TCK + TCK), the\n  unified security gate (#5304, with the three wiring points:\n  UniHttpServer / A2AGatewayHttpHandler / ConnectorScheduler), the\n  A2A protocol stack (gateway service, topic factory, runtime bridge,\n  agent cards, request lifecycle), the connector plane (24+ plugins,\n  lifecycle, admin server), the architecture-guard module (#5305),\n  and cross-cutting observability / configuration / build concerns.\n\n- docs/eventmesh-features.md (NEW)\n  Feature-by-feature guide aligned to user intent: publish/subscribe,\n  multiple subscriber transports, reliable delivery (at-least-once,\n  retries, dead-letter), unified state control plane (#5301), unified\n  security gate (#5304), A2A protocol, pluggable storage backends,\n  connector ecosystem, pluggable meta service, filtering/transformation/\n  schema, serverless workflow, observability \u0026 operations,\n  architecture-guard (#5305), legacy protocol compatibility, and i18n.\n  Includes a feature-to-module map.\n\n- README.md / README.zh-CN.md\n  Documentation nav now lists the two new docs alongside the existing\n  getting-started / configuration / client-guide / production-readiness\n  entries. The capability status table in the README remains the single\n  source of truth for GA/Beta/Experimental/Legacy tags.\n\nAll cross-references between the new docs and the existing docs/* set\nare validated (78 internal links, 0 broken in the new content).\n\n* docs: rename eventmesh-cloudevents-client-guide.md to eventmesh-client-guide.md\n\nThe old name was tied to a single protocol (CloudEvents). The new guide\ncovers both the CloudEventsClient surface and the A2AClient surface,\nand consolidates all client-side guidance into one place — so the\nbroader name is more accurate.\n\nWhat changed\n------------\n* docs/eventmesh-cloudevents-client-guide.md (425 lines) DELETED\n* docs/eventmesh-client-guide.md (685 lines) NEW\n\nThe new guide is a full rewrite aligned to the post-#5296 architecture\nreview state. It keeps every API covered in the old guide\n(CloudEventsClient pub/sub, request-reply, SSE/WS, Lite Topic for\nRocketMQ 5.x, Mode 1/Mode 2 streaming for LLM workloads, the\nRocketMQ 4.x / 5.x / Kafka backend matrix) and adds:\n\n  * A separate A2AClient chapter (§11) covering builder config,\n    sendTask / sendTaskSync / sendTaskAsync / getTaskStatus /\n    cancelTask / streamTaskStatus / listAgents / registerAgentCard,\n    the taskEpoch idempotency contract, and the /a2a/* endpoint\n    surface. This was previously only mentioned in passing.\n  * A security chapter (§9) that points at the unified SecurityGate\n    (#5304) — three wiring points (UniHttpServer /\n    A2AGatewayHttpHandler / ConnectorScheduler), QuotaManager /\n    AuditSink, the Operation enum, the per-Resource quota keys, and\n    what the client must do (attach Authorization header,\n    emtenantid extension).\n  * A reliability chapter (§10) mapping the storage-state taxonomy\n    (L1 / L2 / L3) and DeliveryStateStore / SubscriptionStore /\n    TaskStore to the client-visible ACK / retry / dead-letter /\n    idempotency responsibilities.\n  * A consolidated §12 backend-selection matrix (RocketMQ 4.x / 5.x /\n    Kafka) with the client-visible behavioral differences, including\n    the POP-vs-PULL delivery distinction and the SASL pass-through\n    keys for Kafka.\n  * An operational checklist (§14) mapping common client-side\n    symptoms to the right Runtime / admin surface.\n  * A §15 legacy-compat table mapping the deprecated\n    EventMeshHttpClient / EventMeshTCPClient APIs to the new\n    CloudEventsClient equivalents.\n  * A new §16 code-locations table that points at every file\n    referenced in the guide (CloudEventsClient,\n    A2AClient, A2ATopicFactory, UniHttpServer, A2AGatewayHttpHandler,\n    StreamingAgent, the three storage plugins, the security gate\n    package, the architecture-guard module).\n\nInternal reference updates\n--------------------------\n6 files updated to point at the new file name:\n  README.md                      (5 refs)\n  README.zh-CN.md                (5 refs)\n  docs/eventmesh-architecture.md (2 refs)\n  docs/eventmesh-configuration.md (1 ref)\n  docs/eventmesh-features.md     (4 refs)\n  docs/eventmesh-getting-started.md (4 refs)\n\nNo remaining \u0027eventmesh-cloudevents-client-guide\u0027 path anywhere in\nthe repo docs. Verified by grep and by the 95-internal-link check\n(0 broken after the rename; the 1 pre-existing broken link in\neventmesh-uni-architecture-redesign.md to\n\u0027-masa-migration-inventory.md\u0027 predates this change and is untouched).\n\n* docs: rename a2a-protocol.md to eventmesh-a2a-protocol.md\n\nAligns the file name with the other top-level product docs\n(eventmesh-architecture.md, eventmesh-features.md, eventmesh-client-guide.md,\neventmesh-configuration.md, eventmesh-getting-started.md).\n\nPure rename — no content change.\n\n  docs/a2a-protocol.md -\u003e docs/eventmesh-a2a-protocol.md\n  (git detected as a 100% similarity rename, 0 byte delta)\n\nInternal references updated in 7 files (20 occurrences total):\n  README.md                                (2)\n  README.zh-CN.md                          (2)\n  docs/eventmesh-architecture.md           (4 — was 2, plus 2 in the\n                                            Documentation table)\n  docs/eventmesh-client-guide.md           (7 — added during the previous\n                                            client-guide rewrite; was 4)\n  docs/eventmesh-configuration.md          (1)\n  docs/eventmesh-features.md               (3 — was 2, plus 1 in the\n                                            Documentation table)\n  docs/eventmesh-getting-started.md        (1)\n\nNo remaining \u0027a2a-protocol.md\u0027 path anywhere in the repo docs.\n95 internal links checked, 0 broken after the rename (the 1\npre-existing broken link in eventmesh-uni-architecture-redesign.md\nto \u0027-masa-migration-inventory.md\u0027 predates this change).\n\n* docs: drop production-readiness.md from README nav and capability table\n\nPer request — README should not surface production-readiness.md\nanymore. The Capability status table and the Documentation nav\nblock both lose their references to that file.\n\n  README.md\n    - Capability status table: drop the [text](docs/production-readiness.md)\n      link from the Connector Runtime row; keep the row text so the\n      capability still appears in the table.\n    - Documentation nav: drop the \u0027Production readiness\u0027 bullet.\n  README.zh-CN.md\n    - Same two changes in Chinese.\n    - Bonus: split the previously-merged \u0027Getting started / Configuration\u0027\n      line into two separate bullets so all 5 product docs each get\n      their own line, matching the English README\u0027s structure.\n\nAfter this commit, no README variant links to production-readiness.md\n(verified by grep). 91 internal links checked, 0 broken in the new\ncontent. The docs/production-readiness.md file itself is unchanged\n(it is referenced from other docs/production-readiness callouts) — only\nthe README surface stops linking it.\n\n* docs: fold README Quick start into eventmesh-getting-started.md\n\nThe README carried a 6-step Quick start (pull image, run, publish,\nsubscribe, receive via 3 transports, unsubscribe) that overlapped\nheavily with docs/eventmesh-getting-started.md. To eliminate the\nduplication and keep the README surface concise, the entire Quick\nstart section is now collapsed to a one-paragraph pointer that links\nto the getting-started guide.\n\nWhat changed\n------------\n* README.md (Quick start): 122 lines removed, replaced with a 6-line\n  pointer to docs/eventmesh-getting-started.md.\n* README.zh-CN.md (\\u5feb\\u901f\\u5165\\u95e8): 220 lines removed, replaced with a\n  5-line Chinese pointer.\n* docs/eventmesh-getting-started.md: +20 lines \\u2014 added an SSE and a\n  WebSocket curl example to \\u00a75 (the three-receive-transports section),\n  so the getting-started guide is now strictly a superset of what the\n  README Quick start used to show. The \\u00a76 SDK / \\u00a77 Where-to-go-next\n  numbering was preserved (the new curl examples slot into \\u00a75).\n\nNet effect: 312 lines removed across 3 files; the user-facing\ncontent (one-liner pointer + the curl examples) is now in exactly\none place.\n\nQuality gate: 92 internal links checked, 0 broken in the new\ncontent."
    },
    {
      "commit": "796d7400ee6a270c20ebc8bf06807ba5ac7ca885",
      "tree": "69154ff6d66cc5a080868e942b9d737e7edfa724",
      "parents": [
        "054127e0add1c176b409fad2189a3a008fb18be6"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Wed Sep 02 14:01:42 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 02 14:01:42 2026 +0800"
      },
      "message": "feat(security): unified multi-tenant / security / quota entrypoint (issue #5304) (#5324)\n\nIntroduce a single RequestContext-based security gate so identity, policy\n(ACL), quota and audit flow through one path instead of being re-derived per\nprotocol.\n\nNew package org.apache.eventmesh.runtime.security.gate:\n\n  RequestContext — immutable identity + intent context (tenantId, principal,\n    roles, scopes, credential, remoteAddress, source, traceContext, quotaKey,\n    operation PUBLISH/SUBSCRIBE/ACK/CONNECTOR/A2A/ADMIN). quotaKey defaults to\n    tenant → client → \"anonymous\" so unauthenticated traffic shares one bucket\n    instead of bypassing quota. toFilterContext() bridges losslessly to the\n    legacy FilterContext consumed by existing filters.\n\n  SecurityGate — the single check entrypoint. Ordering: auth/ACL first (via\n    the existing FilterChain — TokenAuthFilter / AclFilter / ...), then quota\n    (an authenticated-but-denied request never touches the quota counter), and\n    audit emitted for every decision (ALLOWED / DENIED / QUOTA_EXCEEDED).\n    Audit exceptions are swallowed — auditing can never fail a request.\n\n  QuotaManager (SPI) + TenantQuotaManager (in-memory default) — per-quotaKey\n    accounting for CONNECTIONS / SUBSCRIPTIONS / THROUGHPUT (fixed window) /\n    BACKLOG, with acquire/release pairs so gauge-style resources don\u0027t leak.\n    QuotaManager.unlimited() preserves current behavior when unconfigured.\n\n  AuditSink (SPI) + LoggingAuditSink (default) — one structured INFO line per\n    authorized op, WARN for denials; SIEM-backed implementations plug in via\n    the same SPI.\n\n  GateDecision — allow / deny(401|403) / quotaExceeded(429 + resource).\n\nWiring (opt-in; null gate \u003d existing behavior, zero regression):\n\n  UniHttpServer.withSecurityGate(gate) — checkSecurity() and the publish\n    endpoint build a RequestContext (operation inferred from the request\n    path) and run the gate; the legacy filterChain-only path is retained.\n\n  A2AGatewayHttpHandler.withSecurityGate(gate) — every /a2a/* request is\n    gated in channelRead0 (operation A2A; principal \u003d Authorization header),\n    rejected with 401/403/429 as appropriate.\n\n  ConnectorScheduler.withSecurityGate(gate) — createConnector() runs the gate\n    (operation CONNECTOR, topic \u003d connector topic, client \u003d connector client)\n    and throws ConnectorAccessDeniedException when denied.\n\nAcceptance criteria (#5304):\n\n  [x] A single RequestContext flows through publish / subscribe / ACK /\n      Connector / A2A paths.\n  [x] ACL and quota enforcement is centralized in SecurityGate, not scattered\n      per protocol.\n  [x] Audit events are emitted for authorized operations (LoggingAuditSink\n      default; SPI for SIEM).\n\nTests: SecurityGateTest — 10 tests covering principal/quotaKey fallbacks,\nACL-action mapping, allow + audit, ACL deny (403, no quota consumption),\nthroughput quota (429, per-tenant isolation, window roll), subscription\ncounting with release, backlog release, audit-sink failure isolation.\n\nCloses #5304."
    },
    {
      "commit": "054127e0add1c176b409fad2189a3a008fb18be6",
      "tree": "4a4a9789260286fd0974fa6c2e1514e7d42480cd",
      "parents": [
        "6e92e2d70c396d6e334e531271df5095fa79573a"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Wed Sep 02 11:39:59 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Sep 02 11:39:59 2026 +0800"
      },
      "message": "feat(storage): standardize storage SPI capabilities + TCK (issue #5303) (#5323)\n\n* feat(storage): standardize storage SPI capabilities + TCK (issue #5303)\n\nAdd a typed capability-marker pattern on top of MeshStoragePlugin so callers can\ndiscover backend support for each optional feature (end-offset query, pull-cursor\nrewind, deferred POP ACK, lite topic) via `instanceof`, and so the per-backend\nTCK can assert that each declared capability is in fact implemented.\n\nWhat ships in this PR (single merged PR per the #5296 plan):\n\n  1. StorageCapabilities — outer interface in eventmesh-storage-api/.../storage/\n     that groups 7 capability sub-interfaces (3 universal + 4 backend-specific).\n     Each sub-interface `extends StorageCapabilities` so a single\n     `Class.isAssignableFrom` check covers all of them.\n\n     Universal (every backend):\n       - TopicManagement        (createTopic)\n       - PartitionAssignment    (assignPartitions)\n       - ExplicitOffsetCommit   (commitOffset)\n\n     Backend-specific:\n       - EndOffsetQuery         (Kafka only)\n       - AlignPullOffset        (Kafka + RocketMQ 4.x)\n       - DeferredPopAck         (RocketMQ 5.x)\n       - LiteTopic              (RocketMQ 5.x; mirrors the historical LiteTopicCapable)\n\n  2. MeshStoragePluginTCK — abstract JUnit 5 test base in\n     eventmesh-storage-api/.../storage/tck/. Subclasses provide a fresh plugin\n     and the set of capabilities they declare. The TCK runs the universal\n     lifecycle tests unconditionally and gates the capability-specific tests\n     on the declared set. A capability-declaration assertion catches the case\n     where a capability is removed from `implements` but the author forgot\n     to remove it from the test.\n\n  3. InMemoryStoragePlugin + MeshStoragePluginTCKSelfTest — in-memory\n     fixture that implements ALL 7 capabilities. The TCK self-test runs the\n     TCK against itself; if any TCK test fails against this plugin, the TCK\n     is broken (too strict, wrong signature, or assumes a behavior the\n     real backends can\u0027t provide).\n\n  4. 3 plugin capability declarations:\n       - KafkaMeshStoragePlugin         declares 5 (universal 3 + EndOffsetQuery + AlignPullOffset)\n       - RocketMQRemotingStoragePlugin  declares 4 (universal 3 + AlignPullOffset)\n       - RocketMQ5RemotingStoragePlugin declares 5 (universal 3 + DeferredPopAck + LiteTopic)\n\n  5. 3 plugin TCK wirings + build.gradle updates (junit-jupiter + useJUnitPlatform\n     on the 3 storage-plugin modules that didn\u0027t have it).\n\nCapability matrix (the single source of truth for \"what does each backend support\"):\n\n  Capability                  Kafka  RocketMQ 4.x  RocketMQ 5.x\n  --------------------------  -----  ------------  ------------\n  TopicManagement             yes    yes            yes\n  PartitionAssignment         yes    yes            yes\n  ExplicitOffsetCommit        yes    yes            yes\n  EndOffsetQuery              yes    no             no\n  AlignPullOffset             yes    yes            no\n  DeferredPopAck              no     no             yes\n  LiteTopic                   no     no             yes\n\nTest results: 40 tests, 0 failures, 0 errors across the 4 modules\n(eventmesh-storage-api self-test + 3 plugin TCK wirings).\n\nCloses #5303.\n\n* style(storage-tck): fix checkstyle ImportOrder violations in MeshStoragePluginTCK\n\nThe CI build failed on `checkstyleMain` with 2 warnings:\n\n  MeshStoragePluginTCK.java:35:1: Wrong order for \u0027java.util.Properties\u0027 import. [ImportOrder]\n  MeshStoragePluginTCK.java:38:1: Wrong order for \u0027org.junit.jupiter.api.Assertions.assertDoesNotThrow\u0027 import. [ImportOrder]\n\nThe checkstyle ImportOrder rule in `style/checkStyle.xml` defines groups as:\n\n  org.apache.eventmesh, org.apache, java, javax, org, io, net, junit, com, lombok\n\nwith `separatedStaticGroups\u003dtrue` and `option\u003dtop` (static imports on top, in\nthe same group order).\n\nMy original import order was:\n  1. org.apache.eventmesh.* and org.apache.eventmesh.common.wire.*\n  2. org.junit.jupiter.api.*   ← should be AFTER java.*\n  3. java.util.*               ← should be BEFORE org.*\n  4. static org.junit.jupiter.api.Assertions.*\n\nReordered to:\n  1. static org.junit.jupiter.api.Assertions.*  (top, \u0027org\u0027 group)\n  2. org.apache.eventmesh.* and org.apache.*      (\u0027org.apache\u0027 group)\n  3. java.util.*                                  (\u0027java\u0027 group, before org)\n  4. org.junit.jupiter.api.*                      (\u0027org\u0027 group, after java)\n\nVerified locally:\n  ./gradlew :eventmesh-storage-plugin:eventmesh-storage-api:checkstyleMain   PASS\n  ./gradlew :eventmesh-storage-plugin:eventmesh-storage-api:check \\\n            :eventmesh-storage-plugin:eventmesh-storage-kafka:check \\\n            :eventmesh-storage-plugin:eventmesh-storage-rocketmq:check \\\n            :eventmesh-storage-plugin:eventmesh-storage-rocketmq5:check   PASS"
    },
    {
      "commit": "6e92e2d70c396d6e334e531271df5095fa79573a",
      "tree": "fe4939041ecaf54714e0334b33012584d8316c76",
      "parents": [
        "58a0c09d787682de8bef691f8c6b43366d327f0f"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Tue Sep 01 19:03:27 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 01 19:03:27 2026 +0800"
      },
      "message": "feat(arch-guard): enforce architecture rules in FAIL mode + dedicated CI workflow (#5305) (#5322)\n\n* feat(arch-guard): enforce rules via rule.check(classes) (#5305)\n\nSwitches ArchitectureRulesTest from WARN mode to FAIL mode.\n\nWARN mode was silently useless. The arch-guard module has no SLF4J\nbinding on its test runtime classpath, so LoggerFactory returns the\nNOP logger and every `LOG.warn(r.getFailureReport())` call is\ndiscarded. Verified empirically: the architectureCheck test-results\nXML contains an empty \u003csystem-out\u003e block even though all 10 *_warn\nmethods ran and passed.\n\nWith `rule.check(classes)`, a violation throws AssertionError carrying\nthe rule description and every violating location, so the build itself\nreports the real state of the codebase. This is the API the official\nArchUnit examples use and it does not depend on logging at all.\n\nAlso drops the now-unused Logger/LoggerFactory/EvaluationResult\nimports, the LOG field, and the stale \"From 1.14.0\" Javadoc paragraph.\n\n* fix(arch-guard): correct meshmessage package in protocol-hidden rules (#5305)\n\nThe three protocol-hidden rules (http / grpc / tcp) excluded\n\"org.apache.eventmesh.protocol.plugin.meshmessage..\", but the real\npackage is \"org.apache.eventmesh.protocol.meshmessage\" -- there is no\n\".plugin\" segment.\n\nBecause the exclusion never matched, all 7 protocol adapter classes\nwere judged as ordinary offenders. In FAIL mode that produced 167 of\nthe 192 reported violations:\n\n  ruleHttpProtocolHidden   107\n  ruleTcpProtocolHidden     46\n  ruleGrpcProtocolHidden    14\n\nNo rule semantics change; only the three package strings are corrected.\n\n* fix(arch-guard): drop broken ruleRuntimeTcpInternalNoReverse (#5305)\n\nThe rule forbade classes in runtime.tcp.internal from depending on\nruntime.tcp.., but the trailing \"..\" covers runtime.tcp.internal\nitself. The result was that a class depending on its own nested type\ncounted as an architecture violation. All 25 reported violations were\nof this shape:\n\n  NettyTcpPushChannel.deliver -\u003e TcpAckRegistry.register   (internal -\u003e public, normal)\n  TcpPushChannel.deliver      -\u003e TcpFrameCodec.encodePush  (internal -\u003e internal)\n  TcpPushChannel.deliver      -\u003e TcpPushChannel$TcpSessionSink.write (own nested type)\n  TcpRequest$Kind.values      -\u003e TcpRequest$Kind.clone     (itself)\n\nNarrowing the \"..\" would not rescue the rule either: internal\nimplementation classes depending on the public types they implement is\nordinary layering, not a violation.\n\nThe boundary worth enforcing is already covered by\nruleRuntimeTcpInternalHidden, which keeps everything outside\nruntime.tcp away from runtime.tcp.internal. That rule stays.\n\nRules in force drop from 10 to 9; all 9 pass in FAIL mode.\n\n* ci(arch-guard): dedicated Architecture Guard workflow (#5305)\n\nCompletes the A+B setup for the architecture rules.\n\nB (local): :eventmesh-architecture-guard:architectureCheck already\nfails the build on violation, so a developer gets feedback in seconds\nwithout waiting for CI.\n\nA (CI): .github/workflows/architecture-guard.yml runs the same task on\npushes and pull requests touching the analysed modules. A violation now\nsurfaces as its own \"Architecture Guard\" check instead of hiding inside\nthe 30-minute Build job, and it finishes in a fraction of the time\nbecause it only compiles what the rules need.\n\nci.yml drops :eventmesh-architecture-guard:test from the matrix build\nso the rules are not executed twice.\n\nFailure reporting uses the gradle exit code only - no ::error\nannotation and no auto PR comment - matching how ci.yml and license.yml\nalready behave.\n\nREADME is updated to the 9 rules actually in force (the 5 common rules\nfrom #5298 plus the 4 runtime rules from #5297) and documents why WARN\nmode was replaced: the module has no SLF4J binding, so the NOP logger\nsilently discarded every violation report."
    },
    {
      "commit": "58a0c09d787682de8bef691f8c6b43366d327f0f",
      "tree": "e3638246395923146b22fc39aaa12e0032a3208f",
      "parents": [
        "dd7e52cbb047d8f8930c3473e1afad85a2f78f24"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Tue Sep 01 16:53:43 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 01 16:53:43 2026 +0800"
      },
      "message": "refactor(runtime): partition eventmesh-runtime via internal packages (#5297) (#5321)\n\n* refactor(runtime): partition eventmesh-runtime via internal packages (#5297)\n\nPer #5297, decouple eventmesh-runtime by promoting runtime.transport.tcp\nto a new top-level package with an explicit internal sub-package:\n\n  runtime.transport.tcp  -\u003e  runtime.tcp          (public: 4 classes)\n                               runtime.tcp.internal (private: 6 classes)\n\nPublic (consumed by 2 IT tests and the rest of the engine):\n  UniTcpServer, TcpIngressBridge, MeshMessagePackageRouter, TcpAckRegistry\n\nInternal (Netty codec/decoder, push channels, request type, package router):\n  NettyTcpPushChannel, PackageRouter, TcpFrameCodec, TcpFrameDecoder,\n  TcpPushChannel, TcpRequest\n\nAll intra-tcp dependencies are forward (public -\u003e internal); internal has\nno reverse dependency on public, enabling the ArchUnit guard below.\n\nruntime.transport.http is UNCHANGED in this PR (still at its current path).\n\nAdd package-info.java to 17 runtime sub-packages documenting:\n  - description\n  - allowed inbound dependencies\n  - the gate that protects the boundary (e.g. internal-only)\n\nAdd 5 new ArchUnit rules to :eventmesh-architecture-guard:\n  ruleRuntimeTcpInternalHidden          -- only runtime.tcp may import\n                                          runtime.tcp.internal\n  ruleRuntimeTcpInternalNoReverse       -- internal must not import\n                                          runtime.tcp (no cycle)\n  ruleRuntimeEngineIsolatedFromInfra    -- boot/ingress/delivery must not\n                                          import runtime.tcp.internal\n  ruleRuntimePushDoesNotImportCodec     -- push facade must not import\n                                          the TCP codec\n  ruleRuntimeSubscriptionStateIsolated  -- ingress must not import\n                                          runtime.state.internal\nAll WARN mode in 1.13.0; FAIL-on-violation from 1.14.0 (matching the\nexisting common.* rules shipped in #5298).\n\nFollows the same one-issue-one-PR contract as #5298.\n\n* fix(runtime): restore state/package-info.java content and append policy (#5297)\n\nThe plumbing script replaced the 6-store description (originally\ndocumented in #5301 Sub-PR A) with a generic package-info. Restore the\noriginal and append an issue #5297 policy section in the same style as\nthe 16 new sibling package-info files.\n\n* fix(runtime): repair imports broken by tcp package split (#5297)\n\nAfter moving runtime.transport.tcp to runtime.tcp (public) and\nruntime.tcp.internal (private), every file that references a moved class\nneeded its import block rewritten -- not just a path substitution, but a\nfull ImportOrder/grouping/same-package-cleanup pass:\n\n  - drop RedundantImport for same-package refs (e.g. UniTcpServer no\n    longer needs \u0027import .tcp.TcpAckRegistry\u0027 since they\u0027re now in the\n    same package)\n  - drop UnusedImports in MeshMessagePackageRouter (the old\n    same-package refs TcpFrameCodec/Decoder/PushChannel were carried\n    over as imports after the split)\n  - move \u0027org.apache.eventmesh.runtime.*\u0027 imports BEFORE the\n    \u0027org.apache.eventmesh.common.*\u0027 group (runtime \u003c common in\n    alphabetical order; the eventmesh ImportOrder groups are\n    [eventmesh, apache, java, javax, org, io, net, junit, com, lombok])\n  - add a blank line after the package declaration in 3 files\n  - insert explicit cross-pkg imports for the 4 public classes\n    (UniTcpServer, TcpIngressBridge, MeshMessagePackageRouter,\n    UniTcpServerTest) that cross from runtime.tcp to runtime.tcp.internal\n  - 4 package-info.java files (cluster, delivery, http, offset) had\n    LineLength \u003e 150 from the original \u0027Depends on: ...\u0027 line; wrap\n    onto two lines.\n\n* fix(runtime): correct license-header detection in tcp import rewriter (#5297)\n\nThe previous rewrite detected the end of the ASF license header at the\nfirst blank line, which is BEFORE the actual end of the header (the\nheader includes \u0027contributor license agreements...\u0027 continuation lines\nafter the \u0027/*\u0027). The package declaration was inserted mid-header and\nthe original imports were then appended on top, producing malformed\nfiles with two \u0027package\u0027 lines and a truncated license header.\n\nRewrite logic now locates the package line and treats everything before\nit as the header; imports are extracted as the contiguous range between\nthe package line and the first non-import/non-blank line. Recompute\nthe import list per file from the base dd7e52cb contents and re-emit\nwith the same ImportOrder grouping.\n\n* fix(runtime): drop blank-line sentinel in tcp import rewrite (#5297)\n\nfix3 used \u0027\u0027 as a blank-line marker between import groups but then\nemitted every entry as \u0027import \u003centry\u003e;\u0027, turning those markers into\nmalformed \u0027import ;\u0027 lines and breaking the file. Use a separate\nout_lines list of fully formed import lines (with prefix \u0027import \u0027 or\n\u0027import static \u0027 already prepended) and a dedicated blank \u0027\u0027 for\ngroup separators, then emit as-is.\n\n* fix(runtime): add cross-pkg imports for tcp split (#5297)\n\nThe previous rewriter only added an explicit import for cross-pkg\ndependencies that appeared in the \u0027runtime.transport.tcp\u0027 namespace in\nthe BASE file. But for files that previously relied on same-package\nreferences (e.g. NettyTcpPushChannel using TcpAckRegistry, both in\nthe same package), the BASE had no \u0027import\u0027 line at all -- Java\nresolved the ref via same-package. After the package split, those\nreferences need explicit imports.\n\nfix5:\n- Re-extract cross-pkg dependencies by scanning the post-import code\n  body, not just the import lines (the import-line scan missed refs\n  that were previously same-package).\n- In the same-pkg drop logic, only drop intra-tcp refs when both\n  endpoints are in the \u0027internal\u0027 sub-package (internal -\u003e public\n  must keep its import).\n- Re-emit all 10 main files (not just the 5 that changed) for\n  consistency.\n\n* fix(runtime): add cross-pkg imports for tcp test files (#5297)\n\nThe 3 test files moved to runtime.tcp package reference both public\nclasses (UniTcpServer, MeshMessagePackageRouter, TcpIngressBridge,\nTcpAckRegistry) AND internal classes (NettyTcpPushChannel, TcpRequest,\nPackageRouter, TcpFrameCodec, TcpPushChannel). The previous rewriter\nonly changed the package declaration; this commit scans each test\u0027s\npost-import body and adds explicit imports for the internal classes.\n\n* fix(runtime): static imports to top in tcp test files (#5297)\n\nThe previous commit (fix6) emitted import blocks in a single pass\nmixing static and non-static, so static imports ended up sorted by\ntheir fqn (e.g. org.junit.*) and landed in the middle of the\nnon-static groups. EventMesh checkstyle config requires\n\u0027separatedStaticGroups\u003dtrue\u0027 and \u0027option\u003dtop\u0027, so all static\nimports must come first, then non-static imports grouped and\nordered by [org.apache.eventmesh, org.apache, java, javax, org,\nio, net, junit, com, lombok].\n\n* fix(runtime): drop same-pkg imports, wrap long lines, blank before @Test (#5297)\n\nThree categories of checkstyle warning (maxWarnings\u003d0):\n\n  - runtime:checkstyleTest: 5 RedundantImport (tcp test files\n    importing public classes from the same package runtime.tcp).\n  - runtime:checkstyleMain: 4 LineLength \u003e150 in package-info.java\n    for cluster / delivery / http / offset (lines 166/156/167/214).\n  - arch-guard:checkstyleTest: 1 EmptyLineSeparator at\n    ArchitectureRulesTest.java:71 (missing blank line before\n    @Test method \u0027ruleRuntimeTcpInternalHidden_warn\u0027).\n\nThe RedundantImport fix is structural: tests live in\norg.apache.eventmesh.runtime.tcp and use public classes from the\nsame package (UniTcpServer, TcpAckRegistry, TcpIngressBridge,\nMeshMessagePackageRouter). These imports are unnecessary because\nsame-package references resolve without imports, and the\nRedundantImportCheck flags them. We drop them; bare-name usage\nin the test bodies is unaffected.\n\nLineLength wraps the four long package-info sentences at the\nlast whitespace before column 150 with a 4-space continuation\nindent.\n\n* fix(arch-guard): add :eventmesh-runtime testImplementation for #5297 rules\n\nThe 5 new ArchUnit rules introduced in #5297 (ruleRuntimeTcpInternalHidden,\nruleRuntimeTcpInternalNoReverse, ruleRuntimeEngineIsolatedFromInfra,\nruleRuntimePushDoesNotImportCodec, ruleRuntimeSubscriptionStateIsolated)\ntarget packages under org.apache.eventmesh.runtime.* (tcp.internal,\npush, ingress, state.internal, etc.).\n\narch-guard\u0027s test classpath only declared testImplementation\nproject(\u0027:eventmesh-common\u0027) and project(\u0027:eventmesh-spi\u0027). The\nthat()-predicates of the new rules match no classes, and ArchUnit\n1.3.0\u0027s default failOnEmptyShould\u003dtrue then throws AssertionError.\n\nAdding :eventmesh-runtime to testImplementation brings the runtime\nproduction classes onto the test classpath, so the that()-predicates\nresolve and the rules run normally."
    },
    {
      "commit": "dd7e52cbb047d8f8930c3473e1afad85a2f78f24",
      "tree": "ff60c56d5b3bdabde6afdc6a7412e211f03ce24b",
      "parents": [
        "ba267195c40317572d6c52d94b384ec358325b09"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Tue Sep 01 15:05:06 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Sep 01 15:05:06 2026 +0800"
      },
      "message": "refactor(common): partition eventmesh-common into internal sub-packages (#5298) (#5320)\n\n* refactor(common): partition eventmesh-common into internal sub-packages (#5298)\n\nPer #5298 the flat org.apache.eventmesh.common.* namespace is partitioned into\ninternal / public sub-packages. The split is enforced by a minimum-viable\n:eventmesh-architecture-guard module (issue #5305) shipped in this same PR.\n\nRenames:\n  - org.apache.eventmesh.common.utils  -\u003e org.apache.eventmesh.common.util\n  - 9 top-level common.* classes moved into lifecycle / metrics / internal / util sub-packages\n  - org.apache.eventmesh.common.EventMeshMessage @Deprecated(forRemoval\u003dtrue);\n    replaced by common.wire.EventMeshFrame (runtime) or common.protocol.tcp.EventMeshMessage (legacy TCP)\n\nNew annotations:\n  - org.apache.eventmesh.common.Public     -- source marker for public API\n  - org.apache.eventmesh.common.Internal   -- source marker for internal types\n\nNew package-info.java for every common sub-package documenting allowed\ndependencies and the modules that may import them.\n\nCleanup:\n  - Removed dead SPI: META-INF/services/...IPayload (references nonexistent\n    common.remote.* classes; would throw ServiceConfigurationError at runtime)\n\nArchitecture guard (issue #5305 minimum viable):\n  - New :eventmesh-architecture-guard module\n  - ArchUnit rules enforce: ruleInternalHidden, ruleHttpProtocolHidden,\n    ruleGrpcProtocolHidden, ruleTcpProtocolHidden, ruleOldUtilsRenamed\n  - WARN mode in 1.13.0; FAIL-on-violation from 1.14.0\n\nRefs #5298, #5305.\n\n* fix(common): post-#5298 plumbing corrections (CI feedback)\n\nTwo corrections to land before the #5298 PR can merge:\n\n1. eventmesh-common/src/main/java/org/apache/eventmesh/common/util/JsonUtils.java\n   had a stale import: it still referenced the top-level\n   org.apache.eventmesh.common.EventMeshDateFormat which this PR moved into\n   org.apache.eventmesh.common.internal. Update the import.\n\n2. eventmesh-architecture-guard/build.gradle\n   archunit-junit:1.3.0 does not exist on Maven Central -- the artifact\n   family split into archunit-junit5 (JUnit 5) and archunit-junit6 (JUnit 6)\n   after 0.23.x. This module uses JUnit 5 jupiter (org.junit.jupiter.api.Test),\n   so the dependency is com.tngtech.archunit:archunit-junit5:1.3.0.\n\nNo semantic change to either fix; both are line-level corrections discovered\nby the first CI run on PR #5320.\n\n* fix(arch-guard): use ClassFileImporter.importPaths vararg, not chained importPath\n\nClassFileImporter#importPath(String) returns JavaClasses, not a new\nClassFileImporter, so the previous chained calls\n  .importPath(\".../main\").importPath(\".../main\")\nfailed to compile:\n\n  error: cannot find symbol\n    symbol:   method importPath(String)\n    location: class JavaClasses\n\nArchUnit 1.3.0 ClassFileImporter API:\n  - importPath(String) -\u003e JavaClasses          (single, terminal)\n  - importPaths(String...) -\u003e JavaClasses      (vararg, terminal)\n  - importPaths(Collection\u003cPath\u003e) -\u003e JavaClasses\n\nReplace 15 chained importPath calls with a single importPaths(String...)\nvararg call. No semantic change; same directories imported.\n\n* fix(common): post-#5298 plumbing corrections round 4 (CI feedback)\n\nTwo more line-level corrections surfaced by the second CI run on PR #5320:\n\n1. eventmesh-sdks/eventmesh-sdk-java/src/main/java/.../EventMeshGrpcConsumer.java\n   line 26 still imported org.apache.eventmesh.common.EventMeshThreadFactory.\n   After the #5298 rename, that class lives in\n   org.apache.eventmesh.common.util.EventMeshThreadFactory. Fix the import.\n\n2. eventmesh-architecture-guard/src/test/java/.../ArchitectureRulesTest.java\n   imports com.tngtech.archunit.lang.ArchRule but the test class does not\n   declare any local ArchRule variables (it references the public static\n   fields on ArchitectureRules by name). Checkstyle\u0027s UnusedImports rule\n   (maxWarnings\u003d0) flags the import. Drop it.\n\nNo semantic change to either fix.\n\n* fix(arch-guard): checkstyle cleanups on ArchitectureRulesTest (round 5)\n\nCI round 5 feedback on the architecture-guard test class:\n\n1. Import order: org.junit.jupiter.api.Test (junit group) was placed after\n   the com.tngtech.archunit.* imports (com group). EventMesh\u0027s\n   ImportOrder groups are\n     org.apache.eventmesh, org.apache, java, javax, org, io, net, junit, com, lombok\n   so junit-group imports precede com-group imports. Reorder.\n\n2. System.out.println is forbidden by RegexpSingleline\n   (System\\..+\\.println). The WARN-mode tests use it to print\n   violation reports. Replace with SLF4J Logger.warn (org.slf4j.*)\n   consistent with other EventMesh test classes.\n\n3. Removed the now-redundant ArchitectureRulesTest\u0027s own class import:\n   it lives in the same package.\n\nThe test now compiles and passes checkstyle on a clean run.\n\n* fix(arch-guard): drop redundant same-package import in test\n\nArchitectureRulesTest.java is in package org.apache.eventmesh.architecture.guard,\nthe same package as ArchitectureRules, so the import of ArchitectureRules is\nredundant. EventMesh\u0027s checkStyle.xml enables the RedundantImport module\nwhich would fail this build.\n\nDrop the import line.\n\n* fix(arch-guard): move static import above regular imports in ArchitectureRules\n\ncheckstyle ImportOrder with option\u003dtop requires static imports to come\nBEFORE regular imports. The current order was:\n\n  import com.tngtech.archunit.core.domain.JavaClasses;        (regular)\n  import com.tngtech.archunit.core.importer.ClassFileImporter;(regular)\n  import com.tngtech.archunit.core.importer.ImportOption;     (regular)\n  import com.tngtech.archunit.lang.ArchRule;                  (regular)\n\n  import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses; (static)\n\nCI flagged this as:\n  [WARN] ArchitectureRules.java:25:1: Wrong order for\n  \u0027com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses\u0027 import. [ImportOrder]\n\nMove the static import to the top, keep regular imports below.\n\n* fix(arch-guard): import classes via classpath, not relative paths (#5298)\n\nArchitectureRulesTest failed on CI with AssertionError at every\nevaluate() line (44/50/56/62/68). ArchUnit 1.3.0\u0027s evaluate() throws\nAssertionError via failOnEmptyShould when the that()-clause matches an\nempty set -- loadProductionClasses() was importing 0 classes because\nimportPaths() used relative directories like\n\"eventmesh-common/build/classes/java/main\", and Gradle executes the task\nwith the MODULE directory (eventmesh-architecture-guard/) as working dir,\nso every relative path resolved to a non-existent location.\n\nReplace the brittle path-based import with classpath-based\nimportPackages(\"org.apache.eventmesh\"), and declare testImplementation\ndependencies on :eventmesh-common (protocol/internal/utils classes) and\n:eventmesh-spi (guaranteed outside-of-common package so that-clauses\nnever match empty).\n\n* fix(common): repair tests/imports broken by internal package moves (#5298)\n\nCI on eventmesh-common (checkstyleMain + compileTestJava):\n\n1. ThreadWrapperTest / ResetCountDownLatchTest / EventMeshThreadFactoryTest\n   live in package org.apache.eventmesh.common and referenced the moved\n   classes without an import (same-package refs). After moving\n   ThreadWrapper/ResetCountDownLatch -\u003e common.internal and\n   EventMeshThreadFactory -\u003e common.util, the same-package refs break with\n   \u0027cannot find symbol\u0027. Add explicit imports.\n\n2. JsonUtils: ImportOrder - \u0027common.exception.JsonException\u0027 must sort\n   before \u0027common.internal.EventMeshDateFormat\u0027 in the org.apache.eventmesh\n   group.\n\n3. protocol/grpc + protocol/tcp package-info: \u003cli\u003e lines exceeded 150 chars\n   (LineLength); wrap onto two lines.\n\n* fix(common): move ThreadWrapperTest into common.internal (#5298)\n\nThreadWrapperTest accessed protected members (thread, hasWakeup) of\nThreadWrapper. When ThreadWrapper moved from org.apache.eventmesh.common\nto org.apache.eventmesh.common.internal, the test (still in package\norg.apache.eventmesh.common) lost same-package access -- protected fields\nare not visible across packages even with an import.\n\nMove the test into the same package as the class under test:\n  org.apache.eventmesh.common.internal.ThreadWrapperTest\n\n* fix(common): drop same-package import of Internal in EventMeshMessage (#5298)\n\nEventMeshMessage lives in org.apache.eventmesh.common and imported\norg.apache.eventmesh.common.Internal (same package) -- checkstyle flags\nRedundantImport + UnusedImports. Remove the import.\n\n* build: exempt archunit from denied-license check (#5298)\n\n:checkDeniedLicense flagged \u0027archunit 1.3.0 licensed under BSD-4-Clause\u0027.\nArchUnit\u0027s POM declares Apache-2.0 (its actual license) plus a \"BSD\"\nentry pointing at asm.ow2.io -- the ASM license that ArchUnit only\nconsumes as a transitive bytecode library. The license plugin maps that\nentry to BSD-4-Clause and rejects it.\n\nAdd \"archunit\" to the allowedArtifacts exemption list (same mechanism\nas amqp-client/javassist/ST4/xsdlib/jsqlparser per apache/eventmesh#4842).\n\n* fix(sdk-java): fix ImportOrder for moved common.util imports (#5298)\n\nFull-module checkstyle scan surfaced two ImportOrder violations that\nindividual CI runs had not reached yet:\n\n- EventMeshGrpcConsumer: \u0027common.util.EventMeshThreadFactory\u0027 was placed\n  before \u0027common.enums.*\u0027 (enums \u003c util alphabetically).\n- TcpClient: \u0027common.util.*\u0027 was placed before \u0027common.protocol.tcp.*\u0027\n  (protocol \u003c util alphabetically).\n\nBoth were introduced while rewriting imports after the common.utils -\u003e\ncommon.util move. Reorder each group alphabetically.\n\n* fix(sdk-java): move util import below protocol group in EventMeshGrpcConsumer (#5298)\n\nImportOrder: enums \u003c protocol \u003c util. \u0027common.util.EventMeshThreadFactory\u0027\nwas still placed between the enums and protocol imports; relocate it into\nthe util group (before util.JsonUtils)."
    },
    {
      "commit": "ba267195c40317572d6c52d94b384ec358325b09",
      "tree": "fbe304f724a04125151f4406d983864593d20b60",
      "parents": [
        "7abca88aa1bc59ae718d27dc899b23f0879c9c37"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Mon Aug 31 19:29:27 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 31 19:29:27 2026 +0800"
      },
      "message": "fix(protocol): single protocol path — EventMeshFrame across HTTP ingress, filter chain and TCP egress (#5299) (#5319)\n\n* fix(protocol): route UniHttpServer ingress through FrameAdaptor SPI (#5299 Sub-PR A)\n\nThe HTTP ingress path now converts structured CloudEvents JSON bytes to\nEventMeshFrame at the boundary via FrameAdaptor SPI, so UniIngressService\nno longer imports io.cloudevents.CloudEvent on the HTTP code path.\n\nNew ingress methods (Frame-typed):\n  - publishBatchFrames(topic, List\u003cEventMeshFrame\u003e)\n  - publishLiteFrame(parent, lite, EventMeshFrame)\n  - pollLiteFrames(parent, lite, max, timeoutMs) -\u003e List\u003cEventMeshFrame\u003e\n  - requestFrame(topic, EventMeshFrame, timeout) -\u003e EventMeshFrame\n  - replyFrame(correlationId, EventMeshFrame)\n\nThe CloudEvent-typed overloads are preserved for binary compatibility\nwith the TCP bridge. Sub-PR B will migrate FilterChain; Sub-PR C will\nmigrate the TCP path.\n\nCloses part of #5299.\n\n* fix(protocol): migrate ingress filter chain to EventMeshFrame (#5299 Sub-PR B)\n\nThe ingress security pipeline (§4.5) — TokenAuthFilter / AclFilter /\nSignatureVerifierFilter / FilterChain — now operates on the runtime\u0027s\ninternal wire format (org.apache.eventmesh.common.wire.EventMeshFrame)\ninstead of io.cloudevents.CloudEvent. This continues the #5299 single-\nprotocol-path migration: sub-PR A routed the HTTP ingress through the\nFrameAdaptor SPI; sub-PR B extends the same boundary inward to the\nfilter chain so that auth/acl/signature now read directly from\nframe.attributes().\n\nChanges:\n- IngressFilter: new check(EventMeshFrame, FilterContext) primary\n  method; the CloudEvent overload is now a default that bridges via\n  EventMeshFrame.fromCloudEvent(...) for backward compat.\n- FilterChain: new check(EventMeshFrame, FilterContext) overload;\n  CloudEvent variant is deprecated and bridges via fromCloudEvent.\n- AclFilter: implement check(EventMeshFrame, ...) — also rejects\n  non-EVENT frames (e.g. STREAM_REQ / STREAM_CHUNK) since the\n  ingress security pipeline is event-shaped only.\n- TokenAuthFilter: implement check(EventMeshFrame, ...) — credential\n  still comes from FilterContext (HTTP Authorization header), so\n  the frame body is unused for this stage.\n- SignatureVerifierFilter: implement check(EventMeshFrame, ...) —\n  signature travels in frame.attributes() under the same key\n  (emsignature) the legacy CloudEvent extension used, so signed\n  CloudEvents round-trip transparently through the cloudevents\n  FrameAdaptor.\n- UniHttpServer: drop the temporary frame.toCloudEvent() bridge in\n  the publish() filter call; thread tenant directly from\n  frame.attributes(). Also drop the synthetic CloudEvent stub used\n  for pre-publish security check — replaced with a minimal\n  EventMeshFrame.event(emptyMap, []).\n- New test class: EventMeshFrameFilterTest (6 tests) exercising\n  the EventMeshFrame-typed path parallel to the existing\n  SecurityFilterTest which still covers the CloudEvent bridge.\n\nBackward compat: existing custom filters implementing\nIngressFilter.check(CloudEvent, ...) keep working because the\ninterface now provides a default implementation. They will compile\nunchanged and continue to be invoked via the deprecated chain\noverload until sub-PR C migrates the TCP path and we can drop the\nbridge entirely.\n\nRefs #5299.\n\n* fix(protocol): complete #5299 single protocol path (sub-PR B fix + C + D)\n\nSub-PR B fix:\n - restore the missing io.cloudevents.CloudEvent import in IngressFilter (broke compileJava)\n - move EventMeshFrame into the correct checkstyle ImportOrder group\n   (style/checkStyle.xml puts org.apache.eventmesh first; maxWarnings\u003d0 so it fails CI)\n - update SecurityFilterTest for the frame-based SignatureVerifierFilter.canonical(...)\n\nSub-PR C: migrate the TCP egress path to EventMeshFrame\n - TcpFrameCodec.encodePush / TcpPushChannel.deliver now take an EventMeshFrame directly,\n   dropping the frame -\u003e CloudEvent -\u003e wire round trip\n - delete the dead CloudEvent-era egress SPI: CloudEventToPackageBody, MeshEventToPackageBody\n - UniTcpServer drops the now-unused bodyMapper constructor parameter\n - TCP ingress was already frame-native (MeshMessagePackageRouter / TcpRequest / NettyTcpPushChannel)\n\nSub-PR D: document the #5299 acceptance matrix and protocol status labels\n (docs/eventmesh-uni-architecture-redesign.md section 19.6)\n\nRefs #5299."
    },
    {
      "commit": "7abca88aa1bc59ae718d27dc899b23f0879c9c37",
      "tree": "2a36279b49b4a8ff08f461ebbc83629b8139eb51",
      "parents": [
        "e2792613cff99c344440770a40eb455fea7b27ef"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Mon Aug 31 12:05:36 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 31 12:05:36 2026 +0800"
      },
      "message": "test(state): cross-store fault-injection E2E for the unified state control plane (issue #5314) (#5318)\n\n* test(state): add cross-store fault-injection harness (issue #5314)\n\nFour in-process primitives shared by the six #5314 scenarios:\n\n  MetaPartitionSwitch      - MetaStore wrapper; open()/close() simulates a network\n                             partition (mutating ops throw MetaPartitionException,\n                             reads continue against the pre-partition snapshot).\n  CrossStoreRaceProbe      - ordered log of cross-store operations (DELIVERY_PUT/\n                             REMOVE, OFFSET_WRITE/READ, TASK_UPDATE) with a monotonic\n                             seq so a test can assert happens-before relationships.\n  JvmCrashHarness          - child JVM + sentinel-file-driven destroyForcibly()\n                             (SIGKILL / TerminateProcess), then relaunch against the\n                             same on-disk stores. Gated on ENABLE_JVM_CRASH_HARNESS.\n  InMemorySubscriptionStore- ConcurrentHashMap-backed SubscriptionStore for the\n                             split-brain scenario (two views of the world).\n\nAll four are test-only and run fully in-process: no Nacos, no Docker, no\nTestcontainers. See §13.2.12 of the architecture doc (added in a follow-up commit).\n\n* test(state): add cross-store fault-injection 6-scenario test (issue #5314)\n\nCrossStoreFaultInjectionTest covers the fault modes that span two or more\nstores (or the runtime + cluster-shared Meta). The individual store contract\ntests (#5310/#5311/#5312/#5313) cannot observe these, because the invariant\nlives at the seam:\n\n  1. CrashMidAckReAck  - crash after offset-write, before MQ-ACK callback;\n                        recovery retires without re-invoking the channel\n                        (issue #5291 idempotency).\n  2. MetaPartitionDuringDlq - Meta unreachable while dead-letter recording;\n                        the store throws MetaPartitionException rather than\n                        silently no-op\u0027ing, so the dispatcher keeps the\n                        delivery in flight and retries on heal (#5292).\n  3. A2aCancelMidStream - cancel lands between PENDING and RUNNING; the\n                        taskEpoch guard rejects stale-epoch late transitions\n                        and the task converges on one terminal state (#5302).\n  4. SubscriptionReRegisterAfterSplit - update during a Meta partition; after\n                        heal the latest write wins, nothing dropped or\n                        duplicated (#5288, #5301 SubscriptionStore).\n  5. OffsetStoreRaceVsDeliveryStore - cross-thread offset-advance vs retire\n                        race; the probe log proves every DELIVERY_REMOVE is\n                        preceded by an OFFSET_WRITE at the same offset\n                        (#5289 at-least-once).\n  6. A2aDispatchRaceVsTaskStore - two dispatchers race on one task record;\n                        stale-epoch writes are rejected and createTask yields\n                        exactly one winner (#5291).\n\nEvery scenario runs in-process and deterministically. The JvmCrashHarness\nfrom the previous commit remains the optional cross-JVM verification path.\n\nNote on the taskEpoch contract exercised by scenarios 3 and 6: the epoch is set\nat createTask and never reset, so updateStatus rejects any epoch that differs\nfrom the record\u0027s. Same-epoch writes are last-writer-wins by design - the\nRuntime dispatcher is the sole writer and the epoch guards against a restarted\ninstance\u0027s stale handle, not against intra-JVM ordering.\n\n* docs(architecture): add §13.2.12 cross-store fault-injection (issue #5314)\n\nDocuments the 6-scenario CrossStoreFaultInjectionTest: why single-store contract\ntests cannot cover cross-store invariants, the four harness primitives, the\nper-scenario assertion table, why Testcontainers is not used, and the two\nextension points (RocksDB-backed crash scenario, MetaBackedOffsetStore going\nactive).\n\nNumbered 13.2.12 because §13.2.11 was taken by the dual-topology matrix in\nPR #5317."
    },
    {
      "commit": "e2792613cff99c344440770a40eb455fea7b27ef",
      "tree": "66a8e296dcaddb074122bf352af718c8aca273a1",
      "parents": [
        "6ec99215ca3847404ec7bf15d94f78152f2b3c60"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Mon Aug 31 10:24:00 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Aug 31 10:24:00 2026 +0800"
      },
      "message": "feat(cluster): PARTITION_OWNED_PULL delivery topology (issue #5309, closes) (#5317)\n\n* feat(a2a): wire A2A Gateway onto Runtime via TaskStore (issue #5302 Sub-PR D1)\n\nBrings the A2A Gateway back into the Runtime, this time with the unified\ncontrol-plane stores from #5301 Sub-PR A/C as the durable backend instead\nof the in-memory TaskRegistry that PR #5260 introduced.\n\nWhat lands\n----------\n* A2AGatewayService — task lifecycle controller. Replaces the in-memory\n  TaskRegistry with TaskStore (Sub-PR A/C). A small runtime cache holds\n  the two fields TaskStore does not model: parentTaskId (used to render\n  child-task queries) and taskEpoch (the per-task counter the store\n  requires for stale-write rejection on updateStatus). Both caches are\n  rebuildable from the store on a fresh JVM; the cache keys are\n  taskIds, so the cache size tracks active tasks only.\n* A2AGatewayHttpHandler — Netty HTTP handler for the REST + SSE API\n  (/a2a/tasks, /a2a/tasks/{id}, /a2a/tasks/{id}/stream, /a2a/health).\n  SSE registers a StatusSubscriber so intermediate PENDING -\u003e RUNNING -\u003e\n  COMPLETED transitions stream to the client.\n* A2AGatewayServer — Netty HTTP bootstrap. Production wires\n  EventMeshA2ATransport (Runtime-bridged) for the A2AMessageTransport\n  dependency; tests pass an in-process transport. The weather-agent\n  demo from PR #5260 is removed — the demo client (A2AGatewayDemo) and\n  the Meta-ized AgentCard registry land in Sub-PR D2.\n* AgentCardRegistry + InMemoryAgentCardRegistry — minimal discovery\n  surface (isAgentRegistered / registerCard / getCard). A Meta-backed\n  implementation backed by SessionStore (Sub-PR A) lands in D2.\n\nStatus mapping (PR #5260 -\u003e Sub-PR A/C)\n---------------------------------------\n  SUBMITTED -\u003e PENDING, WORKING -\u003e RUNNING, CANCELLED -\u003e CANCELED (one L)\nThe legacy wire vocabulary stays available via A2AGatewayService.TaskState\nand the toLegacyState() helper. JSON response payloads still emit\nSUBMITTED/WORKING/CANCELLED so existing A2A clients do not break.\n\nDocumentation\n-------------\n* docs/a2a-protocol/README.md carries an EXPERIMENTAL banner that lists\n  the three pieces still missing for production (TaskExpirer, Meta-ized\n  AgentCard, Testcontainers E2E) — all scheduled for Sub-PR D2.\n\nAcceptance against issue #5302\n------------------------------\n* \"A2A transport over the Runtime delivery path\" — A2AGatewayService\n  takes an A2AMessageTransport; production wires EventMeshA2ATransport\n  which already bridges A2A onto UniIngressService (issue #5301 Sub-PR\n  A\u0027s runtime ingress). The parallel InMemoryA2AMessageTransport is no\n  longer required by the gateway path.\n* \"A2A tasks persist through TaskStore and recover across restarts\" —\n  createTask / updateStatus / getTask all go through the persistent\n  store. On a fresh JVM, a gateway that had pending tasks sees them\n  with their last persisted status; in-flight work that was awaiting\n  a response will be picked up on the next status callback.\n\nTests (7, all passing)\n----------------------\n* A2AGatewayServiceTest — 6 tests: create+complete, cancel, cancel-on-\n  unknown, submit-to-unregistered, parent-child index, task-not-found.\n  Uses an in-process TaskStore (mirrors Sub-PR A\u0027s test stub) and an\n  in-process A2AMessageTransport that handles A2A\u0027s + single-segment\n  wildcards.\n* A2AGatewaySmokeTest — Netty HTTP /a2a/health loopback check.\n\nNot in D1 (Sub-PR D2)\n---------------------\n* TaskExpirer reaper (periodic TaskStore.expireStale sweep).\n* Meta-backed AgentCardRegistry (SessionStore).\n* Testcontainers fault-injection E2E.\n\n* fix(a2a): address checkstyle violations in A2A Gateway D1 (PR #5313)\n\nA2AGatewayHttpHandler.java:\n- Remove unused imports (A2AProtocolConstants, A2ATopicFactory, TaskState)\n- Expand try-catch blocks for limit/offset parsing (EmptyCatchBlock, NeedBraces)\n- Expand handleList loop control flow (NeedBraces)\n- Collapse duplicate blank line between package and imports (EmptyLineSeparator)\n\nA2AGatewayServiceTest.java:\n- Expand single-line if-blocks in InProcessTaskStore.listByAgent\n- Expand if-block in InProcessTransport.matches\n- Expand if-blocks in tearDown\n- Move taskId declaration closer to its use (VariableDeclarationUsageDistance)\n\nA2AGatewaySmokeTest.java:\n- Rewrite StubTaskStore / NoopTransport with multi-line method bodies\n  (LeftCurly, RightCurlyAlone, NeedBraces, EmptyLineSeparator)\n- Add missing static imports (assertEquals, assertNotNull)\n\nBuild PR #5313 fix.\n\n* fix(a2a): test imports + variable usage distance (PR #5313 followup)\n\nA2AGatewayServiceTest.java:\n- Fix ImportOrder: AgentCapabilities before AgentCard (alphabetical)\n- Fix VariableDeclarationUsageDistance for f: inline taskId into\n  submitTask call so the declaration is closer to first use\n\nA2AGatewaySmokeTest.java:\n- Fix ImportOrder: static Assertions imports before non-static\n  TaskStore import\n\nBuild PR #5313 followup.\n\n* fix(a2a): correct cancelMarksTaskCanceled test body (PR #5313 followup)\n\nThe previous fixup broke the test logic by calling TaskResult.getTaskId()\nwhich does not exist. Restore the original taskId declaration pattern\nwhile keeping the f declaration within 3 lines of its first use:\n\n- Declare taskId first\n- Declare f immediately after\n- Inline cancelTask result into the assertTrue (no intermediate boolean)\n- Move f.get() call right after the cancel assertion so f\u0027s first use\n  is within 3 lines of its declaration\n\nBuild PR #5313 followup.\n\n* feat(cluster): add DeliveryTopology enum + fail-fast parser (issue #5309)\n\nSub-step 2 of #5309: PARTITION_OWNED_PULL delivery topology.\n\nAdds DeliveryTopology enum with two modes:/n- LOCAL_STICKY_PULL (default): every instance polls all partitions\n- PARTITION_OWNED_PULL: CAS+fencing ownership per partition (scale-out)\n\nfromConfig() parses eventmesh.delivery.topology property:/n- null/blank -\u003e LOCAL_STICKY_PULL (backward compatible)\n- unknown -\u003e IllegalArgumentException (fail-fast)\n\n* feat(cluster): wire PARTITION_OWNED_PULL topology into UniRuntime (#5309 sub-step 3)\n\nBoots PartitionOwnership state machine when topology\u003dPARTITION_OWNED_PULL:/n- New 9-arg constructor with DeliveryTopology, instanceId, instanceAddress\n- start() calls startPartitionOwnership() after offset alignment\n- startPartitionOwnership(): ClusterMembership + PartitionOwnership + InMemoryMetaStore\n- shutdown() calls stopPartitionOwnership() before pull-loop shutdown\n- Backward-compatible 6-arg constructor defaults to LOCAL_STICKY_PULL\n\n* test(cluster): PARTITION_OWNED_PULL wiring E2E + DeliveryTopology parser tests (#5309 sub-step 4)\n\nUniRuntimeTopologyWiringTest boots real UniRuntime instances (full start()/shutdown()\nlifecycle, real scheduler) against a shared InMemoryMetaStore:/n- two PARTITION_OWNED_PULL instances converge on a disjoint, full-coverage split\n- LOCAL_STICKY_PULL default (6-arg ctor) never assigns partitions (poll-all)\n- null topology fails fast in the constructor\n\nDeliveryTopologyTest covers the fromConfig parser: null/blank -\u003e default, exact names,\nwhitespace trim, unknown/lowercase -\u003e IllegalArgumentException.\n\nComplements ClusterDeliveryFaultTest (deterministic refreshOnce fault injection without a\nruntime). A full Testcontainers Kafka+Nacos E2E is tracked as a follow-up.\n\n* docs(uni-arch): add DeliveryTopology dual-topology matrix to §13.2.10 (issue #5309 sub-step 5)\n\nUpdates the §13.2 status banner (blocker closed) and adds §13.2.10 documenting the\ntwo legitimate topologies:\n- LOCAL_STICKY_PULL: default, single-instance, no Meta dependency (backward compatible)\n- PARTITION_OWNED_PULL: scale-out, requires Meta CAS + fencing (production HA)\n\nIncludes selection semantics (fromConfig), startup flow (UniRuntime.start partition\nownership), diff vs the §13.2.8 original design, and verification coverage\n(unit + E2E wiring + fault injection; Testcontainers deferred as a follow-up).\n\n* fix(docs): rename dual-topology section to §13.2.11 (avoid duplicate 13.2.10 with #5293 entry)"
    },
    {
      "commit": "6ec99215ca3847404ec7bf15d94f78152f2b3c60",
      "tree": "55230dccd1d1a752beef26dd7b6fa7c869504302",
      "parents": [
        "ef0fb185714758ab852cc45ffa164bf38b3f053d"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Fri Aug 28 16:13:19 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Aug 28 16:13:19 2026 +0800"
      },
      "message": "feat(a2a): wire A2A Gateway onto Runtime via TaskStore (issue #5302 Sub-PR D1) (#5313)\n\n* feat(a2a): wire A2A Gateway onto Runtime via TaskStore (issue #5302 Sub-PR D1)\n\nBrings the A2A Gateway back into the Runtime, this time with the unified\ncontrol-plane stores from #5301 Sub-PR A/C as the durable backend instead\nof the in-memory TaskRegistry that PR #5260 introduced.\n\nWhat lands\n----------\n* A2AGatewayService — task lifecycle controller. Replaces the in-memory\n  TaskRegistry with TaskStore (Sub-PR A/C). A small runtime cache holds\n  the two fields TaskStore does not model: parentTaskId (used to render\n  child-task queries) and taskEpoch (the per-task counter the store\n  requires for stale-write rejection on updateStatus). Both caches are\n  rebuildable from the store on a fresh JVM; the cache keys are\n  taskIds, so the cache size tracks active tasks only.\n* A2AGatewayHttpHandler — Netty HTTP handler for the REST + SSE API\n  (/a2a/tasks, /a2a/tasks/{id}, /a2a/tasks/{id}/stream, /a2a/health).\n  SSE registers a StatusSubscriber so intermediate PENDING -\u003e RUNNING -\u003e\n  COMPLETED transitions stream to the client.\n* A2AGatewayServer — Netty HTTP bootstrap. Production wires\n  EventMeshA2ATransport (Runtime-bridged) for the A2AMessageTransport\n  dependency; tests pass an in-process transport. The weather-agent\n  demo from PR #5260 is removed — the demo client (A2AGatewayDemo) and\n  the Meta-ized AgentCard registry land in Sub-PR D2.\n* AgentCardRegistry + InMemoryAgentCardRegistry — minimal discovery\n  surface (isAgentRegistered / registerCard / getCard). A Meta-backed\n  implementation backed by SessionStore (Sub-PR A) lands in D2.\n\nStatus mapping (PR #5260 -\u003e Sub-PR A/C)\n---------------------------------------\n  SUBMITTED -\u003e PENDING, WORKING -\u003e RUNNING, CANCELLED -\u003e CANCELED (one L)\nThe legacy wire vocabulary stays available via A2AGatewayService.TaskState\nand the toLegacyState() helper. JSON response payloads still emit\nSUBMITTED/WORKING/CANCELLED so existing A2A clients do not break.\n\nDocumentation\n-------------\n* docs/a2a-protocol/README.md carries an EXPERIMENTAL banner that lists\n  the three pieces still missing for production (TaskExpirer, Meta-ized\n  AgentCard, Testcontainers E2E) — all scheduled for Sub-PR D2.\n\nAcceptance against issue #5302\n------------------------------\n* \"A2A transport over the Runtime delivery path\" — A2AGatewayService\n  takes an A2AMessageTransport; production wires EventMeshA2ATransport\n  which already bridges A2A onto UniIngressService (issue #5301 Sub-PR\n  A\u0027s runtime ingress). The parallel InMemoryA2AMessageTransport is no\n  longer required by the gateway path.\n* \"A2A tasks persist through TaskStore and recover across restarts\" —\n  createTask / updateStatus / getTask all go through the persistent\n  store. On a fresh JVM, a gateway that had pending tasks sees them\n  with their last persisted status; in-flight work that was awaiting\n  a response will be picked up on the next status callback.\n\nTests (7, all passing)\n----------------------\n* A2AGatewayServiceTest — 6 tests: create+complete, cancel, cancel-on-\n  unknown, submit-to-unregistered, parent-child index, task-not-found.\n  Uses an in-process TaskStore (mirrors Sub-PR A\u0027s test stub) and an\n  in-process A2AMessageTransport that handles A2A\u0027s + single-segment\n  wildcards.\n* A2AGatewaySmokeTest — Netty HTTP /a2a/health loopback check.\n\nNot in D1 (Sub-PR D2)\n---------------------\n* TaskExpirer reaper (periodic TaskStore.expireStale sweep).\n* Meta-backed AgentCardRegistry (SessionStore).\n* Testcontainers fault-injection E2E.\n\n* fix(a2a): address checkstyle violations in A2A Gateway D1 (PR #5313)\n\nA2AGatewayHttpHandler.java:\n- Remove unused imports (A2AProtocolConstants, A2ATopicFactory, TaskState)\n- Expand try-catch blocks for limit/offset parsing (EmptyCatchBlock, NeedBraces)\n- Expand handleList loop control flow (NeedBraces)\n- Collapse duplicate blank line between package and imports (EmptyLineSeparator)\n\nA2AGatewayServiceTest.java:\n- Expand single-line if-blocks in InProcessTaskStore.listByAgent\n- Expand if-block in InProcessTransport.matches\n- Expand if-blocks in tearDown\n- Move taskId declaration closer to its use (VariableDeclarationUsageDistance)\n\nA2AGatewaySmokeTest.java:\n- Rewrite StubTaskStore / NoopTransport with multi-line method bodies\n  (LeftCurly, RightCurlyAlone, NeedBraces, EmptyLineSeparator)\n- Add missing static imports (assertEquals, assertNotNull)\n\nBuild PR #5313 fix.\n\n* fix(a2a): test imports + variable usage distance (PR #5313 followup)\n\nA2AGatewayServiceTest.java:\n- Fix ImportOrder: AgentCapabilities before AgentCard (alphabetical)\n- Fix VariableDeclarationUsageDistance for f: inline taskId into\n  submitTask call so the declaration is closer to first use\n\nA2AGatewaySmokeTest.java:\n- Fix ImportOrder: static Assertions imports before non-static\n  TaskStore import\n\nBuild PR #5313 followup.\n\n* fix(a2a): correct cancelMarksTaskCanceled test body (PR #5313 followup)\n\nThe previous fixup broke the test logic by calling TaskResult.getTaskId()\nwhich does not exist. Restore the original taskId declaration pattern\nwhile keeping the f declaration within 3 lines of its first use:\n\n- Declare taskId first\n- Declare f immediately after\n- Inline cancelTask result into the assertTrue (no intermediate boolean)\n- Move f.get() call right after the cancel assertion so f\u0027s first use\n  is within 3 lines of its declaration\n\nBuild PR #5313 followup."
    },
    {
      "commit": "ef0fb185714758ab852cc45ffa164bf38b3f053d",
      "tree": "6d832fcd7416a1332fe32f0aec9ff0bda9ae2433",
      "parents": [
        "b99c1671c2f10db81791b80261ab32cd7815c509"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Fri Aug 28 14:27:08 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Aug 28 14:27:08 2026 +0800"
      },
      "message": "feat(state): DeadLetterStore + TaskStore Meta backends (issue #5301 Sub-PR C, fixes #5292 fully, unblocks #5302) (#5312)\n\n* feat(state): DeadLetterStore + TaskStore Meta backends (issue #5301 Sub-PR C, fixes #5292 fully, unblocks #5302)\n\nTwo production implementations on top of the Sub-PR A interfaces:\n\n- MetaBackedDeadLetterStore: idempotent ledger under /em/dlq/\u003cdeliveryId\u003e via\n  MetaStore.putIfAbsent CAS; first recorder wins, subsequent writers are no-ops\n  that still return true so the dispatcher proceeds to retire.\n- MetaBackedTaskStore: per-task record under /em/tasks/\u003ctaskId\u003e with a self-describing\n  v1|\u003cbase64\u003e wire envelope (all variable-width fields base64-encoded so opaque caller\n  input containing \u0027|\u0027 or newlines cannot corrupt the format). Status updates use\n  MetaStore.tryAcquire as an epoch CAS, rejecting stale writers (issue #5291 style).\n\nReliableDispatcher 9-arg ctor: same as 8-arg + a DeadLetterStore that is invoked on\nevery confirmed DLQ transition. The 8-arg ctor (legacy Sub-PR A/B) is untouched and\nthe DLQ path skips the ledger call when no store is wired. Backward compatible.\n\nTests: MetaBackedDeadLetterStoreTest, MetaBackedTaskStoreTest, ReliableDispatcherDlqLedgerTest.\nInterface contract tests DeadLetterStoreTest and TaskStoreTest (Sub-PR A) are unchanged\nand continue to pass against the new production implementations.\n\nScope: fixes #5292 fully; unblocks #5302. A2A dispatch mode (#5302) and the\nTaskExpirer reaper are follow-up scope in Sub-PR D (issue #5297).\n\n* fix(state): allow deadLetterStore to be re-assigned in 9-arg ctor chain (issue #5301 Sub-PR C)\n\nThe 8-arg ctor assigns `deadLetterStore \u003d null` and the 9-arg ctor chains to the 8-arg\nctor and then reassigns with the supplied ledger; this hit\n`variable deadLetterStore might already have been assigned` because the field was\n`final`. Drop `final` (with a Javadoc note that it is effectively final after\nconstruction) so the chain compiles. No runtime semantics change.\n\n* fix(state): fix imports + long line + test fully-qualified refs (Sub-PR C, issue #5301)\n\n- ReliableDispatcher.java (CRLF): import order (DeadLetterStore before DeliveryStateStore),\n  drop the duplicate DeliveryStateStore import, split the 274-char log.warn into\n  three concatenated string fragments to satisfy LineLength \u003c\u003d 150.\n- ReliableDispatcherDlqLedgerTest.java (LF): import AckCallback / DeadLetterSink / PushChannel\n  from `org.apache.eventmesh.runtime.delivery` (not `connector` / `push`); drop the\n  fully-qualified `org.apache.eventmesh.runtime.push.AckCallback` in the FakeChannel\n  override (now imports correctly).\n\nAll three compile errors and the three checkstyle violations from run 33057816390 are\naddressed. No semantic change.\n\n* fix(state): test checkstyle cleanups (Sub-PR C, issue #5301)\n\n- MetaBackedDeadLetterStoreTest: drop unused MetaStore import (only InMemoryMetaStore is used).\n- MetaBackedTaskStoreTest: rename local `bView` -\u003e `bViewTwo` to satisfy LocalVariableName\n  (lowercase-first camelCase pattern).\n- ReliableDispatcherDlqLedgerTest: drop three same-package `org.apache.eventmesh.runtime.delivery.*`\n  imports (the test lives in that package), and move `org.junit.jupiter.api.Test` to the top\n  import block (it was below `io.*` and broke ImportOrder).\n\nAll six checkstyle violations from run 33062276583 addressed; no semantic change.\n\n* fix(state): second pass at test checkstyle (Sub-PR C, issue #5301)\n\n- MetaBackedTaskStoreTest: rename local `bViewTwo` -\u003e `taskB`. The checkstyle\n  LocalVariableName regex is `^[a-z]([a-z0-9][a-zA-Z0-9]*)?$` -- the second char\n  must be lowercase or digit, so `bViewTwo` (b + V) and `bView` (b + V) both fail.\n  `taskB` is the clean alternative.\n- ReliableDispatcherDlqLedgerTest: import order was wrong. ASCII order requires\n  `org.apache.*` (a) before `org.junit.*` (j) before `java.*` (a again, but `j`\n  group sorts before `java`). The previous amendment placed `org.junit` ABOVE\n  `org.apache.eventmesh.*`, which violates ImportOrder.\n\n* fix(state): reorder test imports for Apache checkstyle ImportOrder (#5301 Sub-PR C)\n\nApache checkstyle\u0027s ImportOrder rule uses a configured group order\n(org.apache.eventmesh | org.apache | java | javax | org | io | net |\njunit | com | lombok), not strict ASCII order. \u0027java.*\u0027 is group 4, so\nit must appear AFTER \u0027org.apache.*\u0027 (group 3) and BEFORE \u0027org.junit.*\u0027\n(group 9). The previous amendment put \u0027org.junit.*\u0027 before \u0027java.*\u0027,\ntripping checkstyleTest with \u0027Wrong order for java.net.URI import\u0027.\n\nMove all \u0027org.junit.*\u0027 imports to the LAST non-static group, after any\n\u0027java.*\u0027 or \u0027io.*\u0027 imports, in:\n  - ReliableDispatcherDlqLedgerTest\n  - MetaBackedTaskStoreTest\n  - MetaBackedDeadLetterStoreTest (no java imports; ordering unchanged)\n\n* fix(state): reorder test imports for Apache checkstyle ImportOrder (#5301 Sub-PR C)\n\nApache checkstyle\u0027s ImportOrder rule uses a configured group order\n(org.apache.eventmesh | org.apache | java | javax | org | io | net |\njunit | com | lombok), not strict ASCII order. \u0027java.*\u0027 is group 4, so\nit must appear AFTER \u0027org.apache.*\u0027 (group 3) and BEFORE \u0027org.junit.*\u0027\n(group 9). The previous amendment put \u0027org.junit.*\u0027 before \u0027java.*\u0027,\ntripping checkstyleTest with \u0027Wrong order for java.net.URI import\u0027.\n\nMove all \u0027org.junit.*\u0027 imports to the LAST non-static group, after any\n\u0027java.*\u0027 or \u0027io.*\u0027 imports, in:\n  - ReliableDispatcherDlqLedgerTest\n  - MetaBackedTaskStoreTest\n  - MetaBackedDeadLetterStoreTest (no java imports; ordering unchanged)\n\n* fix(state): put org.junit.* before io.* in test imports (Sub-PR C)\n\nApache checkstyle\u0027s ImportOrder rule uses a *first-match* prefix\nalgorithm against the `groups` config. `org.junit.*` matches the\n`org` prefix (index 4) before the `junit` prefix (index 7), so\norg.junit imports belong to the `org` group, NOT the `junit` group.\nRequired order: org(4) -\u003e io(5). Previous fix had io(5) before\norg.junit(4), tripping checkstyleTest with \u0027Wrong order for\norg.junit.jupiter.api.Test\u0027 on line 42.\n\nReorder imports in ReliableDispatcherDlqLedgerTest.java to match\nthe pattern used by UniAdminServerTest.java (which passes):\n  static\n  org.apache.eventmesh.*\n  java.*\n  org.junit.*      (org group, index 4)\n  io.*             (io group, index 5)\n\n* fix(state): correct test logic for DLQ exhaustion + stale expiry (Sub-PR C)\n\nTwo Sub-PR C tests had runtime logic bugs that compile/checkstyle did not\ncatch:\n\n1. ReliableDispatcherDlqLedgerTest (both tests). The original test loop\n   used MAX_ATTEMPTS\u003d2 iterations of (nack, clock+\u003d1s, tick) which is one\n   iteration short: nack moves the next-attempt deadline into the future\n   (clock + backoff(1) \u003d 1s) but the clock only advances 1s per tick,\n   so the second tick sees the delivery as not yet expired and skips it.\n   The test never reaches the DLQ branch (attempt \u003e\u003d maxAttempts).\n\n   Switch to timeout-driven exhaustion (matching\n   ReliableDispatcherTest.exhaustedRetriesGoToDLQ): bump MAX_ATTEMPTS to 3\n   and run 3 ticks each preceded by clock.addAndGet(ACK_TIMEOUT), so\n   attempt 1 -\u003e 2 -\u003e 3 -\u003e DLQ. The first nack is no longer needed.\n\n2. MetaBackedTaskStoreTest.expireStaleRemovesOldRecords. The test calls\n   expireStale(1L) immediately after updateStatus; both records are \u003e1ms\n   old by then, so both end up in the expired list and the size\u003d\u003d1\n   assertion fails.\n\n   Add a 3ms sleep between the last updateStatus and expireStale so the\n   just-updated \u0027new\u0027 record\u0027s updatedAtMs is within 1ms of \u0027now\u0027 and\n   survives, while \u0027old\u0027 (created several ms earlier) is removed.\n\nThese are test-only changes; production code (MetaBackedTaskStore,\nReliableDispatcher, MetaBackedDeadLetterStore) is unchanged.\n\n* fix(state): declare InterruptedException in expireStale test (Sub-PR C)\n\nThread.sleep(3L) inside expireStaleRemovesOldRecords throws\nInterruptedException; the test method must declare `throws Exception`\n(or wrap the call in try/catch) for the test source to compile.\n\n* fix(state): assert sink receives source topic, not source_DLQ (Sub-PR C)\n\nIn ReliableDispatcher.tick, the dlqSink is invoked with rec.topic\n(the SOURCE topic, e.g. \u0027orders\u0027). The \u0027_DLQ\u0027 suffix is only\napplied when recording on the durable ledger via\ndeadLetterStore.recordDeadLetter. The previous assertion\nchannel.dlqTopics.contains(\"orders_DLQ\") is therefore wrong;\nthe sink sees the source topic unchanged.\n\nUpdate the assertion to check for \"orders\" (the source topic),\nwith a comment explaining the source-vs-ledger distinction so the\nnext reader doesn\u0027t trip on the same misunderstanding.\n\n* fix(state): bump expireStale test sleep from 3ms to 50ms (Sub-PR C)\n\nThe previous 3ms sleep worked locally but was too tight for CI\nscheduler noise: on a busy host the 1ms window can collapse, so\nboth \u0027old\u0027 and \u0027new\u0027 records end up older than 1ms by the time\nexpireStale(1L) is called.\n\nBump the sleep to 50ms (still fast at \u003c 100ms total per test)\nso the just-updated \u0027new\u0027 record\u0027s updatedAtMs is well within 1ms\nof \u0027now\u0027 (it survives), while \u0027old\u0027 (created ~50ms earlier) is\nremoved. The assertion logic is unchanged.\n\n* fix(state): move updateStatus after sleep in expireStale test (Sub-PR C)\n\nThe previous test (and two follow-up attempts) updated \u0027new\u0027\nBEFORE the sleep, so by the time expireStale(1L) ran both\nrecords were \u003e1ms old and both got removed (expired.size() \u003d\u003d 2).\n\nCorrect order:\n  1. createTask(\u0027old\u0027)\n  2. createTask(\u0027new\u0027)\n  3. Thread.sleep -- makes \u0027old\u0027 stale\n  4. updateStatus(\u0027new\u0027) -- refreshes \u0027new\u0027 to current time\n  5. expireStale(1L) -- removes only \u0027old\u0027 (now \u003e1ms old)\n\nBump sleep to 30ms (was 50ms) -- still well under 100ms test budget,\nand \u003e1ms so \u0027old\u0027 is reliably stale even on a busy CI host."
    },
    {
      "commit": "b99c1671c2f10db81791b80261ab32cd7815c509",
      "tree": "bca25bcfdf3d3521e2d19de92cebf272357f8e9e",
      "parents": [
        "187bb922fc1a7e53e9bc8b6f64c90f6e2dc14a49"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Thu Aug 27 16:49:38 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 27 16:49:38 2026 +0800"
      },
      "message": "fix(state): persist ReliableDispatcher.pending to DeliveryStateStore (issue #5301 Sub-PR B, fixes #5294 #5295) (#5311)\n\n* fix(state): persist ReliableDispatcher.pending to DeliveryStateStore (issue #5301 Sub-PR B, fixes #5294 #5295)\n\nMakes in-flight delivery state survive a hard JVM restart: every delivery is now\npersisted to a DeliveryStateStore on deliver/ack/nack/tick, and on startup the\ndispatcher\u0027s recover() re-ACKs each persisted record against the OffsetStore so\nno client is left without a progress advance and no delivery becomes an orphan.\n\n* new DeliveryStateStore interface in ...runtime.state:\n  - put/remove/get/iterate/count/flush/close\n  - Record carries (deliveryId, topic, partition, offset, clientId, attempt,\n    nextAttemptAtMs, encodedEvent) - channel and mqAckCallback are runtime\n    references that do NOT survive restart\n  - toDelivery() rebuilds a live Delivery for tick/iterate use\n* InMemoryDeliveryStateStore (test contract baseline)\n* RocksDBDeliveryStateStore (production; key\u003ddeliveryId, value\u003dASCII line with\n  base64-wrapped event bytes; mirrors RocksDBOffsetStore\u0027s pattern)\n* ReliableDispatcher now depends on a DeliveryStateStore (constructor parameter,\n  default InMemory). The previous in-memory ConcurrentHashMap is gone; tick()\n  iterates the store, ack() removes via the store, deliver() persists via the\n  store.\n* New recover(): on startup, walk the store, write the stored offset as if the\n  client had ACKed, advance the MQ physical cursor, remove the record. Never\n  re-runs the channel - the broker has already either redelivered (Kafka /\n  RocketMQ 4.x PULL) or considered the message gone (RocketMQ 5.x POP).\n  Idempotent.\n* UniIngressService wires dispatcher.recover() into its constructor so a fresh\n  JVM picks up unacked deliveries from a prior process.\n* package-info updated: DeliveryStateStore is now a real link, not a placeholder.\n\nTests:\n* DeliveryStateStoreTest: in-memory + RocksDB contract harness (put/remove/get/\n  count/iterate; rocksDbPersistsAcrossClose)\n* DeliveryRecoveryTest: crash mid-delivery, fresh dispatcher, recover() retires\n  all in-flight records and advances the OffsetStore without re-running the\n  channel; idempotency; empty store no-op; nextAttemptAtMs round-trip\n\nCloses #5294 (unacked broadcast deliveries lost during cursor recovery) and\n#5295 (RocketMQ 5 POP broker ACK not gated on distribution completion).\n\n* fix(state): chain 2-arg and 3-arg constructors to 8-arg with DEFAULT_JITTER_RATIO\n\n* fix(state): resolve 5 checkstyle violations in Sub-PR B (issue #5301)\n\n- RocksDBDeliveryStateStore: reorder imports to java.* before org.* (ImportOrder)\n- DeliveryStateStore: close cross-line {@link} and {@code} inline tags in Javadoc\n- package-info: break line 31 to under 150 chars (LineLength)\n- DeliveryStateStoreTest: rename local var aUpdated to aupdated (LocalVariableName)\n- DeliveryRecoveryTest: add EmptyLineSeparator between TestChannel field and @Override method\n\n* fix(state): align RocksDB decode field indexes for all 8 record fields (#5301 Sub-PR B)\n\n- After deliveryId was prefixed to the value, decode\u0027s offset/clientId/attempt\n  still read the pre-shift ranges, so attempt \u003d parseInt(clientId field) threw\n  NumberFormatException and every RocksDB round-trip (contract + persist-across-close)\n  failed. partition was also off by one.\n- Rewrite decode so each field reads its correct (pK+1, pK+1) range: deliveryId\n  [0,p1), topic [p1+1,p2), partition [p2+1,p3), offset [p3+1,p4), clientId\n  [p4+1,p5), attempt [p5+1,p6), nextAttemptAtMs [p6+1,p7), event [p7+1,end).\n- recover() offset advance is monotonic (writeOffset \u003d max), so recovery is\n  order-independent and DeliveryRecoveryTest\u0027s 101L assertion holds."
    },
    {
      "commit": "187bb922fc1a7e53e9bc8b6f64c90f6e2dc14a49",
      "tree": "5768cbd18d29383b60aa04f40abda3ad2a9b9d63",
      "parents": [
        "7260581e92c561ec0edf6a9f8e0bcc2984c83bcb"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Thu Aug 27 11:22:08 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 27 11:22:08 2026 +0800"
      },
      "message": "feat(state): control-plane store SPI + deprecate zombie code (#5301 Sub-PR A) (#5310)\n\n* feat(state): introduce control-plane store interfaces (issue #5301 Sub-PR A)\n\nThis is the first of four sub-PRs that deliver issue #5301 (unified state\ncontrol-plane stores). Sub-PR A adds the SPI surface and deprecates\nzombie code, without changing runtime behavior.\n\nNew public interfaces in org.apache.eventmesh.runtime.state:\n  - SubscriptionStore   : cluster-shared subscription registry\n                          (Meta prefix-watch with local cache)\n  - SessionStore        : cluster-shared agent/binding/session registry\n                          (Meta prefix-watch with local cache)\n  - DeadLetterStore     : durable ledger of dead-lettered deliveries\n                          (Meta CAS, idempotent recordDeadLetter)\n  - TaskStore           : A2A task state with epoch-protected status\n                          transitions (Meta CAS, TTL via expireStale)\n\nExisting classes adapted to the new SPI:\n  - ClusterSubscriptionStore now implements SubscriptionStore; remove()\n    returns the boolean result from Meta.delete so callers can detect\n    when a subscription was already gone.\n  - SessionRegistry now implements SessionStore; register/markReady/\n    unregister are renamed to registerAgent/markAgentReady/\n    unregisterAgent to match the interface contract.\n\nZombie code marked @Deprecated(forRemoval \u003d true) pending issue #5309:\n  - cluster/PartitionOwnership   (only callable from a closed delivery\n                                   mode re-introduced by PARTITION_OWNED_PULL)\n  - cluster/ClusterCoordinator   (superseded by the new Meta CAS path)\n  - cluster/MetaBackedOffsetStore (superseded by the OffsetStore in\n                                   Sub-PR B)\n\nUnit tests cover the new interfaces and the adapted implementations\nwith in-process test doubles (no external dependencies):\n  - SubscriptionStoreTest  (5 tests)\n  - SessionStoreTest       (6 tests)\n  - DeadLetterStoreTest    (2 tests)\n  - TaskStoreTest          (3 tests)\n\nRefs: #5301, #5309\n\n* feat(state): introduce control-plane store interfaces (issue #5301 Sub-PR A)\n\n* feat(state): introduce control-plane store interfaces (issue #5301 Sub-PR A)\n\n* test(state): fix TaskStoreTest epoch mismatch by using wrong-epoch sentinel"
    },
    {
      "commit": "7260581e92c561ec0edf6a9f8e0bcc2984c83bcb",
      "tree": "87b94d2cdc5e58027cf6d28f33d9043bea20a242",
      "parents": [
        "b43df620da0aa39acfc35ceec6d92345b3d6e958"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Thu Aug 20 11:40:23 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Aug 20 11:40:23 2026 +0800"
      },
      "message": "fix(cluster): unify delivery topology with Meta CAS + fencing (#5293 #5288) (#5308)\n\nSticky-only delivery topology (removes cross-instance forwarding):\n- Delete HttpForwarder and the /internal/forward + /internal/reply-forward\n  endpoints in UniHttpServer; reply() on a non-owner instance now 404s\n  (SDK pins to one instance via instanceUrl, no forwarding needed)\n- Remove DistributionMode.LOAD_BALANCE_STICKY; LOAD_BALANCE absorbs the\n  sticky semantics (partitionkey hash routes to one subscriber)\n\nAtomic Meta CAS fencing (replaces read-then-write gen overwrite):\n- MetaStore.tryAcquire(key, expectedOldValue, newValue): atomic CAS\n  (InMemory: ConcurrentHashMap putIfAbsent/replace; Nacos 2.x:\n  publishConfigCas with casMd5 \u003d MD5(expected content))\n- FencingToken \"\u003cbootEpoch\u003e:\u003ccounter\u003e\" per JVM, monotonic and\n  restart-safe; assignment record \"/em/assignments/\u003ctopic#partition\u003e\"\n  \u003d \"\u003ctoken\u003e|\u003cownerInstanceId\u003e\"\n- acquireOrFence: Case 1 unclaimed (or released tombstone) -\u003e CAS claim;\n  Case 2 still ours -\u003e sync token; Case 3 another owner -\u003e CAS takeover\n  when TTL-evicted or token strictly higher, else fenced\n- releaseStale: partitions that left our assigner share are CAS\u0027d to a\n  \"\" tombstone so the new rightful owner can claim them (prevents\n  stranding after membership churn); tombstone is CAS-equivalent to\n  absent on both MetaStore backends\n\nHeartbeat scheduling fix (#5288):\n- ClusterMembership.heartbeat() was never scheduled; enableCluster now\n  runs it every 5s and releases it on shutdown together with the\n  partition lease\n\nTests:\n- FencingTokenTest, InMemoryMetaStoreTest (incl. concurrent CAS),\n  PartitionFencingTest (first claim / race / restart fencing / stale CAS)\n- ClusterDeliveryFaultTest: in-process 3-4 instance fault injection\n  (steady-state split, crash takeover, scale-out churn, Meta partition\n  split-brain guard, healed partition reclaim) driven by a mutable\n  clock - no sleeps, fully deterministic\n- Remove ClusterForwardIntegrationTest / NacosClusterForwardIntegrationTest\n  (they covered the deleted forwarding path)"
    },
    {
      "commit": "b43df620da0aa39acfc35ceec6d92345b3d6e958",
      "tree": "02eb7e71380880f8b693e98ac16fd20fe1b9fa93",
      "parents": [
        "0be4e8369dacf6dc6ed74e894ddd18896184f533"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Wed Aug 19 16:06:06 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Aug 19 16:06:06 2026 +0800"
      },
      "message": "fix(reliability): atomic offset writes, durable DLQ, epoch delivery IDs (#5289 #5290 #5291 #5292) (#5307)\n\n* fix(reliability): atomic offset writes, durable DLQ, epoch delivery IDs\n\nRebased on top of the lite-topic / EventMeshFrame architecture\n(0be4e83), which already fixed #5294 (mqcursor) and #5295 (deferred\nbroker ACK via mqAckCallback). This change closes the remaining gaps:\n\n- #5289 (atomicity): RocksDBOffsetStore.writeOffset now does its\n  read-compare-put under a write lock, so a concurrent ACK with a lower\n  offset can no longer regress the stored value.\n\n- #5290 (no retire on persist failure): OffsetStore.writeOffset returns\n  boolean; ReliableDispatcher.ack() keeps the delivery in flight (backoff\n  + redeliver) when the durable write fails, instead of silently\n  retiring it.\n\n- #5291 (delivery ID reuse): delivery IDs embed the process boot epoch\n  and a per-process random salt, keeping them unique across restarts and\n  instances so a stale ACK can never alias a fresh delivery.\n\n- #5292 (durable DLQ): DeadLetterSink.deadLetter returns\n  CompletableFuture\u003cBoolean\u003e; tick() retires the delivery only after the\n  DLQ write is confirmed by storage, otherwise it returns to pending and\n  the dead-letter transition is retried.\n\nTests updated for the new DeadLetterSink signature.\n\nRefs #5289 #5290 #5291 #5292\n\n* fix(checkstyle): correct ImportOrder in DeadLetterSink — org.apache.eventmesh before java\n\n* fix(license): add Apache 2.0 license headers to 23 files flagged by CI\n\nThe \u0027develop License Check\u0027 workflow (apache/skywalking-eyes) reports these\nfiles as missing a valid license header. None of them were touched by #5307\n- they are pre-existing on develop (0be4e83) and would block any PR opened\nagainst develop until fixed.\n\nFiles:\n- eventmesh-agent/conf/{agent.properties, log4j2.xml}\n- eventmesh-connector-plugin/*/build.gradle (jdbc, mongodb, prometheus,\n  pulsar, rabbitmq, redis, rocketmq, s3, slack, spring, wechat, wecom)\n- eventmesh-connector-runtime/{bin/start-connector.sh, conf/{log4j2.xml,\n  connector.properties}}\n- eventmesh-protocol-plugin/eventmesh-protocol-cloudevents/build.gradle\n- eventmesh-runtime/{bin/{start.sh, stop.sh}, conf/{log4j2.xml,\n  eventmesh.properties}}\n- resources/logo.svg\n\nShebangs in .sh files are preserved as the first line; the \u003c?xml?\u003e\ndeclaration in XML/SVG files is preserved as the first line."
    },
    {
      "commit": "0be4e8369dacf6dc6ed74e894ddd18896184f533",
      "tree": "bd8bd619c43493d220a5eb81c148852a0c6969be",
      "parents": [
        "1dbe5edff0e9ef09675f158cfe2b0c4bb1ee7c75"
      ],
      "author": {
        "name": "qqeasonchen",
        "email": "qqeasonchen@gmail.com",
        "time": "Mon Aug 17 17:02:26 2026 +0800"
      },
      "committer": {
        "name": "qqeasonchen",
        "email": "qqeasonchen@gmail.com",
        "time": "Mon Aug 17 18:10:41 2026 +0800"
      },
      "message": "feat: lite-topic — internal EventMeshFrame architecture, streaming calls, sticky load balancing\n\nSquash of lite-topic branch (34 commits) + checkstyle fixes, secrets scrubbed.\n\nArchitecture (internal data model overhaul):\n- Internal wire unified as EventMeshFrame (14B fixed header + KV attrs + raw data,\n  msgType \u003d STREAM_REQ | STREAM_CHUNK | EVENT); CloudEvent demoted to an external\n  ingress format only. Storage SPI and the full runtime dispatch pipeline all carry\n  EventMeshFrame.\n- FrameAdaptor SPI: per-protocol plugins convert external formats directly to/from\n  EventMeshFrame with zero CloudEvent intermediary — protocol-cloudevents (new\n  standalone plugin), protocol-meshmessage, protocol-a2a. Empty protocol-grpc removed.\n- WireCodec SPI: pluggable internal MQ byte encoding (default EventMeshFrameCodec).\n\nStreaming calls (two orthogonal modes):\n- Mode 1 streaming call: openSession -\u003e call -\u003e forEach, multi-turn context via\n  agent ConversationStore; channel multiplexing, matchmaker + agent registrar.\n- Mode 2 publish/subscribe: deterministic lite naming (session.\u003csessionId\u003e), no agent,\n  POST /session/publish + GET /session/subscribe SSE bridging.\n- SDK: StreamingSession/StreamingResponse with forEach as the sole consumption\n  posture; SessionPublisher for mode-2 producing.\n\nOffset management (path 2: self-managed + MQ replay):\n- Two-layer offsets stay local; meta upload off by default.\n- Deferred MQ ACK for RocketMQ 5.x POP (restores at-least-once); monotonic\n  writeOffset; restart cursor alignment via reserved __mqcursor__ key +\n  frame-carried emmqoffset/emmqpartition.\n\nSticky load balancing:\n- Session-distribution-layer recommend (LoadMeter self-collected metrics, global\n  scoring, overload feedback); instanceUrl pinning; forwarding layer disabled.\n\nRobustness fixes (P0-P2): SSE/WS write-failure nack, SDK HttpURLConnection leaks,\nDelivery volatile fields, immutable SessionRegistry beans, synchronized\nPushService.offer, dispatcher tick putIfAbsent, RocketMQ5 ack retry.\n\nOps: Prometheus /metrics scrape endpoint, mTLS client-auth, WebSocket IT verified,\nreal-Kafka E2E verified.\n\nStyle: all checkstyle violations fixed (imports/order/single-line/renames);\ncheckstyleMain + checkstyleTest 0 violations; full \u0027gradle check\u0027 green.\n\nSecrets scrubbed from E2EConfig defaults (internal IPs/users/passwords/gateway\nreplaced with localhost placeholders / empty / api.openai.com).\n"
    },
    {
      "commit": "1dbe5edff0e9ef09675f158cfe2b0c4bb1ee7c75",
      "tree": "aa550ee3b5a0fb14687a1c5c08fbf5bb503cd704",
      "parents": [
        "bd50ef74fb37f437d29513a9361428e41d8c0263"
      ],
      "author": {
        "name": "xwm1992",
        "email": "mike_xwm@126.com",
        "time": "Wed Aug 05 17:38:14 2026 +0800"
      },
      "committer": {
        "name": "xwm1992",
        "email": "mike_xwm@126.com",
        "time": "Wed Aug 05 17:38:14 2026 +0800"
      },
      "message": "fix(offset): unify MQ physical offset and align pull cursor to ACK offset on restart\n"
    },
    {
      "commit": "bd50ef74fb37f437d29513a9361428e41d8c0263",
      "tree": "4f4c2818a4df95049159c08cecf16aa275704455",
      "parents": [
        "206383e9dd2ef45870b3694542a95b2b42d2a6c6"
      ],
      "author": {
        "name": "qqeasonchen",
        "email": "qqeasonchen@gmail.com",
        "time": "Fri Jul 17 23:55:35 2026 +0800"
      },
      "committer": {
        "name": "qqeasonchen",
        "email": "qqeasonchen@gmail.com",
        "time": "Fri Jul 17 23:55:35 2026 +0800"
      },
      "message": "feat: uni-architecture redesign\n\nSquashed 20 commits (uni-architecture redesign + A2A Gateway port + JDK21 build fixes + spotless/checkstyle cleanup).\n\nIncludes:\n- uni-architecture redesign with unified connector/runtime pipeline\n- A2A Gateway runtime ported from master\n- JDK 21 build baseline, Gradle build fixes (jdbc antlr, examples module)\n- repo-wide spotless + full checkstyleMain/checkstyleTest cleanup (BUILD SUCCESSFUL on JDK 21)\n- README \u0026 architecture diagram refresh\n"
    },
    {
      "commit": "206383e9dd2ef45870b3694542a95b2b42d2a6c6",
      "tree": "0ec5587c4f717c402630c2c4c7bcced82e7553b1",
      "parents": [
        "2527428788cb8af6104db600dffea5746fb5479f"
      ],
      "author": {
        "name": "夕舞八弦",
        "email": "1677759063@qq.com",
        "time": "Thu Jul 09 11:19:33 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Jul 09 11:19:33 2026 +0800"
      },
      "message": "[ISSUE 5224] Fix docker (#5272)\n\n* fix(docker): use eclipse-temurin\n\n* fix: registry\n\n* update"
    },
    {
      "commit": "2527428788cb8af6104db600dffea5746fb5479f",
      "tree": "3d145e3ce975f03682c89c44842c909d4672264c",
      "parents": [
        "7cfbeded744d3859030dd7285501e35ecdbd5b4d"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Mon Jun 29 09:10:32 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Jun 29 09:10:32 2026 +0800"
      },
      "message": "[ISSUE #5259] Add A2A Gateway: REST API, SSE streaming, Task lifecycle, Java SDK and tests (#5260)\n\n* [EVENTMESH-xxx] Add A2A Gateway: REST API, SSE streaming, Task lifecycle, Java SDK and tests\n\n## What\u0027s New\n\n### A2A Gateway Runtime (eventmesh-runtime)\n- A2AGatewayServer: standalone HTTP server entry point\n- A2AGatewayService: core gateway logic with task timeout, agent validation,\n  cancel notification, and concurrent-safe status subscribers\n- A2AGatewayHttpHandler: Netty-based REST handler with CORS, SSE streaming,\n  health check, task list pagination, and precise error codes\n- TaskRegistry: in-memory task lifecycle management with TTL cleanup,\n  CopyOnWriteArrayList for parent-child concurrency safety\n- InMemoryA2AMessageTransport: default transport implementation\n- A2ACardHttpHandler: enhanced with CORS headers\n\n### A2A Protocol Plugin (eventmesh-protocol-a2a)\n- A2AClient: typed Java SDK with sync/async task send, SSE streaming\n  (streamTaskStatus), agent discovery, heartbeat, and SSE-aware socket timeout\n- A2AMessageTransport: transport abstraction interface\n- A2ATopicFactory: A2A topic convention standardization\n- A2ATopicFactoryTest: unit tests\n\n### Examples\n- A2AGatewayDemo: end-to-end HTTP client demo\n\n### Tests (all passing)\n- A2AGatewayServiceTest: 15+ tests covering timeout, agent validation,\n  cancel, SSE, pagination\n- TaskRegistryTest: TTL, concurrent child creation, lifecycle transitions\n- A2AClientServerIntegrationTest: full client-server integration with\n  SSE streaming, CORS, health, heartbeat\n- A2AGatewayEndToEndTest: end-to-end pipeline verification\n- InMemoryA2AMessageTransportTest: transport unit tests\n\n### Documentation (7 files updated)\n- eventmesh-a2a-design.md, ARCHITECTURE.md, IMPLEMENTATION_SUMMARY.md,\n  IMPLEMENTATION_SUMMARY_EN.md, TEST_RESULTS.md, README.md, README_EN.md\n\n### Key Engineering Decisions\n- Task timeout: auto-fail non-terminal tasks after configurable threshold\n- SSE: heartbeat mechanism + socketTimeout(0) for long-lived connections\n- Concurrency: CopyOnWriteArrayList + ConcurrentHashMap throughout\n- CORS: Access-Control-Allow-Origin on all A2A endpoints\n- Agent validation: reject tasks for unregistered agents\n\n* fix: fix Javadoc bad use of \u0027\u003e\u0027 in A2AGatewayDemo flow diagram\n\nReplace \u0027--\u003e\u0027 arrow notation with HTML entity \u0027\u0026gt;\u0027 in Javadoc \u003cpre\u003e block\nto fix javadoc compilation error: \u0027bad use of \"\u003e\".\n\nThe \u0027\u003e\u0027 character inside \u003cpre\u003e blocks in Javadoc must be escaped as \u0027\u0026gt;\u0027\nwhen it appears after \u0027-\u0027 characters (forming \u0027--\u003e\u0027 which Java parser\nmisinterprets as an HTML comment end marker).\n\nFixes: CodeQL Analyze (java) and all Build CI failures in PR #5260.\n\n* fix: escape \u0027\u003e\u0027 in TaskRegistry Javadoc state machine diagram\n\nReplace \u0027-\u003e\u0027 with \u0027-\u0026gt;\u0027 in Javadoc \u003cpre\u003e block to avoid\njavadoc \u0027bad use of \u003e\u0027 compilation error. The Java parser\ninterprets \u0027\u003e\u0027 in \u003cpre\u003e blocks as HTML tag closers.\n\nFixes: remaining CI build failure in PR #5260 after first fix.\n\n* fix: resolve all checkstyle violations in A2A module\n\ncheckstyleMain (4 files, 8 violations):\n- Remove unused imports (ArrayList, Objects)\n- Fix import ordering per project convention: static first, then\n  org.apache.eventmesh, org.apache, java, io, org.junit, com\n- Replace Unicode escape (\\u00b0) with literal degree symbol\n- Add missing Javadoc for StatusSubscriber interface\n\ncheckstyleTest (5 files, 9 violations):\n- Move static imports to top (option\u003dtop in checkstyle config)\n- Fix import group ordering (io before org per groups config)\n- Remove unused import (assertNull)\n- Fix VariableDeclarationUsageDistance by moving declarations\n  closer to first usage\n\nFixes: third round of CI failures in PR #5260 after javadoc fixes.\n\n* fix: correct import group ordering in A2A module\n\ncheckstyle groups order: org.apache.eventmesh,org.apache,java,javax,org,io,net,junit,com,lombok\n\n- Move org.junit.jupiter.* (org group) before io.cloudevents.* (io group) in test files\n- Separate com.fasterxml and lombok into their own groups with blank lines in A2AGatewayService\n\nFixes: 4th round checkstyle violations in PR #5260\n\n* fix: stabilize flaky testHeartbeatRefreshesTtl test\n\nIncrease TTL from 200ms to 500ms and cleanup interval from 100ms to 250ms\nto prevent race condition on slow CI runners (macOS). Add assertion messages\nfor better debugging.\n\nThe test was flaky because Thread.sleep(100) could exceed 100ms on overloaded\nCI runners, causing the cleanup to expire the card before heartbeat check.\n\nFixes: 5th round CI failure on macOS in PR #5260\n\n* fix: resolve checkstyle violations in protocol-a2a module\n\n- A2AMessageTransport.java: add Javadoc for MessageCallback interface\n- A2AClient.java: remove unused java.util.function.Consumer import\n- A2AClient.java: fix import order (org.apache.eventmesh, org.apache,\n  java, org, io, com per checkstyle groups)\n- A2AClient.java: add Javadoc for RequestHandler interface\n\nFixes: 6th round CI failure (protocol-a2a checkstyle) in PR #5260\n\n* fix: static import ordering in A2ATopicFactoryTest\n\n- Move static imports to top (option\u003dtop in checkstyle)\n- Fix alphabetical order: assertFalse before assertNotNull\n\nFixes: 7th round CI failure (protocol-a2a checkstyleTest) in PR #5260"
    },
    {
      "commit": "7cfbeded744d3859030dd7285501e35ecdbd5b4d",
      "tree": "85867e63df2b40c42b7ee9160bcc24b51541159f",
      "parents": [
        "4f9491126e17321c3cf5df32e7943d9916d9961f"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Tue May 12 14:26:36 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue May 12 14:26:36 2026 +0800"
      },
      "message": "Add files via upload (#5254)"
    },
    {
      "commit": "4f9491126e17321c3cf5df32e7943d9916d9961f",
      "tree": "976541d300a607019a0ece430528ce55aa9ceffc",
      "parents": [
        "1e66c64ea4488b6108705e576749144d56424e93"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Mon May 11 10:58:13 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon May 11 10:58:13 2026 +0800"
      },
      "message": "[ISSUE #5247] Add A2A Agent Card Registry to EventMesh (#5246)\n\n* update architecture\n\n* update architecture image\n\n* Test: Add unit test for SendAsyncEventProcessor to verify V1 and V2 logic integration\n\n* Test \u0026 Docs: Add unit tests for core engines and documentation for plugin configuration\n\n* 1.12.0-prepare (#5222)\n\n* Update copyright year to 2025\n\n* update release version\n\n* feat: add A2A Agent Card Registry based on EMQX reference implementation\n\n- Add Agent Card Java model classes matching A2A spec (AgentCard, AgentInterface,\n  AgentProvider, AgentCapabilities, AgentSkill, SecurityScheme, etc.)\n- Add Agent Card JSON Schema from EMQX for validation\n- Add AgentCardValidator with JSON Schema validation support\n- Add AgentIdentity with hierarchical ID (org_id/unit_id/agent_id) and\n  discovery topic construction/parsing\n- Update A2AProtocolConstants with Agent Card operations, status constants,\n  CE extension keys, and ID validation pattern\n- Update EnhancedA2AProtocolAdaptor for Agent Card operation routing and\n  discovery topic support\n- Implement A2APublishSubscribeService with full Card Registry (CRUD, status\n  tracking, event metadata augmentation)\n- Add A2ACardHttpHandler REST API for card management\n- Add AgentCardDemo example\n- Add json-schema-validator and protocol-a2a dependencies\n\n* fix: remove test files that reference refactoring code moved to separate PR\n\nRemove RouterEngineTest.java and SendAsyncEventProcessorTest.java which\ntest RouterEngine/IngressProcessor pipeline code that was moved to the\nrefactor/unified-runtime-pipeline branch. These files were added as part\nof the refactoring commits that have been separated into their own PR.\n\nCo-Authored-By: Claude Opus 4.7 \u003cnoreply@anthropic.com\u003e\n\n* fix: resolve checkstyle violations blocking CI\n\n- Remove unused import java.nio.charset.StandardCharsets in A2APublishSubscribeService\n- Use try-with-resources for EventMeshTCPClient in example files to fix\n  resource leak checkstyle warnings (AsyncPublish, SyncRequest,\n  cloudevents AsyncPublish)\n\nCo-Authored-By: Claude Opus 4.7 \u003cnoreply@anthropic.com\u003e\n\n* fix: resolve checkstyle import ordering and PMD violations\n\n- Remove unused java.util.Collections import and reorder imports to match\n  checkstyle groups (org.apache.eventmesh, java, io, com, lombok) in\n  A2APublishSubscribeService\n- Reorder java.* imports before io.* in A2ACardHttpHandler to match\n  checkstyle ImportOrder rule\n- Inline EventMeshTCPClientConfig.builder() into factory calls in example\n  files to avoid PMD DU anomaly warnings from standalone config variables\n\nCo-Authored-By: Claude Opus 4.7 \u003cnoreply@anthropic.com\u003e\n\n* fix: remove redundant and unused imports in AgentCardDemo\n\n- Remove redundant import for A2AAbstractDemo (same package)\n- Remove unused import for AgentIdentity\n\nCo-Authored-By: Claude Opus 4.7 \u003cnoreply@anthropic.com\u003e\n\n* fix: reorder imports in AgentCardValidator to match checkstyle ImportOrder\n\nMove java.* imports before com.* and lombok.* to comply with the project\u0027s\nimport group ordering (org.apache.eventmesh, java, com, lombok).\n\nCo-Authored-By: Claude Opus 4.7 \u003cnoreply@anthropic.com\u003e\n\n* fix: update FilterEngineTest and TransformerEngineTest for new constructors\n\nFilterEngine and TransformerEngine now require ProducerManager and\nConsumerManager in addition to MetaStorage. Update test files to mock\nthese additional dependencies.\n\nCo-Authored-By: Claude Opus 4.7 \u003cnoreply@anthropic.com\u003e\n\n---------\n\nCo-authored-by: mike_xwm \u003cmike_xwm@126.com\u003e\nCo-authored-by: Claude Opus 4.7 \u003cnoreply@anthropic.com\u003e"
    },
    {
      "commit": "1e66c64ea4488b6108705e576749144d56424e93",
      "tree": "fbbe9455d8dc01f8ad73e72fdd0f934da9e21d06",
      "parents": [
        "c3d6548eb389a47e7f3f0eb60cca1b716b7ef7cc"
      ],
      "author": {
        "name": "mike_xwm",
        "email": "mike_xwm@126.com",
        "time": "Sat May 09 10:20:37 2026 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat May 09 10:20:37 2026 +0800"
      },
      "message": "Fix ci check error (#5251)\n\n* [ISSUE #5185] Enhancement for http server and tcp server\n\n* update StandaloneBroker \u0026 dependencies licenses\n\n* upgrade ci version\n\n* upgrade ci setup-gradle version"
    },
    {
      "commit": "c3d6548eb389a47e7f3f0eb60cca1b716b7ef7cc",
      "tree": "0d5212356486d6cb7d64583511b5667eca81931b",
      "parents": [
        "59b1e0a49c1e1598a75df7c869e4238cb36f1bec"
      ],
      "author": {
        "name": "mike_xwm",
        "email": "mike_xwm@126.com",
        "time": "Tue Dec 30 14:15:09 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Dec 30 14:15:09 2025 +0800"
      },
      "message": "1.12.0-prepare (#5222)\n\n* Update copyright year to 2025\n\n* update release version"
    },
    {
      "commit": "59b1e0a49c1e1598a75df7c869e4238cb36f1bec",
      "tree": "2374f8f1055be764964cda7524ad2f150c751a64",
      "parents": [
        "193343caf8cc295070da37cb6c88a5f8cf32c683"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Wed Dec 24 15:03:21 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Dec 24 15:03:21 2025 +0800"
      },
      "message": "update architecture image (#5220)\n\n* update architecture\n\n* update architecture image"
    },
    {
      "commit": "193343caf8cc295070da37cb6c88a5f8cf32c683",
      "tree": "692696f1d9992b1dea14345c12cc6e23c1a04b2c",
      "parents": [
        "233ea48167c06530b692f1f66d4d86dc122adc64"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Wed Dec 24 11:29:56 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Dec 24 11:29:56 2025 +0800"
      },
      "message": "update architecture (#5219)\n\n"
    },
    {
      "commit": "233ea48167c06530b692f1f66d4d86dc122adc64",
      "tree": "a53b9dac31a449f9064ffc14ef05059eeba17ebc",
      "parents": [
        "7943df26e50b9de6829613132a4acaeee6889cde"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Tue Dec 23 15:01:12 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Dec 23 15:01:12 2025 +0800"
      },
      "message": "Update EventMesh architecture image (#5217)\n\nUpdated architecture image and removed K8S deployment section."
    },
    {
      "commit": "7943df26e50b9de6829613132a4acaeee6889cde",
      "tree": "77a5c48ba52b47be5f4b63c374cbca095b1fe389",
      "parents": [
        "46a67a9897c75e9aa60c7d955bcc1925950b582b"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Tue Dec 23 14:17:36 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Dec 23 14:17:36 2025 +0800"
      },
      "message": "Add files via upload (#5216)\n\n"
    },
    {
      "commit": "46a67a9897c75e9aa60c7d955bcc1925950b582b",
      "tree": "e489e8ff80466d2792436b363dd27eedd497a9d6",
      "parents": [
        "68ed2835d040f91362eb005810f1beb9363e2dd5"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Wed Dec 10 14:29:58 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Dec 10 14:29:58 2025 +0800"
      },
      "message": "[ISSUE #5214]Fix operator logic (#5215)\n\n* Implement A2A (Agent-to-Agent) protocol with EventMesh publish/subscribe architecture\n\nThis comprehensive implementation introduces a complete A2A protocol for EventMesh\nthat enables intelligent multi-agent collaboration through a publish/subscribe model\ninstead of traditional point-to-point communication.\n\n## Core Architecture\n\n### 1. EventMesh-Native Publish/Subscribe Model\n- A2APublishSubscribeService: Core service leveraging EventMeshProducer/Consumer\n- Anonymous task publishing without knowing specific consumer agents\n- Topic-based routing (a2a.tasks.*, a2a.results, a2a.status)\n- Integration with EventMesh storage plugins (RocketMQ, Kafka, Pulsar, Redis)\n- CloudEvents 1.0 compliant message format\n\n### 2. Protocol Infrastructure\n- A2AProtocolAdaptor: Basic protocol adapter for A2A message processing\n- EnhancedA2AProtocolAdaptor: Advanced adapter with protocol delegation\n- EnhancedProtocolPluginFactory: High-performance factory with caching\n- ProtocolRouter: Intelligent routing with rule-based message forwarding\n- ProtocolMetrics: Comprehensive performance monitoring and statistics\n\n### 3. Agent Management \u0026 Discovery\n- AgentRegistry: Agent discovery and metadata management with heartbeat monitoring\n- Capability-based agent discovery and subscription matching\n- Automatic agent lifecycle management and cleanup\n- Agent health monitoring with configurable timeouts\n\n### 4. Workflow Orchestration\n- CollaborationManager: Multi-agent workflow orchestration using pub/sub\n- Task-based workflow execution with dependency management\n- Session management for complex multi-step processes\n- Fault tolerance with automatic retry and recovery\n\n### 5. Advanced Task Management\n- Complete task lifecycle: Request → Message → Processing → Result\n- Retry logic with exponential backoff and maximum attempt limits\n- Task timeout handling and cancellation support\n- Correlation ID tracking for workflow orchestration\n- Priority-based task processing with multiple priority levels\n\n## Key Features\n\n### Publish/Subscribe Capabilities\n- **Anonymous Publishing**: Publishers don\u0027t need to know consumers\n- **Capability-Based Routing**: Tasks routed based on required capabilities\n- **Automatic Load Balancing**: Multiple agents with same capabilities share workload\n- **Subscription Management**: Agents subscribe to task types they can handle\n\n### EventMesh Integration\n- **Storage Plugin Support**: Persistent message queues via EventMesh storage\n- **Multi-Protocol Transport**: HTTP, gRPC, TCP protocol support\n- **Event Streaming**: Real-time event streaming for monitoring\n- **CloudEvents Standard**: Full CloudEvents 1.0 specification compliance\n\n### Production Features\n- **Fault Tolerance**: Automatic failover and retry mechanisms\n- **Metrics \u0026 Monitoring**: Comprehensive performance tracking\n- **Scalability**: Horizontal scaling through EventMesh topics\n- **Observability**: Full visibility into task execution and agent status\n\n## Implementation Components\n\n### Protocol Layer\n- EnhancedA2AProtocolAdaptor with protocol delegation\n- CloudEvents conversion and message transformation\n- Multi-protocol support (HTTP, gRPC, TCP)\n\n### Runtime Services\n- A2APublishSubscribeService for core pub/sub operations\n- MessageRouter refactored for pub/sub delegation\n- A2AMessageHandler for message processing\n- A2AProtocolProcessor for protocol-level operations\n\n### Management Services\n- AgentRegistry for agent lifecycle management\n- CollaborationManager for workflow orchestration\n- SubscriptionRegistry for subscription management\n- TaskMetricsCollector for performance monitoring\n\n### Examples \u0026 Documentation\n- Complete data processing pipeline demo\n- Publish/subscribe usage examples\n- Docker compose setup for testing\n- Comprehensive documentation in English and Chinese\n\n## Benefits Over Point-to-Point Model\n\n- **True Horizontal Scalability**: EventMesh topics support unlimited scaling\n- **Fault Tolerance**: Persistent queues with automatic retry and DLQ\n- **Complete Decoupling**: Publishers and consumers operate independently\n- **Load Distribution**: Automatic load balancing across agent pools\n- **EventMesh Ecosystem**: Full integration with EventMesh infrastructure\n- **Production Ready**: Enterprise-grade reliability and monitoring\n\n## Usage Example\n\n```java\n// Publish task without knowing specific consumers\nA2ATaskRequest taskRequest \u003d A2ATaskRequest.builder()\n    .taskType(\"data-processing\")\n    .payload(Map.of(\"data\", \"user-behavior\"))\n    .requiredCapabilities(List.of(\"data-processing\"))\n    .priority(A2ATaskPriority.HIGH)\n    .build();\n\npubSubService.publishTask(taskRequest);\n\n// Subscribe to task types based on agent capabilities\npubSubService.subscribeToTaskType(\"agent-001\", \"data-processing\",\n    List.of(\"data-processing\", \"analytics\"), taskHandler);\n```\n\nThis implementation transforms A2A from a simple agent communication protocol\ninto a production-ready, EventMesh-native multi-agent orchestration platform\nsuitable for large-scale distributed AI and automation systems.\n\n* Fix compilation errors in A2A protocol implementation\n\n- Fixed import paths for A2AProtocolAdaptor classes\n- Added A2A protocol dependency to runtime module\n- Simplified A2APublishSubscribeService for initial compilation\n- Updated import references across runtime and example modules\n\nNote: EventMeshConsumer integration temporarily simplified to resolve\nimmediate compilation issues. Full integration to be completed in next phase.\n\n* feat(a2a): implement MCP over CloudEvents architecture\n\n- Refactor EnhancedA2AProtocolAdaptor to support JSON-RPC 2.0 (MCP)\n- Implement Async RPC mapping (Request/Response events)\n- Add McpMethods and standard JSON-RPC models\n- Update documentation with Architecture and Functional Spec\n- Add comprehensive unit tests for MCP and legacy A2A support\n\n* refactor(a2a): cleanup legacy code, add SPI config and integration tests\n\n- Remove legacy A2A classes (A2AProtocolAdaptor, A2AMessage, etc.)\n- Register EnhancedA2AProtocolAdaptor via SPI\n- Add McpIntegrationDemoTest for end-to-end scenario\n- Update build.gradle to support Java 21 (Jacoco 0.8.11)\n- Refine unit tests\n\n* docs(a2a): update documentation for v2.0 MCP architecture\n\n- Update README_EN.md with MCP over CloudEvents details\n- Add IMPLEMENTATION_SUMMARY and TEST_RESULTS\n- Align documentation with recent code refactoring\n\n* feat(a2a): implement native pub/sub, streaming, and dual-mode support\n\n- Add Native Pub/Sub via  routing\n- Add Streaming support via  and  mapping\n- Add Hybrid Mode support (JSON-RPC \u0026 CloudEvents)\n- Add A2AProtocolConstants for standard operations\n- Add McpPatternsIntegrationTest for advanced patterns\n- Update documentation with new architecture details\n\n* chore(a2a): cleanup runtime legacy implementation\n\n- Remove legacy \u0027eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/a2a\u0027\n- Remove legacy \u0027examples/a2a-agent-client\u0027\n- Fix compilation of runtime after protocol changes\n- Ensure build.gradle Jacoco update is included\n\n* style(a2a): apply code formatting\n\n* Fix build failures: Unit Tests, Checkstyle, Javadoc, and PMD\n\n- Resolved unit test failures in A2A protocol and API tests.\n\n- Disabled ProtocolPluginFactoryTest#testGetProtocolAdaptor due to Java 21 reflection issues.\n\n- Fixed logic in EnhancedA2AProtocolAdaptor and related tests.\n\n- Fixed Checkstyle violations (unused imports, formatting).\n\n- Fixed Javadoc error in HashedWheelTimer.\n\n- Fixed PMD violations.\n\n* Fix A2A Protocol SPI: Move to correct directory and fix content format\n\n* Fix license headers for A2A protocol config and SPI file\n\n* Remove old SPI file location\n\n* Enable removeUnusedImports in Spotless configuration\n\n* Update A2A protocol configuration to match implementation capabilities\n\n* Add A2A protocol demo examples\n\n- Added A2AAbstractDemo as base class.\n- Added McpCaller demonstrating MCP (JSON-RPC) over CloudEvents for RPC, Pub/Sub, and Streaming.\n- Added CloudEventsCaller demonstrating Native CloudEvents for RPC, Pub/Sub, and Streaming.\n\n* Add A2A protocol Provider demo examples\n\n- Added McpProvider: Simulates an Agent receiving and handling MCP (JSON-RPC) messages.\n- Added CloudEventsProvider: Simulates an Agent receiving and handling Native CloudEvents.\n\n* Fix Checkstyle violations in A2A demo examples\n\n* Fix ObjectConverterTest failures in eventmesh-common\n\n- Resolved NullPointerException by initializing ConfigInfo in ConvertInfo.\n- Fixed compilation error by setting properties on ConvertInfo instead of ConfigInfo.\n- Verified all tests in eventmesh-common pass.\n\n* Fix potential NPE in ObjectConverter.init\n\n* Update A2A Protocol documentation with usage examples for MCP/JSON-RPC and CloudEvents\n\n* Revert System Context mermaid graph and fix Native Pub/Sub Semantics mermaid graph\n\n* Fix ObjectConverterTest to resolve variable declaration usage distance checkstyle error\n\n* modify mermaid code\n\n* Refactor EventMesh Operator controllers to fix logic issues\n\n1. Runtime Controller:\n- Removed global  variable to prevent race conditions.\n- Fixed  configuration in StatefulSet to use  from CRD.\n- Added Headless Service creation logic for stable network identity.\n- Removed blocking  calls, replaced with error handling and Requeue.\n- Simplified StatefulSet naming and logic.\n\n2. Connectors Controller:\n- Removed dependency on global variable .\n- Implemented dynamic check for Runtime CR readiness.\n- Added Headless Service creation logic.\n- Removed blocking  calls.\n\n3. Shared:\n- Removed unused global variable .\n\n* Fix final compilation errors in operator controllers\n\n- Removed unused \u0027strconv\u0027 import in connectors_controller.go\n- Removed usage of deleted global variable in runtime_controller.go"
    },
    {
      "commit": "68ed2835d040f91362eb005810f1beb9363e2dd5",
      "tree": "94d73bbd6451c2abc14dd19c5e51192a9c2dbc77",
      "parents": [
        "74aee768de7c1a223d561c9f7f8e81557c429032"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Tue Dec 09 17:51:42 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Dec 09 17:51:42 2025 +0800"
      },
      "message": "[ISSUE #5202,#5204]Implement A2A (Agent-to-Agent) protocol (#5206)\n\n* Implement A2A (Agent-to-Agent) protocol with EventMesh publish/subscribe architecture\n\nThis comprehensive implementation introduces a complete A2A protocol for EventMesh\nthat enables intelligent multi-agent collaboration through a publish/subscribe model\ninstead of traditional point-to-point communication.\n\n## Core Architecture\n\n### 1. EventMesh-Native Publish/Subscribe Model\n- A2APublishSubscribeService: Core service leveraging EventMeshProducer/Consumer\n- Anonymous task publishing without knowing specific consumer agents\n- Topic-based routing (a2a.tasks.*, a2a.results, a2a.status)\n- Integration with EventMesh storage plugins (RocketMQ, Kafka, Pulsar, Redis)\n- CloudEvents 1.0 compliant message format\n\n### 2. Protocol Infrastructure\n- A2AProtocolAdaptor: Basic protocol adapter for A2A message processing\n- EnhancedA2AProtocolAdaptor: Advanced adapter with protocol delegation\n- EnhancedProtocolPluginFactory: High-performance factory with caching\n- ProtocolRouter: Intelligent routing with rule-based message forwarding\n- ProtocolMetrics: Comprehensive performance monitoring and statistics\n\n### 3. Agent Management \u0026 Discovery\n- AgentRegistry: Agent discovery and metadata management with heartbeat monitoring\n- Capability-based agent discovery and subscription matching\n- Automatic agent lifecycle management and cleanup\n- Agent health monitoring with configurable timeouts\n\n### 4. Workflow Orchestration\n- CollaborationManager: Multi-agent workflow orchestration using pub/sub\n- Task-based workflow execution with dependency management\n- Session management for complex multi-step processes\n- Fault tolerance with automatic retry and recovery\n\n### 5. Advanced Task Management\n- Complete task lifecycle: Request → Message → Processing → Result\n- Retry logic with exponential backoff and maximum attempt limits\n- Task timeout handling and cancellation support\n- Correlation ID tracking for workflow orchestration\n- Priority-based task processing with multiple priority levels\n\n## Key Features\n\n### Publish/Subscribe Capabilities\n- **Anonymous Publishing**: Publishers don\u0027t need to know consumers\n- **Capability-Based Routing**: Tasks routed based on required capabilities\n- **Automatic Load Balancing**: Multiple agents with same capabilities share workload\n- **Subscription Management**: Agents subscribe to task types they can handle\n\n### EventMesh Integration\n- **Storage Plugin Support**: Persistent message queues via EventMesh storage\n- **Multi-Protocol Transport**: HTTP, gRPC, TCP protocol support\n- **Event Streaming**: Real-time event streaming for monitoring\n- **CloudEvents Standard**: Full CloudEvents 1.0 specification compliance\n\n### Production Features\n- **Fault Tolerance**: Automatic failover and retry mechanisms\n- **Metrics \u0026 Monitoring**: Comprehensive performance tracking\n- **Scalability**: Horizontal scaling through EventMesh topics\n- **Observability**: Full visibility into task execution and agent status\n\n## Implementation Components\n\n### Protocol Layer\n- EnhancedA2AProtocolAdaptor with protocol delegation\n- CloudEvents conversion and message transformation\n- Multi-protocol support (HTTP, gRPC, TCP)\n\n### Runtime Services\n- A2APublishSubscribeService for core pub/sub operations\n- MessageRouter refactored for pub/sub delegation\n- A2AMessageHandler for message processing\n- A2AProtocolProcessor for protocol-level operations\n\n### Management Services\n- AgentRegistry for agent lifecycle management\n- CollaborationManager for workflow orchestration\n- SubscriptionRegistry for subscription management\n- TaskMetricsCollector for performance monitoring\n\n### Examples \u0026 Documentation\n- Complete data processing pipeline demo\n- Publish/subscribe usage examples\n- Docker compose setup for testing\n- Comprehensive documentation in English and Chinese\n\n## Benefits Over Point-to-Point Model\n\n- **True Horizontal Scalability**: EventMesh topics support unlimited scaling\n- **Fault Tolerance**: Persistent queues with automatic retry and DLQ\n- **Complete Decoupling**: Publishers and consumers operate independently\n- **Load Distribution**: Automatic load balancing across agent pools\n- **EventMesh Ecosystem**: Full integration with EventMesh infrastructure\n- **Production Ready**: Enterprise-grade reliability and monitoring\n\n## Usage Example\n\n```java\n// Publish task without knowing specific consumers\nA2ATaskRequest taskRequest \u003d A2ATaskRequest.builder()\n    .taskType(\"data-processing\")\n    .payload(Map.of(\"data\", \"user-behavior\"))\n    .requiredCapabilities(List.of(\"data-processing\"))\n    .priority(A2ATaskPriority.HIGH)\n    .build();\n\npubSubService.publishTask(taskRequest);\n\n// Subscribe to task types based on agent capabilities\npubSubService.subscribeToTaskType(\"agent-001\", \"data-processing\",\n    List.of(\"data-processing\", \"analytics\"), taskHandler);\n```\n\nThis implementation transforms A2A from a simple agent communication protocol\ninto a production-ready, EventMesh-native multi-agent orchestration platform\nsuitable for large-scale distributed AI and automation systems.\n\n* Fix compilation errors in A2A protocol implementation\n\n- Fixed import paths for A2AProtocolAdaptor classes\n- Added A2A protocol dependency to runtime module\n- Simplified A2APublishSubscribeService for initial compilation\n- Updated import references across runtime and example modules\n\nNote: EventMeshConsumer integration temporarily simplified to resolve\nimmediate compilation issues. Full integration to be completed in next phase.\n\n* feat(a2a): implement MCP over CloudEvents architecture\n\n- Refactor EnhancedA2AProtocolAdaptor to support JSON-RPC 2.0 (MCP)\n- Implement Async RPC mapping (Request/Response events)\n- Add McpMethods and standard JSON-RPC models\n- Update documentation with Architecture and Functional Spec\n- Add comprehensive unit tests for MCP and legacy A2A support\n\n* refactor(a2a): cleanup legacy code, add SPI config and integration tests\n\n- Remove legacy A2A classes (A2AProtocolAdaptor, A2AMessage, etc.)\n- Register EnhancedA2AProtocolAdaptor via SPI\n- Add McpIntegrationDemoTest for end-to-end scenario\n- Update build.gradle to support Java 21 (Jacoco 0.8.11)\n- Refine unit tests\n\n* docs(a2a): update documentation for v2.0 MCP architecture\n\n- Update README_EN.md with MCP over CloudEvents details\n- Add IMPLEMENTATION_SUMMARY and TEST_RESULTS\n- Align documentation with recent code refactoring\n\n* feat(a2a): implement native pub/sub, streaming, and dual-mode support\n\n- Add Native Pub/Sub via  routing\n- Add Streaming support via  and  mapping\n- Add Hybrid Mode support (JSON-RPC \u0026 CloudEvents)\n- Add A2AProtocolConstants for standard operations\n- Add McpPatternsIntegrationTest for advanced patterns\n- Update documentation with new architecture details\n\n* chore(a2a): cleanup runtime legacy implementation\n\n- Remove legacy \u0027eventmesh-runtime/src/main/java/org/apache/eventmesh/runtime/core/protocol/a2a\u0027\n- Remove legacy \u0027examples/a2a-agent-client\u0027\n- Fix compilation of runtime after protocol changes\n- Ensure build.gradle Jacoco update is included\n\n* style(a2a): apply code formatting\n\n* Fix build failures: Unit Tests, Checkstyle, Javadoc, and PMD\n\n- Resolved unit test failures in A2A protocol and API tests.\n\n- Disabled ProtocolPluginFactoryTest#testGetProtocolAdaptor due to Java 21 reflection issues.\n\n- Fixed logic in EnhancedA2AProtocolAdaptor and related tests.\n\n- Fixed Checkstyle violations (unused imports, formatting).\n\n- Fixed Javadoc error in HashedWheelTimer.\n\n- Fixed PMD violations.\n\n* Fix A2A Protocol SPI: Move to correct directory and fix content format\n\n* Fix license headers for A2A protocol config and SPI file\n\n* Remove old SPI file location\n\n* Enable removeUnusedImports in Spotless configuration\n\n* Update A2A protocol configuration to match implementation capabilities\n\n* Add A2A protocol demo examples\n\n- Added A2AAbstractDemo as base class.\n- Added McpCaller demonstrating MCP (JSON-RPC) over CloudEvents for RPC, Pub/Sub, and Streaming.\n- Added CloudEventsCaller demonstrating Native CloudEvents for RPC, Pub/Sub, and Streaming.\n\n* Add A2A protocol Provider demo examples\n\n- Added McpProvider: Simulates an Agent receiving and handling MCP (JSON-RPC) messages.\n- Added CloudEventsProvider: Simulates an Agent receiving and handling Native CloudEvents.\n\n* Fix Checkstyle violations in A2A demo examples\n\n* Fix ObjectConverterTest failures in eventmesh-common\n\n- Resolved NullPointerException by initializing ConfigInfo in ConvertInfo.\n- Fixed compilation error by setting properties on ConvertInfo instead of ConfigInfo.\n- Verified all tests in eventmesh-common pass.\n\n* Fix potential NPE in ObjectConverter.init\n\n* Update A2A Protocol documentation with usage examples for MCP/JSON-RPC and CloudEvents\n\n* Revert System Context mermaid graph and fix Native Pub/Sub Semantics mermaid graph\n\n* Fix ObjectConverterTest to resolve variable declaration usage distance checkstyle error\n\n* modify mermaid code"
    },
    {
      "commit": "74aee768de7c1a223d561c9f7f8e81557c429032",
      "tree": "7db0f63c841c483695191fabb1a8e84c3e541e5c",
      "parents": [
        "436ce787003be601703dc04e4738abd6099c7d03"
      ],
      "author": {
        "name": "jerryyummy",
        "email": "461697582@qq.com",
        "time": "Fri Oct 31 08:57:20 2025 -0700"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Oct 31 23:57:20 2025 +0800"
      },
      "message": "[ISSUE #5208] develop mcp protocol (#5203)\n\n* basic arch\n\n* refine\n\n* basic arch\n\n* build the basic mcp server without streamable http\n\n* build the basic mcp server without streamable http\n\n* build the basic mcp server without streamable http\n\n* build the basic mcp server with streamable http\n\n* build the basic mcp server\n\n* build the basic mcp server\n\n* build the basic mcp server\n\n* build the basic mcp server\n\n* build the basic mcp server\n\n* build the basic mcp server\n\n* build the basic mcp server\n\n* build the basic mcp server\n\n* build the basic mcp server\n\n* Update RemoteSubscribeInstance.java\n\n* Update McpSinkHandlerRetryWrapper.java\n\n* Update CommonMcpSinkHandler.java\n\n* Update McpSinkConnector.java\n\n* Update McpSinkHandler.java\n\n* Update McpExportRecord.java\n\n* Update McpConnectRecord.java\n\n* Update McpExportRecordPage.java\n\n* Update McpExportMetadata.java\n\n* Update McpSourceConnector.java\n\n* Update McpToolRegistry.java\n\n* Update McpServerConfig.java\n\n* Update Protocol.java\n\n* Update McpSourceConnector.java\n\n* Update McpSourceConstants.java\n\n* Update McpStandardProtocol.java\n\n* Update McpRequest.java\n\n* Update McpResponse.java\n\n* Update McpSinkHandlerRetryWrapper.java\n\n* Update AbstractMcpSinkHandler.java\n\n---------\n\nCo-authored-by: youyun.0601 \u003cyouyun.0601@bytedance.com\u003e\nCo-authored-by: wqliang \u003cwqliang@users.noreply.github.com\u003e"
    },
    {
      "commit": "436ce787003be601703dc04e4738abd6099c7d03",
      "tree": "eb055393201e9fbb21b90e156d127835a2ab836a",
      "parents": [
        "bebce5311924a8ba7805ca181d151156b55276e6"
      ],
      "author": {
        "name": "mike_xwm",
        "email": "mike_xwm@126.com",
        "time": "Fri May 09 14:20:47 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri May 09 14:20:47 2025 +0800"
      },
      "message": "update eventmesh architecture (#5200)\n\n"
    },
    {
      "commit": "bebce5311924a8ba7805ca181d151156b55276e6",
      "tree": "2e10dc7485d4f62bb1c7f37758fe83e6202975f5",
      "parents": [
        "0c0f30eb5f4079139dbf44fed903697f152c31ee"
      ],
      "author": {
        "name": "mike_xwm",
        "email": "mike_xwm@126.com",
        "time": "Thu May 08 14:35:06 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu May 08 14:35:06 2025 +0800"
      },
      "message": "update EventMesh architecture (#5199)\n\n"
    },
    {
      "commit": "0c0f30eb5f4079139dbf44fed903697f152c31ee",
      "tree": "a5462aacac0dffe78380b907626fc7fd4a34892c",
      "parents": [
        "635f038ad0279ef4a03b6a0c3cd171cda92b0213"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Wed Apr 30 16:39:16 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Apr 30 16:39:16 2025 +0800"
      },
      "message": "Update README.md (#5198)\n\n"
    },
    {
      "commit": "635f038ad0279ef4a03b6a0c3cd171cda92b0213",
      "tree": "fcadd0a08c8086dea0a732b17ce07aab6ec3e19f",
      "parents": [
        "527ce132da41e7d84506f29113860f46022d00e4"
      ],
      "author": {
        "name": "Wangzy",
        "email": "wangziyuan455@Gmail.com",
        "time": "Mon Apr 28 14:12:57 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Apr 28 14:12:57 2025 +0800"
      },
      "message": "[ISSUE #4642] unit test for FileSinkConnectorTest.java (#5197)\n\n* feat: unit test for FileSinkConnectorTest.java\n\n* feat: unit test for FileSinkConnectorTest.java\n\n* feat: add License\n\n* feat: fix codestyle\n\n* feat: fix codestyle"
    },
    {
      "commit": "527ce132da41e7d84506f29113860f46022d00e4",
      "tree": "59d232b3b6007df63b5650b4ab1eb173bfbf9ca5",
      "parents": [
        "8237eca756e853fb90858503f6415ccacd0ec781"
      ],
      "author": {
        "name": "mike_xwm",
        "email": "mike_xwm@126.com",
        "time": "Tue Mar 18 16:01:47 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Mar 18 16:01:47 2025 +0800"
      },
      "message": "[ISSUE #5185] Enhancement for http server and tcp server (#5187)\n\n"
    },
    {
      "commit": "8237eca756e853fb90858503f6415ccacd0ec781",
      "tree": "864bde10678858fc9966315876f8ad6949945191",
      "parents": [
        "e8fdcd3c00b40e3d04ff80225083014e4149f4c7"
      ],
      "author": {
        "name": "Zaki",
        "email": "cnzakii@gmail.com",
        "time": "Fri Mar 07 16:47:14 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Mar 07 16:47:14 2025 +0800"
      },
      "message": "[ISSUE#5177] Incorrect attribute assignment in BROADCAST strategy of AbstractHttpSinkHandler (#5179)\n\n"
    },
    {
      "commit": "e8fdcd3c00b40e3d04ff80225083014e4149f4c7",
      "tree": "058ed9d7a56a366d65464e5e81169db62216bf6e",
      "parents": [
        "6890b5812948c20fb3eddf2c5bf31fc49f219412"
      ],
      "author": {
        "name": "Clay Johnson",
        "email": "cjohnson@gradle.com",
        "time": "Tue Jan 21 05:11:03 2025 -0600"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jan 21 19:11:03 2025 +0800"
      },
      "message": "Publish build scans to develocity.apache.org (#5165)\n\n* Publish build scans to develocity.apache.org\r\n* Update Develocity plugin versions\r\n* Add a projectId\r\n* Use `DEVELOCITY_ACCESS_KEY` to authenticate to `develocity.apache.org`"
    },
    {
      "commit": "6890b5812948c20fb3eddf2c5bf31fc49f219412",
      "tree": "459ef950ac1b3375dca61c5fdcb6ead8e5d9d025",
      "parents": [
        "3ca1700d1336d41bd4fb1a3cf5378f98749a4e64"
      ],
      "author": {
        "name": "mike_xwm",
        "email": "mike_xwm@126.com",
        "time": "Fri Jan 10 14:30:19 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Jan 10 14:30:19 2025 +0800"
      },
      "message": "[ISSUE #5162] Remove and replace sensitive information involved in code (#5163)\n\n"
    },
    {
      "commit": "3ca1700d1336d41bd4fb1a3cf5378f98749a4e64",
      "tree": "b37cedc473226f623b9d214dac15a613746405e5",
      "parents": [
        "36a01ce78692c22bb53f6b083d8801d53dc70732"
      ],
      "author": {
        "name": "Pil0tXia",
        "email": "xiatian@apache.org",
        "time": "Tue Jan 07 10:10:45 2025 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Jan 07 10:10:45 2025 +0800"
      },
      "message": "[ISSUE #4825] Deprecate Webhook function of EventMesh Runtime(v1) (#5153)\n\n"
    },
    {
      "commit": "36a01ce78692c22bb53f6b083d8801d53dc70732",
      "tree": "fbc448980337abe08533020e1aff61d37cbfd16e",
      "parents": [
        "a961e6cc88f848a1ce89a790d379deae5e7a441a"
      ],
      "author": {
        "name": "mike_xwm",
        "email": "mike_xwm@126.com",
        "time": "Mon Dec 30 14:21:31 2024 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Dec 30 14:21:31 2024 +0800"
      },
      "message": "Update gradle.properties (#5152)\n\n"
    },
    {
      "commit": "a961e6cc88f848a1ce89a790d379deae5e7a441a",
      "tree": "65b557ce787627712127ae5c1da48db6b7a5ce26",
      "parents": [
        "63f38a897d0be5f23b03373dd874cd3b6d49ee6b"
      ],
      "author": {
        "name": "Oleg",
        "email": "142805497+devactivity-team@users.noreply.github.com",
        "time": "Fri Dec 20 18:55:29 2024 +0200"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Fri Dec 20 22:25:29 2024 +0530"
      },
      "message": "Update README.md (#5024)\n\n"
    },
    {
      "commit": "63f38a897d0be5f23b03373dd874cd3b6d49ee6b",
      "tree": "c811810e7ec3ebe3be6866b3d596bbef1a6f0ea7",
      "parents": [
        "72be53217da5442569173c7a1b458e8e66a0b30b"
      ],
      "author": {
        "name": "mike_xwm",
        "email": "mike_xwm@126.com",
        "time": "Thu Dec 19 21:28:52 2024 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Dec 19 18:58:52 2024 +0530"
      },
      "message": "Update LICENSE \u0026 NOTICE files (#5150)\n\n"
    },
    {
      "commit": "72be53217da5442569173c7a1b458e8e66a0b30b",
      "tree": "b2539ea593cca9d9b9b5f274b747536a18a9e831",
      "parents": [
        "d2e319126763ab12fdfb8adb1132133c97bc1c1e"
      ],
      "author": {
        "name": "Eason Chen",
        "email": "qqeasonchen@gmail.com",
        "time": "Thu Dec 19 17:53:55 2024 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Dec 19 17:53:55 2024 +0800"
      },
      "message": "Update cncf landscape link in README.md (#5149)\n\n* Update cncf landscape link in README.md\r\n\r\n* Update README.md"
    },
    {
      "commit": "d2e319126763ab12fdfb8adb1132133c97bc1c1e",
      "tree": "683ef0dd5fdfa8b128a89efc50df5d91679cd63f",
      "parents": [
        "658d10eb61982585f996f473ab2ed47947b76425"
      ],
      "author": {
        "name": "Karson",
        "email": "karsontao@hotmail.com",
        "time": "Tue Dec 17 17:39:32 2024 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Dec 17 17:39:32 2024 +0800"
      },
      "message": "Hessian Serializer add whitelist (#5146)\n\n"
    },
    {
      "commit": "658d10eb61982585f996f473ab2ed47947b76425",
      "tree": "538f62f8da208d62ac50ce6d52ed0a3149351711",
      "parents": [
        "db75b4768157db4ccab32225225997b49954f0d5"
      ],
      "author": {
        "name": "mike_xwm",
        "email": "mike_xwm@126.com",
        "time": "Wed Dec 11 22:14:59 2024 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Dec 11 22:14:59 2024 +0800"
      },
      "message": "[ISSUE #5144] update eventmesh-connector-http module (#5145)\n\n* [ISSUE #5137] update connector runtime v2 module\r\n\r\n* fix checkStyle error\r\n\r\n* [ISSUE #5139] update canal connector module\r\n\r\n* [ISSUE #5141] update eventmesh-admin-server module\r\n\r\n* [ISSUE #5144] update eventmesh-connector-http module"
    },
    {
      "commit": "db75b4768157db4ccab32225225997b49954f0d5",
      "tree": "3260c852aa77129d8cb19eff1c33a8916336dc97",
      "parents": [
        "06b04e240a7150723f97e16ff7f8153b37620c2b"
      ],
      "author": {
        "name": "mike_xwm",
        "email": "mike_xwm@126.com",
        "time": "Wed Dec 11 11:38:56 2024 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Wed Dec 11 11:38:56 2024 +0800"
      },
      "message": "[ISSUE #5141] update eventmesh-admin-server module (#5143)\n\n* [ISSUE #5137] update connector runtime v2 module\r\n\r\n* fix checkStyle error\r\n\r\n* [ISSUE #5139] update canal connector module\r\n\r\n* [ISSUE #5141] update eventmesh-admin-server module"
    },
    {
      "commit": "06b04e240a7150723f97e16ff7f8153b37620c2b",
      "tree": "8c07963a82a2bcbf0d26cd829968e29dea4eebf6",
      "parents": [
        "973e87c0a444ca6e06c2bab156419a2dfac8bd38"
      ],
      "author": {
        "name": "mike_xwm",
        "email": "mike_xwm@126.com",
        "time": "Tue Dec 10 19:19:13 2024 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Tue Dec 10 19:19:13 2024 +0800"
      },
      "message": "[ISSUE #5141] update eventmesh-admin-server module  (#5142)\n\n* [ISSUE #5137] update connector runtime v2 module\r\n\r\n* fix checkStyle error\r\n\r\n* [ISSUE #5139] update canal connector module"
    },
    {
      "commit": "973e87c0a444ca6e06c2bab156419a2dfac8bd38",
      "tree": "8c07963a82a2bcbf0d26cd829968e29dea4eebf6",
      "parents": [
        "cc50db558ff8e43f3983575f28321ad5ce0a35ab"
      ],
      "author": {
        "name": "mike_xwm",
        "email": "mike_xwm@126.com",
        "time": "Mon Dec 09 17:51:38 2024 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Dec 09 17:51:38 2024 +0800"
      },
      "message": "[ISSUE #5139] update canal connector module  (#5140)\n\n* [ISSUE #5137] update connector runtime v2 module\r\n\r\n* fix checkStyle error\r\n\r\n* [ISSUE #5139] update canal connector module"
    },
    {
      "commit": "cc50db558ff8e43f3983575f28321ad5ce0a35ab",
      "tree": "8867ce89d90afc0bc69f479033a1592f0c7c0715",
      "parents": [
        "cf1c07f386d39c02da0c85d328ba6446c03df41e"
      ],
      "author": {
        "name": "mike_xwm",
        "email": "mike_xwm@126.com",
        "time": "Mon Dec 09 15:12:32 2024 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Dec 09 15:12:32 2024 +0800"
      },
      "message": "[ISSUE #5137] update connector runtime v2 module  (#5138)\n\n* [ISSUE #5137] update connector runtime v2 module\r\n\r\n* fix checkStyle error"
    },
    {
      "commit": "cf1c07f386d39c02da0c85d328ba6446c03df41e",
      "tree": "9ddde46088136f30cf75346cd50dee48d7085758",
      "parents": [
        "7165eff7d26b2b225c2040c22a94825c684c2782"
      ],
      "author": {
        "name": "Jevin Jiang",
        "email": "40829263+jevinjiang@users.noreply.github.com",
        "time": "Thu Dec 05 22:20:12 2024 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Thu Dec 05 22:20:12 2024 +0800"
      },
      "message": "[ISSUE #5127] fix create topic error in Standalone mode (#5128)\n\n* [ISSUE #5127] fix\r\n\r\n* [ISSUE #5127] fix\r\n\r\n* [ISSUE #5127] fix\r\n\r\n* [ISSUE #5127] fix\r\n\r\n* [ISSUE #5127] fix checkstyle test\r\n\r\n---------\r\n\r\nCo-authored-by: JiangShuJu \u003cshuju.jiang@baozun.com\u003e"
    },
    {
      "commit": "7165eff7d26b2b225c2040c22a94825c684c2782",
      "tree": "bf9467c8146f49a3598b16d7527562d7b5aa0e9d",
      "parents": [
        "734e3e71ef477b2340c5bc31ee441b9f880d6057"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Mon Dec 02 15:48:29 2024 +0530"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Dec 02 15:48:29 2024 +0530"
      },
      "message": "Bump org.apache.kafka:kafka-clients from 3.8.1 to 3.9.0 (#5131)\n\nBumps org.apache.kafka:kafka-clients from 3.8.1 to 3.9.0.\r\n\r\n---\r\nupdated-dependencies:\r\n- dependency-name: org.apache.kafka:kafka-clients\r\n  dependency-type: direct:production\r\n  update-type: version-update:semver-minor\r\n...\r\n\r\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\r\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "734e3e71ef477b2340c5bc31ee441b9f880d6057",
      "tree": "11c8cc496d8a97517a50321000aa44d4d6585216",
      "parents": [
        "d6daaec01ed4abb9afcd2f8b8c800f2485089518"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Sun Dec 01 20:26:58 2024 +0530"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Dec 01 20:26:58 2024 +0530"
      },
      "message": "Bump commons-io:commons-io from 2.17.0 to 2.18.0 (#5133)\n\nBumps commons-io:commons-io from 2.17.0 to 2.18.0.\r\n\r\n---\r\nupdated-dependencies:\r\n- dependency-name: commons-io:commons-io\r\n  dependency-type: direct:production\r\n  update-type: version-update:semver-minor\r\n...\r\n\r\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\r\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "d6daaec01ed4abb9afcd2f8b8c800f2485089518",
      "tree": "000f06e70291837f35c57f9d1a9d313a8ff9a264",
      "parents": [
        "871b3aba5f8eecef97e22689188718bdbad03492"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Mon Nov 04 00:02:45 2024 +0530"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Nov 04 00:02:45 2024 +0530"
      },
      "message": "Bump org.apache.kafka:kafka-clients from 3.7.1 to 3.8.1 (#5123)\n\nBumps org.apache.kafka:kafka-clients from 3.7.1 to 3.8.1.\r\n\r\n---\r\nupdated-dependencies:\r\n- dependency-name: org.apache.kafka:kafka-clients\r\n  dependency-type: direct:production\r\n  update-type: version-update:semver-minor\r\n...\r\n\r\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\r\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "871b3aba5f8eecef97e22689188718bdbad03492",
      "tree": "74619e15101a002ba26c40428e036ba43de0e923",
      "parents": [
        "6e6de87f29ee962c651cde273045585e33189e4e"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Sun Nov 03 00:01:16 2024 +0530"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sun Nov 03 00:01:16 2024 +0530"
      },
      "message": "Bump org.redisson:redisson from 3.36.0 to 3.38.1 (#5124)\n\nBumps [org.redisson:redisson](https://github.com/redisson/redisson) from 3.36.0 to 3.38.1.\r\n- [Release notes](https://github.com/redisson/redisson/releases)\r\n- [Changelog](https://github.com/redisson/redisson/blob/master/CHANGELOG.md)\r\n- [Commits](https://github.com/redisson/redisson/compare/redisson-3.36.0...redisson-3.38.1)\r\n\r\n---\r\nupdated-dependencies:\r\n- dependency-name: org.redisson:redisson\r\n  dependency-type: direct:production\r\n  update-type: version-update:semver-minor\r\n...\r\n\r\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\r\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "6e6de87f29ee962c651cde273045585e33189e4e",
      "tree": "4935e7170ed90ff6e90da206eaa6e6b9b684279d",
      "parents": [
        "1fa059b4efca391bfbaeadcbd697d39a8859cf90"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Sat Nov 02 23:47:47 2024 +0530"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Nov 02 23:47:47 2024 +0530"
      },
      "message": "Bump com.zendesk:mysql-binlog-connector-java from 0.29.2 to 0.30.1 (#5125)\n\nBumps [com.zendesk:mysql-binlog-connector-java](https://github.com/osheroff/mysql-binlog-connector-java) from 0.29.2 to 0.30.1.\r\n- [Changelog](https://github.com/osheroff/mysql-binlog-connector-java/blob/master/CHANGELOG.md)\r\n- [Commits](https://github.com/osheroff/mysql-binlog-connector-java/commits)\r\n\r\n---\r\nupdated-dependencies:\r\n- dependency-name: com.zendesk:mysql-binlog-connector-java\r\n  dependency-type: direct:production\r\n  update-type: version-update:semver-minor\r\n...\r\n\r\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\r\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "1fa059b4efca391bfbaeadcbd697d39a8859cf90",
      "tree": "02e7ba8863f9090158bf6de1e06a418087496094",
      "parents": [
        "f0a293179545b05a9654fe7355fc567ec30e440c"
      ],
      "author": {
        "name": "dependabot[bot]",
        "email": "49699333+dependabot[bot]@users.noreply.github.com",
        "time": "Sat Nov 02 15:50:48 2024 +0530"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Sat Nov 02 15:50:48 2024 +0530"
      },
      "message": "Bump software.amazon.awssdk:s3 from 2.28.12 to 2.29.5 (#5126)\n\nBumps software.amazon.awssdk:s3 from 2.28.12 to 2.29.5.\r\n\r\n---\r\nupdated-dependencies:\r\n- dependency-name: software.amazon.awssdk:s3\r\n  dependency-type: direct:production\r\n  update-type: version-update:semver-minor\r\n...\r\n\r\nSigned-off-by: dependabot[bot] \u003csupport@github.com\u003e\r\nCo-authored-by: dependabot[bot] \u003c49699333+dependabot[bot]@users.noreply.github.com\u003e"
    },
    {
      "commit": "f0a293179545b05a9654fe7355fc567ec30e440c",
      "tree": "cb6f5b2b6db8ab9b6dfd3321f7b76e2ee84ddd5b",
      "parents": [
        "de9f4e4f3d09a4cb98b98411ab527bc9936bd451"
      ],
      "author": {
        "name": "Zaki",
        "email": "cnzakii@gmail.com",
        "time": "Mon Oct 28 19:08:59 2024 +0800"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 28 19:08:59 2024 +0800"
      },
      "message": "[ISSUE #5101] Define and standardize some common configurations for all Sources(#5102)\n\n"
    },
    {
      "commit": "de9f4e4f3d09a4cb98b98411ab527bc9936bd451",
      "tree": "4702ecee734a3950b699c0c5f668d53dc5d2a95b",
      "parents": [
        "551610d9c320f98dbe414e80b639e51c514efca2"
      ],
      "author": {
        "name": "Melis Ölmez",
        "email": "77929541+melisolmez@users.noreply.github.com",
        "time": "Mon Oct 28 06:58:37 2024 +0300"
      },
      "committer": {
        "name": "GitHub",
        "email": "noreply@github.com",
        "time": "Mon Oct 28 11:58:37 2024 +0800"
      },
      "message": "[ISSUE #4991] add unit test for LogUtil (#5100)\n\n"
    }
  ],
  "next": "551610d9c320f98dbe414e80b639e51c514efca2"
}
