chore(openspec): archive 44 completed changes, and say what happened to the other 22 - #2057
Conversation
…hat blocked them openspec/changes/ held 67 entries. 44 of them describe work that is in `development` already, so they move to the archive and their deltas land in openspec/specs/. 22 remain: 12 partly implemented, 4 superseded, 5 never started, 1 finished but missing the artefacts to archive with. Every change was verified against the code, not against its tasks file. Six of the 44 carried zero ticked boxes and had shipped anyway. Delta repairs made so the archives apply cleanly: - Five requirements written as MODIFIED against a spec that did not have them become ADDED (the flow-engine trio, contacts-you-can-find). - Two are genuine renames and get a RENAMED block (task-management's resume requirement, dmn-decision-tables' hit policies). - Four requirements were rewritten wholesale by their change, dropping scenarios that are now false. Each is a REMOVED plus an ADDED with the reason recorded, rather than a silent rewrite. - Five scenarios that were merely omitted are copied back into their MODIFIED block unchanged. - Two legacy `### REQ-00n:` headers in workflow-definition-model become `### Requirement:` so the delta can address them. - The two kanban scenarios collided with existing 006d/006e ids and are renumbered to 006f/006g. Pre-existing spec debt fixed on the way: brp-register, kvk-register, initiator-display and initiator-selection had no `## Purpose`, which made the archiver refuse requester-on-the-case. The 11 capability specs the archive created got a written Purpose instead of the TBD placeholder. `openspec validate --strict --all` reports no change and no spec made invalid by this commit, and four specs that were invalid before are valid now.
Quality Report — ConductionNL/dossiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-vue3-compile | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 106/106 | |||
| npm | ✅ | ✅ 549/549 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ❌ | ||||
| Hydra gates | ✅ |
Quality workflow — 2026-09-09 08:59 UTC
Download the full PDF report from the workflow artifacts.
The two red checks are
|
| Specs failing | |
|---|---|
development @ 719b62e |
case-actions-menu:321, case-detail-kpis-and-tabs:416, case-header:297, case-identity:314, case-timeline:98, case-timeline:130, case-type-authoring-extras:494, case-type-authoring-extras:645, contacts-domain:362 |
| this PR | case-actions-menu:321, case-header:297, case-identity:314, case-timeline:98, case-type-authoring-extras:494, case-type-authoring-extras:645, contacts-domain:362 |
This PR's failures are a strict subset of the base's. Seven of nine, with
case-detail-kpis-and-tabs:416 and case-timeline:130 green here because other PRs fixed them since.
Nothing is red that was not red before, and this branch changes nothing outside openspec/: 44 directory
renames, 22 new capability specs, 25 modified specs, zero files under lib/, src/, tests/ or
appinfo/.
The other 40 checks pass. The 7 skips are the usual conditional jobs (deploy, Newman, SBOM, journeydoc,
app:check-code, features extract), all skipped on development runs too.
#2057 moved 44 changes into `openspec/changes/archive/`. It did not repoint the tests that cite them, so 27 spec paths across 17 e2e files named a file that is no longer there, in 119 places. A citation that resolves to nothing reads as verified and is not. Each one now points at the canonical spec where the anchor verifiably exists, and at the archived copy where it does not: the two `tasks.md` task ids, the kanban keyboard scenarios and the workflow-editor canvas scenarios. The five-work-tab scenario has a live successor, `the-strip-holds-six-tabs-and-no-more`, so its two citations go there rather than to the archive. Comment lines only. `playwright test --list` still resolves 381 tests in 67 files. Four citations remain broken and are NOT from #2057: bezwaar-management, case-map, subsidy-intake and workflow-board. `git log --all` finds no commit that ever added those spec files, and their anchors appear nowhere in `openspec/`, so those tests cite a spec that was never written. That needs a decision about the specs, not a repoint.
…an archived change (#2063) * fix(e2e): the tab strip wraps by design, so the spec asks for reach not one line Row A33 asked for the six work tabs to share one line at 1024. Measured, they cannot: six tabs need 661px on a line and this strip's tab row has about 280, and even a full-width strip yields roughly 570. The wrap is not a defect either. CnTabs wraps rather than scrolls on purpose, because a scrolling strip hides tabs behind an edge with nothing to say they are there. So the requirement now asks for what the handler actually loses when this breaks: the strip above the fold, and every tab visible, unclipped and on screen. Three spec files and the design note carried the old wording; all four now say the same thing. * fix(openspec): 55 test citations named a change that #2057 archived #2057 moved 44 changes into `openspec/changes/archive/`. It did not repoint the tests that cite them, so 27 spec paths across 17 e2e files named a file that is no longer there, in 119 places. A citation that resolves to nothing reads as verified and is not. Each one now points at the canonical spec where the anchor verifiably exists, and at the archived copy where it does not: the two `tasks.md` task ids, the kanban keyboard scenarios and the workflow-editor canvas scenarios. The five-work-tab scenario has a live successor, `the-strip-holds-six-tabs-and-no-more`, so its two citations go there rather than to the archive. Comment lines only. `playwright test --list` still resolves 381 tests in 67 files. Four citations remain broken and are NOT from #2057: bezwaar-management, case-map, subsidy-intake and workflow-board. `git log --all` finds no commit that ever added those spec files, and their anchors appear nowhere in `openspec/`, so those tests cite a spec that was never written. That needs a decision about the specs, not a repoint. --------- Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
`bezwaar-management`, `case-map`, `subsidy-intake` and `workflow-board` have no spec file, and `git log --all` finds no commit that ever added one. Their anchors appear nowhere under `openspec/`. So six citations across two e2e files claimed coverage against nothing, and read as verified. Four of the six had a real home and now point at it: - the workflow board, twice, at dashboard's `DASH-V1-006a: Board columns reflect status types`, which is the kanban of statuses the test opens - the case map at `case-map-overview`'s `OVERVIEW-01a: Display all cases on map` - the bezwaar list at `bezwaar-beroep-workflow`'s `Bezwaar index shows only bezwaar cases with correct columns` Two have no home and now say so with `@e2e exclude` and a reason, the form `dutch-value-l10n.spec.ts` already uses. The subsidie specs cover the keten and the settlement of case costs, not the page that lists the aanvragen. And bezwaar-beroep-workflow specifies the transitions, not a list re-rendering after one. Neither test is removed; each pins its behaviour until a scenario exists. Stacked on #2063, which repairs the 27 paths #2057 archived. Merge that first. Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
… for the same reason (#2123) "6,244 anchors, zero unresolvable" was measured with a reimplementation of gate 46's resolver rather than the resolver. It was wrong in both directions. Mine ignored two things the real one does. The flat `openspec/specs/<cap>.md` spelling, which predates the directory form and which the helper explicitly normalises: that alone made it call 13 of planix's healthy anchors dangling. And fragment checking: the helper verifies a `#fragment` names a heading somebody wrote, and mine stopped at the file. Run properly, this repo has 28 unresolved `@e2e` anchors, every one of them "anchor not found" rather than a missing file. That is the opencatalogi#85 shape the gate was built for, surviving in the half of the corpus the gate does not read. Two of the 28 are this session's own. #2057 renumbered the kanban delta's scenarios from `DASH-V1-006d/e` to `006f/g` to clear a collision with two the spec already had, and left `kanban-board-keyboard-status-transition.spec.ts` citing the old ids. Every check passed, the tests kept running, and they kept reporting green while naming scenarios that no longer existed. Gate 46 never looked because they are `@e2e`. Both are repointed at the canonical `openspec/specs/dashboard/spec.md`, per the rule this change writes down, and each fragment was probed through the real helper before it was written. The other 26 are pre-existing and stay. Each needs a judgement about which scenario it meant, which is the work rather than the sed, and the gate fix filed upstream surfaces them on the next PR that touches those files. Upstream gaps filed with the fleet measurement, taken with the real helper across 21 apps: ConductionNL/.github#726 (gate 46's pattern excludes `@e2e`; 1,964 such anchors fleet-wide, 194 dangling, against 55,720 `@spec` anchors with 1) and #727 (`appinfo/` and `scripts/` never enumerated; 52 anchors unopened, and 8 of openregister's 9 in `routes.php` are dangling, two of them ending in a stray full stop that was never a path). The rule underneath all of it: stop reimplementing the instrument. Every wrong number here came from a hand-rolled resolver and every right one came from running `check_spec_anchors.py`. Co-authored-by: Ruben van der Linde <release-bot@conduction.nl>
What this is
openspec/changes/had grown to 67 entries. That directory holds work in flight, and a change issupposed to leave it when it is done. 67 is not a queue, it is a backlog nobody had read in a while.
Every one of the 66 changes was checked against the code in
development. 44 move to the archive.22 stay, and the reasons are below so nobody has to redo the reading.
The full per-change evidence is at
/home/rubenlinde/comp-round2/work/OPENSPEC-TRIAGE.md, one line perchange. This body carries what a reader in three months needs.
A ticked box is not evidence
Verification was against the code, never against
tasks.md. That was the right call twice over.Six changes had zero ticked boxes and had shipped anyway.
ori-removal(0/6) was done by 0b18be5,which deleted
ori_register.jsonandOriDataQualityCheck.php.enforce-dwangsom-callback-signature(0/13) is live at
DwangsomPaymentCallbackController.php:163.nl-locale-coverage-gap-and-dutch-keys(0/17) passes
node tests/l10n/check-l10n.jswith 3825 matching keys against the 2631/2309 the proposalmeasured. Also
first-time-setup,kanban-board-keyboard-status-transitionandremove-unused-map-clustering-dependency. That last one is instructive: the fix landed on 2026-07-07 andthe change directory was committed the day after, so the boxes were never flipped.
One change was ticked 16/16 with the work absent.
beta-surface-alignmentclaims an expanded featurelist in
appinfo/info.xml; lines 9-24 and 29-44 still carry the original ten bullets. It is in bucket 2.Two absences were removals, not gaps.
case-dashboard-viewnamessrc/views/cases/CaseDetail.vueinall four of its tasks; that file was deleted by fe2949d when the case page became a declarative manifest
page.
retire-status-history-pageandretire-cmmn-caseplanstateare removal changes, where absence ofthe thing is completion rather than evidence of nothing happening.
git log --allseparated those fromwork that was never built:
CaseEmailMatchService.phpandFormsIntakeService.phphave empty histories,so
email-case-matchingphases 1 to 4 andleaf-integrationsreally have not started.The deltas that had to be repaired first
openspec archiverefuses a delta it cannot apply, and 12 of the 44 could not apply as written. Therepairs are all in
openspec/changes/, none of them touches code.Ordering, not defects (3).
case-flow-human-stepscreates the spec that three other changes modify,and
case-headeradds the REQ-CDV-16 thatthe-case-page-finishedrewrites. Archiving them in dependencyorder fixed those on its own.
MODIFIED against a requirement that exists nowhere (5). Written as MODIFIED, genuinely new. Now ADDED:
the runAs requirement in
adopt-flow-engine-consumer-seams, two inaskperson-recovers-a-missed-answer,three in
requestdecision-recovers-a-missed-conclusion, and REQ-ID-4 incontacts-you-can-find.Genuine renames (2).
task-management's "A task may hold a suspended flow run" becomes "A completedtask resumes its run through the guarded seam";
dmn-decision-tables' expression-grammar requirement gains"owned by OpenRegister". Both now carry a
## RENAMEDblock with FROM/TO.Requirements rewritten wholesale, dropping scenarios that are now false (4). A MODIFIED block replaces
the whole requirement, and the validator refuses to let it silently drop scenarios. In four cases the drop
was the point:
the-case-page-finishedtook the case page from nine tabs to six, so "The five work tabs come first" and"A tab with nothing in it is absent" describe a strip that is not on the page.
dossiq-delegation-via-eventsretired the integration leaf, so all three REQ-PDCD requirements asked whathappens when "the leaf is not registered", a call dossiq no longer makes.
dossiq-consumes-shared-dmnmade PRIORITY work, so "PRIORITY hit policy is rejected" is false.contacts-you-can-findreplaced a deep-link scenario that pins the table to five schemas by name,including a
/apps/dossiq/voorstellen/{uuid}route that no longer exists.Each is written as a
## REMOVEDwith a stated reason plus an## ADDEDunder the same REQ id, ratherthan a rewrite in place. The dropped scenarios are dropped on the record.
Scenarios merely omitted (5). Copied back into their MODIFIED block unchanged: two in
financial-integration(payment signal generation, IBAN validation, both untouched by a callback-signaturechange), two in
dashboard, one incase-search-via-or-unified-search.Two mechanical fixes.
workflow-definition-modelused legacy### REQ-001:headers that the deltagrammar cannot address; those three are now
### Requirement: REQ-001 .... Andkanban-board-keyboard-status-transitionnumbered its two new scenarios 006d and 006e, which the specalready had; they are 006f and 006g now.
proposals-are-casesis the one exception to all of the above. Its author applied the spec edits directlyin the implementation commit (af1ff19), leaving the delta file as prose reasoning rather than replacement
blocks. It archives with
skip_specs, and the file is kept asspec-changes-already-applied.mdwith aheader saying so.
Pre-existing debt fixed on the way
brp-register,kvk-register,initiator-displayandinitiator-selectionhad no## Purposesection,a legacy shape from the 2026-07-06 archive batch. That made the archiver refuse
requester-on-the-caseoutright. All four now have one, and all four went from invalid to valid under
--strict.The 11 capability specs this archive created got a written Purpose rather than the
TBD - created by archiving change ...placeholder the archiver leaves behind.Verification
openspec validate --strict --allbefore and after: no change and no spec is invalid because of thiscommit, and four specs that were invalid before are valid now. The 7 changes still failing strict
validation are all ones deliberately left in place (
case-dashboard-view,case-type-one-authoring-surface,dossiq-decisions-to-decidiq,integration-maps,portal-contribution,subsidieregeling-is-a-casetype,tenancy-onto-openregister-organisation), and each has a recommendation in the triage doc.Nothing outside
openspec/is touched: 44 directory renames, 22 new capability specs, 25 modified specs.Two things to carry forward
The
@specand@e2eanchors pointing intoopenspec/changes/are stale at scale already, and this PRdid not touch them. 420 anchors name
retrofit-2026-05-24-case-management, archived months ago; about150 change names are cited this way and most are already under
archive/. Rewriting them is a mechanicalsweep across
lib,srcandtestsand deserves its own change rather than riding along here.contacts-you-can-findnow ADDs REQ-ID-4, andcontacts-domainalso ADDs it. Only the first archived,so its block is the one in the spec. When
contacts-domainis eventually archived, its REQ-ID-4 has tobecome MODIFIED or the archiver will refuse the duplicate.
What is not archived, and why
Four changes are superseded and should be deleted rather than archived, because archiving them would
write requirements into
openspec/specs/that describe surfaces nobody built:bezwaar-beroep-cards-collapse(f355412 retired the pages instead of collapsing the cards; its own header already says SUPERSEDED),
case-dashboard-view,integration-maps(archived upstream in openregister) andportal-contribution(
move-portals-to-portaliq, archived here, owns the same file). That is a call for the maintainer, not foran archive sweep, so they stay put.
Of the five never started,
dossiq-mcp-adoptionandhermiq-ai-toolingare worth keeping as backlog andshould be triaged together, since the second is gated on the first.
retire-cmmn-caseplanstateis one weekold with a merged upstream dependency and is not abandoned.
case-type-one-authoring-surfaceandleaf-integrationsneed re-scoping rather than deleting.Read
/home/rubenlinde/comp-round2/work/OPENSPEC-TRIAGE.mdfor the per-change evidence before acting onany of the 22 that stayed.