Issue 1945 note 97. car-hunter #2 (a repository under the operator's personal account) was approved at 16:09 but its merge got 403: the mesh's forge accounts are only read collaborators on personal repositories (mesh-catalog #495/#500). The operator, 2026-10-26 16:3x: "yes the mesh should get write access", only on the repositories that build a registered module; the other personal repositories stay read-only.
gitea (writes.ts, client.ts): mesh-tools, the account that sets statuses and merges, becomes a write collaborator on each repository the indexer's state mesh-delivery-indexer.modules names (new reads), at start and on every registration; each grant read back; emits gitea.repo.writable. nox-builder and nox-agent keep read only; novox-organisation repositories need nothing. Write is not taken back when a repository's last module is unregistered (said in writes.ts).
Tools: gitea_grant_write {repositories?} (refuses a repository that builds no module, names it as left read-only), gitea_unwritable_repos, and gitea_commit_statuses answers merge.writes / merge.cannot_write.
The gate (writes.go): before it asks a merge it reads whether mesh-tools can write every member's repository; if not, no ask, the delivery's waits say so and a condition is raised, cleared when writable. On gitea.repo.writable it asks again a merge the forge refused; the merge still needs the Approve's bound heads, so no head the operator did not approve merges. A 10-minute re-read of an unwritable repository is only a backstop to the event (rule bent and said: the event is the path).
Tests: gitea npm test 210 pass (run by the builder and again by the reviewer in a clean copy; the checker's try does not run gitea's TypeScript tests, the gap noted on 1945); gate unit suite passes, the new test fails without the fix; go vet -tags integration clean. try-1793029252117841205 passed (unit 2221, integration 2241).
After delivery: gitea grants mesh-tools write on jschoubben/car-hunter at start; the gate hears gitea.repo.writable and merges car-hunter #2 under the operator's 16:09 Approve.
Reviewed-by: review-forgewrite@shanks at 24b244bc88
Issue 1945 note 97. car-hunter #2 (a repository under the operator's personal account) was approved at 16:09 but its merge got 403: the mesh's forge accounts are only read collaborators on personal repositories (mesh-catalog #495/#500). The operator, 2026-10-26 16:3x: "yes the mesh should get write access", only on the repositories that build a registered module; the other personal repositories stay read-only.
- gitea (writes.ts, client.ts): mesh-tools, the account that sets statuses and merges, becomes a write collaborator on each repository the indexer's state `mesh-delivery-indexer.modules` names (new `reads`), at start and on every registration; each grant read back; emits `gitea.repo.writable`. nox-builder and nox-agent keep read only; novox-organisation repositories need nothing. Write is not taken back when a repository's last module is unregistered (said in writes.ts).
- Tools: `gitea_grant_write {repositories?}` (refuses a repository that builds no module, names it as left read-only), `gitea_unwritable_repos`, and `gitea_commit_statuses` answers merge.writes / merge.cannot_write.
- The gate (writes.go): before it asks a merge it reads whether mesh-tools can write every member's repository; if not, no ask, the delivery's waits say so and a condition is raised, cleared when writable. On `gitea.repo.writable` it asks again a merge the forge refused; the merge still needs the Approve's bound heads, so no head the operator did not approve merges. A 10-minute re-read of an unwritable repository is only a backstop to the event (rule bent and said: the event is the path).
Tests: gitea npm test 210 pass (run by the builder and again by the reviewer in a clean copy; the checker's try does not run gitea's TypeScript tests, the gap noted on 1945); gate unit suite passes, the new test fails without the fix; go vet -tags integration clean. try-1793029252117841205 passed (unit 2221, integration 2241).
After delivery: gitea grants mesh-tools write on jschoubben/car-hunter at start; the gate hears gitea.repo.writable and merges car-hunter #2 under the operator's 16:09 Approve.
Reviewed-by: review-forgewrite@shanks at 24b244bc88dc492e2eba09bb294b281e3421aff0
car-hunter #2 was approved and its commit status refused 403: mesh-tools only read the
repositories of a user. It is now a write collaborator on each repository the indexer's
modules state names (watched over the bus: at the start and on each registration), read
back and said as gitea.repo.writable; the operator's other repositories stay read-only.
gitea_grant_write and gitea_unwritable_repos do and show it by hand; gitea_commit_statuses
answers merge.writes.
car-hunter #2 was approved and its commit status then refused 403. Before the ask the
gate reads merge.writes for each repository it covers; where the merging account cannot
write, nothing is asked, the delivery waits on 'the forge account cannot write <repo>:
gitea_grant_write' and a condition is raised. gitea.repo.writable reads it again and
asks an approved, refused merge of it again.
Deliverynovox/mesh-catalog@24b244bc88dc — merged since 2026-10-26T16:25:08Z
Source — source.main moved to novox/mesh-catalog@27a7757b97. Whether it reached the machines is mesh-delivery-view's, derived from source.main, the wants and the haves.
Transitions
2026-10-26 16:04 (new) → proposed (announced): novox/mesh-catalog#503's head announced
2026-10-26 16:04 proposed → ready (accepted): a verdict names this commit and the trunk's head as its trunk commit, the gate passed or warned, and the repository's own check did not fail; or the check gates no merge (check-gates-merge false)
2026-10-26 16:25 ready → merged (merged): on the trunk its modules follow: merged there
The commit's note under refs/notes/mesh-plan keeps every transition of this change up to its merge: git log --notes=mesh-plan.
<!-- mesh-delivery:view -->
**Delivery** `novox/mesh-catalog@24b244bc88dc` — **merged** since 2026-10-26T16:25:08Z
**Source** — source.main moved to novox/mesh-catalog@27a7757b970e. Whether it reached the machines is `mesh-delivery-view`'s, derived from `source.main`, the wants and the haves.
**Transitions**
- 2026-10-26 16:04 (new) → proposed (announced): novox/mesh-catalog#503's head announced
- 2026-10-26 16:04 proposed → ready (accepted): a verdict names this commit and the trunk's head as its trunk commit, the gate passed or warned, and the repository's own check did not fail; or the check gates no merge (check-gates-merge false)
- 2026-10-26 16:25 ready → merged (merged): on the trunk its modules follow: merged there
The commit's note under `refs/notes/mesh-plan` keeps every transition of this change up to its merge: `git log --notes=mesh-plan`.
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.
Issue 1945 note 97. car-hunter #2 (a repository under the operator's personal account) was approved at 16:09 but its merge got 403: the mesh's forge accounts are only read collaborators on personal repositories (mesh-catalog #495/#500). The operator, 2026-10-26 16:3x: "yes the mesh should get write access", only on the repositories that build a registered module; the other personal repositories stay read-only.
mesh-delivery-indexer.modulesnames (newreads), at start and on every registration; each grant read back; emitsgitea.repo.writable. nox-builder and nox-agent keep read only; novox-organisation repositories need nothing. Write is not taken back when a repository's last module is unregistered (said in writes.ts).gitea_grant_write {repositories?}(refuses a repository that builds no module, names it as left read-only),gitea_unwritable_repos, andgitea_commit_statusesanswers merge.writes / merge.cannot_write.gitea.repo.writableit asks again a merge the forge refused; the merge still needs the Approve's bound heads, so no head the operator did not approve merges. A 10-minute re-read of an unwritable repository is only a backstop to the event (rule bent and said: the event is the path).Tests: gitea npm test 210 pass (run by the builder and again by the reviewer in a clean copy; the checker's try does not run gitea's TypeScript tests, the gap noted on 1945); gate unit suite passes, the new test fails without the fix; go vet -tags integration clean. try-1793029252117841205 passed (unit 2221, integration 2241).
After delivery: gitea grants mesh-tools write on jschoubben/car-hunter at start; the gate hears gitea.repo.writable and merges car-hunter #2 under the operator's 16:09 Approve.
Reviewed-by: review-forgewrite@shanks at
24b244bc88Delivery
novox/mesh-catalog@24b244bc88dc— merged since 2026-10-26T16:25:08ZSource — source.main moved to novox/mesh-catalog@27a7757b97. Whether it reached the machines is
mesh-delivery-view's, derived fromsource.main, the wants and the haves.Transitions
The commit's note under
refs/notes/mesh-plankeeps every transition of this change up to its merge:git log --notes=mesh-plan.