Repository navigation
feat(governance): a consumer app reads its governance body back - #1694
Merged
Merged
Conversation
GovernanceBodyStateRequestedEvent is the read half of the governance-body contract: a consumer (dossiq) asks by governanceBodyId or by its own (sourceApp, externalReference) and gets the body back with active, quorum, jurisdiction and the roster (uid, role, external), answered in process by GovernanceBodyStateRequestedListener through GovernanceBodyQueryService. Only the asking app's own bodies are returned, reads run as the acting user, and a failed read leaves the event unhandled so the consumer falls back to its own copy instead of treating a live committee as gone. For dossiq migrate-committees-to-decidiq task 3. Spec: REQ-GBE-007.
rubenvdlinde
requested review from
Rem-Dam,
WilcoLouwerse,
bbrands02 and
rjzondervan
as code owners
October 10, 2026 10:39
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 | ✅ | ✅ 107/107 | |||
| npm | ✅ | ✅ 652/652 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| lockfile sync | ✅ | ||||
| PHPUnit | ✅ 2646/2646 · 8 skipped | ||||
| Newman | ✅ 363/363 · 1 skipped | ||||
| Playwright | ⏭️ deferred: E2E runs locally and on the promotion path only. This pull request targets development, so the suite is asked once per promotion into beta and main rather than once per push per open pull request. Run it locally with npx playwright test, or from the Actions tab on a branch with no open pull request into development. |
||||
| Hydra gates | ❌ |
Quality workflow — 2026-10-10 10:43 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
dossiq already holds its bezwaar committees in decidiq through
GovernanceBodyRequestedEvent, but it still reads them from its own copy, because decidiq has no read it may use (ADR-022/066 forbid reading decidiq's register directly). So a committee archived in decidiq can still be given new objections in dossiq.This adds the read half of the contract, in the same request/response-over-the-bus shape
DecisionStateRequestedEventuses:GovernanceBodyStateRequestedEvent: asked bygovernanceBodyIdor by the consumer's own (sourceApp,externalReference). Two result slots kept apart:isHandled()false means decidiq could not answer (absent, or the read failed), handled withoutisFound()means decidiq holds no such body for that consumer.GovernanceBodyQueryService::lookup(): the body (active,quorum,quorumRule,jurisdiction,statutoryBasis, terms, provenance) plus the roster (uid,name,role,external,label, dates). Only the asking app's own bodies; reads run as the acting user, so OpenRegister RBAC decides; filters are re-checked in PHP like the command service does.GovernanceBodyStateRequestedListener, registered inCrossAppEventRegistrar. It never throws; a failed read is left unhandled so the consumer falls back instead of treating a live committee as gone.Spec:
governance-body-eventsgains REQ-GBE-007; change archived asopenspec/changes/archive/2026-10-10-governance-body-read-seam(screens.md: no screen, in-process event).Needed by dossiq
migrate-committees-to-decidiqtask 3 (decision 156: build the dependency).New classes and their tests (coverage guard)
GovernanceBodyQueryService:tests/Unit/Service/GovernanceBodyQueryServiceTest.php(5 cases, against rows written by the realGovernanceBodyCommandService: found by reference with roster, by id withactive: false, another app's body refused, unknown/empty key, roster scoped to its body).GovernanceBodyStateRequestedListenerandGovernanceBodyStateRequestedEvent:tests/Unit/Listener/GovernanceBodyStateRequestedListenerTest.php(found, miss, failed read left unhandled, other event ignored, registrar wiring).Checks run locally
php -l, phpcs (phpcs.xml) and phpmd (phpmd.xml) on the four changed lib files: clean.composer check:strictNOT run locally: the machine's two heavy-command slots were held by another check. CI is the full check for this PR.