localhost port. Tesser keeps that arrangement on the box.
A dependency is a loopback port declared in the manifest, and Tesser connects
that port to the right instance of the other service, wherever it is
actually running.
API_URL=http://localhost:5001 and nothing in it
needs to change.
Which instance a dependency reaches
A dependency names a service, not a box. The rule has no special cases: a dependency reaches the box you wired it to, otherwise the org’s shared instance of that service (described below), and otherwise nothing —dev still starts the server and prints a warning that
the dependency has nothing behind it, and connections to the port fail loud.
Nothing is ever wired automatically. Two boxes only talk to each other
because someone pointed one at the other:
Reaching a box by name
A wire is for code that expects a fixedlocalhost port. Code that is happy
to name the box can skip the wire entirely: on any of your boxes,
http://<box_id>.localhost:<port> reaches that box’s declared port, the
same address the laptop uses. This is a convenience for scripts and
one-off checks, not a substitute for a dependency, and a port the target does
not declare in its manifest is refused. Every instance box in the org has one,
the shared instances included: a shared instance can dial a dev box that
handed it its address, which is how a dev box registers for webhooks. That is
separate from what a dependency resolves to, described above — a shared
instance’s own deps still never reach anyone’s dev box. See
localhost.
The shared instance
A shared instance runs one service at one specific commit, with no laptop involved. It is what everyone’s boxes use for the services they are not currently working on.setup and dev,
waits for the health check to pass, and makes the box the org’s shared instance of
api. Running the command again with the same commit does nothing and prints
the same box id. Running it with a new commit starts a new box, waits until
the new box is healthy, switches the shared instance over, and then removes the
old box. To roll back, run it again with the previous commit.
Usually CI runs this for each service on every push to main. The box belongs
to the org rather than to a person, so it cannot be synced to, and its env
values come from tesser env set rather than from a file (see
Services).
dev starts only the requested service. Verify its dependencies are running;
use ensure-running to create missing shared instances.
Wiring a dependency
api dependency at a box you choose: your
own dev box of api, a teammate’s box, or an older build. --shared returns
it to the org’s shared instance, and the bare form shows where every
dependency of the box currently points. The panel shows each box’s dependency graph and the resolved laptop routes.
Laptop selection can override individual subtrees without changing these wires.
A wire names a box, and it stays put: if the target box is later removed, the
dependency fails loud rather than silently falling back to the shared
instance. Re-wire it, or return it to --shared.
To see a backend change through a frontend you are not working on, run that
frontend yourself from a worktree at main and wire it back at your box:
tesser dev reuses the box for a worktree and service. In a
monorepo, run the dashboard service from the backend change’s worktree.
When both dashboard and backend depend on hp, wire both to the hp instance
intended for the test. Selecting the dashboard brings all reachable services
to localhost, but does not repair inconsistent remote wiring. The agent
prepares and verifies the graph; the panel selects it.
Tests that need the dependencies
A workbench has no dependencies of its own, because it does not serve anything. For an integration test that expectslocalhost:5432 to be a
database, borrow a service’s dependencies for the run:
api’s dependency ports for as long as the command runs
and releases them afterwards. The ports resolve exactly as they do for
api’s own box in this worktree — its wires included — so the test sees
what the service sees. --in api on its own only changes the working
directory to api’s root.
Names
Service names are shared across the org.api means the same service whether
the manifest lives in this repository or another one, which is what lets a
dependency declared in one repository reach a service declared in another.
Registering a name that another repository already owns is an error.