---
title: lfcs-pricing — Blind Comparison Workflow (extracted from CLAUDE.md §4.5)
type: workflow-detail
created: 2026-05-13
status: live
parent: CLAUDE.md
related:
  - "[[appendix-A-blind-comparison-schema.md]]"
---

# Blind Comparison Workflow

**Contract ownership:** this file is the source of truth for the BCS protocol (path exclusion patterns, methodology quarantine semantics, sealed-reasoning capture, REVEAL gate, abort-on-breach). `lfcs-orchestrator` §3.4 is the enforcer that polices these rules during a paired session; if rules here change, the orchestrator's §3.4 updates to match — never the reverse.

**Pattern:** Rocky or Hasibul re-prices a job the other has already priced. Independence requires the comparator's prior pricing not influence the new pricer's reasoning.

**Trigger:** Rocky names the round explicitly (`/blind-compare 2629 against=hasibul-rev2` or "blind-compare this job against Hus's pricing").

---

## Procedure

1. **Pre-flight — define the blind boundary.**
   - `comparator_artefact_paths`: list of files the new pricer must NOT read (e.g. Hasibul priced xlsx, Liam quote PDF based on Hasibul's pricing, prior CC rev3 BoQ if it's the comparator).
   - `comparator_methodology_record_ids`: list of `_methodology_Rate_Templates` + `_methodology_Productivity_Benchmarks` rows that derived from the comparator's past pricing (e.g. HCB-pattern templates if blind-comparing on a different bridge job authored by Liam).

2. **Path exclusion.** Honour `--ab-blind-against=<file_glob>` per Common Misses Pattern `ab-test-integrity-cross-contamination`. Agent must NOT read the comparator artefacts during the blind period. If a file is in `comparator_artefact_paths`, treat as access-denied even if filesystem permission allows.

3. **Methodology row quarantine.** For each `comparator_methodology_record_ids` row, set field `_internal_quarantined_for_session_id` (see Appendix A) to the blind-comparison session UUID. Quarantined rows are EXCLUDED from `lfcs-pricing-estimator` template selection during the blind period. Filter expression: `AND(NOT({_internal_quarantined_for_session_id} = '{session_uuid}'))`.

4. **Open Blind Comparison Session.** Create row in `Blind Comparison Sessions` table (see Appendix A). Fields populated:
   - `session_id` (UUID, primary)
   - `job_record_id` (linked Job)
   - `bid_a_record_id` (the comparator's prior bid; e.g. Hasibul rev2)
   - `bid_b_record_id` (the new blind-priced bid; created in step 5)
   - `comparator_name` (e.g. "Hasibul Khan", "Liam Fitzgerald", "Rocky McLoughlin")
   - `new_pricer_name` (e.g. "claude-code-opsman + Rocky")
   - `comparator_artefact_paths` (multiline)
   - `quarantined_methodology_record_ids` (multiline)
   - `blind_phase_started_at` (datetime)
   - `blind_phase_ended_at` (null until step 7)
   - `comparison_capture_at` (null until step 7)
   - `unquarantined_at` (null until step 9)
   - `pre_comparison_sealed_reasoning` (multilineText — agent's full reasoning trail BEFORE seeing comparator's price; sealed)
   - `post_comparison_corrections_text` (multilineText — populated step 8)
   - `derived_methodology_corrections` (multilineText — populated step 8)

5. **Run §4.1 New tender intake** with the path exclusions + methodology quarantine active. Produce a fresh Bid record (`bid_b`) end-to-end through Phase 0 grill + first-pass + sanity-check. The session UUID flows through every Override row written during this period (`session_ref` field).

6. **Seal the pre-comparison reasoning.** Before reveal: write the agent's full reasoning trail (Pre-Pricing-Grill answers, productivity adjustments, complexity tags applied, exclusions invoked, total + delta vs Rate Card baseline) to `Blind Comparison Sessions.pre_comparison_sealed_reasoning` field. Mark session phase as "sealed". This is the auditable record the new pricer arrived at independently.

7. **Comparison capture (reveal phase).** Set `blind_phase_ended_at` + `comparison_capture_at` timestamps. Write side-by-side comparison to `_Brain/blind-comparison-{job}-{date}.md`:
   - `bid_a` total ex GST, line-by-line breakdown, methodology basis used (which Rate Templates, which complexity factors, which exclusions tier rows)
   - `bid_b` (new blind) total ex GST, line-by-line breakdown, methodology basis used
   - Per-line variance: `delta_pct = (bid_b - bid_a) / bid_a × 100` per line
   - Patterns observed (free text, 1–3 paragraphs)

8. **Post-comparison methodology corrections.** Where `bid_a` reveals signal `bid_b` missed (or vice versa), write proposed corrections to `Blind Comparison Sessions.post_comparison_corrections_text` AND to `derived_methodology_corrections`. Each correction creates a `Bid Line Item Overrides` row with `reviewer_type=Trades-Internal-{name}` + `linked_session_log = {blind_comparison_session_uuid}` + `reason_codes` reflecting the correction domain. NEVER auto-apply to methodology. Rocky reviews + accepts/rejects/modifies each proposed correction. On accept: Rate Template `base_rate_aud` updated with `confidence=Needs review` + `notes` referencing the blind-comparison session.

9. **Unquarantine.** After Rocky-confirmed corrections written: clear `_internal_quarantined_for_session_id` field on each previously-quarantined methodology row. Set `Blind Comparison Sessions.unquarantined_at`. Methodology rows return to active selection pool.

10. **Failure modes specific to blind comparison:**
    - Blind boundary breach (agent reads excluded file mid-session) → IMMEDIATELY abort session, mark `Blind Comparison Sessions.status = ABORTED-BREACH`, do NOT write corrections, do NOT unquarantine. Notify Rocky. Re-run requires fresh session UUID.
    - Comparator artefact arrives mid-session via email or new upload → treat as new file in `comparator_artefact_paths` and exclude going forward; if already read, abort.
    - Quarantined methodology row becomes the only available template for a scope → STOP, ask Rocky. Do not silently fall back to Rate Card hourly basis without a documented decision.
