Skip to content

feat(approval-routes): absorb the parafering runtime into the route engine - #1101

Merged
rubenvdlinde merged 3 commits into
developmentfrom
feature/parafering-route-runtime
Sep 2, 2026
Merged

feat(approval-routes): absorb the parafering runtime into the route engine#1101
rubenvdlinde merged 3 commits into
developmentfrom
feature/parafering-route-runtime

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

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

  • A stage-typed action vocabulary (ApprovalStageGuard): an advisory stage completes with advised (and needs the advice text), an endorsement stage with endorsed, a decisive stage with approved; a return needs its reason. Absorbed from dossiq's ParafeerStepGuard.
  • Mandated delegate signing, with a real registry check (MandateDirectory): a delegate may act only when onBehalfOf names the stage's person and a mandate is presented; a mandate that resolves in the local bevoegdheidstoedeling register 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 of delegatie-mandaatregister REQ-DMR-006.
  • Terugsturen: a returned action naming no step concludes the route back to its sender; naming one keeps the existing rewind.
  • Parallel co-signing: steps sharing an order become 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.
  • The ask rides OpenRegister's task surface (ApprovalStageTaskProjector + ApprovalTaskDecisionListener): each active person-assigned stage is mirrored onto a flow-task (person-assigned, marked decidiq: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 DecisionStage rows stay the engine rather than being replaced by TaskSequenceService: 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

ApprovalRouteConcludedEvent gained subjectSchema, externalReference and the full chronological actions record (defaulted trailing params — the positional contract is unbroken), so the producer keeps who-signed-what-when as case data without reading this register back. ApprovalRouteConclusionAnnouncer is 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

  • PHPUnit: 1349 tests green. New: ParaferingRouteRuntimeTest, MandateDirectoryTest, ApprovalRouteConclusionAnnouncerTest, ApprovalStageTaskProjectorTest, ApprovalTaskDecisionListenerTest; existing route/command/listener tests updated to the absorbed vocabulary.
  • Every absorbed auth-relevant guard is mutation-checked: dropping the stage vocabulary, the delegate structural check, the mandate registry call, the terminal-return conclusion, or the parallel-group hold each turns a named test red.
  • phpcs, psalm, phpstan, phpmd (per subdir) all clean.
  • hydra gates --scope-to-diff origin/development: all 42 applicable gates pass. Fixed a pre-existing gate-53 finding in passing (the FlowDetail page's type was flow, not the v2 flow-detail).
  • l10n: nl + en carry the two new schema property descriptions.

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

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.
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/decidiq @ 69fbf51

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.

@rubenvdlinde
rubenvdlinde merged commit 2806315 into development Sep 2, 2026
49 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant