Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ EIP_MCP_TEST_API_BASE_URL=https://exploit-intel.com \
They must verify the meaning of returned parameters and fields, not merely a
successful HTTP status.

An upstream Git revision can remove a named live test file. The wide-fence
file-read case skips only after a successful complete API file inventory proves
that its named file is absent; the independent oversized ExploitDB file case
still runs. Catalog-filter checks compare returned identities with the API's
bounded page and distinguish explicitly truncated fields from incorrect values.

## Pull requests

- Preserve API ordering, identifiers, attribution, and opaque cursors.
Expand Down
9 changes: 9 additions & 0 deletions tests/test_live.py
Original file line number Diff line number Diff line change
Expand Up @@ -950,6 +950,15 @@ async def test_oversized_file_read_is_capped_with_the_fence_reclosed(tools, arti
as a system message. The text and structured source payload share one complete
serialized-result budget, so neither channel alone is required to fill it.
"""
if (artifact_id, path) == CAPPED_WIDE_FENCE:
# This Git file may disappear as its repository advances. Prove absence
# from the complete current API inventory before declaring this live
# case unavailable; a failed request or incomplete listing must fail.
listing = await tools._post_for_artifact("/api/v1/poc-files", artifact_id)
detail = await tools._api.get(f"/api/v1/pocs/{artifact_id}")
assert len(listing["items"]) == detail["file_count"]
if path not in {item["path"] for item in listing["items"]}:
pytest.skip("current repository snapshot no longer contains the wide-fence test file")
out = await tools.read_exploit_file(artifact_id, path=path)
wire = call_tool_result("read_exploit_file", out).model_dump_json()
assert len(wire) <= 40_000
Expand Down
12 changes: 11 additions & 1 deletion tests/test_live_parameter_effects.py
Original file line number Diff line number Diff line change
Expand Up @@ -1221,7 +1221,17 @@ async def test_catalog_kind_holds_on_every_row(tools, kind):
result = await tools.search_exploits(catalog_kind=kind, limit=10)
rows = result.structured.data["items"]
assert rows, f"catalog_kind={kind} returned nothing"
off = {r.get("catalog_kind") for r in rows if r.get("catalog_kind") != kind}
# The shared wire budget may stop within the final structured row. Compare
# the returned identities to the API's complete bounded page, and only
# permit absent fields when the envelope explicitly discloses truncation.
expected = await tools._api.get("/api/v1/pocs", {"catalog_kind": kind, "limit": 10})
assert all(row["catalog_kind"] == kind for row in expected["items"])
assert [row["artifact_id"] for row in rows] == [
row["artifact_id"] for row in expected["items"][: len(rows)]
]
assert any("catalog_kind" in row for row in rows)
assert result.structured.truncated or all("catalog_kind" in row for row in rows)
off = {r["catalog_kind"] for r in rows if "catalog_kind" in r and r["catalog_kind"] != kind}
assert not off, f"catalog_kind={kind} returned {off}"


Expand Down
Loading