Skip to content

[Refactor] Refactor tests module and add enhanced citest pipeline - #29

Merged
wangxingjun778 merged 2 commits into
mainfrom
feat/core_loop
Aug 6, 2026
Merged

[Refactor] Refactor tests module and add enhanced citest pipeline#29
wangxingjun778 merged 2 commits into
mainfrom
feat/core_loop

Conversation

@wangxingjun778

Copy link
Copy Markdown
Member

No description provided.

`SessionController.recording_step_count` read `recorder.step_count`, which
does not exist: the count lives on the trajectory the recorder is filling.
Every `/teach status` issued while a recording was active raised
AttributeError instead of reporting progress.

Reads through `recorder.current_trajectory.step_count` and coerces the
result, so the property returns 0 both before a recording starts and if the
recorder has yet to open a trajectory.
Every incident in AGENTS.md shipped with a green mock suite: 1531 hermetic
cases cannot observe cross-module wiring, process boundaries, session
identity, or pushed runtime metadata, because they never cross them. This
adds the layer that can, without giving up the fast one.

Six coarse journeys (tests/journeys/) drive a real leapd subprocess over RPC
with the LLM boundary served by a local OpenAI-compatible proxy
(tests/_harness/cassette_proxy.py). A proxy rather than a patched provider:
leapd runs as a separate process, so in-process patching cannot reach it, and
addressing the boundary through LEAPFLOW_LLM_BASE_URL keeps the real SDK,
httpx stack, SSE framing and retry classification in the path.

Four modes select the lane: replay (offline default), seed (build the replay
store from a journey's script, no credential needed), record (capture real
traffic as wire-shape evidence), live (real provider, persists nothing).
Recording writes to a separate store on purpose — a multi-turn conversation
cannot be replayed from a recording, since turn n's prompt embeds the
round-by-round history of turns 1..n-1, so one divergence cascades.

CI gains three tiers. The PR and main lanes stay fully offline, which is a
requirement rather than a convenience: a fork pull request cannot read
secrets, so anything gating a merge has to run without them. Only
nightly-live.yaml reaches a provider, and it selects journeys via
tools/impact.py because there each one costs real tokens.

Cost is bounded by construction, not by trust: each journey declares
max_llm_calls (convergence) and max_llm_tokens (prompt growth, which call
count cannot see), both enforced at the proxy and returned as
non-retryable 400s so a runaway loop stops at the ceiling instead of
feeding the provider's retry logic.

tests/regression/ holds the always-on guards — a hard journey budget (merge,
never raise), an incident ledger, provider-shape drift detection, and
meta-tests against suite degradation.

Also updates AGENTS.md with the two-layer contract and the rules that keep
the split honest, and tests/README.md with the credential setup: three
environment secrets under live-llm, and why both protection rules must stay
off (required reviewers would strand the cron; a main-only branch rule
rejects refs/pull/N/merge).
@wangxingjun778
wangxingjun778 merged commit 86cb69b into main Aug 6, 2026
2 checks passed
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