Files
Alberto Schiabel 5b898e7957 fix(harness): unblock python examples parity runs (#4228)
This PR:

- unpins the examples harness from the staging host: `COMPOSIO_BASE_URL`
now selects the backend and still defaults to staging, with the
structural checks kept (https, bare root, no
path/query/fragment/credentials) — `examples-live.yml` sets staging
explicitly, so CI is unchanged
- renames `harness/staging-backend.mjs` to `harness/backend-url.mjs` and
`requireStagingBaseUrl` to `resolveBackendBaseUrl`, and relaxes the
matching hard-exit in `harness/trace-py/sitecustomize.py`
- fixes the Python candidate swap: `relaxPyClientPin()` drops the
project's exact `composio-client==` pin for the duration of a candidate
sweep, so `COMPOSIO_CLIENT_WHEEL` can win over it, and
`python/pyproject.toml` + `uv.lock` are restored from a pre-run snapshot
afterwards
- adds `harness/README.md` covering backend selection, the
candidate-swap flow for both languages, and how to tell a real parity
pass from a vacuous one
- ignores `.artifacts/`, where every sweep writes its results, traces,
and downloaded client
- extends `harness/run.mjs selftest` with eleven checks over the new
backend-URL behaviour and the pin relaxation; the suite passes locally

## Context

Found while producing a Python examples parity run for the
`composio-client` 2.x bump, which lives on a separate branch. Both
problems blocked that run and neither is specific to it.

The staging pin made a comparison against any other project impossible
without editing the harness in place.

The Python candidate swap was worse than blocking, because it failed
quietly. A candidate sweep layers the wheel onto every entry with `uv
run --with`; seven of the twenty-two Python entries also install the
local `./python` project through `pyWith`, and uv cannot satisfy that
project's exact pin and the candidate wheel together:

```
No solution found when resolving `--with` dependencies:
Because only composio==0.20.0 is available and composio==0.20.0 depends on
composio-client==<pinned>, [...] your requirements are unsatisfiable.
```

Those entries went red in under a tenth of a second for a packaging
reason rather than a client one, and `parity.mjs` only compares entries
green on both sides — so the comparison silently shrank to fifteen
entries and still reported a clean pass. With the pin relaxed, the same
sweep runs 22/22 green and compares all twenty-two.

https://claude.ai/code/session_015Bx2BaSwuq2cxgJSRtAxag
2026-08-24 18:55:31 +02:00
..