Clojure math.repness: priority-metric meta detection treats 0 as truthy, assigning META_PRIORITY^2 to every comment
Summary
priority-metric in math/src/polismath/math/conversation.clj is intended to
distinguish "meta" comments (which get a constant high priority,
META_PRIORITY^2 = 49) from regular comments (which get
(importance * decay-factor)^2). Due to a Clojure truthiness quirk, the meta
branch fires for every comment, so every tid ends up with priority 49.0.
The math pipeline still runs, but comment-priorities is effectively constant
across all comments, defeating the priority-weighted sampler that picks
which comments to surface to participants.
Affected code
math/src/polismath/math/conversation.clj:321-330 (approx.):
(defn priority-metric
[is-meta A P S E]
(matrix/pow
(if is-meta
meta-priority
(* (importance-metric A P S E)
(+ 1 (* 8 (matrix/pow 2 (/ S -5))))))
2))
And the caller, around conversation.clj:325, which produces is-meta:
(get meta-tids tid 0) ; or similar — returns 0 when tid is not in meta-tids
Mechanism
meta-tids is a set (or map) of meta tids.
(get meta-tids tid 0) returns 0 for tids not in meta-tids (the default).
- In Clojure, only
nil and false are falsy — 0 is truthy.
- So
(if is-meta meta-priority ...) selects the meta-priority branch
regardless of whether the tid is actually meta.
- Result: every comment's priority is
META_PRIORITY^2 = 49.0.
Empirical evidence
Prodclone check on two conversations (2026-06-11):
| Conversation |
Meta tids |
Non-meta tids |
Distinct priorities in blob |
vw |
0 |
all |
1 (all 49.0) |
biodiversity |
15 |
301 |
1 (all 49.0) |
If the meta detection worked, we'd expect vw to have zero 49.0 priorities
(no meta tids exist) and varied non-meta values. Instead every tid is 49.0,
confirming the meta branch fires unconditionally.
Suggested fix
Use a predicate that distinguishes "absent" from "present-but-zero":
;; Option A — set membership
(contains? meta-tids tid)
;; Option B — explicit nil check (if meta-tids is a map)
(some? (get meta-tids tid))
;; Option C — explicit boolean coercion
(boolean (get meta-tids tid))
Any of these returns false (not 0) when the tid is absent, so the
(if is-meta ...) form will correctly take the non-meta branch.
Downstream impact
- Python port (
delphi/polismath/conversation/conversation.py,
priority_metric) currently mirrors this bug for byte-for-byte parity with
the Clojure golden snapshots. Once this Clojure bug is fixed, we will
restore the semantically-correct Python implementation (the original logic
is preserved as a commented block in the port; see TODO comment referencing
this issue).
- Re-recording Python regression snapshots after the Clojure fix will be
required.
- Any downstream consumer that relies on comment-priority ranking
(e.g. probabilistic samplers in the participation flow) is currently
operating on a constant distribution.
References
- Clojure source:
math/src/polismath/math/conversation.clj (priority-metric, ~line 321)
- Python parity bug mirror:
delphi/polismath/conversation/conversation.py::priority_metric
- D12.6 decisions log in
delphi/docs/CLJ-PARITY-FIXES-JOURNAL.md (2026-06-11)
Clojure math.repness: priority-metric meta detection treats 0 as truthy, assigning META_PRIORITY^2 to every comment
Summary
priority-metricinmath/src/polismath/math/conversation.cljis intended todistinguish "meta" comments (which get a constant high priority,
META_PRIORITY^2 = 49) from regular comments (which get(importance * decay-factor)^2). Due to a Clojure truthiness quirk, the metabranch fires for every comment, so every tid ends up with priority
49.0.The math pipeline still runs, but
comment-prioritiesis effectively constantacross all comments, defeating the priority-weighted sampler that picks
which comments to surface to participants.
Affected code
math/src/polismath/math/conversation.clj:321-330(approx.):And the caller, around
conversation.clj:325, which producesis-meta:Mechanism
meta-tidsis a set (or map) of meta tids.(get meta-tids tid 0)returns0for tids not inmeta-tids(the default).nilandfalseare falsy —0is truthy.(if is-meta meta-priority ...)selects themeta-prioritybranchregardless of whether the tid is actually meta.
META_PRIORITY^2 = 49.0.Empirical evidence
Prodclone check on two conversations (2026-06-11):
vw49.0)biodiversity49.0)If the meta detection worked, we'd expect
vwto have zero49.0priorities(no meta tids exist) and varied non-meta values. Instead every tid is
49.0,confirming the meta branch fires unconditionally.
Suggested fix
Use a predicate that distinguishes "absent" from "present-but-zero":
Any of these returns
false(not0) when the tid is absent, so the(if is-meta ...)form will correctly take the non-meta branch.Downstream impact
delphi/polismath/conversation/conversation.py,priority_metric) currently mirrors this bug for byte-for-byte parity withthe Clojure golden snapshots. Once this Clojure bug is fixed, we will
restore the semantically-correct Python implementation (the original logic
is preserved as a commented block in the port; see TODO comment referencing
this issue).
required.
(e.g. probabilistic samplers in the participation flow) is currently
operating on a constant distribution.
References
math/src/polismath/math/conversation.clj(priority-metric, ~line 321)delphi/polismath/conversation/conversation.py::priority_metricdelphi/docs/CLJ-PARITY-FIXES-JOURNAL.md(2026-06-11)