[skip-runtime-e2e] ci(definition-of-done): mechanical gate enforcing HARD RULE #0#181
Merged
saurabhjain1592 merged 2 commits intomainfrom May 5, 2026
Merged
Conversation
…HARD RULE #0
Add the same definition-of-done gate that just landed in the four plugin
repos (axonflow-claude-plugin#59 pilot, axonflow-openclaw-plugin#101,
axonflow-cursor-plugin#48, axonflow-codex-plugin#48) — adapted for the
Python SDK's user-facing surface.
What this PR adds:
- scripts/lint-no-mocks-in-runtime-e2e.sh — copied verbatim from the
pilot. Greps runtime-e2e/ for forbidden mock-pattern strings
(unittest.mock, MagicMock, httpx_mock.add_response, jest.fn, sinon,
wiremock, httptest.NewServer, msw, nock, capture-stub harnesses, etc.)
and fails the build if any are found. Inline `allow-mocks-here:`
marker available for the rare doc/comment that legitimately mentions
the patterns by name.
- .github/workflows/definition-of-done.yml — runs the lint, then on PRs
detects whether the diff touches the SDK's user-facing surface
(axonflow/, pyproject.toml, examples/) and requires a runtime-e2e/
test in the same PR. Escape hatch: `[skip-runtime-e2e]` in PR title
+ `## Skip-runtime-e2e justification` section in PR body.
- runtime-e2e/README.md — convention doc + local-run instructions
(register a tenant against a live agent, export creds, run each
test.py).
- runtime-e2e/x-axonflow-client/test.py — first runtime test, derived
from the live driver used in this week's X-Axonflow-Client E2E
(proves the SDK stamps `X-Axonflow-Client: sdk-python/<__version__>`
on every governed request, by forcing the scope-mismatch path so the
agent echoes the value back).
- pyproject.toml — adds a per-file-ignores stanza for runtime-e2e/**/*.py
matching the existing tests/heartbeat-real-stack/** carve-out: these
are real-stack driver scripts, not pytest tests, and the same lint
exemptions apply (print as report channel, blind except for whatever
the SDK wraps, monkey-patch on httpx.AsyncClient.request to inject
the scope-mismatch header).
Why now (CLAUDE.md HARD RULE #0):
The 2026-05-05 X-Axonflow-Client incident landed mocks-only evidence at
PR-merge time on a feature whose runtime was silently broken. The new
top-level HARD RULE in CLAUDE.md states that a user-facing feature is
not done until demonstrated through its actual runtime. This PR is the
mechanical enforcement layer for the Python SDK.
Local validation:
python3 -c "import yaml; yaml.safe_load(open('.github/workflows/definition-of-done.yml'))" # ok
./scripts/lint-no-mocks-in-runtime-e2e.sh # clean
python3 -m ruff check . # clean
python3 -m ruff format --check . # clean
## Skip-runtime-e2e justification
This PR's only "user-facing" change is a comment-only stanza in
pyproject.toml that adds per-file-ignores for runtime-e2e/. There is no
SDK behavior change, no new public API, no examples touched. The
runtime-e2e/x-axonflow-client/ test that already shipped to the four
plugin repos exists here and will run against a real stack the next
time a build pipeline brings one up. The skip-runtime-e2e escape hatch
exists exactly for changes like this — pure CI plumbing where there's
no runtime to demonstrate.
Refs:
- axonflow-claude-plugin#59 (pilot)
- CLAUDE.md HARD RULE #0
Signed-off-by: Saurabh Jain <saurabhjain1592@gmail.com>
…doesn't flag a secret-name f-string CodeQL py/clear-text-logging-sensitive-data flagged line 27 because the f-string interpolation included variable names like AXONFLOW_TENANT_SECRET / AXONFLOW_E2E_PLUGIN_TOKEN. The print only outputs the NAME, never the value, but CodeQL's heuristic flags the pattern. Refactor to a static stderr message with the missing-list collected separately. Signed-off-by: Saurabh Jain <saurabhjain1592@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds the same mechanical definition-of-done gate that just landed in the four plugin repos (pilot: getaxonflow/axonflow-claude-plugin#59; replicas: getaxonflow/axonflow-openclaw-plugin#101, getaxonflow/axonflow-cursor-plugin#48, getaxonflow/axonflow-codex-plugin#48) — adapted for the Python SDK's user-facing surface.
Five additions:
scripts/lint-no-mocks-in-runtime-e2e.sh— copied verbatim from the pilot. Grepsruntime-e2e/for forbidden mock-pattern strings (unittest.mock,MagicMock,httpx_mock.add_response,jest.fn,sinon.stub,wiremock,httptest.NewServer,msw.setupServer,nock., capture-stub harnesses) and fails the build if any are found. Inlineallow-mocks-here:marker is available for the rare README/comment that legitimately names the patterns..github/workflows/definition-of-done.yml— runs the lint, then on every PR diffs against base and requires aruntime-e2e/test alongside any change that touches the SDK's user-facing surface (axonflow/,pyproject.toml,examples/). Escape hatch:[skip-runtime-e2e]in title +## Skip-runtime-e2e justificationsection in body.runtime-e2e/README.md— convention doc and local-run instructions (register a tenant via/api/v1/register, exportAXONFLOW_TENANT_ID+AXONFLOW_TENANT_SECRET, then loop overruntime-e2e/*/test.py).runtime-e2e/x-axonflow-client/test.py— first runtime test, derived from this week's livesdk_py_real.pydriver. Asserts the SDK stampsX-Axonflow-Client: sdk-python/<__version__>on every governed request, by forcing the scope-mismatch path so the agent echoes the header value back in its rejection response.pyproject.toml— adds aruntime-e2e/**/*.pyper-file-ignores stanza, modeled on the existingtests/heartbeat-real-stack/**carve-out. Same justification: real-stack driver scripts, not pytest tests, soprintis the report channel, blind-except is appropriate when inspecting whatever the SDK wraps, and monkey-patchinghttpx.AsyncClient.requestis the documented way to force the scope-mismatch path.Why now
CLAUDE.md HARD RULE #0 (added after the 2026-05-05 X-Axonflow-Client incident, where mocks-only PR evidence masked a feature whose runtime was silently broken): a user-facing feature is not done until demonstrated through its actual runtime — for the Python SDK that means a real
from axonflow import AxonFlowover realhttpxagainst a real running AxonFlow agent. This PR is the mechanical enforcement layer.Skip-runtime-e2e justification
This PR's only "user-facing" change is a comment-only stanza in
pyproject.tomlthat adds per-file-ignores forruntime-e2e/. There is no SDK behavior change, no new public API, no examples touched. Theruntime-e2e/x-axonflow-client/test that already shipped against a live stack across the four plugin repos exists here and will run the next time a build pipeline brings up an agent. The escape hatch exists exactly for changes like this — pure CI plumbing where there's no runtime to demonstrate.Test plan
python3 -c "import yaml; yaml.safe_load(open('.github/workflows/definition-of-done.yml'))"— clean./scripts/lint-no-mocks-in-runtime-e2e.sh— clean (runtime-e2e is clean)python3 -m ruff check .— All checks passedpython3 -m ruff format --check .— cleanRefs