Skip to main content

Worked example — deemed consent

A minor contract change where silence may bind, provided the subject gets an adequate window to object and the § 308 Nr. 5 lit. b warning.

The period is measured to the objection deadline​

The statutory period is measured to the objection deadline, not to the effective date — the subject must have the full period to actually object — and it is never waived, not even for an immediate change. So the deadline must be at least deemed_consent_min_days after the announcement, and the change takes effect after it. An announcement on a day already past counts as today, because no notice goes out before the version is published:

php artisan legal-consent:publish terms de --deemed --regime=bgb_agb --offers-termination \
--announce-at=2026-07-01 --objection-at=2026-08-30 --enforce-at=2026-09-01

The dates above are illustrative — pick your own future dates.

What happens​

legal-consent:dispatch-notices sends a DeemedConsentNotice carrying the warning and the free-termination right.

A subject who does nothing is bound: once the objection deadline passes, legal-consent:close-objection-windows (hourly, auto-scheduled) records a DeemedAccepted row — silence, made provable.

A subject who objects or terminates in time is recorded instead, and the fiction never applies to them.

Silence binds only against a delivered notice​

§ 308 Nr. 5 lit. b BGB makes the special warning — that not objecting counts as agreement — a validity condition of the fiction, not courtesy copy. Without it, silence does not bind at all.

So legal-consent:close-objection-windows deems nobody it cannot show a delivered notice for: a legal_notices row for that subject and version whose mandatory_content_ok is true, delivered with the objection period still ahead of them. A subject with no such row is skipped, counted, and reported — the command exits non-zero and names how many, because a silent skip here is indistinguishable from "nobody was owed anything", and the difference is whether a population is bound to a changed contract.

The warning belongs at the start of the period to object (lit. b), and the period has to be a reasonable one (lit. a). Publishing checks that period from the announcement; a subject whose notice arrived later, behind a queue backlog or a retry, has less of it. So the period is measured again for each subject, from the day their notice was delivered: at least the days the version was published with (deemed_consent_min_days, a regime's period, or the document's min_lead_days), counted from the start of that day, and for a regime the law counts in months, those months on the calendar. A notice delivered after the deadline leaves no period at all. Those subjects are reported apart, and legal-consent:dispatch-notices sends no deemed-consent notice at all once the deadline has passed. Sending the notice again cannot bind them; they need a new version with a new objection deadline.

A version published before migration 000038 did not store its period. It is measured against the configured period, but never against more than the window the version itself left from its announcement to the deadline.

This makes durable_medium.proof a prerequisite of deemed consent rather than an option. With it off, no proof row is ever written, so the sweep refuses to close any window instead of deeming an entire population against no evidence. legal-consent:doctor reports the same contradiction, so you find it before a window closes rather than from a ledger that stays empty.