Skip to content

[judge panel] Pin the lens-assigned role into the lens-verdict spawn so writeLensVerdict's role matches the lens→role binding #450

Description

@jackmcintyre

Summary

A lens judge wrote role planner into judge-structure.json while the judge panel had spawned role architect for the structure lens. The judge spawn does not pin the lens-assigned role strongly enough into writeLensVerdict's role field, so the judge self-identified as its hired persona instead of the lens binding. This triggered a missing-cited-source friction event and risks a hard LensVerdictFileMalformedError.

Tool area

judge-panel lens-verdict spawn seamresolveLensRoles / buildPersonaSpawnPrompt / writeLensVerdict (the role contract between the panel and the per-lens judge)

What happens

  1. resolveLensRoles binds each of the five lenses to a distinct hired role via bipartite matching (e.g. structure → architect).
  2. The panel spawns one judge per lens, passing the lens + the bound role into the spawn prompt (buildPersonaSpawnPrompt).
  3. The judge writes its verdict with writeLensVerdict({ lens, role, pass, missed }).
  4. The bug: the bound role is not pinned strongly enough. The judge echoes its hired persona name (planner) into the role field instead of the lens-bound role (architect).
  5. The on-disk verdict file (judge-structure.json) now disagrees with the panel's lens→role binding. Downstream, aggregateJudgePanel either mis-binds the verdict or throws LensVerdictFileMalformedError (lens/role mismatch).

Observed symptom

  • A missing-cited-source friction event fired (the generic compensating signal), masking the real cause (a role-identity drift, not a missing source).
  • One step away from a hard LensVerdictFileMalformedError that would have stalled the panel.

Why this is fragile

  • The seam relies on the judge inferring and echoing the correct role from prose in its spawn prompt. With multiple hired personas and overlapping domains, that inference is unreliable.
  • The failure currently surfaces as a generic friction kind (missing-cited-source), which makes the seam hard to diagnose — the symptom (friction) does not point at the cause (role pinning).

Impact

  • Risks stalling the gate-1 judge panel mid-grade (hard error) on otherwise-correct verdicts.
  • Pollutes the friction telemetry with mis-categorised events, hiding the real seam.

Suggested direction

  1. Pin the role (preferred): Enforce the lens-assigned role in the judge spawn prompt so writeLensVerdict's role field always matches the panel's lens→role binding. Pass the bound role as an explicit required field the judge must echo verbatim (not infer from persona identity).
  2. Make mismatches diagnosable: At minimum, surface a role mismatch as a distinct friction kind (e.g. lens-role-mismatch) rather than the generic missing-cited-source, so the seam is visible in telemetry and the retro.

The property we want: the role recorded in judge-<lens>.json is always the lens-bound role, by construction — never the judge's self-identified persona.

Context

  • Trigger: retro-analyst / cycle-end retro
  • Raised: 2026-06-28 (finding id 01KW605XA3M8AAACQGJV5NATNC)
  • Observed at: Epic 1 cycle-end retro (structure lens, architect vs planner)

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions