feat(intake): de bodies van protocol v1 en de routes (fase 4, stap 2) #2255

Merged
brenno merged 2 commits from feat/intake-bodies into main 2026-10-03 18:50:55 +00:00
Owner

Wat

Fase 4, stap 2 (gestapeld op de protocol-PR): de bodies van alle handelingen van protocol v1 en de routes, als zuivere typen in ocideck_form_core. Wat de server straks leest en schrijft, en wat de client straks bouwt en leest, staat nu op één plek, met één grammatica.

  • intake_bodies.dart
    • Het formulier zoals een server het geeft en een organisator het publiceert: een state en 1–32 varianten, elk {bundle, template} (een bundel bindt één tekst, dus elke taal is een variant). parseIntakeFormResponse (de client: state verplicht, onbekende leden genegeerd) en parseIntakePublication (de server: state optioneel, een onbekend lid geweigerd, ook in een variant). Een mislukking noemt de variant (index). Grenzen: een bundel ≤ 256 KiB, een sjabloon ≤ 1 MiB in bytes (dus 'é' telt twee), het geheel ≤ 8 MiB.
    • IntakePublishResult, IntakeTokenRequest (de hash, of null om in te trekken; het lid moet aanwezig zijn — null is een antwoord, ontbreken niet) en IntakeTokenResult, IntakeWithdrawRequest/Result, IntakeAckResult.
    • Een pagina van de lijst (IntakeSubmissionPage): een vastgehouden inzending of een grafsteentje; één slechte regel verpest de hele pagina — een lijst die stilletjes korter is dan die van de server is erger dan een fout. Cursorgrammatica ([A-Za-z0-9_-]{1,64}), ≤ 100 regels, ≤ 64 organisatoren per regel, elk één keer.
  • intake_routes.dart: matchIntakeRoute(methode, target) beslist welke handeling een verzoek is — voor de client die een target bouwt en de server die er een leest. Het target wordt streng gelezen: alleen letters, cijfers en . _ ~ - / ? = &; geen %, #, spatie, niet-ASCII, absoluut adres, slotslash of lege segmenten; een query alleen waar de route er een heeft. Zelf gesplitst, omdat Uri een .. wegwerkt en /v1/forms/.. dan als /v1 las (de test ving dat). Vaste volgorde: vorm (not-found) → methode (method-not-allowed) → ids (bad-request) → query (bad-request). De bouwers (intakeFormTarget en broers) weigeren een id die de server zou weigeren.
  • Nieuw in de foutcodes: not-found (404) en method-not-allowed (405); voor de pagina van een proxy is 404 nu not-found in plaats van form-unknown.
  • INTAKE_PROTOCOL.md is bijgewerkt (§2 request-targets, de tabel met foutcodes, per sectie wat gebouwd is), SOURCE_MAP en CHANGELOG ook.

Getoetst

  • 129 tests in de kern (ook op Chrome/dart2js): elke weigering van elk lid met zijn eigen geval, de grenzen tot op de byte (256 KiB, 1 MiB in tekens én in bytes, 8 MiB, 1 MiB voor een pagina), 32/33 varianten, 100/101 regels, 64/65 organisatoren, elke methode op elk pad, elk id-pad met elk soort slecht id, de volgorde van de beslissingen, de cursor-/limietgrammatica, en dat wat de client bouwt door de server wordt gelezen.
  • Mutatietoets over beide bestanden: 0 overlevers. De eerste ronde liet vijf overleven in matchIntakeRoute: vier waren een equivalente grens (q < 0 kan niet 0 zijn, want een target begint met /) en één een dode plaatshouder-closure — de functie is herschreven zodat die niet meer bestaan; verder één ontbrekende test (een inzending van 1 byte) die is geschreven.
  • make check (ongepiped, exit 0), check-registrations, check-secrets, sast, check-packages, test-packages: groen.

Wat er nog niet is

De referentieserver, IntakeHttpTransport, de handelingen in de app en de webinvuller.

