# SKILL — lfcs-bid-prep-doc

**Version:** v4 (2026-05-07)
**Previous:** v3 (2026-05-06), v2, v1 (in `_Log.md`)

## Purpose

Generate the canonical bid analysis document `00-Bid-Prep.md` from the structured outputs of `lfcs-drawing-extract-text` + `lfcs-boq-parse` (when an HC BoQ exists) OR direct from drawings + a similar-job cost summary (when no HC BoQ exists — TCE-style FRP-install jobs).

The bid-prep doc is the upstream input for the priced BOQ + Letter of Offer.

## v4 changes (2026-05-07) — surfaced from 2629 Erskine Park session

Captured gaps from a live pricing session where v3 produced a result but the breakdown wasn't defendable line-by-line because key inputs weren't first-class.

- **NEW INPUT MODE — `boq_source_mode`:**
  - `hc-supplied` (v3 default — HC supplies BoQ to mark up with `ADDED` rows)
  - `lfcs-built-from-drawings` (NEW — head contractor doesn't supply a BoQ; LFCS builds the whole BoQ from drawings + a similar-job cost summary as productivity baseline). When this mode runs, Section 6 of the bid-prep doc becomes "Section structure proposed" rather than "Missing scope vs HC BoQ" — every line is by definition LFCS-authored.
- **NEW INPUT — `similar_job_cost_summary` (optional path):** when a comparable prior job's actuals are supplied (e.g. `TCE_Eastern_Creek_Cost_Summary.xlsx` for an Erskine Park bid), productivity rates derive from that file's actual hours-per-element AND **cross-contamination gate activates: pricing-history flywheel and OTHER jobs' rate references are excluded from this build**. Prevents the "borrow Husse's framework but call it independent" failure mode (2628 Vaughan Civil precedent, _Log 2026-05-04 PM late).
- **NEW INPUT — `job_type` (mandatory):** drives Prelims defaults. Choices:
  - `bridge` (HCB / 2602 pattern) — mob $5,827, demob $5,827, supervision $1,923/wk, telehandler IN, LAFHA candidate
  - `industrial-brownfield-slab` (NEW — 2629 Erskine pattern) — mob $3,500, demob $3,000, supervision $1,500/wk, telehandler EXCLUDED (HC plant), no LAFHA (Sydney metro)
  - `pit-tfnsw-dayworks` (2626 pattern) — mob $2,500, no separate supervision line (baked into hourly), telehandler EXCLUDED
  - `commercial-slab` — mob $4,000, supervision $1,750/wk, telehandler RATE-ONLY
  Defaults are starting points only — Phase 0 grill confirms each before applying.
- **NEW MANDATORY SECTION — "Section 9 — Temporary Works, Edge Protection & Safety":** every BoQ output must include this section, even if other sections vary by job type. Default lines:
  - Temp edge handrail — perimeter star-picket + 3-rail mesh, supply + install + maintain (hire-window) + dismantle. Qty = slab perimeter lin-m. Default rate $35/lin-m.
  - Bar caps / star-picket safety caps — all upturned reo + starter bars + projection ends. Qty = lump per job. Default rate $850 lump.
  - Vapour barrier install labour (when slab is partly suspended-on-natural-ground per S2.05-equivalent section). Qty = applicable area or lump. Default rate $1,500 lump or $5/m².
  - Temp scaffolding / access (where elevated work occurs). Hire-rate basis.
  Section 9 cannot be omitted. v3 missed this on 2629 Erskine until Rocky flagged manually — codifying so it's never missed again.
- **NEW REQUIRED FLAG — `mixed_support_assumption_split`:** when slab drawings show a Section detail of type "suspended-on-natural-ground with vapour barrier" alongside "suspended-on-conventional-formwork" (Erskine S2.05 Section 1 type), formwork qty derivation must explicitly state the assumed % split AND mark line as "**clarify pre-submission with HC/QS**" in Risk column. v3 silently picked a midpoint.
- **NEW REQUIRED FLAG — `reo_qty_source`:** every reo line carries `vision-estimate` / `measured-take-off` / `boq-supplied` / `back-calculated`. When source ≠ `measured-take-off` or `boq-supplied`, a ±15% sensitivity row appears on Rate Buildup Sheet 4.
- **MARGIN MODEL CLARIFIED:** practice (HCB + Munmorah recon) is **16.55% margin baked into per-line rate, no separate redundancy line**. v3 was ambiguous (pricing-checklist Phase 6 says 15% redundancy; submitted bids show baked-per-line). v4 enforces baked-per-line as default; separate redundancy only on `pit-tfnsw-dayworks` mode where rate-card driven hourly is used. Pricing-checklist update tracked separately.
- **DEFEND-EVERY-LINE OUTPUT REQUIREMENT:** for each BoQ line, output must include:
  - Drawing reference (sheet + section + note number)
  - Quantity derivation (formula, source — measured / vision / back-calculated)
  - Rate derivation (productivity hrs/unit × $/hr + materials + margin) — show the math
  - Similar-job productivity check (if `similar_job_cost_summary` provided)
  - Risk flag (the assumption that could move ±$X)
  This becomes the Notes column on the BoQ line + a "Calc Basis" entry per `pricing-checklist.md` Phase 5.
- **REGRESSION FIXTURES UPDATED:** running on 2629 Erskine Park inputs must reproduce the line-by-line walk Rocky asked for in the 2026-05-07 session — every line defendable on drawing ref + qty + rate + similar-job check + risk flag.

## v3 changes (2026-05-06)

- **BOQ hygiene patterns codified** as mandatory output sections (per `templates/letter-of-offer-structure.md` Section "BOQ — Pricing Schedule Hygiene"):
  - **Section 6 (NEW): Missing scope candidates (`ADDED` rows)** — every line LFCS would need to insert into the HC's pricing schedule because they missed it (preliminaries, diaphragm beams, additional items, etc.).
  - **Section 7 (NEW): Cross-reference candidates (`included in Item X.X.X`)** — any line where work is captured in another rate (formwork strip, expansion joints duplicated across approach slabs).
  - **Section 8 (NEW): Rate Only candidates** — items LFCS prices as unit rate but not committed quantity (hire items, weather standby, day labour).
  - **Section 9 (NEW): OPTION row candidates** — client-pick items (sacrificial ply, etc.).
  - **Section 10 (NEW): Cranage delineation row** — explicit Y/N who owns each lift in scope (LFCS vs HC vs Crane subbie).
- **Mandatory upstream alignment** — `00-Bid-Prep.md` now feeds `lfcs-letter-of-offer-draft` directly. The five mandatory LoO clauses (discrepancy / scope-gap / cranage / hire / optional) all derive from sections 6-10 above, so they MUST be populated even when empty (mark "N/A — none identified" rather than omit).
- **Reference fixture upgraded** — `boq-pricing-schedule-pattern.xlsx` (Hammond Canal Bridge) is now the third fixture alongside 2602 and 2626 BOQs.

## Trigger

User says any of:
- "Build the bid prep doc for [job]"
- "Generate 00-Bid-Prep"
- "Run bid prep on [job]"

Or invoked at end of bid-intake skill chain by cowork-lfcs.

## Inputs

Required:
- `job_folder` — absolute path
- `job_type` (NEW v4) — one of `bridge`, `industrial-brownfield-slab`, `pit-tfnsw-dayworks`, `commercial-slab`. Drives Prelims defaults.
- `boq_source_mode` (NEW v4) — `hc-supplied` OR `lfcs-built-from-drawings`. Drives Section 6 logic.

Optional (NEW v4):
- `similar_job_cost_summary` — absolute path to a comparable prior job's actuals xlsx (e.g. Eastern Creek Cost Summary for an Erskine Park bid). When supplied, productivity baselines derive from this file AND cross-contamination gate activates (other-job pricing-history excluded from rate derivation for this build).
- `similar_job_drawings` — absolute path or folder of comparable prior job's drawings, for scope mapping (e.g. "what was that Cyan 294 m² actually doing?").

Implicit (must exist before invocation):
- `00-brief.md` (from `lfcs-job-scaffold`)
- `Drawing-Index.md` (from `lfcs-drawing-extract-text` + `lfcs-drawing-extract-vision` if vision-pass run)
- `boq-normalised.json` (from `lfcs-boq-parse`) — REQUIRED ONLY if `boq_source_mode = hc-supplied`
- `Pre-Pricing-Grill-{date}.md` (from `lfcs-pre-grill` — Phase 0 mandatory)
- `lfcs-standards/templates/letter-of-offer-structure.md` (mandatory read for hygiene patterns)
- `lfcs-standards/templates/boq-pricing-schedule-pattern.xlsx` (regression fixture — Hammond Canal Bridge)
- `lfcs-standards/rate-card.md` + `lfcs-standards/element-taxonomy.md` (always read)

## Behaviour

0. **Phase 0 — Pre-Pricing Exclusion Grill (MANDATORY first step before any pricing).** Read `lfcs-standards/pricing-checklist.md` Phase 0. Run through Q1–Q7 with Rocky/Huss/Liam interactively via `lfcs-pre-grill` skill. **Don't infer answers from RFQ literal text — ASK.** Defaults exist for every question (e.g. "concrete supply: TfNSW dayworks → head contractor"), but agent confirms each before applying. Output: `{job_folder}/02 - Scope and Pricing/02b - BOQ and Rate Schedules/Pre-Pricing-Grill-{date}.md` with every question + answer captured. Skill aborts if grill record missing or any answer is "TBC" / unanswered. **2626 lesson: 5 revisions because grill wasn't run upfront.**

1. **Pre-flight check** — abort if any input missing OR Phase 0 grill incomplete.

1a. **Read `lfcs-standards/pricing-checklist.md` IN FULL** + `lfcs-standards/templates/letter-of-offer-structure.md` IN FULL. Every Phase 1+2 item must be answered before pricing starts. Specifically:
   - RFQ scope email read (programme constraints — day/night/weekend)?
   - All BoQ files opened (failed downloads escalated, NOT ignored)?
   - Rate Card V1.7 NIGHT tier including **midnight crossing loading clause** ("Night Shifts extending past midnight will incur an extra 8 hours at day shift rate") understood and applied if any shift crosses midnight?
   - RFI files read for unsigned acceptance pre-conditions?
   - Pit fixtures supply scope confirmed via Phase 0 grill (NOT inferred from RFQ wording)?
   - Reo qty trusted from BoQ (NOT back-calculated from drawings)?
   - **NEW v3:** BOQ hygiene patterns from `letter-of-offer-structure.md` ingested — `ADDED` row format, `included in Item X.X.X` cross-ref convention, `Rate Only` vs `OPTION` distinction, `EXCLUDED` rows kept visible, consistent units, formula-driven totals.

2. **Read inputs** in order: Pre-Pricing-Grill record → brief → drawing-index → boq-normalised → pricing-checklist → letter-of-offer-structure (Phase 5 output structure: 6-sheet Tender Summary + 5-sheet Rate Buildup + Calc Basis column on every line).

3. **Extract sections to populate (1–5 unchanged from v2):**
   - **What we're bidding on** — 1-paragraph synthesis from `00-brief.md` scope + drawing-index document set summary.
   - **Tender document register** — table from drawing-index document set summary + BOQ filename / rev / date.
   - **Bridge / structure specs** (or domain-equivalent) — geometry, codes/loading, structure elements pulled from drawing-index per-drawing blocks tagged `lfcs_scope: primary`.
   - **Existing conditions / LFCS impact** — from drawing-index `risk:` tags + civil reference-only `existing:` tags.
   - **Quantities (LFCS scope)** — from `boq-normalised.json` grouped by `section_heading`, with per-section subtotal + grand total per element type (concrete m³, reo T, formwork m², strip m²).

4. **Extract Sections 6–10 — BOQ hygiene-pattern outputs (mode-aware in v4):**

   **MODE BRANCH:**
   - If `boq_source_mode = hc-supplied`: Sections 6–10 follow v3 logic (ADDED rows / cross-refs / Rate Only / OPTION / cranage delineation against HC-supplied BoQ).
   - If `boq_source_mode = lfcs-built-from-drawings` (NEW v4): Section 6 becomes "Section structure proposed" — LFCS-authored BoQ structure from drawings. Sections 7–10 still apply but reference LFCS's own line refs.

   ### Section 6 — Missing scope candidates (`ADDED` rows) [hc-supplied mode]
   For every BOQ section group (Preliminaries, Substructure, Superstructure, etc.), cross-reference the drawing-index `lfcs_scope: primary` elements against the HC's BOQ rows. If an element is shown on drawings but absent from the BOQ → flag as `ADDED` row candidate. Output table:
   
   ```
   | ADDED row | Description | Qty | Unit | Source (drawing/spec) |
   ```
   
   Hammond Canal Bridge example: diaphragm beams at abutments (formwork 15.84 m², reo 1.31 T, concrete 4.36 m³) shown on bridge drawings but missing from HC's BOQ. LFCS added all three lines.
   
   Always include the standard preliminaries `ADDED` block: Project Mob/Demob, Project Management, Inductions, Telehandler, LAFHA, Inclement Weather, Temporary Works Design.

   ### Section 7 — Cross-reference candidates (`included in Item X.X.X`)
   Identify rows where work is captured in another rate. Common patterns:
   - Formwork strip → `included in` formwork erect
   - Expansion joints duplicated across approach slabs and bridge deck → second instance `included in` first
   - Reo placement included in fix-and-tie rate
   
   Output table:
   ```
   | BOQ line | Cross-ref target | Reason |
   ```

   ### Section 8 — Rate Only candidates
   Items priced as unit rate without committed quantity. Common:
   - Hire items (edge protection, scaffolding, walkways) — when programme is uncertain
   - Day labour rates
   - Weather standby
   - Sawcut by m, demolition by m³, additional concrete by m³
   
   Output table:
   ```
   | Item | Unit | Suggested rate | Trigger condition |
   ```

   ### Section 9 — OPTION row candidates
   Client-pick items. Common:
   - Sacrificial ply sheets for Super-T girders
   - Alternative finishes (honed vs broom)
   - Optional barrier types
   - Extended hire periods
   
   Output table:
   ```
   | Item | Qty | Unit | Rate | Pick condition |
   ```

   ### Section 10 — Cranage delineation
   Explicit row for every lift in scope. Hammond Canal Bridge example: HC provides cranage for Super-T install AND temporary walkway install AND parapet install; LFCS provides 4-man crew to assist. This row must exist for every job involving lifts because **cranage ambiguity is the #1 source of bridge-job disputes**.
   
   Output table:
   ```
   | Lift | Owner (LFCS / HC / Crane subbie) | Crew (who provides) | Source (BOQ line + Pre-Pricing-Grill answer) |
   ```

   ### Section 9b (NEW v4) — Temporary Works, Edge Protection & Safety [MANDATORY EVERY JOB]
   Always emit this section. Defaults below are starting points — Phase 0 grill confirms quantities and rates per job.
   - **Temp edge handrail** — perimeter star-picket + 3-rail mesh, supply + install + maintain (hire-window weeks) + dismantle. Qty = slab/element perimeter lin-m. Default rate $35/lin-m all-in.
   - **Bar caps / star-picket safety caps** — all upturned reo + starter bars + projection ends + dowels. Qty = lump per job. Default $850 lump (covers ~200 caps + 1 day install labour).
   - **Vapour barrier install labour** — when partly suspended-on-natural-ground (TCE/HC supplies HDPE membrane). Qty = applicable area or lump. Default $5/m² or $1,500 lump.
   - **Temp scaffolding / access** — when elevated work or formwork over edge required. Hire-rate basis per duration.
   - **Site safety setup** — barrier tape, signage, exclusion zone setup. Default $500 lump if not absorbed in mob.
   v3 omitted Section 9b on 2629 Erskine until Rocky flagged manually. v4 makes it mandatory.

   ### Section 6b (NEW v4) — Section structure proposed [lfcs-built-from-drawings mode]
   When LFCS authors the BoQ from scratch, propose section structure based on `job_type` defaults:
   - `industrial-brownfield-slab` (Erskine pattern): Prelims / Sec 6 Main slab+beams / Sec 7 Walkway / Sec 8 Bund wall blockwork / Sec 9 Temp works & safety / Optional & Rate Only
   - `bridge` (HCB pattern): Prelims / Sec 6 Substructure / Sec 7 Superstructure / Sec 8 Approach slabs / Sec 9 Barriers / Sec 10 Temp works & safety / Optional & Rate Only
   - `pit-tfnsw-dayworks` (2626 pattern): Prelims (mob only) / Sec 6 Pit FRP / Sec 7 Penetrations / Sec 8 Temp works & safety / Lump Sum + Schedule of Rates dual presentation
   Output is the proposed structure + rationale. Phase 0 grill can override.

5. **Extract sections 11–14 (formerly 6–9 in v2):**
   - **Cost framework skeleton** — pointer to `lfcs-standards/rate-card.md`, list of cost-build inputs.
   - **Variation rate template** — placeholder rates table (additional concrete $/m³, additional reo $/T, additional formwork $/m², day labour, saw-cutting, demolition).
   - **Exclusions headline** — pointer to draft `Inclusions-Exclusions.md` (after `lfcs-incl-excl-draft` runs).
   - **Submission strategy** — checklist (cover letter, priced BOQ, inclusions/exclusions, VO schedule, programme assumption, references, insurances).
   - **Confidence flags** — note text-extract limitations + vision-pass mandate.

6. **Write `{job_folder}/00-Bid-Prep.md`** with frontmatter (`title`, `created`, `created_by: cowork-lfcs via lfcs-bid-prep-doc v3`, `status: live-working-doc`, `related: [00-brief, Pre-Call-Questions, Inclusions-Exclusions, Drawing-Index, letter-of-offer-structure]`).

7. **Append project log + daily note.**

8. **After vault writes commit, invoke `lfcs-airtable-sync target_table=Jobs mode=upsert`** to update `Jobs.Notes`. Failure non-blocking.

## Files to read (in order)

```
HQ-Vault/_System/CLAUDE.md
HQ-Vault/11_OpsMan_LFCS/_Brain/CLAUDE.md
HQ-Vault/11_OpsMan_LFCS/Operations/lfcs-standards/rate-card.md
HQ-Vault/11_OpsMan_LFCS/Operations/lfcs-standards/pricing-checklist.md
HQ-Vault/11_OpsMan_LFCS/Operations/lfcs-standards/templates/letter-of-offer-structure.md  ← v3 mandatory
HQ-Vault/11_OpsMan_LFCS/Operations/lfcs-standards/templates/boq-pricing-schedule-pattern.xlsx  ← regression fixture #3
HQ-Vault/11_OpsMan_LFCS/Operations/Jobs/Upcoming/2602 - Dec Projects - Munmorah Bridge/00-Bid-Prep.md  ← regression fixture #1
HQ-Vault/11_OpsMan_LFCS/Operations/Jobs/Upcoming/2626 - Mack Civil - Stormwater Pit EXA01A-08/00-Bid-Prep.md  ← regression fixture #2
{job_folder}/00-brief.md
{job_folder}/02 - Scope and Pricing/02b - BOQ and Rate Schedules/Pre-Pricing-Grill-*.md
{job_folder}/03 - Plans and Specifications/03a - Issued for Construction/Drawing-Index.md
{job_folder}/02 - Scope and Pricing/02b - BOQ and Rate Schedules/boq-normalised.json
{job_folder}/02 - Scope and Pricing/02b - BOQ and Rate Schedules/boq-quantities-at-a-glance.md
```

## Airtable behaviour

- **Reads:** `Jobs`, `Drawings` (for this job), `Drawing Elements` (queries by Job link), `Specifications` (linked to Job), `RFIs` (linked to Job — surfaces unresolved RFI risk in the bid-prep doc).
- **Writes:** none directly. May update `Jobs.Notes` with one-liner ("Bid prep doc generated YYYY-MM-DD by lfcs-bid-prep-doc v3"). Calls `lfcs-airtable-sync target_table=Jobs mode=upsert` for the Notes update.
- **Idempotency:** N/A (no creates).

## Output format

To user:

```
✓ 00-Bid-Prep.md generated for {job_no}
  Sections populated: {list}
  Tender docs registered: {n}
  Quantities sections: {n}
  ADDED rows identified: {n} (preliminaries: {m}, scope-gap: {k})
  Cross-ref candidates: {n}
  Rate Only items: {n}
  OPTION rows: {n}
  Cranage delineation rows: {n}
  Risks identified: {n}
  Confidence flags: {list}

  Path: {abs path}

  Next skills:
    - lfcs-precall-questions — generate Pre-Call-Questions-{date}.md
    - lfcs-incl-excl-draft v3 — draft three-tier Inclusions/Exclusions/Qualifications
    - lfcs-letter-of-offer-draft — generate signed-ready cover letter
```

## Hard rules

- **Pre-flight: all inputs must exist.** Abort with helpful message if missing.
- **Phase 0 grill is non-negotiable.** Skill aborts if `Pre-Pricing-Grill-*.md` missing or has TBC answers.
- **No invention.** Every claim in the doc must trace to a specific cell in `boq-normalised.json` or block in `Drawing-Index.md`. Inline cross-references using Obsidian wikilinks where possible.
- **BOQ hygiene sections (6–10) must be populated** — even if empty, mark "N/A — none identified" rather than omit. Downstream `lfcs-letter-of-offer-draft` reads these to fire its mandatory clauses.
- **NEW v4 — Section 9b Temp Works & Safety is MANDATORY** — never omit. Every concrete job has perimeter handrail + bar caps + safety lines.
- **NEW v4 — Cross-contamination gate.** When `similar_job_cost_summary` provided, the agent MUST NOT read pricing-history flywheel entries from other jobs OR rate buildup files from other jobs during this build. Only allowed inputs: vault standards (`lfcs-standards/*`), the named similar-job files, the current job's drawings + brief + grill. Violating this corrupts the A/B integrity per 2628 Vaughan Civil precedent.
- **NEW v4 — Defend-every-line.** Every BoQ line must carry: drawing ref + qty derivation + rate derivation (math shown) + similar-job productivity check + risk flag. No "$X — trust me" rates.
- **NEW v4 — Mixed-support assumption flagged.** When slab has both suspended-on-formwork and suspended-on-natural-ground portions, formwork qty derivation must declare the assumed % split + flag for HC/QS clarification pre-submission.
- **NEW v4 — Reo qty source flagged.** Every reo line carries source = vision-estimate / measured-take-off / boq-supplied / back-calculated. Non-measured sources trigger ±15% sensitivity row.
- **NEW v4 — Margin model = 16.55% baked-per-line** (default; matches HCB + Munmorah practice). Separate-line redundancy reserved for `pit-tfnsw-dayworks` mode only.
- **Verbatim construction notes** when reproducing from drawing-index; italicise + quote.
- **Confidence flags section is mandatory** — every output must end with a confidence-flags section explicitly noting text-extract-only limitations and the vision-pass requirement.
- **Append-only on `00-Bid-Prep.md`** — if file exists, abort + ask user.
- **Read-before-edit.**
- **Regression fixtures:** running on 2602 inputs must reproduce or improve the existing `00-Bid-Prep.md`. Running on Hammond Canal Bridge BOQ must reproduce all `ADDED` rows + cross-refs + Rate Only + OPTION + cranage delineation. **NEW v4:** running on 2629 Erskine inputs (lfcs-built-from-drawings mode + Eastern Creek similar-job + industrial-brownfield-slab job-type) must produce the line-by-line walk Rocky requested 2026-05-07 — every line defendable.
- **Vault markdown is source of truth.** If `lfcs-airtable-sync` write fails, this skill's run is still considered successful — log the Airtable failure to `_System/Conflicts.md` and continue. Never block on Airtable.

## Dependencies

- `lfcs-job-scaffold` (00-brief.md)
- `lfcs-pre-grill` (Pre-Pricing-Grill record)
- `lfcs-drawing-extract-text` (Drawing-Index.md)
- `lfcs-boq-parse` (boq-normalised.json)
- `lfcs-standards/rate-card.md`
- `lfcs-standards/templates/letter-of-offer-structure.md` (v3 dependency)
- `lfcs-standards/templates/boq-pricing-schedule-pattern.xlsx` (regression fixture #3)
- 2602 + 2626 `00-Bid-Prep.md` (regression fixtures #1 + #2)

## Failure modes

| Failure | Detection | Recovery |
|---|---|---|
| Missing input file | Pre-flight | Abort + name the missing skill to run first |
| Phase 0 grill missing or has TBC | Pre-flight | Abort + tell Rocky to run lfcs-pre-grill |
| `00-Bid-Prep.md` already exists | Pre-check | Abort + ask user |
| BOQ has zero LFCS-scope lines | Per-line scope filter | Generate doc with empty quantities section + flag |
| Drawing-Index has zero `lfcs_scope: primary` drawings | Per-drawing filter | Abort + ask user to verify drawings dropped in correct folder |
| Hygiene section trigger ambiguous (e.g. is this a hire item?) | Per-row check | Flag as TBC + ask Rocky pre-write |
