diff --git a/src/agent_env/artifact/artifacts/environment_universe.py b/src/agent_env/artifact/artifacts/environment_universe.py index 1d620e1e..813eac6e 100644 --- a/src/agent_env/artifact/artifacts/environment_universe.py +++ b/src/agent_env/artifact/artifacts/environment_universe.py @@ -59,11 +59,10 @@ def _serialize(self, handler: Any) -> dict[str, Any]: data.pop("service_artifact_ids", None) data.pop("metadata", None) # Dual-write: the pinned refs get a twin, and only them. - # The scope line also asked for a `service_artifact_ids` twin on these - # modern docs — declined. That key means "unpinned, resolve at latest" - # to every reader, and v0.9.1 (pinned permanently by - # synthetic-artifacts-pipeline) acts on it, so writing it onto a doc - # that IS pinned tells that worker to ignore the pins. Nothing legacy + # No `service_artifact_ids` twin on these modern docs: that key means + # "unpinned, resolve at latest" to every reader, older releases + # included, so writing it onto a doc that IS pinned tells those + # readers to ignore the pins. Nothing legacy # is dropped here: unpinned docs never reach this branch and still # round-trip `service_artifact_ids` / `metadata` above, and # get_environment_artifacts still falls back to them. diff --git a/src/agent_env/env/env.py b/src/agent_env/env/env.py index 009f2106..f083b9a8 100644 --- a/src/agent_env/env/env.py +++ b/src/agent_env/env/env.py @@ -81,7 +81,7 @@ class DeployedEnv: expires_at_utc: Optional[str] = None def __post_init__(self) -> None: - # Only records from before #1137 (2026-09-24) lack their card: they keep the stored values. + # Only older records lack their card: they keep the stored values. if self.environment_card and self.environment_card_url: self.mcp_url = _mcp_url(self.environment_url, self.environment_card) self.mcp_server_name = self.environment_card.get("name") diff --git a/src/agent_env/env/envs/service_db/Dockerfile.db-web b/src/agent_env/env/envs/service_db/Dockerfile.db-web index c55bb637..3e4540ed 100644 --- a/src/agent_env/env/envs/service_db/Dockerfile.db-web +++ b/src/agent_env/env/envs/service_db/Dockerfile.db-web @@ -1,8 +1,7 @@ # Official pgweb image, pulled from its public GitHub Container Registry mirror. # We avoid Docker Hub because anonymous pulls are rate-limited per IP (429s from -# CodeBuild's shared NAT). ghcr.io hosts the same image (identical digest) with -# no anonymous rate limit and no auth required, so no private ECR mirror is -# needed. The digest matches docker.io/sosedoff/pgweb:0.16.2. To bump: pick a +# CI runners behind a shared NAT). ghcr.io hosts the same image (identical +# digest) with no anonymous rate limit and no auth required. The digest matches docker.io/sosedoff/pgweb:0.16.2. To bump: pick a # new tag from https://github.com/sosedoff/pgweb/pkgs/container/pgweb and update # the tag + digest here. FROM ghcr.io/sosedoff/pgweb:0.16.2@sha256:8f1ed22e10c9da0912169b98b62ddc54930dc39a5ae07b0f1354d2a93d44c6ed diff --git a/src/agent_env/env/gateway/constants.py b/src/agent_env/env/gateway/constants.py index 270fa154..5a2256d0 100644 --- a/src/agent_env/env/gateway/constants.py +++ b/src/agent_env/env/gateway/constants.py @@ -14,9 +14,8 @@ # Max end-to-end time for a single service's data load (seconds). # -# The previous value of 600 was sized above a then-slowest prod load of ~430s. -# That is no longer the ceiling: a large universe's gmail component now takes 498s and slack -# 499s, leaving under 20% headroom on a number chosen to have plenty. +# A single component of a large universe can take close to 500s, so this leaves +# wide headroom. # # The margin matters more than the average because of how a load fails. A # component that exceeds this does not retry — the environment comes up, reports @@ -33,8 +32,8 @@ # Extra seconds granted per GB of payload, on top of the floor. # # Explicitly a heuristic, not a model. Measured load cost tracks RECORD COUNT, not bytes: -# github moved 3.5GB in 89s while gmail took 206s for 409MB and slack 207s for 86.6MB (~20x -# and ~94x worse per byte). So size is a weak proxy -- it over-grants to the big-blob +# a blob-heavy service can move GBs in about a minute while a record-heavy one takes minutes +# for well under 1GB. So size is a weak proxy -- it over-grants to the big-blob # services that never needed it and under-grants to the small record-heavy ones that do. # It is still strictly better than a flat cap, because the flat cap's failure mode was # killing healthy work. A real fix is a stall timeout (fail on no progress rather than on diff --git a/src/agent_env/explorer/ui/src/components/rubric-grading-results.tsx b/src/agent_env/explorer/ui/src/components/rubric-grading-results.tsx index 464a8e71..1bc85f3d 100644 --- a/src/agent_env/explorer/ui/src/components/rubric-grading-results.tsx +++ b/src/agent_env/explorer/ui/src/components/rubric-grading-results.tsx @@ -35,7 +35,7 @@ export interface VerificationResult { } export interface VerifierOutput { - /** Stamped by agent-env rubrics_verifier (PR1 judge output format registry). */ + /** Stamped by agent-env rubrics_verifier (judge output format registry). */ format?: JudgeOutputFormat; results: VerificationResult[]; score: number; diff --git a/src/agent_env/explorer/ui/src/components/rubric-matrix.tsx b/src/agent_env/explorer/ui/src/components/rubric-matrix.tsx index 34be137f..271f0d68 100644 --- a/src/agent_env/explorer/ui/src/components/rubric-matrix.tsx +++ b/src/agent_env/explorer/ui/src/components/rubric-matrix.tsx @@ -30,7 +30,7 @@ function rubricLabel(rubric: RubricCriterion): string { * Pick the verifier output that actually grades the configured rubrics, * not just whichever happens to come first in dict iteration order. * - * Tasks like `mm-avatar-full-urls` write multiple entries to + * A task can write multiple entries to * `metadata.verifications` — `verify-fs` (sandbox), `verify-response` * (rubric), `aggregate`. Prefer entries stamped with * `format: "rubric_binary"`; fall back to max rubric-id overlap diff --git a/src/agent_env/explorer/ui/src/lib/bar-downloads.smoke.ts b/src/agent_env/explorer/ui/src/lib/bar-downloads.smoke.ts index 4645fc0a..5aa1cf9e 100644 --- a/src/agent_env/explorer/ui/src/lib/bar-downloads.smoke.ts +++ b/src/agent_env/explorer/ui/src/lib/bar-downloads.smoke.ts @@ -164,17 +164,17 @@ function main(): void { ); } - // The reported case: demo-bench-proof-c2, many steps + results. + // A task with many steps + results. { const many = Array.from({ length: 12 }, (_, i) => ({ - agent_trajectory_s3_uri: `obj://halt/${i}`, + agent_trajectory_s3_uri: `obj://bucket/${i}`, step_id: `step-${i}`, })); - const downloads = buildBarDownloads(many, 'obj://halt/results.json'); + const downloads = buildBarDownloads(many, 'obj://bucket/results.json'); assert(downloads.length === 13, 'all 12 trajectories plus results kept'); assert( shouldCollapseBarDownloads(downloads.length), - 'the reported task collapses into a dropdown', + 'a many-step task collapses into a dropdown', ); assert( new Set(downloads.map(d => d.key)).size === downloads.length, diff --git a/src/agent_env/explorer/ui/src/lib/parse-trajectory-claude-cli.smoke.ts b/src/agent_env/explorer/ui/src/lib/parse-trajectory-claude-cli.smoke.ts index 5202ddbf..012e2da5 100644 --- a/src/agent_env/explorer/ui/src/lib/parse-trajectory-claude-cli.smoke.ts +++ b/src/agent_env/explorer/ui/src/lib/parse-trajectory-claude-cli.smoke.ts @@ -4,10 +4,8 @@ * and assert that classification + event extraction + sub-agent folding * produce sensible output. * - * Fixture default: `/tmp/traj.json` — pulled from the real run - * a captured agent run while diagnosing the - * "Cannot read properties of undefined (reading 'openinference.span.kind')" - * crash. Override with `CLAUDE_CLI_FIXTURE=`. + * Fixture default: `/tmp/traj.json`, a captured agent run. Override with + * `CLAUDE_CLI_FIXTURE=`. * * Runner: plain TS, throws on assertion failure. Run with any TS executor: * npx tsx src/lib/parse-trajectory-claude-cli.smoke.ts diff --git a/src/agent_env/explorer/ui/src/lib/parse-trajectory-opencode.smoke.ts b/src/agent_env/explorer/ui/src/lib/parse-trajectory-opencode.smoke.ts index 86989fbe..dd332d1c 100644 --- a/src/agent_env/explorer/ui/src/lib/parse-trajectory-opencode.smoke.ts +++ b/src/agent_env/explorer/ui/src/lib/parse-trajectory-opencode.smoke.ts @@ -4,8 +4,7 @@ * `looksLikeOpenCodeStreamJson`) and assert the event extraction contract. * * Default fixture is inline + synthetic but faithful to the real record shape - * (verified against the live run `task-v2env-186-778c8c2c-opencode-y5hm9olj`: - * records are `{type, timestamp, sessionID, part}`; tool calls are + * (records are `{type, timestamp, sessionID, part}`; tool calls are * self-contained with `part.state={status,input,output,time}`; a turn ends on a * `step_finish` whose `part.reason === 'stop'`). Point at a real pulled * trajectory with `OPENCODE_FIXTURE=`. diff --git a/src/agent_env/explorer/ui/src/lib/parse-trajectory-openinference.smoke.ts b/src/agent_env/explorer/ui/src/lib/parse-trajectory-openinference.smoke.ts index f444ce3c..00313cb3 100644 --- a/src/agent_env/explorer/ui/src/lib/parse-trajectory-openinference.smoke.ts +++ b/src/agent_env/explorer/ui/src/lib/parse-trajectory-openinference.smoke.ts @@ -5,7 +5,7 @@ * output. * * The fixture is a 22-span trajectory captured from a 3-sub-agent kimi-k2p5 - * run via `/tmp/smoke_otel_bridge.py`. It exercises the OpenInference + * run. It exercises the OpenInference * adapter on every span kind (AGENT/CHAIN/TOOL/LLM), nested sub-agent * runs, and tool calls. * diff --git a/src/agent_env/explorer/ui/src/lib/step-attempt-failures.smoke.ts b/src/agent_env/explorer/ui/src/lib/step-attempt-failures.smoke.ts index 802ae939..5e0d3e9e 100644 --- a/src/agent_env/explorer/ui/src/lib/step-attempt-failures.smoke.ts +++ b/src/agent_env/explorer/ui/src/lib/step-attempt-failures.smoke.ts @@ -25,7 +25,7 @@ function assert(cond: unknown, msg: string): void { } function main(): void { - // The real prod entry from aeh-0000000000000-000000000000000a (completed run, one retry). + // A completed run's entry, one retry. const real = { attempt: 1, step_id: 'verify-response', @@ -80,9 +80,8 @@ function main(): void { } { - // Timestamps are minute-precision, so a step failing in seconds produces ties. - // Shape from aeh-0000000000000-000000000000000b, whose verify-response attempts took - // 83s / 11s / 22s. + // Timestamps are minute-precision, so a step failing in seconds produces ties: + // here three verify-response attempts that took 83s / 11s / 22s. const parsed = parseStepAttemptFailures([ { ...real, attempt: 3, occurred_at_utc: '2026-07-29 00:49 UTC' }, { ...real, attempt: 2, occurred_at_utc: '2026-07-29 00:49 UTC' }, diff --git a/src/agent_env/providers/sandbox_providers/modal_sandbox.py b/src/agent_env/providers/sandbox_providers/modal_sandbox.py index 86808e64..fe817c76 100644 --- a/src/agent_env/providers/sandbox_providers/modal_sandbox.py +++ b/src/agent_env/providers/sandbox_providers/modal_sandbox.py @@ -467,7 +467,7 @@ async def _log_sandbox_started( ) -> None: """Log one structured line mapping Modal's container id to the sandbox and its tags. - Modal's Datadog metrics carry only ``container_id`` (the ``ta-`` task id), not sandbox tags, so + Modal's exported metrics carry only ``container_id`` (the ``ta-`` task id), not sandbox tags, so this line is the join key from a container's usage to its run and pipeline step. Never raises: the task id comes from a private Modal method. """ diff --git a/src/agent_env/task_step/snapshot_utils/agent_state_capture.py b/src/agent_env/task_step/snapshot_utils/agent_state_capture.py index 594eecf4..3e969d42 100644 --- a/src/agent_env/task_step/snapshot_utils/agent_state_capture.py +++ b/src/agent_env/task_step/snapshot_utils/agent_state_capture.py @@ -220,8 +220,8 @@ def upload_trajectory( Always uploaded from the worker side, never by the agent: sandbox VMs hold static STS env vars with a fixed expiry, and long runs exceed it. - ``name`` makes the object addressable by an id the caller already records - (#731); omit it to get a random one, which is what writing repeatedly under a + ``name`` makes the object addressable by an id the caller already records; + omit it to get a random one, which is what writing repeatedly under a single prefix needs, since a fixed name would overwrite the last upload. """ diff --git a/src/agent_env/task_step/task_steps/a2a_agent_validator/verify_a2a_modalities.py b/src/agent_env/task_step/task_steps/a2a_agent_validator/verify_a2a_modalities.py index 98491d36..22160a21 100644 --- a/src/agent_env/task_step/task_steps/a2a_agent_validator/verify_a2a_modalities.py +++ b/src/agent_env/task_step/task_steps/a2a_agent_validator/verify_a2a_modalities.py @@ -15,11 +15,10 @@ - `probe_step_did_not_run`: no matching response — the upstream `PromptAgentTaskStep` crashed before `context.prompt_responses.append(...)`. -The gemini wrapper currently passes all 12 modality probes (text, image -{png,jpeg,gif}, audio {wav,mpeg,mp4,ogg}, PDF, video/mp4, plus image/png -delivered via `FileWithUri` over `s3://` and presigned `https://`). New -A2A wrappers (claude-code, codex, grok) inherit this same probe set and -will report which subset they actually ingest. +There are 12 modality probes (text, image {png,jpeg,gif}, audio +{wav,mpeg,mp4,ogg}, PDF, video/mp4, plus image/png delivered via +`FileWithUri` over `s3://` and presigned `https://`). Every A2A agent gets +the same probe set, and the results report which subset it ingests. """ from __future__ import annotations diff --git a/src/agent_env/task_step/task_steps/apply_server_config.py b/src/agent_env/task_step/task_steps/apply_server_config.py index a760e3af..f827d0dc 100644 --- a/src/agent_env/task_step/task_steps/apply_server_config.py +++ b/src/agent_env/task_step/task_steps/apply_server_config.py @@ -57,9 +57,8 @@ def __init__(self, service: str, uri: str, args: dict[str, Any]): def to_dict(self) -> dict: # Dual-write. This feeds the `tasks` and `task_steps` - # documents — NOT the delivered bundle. The bundle mints its own dict - # from these attributes in export/exporter.py, so the permanently frozen - # `{'service': ...}` Harbor applier input is unaffected by the twin here. + # documents only. An exporter builds its own dict from these attributes, + # so a frozen `{'service': ...}` export format is unaffected by the twin here. return {"service": self.service, "environment": self.service, "uri": self.uri, "args": self.args} @classmethod diff --git a/src/agent_env/task_step/task_steps/collect_artifacts.py b/src/agent_env/task_step/task_steps/collect_artifacts.py index 31481ba6..36a9c08e 100644 --- a/src/agent_env/task_step/task_steps/collect_artifacts.py +++ b/src/agent_env/task_step/task_steps/collect_artifacts.py @@ -39,8 +39,8 @@ } With seed CSV: - name,platform,expected_artifacts - VPC Endpoints,Terraform,"Dockerfile,run.sh,codebase.patch,test.patch,gold.patch,prompt.md,before.json,after.json,p2p_tests.json,f2p_tests.json,validation.json,progress.md" + name,expected_artifacts + example-task,"Dockerfile,run.sh,solution.patch,report.md" Or with static fallback (no seed data needed): { @@ -714,7 +714,7 @@ async def _collect_via_controller(self, context, store, artifact_id, version): # Read files via the CUA MCP server (cua_get_file / cua_bash) over the # gateway's step/v1. These are MCP tools registered on the gateway on both # Ubuntu and macOS — NOT endpoints on the macOS controller sidecar, whose - # /step only accepts a ScaleCuaAction and 500s on a call_tool payload. + # /step only accepts a computer-use action and 500s on a call_tool payload. logger.info(f"Collecting artifacts via CUA MCP server (env_id={self.env_id}, gateway={deployed_env.environment_url})") items = self._resolve_items(context) diff --git a/src/agent_env/task_step/task_steps/mcp_env_validator/verify_spec_conformance.py b/src/agent_env/task_step/task_steps/mcp_env_validator/verify_spec_conformance.py index 4d20403e..30acf47d 100644 --- a/src/agent_env/task_step/task_steps/mcp_env_validator/verify_spec_conformance.py +++ b/src/agent_env/task_step/task_steps/mcp_env_validator/verify_spec_conformance.py @@ -14,10 +14,6 @@ enforcement by passing ``spec_conformance`` in ``ValidationGateAggregatorStep``'s ``required_gates`` (a step arg, not env metadata). No baked spec = ``skipped``. Execution errors (unreachable MCP) still raise. - -Keep the diff logic in sync with the universe-generation pipeline's -``synthetic_mcp_server_generation/validation/spec_conformance.py`` (same diff at generation -time); tool shape differs — MCP objects here, dicts there. """ from __future__ import annotations diff --git a/src/agent_env/task_step/task_steps/prompt_agent.py b/src/agent_env/task_step/task_steps/prompt_agent.py index 154fcf4e..4c23de17 100644 --- a/src/agent_env/task_step/task_steps/prompt_agent.py +++ b/src/agent_env/task_step/task_steps/prompt_agent.py @@ -711,7 +711,7 @@ async def _fetch_trajectory(self, a2a_url: str, traj_ext: dict, a2a_server_task_ ) # Fetched by a2a_server_task_id, the id the A2A server produced; stored under # target_a2a_task_id, the client message id persisted on the conversation as - # a2a_task_id, so the FE can resolve it (#731). + # a2a_task_id, so the FE can resolve it. upload = None if mode == "objects": upload = await asyncio.to_thread( diff --git a/tst/integration/env/task_step/test_task_instance_retry_resume.py b/tst/integration/env/task_step/test_task_instance_retry_resume.py index a8355383..a2c64177 100644 --- a/tst/integration/env/task_step/test_task_instance_retry_resume.py +++ b/tst/integration/env/task_step/test_task_instance_retry_resume.py @@ -194,9 +194,9 @@ async def test_a_failed_steps_partial_writes_reach_the_doc_but_not_the_journal() A step that writes and then fails gets its writes onto the instance through ``record_task_failure``'s wholesale ``context`` write, which is not journaled. Replay - therefore omits them and the journal is *not* a complete record of a failed run. The - stacked retry PR is expected to journal the failing step with ``status=failure`` first; - when it does, this test should start failing and be tightened to assert equality. + therefore omits them and the journal is *not* a complete record of a failed run. Once + the failing step is journaled with ``status=failure`` first, this test should start + failing and be tightened to assert equality. """ task_id = f"retry-resume-partial-test-{uuid.uuid4().hex[:8]}" instance_id = f"{task_id}-deterministic" diff --git a/tst/unit/env/envs/test_multi_env_vm_sizing.py b/tst/unit/env/envs/test_multi_env_vm_sizing.py index 3e9866bc..f8c3c8b2 100644 --- a/tst/unit/env/envs/test_multi_env_vm_sizing.py +++ b/tst/unit/env/envs/test_multi_env_vm_sizing.py @@ -1,11 +1,11 @@ """A MultiEnv does not size its own box; cpu and memory both defer to the provider. -The providers already floor both per backend (#1045: 0.125 vCPU on Modal, where cpu is a +The providers already floor both per backend (0.125 vCPU on Modal, where cpu is a burstable reservation, 0.5 on the VM backends; 8GB memory on either), and a number invented here could only override a better-informed default. In container mode it was actively wrong: the derived size landed on the gateway, a router, as if it hosted every service. -7 days of production logs showed nothing depending on the derived cpu except that gateway, +Nothing depended on the derived cpu except that gateway, and the two callers that leaned on the derived memory were getting it from `cpu x 4096` -- an 11-service env on 2GB. An explicit value from the caller still wins on both axes. """ diff --git a/tst/unit/env/gateway/triggers_time_test.py b/tst/unit/env/gateway/triggers_time_test.py index dbee0300..b08ebbbb 100644 --- a/tst/unit/env/gateway/triggers_time_test.py +++ b/tst/unit/env/gateway/triggers_time_test.py @@ -256,7 +256,7 @@ async def test_event_anchored_never_fires_without_anchor(): ], ids=["one-shot", "bounded-recurrence"]) @pytest.mark.asyncio async def test_terminating_time_anchor_does_not_strand_dependent(anchor_when): - """Greptile #765: a TIME anchor that retires must still resolve its dependents, even though + """A TIME anchor that retires must still resolve its dependents, even though `_fire_time` recomputes `_has_time_triggers` (in `finally`) *before* calling `_resolve_dependents`, which early-returns on a cleared flag. @@ -534,7 +534,7 @@ async def test_rearm_reanchors_trigger_that_was_firing(): @pytest.mark.asyncio async def test_rearm_drops_capped_backlog_and_says_so(monkeypatch): - """Greptile P1c: a re-arm that lands while a capped catch-up batch is firing drops the leftover + """A re-arm that lands while a capped catch-up batch is firing drops the leftover backlog — by design (those marks are on a timeline the new clock never reached) — but the drop must NOT be silent: it emits a `reanchored` event naming the dropped mark, and the trigger re-anchors to the new t0 rather than replaying the old axis.""" diff --git a/tst/unit/env/test_env.py b/tst/unit/env/test_env.py index a6a4a7f9..7c52efd9 100644 --- a/tst/unit/env/test_env.py +++ b/tst/unit/env/test_env.py @@ -186,7 +186,7 @@ def test_a_record_takes_its_mcp_url_and_server_name_from_its_card(): @pytest.mark.parametrize("card, card_url", [(None, _CARD_URL), (_CARD, None)], ids=["no-card", "no-card-url"]) def test_a_record_without_its_card_keeps_its_stored_mcp_url_and_name(card, card_url): - """Records written before #1137 carry no card, so their stored values stand.""" + """Older records carry no card, so their stored values stand.""" record = DeployedEnv.from_dict({"env_id": "e", "env_version": 1, "gateway_url": "https://old", "sandbox_id": "sb", "mcp_url": "https://old/mcp", "mcp_server_name": "old", "environment_card": card, "environment_card_url": card_url}) assert (record.mcp_url, record.mcp_server_name) == ("https://old/mcp", "old") diff --git a/tst/unit/providers/env_providers/env_gateway_provider_test.py b/tst/unit/providers/env_providers/env_gateway_provider_test.py index 880abe09..92c27146 100644 --- a/tst/unit/providers/env_providers/env_gateway_provider_test.py +++ b/tst/unit/providers/env_providers/env_gateway_provider_test.py @@ -209,7 +209,7 @@ async def _spy_acquire(self, ctx): assert len(gp._container_sandboxes) == 4 - # PR 2: the deploy routes DB state through the provider. + # The deploy routes DB state through the provider. # servicedb container env comes from the provider's store-spec db_call = next(c for c in create_calls if c["port"] == SERVICE_DB_PORT) assert db_call["env"] == LocalPostgresStateProvider().store_spec(["slack", "email"]).env diff --git a/tst/unit/providers/sandbox_providers/modal_sandbox_test.py b/tst/unit/providers/sandbox_providers/modal_sandbox_test.py index 76080487..a095df55 100644 --- a/tst/unit/providers/sandbox_providers/modal_sandbox_test.py +++ b/tst/unit/providers/sandbox_providers/modal_sandbox_test.py @@ -42,7 +42,7 @@ async def test_create_container_wraps_modal_create_failure_with_context(_patched with pytest.raises(RuntimeError) as ei: await _patched_provider.create_container( - image_name="123456789012.dkr.ecr.us-west-2.amazonaws.com/agent-env/agent-images/mcp-server-airtable:v4", + image_name="123456789012.dkr.ecr.us-west-2.amazonaws.com/example/mcp-server:v1", port=18765, env={}, cpu=2.0, @@ -54,7 +54,7 @@ async def test_create_container_wraps_modal_create_failure_with_context(_patched msg = str(ei.value) assert "Modal sandbox create failed" in msg assert "_BareSandboxTimeoutError" in msg - assert "mcp-server-airtable:v4" in msg + assert "example/mcp-server:v1" in msg assert "port=18765" in msg assert "region=us-east-1" in msg assert "i6pn=True" in msg @@ -75,7 +75,7 @@ async def test_create_container_wraps_post_create_failure_and_terminates(_patche with pytest.raises(RuntimeError) as ei: await _patched_provider.create_container( - image_name="registry.example/mcp-server-openclaw-strava:v6", + image_name="registry.example/mcp-server-example:v1", port=18765, env={}, ) @@ -83,7 +83,7 @@ async def test_create_container_wraps_post_create_failure_and_terminates(_patche msg = str(ei.value) assert "Modal sandbox post-create failed" in msg assert "sb_id=sb-FAKEFAKEFAKEFAKEFAKE" in msg - assert "mcp-server-openclaw-strava:v6" in msg + assert "mcp-server-example:v1" in msg fake_sb.terminate.aio.assert_awaited_once() @@ -141,7 +141,7 @@ def mint(self, host): return RegistryAuth(host, "u", "p") ecr_host = "123456789012.dkr.ecr.us-west-2.amazonaws.com" - ecr = "123456789012.dkr.ecr.us-west-2.amazonaws.com/agent-env/agent-images/x:v1" + ecr = "123456789012.dkr.ecr.us-west-2.amazonaws.com/example/x:v1" _patched_provider._ecr_pull_secret_name = "agent-env-ecr-reader" p = lambda n: patch(f"agent_env.providers.sandbox_providers.modal_sandbox.modal.{n}") # noqa: E731 diff --git a/tst/unit/providers/sandbox_providers/vm_sandbox_test.py b/tst/unit/providers/sandbox_providers/vm_sandbox_test.py index d340e7b1..775125b1 100644 --- a/tst/unit/providers/sandbox_providers/vm_sandbox_test.py +++ b/tst/unit/providers/sandbox_providers/vm_sandbox_test.py @@ -62,7 +62,7 @@ async def test_load_docker_images_downloads_to_file_before_load(signing_store): Retrying `curl ... | gunzip | docker load` directly corrupts the stream because curl can't rewind bytes already piped to stdout, so the retry flags - must only apply to a `-o file` download (Greptile P1 on PR #430). + must only apply to a `-o file` download. """ sandbox = _RecordingVmSandbox(images_stdout="myimage\n") artifact = SimpleNamespace(tar_gz_object_url="s3://bucket/img.tar.gz", image_name="myimage:latest") diff --git a/tst/unit/serialization/golden/env/gateway_server.json b/tst/unit/serialization/golden/env/gateway_server.json index 8049f74b..eab5f047 100644 --- a/tst/unit/serialization/golden/env/gateway_server.json +++ b/tst/unit/serialization/golden/env/gateway_server.json @@ -6,7 +6,7 @@ }, "id": "gateway-env", "metadata": { - "owner": "env-pod" + "owner": "example-team" }, "type": "gateway_server", "version": 11 diff --git a/tst/unit/serialization/golden/env/mcp_server.json b/tst/unit/serialization/golden/env/mcp_server.json index b24dbd55..7c15783c 100644 --- a/tst/unit/serialization/golden/env/mcp_server.json +++ b/tst/unit/serialization/golden/env/mcp_server.json @@ -8,7 +8,7 @@ "environment_name": "slack", "id": "slack-env", "metadata": { - "owner": "env-pod" + "owner": "example-team" }, "service_name": "slack", "type": "mcp_server", diff --git a/tst/unit/serialization/golden/env/multi.json b/tst/unit/serialization/golden/env/multi.json index 930cb21d..08009cec 100644 --- a/tst/unit/serialization/golden/env/multi.json +++ b/tst/unit/serialization/golden/env/multi.json @@ -9,7 +9,7 @@ } ], "metadata": { - "owner": "env-pod" + "owner": "example-team" }, "type": "multi", "version": 6, diff --git a/tst/unit/serialization/golden/env/service_db.json b/tst/unit/serialization/golden/env/service_db.json index 34051b9d..65465b50 100644 --- a/tst/unit/serialization/golden/env/service_db.json +++ b/tst/unit/serialization/golden/env/service_db.json @@ -16,7 +16,7 @@ }, "id": "service-db-env", "metadata": { - "owner": "env-pod" + "owner": "example-team" }, "type": "service_db", "version": 3 diff --git a/tst/unit/serialization/golden/env/website.json b/tst/unit/serialization/golden/env/website.json index 23f83880..c58fccd1 100644 --- a/tst/unit/serialization/golden/env/website.json +++ b/tst/unit/serialization/golden/env/website.json @@ -13,7 +13,7 @@ }, "id": "shop-site-env", "metadata": { - "owner": "env-pod" + "owner": "example-team" }, "service_name": "shop", "type": "website", diff --git a/tst/unit/serialization/test_golden_wire_format.py b/tst/unit/serialization/test_golden_wire_format.py index 689af5df..66f0e0ec 100644 --- a/tst/unit/serialization/test_golden_wire_format.py +++ b/tst/unit/serialization/test_golden_wire_format.py @@ -69,7 +69,7 @@ def _mcp_server_env() -> MCPServerEnv: version=4, docker_image_artifact=_docker_image("slack-mcp-image", 5, "slack-mcp:v5"), environment_name="slack", - metadata={"owner": "env-pod"}, + metadata={"owner": "example-team"}, ) @@ -80,7 +80,7 @@ def _website_env() -> WebsiteEnv: backend_docker_image_artifact=_docker_image("shop-backend-image", 3, "shop-backend:v3"), frontend_docker_image_artifact=_docker_image("shop-frontend-image", 3, "shop-frontend:v3"), environment_name="shop", - metadata={"owner": "env-pod"}, + metadata={"owner": "example-team"}, ) @@ -156,7 +156,7 @@ def _website_env() -> WebsiteEnv: id="gateway-env", version=11, docker_image_artifact=_docker_image("gateway-image", 12, "gateway:v12"), - metadata={"owner": "env-pod"}, + metadata={"owner": "example-team"}, ), "mcp_server": _mcp_server_env, "multi": lambda: MultiEnv( @@ -164,7 +164,7 @@ def _website_env() -> WebsiteEnv: version=6, mcp_server_envs=[_mcp_server_env()], website_envs=[_website_env()], - metadata={"owner": "env-pod"}, + metadata={"owner": "example-team"}, ), "service_db": lambda: ServiceDBEnv( id="service-db-env", @@ -172,7 +172,7 @@ def _website_env() -> WebsiteEnv: db_web_docker_image_artifact=_docker_image("pgweb-image", 1, "pgweb:v1"), db_mcp_docker_image_artifact=_docker_image("db-mcp-image", 1, "db-mcp:v1"), version=3, - metadata={"owner": "env-pod"}, + metadata={"owner": "example-team"}, ), "website": _website_env, } diff --git a/tst/unit/store/test_config_image_store.py b/tst/unit/store/test_config_image_store.py index 4bbc1b62..348937b6 100644 --- a/tst/unit/store/test_config_image_store.py +++ b/tst/unit/store/test_config_image_store.py @@ -93,10 +93,10 @@ def test_env_override_beats_config_toml(monkeypatch, tmp_path): def test_ecr_from_config_builds_store_lazily_without_network(monkeypatch): store = EcrImageStore.from_config( registry_host="123.dkr.ecr.us-west-2.amazonaws.com", - repository_prefix="agent-env/agent-images-dev", + repository_prefix="example/images-dev", ) assert isinstance(store, EcrImageStore) - assert store.image_ref("foo", "v1") == "123.dkr.ecr.us-west-2.amazonaws.com/agent-env/agent-images-dev/foo:v1" + assert store.image_ref("foo", "v1") == "123.dkr.ecr.us-west-2.amazonaws.com/example/images-dev/foo:v1" def test_ecr_rejects_a_non_ecr_credential_provider(): @@ -115,11 +115,11 @@ def test_ecr_rejects_a_non_ecr_credential_provider(): def test_ecr_store_exposes_its_registry_host(): store = EcrImageStore.from_config( registry_host="123.dkr.ecr.us-west-2.amazonaws.com", - repository_prefix="agent-env/agent-images-dev", + repository_prefix="example/images-dev", ) assert store.registry_host == "123.dkr.ecr.us-west-2.amazonaws.com" # Host only — no repository prefix, unlike image_ref(). - assert "agent-images-dev" not in store.registry_host + assert "images-dev" not in store.registry_host def test_registry_host_is_the_host_component_of_image_ref(): diff --git a/tst/unit/store/test_secret_logging.py b/tst/unit/store/test_secret_logging.py index 48a13f6c..dd578604 100644 --- a/tst/unit/store/test_secret_logging.py +++ b/tst/unit/store/test_secret_logging.py @@ -79,7 +79,7 @@ def test_level_restored_even_when_the_call_raises(): def test_an_overlapping_fetch_stays_silenced_when_the_first_finishes(): - """The race Greptile flagged, forced rather than raced for. + """The overlap race, forced rather than raced for. Two fetches overlap and the one that started FIRST finishes first. It captured DEBUG on the way in, so a naive restore puts DEBUG back while the diff --git a/tst/unit/task_step/test_collect_artifacts.py b/tst/unit/task_step/test_collect_artifacts.py index 0af64b66..f6676791 100644 --- a/tst/unit/task_step/test_collect_artifacts.py +++ b/tst/unit/task_step/test_collect_artifacts.py @@ -103,15 +103,15 @@ def test_defaulted_agent_name_with_env_id_tolerated(self): def _macos_cua_context(): """A macOS CUA env: gateway_url (CUA MCP server, 18765) plus a distinct cua_controller_url (the osworld sidecar, 18768). cua_get_file must go to the - gateway, not the sidecar — the sidecar's /step only accepts a ScaleCuaAction - and 500s on a call_tool payload.""" + gateway, not the sidecar — the sidecar's /step only accepts a computer-use + action and 500s on a call_tool payload.""" return TaskStepContext(instance_id="inst-1", deployed_envs=[_macos_record()]) class TestControllerPath: def test_reads_route_to_gateway_mcp_not_controller_sidecar(self): """Regression: reads must use gateway_url (CUA MCP server), even when a - macOS cua_controller_url is present. Routing them to the sidecar (#693) + macOS cua_controller_url is present. Routing them to the sidecar made every read 500.""" step = CollectArtifactsTaskStep( id="collect", version=None, env_id="macos-cua", @@ -581,31 +581,31 @@ class TestManifestResolution: def test_manifest_mode_keys_by_logical_name_and_filters(self): step = CollectArtifactsTaskStep( - id="collect", version=None, base_path="/app/swe_atlas", + id="collect", version=None, base_path="/app/workspace", manifest_step_id="m9", exclude_basenames=["base_image.tar", "base_image.tar.sha256"], ) ctx = _manifest_ctx({ - "dockerfile": "/app/swe_atlas/Dockerfile", - "gold_patch": "/app/swe_atlas/patches/gold_patch.diff", - "base_image_tar": "/app/swe_atlas/base_image.tar", # excluded basename - "m7_iter_logs": "/app/swe_atlas/logs/m7_iter_*.json", # unresolved glob -> skipped - "coverage_state": "target_reached", # literal value, not a path -> skipped - "harbor_zip": "/app/swe_atlas/ruff_harbor_v1.zip", + "dockerfile": "/app/workspace/Dockerfile", + "gold_patch": "/app/workspace/patches/gold_patch.diff", + "base_image_tar": "/app/workspace/base_image.tar", # excluded basename + "run_logs": "/app/workspace/logs/run_*.json", # unresolved glob -> skipped + "status": "complete", # literal value, not a path -> skipped + "bundle_zip": "/app/workspace/bundle_a.zip", }) items = {k: (src, obj) for k, src, obj in step._resolve_items(ctx)} - assert set(items) == {"dockerfile", "gold_patch", "harbor_zip"} + assert set(items) == {"dockerfile", "gold_patch", "bundle_zip"} # logical name -> (absolute source path, base_path-relative object name) - assert items["gold_patch"] == ("/app/swe_atlas/patches/gold_patch.diff", "patches/gold_patch.diff") - assert items["dockerfile"] == ("/app/swe_atlas/Dockerfile", "Dockerfile") + assert items["gold_patch"] == ("/app/workspace/patches/gold_patch.diff", "patches/gold_patch.diff") + assert items["dockerfile"] == ("/app/workspace/Dockerfile", "Dockerfile") def test_enumeration_drops_excluded_basenames(self): step = CollectArtifactsTaskStep( - id="collect", version=None, base_path="/app/swe_atlas", + id="collect", version=None, base_path="/app/workspace", exclude_basenames=["base_image.tar", "base_image.tar.sha256"], ) enumerated = ["Dockerfile", "patches/gold_patch.diff", "base_image.tar", - "base_image.tar.sha256", "245a_harbor_v1.zip"] - assert step._drop_excluded(enumerated) == ["Dockerfile", "patches/gold_patch.diff", "245a_harbor_v1.zip"] + "base_image.tar.sha256", "bundle_b.zip"] + assert step._drop_excluded(enumerated) == ["Dockerfile", "patches/gold_patch.diff", "bundle_b.zip"] def test_manifest_uses_latest_response_when_step_reran(self): # On retry/resume a step can append more than once; the latest output wins. @@ -801,7 +801,7 @@ def test_collects_through_the_named_container(self): class TestControllerWire: def test_controller_call_posts_call_tool_to_the_cards_step_endpoint(self, monkeypatch): - """The #693 intent at the wire: call_tool goes to the gateway's step/v1 (18765), never the macOS sidecar (18768).""" + """The same routing at the wire: call_tool goes to the gateway's step/v1 (18765), never the macOS sidecar (18768).""" sent = _mock_gateway(monkeypatch, {"content": [{"type": "text", "text": "aGk="}]}) step = CollectArtifactsTaskStep(id="collect", version=None, env_id="macos-cua", artifact_paths=["/x"]) diff --git a/tst/unit/task_step/test_load_artifact_env_binding.py b/tst/unit/task_step/test_load_artifact_env_binding.py index 40ae3900..a4f377c4 100644 --- a/tst/unit/task_step/test_load_artifact_env_binding.py +++ b/tst/unit/task_step/test_load_artifact_env_binding.py @@ -1,7 +1,7 @@ """Which deployment of an env a `load_artifact` step loads into. Matching on `env_id` alone sends every branch's load to one deployment, leaving the -others deployed but empty — their agents then bind correctly (#808) to an env with +others deployed but empty — their agents then bind correctly to an env with no data. """ @@ -17,7 +17,7 @@ from agent_env.task_step.task_steps.deploy_env import DeployEnvTaskStep from agent_env.task_step.task_steps.load_artifact import LoadArtifactTaskStep -ENV_ID = "multi-env-0gr8479d" +ENV_ID = "multi-env" def _fake_env(sandbox_id: str): diff --git a/tst/unit/task_step/test_manifest_cli_builder.py b/tst/unit/task_step/test_manifest_cli_builder.py index 46894bac..d760ed5a 100644 --- a/tst/unit/task_step/test_manifest_cli_builder.py +++ b/tst/unit/task_step/test_manifest_cli_builder.py @@ -451,8 +451,7 @@ def test_root_command_collisions_rejected(entities, match): def test_manifest_live_schema_drift_warns(fake_gateway, tmp_path): - # The universe-generation pipeline's manifest validation keeps these in sync, but the renderer parses whatever is - # served: surface drift instead of dropping it silently. + # The renderer parses whatever is served: surface drift instead of dropping it silently. drifted = _manifest( [ { diff --git a/tst/unit/task_step/test_parallel_deploy_env_binding.py b/tst/unit/task_step/test_parallel_deploy_env_binding.py index 886732be..5041db9a 100644 --- a/tst/unit/task_step/test_parallel_deploy_env_binding.py +++ b/tst/unit/task_step/test_parallel_deploy_env_binding.py @@ -1,8 +1,6 @@ -"""The `haltbench-mvp-whichenv` DAG in-process: two `deploy_env` of one `env_id` -running concurrently, then an agent per env. - -Instance haltbench-mvp-whichenv-7c9fb4o9: both envs deployed, both agents wired -to the first. +"""A two-branch DAG in-process: two `deploy_env` of one `env_id` running +concurrently, then an agent per env. Each agent must bind to its own branch's +deployment, not both to the first. """ from __future__ import annotations @@ -17,7 +15,7 @@ from agent_env.task_step.task_steps.deploy_agent import DeployAgentTaskStep from agent_env.task_step.task_steps.deploy_env import DeployEnvTaskStep -ENV_ID = "multi-env-0gr8479d" +ENV_ID = "multi-env" def _fake_env_deploying_to(mcp_url: str, sandbox_id: str): diff --git a/tst/unit/task_step/test_prompt_agent_snapshots.py b/tst/unit/task_step/test_prompt_agent_snapshots.py index 4ac3c318..ff7559cc 100644 --- a/tst/unit/task_step/test_prompt_agent_snapshots.py +++ b/tst/unit/task_step/test_prompt_agent_snapshots.py @@ -700,7 +700,7 @@ async def test_the_final_capture_publishes_the_universe_for_load_artifact(monkey await _series(env_id="env-1").finish(ctx) # Keyed on the step id, so a judge step can be wired to this prompt step - # without knowing it snapshots. `load_artifact` resolves it once #746 lands. + # without knowing it snapshots. `load_artifact` resolves it. assert ctx.metadata["env_snapshotted_universes"]["solve"] == { "id": f"snapshot-env-1-{DISCRIMINATOR}", "version": 4, diff --git a/tst/unit/task_step/test_snapshot_env_env_binding.py b/tst/unit/task_step/test_snapshot_env_env_binding.py index 6c18e5e2..990ca780 100644 --- a/tst/unit/task_step/test_snapshot_env_env_binding.py +++ b/tst/unit/task_step/test_snapshot_env_env_binding.py @@ -2,8 +2,8 @@ Matching on `env_id` alone sends every branch's snapshot to one deployment: the first-appended env gets snapshotted k times while the other rollouts' state is -never captured. Same defect #808 fixed for `deploy_agent` and #817 for -`load_artifact`, on the step that reads the state back out. +never captured. The same defect as in `deploy_agent` and `load_artifact`, on the +step that reads the state back out. `snapshot_env` has three resolution modes rather than one, so the filter is exercised against each: `env_instance_id` (exact, untouched), `env_id`, and the @@ -22,7 +22,7 @@ from agent_env.task_step.task_steps.deploy_env import DeployEnvTaskStep from agent_env.task_step.task_steps.snapshot_env import EnvSnapshotResult, SnapshotEnvTaskStep -ENV_ID = "haltbench-rollout-env-0gr8479d" +ENV_ID = "rollout-env" def _fake_env(sandbox_id: str): diff --git a/tst/unit/task_step/test_universe_comparison.py b/tst/unit/task_step/test_universe_comparison.py index c266164e..e2267279 100644 --- a/tst/unit/task_step/test_universe_comparison.py +++ b/tst/unit/task_step/test_universe_comparison.py @@ -1,7 +1,6 @@ """Unit tests for the universe load/export roundtrip comparison. -Locks in the semantic-comparison behavior, including the two correctness fixes -from PR #403 review: +Locks in the semantic-comparison behavior, including two correctness cases: * large financial amounts in the epoch range must NOT be coerced to timestamps (otherwise distinct amounts collapse to the same second — a silent false-negative); * a DROPPED non-empty nested-dict key is real data loss and must fail, while an @@ -16,7 +15,7 @@ class TestFinancialAmountsNotTimestamps: - """Greptile P1: numbers in the epoch range are amounts, not timestamps.""" + """Numbers in the epoch range are amounts, not timestamps.""" def test_distinct_amounts_in_epoch_range_differ(self): # Both fall in the old 1.4e9–2.0e9 "epoch seconds" window; sub-second precision @@ -34,7 +33,7 @@ def test_numeric_string_matches_number(self): class TestNestedDictKeyAsymmetry: - """Greptile P1: dropped universe keys fail; added export keys are enrichment.""" + """Dropped universe keys fail; added export keys are enrichment.""" def test_dropped_nonempty_key_fails(self): assert _vals_equal(