Documents / Issues / issue-5d6a5e854d11
`scope-creep` uses one character threshold for every type, so a register is always too long
A glossary, a rule register and a probe log are long by definition; the check has no way to know that and advises splitting them.
Class: unstated · Severity: material
Flow: arch-0a3c2d6d54a6 (maintenance) · Step: docir lint --deep
Frequency: every run against a corpus containing a reference document
Finding¶
scope-creep compares a body's character count against a single constant, regardless of
the document's type. Nothing in the schema can raise or waive it, and nothing states what
the threshold is.
What happens today¶
OBSERVED. Of the 7 scope-creep findings on docir's own store, 5 are documents whose
length is the point: the two architecture documents (19 144 and 28 427 chars), the business
rule register (36 823), the glossary (8 100) and the discovery probe log (28 546). A
glossary split in half is two glossaries; a rule register split in half is a register that
no longer answers "what are the rules".
Impact¶
Advisory rather than blocking, so the cost is noise rather than a broken build — but it is
noise that arrives on every run and cannot be silenced, and it lands hardest on exactly the
document types added to hold long reference material. Together with issue-08437ba704ff it means all 21
findings lint --deep produces against the product's own corpus are unactionable.
The parallel is orphan under --strict (issue-9cb85759076d): a warning that fires on the default
state of correct usage. That was fixed by giving findings a severity so the gate could
ignore the noisy kind. Here the equivalent knob does not exist — the threshold is neither
per-type nor configurable nor documented.
Proposed default¶
Make the threshold a per-type schema key (max_body_chars, alongside review_days), with
the current constant as the default and no limit when a type sets it to 0. The bundled
reference type would set 0: a register is a register. State the default in
docir lint --help, which currently describes the check without naming a number.
Actors affected¶
- repository maintainer
Evidence¶
src/docir/modules/documents/application/services/maintenance_service.py(the scope-creep threshold constant).docir/docs-schema.yaml(thereferencetype, added 2026-07-30)- PROBE-L2 in the 2026-07-30 probe log
Resolution¶
FIXED 2026-07-30. max_body_chars is now a per-type schema key, wired exactly the way review_days is: parsed and type-checked by the loader, carried on TypeSchema, reported by docir schema show, and documented in the generated docs-schema.yaml template. Absent inherits the linter's default (8000); 0 means never. This store's reference type sets 0, because a glossary or a rule register split in half is two half-registers. lint --deep over docir's own corpus is now 4 findings, down from 21 — the 14 duplicates went with issue-08437ba704ff and the 5 registers with this. The 4 that remain are long documents where 'consider splitting' is at least arguable, which is what an advisory check should produce. find_scope_creep takes the schema optionally, for the same reason find_duplicates takes linked pairs optionally: a pure domain service should stay usable by a caller that has no schema to offer. Verified by injecting the bug twice — drop the per-type lookup, and drop the loader's parsing — and five guards fail across the two. The loader has its own test that 0 and absent stay distinguishable, since collapsing them would silently re-enable the check on exactly the type that opted out.