Skip to content

fix(examples): pin poms to published 9.0.0; fail loud on tenant mismatch [skip-runtime-e2e] - #196

Merged
saurabhjain1592 merged 3 commits into
mainfrom
fix/2861-example-user-token
Aug 3, 2026
Merged

fix(examples): pin poms to published 9.0.0; fail loud on tenant mismatch [skip-runtime-e2e]#196
saurabhjain1592 merged 3 commits into
mainfrom
fix/2861-example-user-token

Conversation

@saurabhjain1592

@saurabhjain1592 saurabhjain1592 commented Jul 10, 2026

Copy link
Copy Markdown
Member

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

  • Pin all four example poms to the published SDK 9.0.0. basic pinned 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-sdk latest = release = 9.0.0). 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 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":false key (ClientResponse.Blocked has no omitempty, verified at platform v9.13.0), which trips the SDK's handleErrorResponse body.contains("blocked") heuristic and misclassifies the auth rejection as PolicyViolationException - the example then printed Blocked by policy: Tenant mismatch and 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 a Tenant mismatch message 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.handleErrorResponse should only map a 403 to PolicyViolationException when the body actually signals a block (e.g. "blocked":true), not on a bare blocked substring 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-SQLi sys_sqli_stacked_drop block explained end-to-end, and the full WCP retry/idempotency assertion suite. Negative test: basic run with a client id that does not match the user token's tenant exits 1 with proxyLLMCall 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/ClientResponse wire shapes):

  • All four examples mvn package clean against the published 9.0.0 jar.
  • Discriminating run: 403 {"success":false,"error":"Tenant mismatch","blocked":false} -> basic exits 1 with proxyLLMCall failed (auth): ... (and the exception observed is PolicyViolationException, proving published 9.0.0 still misclassifies).
  • Control run: 403 {"success":false,"error":"Blocked by policy: sys_sqli_stacked_drop","blocked":true} -> prints Blocked by policy: ..., continues, exits 0.
  • Mutation run: with the fail-loud hunk reverted to the pre-PR catch block, the same tenant-mismatch response prints Blocked by policy: ... Tenant mismatch and exits 0 - the exact swallowed-auth failure this PR pins. Hunk restored after the run.

Skip-runtime-e2e justification

Examples-only change - no src/main library 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).

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>
@saurabhjain1592
saurabhjain1592 deleted the fix/2861-example-user-token branch July 10, 2026 00:13
@saurabhjain1592
saurabhjain1592 restored the fix/2861-example-user-token branch July 10, 2026 00:14
@saurabhjain1592 saurabhjain1592 changed the title fix(examples): pin poms to SDK 8.5.1; fail loud on tenant-mismatch 403 fix(examples): pin poms to 8.5.1; fail loud on tenant mismatch [skip-runtime-e2e] Jul 10, 2026
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>
@saurabhjain1592 saurabhjain1592 changed the title fix(examples): pin poms to 8.5.1; fail loud on tenant mismatch [skip-runtime-e2e] fix(examples): pin poms to published 9.0.0; fail loud on tenant mismatch [skip-runtime-e2e] Aug 3, 2026
@saurabhjain1592

Copy link
Copy Markdown
Member Author

Backlog-clearance verification (head a60dede):

Pin refresh 8.5.1 -> 9.0.0. Maven Central serves com.getaxonflow:axonflow-sdk latest = release = 9.0.0 (repo1 maven-metadata.xml, lastUpdated 2026-07-18); the 8.5.1 pin went stale mid-flight. All four example poms now pin 9.0.0. The 9.0.0 breaking change is confined to the LangGraph MCP adapter (connector_type/tool split), which none of the examples touch. All four examples mvn package clean against the published 9.0.0 jar resolved from Central into a fresh local repository (_remote.repositories confirms central provenance, ruling out a locally-built jar masking the published one).

Fail-loud-on-tenant-mismatch hostile-read, proven discriminating against a stub agent emitting the exact v9.13.0 wire shapes (sendErrorResponse + ClientResponse with non-omitempty blocked, verified in platform/agent/run.go at tag v9.13.0):

  • Mismatch run: 403 {"success":false,"error":"Tenant mismatch","blocked":false} -> basic prints proxyLLMCall failed (auth): Request blocked by policy: Tenant mismatch ... and exits 1. The exception observed is PolicyViolationException, which also proves the published 9.0.0 still carries the body.contains("blocked") misclassification (fix tracked as fix(errors): 403 auth rejections no longer read as policy blocks #197), so the workaround and the updated SDK <= 9.0.0 comment are correct.
  • Control run: 403 {"success":false,"error":"Blocked by policy: sys_sqli_stacked_drop","blocked":true} -> prints Blocked by policy: ..., continues to Step 3, exits 0. The check does not fire on genuine blocks.
  • Mutation run: with the fail-loud hunk reverted to the pre-PR catch block, the same tenant-mismatch response prints Blocked by policy: ... Tenant mismatch and exits 0 - the exact swallowed-auth failure this PR pins. Hunk restored; restored build re-verified by the mismatch run above.

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.

@saurabhjain1592
saurabhjain1592 merged commit 128b82b into main Aug 3, 2026
16 checks passed
@saurabhjain1592
saurabhjain1592 deleted the fix/2861-example-user-token branch August 3, 2026 17:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant