Put the grouping dials where the regrouping is
The merge probability was `dr_face`'s constant and the smallest group was a bare `< 2` in the clustering pass. Both were tuned on one library — 1,813 faces of one photographer's family — and the quantity they optimise is a property of the population, not of the model. A household at close family resemblance and two thousand strangers at a wedding want different answers, and neither of them is the reference library. The doc comment already conceded the point and pointed at `face_index --tune`; a photographer does not have a terminal. So they are `FaceSettings` now, saved per device beside the cache budgets and edited from the People screen — beside the Regroup button that applies them and the rail that shows what they did, because a value changed three screens away from its effect is one nobody can tune. Moving them is safe by construction, which is why nothing asks for confirmation: a regroup writes only the suggested half, and confirmations, names and ignores enter as anchors and come back unchanged. The smallest-group rule is applied only to groups the system invented — a group the user named or set aside survives it whatever its size, because a display preference does not overrule a judgement. **Withdrawal, without which the setting does nothing visible.** Raising the smallest group stops the pass creating small groups; it does not remove the ones a previous pass made, because those still hold their suggestions, so they are not empty, so the prune leaves them. The pass now releases every unanchored face it did not place before pruning. And a dial you cannot see the effect of is not a dial. "What would this do?" runs the same population through the clusterer without opening a transaction and reports groups, faces grouped and largest group — one row of `--tune`'s table, on the user's own library, on a worker thread. The line leads with the group count because that is the number that says which side of the right setting you are on: it climbs as fragments are gathered into people and falls as separate people start being welded, while the grouped-face count rises straight through both. The preview parks its poll timer in a slot of its own. A preview and a regroup are allowed to be in flight together, and sharing the sweep's single slot would have the second to start drop the first's timer — visible as a Regroup that finished on its worker and never said so. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -788,6 +788,40 @@ It is **not** a merge threshold and must not become one. Uniqueness is relative,
|
||||
one named person would hand every stray face a 1. "Is this the same person at all" stays §8's
|
||||
question, and coherence is the half of the product that carries it.
|
||||
|
||||
### 9.2 The two numbers the user is allowed to move · 2026-08-29
|
||||
|
||||
The merge probability and the smallest group the pass will call a person are `FaceSettings` in
|
||||
`dr-types`, edited from the People screen and saved per device beside the cache budgets. They were
|
||||
constants: `dr_face::DEFAULT_MERGE_PROBABILITY` and a bare `< 2` in `dr_ui::faces::recluster`.
|
||||
|
||||
**Why they had to become settings.** The default was tuned on one library — the table in
|
||||
`dr_face::cluster`'s doc comment is 1,813 faces of one photographer's family — and the quantity it
|
||||
optimises is a property of the population, not of the model. A library of one household at close
|
||||
family resemblance and a library of two thousand strangers at a wedding want different answers, and
|
||||
neither of them is the reference library. The doc comment already conceded the point ("this is a
|
||||
*default*, not a constant of nature") and pointed at `face_index --tune` as the way to find a better
|
||||
one; a photographer does not have a terminal.
|
||||
|
||||
**Why moving them is safe, and why that is the reason there is no confirmation on it.** A regroup
|
||||
writes only the *suggested* half. Confirmations, names and ignores enter as anchors and come back
|
||||
unchanged (FR-CULL-10), so the pass is re-runnable by construction and a dial the user can move is
|
||||
just that property being used. The smallest-group rule is applied only to groups the system invented:
|
||||
a group carrying a person — confirmed, named or set aside — survives it whatever its size, because a
|
||||
display preference does not overrule a judgement (FR-CULL-12).
|
||||
|
||||
**Withdrawal, which the setting does not work without.** Raising the smallest group stops the pass
|
||||
*creating* small groups; it does not by itself remove the ones a previous pass made, because those
|
||||
still hold their suggestions, so they are not empty, so `prune_empty_unnamed` leaves them. The pass
|
||||
therefore now releases every unanchored face it did not place — `faces::unassign` — before pruning.
|
||||
Without that step the control appears to do nothing until the library is reindexed.
|
||||
|
||||
**The preview.** `dr_ui::faces::preview_grouping` runs the same population through
|
||||
`dr_face::cluster` and reports groups, faces grouped and largest group without opening a
|
||||
transaction. It is `face_index --tune`'s row for one setting, on the user's own library, on a worker
|
||||
thread. The line leads with the **group count** because that is the number that says which side of
|
||||
the right setting you are on: it climbs as fragments are gathered into people and falls as separate
|
||||
people start being welded together, while the grouped-face count rises straight through both.
|
||||
|
||||
---
|
||||
|
||||
## 10. Catalog and jobs
|
||||
|
||||
Reference in New Issue
Block a user