Repository navigation
fix(zgw): a reference or uniqueness read that fails refuses the write (Q-dossiq-L11-3) - #3920
Merged
Merged
Conversation
Decision 224. The case type delete check, drc-004 and drc-007 let a request through when their lookup failed. They now refuse with 503 check-not-completed, name the rule, and log the rule and the object. drc-003 gives the same answer instead of claiming a duplicate, and the controller's relation check before a document delete (drc-008a) follows. Two sites leave the catch-return-null list, ceiling 263 to 261.
… facades method-decomposition slice 8h. The engine couples to 18 classes against 13 and takes 14 constructor arguments. The design gives it one facade over what a case declares and one over what a move writes; the engine keeps the order of the checks.
Characterisation before the StatusTransitionService split (method-decomposition slice 8h), green on the single class: the order of the five refusals, the conflict check, the one save of a closing move with the version it read, the timer after the save, the record that cannot be written back, the free-form refusals and the shape of the available transitions. Seven mutations of the engine turn it red.
…fourteen collaborators method-decomposition slice 8h. StatusTransitionService coupled to 18 classes against 13 and took 14 constructor arguments. Transitions/CaseDeclarations reads what a case declares about its status and its moves, and Transitions/CaseMoveLedger holds what a move writes. The engine keeps the decision and the order of the checks, takes nine arguments and couples to 12 classes. Both suppressions are gone; phpmd.suppressWarnings 183 to 181. The public methods and their answers are unchanged. The characterisation test and the five existing engine tests are green with only their constructor call changed.
…ceiling 256 to 254
…26; phpmd.suppressWarnings 182 to 180
…ments The change what-a-status-declares was archived on 7 October. 206 @SPEC lines in 42 files still cited its path under openspec/changes/, which no longer exists. They now cite openspec/specs/status-transition-engine/spec.md (REQ-SDC-01 to 05) and openspec/specs/doorlooptijd-dashboard/spec.md (REQ-SDW-01), where the requirements live. Two lines that became a repeat of the line above them are removed.
… (Q-dossiq-L11-3) The store reads the ZGW rules share answered a failed read as nothing found: a uniqueness search that failed counted the identificatie as free, and a zaaktype, informatieobjecttype or besluittype that could not be read counted as absent. They now throw LookupNotCompleted, and ZgwBusinessRulesService refuses the request for it once, with the 503 check-not-completed answer of decision 224, logged at error with the rule and what was read. Not found, and a read OpenRegister refuses (NotAuthorizedException), still read as none. No store in the request, or an empty schema setting, still skips the lookup (the coordinator's ruling on the question). The lookups lost their logger, which only logged the swallowed failures. catch-return-null: three sites left, ceiling 254 to 251. REQ-ZBR-022.
rubenvdlinde
requested review from
Rem-Dam,
SudoThijn,
WilcoLouwerse,
bbrands02,
remko48 and
rjzondervan
as code owners
October 14, 2026 21:17
This was referenced Oct 14, 2026
Merged
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.
Coordinator ruling on Q-dossiq-L11-3, following decision 224 (guards refuse when unsure). Stacked on #3919 (citations), #3858 and #3854: land after them.
What changes
The store reads that every ZGW rule shares (
Zgw/ZgwRuleLookups) answered a failed read as "nothing found":fieldPairExists): a search that failed counted the identificatie as free, so a duplicate could be stored.findObjectByField,findAllObjectsByField,findBySchemaKey): a zaaktype, informatieobjecttype or besluittype that could not be read counted as one that does not exist.They now throw
Zgw/LookupNotCompleted, naming what they were reading.ZgwBusinessRulesService::validate()catches it in one place and refuses with the answer decision 224 gave its guards: 503, codecheck-not-completed, noinvalidParams, logged at error with the rule (catalogi/zaaktypen create) and what was read. This covers the entry point's own ZTC guards and every per-register rule.What stays as it was:
DoesNotExistException, or no object) is still "none".NotAuthorizedException) is still "none": a rule cannot use a type the caller may not see, and that is not a check that could not run.The lookups lost their logger: it only logged the failures they swallowed.
Debt list
catch-return-null.allowlist.json: three sites left (findObjectByField,findAllObjectsByField,findBySchemaKey). Ceiling 254 to 251 on top of #3854's 256 to 254.Spec
REQ-ZBR-022 in
openspec/changes/guards-refuse-when-unsure, tasks section 5.Seen, not fixed
ZgwZrcZaakinformatieobjectRules::isCaseTypeInformatieobjecttypeMissing()reads the store itself (not through the lookups) and answers "not missing" when its search fails. Same shape, outside this ruling's scope.Verified (once, on the stack top 3bfc0b4, which holds #3858 and the four PRs above it)
Every
composer check:strictstage once, one at a time in the lane's check worktree (exit codes indq-l11-logs/r7/s31.rc):BooleanArgumentFlagfindings inlib/Service/Termijn/TermLetters.php(401, 425) that development carries since fix(letters): every date in a letter to the applicant reads the same way #3884/fix(portal): the Woo request form reads Dutch dates and names refused fields in Dutch #3895. Inherited.--no-coverage: 8,676 tests, exit 0 (7 skipped, 1 warning). A first run found 3 reds of this stack (BrcCrossRegisterSyncTeststill read the old warning lines), fixed in 28e4ad6, then the run above.ZgwBusinessRulesService, the throw infindBySchemaKey, the throw infieldPairExists, the not-found branch, the not-allowed branch and the null check inhandleDestroyeach turn their tests red.@covers/@usesof every touched test were checked by hand (each class a test can now execute is listed). CI is the check for that.src/manifest.json, which this stack does not touch; 23, 43, 51, 55, 104, 107). Gates 5, 13, 16, 25 and 46 pass.openspec validate guards-refuse-when-unsureandmethod-decomposition: valid.phpmd.suppressWarnings187 measured against 182) andeslint.inlineDisables15 against 14.No register change, so no
info.versionbump.