source: Klonkt/test/decisive-vote.test.js

main
Last change on this file was 29eb745, checked in by roboburr <roboburr@…>, 4 weeks ago

Doorslaggevend schuift mee, en de daemons hoeven geen TLS

Drie dingen van Bart (8-8).

  1. DOORSLAGGEVEND IS EEN STAND, GEEN MOMENT -- een fout in wat ik een uur eerder

bouwde. Ik berekende shaer:decisive een keer bij het doorsturen en bevroor het.
Bij vijf guardians staat er dan "je beslist niets", en zodra er een ja bij komt IS
elk van de anderen de doorslag. Precies de stille kant: het scherm zwijgt op het
moment dat het moet spreken. Na elke stem die het besluit open laat krijgen de
overgeblevenen nu een herziene stand, en alleen zij.

  1. DE VOLGPOORT MAG UITGEROLD (Barts akkoord). Zit in deze reeks.
  1. GEEN TLS VOOR DE TESTKUDDE. Barts vraag: waarom via https, gewoon localhost

::1. Terecht -- een certificaat en een publieke hostname toevoegen aan een doos
die ook andermans sites draait, om honderd neptestkinderen te bereiken, is de
verkeerde prijs.

Daarvoor mag de SSRF-poort gericht open: AP_ALLOW_HOSTS, een lijst van precieze
host:poort-paren. Geen "loopback is oke"-vlag. [::1]:3060 opent niet 127.0.0.1,
niet 3061, en niets in het interne netwerk -- want een brede vlag zet de
bescherming uit in een dev-omgeving, en dev-omgevingen worden productie. Leeg
tenzij een beheerder hem vult, en dat is de stand van elke productie-instance.

En het toetst iets dat we toch moesten kunnen: http MET HTTP-signatures, zonder
TLS. Een echt federatiegeval, tot nu toe nergens uitgeprobeerd.

ONDERWEG EEN LATENTE FOUT GEVONDEN. URL.hostname geeft een IPv6-literal met
blokhaken, en net.isIP herkent die vorm niet -- elk IPv6-adres viel door naar de
DNS-tak en strandde daar op ENOTFOUND. Geweigerd, maar per ongeluk en met de
verkeerde reden; isBlockedIp strippte die haken al en verwachtte dus input die
nooit aankwam. Nu wordt een IPv6-literal echt gecontroleerd.

EN EEN SLAAGTEST, want die ontbrak. Al mijn SSRF-toetsen controleerden alleen
weigeringen: de lijst helemaal negeren gaf nul rode toetsen, en de farm zou
stilletjes nooit werken. Nu bewijst er een dat wat op de lijst staat er ook
doorheen komt.

Suite 755/755. Drie mutaties gecontroleerd.

  • Property mode set to 100644
File size: 2.7 KB
Line 
1// Weet je dat je de doorslag geeft? (shaer-8vt)
2//
3// De telling is een race naar de drempel: zodra het aantal gehaald is, is het
4// besluit gevallen. Bij 2 van 3 is de tweede ja meteen de beslissing, en sinds
5// Barts meerderheidsbesluit is bij een volgverzoek met twee guardians de EERSTE
6// ja dat al. Wie antwoordde wist dat niet, en het scherm zei het nergens.
7//
8// Wat hier bewaakt wordt is vooral de FAALSTAND: bij twijfel waarschuwen. De
9// twee fouten zijn niet gelijk -- zeggen dat je beslist terwijl dat niet zo is
10// maakt iemand voorzichtiger dan nodig; niets zeggen terwijl hij wel beslist
11// laat hem het onwetend doen.
12//
13// Run: npm test
14import { test } from 'node:test';
15import assert from 'node:assert/strict';
16
17process.env.DATABASE_PATH = ':memory:';
18const gated = await import('../src/services/guardianship/gated.js');
19const follows = await import('../src/services/guardianship/follows.js');
20
21test('de laatste stem die nodig is, is beslissend', () => {
22 assert.equal(gated.isDecisive(1, 2), true); // nog een nodig: die van jou
23 assert.equal(gated.isDecisive(2, 3), true);
24});
25
26test('met nog twee te gaan ben je het niet', () => {
27 assert.equal(gated.isDecisive(0, 2), false);
28 assert.equal(gated.isDecisive(1, 3), false);
29});
30
31test('een drempel van 1 maakt de EERSTE stem beslissend', () => {
32 // Dit is het geval dat Barts meerderheidsbesluit oplevert: twee guardians,
33 // drempel 1. Wie als eerste ja zegt heeft het besloten.
34 assert.equal(gated.isDecisive(0, 1), true);
35 assert.equal(gated.isDecisive(0, follows.followThreshold(2)), true);
36});
37
38test('bij drie guardians is de eerste ja NIET beslissend', () => {
39 assert.equal(gated.isDecisive(0, follows.followThreshold(3)), false);
40});
41
42test('onzin telt als BESLISSEND, niet als veilig', () => {
43 // Een ontbrekend of onleesbaar getal mag nooit "je beslist niets" opleveren.
44 // Dat is de stille fout: het scherm zwijgt precies wanneer het moet spreken.
45 assert.equal(gated.isDecisive(undefined, undefined), true);
46 assert.equal(gated.isDecisive(NaN, NaN), true);
47 assert.equal(gated.isDecisive(null, null), true);
48});
49
50test('doorslaggevend is een STAND, geen moment', () => {
51 // Barts correctie (8-8): het geldt voor ALLE opvolgende beslissers. Bij vijf
52 // guardians is bij het doorsturen niemand het (drempel 3, een stem), maar na
53 // de tweede ja is iedereen die nog moet antwoorden het wel.
54 const drempel = gated.thresholdFor(5); // 3
55 assert.equal(gated.isDecisive(1, drempel), false, 'bij het doorsturen nog niet');
56 assert.equal(gated.isDecisive(2, drempel), true, 'na een ja erbij wel');
57});
58
59test('en bij drie guardians is het meteen zo', () => {
60 assert.equal(gated.isDecisive(1, gated.thresholdFor(3)), true);
61});
Note: See TracBrowser for help on using the repository browser.