Serve >=51% likely-resolve questions in the WTC feed - #443
Merged
Conversation
Serves likely-resolve printing questions (one agreeing human vote away from resolving under the real resolver) at >=51% of the WTC feed when supply exists, falling back to the existing ranked union otherwise; logs served-mix composition per the data brief's soundness note. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Renumbers the served-log migration to 0080 with a dependency on 0079_envelopetrip (landed on master after this branch's base, PR #440) to resolve the migration-graph conflict; retargets the mix-composition policy's soundness citation from an ephemeral session-transcript path to docs/theory.md's now-landed §10, and folds the mix-log's existence back into that section per its own invitation. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Implements the owner-ratified question-feed serving policy from the
2026-07-24 WTC vote-queue data brief: the served question mix now
prioritizes likely-resolve 1-click printing questions at ≥51% of served
questions when supply exists, falling back to the pre-existing
three-tier ranked union otherwise. This is a selection-layer change
only — zero changes to
vote_consensus.py's weights, thresholds, orgates (D1/D4 mechanisms untouched);
is_likely_resolve_printingcallsthe real
resolve_weighted_consensus, it never reimplements itsarithmetic.
is_likely_resolve_printing):for a card's current highest-weighted printing outcome group, adds
one hypothetical
VoteSource.USER-weight vote and re-runs the realresolver to check whether that group now wins — the brief's own
exact-code simulation approach (the same method that produced its
46,310-card LIKELY-RESOLVE SUPPLY figure). Compute-per-serve, no
caching layer — see
_likely_resolve_printing_card's docstring forthe cost/approach tradeoff this accepts.
get_next_question_feed_itemserves from thelikely-resolve pool whenever this session's served-mix ratio is
below
settings.QUESTION_FEED_LIKELY_RESOLVE_MIX_RATIO(default0.51) and the pool has supply for this voter; otherwise falls
through to the existing tier 1 → tier 2 → tier 4 ranked union
unchanged, with one addition inside tier 4: cards whose latest Stage
D scan-log origin is a "quick-negative" reason
(
unknown-set-code/eliminated/border-mismatch/frame-mismatch)are now prioritized over the harder/open-ended remainder (secondary
tiebreak, after the pre-existing
-vote_countordering, never aheadof it). Per-voter exclusion and existing tier semantics preserved.
new
QuestionFeedServedLogmodel (anonymous_id,pool,question_type,origin_reason,served_at) — thebias-conditioning record the data brief's SOUNDNESS NOTE calls for,
so a future audit can correlate click behavior against a session's
easy-question exposure. Migration
0079_questionfeedservedlog.py(hand-written and verified via
manage.py makemigrations --checkagainst a local venv — no live DB/container was touched to produce
it).
docs/features/printing-tags.md's "Unified question feed"section updated in place with the new "Mix-composition policy"
bullet (soundness citation, mix-log description, quick-negative
ordering rationale).
Checklist
pre-commitand installed the hooks withpre-commit installbefore creating any commits.pytest .against afresh testcontainers Postgres/ES, via a local venv — no live
production DB/containers touched): 1931 passed, 4 skipped
(skips are the pre-existing named ones), 0 failed.
cardpicker/tests/test_question_feed.pyalone: 40 passed (25pre-existing + 15 new), including likely-resolve classification
round-tripped against the real resolver (1-away resolves,
2-away doesn't), mix-ratio gating (below/at target), graceful
degradation with no likely-resolve supply (no hang/exception,
ratio drops honestly), per-voter exclusion on the new pool, the
served-mix log rows, and the quick-negative tier-4 reordering
(including the deliberate "ambiguous" exclusion).
manage.py makemigrations cardpicker --check --dry-runreports"No changes detected" against the new model — the hand-written
migration is verified to exactly match
models.py.pre-commit run(ruff/isort/black/mypy/prettier) clean on allchanged files.
Deviations from spec
"near-threshold multi-candidate" slice of the brief's remainder
ranking is naturally covered by the same
is_likely_resolve_printingclassification (it doesn't distinguish single- vs multi-candidate —
both are just "current leading group, one vote away"), so it lives in
the likely-resolve pool rather than as a separate remainder tier; the
remaining two remainder slices (quick-negative to-review, then
hard/open-ended) are implemented as described inside tier 4.
Open items
makemigrations --check) rather than generated viamanage.py makemigrationsagainst the live
mpcautofill_djangocontainer, since running thatcommand against the live container was blocked by this session's
own tooling guardrail. Verified exact-match against the model state;
flagging so a reviewer can independently confirm before merge.
deploy-freeze-activelabel check was empty) — this PR includes a migration, so please
check freeze status again before merging/deploying if time has
passed.