Files
sortof/docs/backlog/polling-path-pz-build.md

3.3 KiB

Backlog: polling-path pz_build plumbing

Status: parked. File a Gitea issue with this content when one comes up. Trigger to schedule: a B41 user submits a collection URL or bare-uncached input AND complains about getting B42-flavored auto-picks (or audits the result and notices Rule A misfired).

What's missing

/api/sort's sync path passes req.pz_build into adapters.build_response correctly. The async path (_route_to_jobexpansion.run_expansion_build_result_for_job) does not persist pz_build and defaults to "B42" when the GET endpoint builds the final result.

A B41 user submitting a collection URL gets:

  • Sync part of /api/sort (validation, classify) sees pz_build=B41.
  • Job created, expansion runs.
  • GET /api/jobs/{id} builds result_json via _build_result_for_job(conn, wsids, rules_raw)adapters.build_response(...) → defaults pz_build="B42" → Rule A picks B42-flavored branches.

For the canonical fhqMotoriusZone/SZ-class fixtures this doesn't matter (those are coordinated, exempt from Rule A). The bug bites on truly-ambiguous multi-branch wsids like zReApoModernArmor (2 branches: unflavored + B42-flavored) when B41 user routes through cold drain.

Migration sketch

Add a column to sort_jobs:

-- /opt/sortof/init/02_sort_jobs.sql (re-run on idempotent CREATE; live DB needs ALTER)
ALTER TABLE sort_jobs ADD COLUMN IF NOT EXISTS pz_build TEXT;

Apply via:

sudo docker exec -i sortof_db psql -U sortof -d sortof -c \
  "ALTER TABLE sort_jobs ADD COLUMN IF NOT EXISTS pz_build TEXT;"

Edit init/02_sort_jobs.sql to include the column in the CREATE TABLE IF NOT EXISTS block so fresh deploys get it.

Plumbing checklist

  1. /opt/sortof/api/jobs.pycreate_job(...) gains pz_build: Optional[str] = None; INSERT writes the column. get_job_row returns it (no code change needed if SELECT *).
  2. /opt/sortof/api/app.py_route_to_job(...) gains pz_build: Optional[str] = None; passes to jobs.create_job. Both call sites in sort_endpoint (collection short-circuit and bare-uncached fork) pass req.pz_build.
  3. /opt/sortof/api/app.py_build_result_for_job(conn, wsids, rules_raw) signature gains pz_build: Optional[str] = None. The GET handler reads row["pz_build"] and passes it through. adapters.build_response(... pz_build=...) already accepts it.
  4. No frontend changepzBuild is already in /api/sort POST body.

Acceptance criteria

  • B41 user submits collection URL containing zReApoModernArmor (3483407987) — final result_json.MODS_LINE includes zReApoModernArmor (un-flavored), not zReApoModernArmorB42.
  • WARNINGS includes build-mismatch if appropriate.
  • B42 user behavior unchanged (default).
  • Existing sort_jobs rows with NULL pz_build continue to work (NULL → fall back to "B42" in the build_response default).

Why parked

  • No telemetry showing cold-collection B41 traffic exists.
  • DB migrations against synthetic demand bitrot between writing and shipping (function signatures drift, the DDL goes stale).
  • Sync-path B41 users (the dominant case in this user base) work correctly today — Rule A fires off req.pz_build directly.
  • Schedule when a real user hits it. The migration is small and self-contained.