Skip to main content

Module grow

Module grow 

Source
Expand description

Step 3: ontology growth — the MDL-style split criterion from design.py.

The seed spec (step 0) is deliberately minimal (“3-4 SEED entity facets … growth adds more later”). Growth then asks an agent for one candidate facet covering what the existing facets leave unexplained, and keeps it only if it earns its place:

  gain = coverage × (1 − maxcos)         (Collectively-Exhaustive × Mutually-Exclusive)
  keep ⟺ gain ≥ threshold

The reference measures orthogonality between trained SPLADE decoder weights, which means finetuning a head per candidate before you can score it. That is the expensive part, and it is not necessary to decide the question the gate asks: does this facet pick out corpus content the others miss? Here each facet is given a detector — its name plus the example surfaces the proposing agent supplied — and the candidate is scored on the real corpus incidence those detectors produce (crate::mece). Cheap, deterministic, and measured on the corpus as it actually is rather than on model weights.

The honest limitation of that substitution: a detector built from a handful of example surfaces under-measures a facet whose vocabulary is broad, so gain is a lower bound. A candidate that clears the threshold has definitely earned its place; one that narrowly fails might have earned it with a trained head.

Structs§

Candidate
A growth candidate — mirrors design.py::propose_candidate’s schema.
GrowEvent
One decision in the growth log — kept for the registry so a spec’s provenance is auditable.

Functions§

adopt
Add a kept candidate to the spec.
contains_word
Word-boundary containment (so org doesn’t match inside organic). Whole-word containment. A substring test would match “it” inside “submitted”, which silently corrupts both training labels and projected tokens.
gate
Apply the gate to a scored candidate: keep iff gain ≥ threshold, the candidate is wanted, its parent exists, and its name isn’t already taken.
gate_full
Full gate including the parent-duplication signal from score_candidate_full.
grow
Run the growth loop: propose → score → gate → adopt, stopping when a round keeps nothing (the reference’s “Else stop”). Returns the grown spec and the full decision log.
score_candidate
Score a candidate against the current spec on a document sample. Returns the MECE numbers for the candidate facet, or None when its detectors never fire (nothing to measure).
score_candidate_full
Score a candidate and also report parent duplication: (candidate_coverage / parent_coverage, maxcos_against_parent). A specialisation must be strictly narrower than the facet it refines — if it reproduces the parent’s coverage and its incidence, it is a rename, not a new node type.