Commit Graph
3 Commits
Author SHA1 Message Date
kevinveenbirkenbachandClaude Opus 5 d9f8af9b16 fix(ci): refuse a mesh pin the row cannot take
A selection token may pin the mesh state as &vpn or &direct, but check_pins
had no arm for it. pinned_vpn_states intersects the pin with the states the
mode allows and only swarm meshes, so a token like @compose+clearnet&vpn left
an empty state list: the row produced no job at all and the run reported green
for a combination that never deployed. That is the outcome _reject exists to
prevent, and every sibling axis already refuses an impossible pin.

The new arm asks whether any candidate mode keeps a state rather than whether
the pin is reachable, so a held vpn axis still overrides the pin instead of
being refused. That behaviour has its own test and is unchanged.

An earlier check was removed with the compose-mesh revert of 2026-10-16
because it rested on meshable() and smallest_variant(), which that revert
deleted. This one reuses pinned_vpn_states, applies to the swarm-only axis the
revert restored, and covers both mesh states instead of only &vpn.

pin_vpn and vpn_mode now reach check_pins from all three callers. The run's
vpn axis reaches the validation job through call-orchestrator and
call-validation, which passed every other axis but this one. The priority
procedure and its skill state all eight axes a token carries, not six:
architecture and mesh were pinnable and, for architecture, already validated,
yet neither was documented.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-21 18:13:54 +02:00
kevinveenbirkenbachandClaude Opus 5 1c1432a7f0 docs(agents): pin every axis in every priority token
The runbook let an axis fall back to the rotation whenever the measurement could not carry it, and that is exactly what happened on its first real run: distro and filesystem had one measured value each, so they went in as run-level inputs instead of into the tokens. A row the rotation may still move is not a verification row, because the combination that comes back is not the one the question was asked about.

The measurement now decides which value an axis takes, never whether it takes one. Too few samples moves the choice one rung down instead of opening the axis: the value the row failed in, then the only value seen at all, then the pool default. Which rung a pin came from belongs in the report, because a pool-default pin is a guess wearing a token.

The run-level axis inputs are gone with it. A pool of exactly one refuses every token naming the other value, so a line that verifies a swarm question and a compose question at once needs auto at run level and a pin per token. Proven: agent-broker compose+clearnet, agent-broker swarm+clearnet and matomo swarm+tor, all six axes pinned, validate clean in one line against --modes auto --tor auto.

Nothing enforces this mechanically yet. A token without %distro/filesystem still validates, because the validator checks existence, not completeness.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-23 12:38:05 +02:00
kevinveenbirkenbachandClaude Opus 5 8b16697378 docs(agents): a runbook for leading a CI run with a priority line
The measurement and the dispatch flags landed in the two previous commits and are useless without the order they go in. This is that order: collect at most 20 candidates, run verdicts first and open root causes after; measure the axes instead of asserting them; pin the cheap value only where the axis is not part of the question; validate; dispatch with the workspace test and the chunk gate off; then report which question the run will not answer.

The filesystem gets its own step because it is the only axis with a host condition: resolve.sh serves a kind only when the host kernel carries it, while the distro images carry just the userland, and a pool or token of exactly one kind is read as a demand, so the row fails instead of substituting. It is pinned only when the samples support it and no fallback was reported.

Measured on this branch on 2026-09-23: compose 47m against swarm 83m, clearnet 52m against tor 79m, over six runs. Those numbers live here rather than in the policy files, where nobody would recompute them.

The validation step is written as mandatory because it earned it: run against a 20-token line it caught 'web-svc-openresty', which does not exist under that name, and separated it from 'web-app-minio', which warns because its lifecycle is eol. A dispatch would have lost the first candidate silently and still reported green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-23 12:22:05 +02:00