Branch protection now requires mesh/merge-gate (and mesh/repo-check on mesh-controller, mesh-host, mesh-catalog, mesh-tools, mesh-sdk, hq, mesh-lab), with admin override off. The forge combines warning as a failure: verified live, success+warning+success gives combined failure. So a required check that says warning blocks the merge.
Audit: where warning reached these two statuses. The controller and the build seat say verdicts (pass, warning, fail, error). Only this module turns a verdict into a forge state (pulls.tsstateOf). The controller sends warning in these cases:
gate: a wide rebuild, "a merge rebuilds N module(s) in T tier(s)" (merge_gate.go)
gate: the module check's problems were already so on the base (builder/check.go)
repo-check: a merge-check.sh that says warning itself
repo-check: the repository declares no merge-check.sh (builder/check.go noScript; checks.go noMergeCheck)
The gitea_commit_status tool also accepted any mesh/… context, warning included.
Final mapping
verdict
forge state
description
pass
success
pass: …
warning (1, 2, 3: a note)
success
pass, with a note: …
repo-check, no merge-check.sh, repo-check not required on the base branch
success
no repository check defined
repo-check, no merge-check.sh, repo-check required, or the protection unreadable
failure
fail: mesh/repo-check is required here and this head defines no merge-check.sh — a person adds one, or lifts the requirement…
fail
failure
fail: …
error, or no verdict
error
never a success
Only for a repo-check warning does the module ask the forge whether the head holds merge-check.sh and whether the base branch's rule requires mesh/repo-check. When the rule cannot be read, the result is a failure: a failure on a status nothing requires blocks nothing, and a success on a required status would let an untested repository merge. gitea_commit_status now refuses mesh/merge-gate and mesh/repo-check: those are set by the verdict only. mesh/delivery keeps warning for superseded, because it is not a required context.
The pull request comment says PASS, WITH A NOTE for a note. A required check that is not defined counts as a comment-worthy failure.
Tests
test/pulls.test.ts: no verdict and no combination of facts sets warning. The not-required, required and unreadable cases are covered, as are a script's own note and the gate's notes.
test/delivery.test.ts: the merge-check contexts are refused.
8 of 9 pass with node --test --experimental-strip-types. The one failing test (client.ts → token.js) fails the same way on main without a build, so it is environmental. tsc finds no new errors in pulls.ts, delivery.ts or index.ts, only missing @types/node and the SDK, as on main.
mesh-controller check-here --registry novox.internal:5100: merge-gate PASS (4 of 4 compose), repo-check PASS. The repo's own script does not test TypeScript, so the tests above were run by hand.
The module stays in TypeScript for this small fix. A Go port is a separate piece of work.
Branch protection now requires `mesh/merge-gate` (and `mesh/repo-check` on mesh-controller, mesh-host, mesh-catalog, mesh-tools, mesh-sdk, hq, mesh-lab), with admin override off. The forge combines `warning` as a failure: verified live, success+warning+success gives combined failure. So a required check that says `warning` blocks the merge.
**Audit: where `warning` reached these two statuses.** The controller and the build seat say verdicts (`pass`, `warning`, `fail`, `error`). Only this module turns a verdict into a forge state (`pulls.ts` `stateOf`). The controller sends `warning` in these cases:
1. gate: a wide rebuild, "a merge rebuilds N module(s) in T tier(s)" (merge_gate.go)
2. gate: the module check's problems were already so on the base (builder/check.go)
3. repo-check: a merge-check.sh that says `warning` itself
4. repo-check: the repository declares no merge-check.sh (builder/check.go noScript; checks.go noMergeCheck)
The `gitea_commit_status` tool also accepted any `mesh/…` context, `warning` included.
**Final mapping**
| verdict | forge state | description |
|---|---|---|
| pass | success | `pass: …` |
| warning (1, 2, 3: a note) | **success** | `pass, with a note: …` |
| repo-check, no merge-check.sh, repo-check **not required** on the base branch | **success** | `no repository check defined` |
| repo-check, no merge-check.sh, repo-check **required**, or the protection unreadable | **failure** | `fail: mesh/repo-check is required here and this head defines no merge-check.sh — a person adds one, or lifts the requirement…` |
| fail | failure | `fail: …` |
| error, or no verdict | error | never a success |
Only for a repo-check `warning` does the module ask the forge whether the head holds `merge-check.sh` and whether the base branch's rule requires `mesh/repo-check`. When the rule cannot be read, the result is a failure: a failure on a status nothing requires blocks nothing, and a success on a required status would let an untested repository merge. `gitea_commit_status` now refuses `mesh/merge-gate` and `mesh/repo-check`: those are set by the verdict only. `mesh/delivery` keeps `warning` for *superseded*, because it is not a required context.
The pull request comment says `PASS, WITH A NOTE` for a note. A required check that is not defined counts as a comment-worthy failure.
**Tests**
- `test/pulls.test.ts`: no verdict and no combination of facts sets `warning`. The not-required, required and unreadable cases are covered, as are a script's own note and the gate's notes.
- `test/delivery.test.ts`: the merge-check contexts are refused.
- 8 of 9 pass with `node --test --experimental-strip-types`. The one failing test (client.ts → token.js) fails the same way on main without a build, so it is environmental. tsc finds no new errors in pulls.ts, delivery.ts or index.ts, only missing @types/node and the SDK, as on main.
`mesh-controller check-here --registry novox.internal:5100`: merge-gate PASS (4 of 4 compose), repo-check PASS. The repo's own script does not test TypeScript, so the tests above were run by hand.
The module stays in TypeScript for this small fix. A Go port is a separate piece of work.
Branch protection requires mesh/merge-gate (and mesh/repo-check on the core
repositories) with no admin override, and the forge combines warning as a
failure. A note is now a success that says it; a repository without a
merge-check.sh is a success where repo-check is not required and a failure
for a person where it is; the status tool refuses the merge check's contexts.
Deliverynovox/mesh-catalog@33857626be9c — delivered since 2026-10-07T12:08:54Z
Delivery plan — builds gitea → novox; no bus step
tier 0: gitea
novox: receives gitea
gitea provides npm-package-registry, git: its consumers are sent again after it
gitea keeps data (ADR 0233): what it holds is backed up before it moves
Machines
gitea on novox: passed — healthy 3 times over 2m1s
gitea on the rest running it: sent
Transitions
2026-10-07 11:56 (new) → proposed (announced): novox/mesh-catalog#102's head announced
2026-10-07 11:59 proposed → checked (checked): the verdict names this commit
2026-10-07 11:59 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
2026-10-07 12:05 ready → published (merged): on the trunk its modules follow: merged there, and its walk opened — or nothing for a walk to move
2026-10-07 12:06 published → delivering (go): its walk started: let go by this owner in its group's order, by a person, or on the controller's own path
2026-10-07 12:08 delivering → delivered (done): its walk is done: every machine of its deploy plan passed, or was left as its policy says
The commit's note under refs/notes/mesh-plan keeps every transition: git log --notes=mesh-plan.
<!-- mesh-delivery:view -->
**Delivery** `novox/mesh-catalog@33857626be9c` — **delivered** since 2026-10-07T12:08:54Z
**Delivery plan** — builds gitea → novox; no bus step
- tier 0: gitea
- novox: receives gitea
- gitea provides npm-package-registry, git: its consumers are sent again after it
- gitea keeps data (ADR 0233): what it holds is backed up before it moves
**Machines**
- gitea on novox: passed — healthy 3 times over 2m1s
- gitea on the rest running it: sent
**Transitions**
- 2026-10-07 11:56 (new) → proposed (announced): novox/mesh-catalog#102's head announced
- 2026-10-07 11:59 proposed → checked (checked): the verdict names this commit
- 2026-10-07 11:59 checked → ready (accepted): the gate passed or warned, and the repository's own check did not fail
- 2026-10-07 12:05 ready → published (merged): on the trunk its modules follow: merged there, and its walk opened — or nothing for a walk to move
- 2026-10-07 12:06 published → delivering (go): its walk started: let go by this owner in its group's order, by a person, or on the controller's own path
- 2026-10-07 12:08 delivering → delivered (done): its walk is done: every machine of its deploy plan passed, or was left as its policy says
The commit's note under `refs/notes/mesh-plan` keeps every transition: `git log --notes=mesh-plan`.
mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: gitea)
mesh/repo-check: PASS — its merge-check.sh passed
Change plan — builds gitea → novox; no bus step
tier 0: gitea
novox: receives gitea
gitea provides npm-package-registry, git: its consumers are sent again after it
gitea keeps data (ADR 0233): what it holds is backed up before it moves
Run by the build seat on g14 as build-1791374179997771381 (builds --log build-1791374179997771381).
--- the gate: gitea
gitea: ok, keeps data (valuable)
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-07T11:26:48Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-07T11:26:48Z
modules the change moves:
- gitea (changed)
machines:
- a machine (f35): composes
- holds mesh-dns-resolver (idt): composes
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
- a machine (yvbpsm): composes
a merge would rebuild 1 module(s) in 1 tier(s): gitea
--- its merge-check.sh (go toolchain)
NOT TESTED HERE: modules/gitea is TypeScript; the gate judges its manifest
**Merge check** at `33857626`
- `mesh/merge-gate`: **PASS** — every machine composes with the change as it did without (4 of 4 compose) (modules: gitea)
- `mesh/repo-check`: **PASS** — its merge-check.sh passed
**Change plan** — builds gitea → novox; no bus step
- tier 0: gitea
- novox: receives gitea
- gitea provides npm-package-registry, git: its consumers are sent again after it
- gitea keeps data (ADR 0233): what it holds is backed up before it moves
Run by the build seat on g14 as `build-1791374179997771381` (`builds --log build-1791374179997771381`).
```
--- the gate: gitea
gitea: ok, keeps data (valuable)
1 manifest(s) checked. Judged against the seats this binary carries; a claim on one of the mesh's own seats is judged fully at registration, and a seat declared by a module not given here reads as unknown. Identities judged on a 6-character machine name, against the bounds of the providers given here
judging 1 module(s) changed against 4 machine(s), as the snapshot of 2026-10-07T11:26:48Z says they run
composing every machine as the mesh is
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
composing every machine with the change
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
the bus's user list leaves out 5 user(s) the mesh has minted no credential for: controller, node.f35, node.idt, node.ygcyr, node.yvbpsm. Each is a user that cannot connect until one is issued
merge gate: PASS — every machine composes with the change as it did without (4 of 4 compose)
judged by controller development build against the facts of 2026-10-07T11:26:48Z
modules the change moves:
- gitea (changed)
machines:
- a machine (f35): composes
- holds mesh-dns-resolver (idt): composes
- holds git, holds mesh-artifact-store, holds mesh-broker, holds mesh-catalog, holds mesh-dns-resolver, holds mesh-store, holds mesh-vault, holds npm-package-registry, the control node, the hub (ygcyr): composes
- a machine (yvbpsm): composes
a merge would rebuild 1 module(s) in 1 tier(s): gitea
--- its merge-check.sh (go toolchain)
NOT TESTED HERE: modules/gitea is TypeScript; the gate judges its manifest
```
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Branch protection now requires
mesh/merge-gate(andmesh/repo-checkon mesh-controller, mesh-host, mesh-catalog, mesh-tools, mesh-sdk, hq, mesh-lab), with admin override off. The forge combineswarningas a failure: verified live, success+warning+success gives combined failure. So a required check that sayswarningblocks the merge.Audit: where
warningreached these two statuses. The controller and the build seat say verdicts (pass,warning,fail,error). Only this module turns a verdict into a forge state (pulls.tsstateOf). The controller sendswarningin these cases:warningitselfThe
gitea_commit_statustool also accepted anymesh/…context,warningincluded.Final mapping
pass: …pass, with a note: …no repository check definedfail: mesh/repo-check is required here and this head defines no merge-check.sh — a person adds one, or lifts the requirement…fail: …Only for a repo-check
warningdoes the module ask the forge whether the head holdsmerge-check.shand whether the base branch's rule requiresmesh/repo-check. When the rule cannot be read, the result is a failure: a failure on a status nothing requires blocks nothing, and a success on a required status would let an untested repository merge.gitea_commit_statusnow refusesmesh/merge-gateandmesh/repo-check: those are set by the verdict only.mesh/deliverykeepswarningfor superseded, because it is not a required context.The pull request comment says
PASS, WITH A NOTEfor a note. A required check that is not defined counts as a comment-worthy failure.Tests
test/pulls.test.ts: no verdict and no combination of facts setswarning. The not-required, required and unreadable cases are covered, as are a script's own note and the gate's notes.test/delivery.test.ts: the merge-check contexts are refused.node --test --experimental-strip-types. The one failing test (client.ts → token.js) fails the same way on main without a build, so it is environmental. tsc finds no new errors in pulls.ts, delivery.ts or index.ts, only missing @types/node and the SDK, as on main.mesh-controller check-here --registry novox.internal:5100: merge-gate PASS (4 of 4 compose), repo-check PASS. The repo's own script does not test TypeScript, so the tests above were run by hand.The module stays in TypeScript for this small fix. A Go port is a separate piece of work.
Delivery
novox/mesh-catalog@33857626be9c— delivered since 2026-10-07T12:08:54ZDelivery plan — builds gitea → novox; no bus step
Machines
Transitions
The commit's note under
refs/notes/mesh-plankeeps every transition:git log --notes=mesh-plan.Merge check at
33857626mesh/merge-gate: PASS — every machine composes with the change as it did without (4 of 4 compose) (modules: gitea)mesh/repo-check: PASS — its merge-check.sh passedChange plan — builds gitea → novox; no bus step
Run by the build seat on g14 as
build-1791374179997771381(builds --log build-1791374179997771381).