fix(examples): pin poms to published 9.0.0; fail loud on tenant mismatch [skip-runtime-e2e] - #196
Conversation
Release-gate smoke against a live enterprise stack (v9.6.1, epic #2861)
surfaced two example-level issues:
- Example poms pinned stale SDK versions (basic at 6.1.0, the rest at
8.5.0), so smoke runs resolved remote Maven artifacts instead of the
locally built 8.5.1 under test. Pin all four to 8.5.1.
- basic swallowed a 403 tenant-mismatch rejection as a policy block and
exited 0: the agent's error body carries a literal "blocked":false
key, which trips the SDK's handleErrorResponse body.contains("blocked")
heuristic and misclassifies the 403 as PolicyViolationException. Until
the library fix ships, the example treats a Tenant mismatch message as
the auth failure it is and exits 1 with a pointer to the
AXONFLOW_CLIENT_ID/user-token tenant pairing requirement.
Verified against the live stack: all four examples exit 0 with real
LLM round-trips, and basic exits 1 on a deliberately mismatched
client-id/token pairing.
Signed-off-by: Saurabh Jain <saurabh.jain@getaxonflow.com>
No-diff commit: the DoD workflow only runs on opened/synchronize/reopened, so the [skip-runtime-e2e] title + justification body edit needs a fresh synchronize event to be evaluated against the updated payload. Signed-off-by: Saurabh Jain <saurabh.jain@getaxonflow.com>
8.5.1 went stale mid-flight: Maven Central now serves 9.0.0
(released 2026-07-18, com.getaxonflow:axonflow-sdk latest/release).
The 9.0.0 breaking change is confined to the LangGraph MCP adapter
(connector_type/tool split), which none of the four examples touch;
all four build clean against the published 9.0.0 artifact from a
fresh local repository.
The Basic.java comment is updated to 'SDK <= 9.0.0': the 403
body.contains("blocked") misclassification is still present in the
published 9.0.0 (verified in the v9.0.0 tag and reproduced against
the published jar), so the tenant-mismatch fail-loud workaround
remains required until the library fix (#197) ships.
Signed-off-by: Saurabh Jain <saurabh.jain@getaxonflow.com>
|
Backlog-clearance verification (head a60dede): Pin refresh 8.5.1 -> 9.0.0. Maven Central serves Fail-loud-on-tenant-mismatch hostile-read, proven discriminating against a stub agent emitting the exact v9.13.0 wire shapes (
CI: all 15 checks green on a60dede (build/package, Contract Integration WireMock, real-stack ubuntu/macos/windows, CodeQL, lint, no-mocks lint, Runtime E2E presence gate, DCO): https://github.com/getaxonflow/axonflow-sdk-java/actions/runs/30836424042 https://github.com/getaxonflow/axonflow-sdk-java/actions/runs/30836423592 Merging per backlog-clearance brief. |
Follow-up to #194 (merged mid-smoke) from the release-readiness gate for getaxonflow/axonflow-enterprise#2861 - Java SDK examples smoke-tested against a live enterprise stack (platform v9.6.1), pins since refreshed to the current published artifact.
What
basicpinned 6.1.0 and the other three pinned 8.5.0, so smoke runs resolved stale remote Maven artifacts. Originally pinned to 8.5.1; refreshed in-flight because Maven Central now serves 9.0.0 (released 2026-07-18,com.getaxonflow:axonflow-sdklatest = release = 9.0.0). The 9.0.0 breaking change is confined to the LangGraph MCP adapter (connector_type/toolsplit), which none of the four examples touch; all four build clean against the published 9.0.0 jar resolved from Central into a fresh local repository.basic: fail loud on tenant-mismatch 403. The agent's 403 error body carries a literal"blocked":falsekey (ClientResponse.Blockedhas noomitempty, verified at platform v9.13.0), which trips the SDK'shandleErrorResponsebody.contains("blocked")heuristic and misclassifies the auth rejection asPolicyViolationException- the example then printedBlocked by policy: Tenant mismatchand exited 0 (same swallowed-auth class fix(examples): basic reads AXONFLOW_USER_TOKEN; async parity e2e #194 fixed for 401s). The heuristic is still present in the published 9.0.0 (checked in the v9.0.0 tag and reproduced against the published jar), so until the library fix (fix(errors): 403 auth rejections no longer read as policy blocks #197) ships, the example treats aTenant mismatchmessage as an auth failure and exits 1 with a pointer to the client-id/user-token tenant pairing requirement.Library follow-up (not in this PR - examples-only)
AxonFlow.handleErrorResponseshould only map a 403 toPolicyViolationExceptionwhen the body actually signals a block (e.g."blocked":true), not on a bareblockedsubstring that matches every error envelope. Tracked as #197.Testing
Original round (live enterprise stack, platform v9.6.1): all four examples (
basic,explain-decision,list-decisions,wcp-retry-idempotency) exit 0 with meaningful output under the stack's canonical tenant identity, including a real LLM round-trip, a stacked-SQLisys_sqli_stacked_dropblock explained end-to-end, and the full WCP retry/idempotency assertion suite. Negative test:basicrun with a client id that does not match the user token's tenant exits 1 withproxyLLMCall failed (auth): ... Tenant mismatch.9.0.0 refresh round (published artifact from Maven Central, fresh local repo, stub agent emitting the exact v9.13.0
sendErrorResponse/ClientResponsewire shapes):mvn packageclean against the published 9.0.0 jar.{"success":false,"error":"Tenant mismatch","blocked":false}->basicexits 1 withproxyLLMCall failed (auth): ...(and the exception observed isPolicyViolationException, proving published 9.0.0 still misclassifies).{"success":false,"error":"Blocked by policy: sys_sqli_stacked_drop","blocked":true}-> printsBlocked by policy: ..., continues, exits 0.Blocked by policy: ... Tenant mismatchand exits 0 - the exact swallowed-auth failure this PR pins. Hunk restored after the run.Skip-runtime-e2e justification
Examples-only change - no
src/mainlibrary code or SDK runtime surface is touched (4 example pom version pins + one example error-handling branch). The examples themselves were exercised end-to-end against a live enterprise stack (platform v9.6.1) plus the stub-agent discrimination/control/mutation runs above against the published 9.0.0 artifact. The SDK surface these examples call is already covered by runtime-e2e (incl. the async verdict-parity leg added in #194).