not 849bf4723b
CI / lint (push) Successful in 1m34s
CI / build (push) Successful in 1m30s
CI / unit (push) Successful in 1m47s
CI / frontend (push) Successful in 3m36s
CI / mutation (push) Successful in 7m27s
CI / verify-stack (push) Canceled after 0s
ci: unstick verify-stack on Gitea 1.27 + act_runner 2.0.0 (closes #134) (#135)
## What & why

After the Gitea 1.27 + act_runner 2.0.0 upgrade, `verify-stack` never starts: the run sits in `waiting` forever with no logs for that job, while the other five jobs pass — so `main` stays pending/red (P0). See #134.

Closes #134

### Root cause

`verify-stack` was the only job gated by a status-function `if` on top of `needs`:

```yaml
verify-stack:
  needs: [mutation]
  if: ${{ !cancelled() }}
```

Gitea 1.27 reworked cancellation/aggregation so that `always()`/`cancelled()`-gated `needs` jobs route through a new transitional **`Cancelling`** state + server↔runner **capability negotiation** ("Requires Gitea Runner 2.0.0"). On this 1.27 + 2.0.0 pairing that handshake doesn't resolve, so the job is never dispatched and never leaves `waiting`. Plain jobs (no `if`/`needs`) are unaffected — exactly the observed pattern. It worked pre-upgrade (old runner).

### Fix

Drop the `if: ${{ !cancelled() }}`; keep `needs: [mutation]`. Default `if: success()` dispatches normally and still serialises the two memory-heavy jobs (OOM avoidance, #126).

**Trade-off:** the `!cancelled()` (added in #127) let verify-stack run even when the mutation ratchet fails. Now a failing mutation skips verify-stack; the fix-and-re-push re-run exercises it, so the signal isn't lost — just deferred to the green-mutation run. If we later want both signals on one run, serialise via a `concurrency` group rather than `needs` + `always()`.

Documented as §7 in `docs/runbooks/gitea-actions-gotchas.md`.

## Note on the stuck run

Run 582 (the #133 merge) will **not** clear itself and must be force-cancelled from the Actions UI (plain cancel can also stall on this version, gitea#35782). This PR's own run is the first real test of the fix — if `verify-stack` dispatches and runs here, the fix holds.

## Definition of Done

- [x] Linked issue (#134).
- [x] Conventional Commit referencing the issue.
- [ ] CI green — this PR's run is the verification (verify-stack must dispatch).
- [x] Runbook updated (gotchas §7).
- [ ] Closed by the merging PR.

🤖 Generated with [Claude Code](https://claude.com/claude-code)Reviewed-on: #135
2026-07-24 11:59:27 +00:00
2026-07-14 14:46:55 +00:00
2026-06-03 11:38:28 +02:00

register-reference

A reference application demonstrating how to build a Dutch government register (a BIG-style professional register) on top of unforked Common Ground modules — OpenZaak, Open Notificaties, Objecten, Open Klant — with loose coupling, modern workflow tooling, and data-governance ready integration points.

This repository is the runnable companion to Respellion's Foundations playbook entry on Common Ground architecture for non-municipal contexts (CIBG, DUO, RVO, and similar uitvoeringsorganisaties).

Status: under active development. See BACKLOG.md for the current iteration.


Start here

Document Purpose
docs/PRD.md What we're building and why. Goals, non-goals, architecture summary, scope. Read once at project start.
CLAUDE.md How we work. Engineering principles, TDD/DDD/BDD discipline, non-negotiable architectural rules, Gitea conventions. Read every task.
BACKLOG.md Iteration plan. A curated mirror of the active Gitea milestone — Gitea Issues are the system of record.
docs/architecture/ Diagrams (Mermaid sources) and ADRs. Start with adr-0001-loose-coupling.md.
docs/runbooks/ Operational guides: local startup, seeding, common failures, CI debugging.

The day-to-day operational pages — environment URLs, known issues right now, on-call notes — live in the Gitea Wiki for this repository. The wiki points at docs/ for anything authoritative.


What this application demonstrates

  • A BIG-style professional register modelled on Dutch public-sector patterns, with four end-user portals: self-service, openbaar register, behandel-portal, beheer-portal.
  • Common Ground modules as upstream peers — never forked, reached only via documented APIs (ZGW, NRC events).
  • An Anti-Corruption Layer that confines all ZGW knowledge to one place, so the rest of the codebase stays domain-shaped rather than municipality-shaped.
  • BPMN + DMN workflows via Flowable as a separate, swappable module — using the external-task job-worker pattern so BPMN models never reach into OpenZaak.
  • A read projection as the public-facing data path, decoupled from the authoritative modules.
  • Synthetic data and mock identity (Keycloak realms standing in for DigiD, eHerkenning, eIDAS, and a medewerker IdP) so the whole system runs locally without external dependencies.
  • TDD, DDD, BDD, mutation testing, ADRs, and Conventional Commits as enforced defaults — encoded in CI.
  • Gitea-native delivery: source, issues, milestones, project boards, releases, container registry, packages, wiki, and Actions.

For the architecture rationale, see docs/PRD.md §3 and docs/architecture/.


Local quickstart

Prerequisites

  • .NET 10 SDK (for make lint/build/unit)
  • A container engine with Compose v2 — Docker, or rootless Podman (see docs/runbooks/ci.md for the Podman + Compose-provider setup)
  • make, curl, git
  • ~4 GB free RAM, ~5 GB free disk (grows as services land)

Clone

git clone git@git.labs.respellion.tech:eho/register-referentie.git
cd register-referentie

Wired today (Iteration 0): only the placeholder BFF exists so far. Get to green in under 10 minutes — run the full check gate, or just the running service:

make ci          # lint + build + unit + container smoke — the CI gate
docker compose -f infra/docker-compose.yml up -d --build --wait
curl http://localhost:8080/health     # -> Healthy

--wait exits non-zero unless the container reports healthy, so it doubles as the compose-up smoke test. The remaining services and the URLs below land in later slices.

Target service URLs (most land in later slices)

Service URL
Self-Service portal http://localhost:4200
Openbaar register http://localhost:4201
Behandel-portal http://localhost:4202
Beheer-portal http://localhost:4203
BFF http://localhost:8080
OpenZaak http://localhost:8000
Open Notificaties http://localhost:8001
Flowable http://localhost:8080
Keycloak http://localhost:8180
MkDocs site (after build) http://localhost:8000/docs/

Test credentials, BSNs, and personas: see docs/synthetic-data.md.

Build the docs site

python3 -m venv .venv && .venv/bin/pip install mkdocs-material
.venv/bin/mkdocs serve         # live preview at http://localhost:8000
.venv/bin/mkdocs build         # static site in ./site

Repository layout

register-reference/
├── apps/                       # Angular portals (Nx monorepo)
│   ├── self-service/
│   ├── openbaar/
│   ├── behandel/
│   └── beheer/
├── libs/                       # shared Angular libs (UI, auth, generated API client)
├── services/                   # .NET services
│   ├── bff/
│   ├── domain/                 # BIG Domain Service
│   ├── acl/                    # Anti-Corruption Layer (the only code that knows ZGW)
│   ├── event-subscriber/
│   └── projection-api/
├── workflows/                  # BPMN + DMN sources
├── infra/                      # docker-compose, Keycloak, OpenZaak, Flowable, seed
├── tests/
│   ├── acceptance/             # Gherkin / Reqnroll BDD scenarios
│   └── e2e/                    # Playwright
├── docs/                       # versioned documentation (MkDocs source)
├── .gitea/                     # Gitea Actions workflows, issue/PR templates
├── CLAUDE.md                   # working agreements
├── BACKLOG.md                  # iteration plan (mirror of active milestone)
└── README.md

Full description in docs/PRD.md §9.


Working in this repository

Source of truth for work: Gitea Issues + Milestones for this repository. BACKLOG.md is a mirror.

Branching: trunk-based. Short-lived branches off main, named <type>/<issue-number>-<short-slug> (e.g. feat/14-acl-default-fill).

Commits: Conventional Commits, referencing the Gitea issue:

feat(acl): default-fill bronorganisatie (refs #14)

The merging PR closes the issue via closes #14 in the squash-commit body.

Pull Requests: the unit of review. Squash-merged. PR template enforces the Definition of Done checklist from CLAUDE.md §3.

Releases: CalVer (YYYY.MM.PATCH), tagged on main, changelog generated by git-cliff, published as a Gitea Release with container images in the Gitea Container Registry.

See CLAUDE.md for the full working agreements, the architectural non-negotiables, and the rules Claude Code follows on every task.


Testing

  • Unit tests — dominant. .NET (xUnit) and Angular (Vitest / Testing Library).
  • Integration tests — Testcontainers-driven, exercising real OpenZaak, Flowable, NRC.
  • Acceptance tests — Gherkin scenarios in tests/acceptance/, one per user-visible flow.
  • End-to-end — Playwright, expanding slice by slice from the walking-skeleton happy path.
  • Mutation testing — Stryker.NET and Stryker, baseline-ratcheted on main.

Run everything:

./tools/test-all.sh

Run a focused slice (example):

dotnet test services/acl

Contributing

  1. Find or open a Gitea issue using one of the templates in .gitea/ISSUE_TEMPLATE/ (slice.md, bug.md, adr-proposal.md).
  2. Assign yourself, move it to "In progress" on the milestone's project board.
  3. Branch off main, follow the CLAUDE.md working agreements (TDD: red commit → green commit → refactor commit).
  4. Open a PR using the template, link the issue, ensure the Gitea Actions pipeline is green.
  5. Squash-merge once approved. The merging commit closes the issue.

If a task pushes against any of the architectural rules in CLAUDE.md §8, stop and open an adr-proposal issue first. That conversation is more important than the code.


License and attribution

Respellion-authored code is licensed under EUPL-1.2. Upstream Common Ground modules retain their own licences (typically EUPL-1.2 or MIT — see each module's repository).

This reference application is not an official product of CIBG, DUO, VNG Realisatie, or any government body. It is a Respellion playbook artefact illustrating an architectural pattern.


Contact

  • Issues, questions, proposals: open a Gitea issue on this repository.
  • Architectural discussion: start with an adr-proposal issue.
  • Anything sensitive: contact Respellion through the channel in docs/runbooks/contact.md.
S
Description
No description provided
Readme
1.8 MiB
2026.07.0
Latest
2026-07-14 14:47:22 +00:00
Languages
C# 60.8%
TypeScript 14.3%
Python 8.5%
Shell 8.3%
Makefile 2.6%
Other 5.4%