Skip to content

chore(ci): add definition-of-done gate + runtime-e2e seed [skip-runtime-e2e]#162

Merged
saurabhjain1592 merged 1 commit intomainfrom
chore/definition-of-done-gate
May 5, 2026
Merged

chore(ci): add definition-of-done gate + runtime-e2e seed [skip-runtime-e2e]#162
saurabhjain1592 merged 1 commit intomainfrom
chore/definition-of-done-gate

Conversation

@saurabhjain1592
Copy link
Copy Markdown
Member

Summary

Mechanical enforcement of CLAUDE.md HARD RULE #0: a user-facing feature is not done until it has been demonstrated through its actual runtime. Mirrors the equivalent gates already merged in:

  • axonflow-claude-plugin#59
  • axonflow-cursor-plugin#48
  • axonflow-codex-plugin#48
  • axonflow-openclaw-plugin#101

What this PR lands

  1. .github/workflows/definition-of-done.yml — runs on every PR. If the PR diff touches src/main/java/, pom.xml, or examples/ (the SDK's published surface) but does NOT add or update anything under runtime-e2e/, the gate fails. Escape hatch: put [skip-runtime-e2e] in the PR title AND a ## Skip-runtime-e2e justification section in the body.

  2. scripts/lint-no-mocks-in-runtime-e2e.sh — verbatim copy of the script from the plugin repos. Greps runtime-e2e/ for forbidden stub/mock patterns (WireMock builder, MockWebServer-style stubs, Mockito stubFor, httptest.NewServer, MagicMock, etc.) and fails CI on any hit. Per-line escape hatch via # allow-mocks-here: exists for genuine edge cases — reviewer must approve.

  3. runtime-e2e/ — seeded with one feature folder, x-axonflow-client/, ported from /tmp/axonflow-e2e/SdkJavaProof.java (May 4 2026 wire-shape session). The test constructs a real AxonFlow client via the public builder, calls mcpCheckInput against a real running agent, and asserts the agent's scope_mismatch error echoes the SDK's own X-Axonflow-Client: sdk-java/<SDK_VERSION> header — proving the header crossed the wire.

Why a logging proxy?

sdk-java does not currently expose a public per-request header hook (same constraint as sdk-go). Tests that need to assert a particular X-License-Token reaches the agent must chain through a tiny local logging proxy that injects the token before forwarding. This is documented in both READMEs. A future PR can add a public requestInterceptor and let the test skip the proxy; that is tracked separately.

Validation done locally

  • python3 -c "import yaml; yaml.safe_load(open('.github/workflows/definition-of-done.yml'))" — clean.
  • ./scripts/lint-no-mocks-in-runtime-e2e.sh — clean (no forbidden patterns in seeded files; mention of WireMock/MockWebServer in prose carefully avoided so as not to self-trigger the lint).
  • Seed SdkClientHeaderTest.java is a java-single-file script (not a Maven test source); it is intentionally not under src/test/java/ and is not compiled by mvn.

Skip-runtime-e2e justification

This PR adds the runtime-e2e/ infrastructure itself; it does not change src/main/java/, pom.xml, or examples/. The detector would never fire on this PR (no user-facing SDK code changed), but the [skip-runtime-e2e] marker is included as the formal acknowledgement that the seed test file under runtime-e2e/x-axonflow-client/ is fixture of the gate, not a new SDK capability under verification. From the next PR onward, any SDK-surface change must update or add a real runtime-e2e/<feature>/ test or carry its own justification.

Test plan

  • CI on this PR is green: Lint — no mocks in runtime-e2e/ and Runtime E2E required for user-facing changes both pass.
  • Open a follow-up trial PR that tweaks src/main/java/com/getaxonflow/sdk/AxonFlowConfig.java without touching runtime-e2e/ and confirm the gate fires red with the expected error message.
  • Confirm the seed Java file runs successfully against a local community-saas stack with a logging proxy chain (manual smoke; not part of PR CI).

…me-e2e]

Mechanical enforcement of CLAUDE.md HARD RULE #0: a user-facing feature
is not done until it has been demonstrated through its actual runtime.
Mirrors the equivalent gates landed in axonflow-claude-plugin#59,
axonflow-cursor-plugin#48, axonflow-codex-plugin#48, and
axonflow-openclaw-plugin#101.

What this PR adds:

1. .github/workflows/definition-of-done.yml — PR-time gate. When a PR
   touches the SDK's user-facing surface (src/main/java/, pom.xml,
   examples/) but does NOT update runtime-e2e/, the workflow fails
   unless the PR carries `[skip-runtime-e2e]` in the title AND a
   `## Skip-runtime-e2e justification` section in the body. Also runs
   the lint-no-mocks script.

2. scripts/lint-no-mocks-in-runtime-e2e.sh — copied verbatim from the
   plugin repos. Greps runtime-e2e/ for forbidden mock-pattern strings
   (WireMock builder, MockWebServer-style stubs, Mockito stubFor, etc.)
   and fails the build if any are present. Per-line escape hatch via
   `# allow-mocks-here:` is supported but discouraged.

3. runtime-e2e/ — seeded with the x-axonflow-client wire-assertion
   feature folder, ported from /tmp/axonflow-e2e/SdkJavaProof.java
   (the May 4 2026 wire-shape session). The test constructs a real
   AxonFlow client through the public builder, calls mcpCheckInput
   against a real running agent, and asserts the agent's
   scope_mismatch error message echoes the SDK's own
   X-Axonflow-Client header value (sdk-java/<SDK_VERSION>) — proving
   the header travelled the wire and was read by the agent.

   Documented in runtime-e2e/README.md (top-level) and
   runtime-e2e/x-axonflow-client/README.md (per-feature).

## Skip-runtime-e2e justification

This PR adds the runtime-e2e infrastructure itself; it does not change
src/main/java/, pom.xml, or examples/. Detector legitimately fires on
the seed test file (which lives under runtime-e2e/), but the workflow
condition only counts runtime-e2e/ as the user-facing-surface trigger
for SDK code paths, not its own scaffolding. The `[skip-runtime-e2e]`
marker is used here as the formal acknowledgement that no SDK feature
is being introduced in this commit — the runtime-e2e/ seed is a fixture
of the gate, not a new SDK capability.

Signed-off-by: Saurabh Jain <saurabhjain1592@gmail.com>
@saurabhjain1592 saurabhjain1592 merged commit 350b73e into main May 5, 2026
19 checks passed
@saurabhjain1592 saurabhjain1592 deleted the chore/definition-of-done-gate branch May 5, 2026 11: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