[PR #4999] [MERGED] feat(environment): export an environment manifest as an agent environment bundle #6719

Closed
opened 2026-11-01 21:42:31 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/4999
Author: @earakely-scale
Created: 10/18/2026
Status: ✅ Merged
Merged: 10/19/2026
Merged by: @gensokyo-dev

Base: main ← Head: feat/environment-export


📝 Commits (10+)

  • 46dd8f0 feat(mcp): serve the MCP server over streamable HTTP
  • b0ec63c fix(mcp): harden the streamable HTTP listener's session replacement and shutdown
  • 9ed8f06 fix(mcp): compare the media type proper and bind before creating the server
  • b76f354 fix(mcp): classify loopback from the bound address and keep startup failures out of onerror
  • fb22df3 fix(mcp): match Accept ranges exactly and keep a session whose shutdown failed
  • 54a7475 refactor(mcp): release the listener through one helper
  • 1741882 fix(mcp): fire the shutdown hook once, stop awaiting the probe's tee and keep every Set-Cookie
  • 354b4d8 fix(mcp): latch startup signals so the HTTP entry never ends without cleanup
  • 136d073 fix(mcp): keep a startup signal's exit status through the entry's normal return
  • a23f5f1 fix(mcp): close the connection after a reply sent before the body was read

📊 Changes

40 files changed (+4037 additions, -107 deletions)

View changed files

📝 .github/workflows/ci.yml (+11 -1)
➕ .github/workflows/real-agentenv.yml (+82 -0)
📝 docs/agent-environments.md (+90 -1)
📝 docs/cli.md (+38 -0)
➕ docs/specs/agent-environments/environment-export/plan.md (+25 -0)
➕ docs/specs/agent-environments/environment-export/spec.md (+116 -0)
➕ docs/specs/agent-environments/environment-export/tasks.md (+12 -0)
➕ docs/specs/agent-environments/environment-export/verification.md (+362 -0)
📝 docs/testing.md (+65 -3)
📝 package.json (+1 -0)
📝 scripts/ci/scopes.mjs (+15 -0)
➕ scripts/verify-agentenv-environment.mjs (+358 -0)
📝 src/application/JsonInputFile.ts (+27 -9)
➕ src/application/OwnedJsonInput.ts (+54 -0)
📝 src/application/RegularFileRead.ts (+3 -0)
➕ src/application/environment/environmentBundle.test.ts (+274 -0)
➕ src/application/environment/environmentBundle.ts (+340 -0)
➕ src/application/environment/environmentBundleWrite.test.ts (+203 -0)
➕ src/application/environment/environmentBundleWrite.ts (+194 -0)
➕ src/application/environment/environmentExport.test.ts (+342 -0)

...and 20 more files

📄 Description

Change

rea environment-export manifest.json --evidence capture.json ./bundle writes an authenticated, byte-exact capture/manifest pair as an agentenv bundle with a Dockerfile, pinned package, verifier, smoke task and provenance. --package-tarball supports an unreleased checkout. This remains the original author’s PR, updated from main after #4955/#4975 and their followups.

Followups share immutable JSON at its owning boundary, preflight the served discovery budget, use the shared output-tree identity/cleanup owner, retain one admitted tarball descriptor, verify POSIX modes independently of umask, preserve caller path semantics, and return tagged input/cleanup failures. Unicode inventory comparison retains file identities and distinct Linux names. The verifier checks the actual framework version and selected npm entrypoint. Default rea mcp stays stdio; environment HTTP is explicit.

Validation

Linux x64, pinned Node 24.18.0 / npm 11.16.0:

  • Typecheck, runtime build, lint, formatting, generated documentation and unused-code checks passed. 452 focused tests in 33 files plus ten product-catalog checks passed, including compiled CLI/SDK/lifecycle, output identity, cleanup retry and npm selection.
  • Four real captured public GitHub responses: generated Dockerfile built unchanged with the checkout tarball; a fresh non-root container replayed each response twice through the official MCP SDK with exact body/status/Evidence/provenance. Input copies, discovery/card parity, package removal and cleanup passed. Warm base-image complete task: 40.699 s / 8.274 s process CPU / 421.04 MiB peak family RSS.
  • Real agent-env 0.9.1334: five public cases and exported smoke task passed; sandbox torn down with no new task containers or supervised descendants. Prepared infrastructure: Final committed head 5977cf477 was rerun with the actual selected npm: 165.003 s / 93.482 s CPU / 501.29 MiB. All five cases and smoke passed, with no residual task containers or descendants; Unicode/close/npm boundary regressions also passed.
  • Heavy tasks run serially on one CPU; Docker build/runtime bounds are 4/2 GiB. Final typecheck/build/lint peak: 4449.45 MiB family RSS. RSS is sampled descendants, potentially double-counting shared pages; Docker daemon/container peaks/CPU and agent tokens are unmeasured.

Matched before/after export ownership task: elapsed 1.827/2.604 s, CPU 1.807/2.545 s, family RSS 316.43/334.11 MiB. A separate matched serve+21 SDK replay comparison likewise does not establish overall speed/memory improvement. Full commands, cold/warm distinctions, earlier failed attempts, measurements and coverage limits are in docs/specs/agent-environments/environment-export/verification.md.

Scope: historical response replay without application-state reconstruction. The checkout package was tested; the published registry package and actual Windows/HFS+ were not. Windows privacy follows the destination ACL; portable writes require a trusted destination and parents. No new MCP tool or dependency. The original author’s initial readiness declaration is preserved below.

Author readiness

Human owner: @earakely-scale

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

🤖 Generated with Claude Code


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/4999 **Author:** [@earakely-scale](https://github.com/earakely-scale) **Created:** 10/18/2026 **Status:** ✅ Merged **Merged:** 10/19/2026 **Merged by:** [@gensokyo-dev](https://github.com/gensokyo-dev) **Base:** `main` ← **Head:** `feat/environment-export` --- ### 📝 Commits (10+) - [`46dd8f0`](https://github.com/morluto/rea/commit/46dd8f0e2b5ff74e09821e09e51bc6fd47f3bc1a) feat(mcp): serve the MCP server over streamable HTTP - [`b0ec63c`](https://github.com/morluto/rea/commit/b0ec63cc0399ad9ca7bd00a65cb1c2d753cfd47b) fix(mcp): harden the streamable HTTP listener's session replacement and shutdown - [`9ed8f06`](https://github.com/morluto/rea/commit/9ed8f06f75ea772dfd81d552142b059852e530c3) fix(mcp): compare the media type proper and bind before creating the server - [`b76f354`](https://github.com/morluto/rea/commit/b76f354d76384abe56b079b0b37e1367d1908efd) fix(mcp): classify loopback from the bound address and keep startup failures out of onerror - [`fb22df3`](https://github.com/morluto/rea/commit/fb22df370b5146b3798b6f83e64317e2785ecfcb) fix(mcp): match Accept ranges exactly and keep a session whose shutdown failed - [`54a7475`](https://github.com/morluto/rea/commit/54a747560207c06196a1ba4eb8b8ca062f15ddc5) refactor(mcp): release the listener through one helper - [`1741882`](https://github.com/morluto/rea/commit/174188279b6ce482354966ed542436514d3d4624) fix(mcp): fire the shutdown hook once, stop awaiting the probe's tee and keep every Set-Cookie - [`354b4d8`](https://github.com/morluto/rea/commit/354b4d8c0867f3d0eadaae2b0dfe42cea810287e) fix(mcp): latch startup signals so the HTTP entry never ends without cleanup - [`136d073`](https://github.com/morluto/rea/commit/136d073fa019fb8a1c5ef95ff70ecaf6d34676c4) fix(mcp): keep a startup signal's exit status through the entry's normal return - [`a23f5f1`](https://github.com/morluto/rea/commit/a23f5f13524b5403794f3599e26f93cc18398820) fix(mcp): close the connection after a reply sent before the body was read ### 📊 Changes **40 files changed** (+4037 additions, -107 deletions) <details> <summary>View changed files</summary> 📝 `.github/workflows/ci.yml` (+11 -1) ➕ `.github/workflows/real-agentenv.yml` (+82 -0) 📝 `docs/agent-environments.md` (+90 -1) 📝 `docs/cli.md` (+38 -0) ➕ `docs/specs/agent-environments/environment-export/plan.md` (+25 -0) ➕ `docs/specs/agent-environments/environment-export/spec.md` (+116 -0) ➕ `docs/specs/agent-environments/environment-export/tasks.md` (+12 -0) ➕ `docs/specs/agent-environments/environment-export/verification.md` (+362 -0) 📝 `docs/testing.md` (+65 -3) 📝 `package.json` (+1 -0) 📝 `scripts/ci/scopes.mjs` (+15 -0) ➕ `scripts/verify-agentenv-environment.mjs` (+358 -0) 📝 `src/application/JsonInputFile.ts` (+27 -9) ➕ `src/application/OwnedJsonInput.ts` (+54 -0) 📝 `src/application/RegularFileRead.ts` (+3 -0) ➕ `src/application/environment/environmentBundle.test.ts` (+274 -0) ➕ `src/application/environment/environmentBundle.ts` (+340 -0) ➕ `src/application/environment/environmentBundleWrite.test.ts` (+203 -0) ➕ `src/application/environment/environmentBundleWrite.ts` (+194 -0) ➕ `src/application/environment/environmentExport.test.ts` (+342 -0) _...and 20 more files_ </details> ### 📄 Description ## Change `rea environment-export manifest.json --evidence capture.json ./bundle` writes an authenticated, byte-exact capture/manifest pair as an agentenv bundle with a Dockerfile, pinned package, verifier, smoke task and provenance. `--package-tarball` supports an unreleased checkout. This remains the original author’s PR, updated from main after #4955/#4975 and their followups. Followups share immutable JSON at its owning boundary, preflight the served discovery budget, use the shared output-tree identity/cleanup owner, retain one admitted tarball descriptor, verify POSIX modes independently of umask, preserve caller path semantics, and return tagged input/cleanup failures. Unicode inventory comparison retains file identities and distinct Linux names. The verifier checks the actual framework version and selected npm entrypoint. Default `rea mcp` stays stdio; environment HTTP is explicit. ## Validation Linux x64, pinned Node 24.18.0 / npm 11.16.0: - Typecheck, runtime build, lint, formatting, generated documentation and unused-code checks passed. 452 focused tests in 33 files plus ten product-catalog checks passed, including compiled CLI/SDK/lifecycle, output identity, cleanup retry and npm selection. - Four real captured public GitHub responses: generated Dockerfile built unchanged with the checkout tarball; a fresh non-root container replayed each response twice through the official MCP SDK with exact body/status/Evidence/provenance. Input copies, discovery/card parity, package removal and cleanup passed. Warm base-image complete task: 40.699 s / 8.274 s process CPU / 421.04 MiB peak family RSS. - Real `agent-env 0.9.1334`: five public cases and exported smoke task passed; sandbox torn down with no new task containers or supervised descendants. Prepared infrastructure: Final committed head `5977cf477` was rerun with the actual selected npm: **165.003 s / 93.482 s CPU / 501.29 MiB**. All five cases and smoke passed, with no residual task containers or descendants; Unicode/close/npm boundary regressions also passed. - Heavy tasks run serially on one CPU; Docker build/runtime bounds are 4/2 GiB. Final typecheck/build/lint peak: 4449.45 MiB family RSS. RSS is sampled descendants, potentially double-counting shared pages; Docker daemon/container peaks/CPU and agent tokens are unmeasured. Matched before/after export ownership task: elapsed 1.827/2.604 s, CPU 1.807/2.545 s, family RSS 316.43/334.11 MiB. A separate matched serve+21 SDK replay comparison likewise does not establish overall speed/memory improvement. Full commands, cold/warm distinctions, earlier failed attempts, measurements and coverage limits are in `docs/specs/agent-environments/environment-export/verification.md`. Scope: historical response replay without application-state reconstruction. The checkout package was tested; the published registry package and actual Windows/HFS+ were not. Windows privacy follows the destination ACL; portable writes require a trusted destination and parents. No new MCP tool or dependency. The original author’s initial readiness declaration is preserved below. ## Author readiness Human owner: @earakely-scale - [x] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [x] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [x] I declare this PR ready for initial maintainer review. ## Before merge - [x] This PR addresses a concrete problem or an agreed enhancement. - [x] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [x] The PR has one focused outcome and the title follows `type(scope): outcome`. - [x] Related issue is linked, or the reason for not linking one is stated above. - [x] Tests cover changed observable behavior and meaningful failure paths. - [x] Owning docs, contracts, and generated metadata are updated where needed. - [x] User-visible CLI/MCP changes include representative output. - [x] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-11-01 21:42:31 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#6719
No description provided.