Repository navigation
fix(lvs): freeze a verified LVS score now that LvsResult is no longer append-only - #1195
Merged
Merged
Conversation
… append-only Since #1124 dropped appendOnly so verify and archive could run, coordinators and compliance officers could also edit a verified score. LvsResultFreezeListener fixes the score fields once a result is verified, lets a verified result only move on to archived, and leaves admins and the import job unpoliced. The AssessmentResult and LvsResult freezes move into EvidenceFreezeListenerRegistrar to keep IntegrityListenerRegistrar under the coupling limit. See openspec/changes/lvs-score-freeze/.
…ption and demo row say A result entered by hand has no exchange job; gate 101 refused the demo row.
Contributor
Quality Report — ConductionNL/learniq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-specs | ✅ | ||||
| format | ✅ | ||||
| check-l10n-js | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| composer | ✅ | ✅ 107/107 | |||
| npm | ✅ | ✅ 747/747 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| lockfile sync | ✅ | ||||
| PHPUnit | ❌ | ||||
| Newman | ⏭️ | ||||
| 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 on any branch from the Actions tab, or locally with npx playwright test. |
||||
| Hydra gates | ❌ |
Quality workflow — 2026-09-28 16:13 UTC
Download the full PDF report from the workflow artifacts.
Contributor
Quality Report — ConductionNL/learniq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-specs | ✅ | ||||
| format | ✅ | ||||
| check-l10n-js | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| composer | ✅ | ✅ 107/107 | |||
| npm | ✅ | ✅ 747/747 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| lockfile sync | ✅ | ||||
| PHPUnit | ❌ | ||||
| Newman | ⏭️ | ||||
| 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 on any branch from the Actions tab, or locally with npx playwright test. |
||||
| Hydra gates | ❌ |
Quality workflow — 2026-09-28 16:38 UTC
Download the full PDF report from the workflow artifacts.
This was referenced Sep 28, 2026
This was referenced Sep 28, 2026
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.
Scope
Since #1124 took
appendOnlyoff LvsResult soverifyandarchivecould run, coordinators and compliance officers could also edit a verified LVS score. A newLvsResultFreezeListenerfixes the score fields once a result is verified and lets a verified result only move on toarchived, in the style ofAssessmentResultIntegrityListener.openspec/changes/access-control-ratchet-compliance/design.md("a freeze listener in the style ofAssessmentResultIntegrityListeneris a named follow-up"); TRACKER-R2 "ROUND 3 FINAL": LVS score freeze listener.verifiedorarchived:provider,instrument,moment,takenAt,rawScore,vaardigheidsscore,niveau,referentieniveau,dle,dataExchangeJobId,tenant_id.learnerId(learner merge) andassessmentResultId(back-link) stay writable; animportedrow can still be corrected.EvidenceFreezeListenerRegistrar, called fromIntegrityListenerRegistrar, which had hit phpmd's coupling limit.dataExchangeJobIdnullable),info.version0.30.0 to 0.30.1.Change:
openspec/changes/lvs-score-freeze/.Verification
vendor/bin/phpunit --filter LvsResultFreezeListenerTestred first (8 errors, 2 failures with the listener absent and unwired), then green (10 tests).composer check:strict(TMPDIR in the clone, timeout off): first run exit 1 on phpmd only (IntegrityListenerRegistrarcoupling 13, my line); lint, phpcs, psalm, phpstan clean andtest:all2121 tests OK (5 skipped). After the registrar split:composer phpmd0,composer psalm0,composer phpstan0.npm run lint0 (2 inherited warnings),npm run format0,npm run check:schema-l10n0. Notest:l10nscript.openspec validate lvs-score-freezevalid.vendor/conduction/hydra-gates/hydra-gates/scripts/run-hydra-gates.sh,HYDRA_GATE_BASE_REF=origin/development): exit 6. Six whole-tree gates red, none on this diff: 3 stub-scan (caller-identity-ignoredin six untouched services), 25 contract-coverage, 49 controller-exception-translation, 55 detail-page-discipline, 60 icon-vocabulary, and 101 demo-data-coverage. Gate 101 also named LvsResult (demo row withdataExchangeJobId: nullagainst a non-nullable string, from feat(data-exchange): integriq carries the exchanges, learniq keeps the gates (D7, D25) #1157); fixed here by declaring it nullable, as its description already says. Re-run standalone (generate_mock_register.py . --check --only-changed): LvsResult passes; DossierReview, ExchangePartnerApproval, TeldatumCheck (no demo rows) and OsoImportDossier (same null) remain, inherited.Inherited
phpcs warnings on untouched files (missing
@specon other classes) and two eslint warnings; none on lines this PR touches.Landing note
Touches
lib/Settings/learniq_register.json(info.version, LvsResult); other f-quality PRs bumpinfo.versiontoo.🤖 Generated with Claude Code