Skip to content

chore(openspec): archive 44 completed changes, and say what happened to the other 22 - #2057

Merged
rubenvdlinde merged 1 commit into
developmentfrom
chore/openspec-triage-archive
Sep 9, 2026
Merged

chore(openspec): archive 44 completed changes, and say what happened to the other 22#2057
rubenvdlinde merged 1 commit into
developmentfrom
chore/openspec-triage-archive

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

What this is

openspec/changes/ had grown to 67 entries. That directory holds work in flight, and a change is
supposed 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.

Bucket Count
Archivable, archived here 44
Archivable but missing the artefacts to archive with 1
Genuinely in flight 12
Superseded 4
Never started 5

The full per-change evidence is at /home/rubenlinde/comp-round2/work/OPENSPEC-TRIAGE.md, one line per
change. 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.json and OriDataQualityCheck.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.js with 3825 matching keys against the 2631/2309 the proposal
measured. Also first-time-setup, kanban-board-keyboard-status-transition and
remove-unused-map-clustering-dependency. That last one is instructive: the fix landed on 2026-07-07 and
the 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-alignment claims an expanded feature
list 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-view names src/views/cases/CaseDetail.vue in
all four of its tasks; that file was deleted by fe2949d when the case page became a declarative manifest
page. retire-status-history-page and retire-cmmn-caseplanstate are removal changes, where absence of
the thing is completion rather than evidence of nothing happening. git log --all separated those from
work that was never built: CaseEmailMatchService.php and FormsIntakeService.php have empty histories,
so email-case-matching phases 1 to 4 and leaf-integrations really have not started.

The deltas that had to be repaired first

openspec archive refuses a delta it cannot apply, and 12 of the 44 could not apply as written. The
repairs are all in openspec/changes/, none of them touches code.

Ordering, not defects (3). case-flow-human-steps creates the spec that three other changes modify,
and case-header adds the REQ-CDV-16 that the-case-page-finished rewrites. Archiving them in dependency
order 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 in askperson-recovers-a-missed-answer,
three in requestdecision-recovers-a-missed-conclusion, and REQ-ID-4 in contacts-you-can-find.

Genuine renames (2). task-management's "A task may hold a suspended flow run" becomes "A completed
task resumes its run through the guarded seam"; dmn-decision-tables' expression-grammar requirement gains
"owned by OpenRegister". Both now carry a ## RENAMED block 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-finished took 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-events retired the integration leaf, so all three REQ-PDCD requirements asked what
    happens when "the leaf is not registered", a call dossiq no longer makes.
  • dossiq-consumes-shared-dmn made PRIORITY work, so "PRIORITY hit policy is rejected" is false.
  • contacts-you-can-find replaced 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 ## REMOVED with a stated reason plus an ## ADDED under the same REQ id, rather
than 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-signature
change), two in dashboard, one in case-search-via-or-unified-search.

Two mechanical fixes. workflow-definition-model used legacy ### REQ-001: headers that the delta
grammar cannot address; those three are now ### Requirement: REQ-001 .... And
kanban-board-keyboard-status-transition numbered its two new scenarios 006d and 006e, which the spec
already had; they are 006f and 006g now.

proposals-are-cases is the one exception to all of the above. Its author applied the spec edits directly
in 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 as spec-changes-already-applied.md with a
header saying so.

Pre-existing debt fixed on the way

brp-register, kvk-register, initiator-display and initiator-selection had no ## Purpose section,
a legacy shape from the 2026-07-06 archive batch. That made the archiver refuse requester-on-the-case
outright. 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 --all before and after: no change and no spec is invalid because of this
commit
, 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 @spec and @e2e anchors pointing into openspec/changes/ are stale at scale already, and this PR
did not touch them.
420 anchors name retrofit-2026-05-24-case-management, archived months ago; about
150 change names are cited this way and most are already under archive/. Rewriting them is a mechanical
sweep across lib, src and tests and deserves its own change rather than riding along here.

contacts-you-can-find now ADDs REQ-ID-4, and contacts-domain also ADDs it. Only the first archived,
so its block is the one in the spec. When contacts-domain is eventually archived, its REQ-ID-4 has to
become 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) and portal-contribution
(move-portals-to-portaliq, archived here, owns the same file). That is a call for the maintainer, not for
an archive sweep, so they stay put.

Of the five never started, dossiq-mcp-adoption and hermiq-ai-tooling are worth keeping as backlog and
should be triaged together, since the second is gated on the first. retire-cmmn-caseplanstate is one week
old with a merged upstream dependency and is not abandoned. case-type-one-authoring-surface and
leaf-integrations need re-scoping rather than deleting.

Read /home/rubenlinde/comp-round2/work/OPENSPEC-TRIAGE.md for the per-change evidence before acting on
any of the 22 that stayed.

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

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/dossiq @ 0d9a758

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.

@rubenvdlinde

Copy link
Copy Markdown
Contributor Author

The two red checks are development's, not this PR's

quality / E2E Tests (Playwright) and quality / Quality Report fail here. They fail on
development too, at the exact commit this branch was cut from.

development push run for 719b62e, this branch's base:
https://github.com/ConductionNL/dossiq/actions/runs/34322780232 — the same two jobs, and only those two.
The four development push runs before it are also red or cancelled.

Playwright did start (Running ... tests using is present in both logs, so this is not the
never-started shape). The failing spec sets:

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.

@rubenvdlinde
rubenvdlinde merged commit 03ab6a8 into development Sep 9, 2026
47 of 49 checks passed
@rubenvdlinde
rubenvdlinde deleted the chore/openspec-triage-archive branch September 9, 2026 09:16
rubenvdlinde pushed a commit that referenced this pull request Sep 9, 2026
#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.
rubenvdlinde added a commit that referenced this pull request Sep 9, 2026
…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>
rubenvdlinde added a commit that referenced this pull request Sep 9, 2026
`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>
rubenvdlinde added a commit that referenced this pull request Sep 9, 2026
… 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>
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