Skip to content

chore(deps)(deps): bump the cargo-minor-patch group across 1 directory with 2 updates - #6

Merged
github-actions[bot] merged 1 commit into
mainfrom
dependabot/cargo/cargo-minor-patch-fc9d4d6c09
May 10, 2026
Merged

github-actions[bot] merged 1 commit into
mainfrom
dependabot/cargo/cargo-minor-patch-fc9d4d6c09

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github May 10, 2026 •

Copy link
Copy Markdown
Contributor

⚠️ Dependabot is rebasing this PR ⚠️

Rebasing might not happen immediately, so don't worry if this takes some time.

Note: if you make any changes to this PR yourself, they will take precedence over the rebase.


Bumps the cargo-minor-patch group with 2 updates in the / directory: tokio and rustls.

Updates tokio from 1.52.1 to 1.52.3

Release notes

Sourced from tokio's releases.

Tokio v1.52.3

1.52.3 (May 8th, 2026)

Fixed

  • sync: fix underflow in mpsc channel len() (#8062)
  • sync: notify receivers in mpsc OwnedPermit::release() method (#8075)
  • sync: require that an RwLock has max_readers != 0 (#8076)
  • sync: return Empty from try_recv() when mpsc is closed with outstanding permits (#8074)

#8062: tokio-rs/tokio#8062 #8074: tokio-rs/tokio#8074 #8075: tokio-rs/tokio#8075 #8076: tokio-rs/tokio#8076

Tokio v1.52.2

1.52.2 (May 4th, 2026)

This release reverts the LIFO slot stealing change introduced in 1.51.0 (#7431), due to [its performance impact]#8065. (#8100)

#7431: tokio-rs/tokio#7431 #8065: tokio-rs/tokio#8065 #8100: tokio-rs/tokio#8100

Commits

Updates rustls from 0.23.39 to 0.23.40

Commits
  • b44c09f Prepare 0.23.40
  • e7a555f Prefer Ord::max to core::cmp
  • c0005be ech: base inner name padding on actual extension
  • 4e49529 ech: test inner name padding
  • 3e06ef1 ech: add both name and "gross" padding
  • c574ffd ech: avoid short-lived allocation for padding
  • 8bf935c ech: pop comment from match arm
  • 9088004 ech: expand maximum_name_length to usize ASAP
  • a612901 Default require_ems based on CryptoProvider FIPS status
  • See full diff in compare view

@dependabot dependabot Bot added dependencies Pull requests that update a dependency file rust Pull requests that update rust code labels May 10, 2026
@nikhilunni

Copy link
Copy Markdown
Contributor

@dependabot recreate

…y with 2 updates

Bumps the cargo-minor-patch group with 2 updates in the / directory: [tokio](https://github.com/tokio-rs/tokio) and [rustls](https://github.com/rustls/rustls).


Updates `tokio` from 1.52.1 to 1.52.3
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](tokio-rs/tokio@tokio-1.52.1...tokio-1.52.3)

Updates `rustls` from 0.23.39 to 0.23.40
- [Release notes](https://github.com/rustls/rustls/releases)
- [Changelog](https://github.com/rustls/rustls/blob/main/CHANGELOG.md)
- [Commits](rustls/rustls@v/0.23.39...v/0.23.40)

---
updated-dependencies:
- dependency-name: rustls
  dependency-version: 0.23.40
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: cargo-minor-patch
- dependency-name: tokio
  dependency-version: 1.52.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: cargo-minor-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot changed the title chore(deps)(deps): bump the cargo-minor-patch group with 2 updates chore(deps)(deps): bump the cargo-minor-patch group across 1 directory with 2 updates May 10, 2026
@dependabot
dependabot Bot force-pushed the dependabot/cargo/cargo-minor-patch-fc9d4d6c09 branch from d9ff973 to b09f0d1 Compare May 10, 2026 22:41

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Auto-approved: version-update:semver-patch via Dependabot.

@github-actions
github-actions Bot enabled auto-merge (squash) May 10, 2026 22:42
@github-actions
github-actions Bot merged commit 957a39d into main May 10, 2026
9 checks passed
@dependabot
dependabot Bot deleted the dependabot/cargo/cargo-minor-patch-fc9d4d6c09 branch May 10, 2026 22:44
nikhilunni added a commit that referenced this pull request May 11, 2026
Adds `Ca::from_pem(cert_pem, key_pem)` so the coordinator can load
the CA from k8s-Secret-projected env vars instead of generating a
fresh keypair onto local disk on every pod restart. Without this,
every stateless replica restart invalidates every live VM's trust
store.

`build_egress_proxy` now prefers `ENGRAM_EGRESS_CA_CERT_PEM` +
`_KEY_PEM` when set; falls back to local-disk load-or-generate for
dev (`--mode=all`) and single-host workflows.

V1 keeps the proxy itself on the coordinator. The full "proxy per
FC host-agent" topology (chosen in the deploy plan) needs two
follow-ups that aren't blocking the initial deploy: cross-machine
session-policy delivery, and substrate CA injection in the
production `ensure_harness_ext4` path. Documented both in
deploy.md and known-issues.md (#6).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
nikhilunni added a commit that referenced this pull request May 11, 2026
Three stale spots actively contradicted the current codebase:

- The ADR preamble listed 0001-0003 only. ADRs 0004 + 0005 are
  load-bearing today (ADR 0005 reversed 0001's "blob storage retired"
  and amended 0002's "session lifetime is host-bounded" contract);
  added 0004, 0005, 0006 + a pointer to docs/deploy.md.

- The "~BlobStorage~ retired" section described tearing out the cold-
  tier subsystem; ADR 0005 brought it back as the cross-host
  durability primitive. Replaced with the real trait + impls
  (engram-storage-{gcs,s3,local}) and the flush pipeline shape.

- The Postgres schema sketch had drifted hard (no session_events,
  no enabled_images, no harness_packs, no registry_credentials, no
  session_secrets, no sealed-blob-ref columns on snapshots).
  Replaced with a short table inventory + pointer to
  deploy/migrations/ as the source of truth.

Also fixed the architecture diagram (cold-tier flush to BlobStorage,
not git push to a Git remote), the goal-#6 wording ("recoverable
from host loss" instead of "snapshot loss"), and the
component-summary paragraph that still claimed snapshots aren't
replicated.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
nikhilunni added a commit that referenced this pull request May 11, 2026
The architectural decision record for what the previous eight
commits actually built. Captures the iptables-locality constraint
that forces host-agent ownership of the proxy, the CaSource
abstraction for pluggable cloud backends, and the WS-notify
sequencing invariant that keeps policy in place before the
harness starts.

Also:
  - docs/deploy.md egress section rewritten to describe the
    host-agent topology + per-`CaSource`-impl env vars + the
    Workload Identity production setup.
  - docs/known-issues.md #6 closed, pointing at the new ADR.
  - DESIGN.md ADR preamble updated to reflect the shipped decision
    (previously listed v2 deferral; that's no longer accurate).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
nikhilunni added a commit that referenced this pull request May 12, 2026
Phase 5 follow-up #32 slice 1: plumb the per-image bake-time
canonical memory manifest through the type system end-to-end.
The image-builder doesn't yet auto-populate it (slice 2 of #32
implements the bake-time FC boot+pause+chunk dance), but the
wiring is in place — once an operator pre-computes a canonical
ref on a sidecar Linux+KVM job, the field flows cleanly from
`bundle.json` → `CachedImage.bundle.canonical_memory_manifest`
→ `SandboxSpec.canonical_memory_manifest` → `FcSnapshotManifest.
canonical_memory_manifest` → UFFD handler's `--canonical-manifest`.

Plumbing:
- `engram_core::types::sandbox::SandboxSpec.canonical_memory_manifest`
  (new, `#[serde(default)]` — pre-existing specs round-trip).
- `engram_host_agent::image_cache::ImageBundle.canonical_memory_manifest`
  (new, serde-default).
- `engram_image_builder::BuildRequest.canonical_memory_manifest` —
  optional pre-computed ref; written to `bundle.json` verbatim.
- `engram_sandbox_firecracker::FcSnapshotManifest.
  canonical_memory_manifest` — now sourced from
  `spec.canonical_memory_manifest` at snapshot time (was
  hardcoded `None`). UFFD restore sees the canonical ref from
  the FC sidecar JSON the way it always has.
- `PooledBackend::create()` lifts
  `cached.bundle.canonical_memory_manifest` onto
  `spec.canonical_memory_manifest` after image-cache resolve.

Mass-edit: 18 `SandboxSpec { ... }` literals across the workspace
(coord, sandbox-process, sandbox-vz, sandbox-firecracker tests,
host-agent, protocol) gain `canonical_memory_manifest: None`.
Same for 5 `BuildRequest` literals and 2 `ImageBundle` test
constructors.

ADR 0007 e2e test suite (`crates/engram-host-agent/tests/
adr_0007_e2e.rs`):
- **#1 — snapshot path patches sidecar JSON's memory_manifest +
  chunks memory.bin into the store**: fake FC backend writes the
  on-disk shape a real FC snapshot produces; PooledBackend.snapshot
  chunks the emitted memory.bin and patches the JSON. Asserts
  metadata.memory_manifest is set, the JSON sidecar carries the
  matching ref, and `materialize_to_file` round-trips byte-for-byte.
- **#2 — cross-host restore materialises memory.bin from chunks**:
  host A creates + snapshots; the local memory.bin is then deleted
  to simulate cross-host transfer (only state.bin + manifest.json
  staged); host B's PooledBackend (sharing the chunk store) calls
  restore — the wrap materialises memory.bin from the chunked
  memory_manifest before inner.restore sees it. Asserts the inner
  backend sees a fully-formed snapshot dir + bytes round-trip.
- **#3 — trace_host_hint round-trips through sidecar JSON**: the
  snapshotting host's id flows through serde so a cross-host
  restoring backend can pass `--prefault-trace <hint>` to the UFFD
  handler.
- **#4 — bundle.canonical_memory_manifest lifts onto SandboxSpec**:
  validates the wire shape so the canonical ref survives bundle
  → spec → snapshot manifest plumbing.
- **#5 — content-addressed dedup across sessions**: same bytes
  chunked twice produce identical hashes (the property the
  cross-session dedup story relies on).
- **#6 — Linux + nbd-module-gated NBD daemon spawn** (`#[ignore]`,
  validates the disk-side end-to-end on the dev VM): builds a
  disk manifest, attaches a real NBD daemon against `/dev/nbd0`,
  drops cleanly.

Pure Rust, no FC, no KVM, no real kernel — runs in 0.42s on
every CI lane (macOS + Linux). The Linux+KVM-gated tests for
real FC + real NBD live in `crates/engram-sandbox-firecracker/
tests/snapshot_uffd.rs` + the planned `nbd_chunked_disk.rs`
(task #34).

206 unit + integration tests pass workspace-wide:
- engram-host-agent lib: 85
- engram-host-agent adr_0007_e2e: 5
- engram-sandbox-firecracker lib: 38
- engram-image-builder lib: 15
- engram-core lib: 25
- engram-coordinator lib: 43
- (the new test file adds 5 + 1 ignored)

clippy + fmt clean on macOS; Linux check clean via dev VM.
nikhilunni added a commit that referenced this pull request May 20, 2026
Session bb3dd147 surfaced two additional issues for the
post-M1.16 follow-up queue:

#6: Shell tab architecturally broken from k8s coord.
    Coord opens ws://<guest_ip>:7681/ws directly, but
    10.200.0.0/24 lives behind FC host TAPs — coord pod
    has no route. Worked in dev (single-VM); never worked
    from k8s. Failure mode: connect to ttyd: IO error:
    Connection timed out. M1.16's per-VM netns + bake-time
    networking gave the VM an eth0 but didn't add a path
    from coord. Fix: tunnel the shell through host-agent's
    gRPC channel via a new ProxyShell bidi-streaming RPC.

#7: NBD manifest version conflict still surfacing despite
    fix #2 (commit de0abcb). Either retry exhausts, hits a
    different code path, or has a bug in the retry loop.
    Self-recovering so lower urgency. Verify via re-read
    of disk_daemon/backend.rs::flush and a unit test with
    a mock that returns VersionConflict once.

Pointers section gains entry points for both, and the
attack order interleaves #6 as a self-contained parallel
shippable alongside #1/#2.

Production state snapshot block updated: bb3dd147 added
to the list of confirming sessions (alongside b511cf9b).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
nikhilunni added a commit that referenced this pull request May 20, 2026
ADR 0014 issue #6. Coord pods in GKE have no route to the per-VM
`guest_ip` (10.200.0.x lives behind a TAP on the FC host VM, or
behind a per-VM netns for warm-restored sandboxes), so coord's
pre-M1.16 direct WebSocket to `ws://<guest_ip>:7681/ws` always
times out from prod ("shell proxy ended with error … connect to
ttyd: IO error: Connection timed out" in Cloud Logging). Worked
in `--mode=all` dev where coord and host-agent share a host's
network namespace; never worked from k8s.

The fix tunnels WS frames through the existing coord ↔ host-agent
gRPC channel:

- New bidi `rpc ProxyShell(stream ProxyShellFrame) returns (stream
  ProxyShellFrame)` in host_service.proto. First inbound frame
  carries sandbox_id; subsequent frames carry only kind + data
  (+ close_code/close_reason for CLOSE).
- New trait surface in `engram-core`:
  - `SandboxBackend::netns_name_for(id)` — default None; FC
    returns `Some("engr-vm-<id>")` for warm-restored sandboxes.
  - `HostClient::proxy_shell(sandbox_id) -> ShellTunnel` — default
    NotFound; LocalHostClient and GrpcHostClient implement.
  - `engram_core::types::shell::{ShellFrame, ShellTunnel,
    ShellTunnelEnds, ShellClose}` — in-process WS-frame
    representation that doesn't leak proto types into the trait.
- New `engram-host-agent::proxy_shell` module: cold-path dials
  ttyd via `tokio_tungstenite::connect_async` from host root;
  warm-path opens a TCP socket inside the per-VM netns via
  `setns(CLONE_NEWNET)` on Tokio's blocking pool, restores root
  netns, then runs the WS handshake over the resulting
  `tokio::net::TcpStream` wrapped in `MaybeTlsStream::Plain`.
- gRPC server and client wire ProxyShellFrame ↔ ShellFrame.
- coord/api/shell.rs rewritten: open a ShellTunnel via
  `host.proxy_shell(sandbox_id)`, bridge Axum WS ↔ ShellTunnel.
  Drops GUEST_TTYD_PORT and the connection-refused retry loop
  (both now live on the host-agent side where they can actually
  observe ttyd's bind).

Tests added:

- `proxy_shell::tests::pump_round_trips_binary_frames` — covers
  the frame translation table in both directions over an in-memory
  WS.
- `pump_round_trips_text_and_close` — Text + Close variants
  exercise the rest of the translation matrix.
- `open_shell_tunnel_at_connects_and_round_trips` — full
  `connect + handshake + pump` round-trip via a fake ttyd on a
  localhost port (the production `open_shell_tunnel` wraps this
  with `TTYD_PORT = 7681`).
- `open_shell_tunnel_at_errors_when_server_absent` — connect
  failure surfaces synchronously as `SandboxError::Vm` instead
  of leaving zombie pumps.

All 753 tests pass; `just check` clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
nikhilunni added a commit that referenced this pull request May 20, 2026
ADR 0014 issue #6 follow-up. The host-agent's new ProxyShell tunnel
dials the in-guest ttyd from host root (cold path) or per-VM netns
(warm path). Either way, the guest's SYN+ACK return packet comes
back to host root with src=10.200.0.x dst=10.200.0.1 and hits the
INPUT chain. Pre-fix, only specific dports (8443, 5353) had ACCEPT
rules; the blanket `engram-host-input DROP` caught everything else
including the ephemeral src ports the host kernel picks for
host-initiated dials. Result: every host→VM TCP connection hung
until ETIMEDOUT.

Observed in prod on session 379abfec (2026-05-20): coord logged
"proxy_shell tunnel open failed; closing browser WS … connect to
ttyd: IO error: Operation timed out (os error 110)" while
`curl http://10.200.0.2:7681/` from the host root timed out with
the same shape. ARP resolved (`REACHABLE`); the L2 path was fine.
The SYN+ACK was being dropped by iptables INPUT rule 4.

Fix: insert a conntrack ACCEPT for ESTABLISHED,RELATED from the
pool *before* the blanket DROP. Only permits return traffic for
flows the host initiated — does NOT widen VM-initiated attack
surface (new VM→host flows still hit the DROP).

Tested via:
- new `host_startup_accepts_established_input_before_drop` unit
  test pins both the rule's presence and its ordering relative
  to the DROP, in both proxy and no-proxy modes.
- Adjusted `host_startup_with_proxy_redirects_dns_through_filtering_proxy`
  and `host_startup_proxy_input_accept_comes_before_drop` to match
  on `"comment engram-host-input "` instead of substring
  `"engram-host-input"`, since the new rule's comment string
  contains that substring as a prefix.

All 7 net::tests::host_startup_* tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
nikhilunni added a commit that referenced this pull request Jul 17, 2026
engrams-agent Bot added a commit that referenced this pull request Aug 8, 2026
tokio-tungstenite 0.24 has no API change that reaches production code —
`proxy_shell.rs` compiles unchanged. What it does change is handshake
STRICTNESS, and that is what the two red lanes were.

1. The test's fake ttyd never echoed the subprotocol.

   `ttyd_request_from` sends `Sec-WebSocket-Protocol: tty`, because that
   is what ttyd requires. tungstenite 0.21 ignored what came back; 0.24
   validates it:

     connect to ttyd: WebSocket protocol error:
       SubProtocol error: Server sent no subprotocol

   The test server answered with `accept_async`, which echoes nothing, so
   the fake was the unrealistic side of the pair — real ttyd confirms the
   subprotocol. Fixed by having it answer the handshake explicitly and
   echo what the client offered, and by asserting the client still OFFERS
   `tty`. That assertion matters: the other way to make this green is to
   drop the header from the request, which would silently break the real
   ttyd dial.

   The handshake is spelled out rather than using `accept_hdr_async`
   because that callback must return `Result<Response, ErrorResponse>`,
   `ErrorResponse` is 136 bytes, and `clippy::result_large_err` (denied
   workspace-wide) rejects it. The type is the library's, so it cannot be
   boxed — and writing the 101 out shows exactly what ttyd sends back,
   which is what the test is about.

2. `engram-coordinator` declared `tokio-tungstenite` and never used it.

   No `tokio_tungstenite` reference anywhere under
   `crates/engram-coordinator/src`; the crate builds with the declaration
   removed. The coord side of the shell path goes over gRPC to the
   host-agent (ADR 0014 #6 / ADR 0066), so the WebSocket dependency
   became dead when that moved. Same crate, so it stays on this branch.

The bump is a graph win rather than a cost: `main`'s lockfile carries
tokio-tungstenite 0.21.0 AND 0.24.0, because axum 0.7.9 pulls 0.24. Going
to 0.24 retires the duplicate — one tokio-tungstenite and one tungstenite
after this. Staying below axum 0.8 is also why 0.24 is the right target
rather than the current 0.30: axum 0.7 pins ^0.24, so anything higher
re-introduces a second copy until axum moves.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file rust Pull requests that update rust code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant