Skip to content

feat(ENG-016): Kappa-style consensus over implementation directions (Phase 1) - #13

Merged
tobyvee merged 1 commit into
mainfrom
feat/eng-016-kappa-consensus
Jun 27, 2026
Merged

tobyvee merged 1 commit into
mainfrom
feat/eng-016-kappa-consensus

Conversation

@tobyvee

@tobyvee tobyvee commented Jun 27, 2026

Copy link
Copy Markdown
Owner

Closes ENG-016 (Wave 4), implementing PRD-001. (Supersedes #12, which GitHub auto-closed when the stacked base branch was deleted on #11's merge — same commit, now based on main.)

At the architecture/system-design stage the senior technical roles independently rate candidate implementation directions; a chance-corrected inter-rater agreement coefficient gates whether the aggregate winner is adopted or sent to a tie-breaker. Phase 1 ships advisory (records the round + agreement score, doesn't block) behind CONSENSUS_ENABLED.

What's added

  • core (pure, heavily unit-tested) — Krippendorff's alpha (primary; nominal/ordinal/interval, missing-data tolerant), Fleiss' kappa (single-pick), Kendall's W (ranked); all degenerate-safe (no variation / unanimity → 1, never NaN). decide() = aggregate winner (vote tally / Borda) gated on coefficient ≥ threshold with a strict no-tie check. zod schemas for candidate/rating/config/round/outcome.
  • agents — proposeDirections (2–4 distinct candidates) + rateDirections (one independent rater, structured output constrained to candidate ids — ENG-009).
  • server — durable directionConsensus workflow: generate → rate the three roles in parallel (barrier) → decide → branch. Tie-break = human escalation via the architecture_decision gate (signal + approveArchitecture + POST /api/epics/:id/approve-architecture, mirroring approveRoadmap). Budget-enforced per rater, audited, emitted to the decision log (ENG-014), traceable to the originating request. No-op when <2 viable candidates / runtime unavailable. Per-unit config (rubric/mode/threshold/tie-breaker).

Acceptance criteria — all met

core schemas ✓ · pure agreement fn (Krippendorff + Fleiss + Kendall, perfect/none/partial/degenerate) ✓ · pure decide() ✓ · independent structured raters + 2–4 candidate gen ✓ · durable parallel-rater step branching on threshold, budget-enforced + audited ✓ · architecture_decision tie-break with deciding identity ✓ · round/ratings/outcome in the decision log ✓ · config-driven + no-op path ✓ · workflow tests for consensus-reached and tie-break→gate (plus advisory + no-op) ✓

Tests

pnpm typecheck · lint · test (144) · build all green.

🤖 Generated with Claude Code

…Phase 1)

Implements PRD-001: at the architecture/system-design stage the senior
technical roles independently rate candidate directions; a chance-corrected
inter-rater agreement coefficient gates adopt-vs-tie-break. Phase 1 ships
advisory (records the round + score, doesn't block) behind CONSENSUS_ENABLED.

- core (pure, heavily tested):
  - agreement coefficients — Krippendorff's alpha (primary; nominal/ordinal/
    interval over a units×raters matrix), Fleiss' kappa (single-pick) and
    Kendall's W (ranked). Degenerate cases (no variation / unanimity) map to 1,
    never NaN.
  - `decide()` — aggregate winner (vote tally / Borda) gated on
    `coefficient ≥ threshold` with a strict no-tie check; the coefficient is a
    confidence signal feeding the rule, not a hard inference (PRD caveat).
  - zod schemas: ConsensusCandidate/Rating/ConsensusConfig/Round/Outcome.
- agents: `proposeDirections` (2–4 distinct candidates) + `rateDirections`
  (one rater, independent, structured output constrained to candidate ids).
- server: durable `directionConsensus` workflow — generate → rate the roles
  **in parallel (barrier)** → decide → branch; tie-break = human escalation via
  the `architecture_decision` gate (signal + client fn + API endpoint mirroring
  approveRoadmap). Budget-enforced per rater, audited, and emitted to the
  decision log (ENG-014). No-op when <2 viable candidates or runtime/budget
  unavailable. Config-driven (rubric/mode/threshold/tie-breaker), per unit.

Tests: agreement fixtures (perfect/none/negative/partial/degenerate) for all
three coefficients; decide() pick + ranked paths; rater output parsing; and
workflow-branch tests (consensus-reached · tie-break→gate · advisory · no-op)
via the time-skipping harness. typecheck/lint/test (144)/build all green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@tobyvee
tobyvee merged commit 65d3b23 into main Jun 27, 2026
1 check passed
@tobyvee
tobyvee deleted the feat/eng-016-kappa-consensus branch June 27, 2026 07:38
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