feat(approval-routes): absorb the parafering runtime into the route engine - #1101
Merged
Merged
Conversation
The stage-typed vocabulary, mandated delegate signing judged against the local toedeling register, the terminal return (terugsturen), parallel co-signing groups, a conclusion announced from every concluding path with the full sign-off record on the event, and the ask mirrored onto OpenRegister's task surface. dossiq's retirement of its local runtime (parafering-runtime-to-decidiq) depends on this and merges after it.
…r each PHPMD flagged the absorbed runtime's weight honestly: the engine class had grown past the complexity threshold. The fail-closed authorisation questions move to ApprovalStageGuard (the split dossiq's ParafeerStepGuard made, for the same reason) and the pure step-to-stage shaping to ApprovalRouteStepMapper. Neither is a second engine: nothing in either advances a route or writes a row.
…per methods carry their spec 'flow' is not in the v2 page-type enum and resolves to no component in the renderer's page map, so the FlowDetail route rendered nothing manifest-driven. Found by gate-53 on the assembled manifest; pre-existing, fixed in passing per the repo's standing rule. The step mapper's methods gain the @SPEC tags gate-16 asked for.
rubenvdlinde
requested review from
Rem-Dam,
SudoThijn,
WilcoLouwerse,
bbrands02,
remko48 and
rjzondervan
as code owners
September 2, 2026 11:42
Contributor
Quality Report — ConductionNL/decidiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-nav-ceiling | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-l10n-js | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| composer | ✅ | ✅ 104/104 | |||
| npm | ✅ | ✅ 537/537 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ✅ | ||||
| Playwright | ⏭️ deferred — runs on the promotion into beta/main, not on a pull request into development | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-09-02 11:48 UTC
Download the full PDF report from the workflow artifacts.
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.
What this does
The approval-route engine absorbs the parafering runtime dossiq is retiring, so dossiq can delegate parafering the way it already delegates decisions: raise, wait for the conclusion, record. Four capabilities dossiq's pipeline owned that this engine did not are now here, and the two seams that made full delegation impossible are closed.
What the engine absorbed, and how it rides the task surface
ApprovalStageGuard): an advisory stage completes withadvised(and needs the advice text), an endorsement stage withendorsed, a decisive stage withapproved; a return needs its reason. Absorbed from dossiq'sParafeerStepGuard.MandateDirectory): a delegate may act only whenonBehalfOfnames the stage's person and a mandate is presented; a mandate that resolves in the localbevoegdheidstoedelingregister must be effective, in-window, and issued to that delegate. dossiq recorded these fields but left the check "for the future MandaatService" — this is that future. Scoped to route sign-offs, not Decision transitions, so it stays clear ofdelegatie-mandaatregisterREQ-DMR-006.returnedaction naming no step concludes the route back to its sender; naming one keeps the existing rewind.orderbecome stages that sign side by side; the group advances when its last member completes. A stage's sequence is now the step's own order.ApprovalStageTaskProjector+ApprovalTaskDecisionListener): each active person-assigned stage is mirrored onto a flow-task (person-assigned, markeddecidiq:approval-stage), so the sign-off lands in the approver's work queue; an answered projected task becomes an engine action under the same rules. Best effort — an instance whose OpenRegister lacks the task surface loses visibility, never correctness.Why the
DecisionStagerows stay the engine rather than being replaced byTaskSequenceService: that surface is ordinal-only, group-assigned, has no return primitive, and has nowhere to put a per-action mandate. A parafering route needs exactly what it excludes, so the ride is at the task layer — real flow-tasks carry each ask, the stage rows keep the truth.The conclusion out
ApprovalRouteConcludedEventgainedsubjectSchema,externalReferenceand the full chronologicalactionsrecord (defaulted trailing params — the positional contract is unbroken), so the producer keeps who-signed-what-when as case data without reading this register back.ApprovalRouteConclusionAnnounceris now the single door: the cross-app command, the REST surface, and the task inbox all announce through it. An internal route (no sourceApp) announces nothing, the precedent decisions set.Checks
ParaferingRouteRuntimeTest,MandateDirectoryTest,ApprovalRouteConclusionAnnouncerTest,ApprovalStageTaskProjectorTest,ApprovalTaskDecisionListenerTest; existing route/command/listener tests updated to the absorbed vocabulary.--scope-to-diff origin/development: all 42 applicable gates pass. Fixed a pre-existing gate-53 finding in passing (the FlowDetail page'stypewasflow, not the v2flow-detail).Train order
🔴 This PR merges FIRST. Its counterpart, dossiq
feature/parafering-runtime-to-decidiq(ConductionNL/dossiq), deletes dossiq's local parafering engine on the assumption this engine already holds the runtime. Merge dossiq's PR the other way round and a voorstel entering parafering has nothing anywhere to run its chain. Sequence: this PR, then dossiq's.🤖 Generated with Claude Code