Skip to content

fix(math): correct comment-extremity sign in pca_project_cmnts (D1b)#2615

Open
jucor wants to merge 1 commit into
spr/edge/31321c47from
spr/edge/a6494735
Open

fix(math): correct comment-extremity sign in pca_project_cmnts (D1b)#2615
jucor wants to merge 1 commit into
spr/edge/31321c47from
spr/edge/a6494735

Conversation

@jucor

@jucor jucor commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

pca_project_cmnts computed coefs = -scale * (1.0 + center), a literal,
untranslated copy of Clojure's synthetic vote value -1 (pca.clj:167-178).
Clojure stays in raw-Postgres convention (AGREE=-1) throughout, so -1 is
correct there. Delphi flips votes to its own convention at the Postgres ingress
(postgres_vote_to_delphi), fitting PCA on AGREE=+1 data, so the untranslated
-1 INVERTS comment extremity: |correct| = scale*|1-center| vs
|actual| = scale*|1+center| (equal only at center==0). A near-unanimous-AGREE
comment (center -> +1) read as maximally extreme (2*scale) instead of ~0; a
near-unanimous-DISAGREE comment (center -> -1) read as ~0 instead of maximal.

Fix: coefs = scale * (AGREE - center) (AGREE=+1, from utils.general) — the
faithful Delphi-convention port of Clojure's synthetic-AGREE projection.
Docstring rewritten to document the convention translation.

