Skip to content

Trips is a third fake devpod the conformance corpus does not cover #405

Closed

Description

@blooop

Question

One conformance corpus for both devpod fakes decided there are two fake devpods and a shared corpus keeps them in step. There are three, and the corpus covers two.

Trips (rust/devlaunch-core/src/flows/provision.rs:2371) is a third impl Runner standing in for devpod. It is not a general fake — it answers a recorded script per trip — but it does decide what provision_tools sees devpod do, and it knows the argv convention of the code under test: Trip::script (:2348) finds --command in the recorded argv and returns the next element. Nothing drives it over test/fixtures/devpod/conformance.json.

Decide which it is:

  • a fake devpod that belongs under the corpus, like the other two; or
  • a recording harness that is not pretending to be devpod, in which case say so where it is defined, and say what stops it drifting from the argv setup_pass (:1939-1944) actually builds.

The second looks likelier — it asserts trips rather than emulating a CLI — but the argv coupling is real and undocumented either way.

While there

rust/devlaunch-runner/src/lib.rs:384-385 says the Runner trait is "Implemented once for real processes and once for tests." There are nine implementations:

ProcessRunner (devlaunch-runner/src/lib.rs:419), FakeRunner (devlaunch-test-support/src/fake_runner.rs:370), ScriptedRunner (devlaunch-core/src/testing.rs:88), FakeGit (flows/repo_manager.rs:1855), FakeDevpodRealGit (flows/listing.rs:1208), Devpod (flows/lifecycle.rs:3417), Trips (flows/provision.rs:2463), Rebuilding (flows/provision.rs:4876), StubbedLfs (flows/workspace_clone.rs:4026).

Five of the extras are program-name routers that send git to the real ProcessRunner while faking devpod and docker. That is worth saying in the doc, because it is the seam's actual shape and a reader currently learns it by grepping.

Testing the outcome

If it joins the corpus: a row it fails today. If it does not: the doc change plus whatever guard is chosen for the argv coupling — Trip::script panicking rather than silently returning the wrong element when --command is absent would be the cheap one.

Activity

  1. self-assigned this
    on Aug 24, 2026
  2. blooop commented on Aug 24, 2026

    @blooop
    OwnerAuthor

    agent-decided (Simplicity): Trips is a recording harness, not a third fake devpod. Nothing joins the corpus; the doc is corrected and the existing guard is named where it lives.

    The premise does not survive reading record. A fake devpod is a thing that decides an outcome from argv, and Trips never looks at argv to decide anything — it picks its answer by call index (self.answers[(seen.len() - 1).min(self.answers.len() - 1)], flows/provision.rs:2442) from a list the test handed it. It holds no workspaces, has no Running/Stopped to move between, and does not dispatch on a subcommand at all.

    That is what rules out a corpus row rather than any judgement about tiers. A row is given (seeded workspaces) → argv → exit + then (workspaces afterwards, with state). Trips has no given to seed and no then to read back, and its exit is whatever the test wrote in the constructor. Driving it over conformance.json would assert a fixture against itself — the exact failure mode #309 built the corpus to end.

    The same argument covers the siblings, and it covers them because of where the real fake sits. FakeRunner is "a call recorder, a response table, and a devpod behind them" (devlaunch-test-support/src/fake_runner.rs:1-13), and that devpod is DevpodMachine — the corpus-covered one. ScriptedRunner, FakeGit, FakeDevpodRealGit and Devpod all delegate their devpod calls into FakeRunner, so every one of them already inherits the corpus and none is a separate fake to cover. StubbedLfs fakes git lfs and never sees devpod. Only Trips and Rebuilding (which wraps Trips) bypass FakeRunner, and they can, precisely because they answer nothing from argv. So #309's count of two fake devpods was right: DevpodMachine and devpod_shim.py, one per language, both driven over the table.

    On the argv coupling — the guard the ticket proposed is already in the tree, and the shape it couples to is already a corpus row. Trip::script (:2347-2355) does .position(|arg| arg == "--command").expect("a trip with a --command"): it panics rather than silently returning the wrong element, which is exactly the cheap guard the ticket asked to choose. And the argv setup_pass builds (:1939-1944, devpod ssh <ws> --command <payload>) is not an invention of the harness — --command is in SSH_VALUE_FLAGS (devpod.rs:180) and the corpus already carries "ssh with a workdir and a remote command runs against a running workspace" (conformance.json:258), measured against v0.26.1. So the convention is pinned where devpod behaviour belongs, and drift away from it fails loudly at the read. Adding a second guard would be spending a mechanism on a hazard the code has already closed; what is missing is that none of this is written down where either function is defined.

    The Runner doc count, verified. Nine impl Runner in the workspace, matching the ticket's list. But "five of the extras are program-name routers" is also off: it is three — FakeDevpodRealGit (listing.rs:1208), Devpod (lifecycle.rs:3417) and StubbedLfs (workspace_clone.rs:4026) hold a real ProcessRunner and route to it by program name. FakeGit wraps FakeRunner and adds filesystem effects for git clone; Trips and Rebuilding answer everything themselves. The shape worth stating at devlaunch-runner/src/lib.rs:384-385 is not a count but the two-plus-wrappers structure: one production impl (ProcessRunner), one shared fake (FakeRunner, carrying the response table and DevpodMachine), and seven test-local wrappers over those two — three of which route by program name so the programs they do not fake reach real processes.

    Build: 409.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions