Completes the re-source (ADR-0030): the Event Subscriber's abonnement moves from `zaken` to
`objecten`, in both the local stack's `nrc-subscribe` and the CI projection check. The
OpenZaak → NRC check keeps its own `zaken` abonnement — OpenZaak still publishes, nothing
in the product listens.
- register-abonnement.py subscribes to `objecten`, and now treats the kanaal as part of
"already current" — an abonnement left from before this slice points at the right callback
but the wrong kanaal, and would never have been replaced on IP alone.
- run-projection-check.sh opens its zaak *through the ACL* instead of straight against
OpenZaak, because the ACL is what writes the register record the projection is now derived
from. A zaak created behind the ACL's back produces no row — which is the re-source working.
- The acceptance scenario is restated in register terms and gains the approval case: the same
row moving INGEDIEND → INGESCHREVEN is now one registration's record being updated, not two
unrelated ZGW events.
Add projection-db + the two services to both compose files (host ports 8110/8120), their
Dockerfiles (repo-root context — they share Projection.ReadModel), and a runner-safe
verify-projection check (infra/run-projection-check.sh) that registers the abonnement at the
real subscriber, creates a zaak and asserts projection-api serves an INGEDIEND row. Wire it
into make (verify-projection, verify, WAIT_SVCS) and the CI verify-stack job, and run the
event-subscriber Stryker ratchet in `make mutation` + upload its report.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>