feat(dispatch): QUEUE_REVIEW-supervisorkant — opdrachtbron, read-checkout, producer-eis en gate (M41) #94

Merged
janpeter merged 4 commits from feat/m41-review-contract into master 2026-10-02 15:44:05 +02:00
Owner

Samenvatting

M41 increment 1 (sprint S-2026-10-02-1, story ST-1614, taken T-1928…T-1930): de supervisorkant van een QUEUE_REVIEW.

  • T7 — opdracht naar het kind. De servicebron __dispatch_input komt via producer en broker als /sources/__dispatch_input bij het kind, hash-geverifieerd. Producer en broker behandelden manifestbronnen al generiek; alleen de oude shared-pin c65f5a8 weigerde de bron. vendor/scrum4me-shared → b3d2b98 (scrum4me-shared#68).
  • T8 — checkout bij reviews. Bij access: read met een gepinde repository maakt de broker nu ook een checkout in /work.
    • Via materializePreparedRepository(…, writable=false): eigendom van de broker en zonder group/other-schrijfbit, ook op de root.
    • De ruwe bundle blijft in /sources; repo_write is ongewijzigd.
  • T8 — producer verplicht voor elk profiel. Omdat elk verzoek nu __dispatch_input meekrijgt, eist dispatch-config voor élk profiel de gearmde bronproducent: DISPATCH_PREPARED_SOURCES_PRODUCER_REQUIRED vóór registratie.
    • Een slot zonder producer zou anders bij prepare als onzekere poging eindigen.
    • README, operator-doc en beide compose-bestanden noemen de producer-overlay nu verplicht.
  • T9 — contractgate. Twee nieuwe QUEUE_REVIEW-gevallen (review, review_repo) op de beheerde jobroute.
    • Ze gebruiken de echte bronproducent: ondertekend manifest plus GET /artifacts/:id met pogingsbewijs.
    • Een nep-kind leest __dispatch_input en antwoordt GO; een /deliver-route draait de echte projector.
    • Bewuste contractwijziging: de verwachte bronnen zijn nu ['__dispatch_input','__repository_base'].

Test

  • Gate: DISPATCH_CONTRACT_MCP_ROOT=<scrum4me-mcp feat/m41-review-contract> met een wegwerp-pg17.
    • Tegen mcp main: 3 failed. De review eindigt FAILED DISPATCH_INPUT_UNREADABLE, zonder source_delivered en zonder root-id.
    • Tegen scrum4me-mcp#175: 9/9 groen. Review e0334bde-… eindigt SUCCEEDED met GO en één source_delivered; de job QUEUE_REVIEW staat op DONE; de reply reviewed heeft in_reply_to = root-id.
    • review_repo heeft een checkout op de base-commit, niet schrijfbaar.
    • Door de orkestrator onafhankelijk herhaald op een verse database: 9/9.
  • npm test: 970 groen, plus 2 failures in transcript-retention.test.ts die al vóór deze branch bestonden. Die tests vereisen GNU chmod --reference, die macOS niet heeft.
  • typecheck:dispatch schoon; skills:verify OK.

Niet bewezen

Geen model, image, container of egress; de broker-mount is gesimuleerd. Geen live service, geen Forgejo-route. Dat volgt in M41 increment 2 en 3.

Merge-volgorde

Na scrum4me-shared#68 en scrum4me-mcp#175.

🤖 Generated with Claude Code

## Samenvatting M41 increment 1 (sprint S-2026-10-02-1, story ST-1614, taken T-1928…T-1930): de supervisorkant van een `QUEUE_REVIEW`. - **T7 — opdracht naar het kind.** De servicebron `__dispatch_input` komt via producer en broker als `/sources/__dispatch_input` bij het kind, hash-geverifieerd. Producer en broker behandelden manifestbronnen al generiek; alleen de oude shared-pin `c65f5a8` weigerde de bron. `vendor/scrum4me-shared` → `b3d2b98` (scrum4me-shared#68). - **T8 — checkout bij reviews.** Bij `access: read` met een gepinde repository maakt de broker nu ook een checkout in `/work`. - Via `materializePreparedRepository(…, writable=false)`: eigendom van de broker en zonder group/other-schrijfbit, ook op de root. - De ruwe bundle blijft in `/sources`; repo_write is ongewijzigd. - **T8 — producer verplicht voor elk profiel.** Omdat elk verzoek nu `__dispatch_input` meekrijgt, eist `dispatch-config` voor élk profiel de gearmde bronproducent: `DISPATCH_PREPARED_SOURCES_PRODUCER_REQUIRED` vóór registratie. - Een slot zonder producer zou anders bij prepare als onzekere poging eindigen. - README, operator-doc en beide compose-bestanden noemen de producer-overlay nu verplicht. - **T9 — contractgate.** Twee nieuwe `QUEUE_REVIEW`-gevallen (`review`, `review_repo`) op de beheerde jobroute. - Ze gebruiken de echte bronproducent: ondertekend manifest plus `GET /artifacts/:id` met pogingsbewijs. - Een nep-kind leest `__dispatch_input` en antwoordt `GO`; een `/deliver`-route draait de echte projector. - Bewuste contractwijziging: de verwachte bronnen zijn nu `['__dispatch_input','__repository_base']`. ## Test - **Gate:** `DISPATCH_CONTRACT_MCP_ROOT=<scrum4me-mcp feat/m41-review-contract>` met een wegwerp-pg17. - Tegen mcp main: 3 failed. De review eindigt `FAILED DISPATCH_INPUT_UNREADABLE`, zonder `source_delivered` en zonder root-id. - Tegen scrum4me-mcp#175: 9/9 groen. Review `e0334bde-…` eindigt `SUCCEEDED` met `GO` en één `source_delivered`; de job `QUEUE_REVIEW` staat op `DONE`; de reply `reviewed` heeft `in_reply_to` = root-id. - `review_repo` heeft een checkout op de base-commit, niet schrijfbaar. - Door de orkestrator onafhankelijk herhaald op een verse database: 9/9. - **`npm test`:** 970 groen, plus 2 failures in `transcript-retention.test.ts` die al vóór deze branch bestonden. Die tests vereisen GNU `chmod --reference`, die macOS niet heeft. - `typecheck:dispatch` schoon; `skills:verify` OK. ## Niet bewezen Geen model, image, container of egress; de broker-mount is gesimuleerd. Geen live service, geen Forgejo-route. Dat volgt in M41 increment 2 en 3. ## Merge-volgorde Na scrum4me-shared#68 en scrum4me-mcp#175. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Bumpt scrum4me-shared naar b3d2b98: het ondertekende bronmanifest staat nu
precies één servicebron __dispatch_input toe waarvan de hash de ondertekende
inputSha256 is. Producer, staging en broker behandelen bronnen al generiek
(geen sleutel-allowlist of __-weigering op het downloadpad, de broker-create
accepteert elke gestagede pin), dus er is geen codewijziging nodig.

Tests bewijzen het pad: de producer staget de canonieke inputbytes, een claim
die de bron weglaat en een manifest met een afwijkende hash worden geweigerd
vóór er een byte binnenkomt, en de broker kopieert de bron byte-gelijk naar
<attempt>/sources/__dispatch_input (read-only /sources) en weigert gewijzigde
gestagede bytes vóór docker create.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
G5: een read-poging waarvan het ondertekende manifest een repository draagt
krijgt nu ook een checkout van de gepinde base in <attempt>/work.
materializePreparedRepository kreeg een writable-vlag: voor read blijft de
checkout broker-eigendom zonder group/other-schrijfbit (dirs 0755, bestanden
0644/0755, ook de work-root), dus uid 10001 leest maar wijzigt niets. Geen
chown; repo_write blijft identiek (0777/0666). De ruwe bundle blijft in
/sources. Zonder repository geen checkout.

G7: een profiel met actions ⊇ review vereist de prepared-sources-producer al
bij de configcontrole (DISPATCH_PREPARED_SOURCES_PRODUCER_REQUIRED), zodat een
reviewslot zonder producer niet registreert in plaats van pas bij prepare met
een onzekere poging te eindigen. De standaard configfixture is nu een
producer-loze free_task-readslot. README, operatordoc en producer-overlay
bijgewerkt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Elk verzoek draagt na M41 de ondertekende servicebron __dispatch_input, dus
elke claim heeft voorbereide bronnen. Een slot zonder producer zou elke claim
bij prepare laten falen en onzeker laten eindigen. lib/dispatch-config.ts
weigert daarom elk profiel (elke actie, elke access) zonder gewapende
producer met DISPATCH_PREPARED_SOURCES_PRODUCER_REQUIRED, vóór registratie.
De halve-producer- en sleutelweigeringen blijven ongewijzigd.

De configfixture wapent de producer standaard; één test bewijst de weigering
voor free_task-read, review, gemengd, source-mount en repo_write en de
acceptatie met producer. README, operatordoc, beide compose-bestanden en de
deploymenttestomschrijving noemen de producer-overlay nu verplicht; er is
geen producer-loze readslot meer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
test(dispatch): reviewgeval in de cross-repo contractgate (M41 T9)
All checks were successful
CI / Compose config (pull_request) Successful in 5s
CI / Build-arg coverage (pull_request) Successful in 5s
CI / Docker build (pull_request) Successful in 5m22s
1adfe64b24
Twee reviewgevallen (zonder en met gepinde repository) sturen één
QUEUE_REVIEW over de managed job-route door de echte producer: het
ondertekende manifest en GET /artifacts/:id onder het pogingsbewijs, wat
het source_delivered-ontvangstbewijs schrijft. Het nepkind leest de
gestagede __dispatch_input en het document, de repo-variant krijgt de
read-only checkout. Gemeten: SUCCEEDED, verdict GO met ongewijzigde
documenten, één source_delivered voor plan, claude_jobs QUEUE_REVIEW DONE,
root/reply-id in de view en na de projector-levering een reviewed-antwoord
met in_reply_to = root. Tegen de oude mcp (origin/main) faalt het geval:
geen __dispatch_input, geen ontvangstbewijs, geen message-ids.

Bestaande verwachtingen bijgewerkt als contractwijziging: de request-bronnen
bevatten nu ook __dispatch_input, en de configlezing wapent de producer
(T8 maakt die verplicht).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
s4m-codex-reviewer left a comment

APPROVED

Findings

  • Geen blokkerende of error-severity findings aangetroffen. De wijziging maakt de producer-eis consistent voor alle profielen, houdt de read-checkout niet-schrijfbaar voor de child en voegt gerichte unit-, contract- en deploymenttests plus operator-documentatie toe.

Geen gekoppeld plan gevonden — beoordeeld op codekwaliteit + product-standaarden.

# APPROVED ## Findings - Geen blokkerende of error-severity findings aangetroffen. De wijziging maakt de producer-eis consistent voor alle profielen, houdt de read-checkout niet-schrijfbaar voor de child en voegt gerichte unit-, contract- en deploymenttests plus operator-documentatie toe. Geen gekoppeld plan gevonden — beoordeeld op codekwaliteit + product-standaarden.
janpeter merged commit dcca32d664 into master 2026-10-02 15:44:05 +02:00
Sign in to join this conversation.
No reviewers
No labels
severity/s3
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
janpeter/scrum4me-docker!94
No description provided.