fix(ci): offer multi to bond-less rows whose deploy pulls Tor in

A role without a Tor bond only took clearnet rows, and clearnet rows disable
Tor. svc-ai-litellm (variants 0 and 2) and web-app-seaweedfs (variant 0) still
pull the Tor provider in through their dependencies, so they ran on a node
with Tor about half the time under the tor axis and never under the network
axis.

row_states now gives such a row clearnet and multi. Whether the deploy pulls
the provider in is read from the services closure the discovery row already
carries, which matched the deploy's own include resolution on all 33 rows
without a bond. A row whose deploy contains no Tor provider stays clearnet
only, because NETWORK_MODE=multi without the provider fails the deploy, and a
gate pinned false still means clearnet. The matrix and the selection
validator pass the same flag, so a +multi pin agrees with the matrix.
tor_capable lost its last caller and is gone.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
kevinveenbirkenbachandClaude Opus 5.5 committed 2026-09-24 22:42:55 +02:00
1 parent 6314938133
commit 098b0caffc
7 files changed
+117 -51

No files matched your search

+29 -1
View File
@@ -6,7 +6,7 @@ import unittest.mock as mock
from contextlib import redirect_stderr, redirect_stdout
from cli.meta.ci import validate
from utils.github.variant import axes
from utils.github.variant import axes, network
_ROWS = [
{"name": "web-app-a", "variant": 0, "test_compose": True, "test_swarm": True},
@@ -91,6 +91,34 @@ class TestProblems(unittest.TestCase):
)
self.assertEqual((errors, warnings), ([], []))
def test_a_role_without_a_bond_may_pin_multi_when_its_deploy_pulls_tor(
self,
) -> None:
rows = [
{
"name": "web-app-c",
"variant": 0,
"test_compose": True,
"services": [network.tor_provider()],
}
]
with (
mock.patch.object(validate.query, "discover_rows", return_value=rows),
mock.patch.object(
validate, "get_variants", return_value={"web-app-c": [{"services": {}}]}
),
):
problems = validate.problems(
"web-app-c#0@compose+multi",
modes=("compose",),
network_input="auto",
distros=axes.DISTROS,
filesystems=axes.FILESYSTEMS,
lifecycles="",
label="priority",
)
self.assertEqual(problems, ([], []))
def test_a_warning_still_separates_a_missing_role_from_a_present_one(self) -> None:
_errors, warnings = _problems("web-app-a web-app-gone web-app-b")
self.assertEqual(len(warnings), 1)