Skip to content

python-math #14: feat(math): degenerate-tick group-clusterings overwrite + <2-participants edge (legacy mode) - #2642

Draft
jucor wants to merge 1 commit into
spr/edge/bc0518d7from
spr/edge/bbb74f71
Draft

python-math #14: feat(math): degenerate-tick group-clusterings overwrite + <2-participants edge (legacy mode)#2642
jucor wants to merge 1 commit into
spr/edge/bc0518d7from
spr/edge/bbb74f71

Conversation

@jucor

@jucor jucor commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

What

Ports the approved 2026-07-21 Opus review verdict covering quirks Q4 and Q5 from delphi/docs/CLOJURE_QUIRKS.md into clojure-legacy mode (the engine setting that reproduces the old Clojure engine's behavior exactly):

  • Quirk Q4 (degenerate ticks still cluster): Clojure recomputes :group-clusterings EVERY tick unconditionally — max-k-fn is always >= 2 (conversation.clj:274-279) — so a tick with only 1 base cluster still runs k=2 kmeans on a single point. The clean-start initialization caps k at the number of distinct points, yielding 1 cluster carrying a lineage id; that degenerate value OVERWRITES :group-clusterings; and the recovery tick warm-starts from it, minting split ids via (inc max-id) (clusters.clj:267).
  • Quirk Q5 (<2-participants edge): Clojure also has no guard for fewer than 2 in-conv participants (the set of participants admitted to clustering) beyond the truly-empty short-circuit — a 1-participant tick runs the full pipeline.

How it works

clojure-legacy mode now skips both early returns and falls through to the normal legacy path, which reproduces all of the above exactly: the max_k arithmetic yields the k range [2]; calculate_silhouette_sklearn returns the 0.0 sentinel for singleton clusterings, matching Clojure's singleton rule (clusters.clj:350-353); and the advance of the group-k smoother (ported earlier in this stack as PR P6a) is preserved with the same {2: 0.0} input via the main path — the branch-local P6a advance block is removed as dead code. The 0-participant early return stays in both modes: it is unreachable past the empty short-circuit given the greedy in-conv floor from PR-E (#2623). improved mode (the engine setting that keeps Python's corrected behavior) keeps both guards byte-for-byte.

Testing

TDD: tests/test_degenerate_tick_parity.py was RED on the old code for the pinned divergences (stale 2-cluster group_clusterings after a collapse tick; empty structures on a single-participant tick), GREEN after. Existing P6a smoother tests are unchanged and green (24 passed with test_group_k_smoother.py; 37 passed with the lineage / greedy-carry / pca-warm-start / engine-mode neighbor suites).

commit-id:bbb74f71


Stack:


⚠️ Part of a stack created by spr. Do not merge manually using the UI - doing so may have unexpected results.

This was referenced Jul 22, 2026
@jucor
jucor marked this pull request as draft July 22, 2026 00:51
@jucor jucor changed the title feat(math): degenerate-tick group-clusterings overwrite + <2-participants edge (legacy mode) feat(math): degenerate-tick group-clusterings overwrite + <2-particip… Jul 22, 2026
@jucor
jucor changed the base branch from spr/edge/bc0518d7 to edge July 22, 2026 02:01
@jucor jucor changed the title feat(math): degenerate-tick group-clusterings overwrite + <2-particip… feat(math): degenerate-tick group-clusterings overwrite + <2-participants edge (legacy mode) Jul 22, 2026
@jucor
jucor changed the base branch from edge to spr/edge/bc0518d7 July 22, 2026 02:02
@jucor jucor changed the title feat(math): degenerate-tick group-clusterings overwrite + <2-participants edge (legacy mode) feat(math): degenerate-tick group-clusterings overwrite + <2-particip… Jul 22, 2026
@jucor
jucor changed the base branch from spr/edge/bc0518d7 to edge July 22, 2026 02:10
@jucor jucor changed the title feat(math): degenerate-tick group-clusterings overwrite + <2-particip… feat(math): degenerate-tick group-clusterings overwrite + <2-participants edge (legacy mode) Jul 22, 2026
This was referenced Jul 25, 2026
@jucor
jucor force-pushed the spr/edge/bbb74f71 branch from 4bc5e04 to 187c549 Compare July 28, 2026 00:12
@jucor
jucor force-pushed the spr/edge/bc0518d7 branch from 1d21d27 to 0088d79 Compare July 28, 2026 00:12
@jucor jucor changed the title feat(math): degenerate-tick group-clusterings overwrite + <2-participants edge (legacy mode) python-math #14: feat(math): degenerate-tick group-clusterings overwrite + <2-participants edge (legacy mode) Jul 28, 2026
…ite + <2-participants edge (legacy mode)

## What

Ports the approved 2026-07-21 Opus review verdict covering quirks Q4 and Q5 from `delphi/docs/CLOJURE_QUIRKS.md` into clojure-legacy mode (the engine setting that reproduces the old Clojure engine's behavior exactly):

- Quirk Q4 (degenerate ticks still cluster): Clojure recomputes `:group-clusterings` EVERY tick unconditionally — `max-k-fn` is always >= 2 (conversation.clj:274-279) — so a tick with only 1 base cluster still runs k=2 kmeans on a single point. The clean-start initialization caps k at the number of distinct points, yielding 1 cluster carrying a lineage id; that degenerate value OVERWRITES `:group-clusterings`; and the recovery tick warm-starts from it, minting split ids via `(inc max-id)` (clusters.clj:267).
- Quirk Q5 (<2-participants edge): Clojure also has no guard for fewer than 2 in-conv participants (the set of participants admitted to clustering) beyond the truly-empty short-circuit — a 1-participant tick runs the full pipeline.

## How it works

clojure-legacy mode now skips both early returns and falls through to the normal legacy path, which reproduces all of the above exactly: the max_k arithmetic yields the k range [2]; `calculate_silhouette_sklearn` returns the 0.0 sentinel for singleton clusterings, matching Clojure's singleton rule (clusters.clj:350-353); and the advance of the group-k smoother (ported earlier in this stack as PR P6a) is preserved with the same `{2: 0.0}` input via the main path — the branch-local P6a advance block is removed as dead code. The 0-participant early return stays in both modes: it is unreachable past the empty short-circuit given the greedy in-conv floor from PR-E (#2623). improved mode (the engine setting that keeps Python's corrected behavior) keeps both guards byte-for-byte.

## Testing

TDD: `tests/test_degenerate_tick_parity.py` was RED on the old code for the pinned divergences (stale 2-cluster group_clusterings after a collapse tick; empty structures on a single-participant tick), GREEN after. Existing P6a smoother tests are unchanged and green (24 passed with `test_group_k_smoother.py`; 37 passed with the lineage / greedy-carry / pca-warm-start / engine-mode neighbor suites).

commit-id:bbb74f71
@jucor
jucor force-pushed the spr/edge/bbb74f71 branch from 187c549 to 736211a Compare July 28, 2026 01:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants