Publish only a commit on its module's trunk; post a pull request's change plan (hq ADR 0238)
mesh/merge-gate pass: the change touches no module of the mesh's graph
mesh/delivery delivered
mesh/delivery-group group feat/the-graph-decides-what-is-checked delivered: every member is delivered

One commit, one plan: a commit off the trunk — a pull request's head, a branch built by
hand, a rebuild or replay of one — is for checking. The build seat reads from its clone
which branches hold the commit, and the controller records and never registers a build
whose commit is not on the branch the module follows (the repository's default for a
new one), so nothing off the trunk can be sent.

A pull request's check now carries its change plan, computed by the planner: what a
merge would build in which order, what each machine would receive, and what is not an
ordinary send — the bus step, a module waiting for a person, a provider's consumers.
This commit is contained in:
jochen
2026-10-06 22:49:55 +02:00
parent 58ebe590a5
commit 3d05d74400
11 changed files with 481 additions and 3 deletions
+11
View File
@@ -114,6 +114,8 @@ type CheckRequest struct {
// Dependents are the modules a merge would build after Modules because they stand on them: the
// planner's dependency walk, said on the pull request.
Dependents []string `json:"dependents,omitempty"`
// Plan is the change plan of the commit checked, computed by the controller and echoed with the outcome.
Plan *ChangePlan `json:"plan,omitempty"`
// Manifests are the touched modules' manifests in the change's tree, by path from its root: what the
// gate puts through `module check`.
Manifests []string `json:"manifests,omitempty"`
@@ -203,6 +205,15 @@ type BuildResult struct {
// manifest the mesh keeps says nothing about it (novox/hq 04-ISSUES/131).
Read []ReadRepository `json:"read,omitempty"`
// Trunk is the repository's default branch at the build, and OnTrunk whether the commit built is on it
// (novox/hq ADR 0238): **only a commit on the trunk is published** — the controller refuses to register
// a build of one off it. Empty Trunk is a build seat that could not say, or predates the rule.
Trunk string `json:"trunk,omitempty"`
OnTrunk bool `json:"on-trunk,omitempty"`
// Branches are every branch the commit is on: the trunk of a module that follows a branch other than
// the repository's default is the branch it follows.
Branches []string `json:"branches,omitempty"`
// SourceFingerprint is what the build was made from, hashed (novox/hq issue 280): the module's
// tree at the commit, the trees of the contexts it read, its bases and toolchains by digest. Two
// builds with one fingerprint are one build, however their digests differ — an image is not
+35
View File
@@ -258,6 +258,41 @@ type Checked struct {
// RepoCheck is nil when the repository is not the mesh's and touches nothing of it: nothing is said.
Gate *CheckLayer `json:"gate,omitempty"`
RepoCheck *CheckLayer `json:"repo-check,omitempty"`
// Plan is the change plan of the commit checked (novox/hq ADR 0238): what a merge of it would build
// and send, posted with the verdict.
Plan *ChangePlan `json:"plan,omitempty"`
}
// ChangePlan is what a change does to the mesh, computed from its diffset — a repository, the branch it
// merges into and the commit at hand — by the planner (novox/hq ADR 0238): **one commit, one plan**, the
// object a pull request's check posts, the release follows and a person reads.
type ChangePlan struct {
Repository string `json:"repository"`
Base string `json:"base"`
Head string `json:"head"`
// Moved are the modules a merge moves itself, Dependents those built after them because they stand
// on them, New the directories it adds a module in, and Unread the changed files no build reads.
Moved []string `json:"moved,omitempty"`
Dependents []string `json:"dependents,omitempty"`
New []string `json:"new,omitempty"`
Unread []string `json:"unread,omitempty"`
// Tiers are the build plan's order: each tier built after the one before.
Tiers [][]string `json:"tiers,omitempty"`
// Machines are the deploy plan: what each machine is sent, in the build plan's order, and what waits
// there for a person.
Machines []MachinePlan `json:"machines,omitempty"`
// Steps are what is not an ordinary send: a planned bus step, a provider whose consumers are sent again,
// a module that waits for a person, a module that keeps data.
Steps []string `json:"steps,omitempty"`
// Summary is the plan in one line, for a commit status.
Summary string `json:"summary"`
}
// MachinePlan is one machine's part of a change plan.
type MachinePlan struct {
Machine string `json:"machine"`
Receives []string `json:"receives,omitempty"`
Waits []string `json:"waits,omitempty"`
}
// CheckLayer is one layer of a merge check, judged.