Conversation
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…erdeelpaneel als dialoog Twee besluiten van de eigenaar over etappe 3 verwerkt in spec en plan3: (1) pin/plafond/ rangorde zijn sessie-stand, geen projectdata — bevestigt de bestaande keuze in plan3 en komt als §11.7 + een §6-bullet in de spec; (2) de verdeelflow wordt een losse dialoog via de gedeelde Dialog-component en hasBlockingDialogOpen, geen drill-down binnen ResourceOccupancyView — draait taak 8's eerdere keuze om en trekt taken 9–13, de browsertest-voorschriften in taak 15, de Zelfreview en de i18n-/gebruikersgidsteksten recht. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… een lege dagenset (B1c) Bevinding 12: `scatterSlot` gaf `[]` terug zodra `need === 0` (fractionele duur strikt tussen 0 en 1, waarbij `distributeUnits` een lege vraagarray levert). `[]` is truthy, dus `findSlot` deed `parseDate(scatterDays[0])` op `undefined` — een Invalid Date die als starttijd de hele hoofdlus in reisde. De guard valt nu door naar het "geen slot"-vangnet. Onderzocht en in de testcase gedocumenteerd: met de huidige fits()/occurrenceFor()-implementatie is deze tak in de praktijk niet bereikbaar (een lege vraagarray maakt de aaneengesloten scan altijd triviaal geslaagd), dus de guard is een vangnet voor een toekomstige wijziging aan die symmetrie, geen live-reproduceerbare bug meer. Bevinding 11: zonder bindend venster (geen plafond, geen constrainToFloat) had de scatter-scan alleen `HARD_SCAN_CAP` (200.000) als rem. `scatterSlot` krijgt nu dezelfde tweetrapsgrens als de aaneengesloten scan (`scanLimit`, eventueel verlengd door een grootboekhorizon) — gemeten: 20 onafhankelijke onplaatsbare taken gingen van ~2,9s naar ~26ms. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…één hoop (B1c) `makeLedgerForDoc` negeerde `itemId` volledig (`residualOn`/`book` gingen rechtstreeks naar één gedeelde `placed`-emmer). Dat was tot dusver correct omdat `poolItemOf` uitsluitend `libraryItemId` teruggeeft, maar het is een ongeschreven invariant terwijl `LevelingPoolLedger`s contract expliciet een per-item-boekhouding belooft. `placed` is nu `placedByItem`, geboekt en gelezen op de sleutel; een boeking op een ander itemId raakt het poolitem van deze run niet meer. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… ingevoegde pauzedagen (B1c) `applyLeveling` accepteert nu `Pick<LevelingResult, 'delays' | 'gaps'>` plus een optionele `opts.scopeTaskIds`: met scope raakt de reset-lus alleen de gescopete taken (een delay op een taak buiten de scope is vaste last waarop het voorstel gerekend heeft), zonder scope blijft het gedrag byte-identiek. `applyLeveling` schrijft nu ook `splitGaps` — de volledige waarde uit de verdeler, idempotent herschreven via `clearLevelingGaps` wanneer een taak niet in `write.gaps` voorkomt. `clearLeveling` wist nu ook leveling-gaten en de no-op-guard telt ze mee; de ribbon-enable-check voor "Nivellering wissen" is letterlijk gelijk gehouden aan die guard. Dezelfde twee wijzigingen zijn doorgevoerd in de MCP-transactievariant (`createMcpTransactions.ts`). De motor-idempotentie die dit pas waar maakt: `levelResources`' `workTasks`- baseline stript nu ook `splitGaps` (symmetrisch met `levelingDelay`) voor in-scope taken, en `bookDemandAt`/`findSlot`/`scatterSlot` lezen hun occurrence-taak voortaan uit de gestripte `workById` in plaats van het ongestripte `taskById` — zonder die tweede stap bleef een leveling-gat uit een vorige nivellering via de kandidaat-scan doorsijpelen (getest en bevestigd met een falende idempotentiecase vóór deze uitbreiding). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… van die taak (B1c) `clearLevelingGaps` (etappe-2 taak 7) had tot nu toe nul aanroepplekken. Bedraad op elke bestaande `clearTimephasedWindow`-aanroepplek — de discoverable regel die het plan voorschrijft (`grep -rn "clearTimephasedWindow" src/`): `taskSlice.ts` (updateTask, setTaskCalendar), `resourceSlice.ts` (assignResource, unassignResource, moveAssignment ×2, removeCalendar, commitCalendarLibrary) en `createMcpTransactions.ts` (dezelfde acht MCP-draft-tegenhangers). Een gat met `source: 'leveling'` wordt gewist; een importsplit (geen `source`) blijft staan. Geen melding — dit is app-eigen afgeleide nivelleeruitvoer op een as die de gebruiker zelf net verzet heeft, geen importverlies zoals de M10-afronding. AFWIJKING — de spec (§4, "Invalidatie") noemt "voortgang" (completion/ actualStart/actualFinish) als vierde klasse naast duur/kalender/ handmatige datums. De discoverable regel wijst die klasse echter niet aan: `setTaskProgress`/`setActualStart`/`setActualFinish` roepen `clearTimephasedWindow` nergens aan (geverifieerd in de bron), dus een leveling-gat aan voortgang koppelen zou een NIEUW triggerpunt zijn, niet het overnemen van een bestaand patroon. Niet toegevoegd; gemeld i.p.v. stilzwijgend uitgebreid. De testcase dekt in plaats daarvan de "toewijzingen"- klasse, die de code zelf al als vierde trigger voert naast duur/kalender/ datums. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rafdruk (B1c) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… stille host-events (B1c) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…eerdere documenten (B1c) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…n (B1c) Plan 3 taak 7: één gedeelde LevelingReason→sleutel-mapping (levelingReasonKey.ts, met satisfies-poort op de taxonomie), de vier ontbrekende reden-teksten en de volledige resource.distribution-sleutelset in alle veertien locales met CLDR-pluralcategorieën. Poorten: verify:i18n, tsc en tests/library/run.sh exit 0. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Main verving intussen het undo-model: `undoStack`/`redoStack` per document(payload) is één app-globale sessiechronologie geworden (`historyEvents`/`nextHistorySequence`, `src/state/sessionHistory.ts`). De drie B1c-etappe-3-onderdelen die daarop leunden zijn in deze commit meegetrokken, want zonder dat compileert de merge niet: - taak 4: de `mutationSeq()`-bump staat nu als eerste regel van main's `beginUndoable` (vóór de batch-/lease-guard én vóór de pending-tak); `pushUndoSnapshot` bestaat niet meer. - taak 5: `StoreRuntimeOptions`/`emitHostEvent` mechanisch op main's runtime; elke `emitExtensionEvent(HOST_EVENTS.…)` in `src/state/slices/` loopt weer via `runtime.emitHostEvent` — ook main's nieuwe aanroep in `fileSlice`. - taak 6: `DistributionApplyRecord.docs[]` draagt niet langer `undoDepthAfterApply` maar het `historyEventId` (+ `sequence`) van het event dat het toepassen per document achterliet. `applyDistribution` registreert dat event voor een slaper zelf met `recordSessionHistoryDeltas` + de nieuwe pure `snapshotOfPayload`; `undoDistribution` poort per document op "dit event is nog het event dat `selectUndoHistoryEvent` voor dat document zou kiezen". Conflictoplossingen verder: `src/types/task.ts` main-inhoud (de branch-commit deed alleen CRLF→LF, main is al LF), `tests/library/run.sh` + `tsconfig.check.json` main (glob i.p.v. handopsomming), en in taskSlice/resourceSlice/createMcpTransactions de `clearLevelingGaps`-aanroepen van taak 3 bovenop main's `runtime.finishMutation`. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…sessiehistorie) Geen herschrijving — alleen gemarkeerde noten bij wat feitelijk anders is nu `undoStack`/`redoStack` per document vervangen zijn door de app-globale sessiechronologie: de mutatieteller bumpt in main's `beginUndoable`, de scratch-instantie levert geen undo-stap meer op, en het toegepast-record draagt per document een `historyEventId` in plaats van een undo-diepte. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…p.v. geïmporteerd (B1c) `verify:cycles` vond na de merge een echte importcyclus: appStore → librarySlice → scratchDocument → appStore. Die ontstond doordat `scratchDocument.ts` `createAppStoreContext` als WAARDE importeerde terwijl `librarySlice` (die appStore samenstelt) hem gebruikt. Plan-taak 5 stap 4 voorzag dit geval al en wees de route aan: de fabriek losmaken. Opgelost met hetzelfde patroon als `bindDefaultGridTransactionStore`: een late binding (`bindScratchDocumentContextFactory`) die `appStore.ts` één keer zet, naast de gridtransactie-binding. De typen blijven rechtstreeks geïmporteerd — `import type` wordt geërase en telt niet in de importgraaf, wat precies is waarom `verify:cycles` ná type-erasure meet. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…p.v. een vaste x (weekend-flake) De fixture hangt aan vandaag: op een weekenddag lag x=20 px vóór de balk en gaf getTaskBarBounds null (gemeten 2026-09-05, groen op 09-04 en 09-07). Pre-existent op main, los van B1c. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…tel op discrete momenten (B1c) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…loog (B1c) De tijdas van het bezettingsoverzicht is letterlijk uit `OccupancyHistogram` getrokken naar `occupancyAxis.ts` (domein, gatcompressie, dagbreedte, segmenten/breuken), zodat de stroken en het histogram per constructie op dezelfde x-posities uitkomen. Per document één SVG-rij: de vaste last als achtergrondband, de eigen boeking als blokken (gaten blijven gaten), een gestippelde staart voor toegestaan-maar-niet-benut, en een `role="slider"`-handle met volledige toetsenbordbediening (pijltjes/PageUp/PageDown/Home/End). Het label bij de handle toont het EINDDATUM-effect, niet de sleepafstand; blijft er ruimte over, dan staat er apart bij wat er gevraagd en wat er haalbaar was. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ing als het grootboek (B1c) DistributionProposal krijgt bookingByDay (letterlijk row.docs[].dailyLoad per document) en afterLoadByDay (wat er via bookPlaced daadwerkelijk geboekt wordt, incl. de ongewijzigde boeking van gepinde/#63-documenten) plus afterIncomplete. Zo hoeft de verdeeldialoog computeLibraryOccupancy niet nog een keer aan te roepen voor de "voor"-stand. Meegenomen: tests/library/check-apply-distribution.ts se hand-gebouwde makeProposal() kreeg de drie nieuwe verplichte velden erbij — zonder die aanvulling faalde de tsc-compile-afdwinging in tests/library/run.sh voor de hele suite, niet alleen voor dit werk. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…j loslaten (B1c) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…nte terugweg en voorstel-invalidatie (B1c) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…hapsstand (B1c) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…berekening en de levensduur van de terugdraai-strook kloppend gemaakt (B1c) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… (B1c fixronde 1, B2) `INITIAL_DOC_ID` stond op MODULE-niveau, dus elke `createAppStoreContext()` — ook elke wegwerpbare scratch-context uit `runInScratchDocument` — begon met hetzelfde `activeDocumentId` als document 1 van de gemounte app. `applyLeveling` in zo'n scratch-run claimde daarmee de sessie-permanente M10-gate (`notifiedLevelingDelayDocIds`, app-globale module-state in `timephasedLossNotice.ts`) voor het ECHTE eerste document, dat de melding daarna deze sessie nooit meer kreeg. Twee lagen: - `documentSlice` genereert het id nu per slice-instantie (`initialDocumentRegistry()`), niet per module; - `runInScratchDocument` neemt een `docId` en zet die op `activeDocumentId`/`documents`, zodat de bewerking onder het ECHTE document-id van de payload draait. `librarySlice.applyDistribution` geeft `w.docId` mee. Regressie: `check-scratch-document.ts` geval 5b — de scratch draait onder een eigen id, de gate van het app-document blijft vrij, en met een expliciet docId landt de claim op precies dat document. Zonder de fix faalt die case op vier poorten (gemeten). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… fixronde 1, B3) `resetDocumentScopedUI` gooide bij elke documentwissel/-opening/-sluiting niet alleen de verdeeldialoog dicht maar ook `ui.levelingDistribution` weg — inclusief `applied`, het record achter "Alles terugdraaien". Dat is de ENIGE manier om een verdeling die in meerdere documenten geschreven is in één keer terug te draaien, terwijl je die documenten juist moet kunnen bekijken (dus wisselen!) om te beoordelen of je haar wilt houden. Een tabwissel liet de verdeling zo onterugdraaibaar achter. Besluit (orkestrator, in lijn met de reviewer): `showDistributionDialog = false` blijft — het voorstel op het scherm hoorde bij een momentopname die niet meer geldt — maar de tune-state en het toegepast-record blijven staan. Verdwenen of verschoven history-events zijn geen reden om het record te wissen: `undoDistribution` toetst dat per document en meldt de rest via `skippedDocIds`. Het record vervalt alleen door "Alles terugdraaien", een NIEUW Toepassen, of het kiezen van een ANDER poolitem. Meegenomen: de docblokken bij `UIState.levelingDistribution`, `UIState.showDistributionDialog` en `DistributionUiState.applied`, het commentaar in `resetDocumentScopedUI` en bij de "toegepast"-strook in `DistributionDialog`, plus geval 12 in `check-apply-distribution.ts` (nu met een NIET-leeg record, zodat de terugweg zelf getoetst wordt) en de browsercase "van document wisselen sluit de dialoog". Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
De as werd op een vaste richtbreedte van 560 gebouwd terwijl hij tegen zijn dagbreedteplafond van 16 px aan liep: de hele track was 74 px en driekwart van de dialoog bleef leeg. De dialoog meet nu de ruimte tussen label en uitkomstlabel en geeft die als `minWidth` mee, met een ruimer dagbreedteplafond van 28 px; weinig dagen geeft dus lege track in plaats van metersbrede blokken. Daarnaast legt de eerste as van een dialoogsessie de dagbreedte vast (`fixedDayWidth`). Zonder dat fitte elke herberekening de groeiende dagenset opnieuw, kromp de tijdas onder de muis tijdens het slepen en sprong de andere rij mee. Een aanroep zonder de nieuwe opties — het bezettingshistogram — blijft onveranderd. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…is compacter
De ondertitel herhaalde de itemnaam die er als titel al boven stond; hij zegt nu
alleen nog wát je hier doet. Sleutel aangepast in alle veertien locales, dus
`{{item}}` is nergens meer nodig. Daarnaast gaat de plothoogte van "Nu" en "Na"
van 72 naar 56 px: twee lage staafjes in een paneel van 253 px las als "er is
iets niet geladen".
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Een tekort gaf een volkomen lege track — dat las als een weergavefout in plaats van als "dit past niet". De balk tekent nu waar dat werk vóór de verdeling stond als omlijnde blokjes in de projectkleur; een dag die wél geplaatst is krijgt geen spook. De rode pil en strook blijven onveranderd. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…teken
De pin was een onderstreept woordje tussen twee regels grijze tekst; hij krijgt
de vorm van "Reset" onderin dezelfde dialoog, met het accent in gepinde stand.
`aria-pressed` en het testanker blijven.
De statusstrook plakte clausules aan elkaar met een spatie, waardoor er twee
em-dashes achter elkaar stonden ("… niet meer actueel. — druk op Herbereken") en
de tekortkop zijn "…" als scheidingsteken leek te gebruiken. Eén helper zet er
nu " · " tussen. De legenda krijgt een breedtecap zodat hij wrapt in plaats van
de scroll-container breder te duwen dan de balken.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Twee regressies die de polishronde afdekt: een sleep in rij 2 laat de greep van rij 1 op dezelfde x staan (tijdens én na de herberekening) en verandert de dagbreedte niet, en een rij met een tekort toont spookblokjes in plaats van een lege balk terwijl de rij zonder tekort er geen krijgt. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…lokjes Bij een onbegrensd plafond staat de greep aan de rechterrand, dus die doos beslaat sinds de breedtefix de hele track. Op volle sterkte was hij daarmee het luidste element in de dialoog, terwijl hij ruimte aanduidt en geen boeking. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…kqmzu Rapport: resourcediagram — typelaag, rapportageperiode en toewijzingskolommen (#113, manuvarkey 1–3)
…kolommen laten vallen, weekendcijfers, getalnotatie, artifacts-beleid, middernacht-doc Alle zes vervolgpunten die na PR #138 waren blijven liggen, in één keer: - Eén weergaveregel voor de curvetoestand van een toewijzing (`src/engine/contour/curveState.ts`: `assignmentCurveState`, `contouredAssignmentIds`) die het eigenschappenpaneel én het resourcediagram delen; het verschil met de verdeelregel van `assignmentDayUnits` staat daar gedocumenteerd in plaats van op twee plekken herhaald. - De toewijzingskolommen vallen automatisch weg zodra de tabel minder dan `MIN_CHART_WIDTH_PX` (240 px) tijdlijn per papierbreedte overlaat (lange taaknamen met afkappen uit); `RenderReportResult.assignmentColumnsDropped`, melding in het overzichtsblok, sleutel in 14 locales. - Een tijdvenster zonder werkdag dat op de kalender-as terugvalt nummert nu ook de weekenddagen (anders stond er geen enkel dagcijfer). - Eén getalnotatie voor alle rapporten (`src/utils/reportNumber.ts`): hoogstens twee decimalen, geen duizendtalscheiding, decimaalteken van de app-taal — tabelrapporten via `dd.num`/`dd.signed`, de eenhedenkolom via `PrintOptions.numberLocale`; zonder taal de neutrale punt (tests ongewijzigd). - Artifacts-beleid vastgelegd: `artifacts/<onderwerp>/` = klein gecommit schermbewijs bij een PR, `qa/` = lokaal (CLAUDE.md, .gitignore). - Gids nl+en: presets zonder statusdatum schuiven na middernacht een dag op; de kolommen kunnen wegvallen bij een brede naamkolom. Regressie: check-print-report (weglaten bij 800 px naamkolom op A4 liggend, niet bij de gewone; weekendcijfers 10/11 op een weekendvenster; "1,5" bij numberLocale nl), check-reports (curvetoestand-helper, contourkoppeling, getalnotatie nl/en/de/plus). Browserspecs resourcediagram, tabelrapporten, contourdialoog en rapportopties groen. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014zosxbSXvi3YSGmeN1MsQq
… het helpt, één getalnotatie in alle rapporten, docs en melding waarheidsgetrouw Hyperkritische review op de restpunten-PR (twaalf bevindingen, alle opgepakt): - Toewijzingskolommen laten vallen (bevindingen 1, 2, 4): de grens is niet langer een vaste 240 px maar een vijfde van de printbreedte met een vloer van 160 px, en de render laat de kolommen alléén weg als de tabel zónder die kolommen wél past. A4 staand met verse instellingen houdt de kolommen dus; een naamkolom van 800 px op A4 liggend houdt ze óók (weglaten loste daar niets op: 8 px tijdlijn). De melding en beide gidsen noemen nu de echte hefbomen (papier/richting, lettergrootte, naamkolom, Voltooiing tonen) in plaats van "kap de namen af" — dat stond al aan (bevinding 3). - Getalnotatie (bevindingen 5–7): `formatReportNumber` dwingt Latijnse cijfers af (`-u-nu-latn`, fa koos anders arabext naast Latijnse tellingen), stript de bidi-markering U+200E die Inter in de vector-PDF als spatie zette, geeft "0" in plaats van "-0", en de plus komt uit `signDisplay: 'exceptZero'` in plaats van een ASCII-plus naast een typografische min. De Duur-cel van de Gantt-afdruk, `fmtDelta` in het variance-rapport (DOM én PDF) en de lag-tekst in het gezondheidsrapport (`localizeDecimalPoint`) volgen nu dezelfde notatie als de Eenh./d-cel en de tabelrapporten. - Middernacht-doc (bevinding 8): "vandaag" volgt de UTC-kalender en wordt bij elke weergave bepaald, niet "bij elke herberekening". - Artifacts-beleid (bevinding 9): benoemt dat `artifacts/tabel-overhaul/` van vóór de regel dateert. - Melding (bevindingen 10, 11): browserassertie op de melding (verschijnt op A4 staand 125 %, verdwijnt op 100 %); de vlag wordt gewist zodra er geen Gantt-render meer is. - `curveState` (bevinding 12): lege `curveValues` zijn geen geïmporteerde curve. Regressie: check-print-report (drop/geen drop/staand/lettergrootte, duurcel), check-reports (fa/ar/-0/NaN/onbekende taal/lag-tekst/lege curveValues), resource-gantt-report.spec.ts. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014zosxbSXvi3YSGmeN1MsQq
…p monotoon, melding zonder loze hefbomen, formatters gecachet Zeven bevindingen van de tweede hyperkritische review, alle opgepakt: - Bidi (bevinding 1, hoog): de U+200E die Intl in ar/fa vóór een teken zet wordt niet meer gestript — zonder staat "-2" in een RTL-alinea als "2-" (DOM én de bidi-js-levels van de vector-PDF). De tofu die Inter ervan maakte is een emissieprobleem en zit nu dáár: `bidiShape.stripBidiControls` haalt de stuurtekens (LRM/RLM/ALM/embeddings/isolaten) pas weg bij het shapen van elke run, ná de levelberekening; het Latijnse/CJK-snelpad en `measureText` strippen vóór het encoden; beide coverage-checks slaan ze over. De test die de strip eiste is omgekeerd, plus een headless `layoutRuns`-test met nepfonts. - Kolomdrop (bevinding 3): weer monotoon in de tabelbreedte — de tussen- variant "alleen als weglaten helpt" liet een dode zone open (A4 staand, naamkolom 350: tabel past de pagina niet, kolommen bleven, tijdas 1 px, geen melding) en een bredere naamkolom bracht de kolommen terug. Regressiecase op precies die zone; de 800-px-case laat nu wél vallen. - Melding + gidsen (bevinding 2): geen "zet Voltooiing tonen uit" en geen verwijzing naar de naamkolomslider (die in de automodus niet bestaat); alleen wat aantoonbaar ruimte geeft, zonder te beloven dat de kolommen terugkomen. 14 locales. - Formatters gecachet per taal (bevinding 4: ~35 µs → ~0,7 µs per cel), ook het decimaalteken voor `localizeDecimalPoint`. - Duurcel: niet-eindig ⇒ "—" in plaats van een losse "d" (bevinding 5). - WarningsPanel toont de lag met hetzelfde decimaalteken als het gezondheidsrapport (bevinding 6); bewerkbare cellen blijven ASCII. - `formatSignedReportNumber` past dezelfde "-0"-vangnet toe en een welgevormde maar onbekende taalcode valt expliciet terug (bevinding 7). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014zosxbSXvi3YSGmeN1MsQq
…kqmzu Rapport: restpunten uit de reviews op #138 (curvetoestand, kolommen laten vallen, weekendcijfers, getalnotatie, artifacts-beleid)
…ollt Rekt een opgerekt plafond de tijdas voorbij de dialoogbreedte, dan schoven de projectnaam links en de uitkomstpil rechts mee uit beeld — de eigenaar zag "eind +5 dage" en "max onbegrensd · benu" afgekapt tegen de rand. Beide kolommen zijn nu bevroren; legenda en einddatum-badges horen bij de rijen en schuiven evenmin mee. Het histogram schuift wél mee (kolom-op-kolom onder de dagblokjes) en krijgt aan weerszijden een even brede afdekstrook, zodat er geen staaf zichtbaar blijft voor een dag waarvan het blokje erboven achter het label zit. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…reep Eigenaarsbesluit 2026-09-14, dat het "live meerekenen per gesnapte werkdag" uit spec §5 vervangt: "het flikkert enorm omdat het elke keer herberekent; het moet pas herberekenen en de nieuwe statusmelding tonen wanneer ik de muis loslaat." Tijdens een pointer-sleep is alles lokaal — alleen de greep, de gestippelde rest en de plafondtekst van de eigen rij bewegen mee. Er gaat geen onCeilingChange uit, dus geen computeDistribution en geen hertekening van pil, badges, histogram, validatiestrook of prijskaartje. Het pointerup commit één keer, dus de bezig-toestand gaat precies één keer aan en uit. Toetsenbordstappen blijven wél discrete rekenmomenten (spec §3.4). De liveCommit-prop is daarmee weg; de in-flight-bewaking in de hook blijft, maar niet langer als sleep-throttle. Spec §5 krijgt een gedateerde eigenaarsnoot, de gidsen nl+en de nieuwe zin. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ar verschil (Masonry crew)
KLEIN's ankerschuif gaat van 63 naar 66 kalenderdagen. Daardoor begint "Build
masonry walls" op 2027-06-03 in plaats van 2027-05-31 en heeft MIDDEL's "Ground
floor masonry — House 6" VIER vrije werkdagen vóór de blokkade in plaats van één.
Waarom dat het verschil is: de schakelaar "Onderbrekingen toestaan" is in
ResourceLeveler.findSlot geen tweede zoekstrategie maar een terugval — eerst de
aaneengesloten scan, en pas als díé binnen het venster faalt komt scatterSlot met
de pauzedagen. Het venster bestaat alleen met een plafond ("maximale uitloop"),
en het bruikbare plafondbereik is precies zo breed als het aantal vrije werkdagen
vóór de blokkade. Bij 63 was dat bereik één enkel getal (plafond 14); bij 66 is
het 14 t/m 17, met het ronde "15 werkdagen" in het midden.
Gemeten op de drie showcases samen, poolitem Masonry crew, plafond 15 werkdagen
op De Akkers: onderbrekingen UIT ⇒ 1 tekort, geen uitloop, Toepassen geblokkeerd;
onderbrekingen AAN ⇒ geen tekort, 6 werkdagen uitloop, één taak met
leveling-gaten. Zonder plafond blijven beide standen gelijk (10/10) — dat is
engine-gedrag, geen data-eigenschap.
Beide kruisconflicten blijven staan; alleen de overlapstrook van de Masonry crew
wordt korter (2 dagen i.p.v. 5).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
De kop is in de gevulde stand drie regels hoog (itemnaam, ondertitel, introregel), en `items-center` centreerde het kruisje over die hele hoogte — het zweefde halverwege de kop. Met `items-start` lijnt hij uit op de titelregel, zoals in de eenregelige koppen elders. De kophoogte verandert niet (§7). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…aakt Twee nieuwe blokken in check-showcase-occupancy.ts, plus de gidsalinea nl/en. (b3) bewijst het verschil zelf: met een plafond van 15 werkdagen op De Akkers geeft de uit-stand een tekort (Toepassen geblokkeerd) en de aan-stand een toepasbaar voorstel met zes werkdagen uitloop en minstens één taak met leveling-gaten. De eis is bewust NIET "kleinere uitloop bij gelijke tekorten". Dat is met deze nivelleerder onbereikbaar, niet ongemeten: scatterSlot is een terugval na de aaneengesloten scan, dus de twee standen kunnen alleen verschillen op precies het punt waar de uit-stand vastloopt — en daar levert die stand een tekort op, geen grotere uitloop. Het commentaarblok bij (b3) legt dat uit zodat niemand deze assert "strenger" maakt in een richting die niet bestaat. (b4) bewaakt de BREEDTE: het plafondbereik waarin de schakelaar verschil maakt moet minstens drie opeenvolgende waarden tellen en het ronde 15 bevatten. Gemeten bereik nu: 14 t/m 17. Vóór de ankerschuif was het alleen 14 — dat is de reden dat het verschil in de demo niet te vinden was. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Zonder Home vooraf staat de greep al tegen de rechterrand van de as (plafond onbegrensd), en levert één sleep tot de vensterrand maar een handvol werkdagen op — te weinig om de as buiten de dialoog te laten groeien, dus toetste de test zijn eigen aanname niet. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Vervolg op het rekenen-bij-loslaten: zonder herberekening groeit de tijdas tijdens het slepen niet mee, en dan kan de geometrie de greep niet plaatsen — `advanceWorkdays` landt op een datum buiten de as en `rightEdgeX` klemt die terug op de rechterrand van het laatste assegment. Gemeten op de screenshot van deze ronde: het uitkomstlabel liep door naar "max 22 okt" terwijl de greep bij het fase-einde bleef plakken, dus je sleepte en er bewoog niets. De greep wordt tijdens een sleep daarom getekend op zijn anker plus het aantal gesnapte werkdagen × de dagbreedte — dezelfde omrekening die de waarde zelf bepaalt, dus greep en muis lopen per constructie synchroon. De gestippelde rest loopt mee tot diezelfde x. Het anker wordt pas op de EERSTE beweging vastgelegd, zodat een plafond dat van onbegrensd komt niet verspringt. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…e) in t3code/b1c-etappe3
De eigenaar vroeg in de gebruikstest wat "taken passen niet" betekent. De dialoog gebruikt een vocabulaire dat nergens anders in het programma voorkomt — speling, plafond, benut, vaste last, pauzedag, tekort, einddatum-verschuiving, vastzetten en het besparingsprijskaartje — en dat stond nergens uitgelegd op de plek waar je het leest. Onder de legenda staat nu een uitklapregel "Wat betekenen de termen?" met per term één zin. Ingeklapt kost hij één regel; uitklappen is een gebruikershandeling en mag dus de hoogte veranderen (spec §7 verbiedt alleen dat een REKENtoestand de maat laat verspringen). De open/dicht stand blijft lokale componentstate: in `ui.levelingDistribution` zou hij de fingerprint raken en een rekenronde uitlokken. Alleen niet-vanzelfsprekende termen; gewone app-begrippen als resource, capaciteit en project staan er bewust niet in. De veertien vertalingen nemen per taal de woorden over uit de labels die ze uitleggen. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…terug Bewaakt drie dingen die makkelijk stilletjes wegvallen: hij staat ingeklapt bij het openen, alle negen termen staan erin (poort op acht dt-regels), en inklappen brengt de boundingBox van de dialoog exact terug — de §7-belofte dat alleen een gebruikershandeling de hoogte verandert. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…rand uit De lijst erfde de breedtecap van de legenda — de AS-breedte. Dat werkt voor één korte regel, maar de definities zijn lopende tekst, dus bij een opgerekt plafond liepen ze mee de scroller in en las de eindscreenshot "… zonder dat zijn einddatum opschu". `trackSpace` is per constructie de breedte die naast de bevroren labelkolom zichtbaar blijft; daarmee wrapt de tekst waar hij hoort. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Het "…" stond in de vertaalstring zelf, dus "Nog 1 ploegdag tekort op 7 sep…" beloofde ook bij één datum dat er meer volgden. Het teken hoort bij de lijst: de dialoog plakt het nu aan de dagenparameter zodra er meer dan drie data zijn, en de veertien locales laten het weg. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
De native title van vier regels dekte na het loslaten de legenda en de knop naar de begrippenlijst af. De lange uitleg staat inmiddels in die begrippenlijst, dus de tooltip is in alle veertien locales ingekort tot één regel. aria-valuetext blijft ongewijzigd. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
"Toegestaan maar niet benut" is een maat; onbegrensd is dat niet, dus de doos vulde de hele track tot de rand van de as en beloofde ruimte die de as niet uitdrukt. buildStripGeometry geeft bij ceiling null nu freeBox null, ook tijdens een sleep. Vastgelegd als noot bij spec §4 (2026-09-14), met een geometriecase en een browserassertie erbij. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
De semantische tokens waren op wit gekozen: als tekst op een donkere kaart haalde de validatiestrook van de verdeeldialoog 2,55:1. Donker en high-contrast krijgen nu lichtere varianten (gemeten 7,3-8,3:1 resp. 10,5-15,1:1); het lichte thema zet de verzadigde waarden terug, want het gedeelde blok is :root plus dark. De handvol plekken waar zo'n token juist een ACHTERGROND onder witte tekst is (meldingsballon, gevaar-knoppen) krijgt in die twee thema's het verzadigde rood terug - een lichte tint is een tekstkleur, geen vlak. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…leen de thema-overrides blijven als verschil Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
B1c — etappe 3: het schrijfpad en de verdeeldialoog
Sluit B1c af (spec
docs/superpowers/specs/2026-08-17-b1c-nivelleren-restcapaciteit-design.md, plan 3docs/superpowers/plans/2026-08-31-b1c-plan3-schrijfpad-paneel.md, en het herontwerp van 12 september: specdocs/superpowers/specs/2026-09-12-b1c-verdeeldialoog-herontwerp-design.md, plan 4docs/superpowers/plans/2026-09-12-b1c-plan4-verdeeldialoog-herontwerp.md). W0 en etappe 2 (de verdeler-kern) stonden al op main; deze PR brengt alles wat een gebruiker ervan ziet.Wat er nieuw is
docs/superpowers/prototypes/2026-08-27-b1c-interface-lab.html, tabblad 4, eigenaarsbesluit 2026-08-27; opnieuw bevestigd en aangescherpt op 2026-09-12 na een gebruikstest): per project één balk als bediening op de gedeelde tijdas (telbare dagblokjes, arcering voor pauzedagen, meetlat grijs = speling / rood = einddatum-verschuiving, gestippelde rest voor toegestaan-maar-niet-benut), een handle aan het fase-einde (15×30, pointer capture, snappen per werkdag,role="slider"met echte datum inaria-valuetext, toetsenbord ←/→/PageUp/PageDown/Home/End), live meerekenen tijdens het slepen onder de ondersteunde schaal, een pin-tekstknop per rij, een gekleurde uitkomstpil ("+N dagen · max · benut N", rood bij tekort), het voor/na-histogram kolom-op-kolom onder de balken, en een altijd aanwezige validatiestrook (opgelost / tekort met data / alles vast / niet meer actueel). Geen rangordelijst meer: de rijvolgorde is de plaatsingsvolgorde op speling; sturen gaat via handle en pin.mutationSeq), documentwissel sluit de dialoog (sneltoetsen zijn modaal geblokkeerd sinds Status-update view and spreadsheet round-trip for progress data #27), degradatie boven 1000 taken/doc, 40 boekende taken of 6 documenten.applyLevelingscope-behoudend en schrijftsplitGaps(leveling-gaten met herkomst); idempotent hernivelleren; tijdbasis-, voortgangs- én constraintbewerkingen wissen leveling-gaten; eerlijkeNO_WINDOW_IN_HORIZONbij onderbrekingen; poolitem-grootboek per item; verdeler levertbookingByDay/afterLoadByDay.Switch-component (titelbalk + dialoog), gecentreerde knop gemeten.gids-verdelen-restcapaciteit(nl + en, incl. "Uitproberen met de voorbeelden"),gids-resourcebibliotheken,docs/library.md.Eigenaarsbesluiten die erin verwerkt zijn
Losse dialoog i.p.v. drill-down; tune-standen zijn sessie-stand; onderbrekingen in v1; Toepassen schrijft ook met "Automatisch berekenen" uit; rangordelijst weg uit beeld (12 sep); verschil-prijskaartje (12 sep); geen flitsen (12 sep); live meerekenen per gesnapte werkdag (bijstelling van spec-2026-08-17 §3.4).
Kwaliteit
npm run verifyexit 0 op de eindstand (168 browsertests). Nieuwe headless checks:check-distribution-strip-geometry(7 gevallen),check-distribution-chart-scale,check-showcase-occupancy,check-apply-distribution,check-distribute(uitgebreid),check-apply-leveling-scope,check-mutation-seq,check-scratch-document; browserspectests/browser/leveling-distribution.spec.ts(21 flows) enlibrary-view-badge.spec.ts.Parkeerlijst (niet in deze PR)
--success/--error/--warningzijn niet thema-adaptief (projectbreed, high-contrast-thema).aria-livevan de validatiestrook tijdens een sleep dempen.🤖 Generated with Claude Code