ADR 0261: an assignment made while its module's build runs is kept pending
The review of mesh-controller#150 found the controller now makes an assignment after the person's act, which no record decided. Decide it, cite it from the glossary and to-be 45, and correct issue 325's account of what is settled where and what is sent.
This commit is contained in:
+90
@@ -0,0 +1,90 @@
|
||||
---
|
||||
topic: what runs on it
|
||||
status: accepted
|
||||
date: 2026-10-08
|
||||
deciders: jochen
|
||||
reconstructed: false
|
||||
---
|
||||
|
||||
# 261. An assignment made while its module's build runs is kept pending, and the controller makes it
|
||||
|
||||
## Context
|
||||
|
||||
Since issue 300's fix, a merge that adds a module asks the build seat for it, and the module is registered
|
||||
when the build's outcome is taken in, minutes later. On 2026-10-08 `assign` was called in that window and
|
||||
answered "no module of that name"
|
||||
([issue 325](../04-ISSUES/325-assign-said-no-such-module-while-its-build-ran/00-report.md)). The controller
|
||||
kept no record of a build it had asked for until the outcome came back, so it could not tell a build in
|
||||
flight from a typo.
|
||||
|
||||
Until now an assignment was always made at the person's act, and refused there if it could not be made.
|
||||
Keeping it for later means the controller makes an assignment after the act, without the person present.
|
||||
That is a new kind of act, and it needs a rule.
|
||||
|
||||
## Considered Options
|
||||
|
||||
1. **Refuse, and say the build is running.** The person waits and calls `assign` again. Rejected: it brings
|
||||
back the second act by hand that issue 300 removed, and nothing reminds the person to make it.
|
||||
2. **Keep the assignment only when asked** (an argument such as `wait`). Rejected: a person who knows to ask
|
||||
for it already knows the build is running; the one who does not is the one this is for.
|
||||
3. **Keep the assignment by default while a build is in flight, and have the controller make it when the
|
||||
build registers the module.** Chosen.
|
||||
|
||||
## Decision
|
||||
|
||||
1. **The controller keeps every build request it makes**, once the ask is made and never before, with who
|
||||
asked it (a merge, a plan, a person's `build`, `assign`), the repository, the directory, the branch and
|
||||
the merge's commit. A request whose ask could not be made, or whose asker stopped waiting, is kept with
|
||||
why. A request is kept for 30 days.
|
||||
2. **`assign` of a module the catalogue does not hold says which case it is in:**
|
||||
- *a build is in flight*: a kept request for the module's directory has no outcome yet (within two
|
||||
hours of asking), or its build succeeded within the last five minutes and is being registered;
|
||||
- *known, not built*: there is a kept request, and its build failed, was not registered, gave no outcome,
|
||||
or could not be asked;
|
||||
- *unknown*: no module registered and no kept request by that name. The answer claims only that, and
|
||||
names the closest names.
|
||||
3. **In the first case the assignment is kept as a pending assignment**, with no argument needed. In the
|
||||
second, `assign` refuses, and its `build` argument asks for the build from where the last request came
|
||||
from and keeps the assignment pending on it. If a pending assignment of that module to that machine is
|
||||
already waiting, it is made to wait for the new build; no build is asked that nothing waits on.
|
||||
4. **The controller makes a pending assignment by the same act as a person's `assign`**, with the same
|
||||
checks, when the build registers the module. It first takes the machine's hold and claims the pending
|
||||
assignment, so a withdrawal cannot land in between. A refusal then ends it as refused. Making it sends
|
||||
nothing, as a person's `assign` sends nothing.
|
||||
5. **A pending assignment never waits silently.** It expires with the builder's own words when its build
|
||||
fails or is not registered, and with a sentence when no outcome comes within two hours. The controller
|
||||
settles pending assignments on a tick of its own, every minute, and on each build's outcome. A read,
|
||||
such as `status`, settles nothing.
|
||||
6. **An assignment that was not made is a condition** (`assignment-not-made`, a warning the operator
|
||||
resolves). It stays open until it is answered: the module is assigned to that machine later, it is
|
||||
assigned again and pending on another build, or a person takes it back with `unassign`.
|
||||
7. **`unassign` withdraws a waiting pending assignment.** It is refused, and says so, while the controller
|
||||
is making one. Ended pending assignments are deleted after 30 days, and a machine's go with it.
|
||||
|
||||
## Consequences
|
||||
|
||||
- One kind of assignment is now made by the controller, not at the person's act. The person's intention is
|
||||
still the cause: nothing is assigned that a person did not ask for.
|
||||
- `status` lists open pending assignments (and is not well while one is open) and those ended in the last
|
||||
day; the condition carries an assignment not made until it is answered.
|
||||
- The controller cannot read the forge. A module directory that no merge announced since this record and no
|
||||
person asked to build still reads as unknown; the refusal says how to build it.
|
||||
- A build being registered reads as in flight for five minutes after its outcome. A build recorded and never
|
||||
registered reads so only after that.
|
||||
|
||||
## How it is checked
|
||||
|
||||
- mesh-controller `cmd/mesh-controller/pending_test.go`: each case of point 2; the claim under the hold and
|
||||
the refused withdrawal (point 4, 7); a failed ask that never reads as in flight and the asker kept
|
||||
(point 1); `build` re-pointing a waiting assignment (point 3); a status read that settles nothing, the
|
||||
tick that does, and a silent build expiring (point 5); the condition raised, and cleared by `unassign` or
|
||||
a later assignment (point 6); ended rows deleted after 30 days.
|
||||
- mesh-controller `internal/inventory/pending_test.go`: a pending assignment goes with its machine.
|
||||
- `TestReplay325`, R325 in mesh-lab's replays register: the live case of issue 325.
|
||||
|
||||
## References
|
||||
|
||||
- [Issue 325](../04-ISSUES/325-assign-said-no-such-module-while-its-build-ran/00-report.md); issue 300.
|
||||
- novox/mesh-controller#150, novox/mesh-lab#68.
|
||||
- [ADR 0207](0207-a-module-depends-on-the-node-seats-that-apply-its-resources.md): modules assigned together
|
||||
are judged together, so an act naming a module not registered is refused whole.
|
||||
Reference in New Issue
Block a user