feat(IDEA-213): contracten voor managed queue dispatch (ST-1590) #61
No reviewers
Labels
No labels
severity/s4
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
janpeter/scrum4me-shared!61
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/idea-213-dispatch"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Draft — niet mergen. Geopend om CI te laten draaien; IP-10 t/m IP-14 van ST-1590 zijn nog niet uitgevoerd. Hoort bij Scrum4Me #251; de zeven
feat/idea-213-dispatch-branches horen bij elkaar.Inhoud
Gedeelde contracten (IP-01, IP-06 t/m IP-08): dispatch-types en job-kinds, statetabel, getekende start-permit, runtime-stopobservatie, bronpinning, validatie, gedeelde document-reader en de dispatch-modellen in
prisma/schema.prisma.Review-fixes (code-review 2026-09-20)
Geen wijzigingen in deze repo. Open MINORs: T-1853 (canonicalisatie, branch-ref, reply_to), T-1854 (klok-tolerantie en key-id van de start-permit), T-1855 (RUNNING bereikbaar zonder start).
Verificatie (lokaal)
95a4d8b) is door de reviewer gelijk bevonden aan deze HEAD.6d72c8f, twee commits vóór deze HEAD.Commits
365ac3ffeat(IDEA-213): define managed dispatch contracts and job kindsbd8e9fefeat(IDEA-213): define signed start permit contract6d72c8ffeat(IDEA-213): expose guarded Task dispatch occupancy70bb86ffeat(IDEA-213): define bound runtime stop observations3dd2b71fix(IDEA-213): require successful exact-scope stop observation2f3ba33feat(IDEA-213): pin execution sources and preserve code artifacts95a4d8bfix(IDEA-213): align managed source key and wire limits🤖 Generated with Claude Code
canonicalPreparedSourcesManifest sorted source keys with localeCompare (ICU/locale-dependent for '_', '-' and case) and derived the property order implicitly from the zod shape, so a consumer that re-canonicalises to verify the signed string could produce different bytes than the signer. Switch to UTF-16 code-unit ordering ('<' on strings) and build the object in an explicit property order, mirroring canonicalStartPermitClaims. Bound repository.productId (<=128, no control/space chars) and enforce DISPATCH_SOURCE_MANIFEST_MAX_BYTES at the production site. A fixture pins both the old localeCompare form and the new code-unit form so the wire change is visible and locked. Safe now because nothing is signed in production yet (draft PRs); every consumer re-pins afterwards. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>Add a `kid` to the start-permit claims (a wire-format version bump v1->v2) and a distinct `kid` to the prepared-sources manifest, so a verifier can trust a keyset of {kid, publicKey} and rotate Ed25519 keys with zero downtime. - `dispatchStartPermitClaimsSchema` is now version 2 and carries `kid`; the v1 vector is kept as a rejection fixture (`dispatch-start-permit-v1.json`) and the portable v2 vector is added (`dispatch-start-permit-v2.json`). - `validateStartPermitClaims` takes a keyset, selects the public key by the claim's `kid` (unknown/missing kid is a bounded refusal), and still enforces the m10 clock-skew tolerance and every identity binding; it returns the selected key for the consumer's own Ed25519 verify (kid selects the key, never the algorithm). - `selectDispatchVerificationKey` is the shared, total, crypto-free selector. - The manifest carries its own `kid` inside the signed bytes next to the purpose domain tag; `sourceBindingSchema` and the runtime-observation binding omit `kid` because it is a key selector, not part of the attempt identity. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>WIP: feat(IDEA-213): contracten voor managed queue dispatch (ST-1590)to feat(IDEA-213): contracten voor managed queue dispatch (ST-1590)Verdict: REQUEST_CHANGES
Geen gekoppeld plan gevonden — beoordeeld op codekwaliteit + product-standaarden.
Findings
lib/queue-dispatch-validation.ts:41:dispatchStateSchemaaccepteertUNCERTAIN_UNSTARTEDniet, terwijlDispatchStatedeze state wel exposeert endecideDispatchTransition('CLAIMED', 'lease_lost')hem produceert. Daardoor kunnen consumers een geldige dispatch-view/state uit de gedeelde state machine niet valideren, en juist de m11-safety split voor nooit-gestarte attempts wordt aan de API/contractrand onbruikbaar. VoegUNCERTAIN_UNSTARTEDtoe aandispatchStateSchemaen dek dit expliciet met een validatietest.Verificatie
node node_modules/typescript/bin/tsc --noEmitgeslaagd op een verse clone met de PR-diff toegepast.npm run verify/Vitest kon lokaal niet volledig draaien door sandbox/runtime-problemen met uitvoerrechten/native Rollup optional dependency (tsc: Permission denied, daarnafailed to map segment from shared objectbij Vitest).dispatchStateSchema omitted UNCERTAIN_UNSTARTED, so the shared validation rejected a state the shared state-machine itself produces (CLAIMED:lease_lost) and the projection handles (dispatchRootStatus → claimed). The m11 safety split for never-started attempts was unusable at the contract edge. Add the value after UNCERTAIN and cover it with a test that also asserts decideDispatchTransition('CLAIMED','lease_lost') output passes the schema. candidateStateSchema/attemptStateSchema left untouched (their types do not carry this state). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>APPROVED
Geen gekoppeld plan gevonden — beoordeeld op codekwaliteit + product-standaarden.
Findings
Review-notities
lib/queue-dispatch*contractmodules blijven binnen de productstandaard voorscrum4me-shared: pure TypeScript, interne imports enzod, zonder runtime/server-afhankelijkheden in productcode.QUEUE_TASK/QUEUE_REVIEWdefaults falen gesloten op onbeperkte tools,bypassPermissionsen te brede Codex-sandboxes; dit past bij de job-config ownership-regels in de architectuurdoc.scrum4me-sharedals canonieke schema-bron en markeert de SQL-only guards duidelijk voor de designated migrator.Niet lokaal uitgevoerd: er was geen PR-checkout/package in
/opt/agent; review is uitgevoerd op de aangeleverde unified diff plus productdocs.Review afgehandeld — F-S1 gerepareerd.
lib/queue-dispatch-validation.ts:dispatchStateSchemaaccepteerdeUNCERTAIN_UNSTARTEDniet, terwijl de gedeelde state-machine (decideDispatchTransition('CLAIMED','lease_lost')) die state produceert. Toegevoegd aan het enum + validatietest (rood-eerst bevestigd). Commitc65f5a8.Verificatie:
npm test538 passed. De vier consumers zijn apart herpind naarc65f5a8.