## Wat Fase 4, stap 2 (gestapeld op de protocol-PR): de **bodies** van alle handelingen van protocol v1 en de **routes**, als zuivere typen in `ocideck_form_core`. Wat de server straks leest en schrijft, en wat de client straks bouwt en leest, staat nu op één plek, met één grammatica. - **`intake_bodies.dart`** - Het **formulier** zoals een server het geeft en een organisator het publiceert: een `state` en 1–32 varianten, elk `{bundle, template}` (een bundel bindt één tekst, dus elke taal is een variant). `parseIntakeFormResponse` (de client: `state` verplicht, onbekende leden **genegeerd**) en `parseIntakePublication` (de server: `state` optioneel, een onbekend lid **geweigerd**, ook in een variant). Een mislukking noemt de variant (`index`). Grenzen: een bundel ≤ 256 KiB, een sjabloon ≤ 1 MiB **in bytes** (dus 'é' telt twee), het geheel ≤ 8 MiB. - `IntakePublishResult`, `IntakeTokenRequest` (de hash, of `null` om in te trekken; het lid moet **aanwezig** zijn — `null` is een antwoord, ontbreken niet) en `IntakeTokenResult`, `IntakeWithdrawRequest`/`Result`, `IntakeAckResult`. - Een **pagina van de lijst** (`IntakeSubmissionPage`): een vastgehouden inzending of een grafsteentje; **één slechte regel verpest de hele pagina** — een lijst die stilletjes korter is dan die van de server is erger dan een fout. Cursorgrammatica (`[A-Za-z0-9_-]{1,64}`), ≤ 100 regels, ≤ 64 organisatoren per regel, elk één keer. - **`intake_routes.dart`**: `matchIntakeRoute(methode, target)` beslist welke handeling een verzoek is — voor de client die een target bouwt en de server die er een leest. Het target wordt **streng** gelezen: alleen letters, cijfers en `. _ ~ - / ? = &`; geen `%`, `#`, spatie, niet-ASCII, absoluut adres, slotslash of lege segmenten; een query alleen waar de route er een heeft. **Zelf gesplitst**, omdat `Uri` een `..` wegwerkt en `/v1/forms/..` dan als `/v1` las (de test ving dat). Vaste volgorde: vorm (`not-found`) → methode (`method-not-allowed`) → ids (`bad-request`) → query (`bad-request`). De bouwers (`intakeFormTarget` en broers) weigeren een id die de server zou weigeren. - Nieuw in de foutcodes: **`not-found`** (404) en **`method-not-allowed`** (405); voor de pagina van een proxy is `404` nu `not-found` in plaats van `form-unknown`. - `INTAKE_PROTOCOL.md` is bijgewerkt (§2 request-targets, de tabel met foutcodes, per sectie wat gebouwd is), SOURCE_MAP en CHANGELOG ook. ## Getoetst - 129 tests in de kern (ook op Chrome/dart2js): elke weigering van elk lid met zijn eigen geval, **de grenzen tot op de byte** (256 KiB, 1 MiB in tekens én in bytes, 8 MiB, 1 MiB voor een pagina), 32/33 varianten, 100/101 regels, 64/65 organisatoren, elke methode op elk pad, elk id-pad met elk soort slecht id, de volgorde van de beslissingen, de cursor-/limietgrammatica, en dat wat de client bouwt door de server wordt gelezen. - Mutatietoets over beide bestanden: 0 overlevers. De eerste ronde liet vijf overleven in `matchIntakeRoute`: vier waren een equivalente grens (`q < 0` kan niet 0 zijn, want een target begint met `/`) en één een dode plaatshouder-closure — de functie is herschreven zodat die niet meer bestaan; verder één ontbrekende test (een inzending van 1 byte) die is geschreven. - `make check` (ongepiped, exit 0), `check-registrations`, `check-secrets`, `sast`, `check-packages`, `test-packages`: groen. ## Wat er nog niet is De referentieserver, `IntakeHttpTransport`, de handelingen in de app en de webinvuller.
intake_bodies.dart: het formulier (varianten, state), het tokenverzoek, de intrekking, het
publicatieresultaat, een pagina van de lijst en het resultaat van ack — een verzoek weigert een
onbekend lid, een antwoord negeert het. intake_routes.dart: matchIntakeRoute leest een
request-target streng en beslist in vaste volgorde (vorm, methode, ids, query); de bouwers voor
de client weigeren wat de server zou weigeren. Nieuw: de foutcodes not-found en method-not-allowed.
brenno merged commit 5f744cc44c into main 2026-10-03 18:50:55 +00:00
brenno deleted branch feat/intake-bodies 2026-10-03 18:50:55 +00:00
Sign in to join this conversation.
No description provided.