Skip to content

feat(website): sync the clock of, snapshot, and configure a multi env's websites as its MCP servers (FD-4683) - #427

Open
williamloo-scale wants to merge 25 commits into
wloo/web-app-contractfrom
wloo/website-harness-gaps
Open

williamloo-scale wants to merge 25 commits into
wloo/web-app-contractfrom
wloo/website-harness-gaps

Conversation

@williamloo-scale

@williamloo-scale williamloo-scale commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #392.

A website env, and a multi env's websites, now get the same harness treatment as MCP servers:

  • sync_env_clock syncs a website env's site and a multi env's websites; a site that doesn't follow the clock is tolerated. With main's timezone (feat(sync_env_clock): an optional timezone reads virtual_time in the zone and tells every synced server (FD-5003) #442), every synced server, website or MCP server, is told the zone, and a site that follows the clock but can't take the zone fails the step, as an MCP server does.
  • snapshot_env exports each website child through its data plane; one without a data plane is skipped with a warning, and the step fails only if nothing is exported.
  • A config broadcast (apply_server_config with "*") reaches websites, and skips one without a card or the extension, even in strict mode, so a multi env with an older site behaves as before.

legacy_protocol.backing_servers(env) lists MCP servers then websites; on a name clash the MCP server wins.

Test

Unit suite and protocol tests: 12,607 passed, lint clean.
tst/unit/task_step, tst/unit/env, tst/unit/providers: 5303 passed (one timing test in child_sessions_test.py, untouched here, flaked once and passes on rerun).

🤖 Generated with Claude Code

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge; no new blocking issue was found.

Summary

Adds websites to clock sync, state snapshots, and config broadcasts.

  • Clock sync now reaches websites that follow the virtual clock.
  • A broadcast config directive now reaches website servers too.
  • Environment snapshots now include website state when it is available.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Environment definition] --> B[Backing MCP servers and websites]
  B --> C[Clock sync]
  B --> D[Snapshot]
  B --> E[Config broadcast]
  C --> F[Sync servers that advertise clock support]
  D --> G[Export state; warn for websites without a data plane]
  E --> H[Apply advertised config; skip unsupported websites]
Loading

Reviews (6) · Last reviewed commit: "Merge wloo/web-app-contract into wloo/we..." · Reviewed by Greptile

williamloo-scale and others added 3 commits October 29, 2026 22:41
… plane off the site's route (FD-4683)

A website whose server image serves its pages runs as one container: /website/<name>/ and /svc/<name>/ both reach
it, and it's checked at its declared health path. A site's route never forwards its data plane or env card, however
the path is spelled, so an agent browsing the site can't read what grades it; agentenv reaches them through
/svc/<name>/. A site built on a separate frontend image deploys as before.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… and verify its state at /go (FD-4683)

agent-env env website put takes the server image from --server-dockerfile, stored with its build context as an a2a
agent's image is, from --server-image-ref, or from GitHub, with --health-path; a separate frontend image is optional
and warned of. The website_state_verifier step reads each checked session of a website env's sites, or a multi
env's, at the site's /go?sid= through /svc/<name>/, the verifier endpoint CUA-Gym sites serve, and checks dot paths
of its current_state, initial_state or state_diff; with env_version pinned, put and preflight refuse checks of sites
that version doesn't serve.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…'s websites as its MCP servers (FD-4683)

sync_env_clock reaches a website env's site, and a multi env's websites beside its MCP servers; a site that doesn't
follow the clock is tolerated. snapshot_env exports each website child through its data plane and skips, with a
warning, one that has none. A config broadcast to every service reaches websites too, and skips one without a card or
the extension, so a multi env with an older site behaves as before.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
williamloo-scale and others added 4 commits November 2, 2026 02:20
# Conflicts:
#	AGENTS.md
#	src/agent_env/env/envs/multi_env.py
#	src/agent_env/env/envs/website.py
…no image source (FD-4683)

website put now takes one of --server-dockerfile, --server-dockerfile-github-url
and --server-image-ref, so the missing-source check names those options instead
of --backend-dockerfile.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
# Conflicts:
#	src/agent_env/task_step/task_steps/snapshot_env.py
williamloo-scale and others added 3 commits November 2, 2026 14:46
Brings in main's sync_env_clock timezone (#442) beside this branch's
websites: every synced server, MCP server or website, is told the zone,
and a website that follows the clock but can't take it fails the step
as an MCP server does. A website sharing an MCP server's name, synced
with no record so its card is read live, now gets the env's control
headers instead of reading them off the missing record. #442's tests
stub _backing_servers, which replaced _service_names here.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@williamloo-scale
williamloo-scale marked this pull request as ready for review November 2, 2026 23:27
@williamloo-scale
williamloo-scale requested a review from a team as a code owner November 2, 2026 23:27
williamloo-scale and others added 10 commits November 2, 2026 15:32
…the site receives is spelled (FD-4683)

The guard checked the decoded path, but the proxy forwards the raw one
and httpx removes its dot segments, so /website/mail/public%2Fx/../agentenv
passed the guard and reached the site as /agentenv. The guard now also
checks the path the site's server receives: the forwarded URL as httpx
normalizes it, decoded.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…s website/v1 ready (FD-4683)

The env card is the protocol layer, so a site's readiness is read from
it, as computer-app/v1's ready is read of an app: once the gateway
serves its card, the deploy reads each site's card through
/svc/<name>/ and polls website/v1's ready until it says so, failing
after 300s naming each site's problems. A site whose card has no ready,
or that serves no card, is read at its stored health path instead,
with a deprecation warning. The compose health check now only says the
server is up: it answers its card, or for a site serving none its
health path.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
# Conflicts:
#	tst/unit/providers/env_providers/env_gateway_provider_test.py
…D-4683)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… isn't reserved, not in a comment (FD-4683)

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
williamloo-scale and others added 3 commits November 2, 2026 17:50
…ead of being skipped (FD-4683)

Without a stored card, v1_base_url probed a website with supports_v1, which reads a timeout, a 5xx or a
connection error as "legacy", so snapshot_env skipped the website as one serving no data plane and the
snapshot could succeed without its state. A website's live probe is now a card read that is None only on
a 404 and raises otherwise, so export_one fails that website and the snapshot with it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…e or registry write (FD-4683)

`agent-env env website put` now checks --health-path with health_path_problem right after its other option
checks, so a path like `healthz` no longer costs a build or leaves a saved image artifact behind.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Base automatically changed from wloo/web-apps-verifier to wloo/web-apps-deploy November 3, 2026 17:59
Base automatically changed from wloo/web-apps-deploy to wloo/web-app-contract November 3, 2026 18:00
williamloo-scale and others added 2 commits November 3, 2026 10:22
#391 and #392 were squash-merged into wloo/web-app-contract, which then
gained the deploy's refusal of a site serving a page at its card's path;
this branch's copies of those commits conflict line for line with the
squash, so the provider takes the base's code and the tests keep both
sides.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

This branch has not been deployed

No deployments
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