---
skill: lfcs-boq-response-builder
version: 1
status: live
model: claude-haiku-4-5-20251001
inputs:
  - bid_record_id (Airtable Bid)
  - operator_of_record (default "Liam Fitzgerald")
  - company (default "LF Construction Services Pty Ltd")
  - margin_pct (default 16.5 — Lump-sum FRP package mode)
  - materials_markup_pct (default 10.0)
outputs:
  - BOQ-Response-{job_no}-LFCS-submitted.xlsx (sanitised xlsx)
  - BoQResponseOutput dataclass (line_count + hygiene_patterns_present + structural_parity dict)
implementation: HQ-Vault/11_OpsMan_LFCS/Codebase/lfcs-pricing-agent/lib/boq_response_builder.py
spec_source: Operations/lfcs-standards/templates/letter-of-offer-structure.md (BOQ section)
fixture: HCB priced BOQ (P424-HCB, May 2026)
---

# lfcs-boq-response-builder

HCB-style priced BOQ-response xlsx builder. Reads Bid + Bid Line Items from
Airtable; produces a live-formula xlsx mirroring the Hammond Canal Bridge BOQ
structure.

## Layout

| Column | Field |
|---|---|
| A | Bill Ref |
| B | Description |
| C | Qty |
| D | Unit (m2 / m3 / Tonne / m / Item / week / day / hr) |
| E | Rate ex GST |
| F | Total ex GST (live formula =Cn*En) |
| G | Notes / Calc Basis |

Bottom-of-sheet rows:
- Construction Sub-total ex GST: `=SUM(F2:F{last_row})` (live)
- Loaded uplift (26.5%): `=F{subtotal}*0.265` (live; per standing-context §1.5 locked formula)
- Contract Sum ex GST: `=F{subtotal}+F{margin}` (live)

## 7 Hygiene Patterns Enforced

Per `letter-of-offer-structure.md` BOQ Pricing Schedule Hygiene section:

| # | Pattern | Detected from |
|---|---|---|
| 1 | ADDED rows for missing scope | `bill_ref` or `notes` contains `ADDED` |
| 2 | "Included in Item X.X.X" cross-references | `notes` contains `Included in Item` |
| 3 | Rate Only items | `notes` contains `Rate Only` |
| 4 | OPTION rows | `bill_ref` or `notes` contains `OPTION` |
| 5 | EXCLUDED rows kept visible | `notes` contains `EXCLUDED` (NOT deleted from BoQ) |
| 6 | Consistent units | always — controlled vocab in column D |
| 7 | Formula-driven section totals | always — `=SUM(...)` cells, never pasted values |

`BoQResponseOutput.hygiene_patterns_present` returns the subset detected for the
specific bid; `6` and `7` are always present (always enforced); 1–5 depend on
whether the bid has lines tagged with the corresponding markers.

## Sanitisation seam

xlsx passes through `sanitise.sanitise_xlsx` (Layer 1) — strips `_internal_*`
sheets/values + regex-strips agent-derivation patterns + sets file metadata
(Author / LastModifiedBy / Company / Comments). Then `verify.verify_xlsx`
(Layer 2 INDEPENDENT) re-reads the output bytes and asserts no `_internal_*`
field/sheet survives + no agent-derivation token in any cell value or comment +
file properties match expected operator-of-record.

If Layer 2 fails, caller MUST delete the artefact + log layer2_pass=False.

## Margin mode

Defaults to **locked combined uplift 26.5%** per `standards/standing-context.md`
§1.5 locked formula (labour 1.10 contingency × 1.15 margin = 1.265; materials
1.15 margin × 1.10 contingency = 1.265 — same final multiplier). Caller
overrides via `margin_pct` for per-job design-maturity / posture variations
(intake-gate Q-4). Customer-facing format §1.5 spec hides loadings in rates;
this builder currently still shows the loaded uplift as a separate line —
broader xlsx-layout refactor queued in `proposals-pending.md`.

`materials_markup_pct` field retained for API compatibility but unused in
body (vestigial from pre-2026-05-08 16.5%/10% Concept Pattern).

## Run

```python
from lib.boq_response_builder import BoQResponseInputs, build_boq_response_for_bid
from pathlib import Path

result = build_boq_response_for_bid(
    BoQResponseInputs(bid_record_id="recXXXXXXXXXXXXXX"),
    output_dir=Path("./output"),
)
print(f"Wrote {result.xlsx_path} with {result.line_count} lines")
print(f"Hygiene patterns: {result.hygiene_patterns_present}")
print(f"Construction subtotal: ${result.construction_subtotal:,.2f}")
print(f"Contract sum: ${result.contract_sum:,.2f}")
print(f"Layer 2 verification: {'PASS' if result.sanitisation_layer2.passed else 'FAIL'}")
```
