cadrumo.core.text_bounds module¶
The bounded scalar shapes that recur across every layer, stated once.
Most of this campaign’s aliases name a DOMAIN concept – a filing year, a share
of one, a country code – and carry its bound as a consequence. These are
different: they name a SHAPE. NonEmptyStr says only that a string carries
something, and PositiveCount only that a count is at least one.
That is a weaker kind of canonicality and worth being honest about. The value
is not that the name teaches a reader something new; it is that the shape is
written down once instead of a hundred and eight times, so a payload cannot
quietly disagree with the model it projects about whether empty is allowed.
Where a real domain concept exists, its own alias is the better home and these
should not be reached for – an evidence reference is
EvidenceReference, not a bounded string that happens to be non-empty.
PositiveCount exists because pydantic’s PositiveInt is not a drop-in
substitute at these sites. It is Gt(0) where these are Ge(1); for an
integer those admit the same values, but they serialise to different JSON
schemas – exclusiveMinimum: 0 against minimum: 1 – and these bounds
sit on a published envelope contract. NonNegativeInt has no such problem
and is used directly; only the positive case needs a local name.
- is_calendar_month(value)[source]¶
Whether
valuenames a month, inclusive at both ends.For the callers that cannot use the annotation because they must raise their OWN refusal: the profile answer reader raises a
ProfileAnswerTypeErrornaming the answer key, the descendant record aProfileValidationError, the setup wizard returns a failed verdict carrying a locale key, and the CLI payload a plainValueErrorpydantic wraps. Those differ on purpose – the operator’s first instructive surface should name the field they typed into – so what is shared is the question, not the answer.The bound was open-coded as
1 <= month <= 12at five sites, twice within a single module for the SAME field, which is how a bound stops being one rule and becomes five that happen to agree.
- is_canonical_month_set(months)[source]¶
Whether
monthsis a canonical set: real months, no repeat, ascending.The three rules travel together and were written out twice – once on the descendant record and once on the wire payload that projects it. Only the first of the three delegated; uniqueness and ordering were restated.
Ascending order is ENFORCED rather than applied, so a record has exactly one representation of a given set and a save-then-reload cannot reorder it. A repeat is refused rather than collapsed, because a month either qualified or it did not and silently dropping the second mention would hide a transcription slip while changing nothing the operator can see.
A predicate rather than a validator because the two callers raise different errors on purpose – the record a
ProfileValidationErrornaming the repeated months, the payload a plainValueErrorpydantic wraps – and the detail each builds is a message, not a rule.