Tests (TDD, RED->GREEN):

  • Replace the tautological test_pca_project_cmnts_formula (it re-derived the
    implementation's own buggy formula) with one deriving expected values
    independently from the AGREE constant.
  • Add a behavioral sign test: unanimous-agree -> extremity 0,
    unanimous-disagree -> maximal.
  • Add an integration test spying on the extremity E reaching priority_metric
    through _compute_comment_priorities (works despite the Clojure math.repness: priority-metric meta detection treats 0 as truthy, assigning META_PRIORITY^2 to every comment #2571 mirror — it
    inspects the argument, not the return), pinned to hand-derived 0 and 2*sqrt(2).
  • Provenance comment in regression/utils.py: the regression CSVs are pre-flipped
    to Delphi convention by server/src/report.ts (~line 393, String(-row.vote)),
    so the regression path must NOT re-flip.

Output-inert today: priority_metric still returns META_PRIORITY**2 (the #2571
Clojure bug-mirror), so extremity affects no DynamoDB output yet and no golden
snapshots move. This is the extremity/PCA-parity groundwork the D12
priority_metric un-mirror is blocked on. Distinct from D1 (align_pca_signs,
temporal ±eigenvector stability).

Full delphi suite: 406 passed / 17 skipped / 47 xfailed / 0 failed.

Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

commit-id:a6494735


Stack:


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

`pca_project_cmnts` computed `coefs = -scale * (1.0 + center)`, a literal,
untranslated copy of Clojure's synthetic vote value `-1` (pca.clj:167-178).
Clojure stays in raw-Postgres convention (AGREE=-1) throughout, so `-1` is
correct there. Delphi flips votes to its own convention at the Postgres ingress
(`postgres_vote_to_delphi`), fitting PCA on AGREE=+1 data, so the untranslated
`-1` INVERTS comment extremity: `|correct| = scale*|1-center|` vs
`|actual| = scale*|1+center|` (equal only at center==0). A near-unanimous-AGREE
comment (center -> +1) read as maximally extreme (2*scale) instead of ~0; a
near-unanimous-DISAGREE comment (center -> -1) read as ~0 instead of maximal.

Fix: `coefs = scale * (AGREE - center)` (AGREE=+1, from utils.general) — the
faithful Delphi-convention port of Clojure's synthetic-AGREE projection.
Docstring rewritten to document the convention translation.

Tests (TDD, RED->GREEN):
- Replace the tautological `test_pca_project_cmnts_formula` (it re-derived the
  implementation's own buggy formula) with one deriving expected values
  independently from the AGREE constant.
- Add a behavioral sign test: unanimous-agree -> extremity 0,
  unanimous-disagree -> maximal.
- Add an integration test spying on the extremity `E` reaching `priority_metric`
  through `_compute_comment_priorities` (works despite the #2571 mirror — it
  inspects the argument, not the return), pinned to hand-derived 0 and 2*sqrt(2).
- Provenance comment in regression/utils.py: the regression CSVs are pre-flipped
  to Delphi convention by server/src/report.ts (~line 393, `String(-row.vote)`),
  so the regression path must NOT re-flip.

Output-inert today: `priority_metric` still returns META_PRIORITY**2 (the #2571
Clojure bug-mirror), so extremity affects no DynamoDB output yet and no golden
snapshots move. This is the extremity/PCA-parity groundwork the D12
`priority_metric` un-mirror is blocked on. Distinct from D1 (align_pca_signs,
temporal ±eigenvector stability).

Full delphi suite: 406 passed / 17 skipped / 47 xfailed / 0 failed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

commit-id:a6494735
@github-actions

Copy link
Copy Markdown

Delphi Coverage Report

File Stmts Miss Cover
init.py 2 0 100%
benchmarks/bench_pca.py 128 107 16%
benchmarks/bench_repness.py 81 65 20%
benchmarks/bench_update_votes.py 38 28 26%
benchmarks/benchmark_utils.py 34 24 29%
components/init.py 1 0 100%
components/config.py 165 133 19%
conversation/init.py 2 0 100%
conversation/conversation.py 1108 259 77%
conversation/manager.py 131 42 68%
database/init.py 1 0 100%
database/dynamodb.py 395 189 52%
database/postgres.py 306 206 33%
pca_kmeans_rep/init.py 5 0 100%
pca_kmeans_rep/clusters.py 257 21 92%
pca_kmeans_rep/corr.py 98 17 83%
pca_kmeans_rep/pca.py 136 18 87%
pca_kmeans_rep/repness.py 208 9 96%
regression/init.py 4 0 100%
regression/clojure_comparer.py 188 20 89%
regression/comparer.py 887 720 19%
regression/datasets.py 135 27 80%
regression/recorder.py 36 27 25%
regression/utils.py 138 94 32%
run_math_pipeline.py 261 114 56%
umap_narrative/500_generate_embedding_umap_cluster.py 210 109 48%
umap_narrative/501_calculate_comment_extremity.py 112 53 53%
umap_narrative/502_calculate_priorities.py 135 135 0%
umap_narrative/700_datamapplot_for_layer.py 502 502 0%
umap_narrative/701_static_datamapplot_for_layer.py 310 310 0%
umap_narrative/702_consensus_divisive_datamapplot.py 432 432 0%
umap_narrative/801_narrative_report_batch.py 785 785 0%
umap_narrative/802_process_batch_results.py 268 268 0%
umap_narrative/803_check_batch_status.py 183 183 0%
umap_narrative/llm_factory_constructor/init.py 2 2 0%
umap_narrative/llm_factory_constructor/model_provider.py 192 192 0%
umap_narrative/polismath_commentgraph/init.py 1 0 100%
umap_narrative/polismath_commentgraph/cli.py 270 270 0%
umap_narrative/polismath_commentgraph/core/init.py 3 3 0%
umap_narrative/polismath_commentgraph/core/clustering.py 108 108 0%
umap_narrative/polismath_commentgraph/core/embedding.py 104 104 0%
umap_narrative/polismath_commentgraph/lambda_handler.py 219 219 0%
umap_narrative/polismath_commentgraph/schemas/init.py 2 0 100%
umap_narrative/polismath_commentgraph/schemas/dynamo_models.py 160 9 94%
umap_narrative/polismath_commentgraph/tests/conftest.py 17 17 0%
umap_narrative/polismath_commentgraph/tests/test_clustering.py 74 74 0%
umap_narrative/polismath_commentgraph/tests/test_embedding.py 55 55 0%
umap_narrative/polismath_commentgraph/tests/test_storage.py 87 87 0%
umap_narrative/polismath_commentgraph/utils/init.py 3 0 100%
umap_narrative/polismath_commentgraph/utils/converter.py 283 237 16%
umap_narrative/polismath_commentgraph/utils/group_data.py 354 336 5%
umap_narrative/polismath_commentgraph/utils/storage.py 584 518 11%
umap_narrative/reset_conversation.py 159 50 69%
umap_narrative/run_pipeline.py 453 312 31%
utils/general.py 62 41 34%
Total 10874 7531 31%

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.

1 participant